LCOV - code coverage report
Current view: top level - vcl/source/gdi - print.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 255 1008 25.3 %
Date: 2015-06-13 12:38:46 Functions: 31 87 35.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <list>
      21             : 
      22             : #include <tools/debug.hxx>
      23             : #include <tools/resary.hxx>
      24             : #include <tools/stream.hxx>
      25             : #include <tools/vcompat.hxx>
      26             : #include <tools/helpers.hxx>
      27             : 
      28             : #include <vcl/unohelp.hxx>
      29             : #include <vcl/svapp.hxx>
      30             : #include <vcl/wrkwin.hxx>
      31             : #include <vcl/virdev.hxx>
      32             : #include <vcl/window.hxx>
      33             : #include <vcl/gdimtf.hxx>
      34             : #include <vcl/metaact.hxx>
      35             : #include <vcl/print.hxx>
      36             : 
      37             : #include <salinst.hxx>
      38             : #include <salvd.hxx>
      39             : #include <salgdi.hxx>
      40             : #include <salptype.hxx>
      41             : #include <salprn.hxx>
      42             : #include <svdata.hxx>
      43             : #include <svids.hrc>
      44             : #include <jobset.h>
      45             : #include <outdev.h>
      46             : #include "PhysicalFontCollection.hxx"
      47             : #include <print.h>
      48             : 
      49             : #include <comphelper/processfactory.hxx>
      50             : 
      51             : #include "com/sun/star/beans/XPropertySet.hpp"
      52             : #include "com/sun/star/configuration/theDefaultProvider.hpp"
      53             : #include "com/sun/star/container/XNameAccess.hpp"
      54             : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
      55             : 
      56             : using namespace com::sun::star::uno;
      57             : using namespace com::sun::star::lang;
      58             : using namespace com::sun::star::beans;
      59             : using namespace com::sun::star::container;
      60             : using namespace com::sun::star::configuration;
      61             : 
      62             : int nImplSysDialog = 0;
      63             : 
      64             : namespace
      65             : {
      66           0 :     static Paper ImplGetPaperFormat( long nWidth100thMM, long nHeight100thMM )
      67             :     {
      68           0 :         PaperInfo aInfo(nWidth100thMM, nHeight100thMM);
      69           0 :         aInfo.doSloppyFit();
      70           0 :         return aInfo.getPaper();
      71             :     }
      72             : 
      73           0 :     static const PaperInfo& ImplGetEmptyPaper()
      74             :     {
      75           0 :         static PaperInfo aInfo(PAPER_USER);
      76           0 :         return aInfo;
      77             :     }
      78             : }
      79             : 
      80         495 : void ImplUpdateJobSetupPaper( JobSetup& rJobSetup )
      81             : {
      82         495 :     const ImplJobSetup* pConstData = rJobSetup.ImplGetConstData();
      83             : 
      84         495 :     if ( !pConstData->mnPaperWidth || !pConstData->mnPaperHeight )
      85             :     {
      86         495 :         if ( pConstData->mePaperFormat != PAPER_USER )
      87             :         {
      88         495 :             ImplJobSetup* pData  = rJobSetup.ImplGetData();
      89         495 :             PaperInfo aInfo(pConstData->mePaperFormat);
      90         495 :             pData->mnPaperWidth  = aInfo.getWidth();
      91         495 :             pData->mnPaperHeight = aInfo.getHeight();
      92         495 :         }
      93             :     }
      94           0 :     else if ( pConstData->mePaperFormat == PAPER_USER )
      95             :     {
      96           0 :         Paper ePaper = ImplGetPaperFormat( pConstData->mnPaperWidth, pConstData->mnPaperHeight );
      97           0 :         if ( ePaper != PAPER_USER )
      98           0 :             rJobSetup.ImplGetData()->mePaperFormat = ePaper;
      99             :     }
     100         495 : }
     101             : 
     102             : // PrinterOptions
     103         430 : PrinterOptions::PrinterOptions() :
     104             :     mbReduceTransparency( false ),
     105             :     meReducedTransparencyMode( PRINTER_TRANSPARENCY_AUTO ),
     106             :     mbReduceGradients( false ),
     107             :     meReducedGradientsMode( PRINTER_GRADIENT_STRIPES ),
     108             :     mnReducedGradientStepCount( 64 ),
     109             :     mbReduceBitmaps( false ),
     110             :     meReducedBitmapMode( PRINTER_BITMAP_NORMAL ),
     111             :     mnReducedBitmapResolution( 200 ),
     112             :     mbReducedBitmapsIncludeTransparency( true ),
     113             :     mbConvertToGreyscales( false ),
     114         430 :     mbPDFAsStandardPrintJobFormat( false )
     115             : {
     116         430 : }
     117             : 
     118         424 : PrinterOptions::~PrinterOptions()
     119             : {
     120         424 : }
     121             : 
     122             : #define PROPERTYNAME_REDUCETRANSPARENCY                 OUString("ReduceTransparency")
     123             : #define PROPERTYNAME_REDUCEDTRANSPARENCYMODE            OUString("ReducedTransparencyMode")
     124             : #define PROPERTYNAME_REDUCEGRADIENTS                    OUString("ReduceGradients")
     125             : #define PROPERTYNAME_REDUCEDGRADIENTMODE                OUString("ReducedGradientMode")
     126             : #define PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT           OUString("ReducedGradientStepCount")
     127             : #define PROPERTYNAME_REDUCEBITMAPS                      OUString("ReduceBitmaps")
     128             : #define PROPERTYNAME_REDUCEDBITMAPMODE                  OUString("ReducedBitmapMode")
     129             : #define PROPERTYNAME_REDUCEDBITMAPRESOLUTION            OUString("ReducedBitmapResolution")
     130             : #define PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY  OUString("ReducedBitmapIncludesTransparency")
     131             : #define PROPERTYNAME_CONVERTTOGREYSCALES                OUString("ConvertToGreyscales")
     132             : #define PROPERTYNAME_PDFASSTANDARDPRINTJOBFORMAT        OUString("PDFAsStandardPrintJobFormat")
     133             : 
     134           0 : bool PrinterOptions::ReadFromConfig( bool i_bFile )
     135             : {
     136           0 :     bool bSuccess = false;
     137             :     // save old state in case something goes wrong
     138           0 :     PrinterOptions aOldValues( *this );
     139             : 
     140             :     // get the configuration service
     141           0 :     Reference< XMultiServiceFactory > xConfigProvider;
     142           0 :     Reference< XNameAccess > xConfigAccess;
     143             :     try
     144             :     {
     145             :         // get service provider
     146           0 :         Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
     147             :         // create configuration hierarchical access name
     148             :         try
     149             :         {
     150           0 :             xConfigProvider = theDefaultProvider::get( xContext );
     151             : 
     152           0 :             Sequence< Any > aArgs(1);
     153           0 :             PropertyValue aVal;
     154           0 :             aVal.Name = "nodepath";
     155           0 :             if( i_bFile )
     156           0 :                 aVal.Value <<= OUString( "/org.openoffice.Office.Common/Print/Option/File" );
     157             :             else
     158           0 :                 aVal.Value <<= OUString( "/org.openoffice.Office.Common/Print/Option/Printer" );
     159           0 :             aArgs.getArray()[0] <<= aVal;
     160           0 :             xConfigAccess = Reference< XNameAccess >(
     161           0 :                     xConfigProvider->createInstanceWithArguments(
     162           0 :                         OUString( "com.sun.star.configuration.ConfigurationAccess" ), aArgs ),
     163           0 :                         UNO_QUERY );
     164           0 :             if( xConfigAccess.is() )
     165             :             {
     166           0 :                 Reference< XPropertySet > xSet( xConfigAccess, UNO_QUERY );
     167           0 :                 if( xSet.is() )
     168             :                 {
     169           0 :                     sal_Int32 nValue = 0;
     170           0 :                     bool  bValue = false;
     171           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCETRANSPARENCY) >>= bValue )
     172           0 :                         SetReduceTransparency( bValue );
     173           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDTRANSPARENCYMODE) >>= nValue )
     174           0 :                         SetReducedTransparencyMode( (PrinterTransparencyMode)nValue );
     175           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEGRADIENTS) >>= bValue )
     176           0 :                         SetReduceGradients( bValue );
     177           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTMODE) >>= nValue )
     178           0 :                         SetReducedGradientMode( (PrinterGradientMode)nValue );
     179           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDGRADIENTSTEPCOUNT) >>= nValue )
     180           0 :                         SetReducedGradientStepCount( (sal_uInt16)nValue );
     181           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEBITMAPS) >>= bValue )
     182           0 :                         SetReduceBitmaps( bValue );
     183           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPMODE) >>= nValue )
     184           0 :                         SetReducedBitmapMode( (PrinterBitmapMode)nValue );
     185           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPRESOLUTION) >>= nValue )
     186           0 :                         SetReducedBitmapResolution( (sal_uInt16)nValue );
     187           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_REDUCEDBITMAPINCLUDESTRANSPARENCY) >>= bValue )
     188           0 :                         SetReducedBitmapIncludesTransparency( bValue );
     189           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_CONVERTTOGREYSCALES) >>= bValue )
     190           0 :                         SetConvertToGreyscales( bValue );
     191           0 :                     if( xSet->getPropertyValue(PROPERTYNAME_PDFASSTANDARDPRINTJOBFORMAT) >>= bValue )
     192           0 :                         SetPDFAsStandardPrintJobFormat( bValue );
     193             : 
     194           0 :                     bSuccess = true;
     195           0 :                 }
     196           0 :             }
     197             :         }
     198           0 :         catch( const Exception& )
     199             :         {
     200           0 :         }
     201             :     }
     202           0 :     catch( const WrappedTargetException& )
     203             :     {
     204             :     }
     205             : 
     206           0 :     if( ! bSuccess )
     207           0 :         *this = aOldValues;
     208           0 :     return bSuccess;
     209             : }
     210             : 
     211           0 : bool Printer::DrawTransformBitmapExDirect(
     212             :     const basegfx::B2DHomMatrix& /*aFullTransform*/,
     213             :     const BitmapEx& /*rBitmapEx*/)
     214             : {
     215             :     // printers can't draw bitmaps directly
     216           0 :     return false;
     217             : }
     218             : 
     219           0 : bool Printer::TransformAndReduceBitmapExToTargetRange(
     220             :     const basegfx::B2DHomMatrix& /*aFullTransform*/,
     221             :     basegfx::B2DRange& /*aVisibleRange*/,
     222             :     double& /*fMaximumArea*/)
     223             : {
     224             :     // deliberately do nothing - you can't reduce the
     225             :     // target range for a printer at all
     226           0 :     return true;
     227             : }
     228             : 
     229           0 : void Printer::DrawDeviceBitmap( const Point& rDestPt, const Size& rDestSize,
     230             :                                 const Point& rSrcPtPixel, const Size& rSrcSizePixel,
     231             :                                 BitmapEx& rBmpEx )
     232             : {
     233           0 :     if( rBmpEx.IsAlpha() )
     234             :     {
     235             :         // #107169# For true alpha bitmaps, no longer masking the
     236             :         // bitmap, but perform a full alpha blend against a white
     237             :         // background here.
     238           0 :         Bitmap aBmp( rBmpEx.GetBitmap() );
     239           0 :         aBmp.Blend( rBmpEx.GetAlpha(), Color( COL_WHITE) );
     240           0 :         DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, aBmp );
     241             :     }
     242             :     else
     243             :     {
     244           0 :         Bitmap aBmp( rBmpEx.GetBitmap() ), aMask( rBmpEx.GetMask() );
     245           0 :         aBmp.Replace( aMask, Color( COL_WHITE ) );
     246           0 :         ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel );
     247             :     }
     248           0 : }
     249             : 
     250           0 : void Printer::EmulateDrawTransparent ( const tools::PolyPolygon& rPolyPoly,
     251             :                                        sal_uInt16 nTransparencePercent )
     252             : {
     253             :     // #110958# Disable alpha VDev, we perform the necessary
     254           0 :     VirtualDevice* pOldAlphaVDev = mpAlphaVDev;
     255             : 
     256             :     // operation explicitly further below.
     257           0 :     if( mpAlphaVDev )
     258           0 :         mpAlphaVDev = NULL;
     259             : 
     260           0 :     GDIMetaFile* pOldMetaFile = mpMetaFile;
     261           0 :     mpMetaFile = NULL;
     262             : 
     263           0 :     mpMetaFile = pOldMetaFile;
     264             : 
     265             :     // #110958# Restore disabled alpha VDev
     266           0 :     mpAlphaVDev = pOldAlphaVDev;
     267             : 
     268           0 :     Rectangle       aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() );
     269           0 :     const Size      aDPISize( LogicToPixel( Size( 1, 1 ), MAP_INCH ) );
     270           0 :     const long      nBaseExtent = std::max( FRound( aDPISize.Width() / 300. ), 1L );
     271             :     long            nMove;
     272             :     const sal_uInt16    nTrans = ( nTransparencePercent < 13 ) ? 0 :
     273             :         ( nTransparencePercent < 38 ) ? 25 :
     274             :         ( nTransparencePercent < 63 ) ? 50 :
     275           0 :         ( nTransparencePercent < 88 ) ? 75 : 100;
     276             : 
     277           0 :     switch( nTrans )
     278             :     {
     279           0 :         case( 25 ): nMove = nBaseExtent * 3; break;
     280           0 :         case( 50 ): nMove = nBaseExtent * 4; break;
     281           0 :         case( 75 ): nMove = nBaseExtent * 6; break;
     282             : 
     283             :             // #i112959#  very transparent (88 < nTransparencePercent <= 99)
     284           0 :         case( 100 ): nMove = nBaseExtent * 8; break;
     285             : 
     286             :             // #i112959# not transparent (nTransparencePercent < 13)
     287           0 :         default:    nMove = 0; break;
     288             :     }
     289             : 
     290           0 :     Push( PushFlags::CLIPREGION | PushFlags::LINECOLOR );
     291           0 :     IntersectClipRegion(vcl::Region(rPolyPoly));
     292           0 :     SetLineColor( GetFillColor() );
     293           0 :     const bool bOldMap = mbMap;
     294           0 :     EnableMapMode( false );
     295             : 
     296           0 :     if(nMove)
     297             :     {
     298           0 :         Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) );
     299           0 :         while( aRect.Top() <= aPolyRect.Bottom() )
     300             :         {
     301           0 :             DrawRect( aRect );
     302           0 :             aRect.Move( 0, nMove );
     303             :         }
     304             : 
     305           0 :         aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) );
     306           0 :         while( aRect.Left() <= aPolyRect.Right() )
     307             :         {
     308           0 :             DrawRect( aRect );
     309           0 :             aRect.Move( nMove, 0 );
     310             :         }
     311             :     }
     312             :     else
     313             :     {
     314             :         // #i112959# if not transparent, draw full rectangle in clip region
     315           0 :         DrawRect( aPolyRect );
     316             :     }
     317             : 
     318           0 :     EnableMapMode( bOldMap );
     319           0 :     Pop();
     320             : 
     321           0 :     mpMetaFile = pOldMetaFile;
     322             : 
     323             :     // #110958# Restore disabled alpha VDev
     324           0 :     mpAlphaVDev = pOldAlphaVDev;
     325           0 : }
     326             : 
     327           0 : void Printer::DrawOutDev( const Point& /*rDestPt*/, const Size& /*rDestSize*/,
     328             :                                const Point& /*rSrcPt*/,  const Size& /*rSrcSize*/ )
     329             : {
     330             :     DBG_ASSERT( false, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
     331           0 : }
     332             : 
     333           0 : void Printer::DrawOutDev( const Point& /*rDestPt*/, const Size& /*rDestSize*/,
     334             :                                const Point& /*rSrcPt*/,  const Size& /*rSrcSize*/,
     335             :                                const OutputDevice& /*rOutDev*/ )
     336             : {
     337             :     DBG_ASSERT( false, "Don't use OutputDevice::DrawOutDev(...) with printer devices!" );
     338           0 : }
     339             : 
     340           0 : void Printer::CopyArea( const Point& /*rDestPt*/,
     341             :                         const Point& /*rSrcPt*/,  const Size& /*rSrcSize*/,
     342             :                         bool /*bWindowInvalidate*/ )
     343             : {
     344             :     DBG_ASSERT( false, "Don't use OutputDevice::CopyArea(...) with printer devices!" );
     345           0 : }
     346             : 
     347           0 : void Printer::SetPrinterOptions( const PrinterOptions& i_rOptions )
     348             : {
     349           0 :     *mpPrinterOptions = i_rOptions;
     350           0 : }
     351             : 
     352           0 : bool Printer::HasMirroredGraphics() const
     353             : {
     354             :     // due to a "hotfix" for AOO bug i55719, this needs to return false
     355           0 :     return false;
     356             : }
     357             : 
     358             : // QueueInfo
     359           0 : QueueInfo::QueueInfo()
     360             : {
     361           0 :     mnStatus    = PrintQueueFlags::NONE;
     362           0 :     mnJobs      = 0;
     363           0 : }
     364             : 
     365           0 : QueueInfo::QueueInfo( const QueueInfo& rInfo ) :
     366             :     maPrinterName( rInfo.maPrinterName ),
     367             :     maDriver( rInfo.maDriver ),
     368             :     maLocation( rInfo.maLocation ),
     369             :     maComment( rInfo.maComment ),
     370             :     mnStatus( rInfo.mnStatus ),
     371           0 :     mnJobs( rInfo.mnJobs )
     372             : {
     373           0 : }
     374             : 
     375           0 : QueueInfo::~QueueInfo()
     376             : {
     377           0 : }
     378             : 
     379           0 : bool QueueInfo::operator==( const QueueInfo& rInfo ) const
     380             : {
     381             :     return
     382           0 :         maPrinterName   == rInfo.maPrinterName  &&
     383           0 :         maDriver        == rInfo.maDriver       &&
     384           0 :         maLocation      == rInfo.maLocation     &&
     385           0 :         maComment       == rInfo.maComment      &&
     386           0 :         mnStatus        == rInfo.mnStatus       &&
     387           0 :         mnJobs          == rInfo.mnJobs;
     388             : }
     389             : 
     390           0 : SvStream& WriteQueueInfo( SvStream& rOStream, const QueueInfo& rInfo )
     391             : {
     392           0 :     VersionCompat aCompat( rOStream, StreamMode::WRITE, 1 );
     393             : 
     394           0 :     write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rInfo.maPrinterName, RTL_TEXTENCODING_UTF8);
     395           0 :     write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rInfo.maDriver, RTL_TEXTENCODING_UTF8);
     396           0 :     write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rInfo.maLocation, RTL_TEXTENCODING_UTF8);
     397           0 :     write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rInfo.maComment, RTL_TEXTENCODING_UTF8);
     398           0 :     rOStream.WriteUInt32( static_cast<sal_uInt32>(rInfo.mnStatus) );
     399           0 :     rOStream.WriteUInt32( rInfo.mnJobs );
     400             : 
     401           0 :     return rOStream;
     402             : }
     403             : 
     404           0 : SvStream& ReadQueueInfo( SvStream& rIStream, QueueInfo& rInfo )
     405             : {
     406           0 :     VersionCompat aCompat( rIStream, StreamMode::READ );
     407             : 
     408           0 :     rInfo.maPrinterName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
     409           0 :     rInfo.maDriver = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
     410           0 :     rInfo.maLocation = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
     411           0 :     rInfo.maComment = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStream, RTL_TEXTENCODING_UTF8);
     412             :     sal_uInt32 nTmp;
     413           0 :     rIStream.ReadUInt32( nTmp );
     414           0 :     rInfo.mnStatus = static_cast<PrintQueueFlags>(nTmp);
     415           0 :     rIStream.ReadUInt32( rInfo.mnJobs );
     416             : 
     417           0 :     return rIStream;
     418             : }
     419             : 
     420          48 : SalPrinterQueueInfo::SalPrinterQueueInfo()
     421             : {
     422          48 :     mnStatus    = PrintQueueFlags::NONE;
     423          48 :     mnJobs      = QUEUE_JOBS_DONTKNOW;
     424          48 :     mpSysData   = NULL;
     425          48 : }
     426             : 
     427          47 : SalPrinterQueueInfo::~SalPrinterQueueInfo()
     428             : {
     429          47 : }
     430             : 
     431          94 : ImplPrnQueueList::~ImplPrnQueueList()
     432             : {
     433          47 :     ImplSVData*         pSVData = ImplGetSVData();
     434          94 :     for( size_t i = 0; i < m_aQueueInfos.size(); i++ )
     435             :     {
     436          47 :         delete m_aQueueInfos[i].mpQueueInfo;
     437          47 :         pSVData->mpDefInst->DeletePrinterQueueInfo( m_aQueueInfos[i].mpSalQueueInfo );
     438             :     }
     439          47 : }
     440             : 
     441          48 : void ImplPrnQueueList::Add( SalPrinterQueueInfo* pData )
     442             : {
     443             :     std::unordered_map< OUString, sal_Int32, OUStringHash >::iterator it =
     444          48 :         m_aNameToIndex.find( pData->maPrinterName );
     445          48 :     if( it == m_aNameToIndex.end() )
     446             :     {
     447          48 :         m_aNameToIndex[ pData->maPrinterName ] = m_aQueueInfos.size();
     448          48 :         m_aQueueInfos.push_back( ImplPrnQueueData() );
     449          48 :         m_aQueueInfos.back().mpQueueInfo = NULL;
     450          48 :         m_aQueueInfos.back().mpSalQueueInfo = pData;
     451          48 :         m_aPrinterList.push_back( pData->maPrinterName );
     452             :     }
     453             :     else // this should not happen, but ...
     454             :     {
     455           0 :         ImplPrnQueueData& rData = m_aQueueInfos[ it->second ];
     456           0 :         delete rData.mpQueueInfo;
     457           0 :         rData.mpQueueInfo = NULL;
     458           0 :         ImplGetSVData()->mpDefInst->DeletePrinterQueueInfo( rData.mpSalQueueInfo );
     459           0 :         rData.mpSalQueueInfo = pData;
     460             :     }
     461          48 : }
     462             : 
     463         544 : ImplPrnQueueData* ImplPrnQueueList::Get( const OUString& rPrinter )
     464             : {
     465         544 :     ImplPrnQueueData* pData = NULL;
     466             :     std::unordered_map<OUString,sal_Int32,OUStringHash>::iterator it =
     467         544 :         m_aNameToIndex.find( rPrinter );
     468         544 :     if( it != m_aNameToIndex.end() )
     469         430 :         pData = &m_aQueueInfos[it->second];
     470         544 :     return pData;
     471             : }
     472             : 
     473          48 : static void ImplInitPrnQueueList()
     474             : {
     475          48 :     ImplSVData* pSVData = ImplGetSVData();
     476             : 
     477          48 :     pSVData->maGDIData.mpPrinterQueueList = new ImplPrnQueueList;
     478             : 
     479          48 :     static const char* pEnv = getenv( "SAL_DISABLE_PRINTERLIST" );
     480          48 :     if( !pEnv || !*pEnv )
     481          48 :         pSVData->mpDefInst->GetPrinterQueueInfo( pSVData->maGDIData.mpPrinterQueueList );
     482          48 : }
     483             : 
     484         242 : void ImplDeletePrnQueueList()
     485             : {
     486         242 :     ImplSVData*         pSVData = ImplGetSVData();
     487         242 :     ImplPrnQueueList*   pPrnList = pSVData->maGDIData.mpPrinterQueueList;
     488             : 
     489         242 :     if ( pPrnList )
     490             :     {
     491          47 :         delete pPrnList;
     492          47 :         pSVData->maGDIData.mpPrinterQueueList = NULL;
     493             :     }
     494         242 : }
     495             : 
     496           0 : const std::vector<OUString>& Printer::GetPrinterQueues()
     497             : {
     498           0 :     ImplSVData* pSVData = ImplGetSVData();
     499           0 :     if ( !pSVData->maGDIData.mpPrinterQueueList )
     500           0 :         ImplInitPrnQueueList();
     501           0 :     return pSVData->maGDIData.mpPrinterQueueList->m_aPrinterList;
     502             : }
     503             : 
     504           0 : const QueueInfo* Printer::GetQueueInfo( const OUString& rPrinterName, bool bStatusUpdate )
     505             : {
     506           0 :     ImplSVData* pSVData = ImplGetSVData();
     507             : 
     508           0 :     if ( !pSVData->maGDIData.mpPrinterQueueList )
     509           0 :         ImplInitPrnQueueList();
     510             : 
     511           0 :     if ( !pSVData->maGDIData.mpPrinterQueueList )
     512           0 :         return NULL;
     513             : 
     514           0 :     ImplPrnQueueData* pInfo = pSVData->maGDIData.mpPrinterQueueList->Get( rPrinterName );
     515           0 :     if( pInfo )
     516             :     {
     517           0 :         if( !pInfo->mpQueueInfo || bStatusUpdate )
     518           0 :             pSVData->mpDefInst->GetPrinterQueueState( pInfo->mpSalQueueInfo );
     519             : 
     520           0 :         if ( !pInfo->mpQueueInfo )
     521           0 :             pInfo->mpQueueInfo = new QueueInfo;
     522             : 
     523           0 :         pInfo->mpQueueInfo->maPrinterName   = pInfo->mpSalQueueInfo->maPrinterName;
     524           0 :         pInfo->mpQueueInfo->maDriver        = pInfo->mpSalQueueInfo->maDriver;
     525           0 :         pInfo->mpQueueInfo->maLocation      = pInfo->mpSalQueueInfo->maLocation;
     526           0 :         pInfo->mpQueueInfo->maComment       = pInfo->mpSalQueueInfo->maComment;
     527           0 :         pInfo->mpQueueInfo->mnStatus        = pInfo->mpSalQueueInfo->mnStatus;
     528           0 :         pInfo->mpQueueInfo->mnJobs          = pInfo->mpSalQueueInfo->mnJobs;
     529           0 :         return pInfo->mpQueueInfo;
     530             :     }
     531           0 :     return NULL;
     532             : }
     533             : 
     534        2038 : OUString Printer::GetDefaultPrinterName()
     535             : {
     536        2038 :     static const char* pEnv = getenv( "SAL_DISABLE_DEFAULTPRINTER" );
     537        2038 :     if( !pEnv || !*pEnv )
     538             :     {
     539        2038 :         ImplSVData* pSVData = ImplGetSVData();
     540             : 
     541        2038 :         return pSVData->mpDefInst->GetDefaultPrinter();
     542             :     }
     543           0 :     return OUString();
     544             : }
     545             : 
     546         430 : void Printer::ImplInitData()
     547             : {
     548         430 :     mbDevOutput         = false;
     549         430 :     meOutDevType        = OUTDEV_PRINTER;
     550         430 :     mbDefPrinter        = false;
     551         430 :     mnError             = 0;
     552         430 :     mnCurPage           = 0;
     553         430 :     mnCurPrintPage      = 0;
     554         430 :     mnPageQueueSize     = 0;
     555         430 :     mnCopyCount         = 1;
     556         430 :     mbCollateCopy       = false;
     557         430 :     mbPrinting          = false;
     558         430 :     mbJobActive         = false;
     559         430 :     mbPrintFile         = false;
     560         430 :     mbInPrintPage       = false;
     561         430 :     mbNewJobSetup       = false;
     562         430 :     mpInfoPrinter       = NULL;
     563         430 :     mpPrinter           = NULL;
     564         430 :     mpDisplayDev        = NULL;
     565         430 :     mbIsQueuePrinter    = false;
     566         430 :     mpPrinterOptions    = new PrinterOptions;
     567             : 
     568             :     // Add printer to the list
     569         430 :     ImplSVData* pSVData = ImplGetSVData();
     570         430 :     mpNext = pSVData->maGDIData.mpFirstPrinter;
     571         430 :     mpPrev = NULL;
     572         430 :     if ( mpNext )
     573         217 :         mpNext->mpPrev = this;
     574             :     else
     575         213 :         pSVData->maGDIData.mpLastPrinter = this;
     576         430 :     pSVData->maGDIData.mpFirstPrinter = this;
     577         430 : }
     578             : 
     579        1120 : bool Printer::AcquireGraphics() const
     580             : {
     581             :     DBG_TESTSOLARMUTEX();
     582             : 
     583        1120 :     if ( mpGraphics )
     584         625 :         return true;
     585             : 
     586         495 :     mbInitLineColor     = true;
     587         495 :     mbInitFillColor     = true;
     588         495 :     mbInitFont          = true;
     589         495 :     mbInitTextColor     = true;
     590         495 :     mbInitClipRegion    = true;
     591             : 
     592         495 :     ImplSVData* pSVData = ImplGetSVData();
     593             : 
     594         495 :     if ( mpJobGraphics )
     595           0 :         mpGraphics = mpJobGraphics;
     596         495 :     else if ( mpDisplayDev )
     597             :     {
     598           0 :         const VirtualDevice* pVirDev = mpDisplayDev;
     599           0 :         mpGraphics = pVirDev->mpVirDev->AcquireGraphics();
     600             :         // if needed retry after releasing least recently used virtual device graphics
     601           0 :         while ( !mpGraphics )
     602             :         {
     603           0 :             if ( !pSVData->maGDIData.mpLastVirGraphics )
     604           0 :                 break;
     605           0 :             pSVData->maGDIData.mpLastVirGraphics->ReleaseGraphics();
     606           0 :             mpGraphics = pVirDev->mpVirDev->AcquireGraphics();
     607             :         }
     608             :         // update global LRU list of virtual device graphics
     609           0 :         if ( mpGraphics )
     610             :         {
     611           0 :             mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
     612           0 :             pSVData->maGDIData.mpFirstVirGraphics = const_cast<Printer*>(this);
     613           0 :             if ( mpNextGraphics )
     614           0 :                 mpNextGraphics->mpPrevGraphics = const_cast<Printer*>(this);
     615           0 :             if ( !pSVData->maGDIData.mpLastVirGraphics )
     616           0 :                 pSVData->maGDIData.mpLastVirGraphics = const_cast<Printer*>(this);
     617             :         }
     618             :     }
     619             :     else
     620             :     {
     621         495 :         mpGraphics = mpInfoPrinter->AcquireGraphics();
     622             :         // if needed retry after releasing least recently used printer graphics
     623         990 :         while ( !mpGraphics )
     624             :         {
     625           0 :             if ( !pSVData->maGDIData.mpLastPrnGraphics )
     626           0 :                 break;
     627           0 :             pSVData->maGDIData.mpLastPrnGraphics->ReleaseGraphics();
     628           0 :             mpGraphics = mpInfoPrinter->AcquireGraphics();
     629             :         }
     630             :         // update global LRU list of printer graphics
     631         495 :         if ( mpGraphics )
     632             :         {
     633         495 :             mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
     634         495 :             pSVData->maGDIData.mpFirstPrnGraphics = const_cast<Printer*>(this);
     635         495 :             if ( mpNextGraphics )
     636         260 :                 mpNextGraphics->mpPrevGraphics = const_cast<Printer*>(this);
     637         495 :             if ( !pSVData->maGDIData.mpLastPrnGraphics )
     638         235 :                 pSVData->maGDIData.mpLastPrnGraphics = const_cast<Printer*>(this);
     639             :         }
     640             :     }
     641             : 
     642         495 :     if ( mpGraphics )
     643             :     {
     644         495 :         mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
     645         495 :         mpGraphics->setAntiAliasB2DDraw(bool(mnAntialiasing & AntialiasingFlags::EnableB2dDraw));
     646             :     }
     647             : 
     648         495 :     return mpGraphics != nullptr;
     649             : }
     650             : 
     651         489 : void Printer::ImplReleaseFonts()
     652             : {
     653             : #ifdef UNX
     654             :     // HACK to fix an urgent P1 printing issue fast
     655             :     // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions
     656             :     // so Printer::mpGraphics often points to a dead WinSalGraphics
     657             :     // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling
     658         489 :     mpGraphics->ReleaseFonts();
     659             : #endif
     660         489 :     mbNewFont = true;
     661         489 :     mbInitFont = true;
     662             : 
     663         489 :     if ( mpFontEntry )
     664             :     {
     665         205 :         mpFontCache->Release( mpFontEntry );
     666         205 :         mpFontEntry = NULL;
     667             :     }
     668             : 
     669         489 :     if ( mpGetDevFontList )
     670             :     {
     671          35 :         delete mpGetDevFontList;
     672          35 :         mpGetDevFontList = NULL;
     673             :     }
     674             : 
     675         489 :     if ( mpGetDevSizeList )
     676             :     {
     677           0 :         delete mpGetDevSizeList;
     678           0 :         mpGetDevSizeList = NULL;
     679             :     }
     680         489 : }
     681             : 
     682         489 : void Printer::ReleaseGraphics( bool bRelease )
     683             : {
     684             :     DBG_TESTSOLARMUTEX();
     685             : 
     686         489 :     if ( !mpGraphics )
     687         489 :         return;
     688             : 
     689             :     // release the fonts of the physically released graphics device
     690         489 :     if( bRelease )
     691         489 :         ImplReleaseFonts();
     692             : 
     693         489 :     ImplSVData* pSVData = ImplGetSVData();
     694             : 
     695         489 :     Printer* pPrinter = this;
     696             : 
     697         489 :     if ( !pPrinter->mpJobGraphics )
     698             :     {
     699         489 :         if ( pPrinter->mpDisplayDev )
     700             :         {
     701           0 :             VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
     702           0 :             if ( bRelease )
     703           0 :                 pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
     704             :             // remove from global LRU list of virtual device graphics
     705           0 :             if ( mpPrevGraphics )
     706           0 :                 mpPrevGraphics->mpNextGraphics = mpNextGraphics;
     707             :             else
     708           0 :                 pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
     709           0 :             if ( mpNextGraphics )
     710           0 :                 mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
     711             :             else
     712           0 :                 pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
     713             :         }
     714             :         else
     715             :         {
     716         489 :             if ( bRelease )
     717         489 :                 pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
     718             :             // remove from global LRU list of printer graphics
     719         489 :             if ( mpPrevGraphics )
     720          25 :                 mpPrevGraphics->mpNextGraphics = mpNextGraphics;
     721             :             else
     722         464 :                 pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
     723         489 :             if ( mpNextGraphics )
     724         237 :                 mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
     725             :             else
     726         252 :                 pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
     727             :         }
     728             :     }
     729             : 
     730         489 :     mpGraphics      = NULL;
     731         489 :     mpPrevGraphics  = NULL;
     732         489 :     mpNextGraphics  = NULL;
     733             : }
     734             : 
     735         430 : void Printer::ImplInit( SalPrinterQueueInfo* pInfo )
     736             : {
     737         430 :     ImplSVData* pSVData = ImplGetSVData();
     738             :     // #i74084# update info for this specific SalPrinterQueueInfo
     739         430 :     pSVData->mpDefInst->GetPrinterQueueState( pInfo );
     740             : 
     741             :     // Test whether the driver actually matches the JobSetup
     742         430 :     ImplJobSetup* pJobSetup = maJobSetup.ImplGetData();
     743             : 
     744         430 :     if ( pJobSetup->mpDriverData )
     745             :     {
     746           0 :         if ( (pJobSetup->maPrinterName != pInfo->maPrinterName) ||
     747           0 :              (pJobSetup->maDriver != pInfo->maDriver) )
     748             :         {
     749           0 :             rtl_freeMemory( pJobSetup->mpDriverData );
     750           0 :             pJobSetup->mpDriverData = NULL;
     751           0 :             pJobSetup->mnDriverDataLen = 0;
     752             :         }
     753             :     }
     754             : 
     755             :     // Remember printer name
     756         430 :     maPrinterName = pInfo->maPrinterName;
     757         430 :     maDriver = pInfo->maDriver;
     758             : 
     759             :     // Add printer name to JobSetup
     760         430 :     pJobSetup->maPrinterName = maPrinterName;
     761         430 :     pJobSetup->maDriver = maDriver;
     762             : 
     763         430 :     mpInfoPrinter   = pSVData->mpDefInst->CreateInfoPrinter( pInfo, pJobSetup );
     764         430 :     mpPrinter       = NULL;
     765         430 :     mpJobGraphics   = NULL;
     766         430 :     ImplUpdateJobSetupPaper( maJobSetup );
     767             : 
     768         430 :     if ( !mpInfoPrinter )
     769             :     {
     770           0 :         ImplInitDisplay( NULL );
     771           0 :         return;
     772             :     }
     773             : 
     774             :     // we need a graphics
     775         430 :     if ( !AcquireGraphics() )
     776             :     {
     777           0 :         ImplInitDisplay( NULL );
     778           0 :         return;
     779             :     }
     780             : 
     781             :     // Init data
     782         430 :     ImplUpdatePageData();
     783         430 :     mpFontCollection = new PhysicalFontCollection();
     784         430 :     mpFontCache = new ImplFontCache();
     785         430 :     mpGraphics->GetDevFontList( mpFontCollection );
     786             : }
     787             : 
     788           0 : void Printer::ImplInitDisplay( const vcl::Window* pWindow )
     789             : {
     790           0 :     ImplSVData* pSVData = ImplGetSVData();
     791             : 
     792           0 :     mpInfoPrinter       = NULL;
     793           0 :     mpPrinter           = NULL;
     794           0 :     mpJobGraphics       = NULL;
     795             : 
     796           0 :     if ( pWindow )
     797           0 :         mpDisplayDev = VclPtr<VirtualDevice>::Create( *pWindow );
     798             :     else
     799           0 :         mpDisplayDev = VclPtr<VirtualDevice>::Create();
     800           0 :     mpFontCollection          = pSVData->maGDIData.mpScreenFontList;
     801           0 :     mpFontCache         = pSVData->maGDIData.mpScreenFontCache;
     802           0 :     mnDPIX              = mpDisplayDev->mnDPIX;
     803           0 :     mnDPIY              = mpDisplayDev->mnDPIY;
     804           0 : }
     805             : 
     806           0 : void Printer::DrawDeviceMask( const Bitmap& rMask, const Color& rMaskColor,
     807             :                          const Point& rDestPt, const Size& rDestSize,
     808             :                          const Point& rSrcPtPixel, const Size& rSrcSizePixel )
     809             : {
     810           0 :     Point       aPt;
     811           0 :     Point       aDestPt( LogicToPixel( rDestPt ) );
     812           0 :     Size        aDestSz( LogicToPixel( rDestSize ) );
     813           0 :     Rectangle   aSrcRect( rSrcPtPixel, rSrcSizePixel );
     814             : 
     815           0 :     aSrcRect.Justify();
     816             : 
     817           0 :     if( !rMask.IsEmpty() && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
     818             :     {
     819           0 :         Bitmap  aMask( rMask );
     820           0 :         BmpMirrorFlags nMirrFlags = BmpMirrorFlags::NONE;
     821             : 
     822           0 :         if( aMask.GetBitCount() > 1 )
     823           0 :             aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
     824             : 
     825             :         // mirrored horizontically
     826           0 :         if( aDestSz.Width() < 0L )
     827             :         {
     828           0 :             aDestSz.Width() = -aDestSz.Width();
     829           0 :             aDestPt.X() -= ( aDestSz.Width() - 1L );
     830           0 :             nMirrFlags |= BmpMirrorFlags::Horizontal;
     831             :         }
     832             : 
     833             :         // mirrored vertically
     834           0 :         if( aDestSz.Height() < 0L )
     835             :         {
     836           0 :             aDestSz.Height() = -aDestSz.Height();
     837           0 :             aDestPt.Y() -= ( aDestSz.Height() - 1L );
     838           0 :             nMirrFlags |= BmpMirrorFlags::Vertical;
     839             :         }
     840             : 
     841             :         // source cropped?
     842           0 :         if( aSrcRect != Rectangle( aPt, aMask.GetSizePixel() ) )
     843           0 :             aMask.Crop( aSrcRect );
     844             : 
     845             :         // destination mirrored
     846           0 :         if( nMirrFlags != BmpMirrorFlags::NONE)
     847           0 :             aMask.Mirror( nMirrFlags );
     848             : 
     849             :         // do painting
     850           0 :         const long      nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
     851             :         long            nX, nY; //, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
     852           0 :         long*           pMapX = new long[ nSrcWidth + 1 ];
     853           0 :         long*           pMapY = new long[ nSrcHeight + 1 ];
     854           0 :         GDIMetaFile*    pOldMetaFile = mpMetaFile;
     855           0 :         const bool      bOldMap = mbMap;
     856             : 
     857           0 :         mpMetaFile = NULL;
     858           0 :         mbMap = false;
     859           0 :         Push( PushFlags::FILLCOLOR | PushFlags::LINECOLOR );
     860           0 :         SetLineColor( rMaskColor );
     861           0 :         SetFillColor( rMaskColor );
     862           0 :         InitLineColor();
     863           0 :         InitFillColor();
     864             : 
     865             :         // create forward mapping tables
     866           0 :         for( nX = 0L; nX <= nSrcWidth; nX++ )
     867           0 :             pMapX[ nX ] = aDestPt.X() + FRound( (double) aDestSz.Width() * nX / nSrcWidth );
     868             : 
     869           0 :         for( nY = 0L; nY <= nSrcHeight; nY++ )
     870           0 :             pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
     871             : 
     872             :         // walk through all rectangles of mask
     873           0 :         const vcl::Region aWorkRgn(aMask.CreateRegion(COL_BLACK, Rectangle(Point(), aMask.GetSizePixel())));
     874           0 :         RectangleVector aRectangles;
     875           0 :         aWorkRgn.GetRegionRectangles(aRectangles);
     876             : 
     877           0 :         for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     878             :         {
     879           0 :             const Point aMapPt(pMapX[aRectIter->Left()], pMapY[aRectIter->Top()]);
     880             :             const Size aMapSz(
     881           0 :                 pMapX[aRectIter->Right() + 1] - aMapPt.X(),      // pMapX[L + W] -> L + ((R - L) + 1) -> R + 1
     882           0 :                 pMapY[aRectIter->Bottom() + 1] - aMapPt.Y());    // same for Y
     883             : 
     884           0 :             DrawRect(Rectangle(aMapPt, aMapSz));
     885             :         }
     886             : 
     887           0 :         Pop();
     888           0 :         delete[] pMapX;
     889           0 :         delete[] pMapY;
     890           0 :         mbMap = bOldMap;
     891           0 :         mpMetaFile = pOldMetaFile;
     892             :     }
     893           0 : }
     894             : 
     895         430 : SalPrinterQueueInfo* Printer::ImplGetQueueInfo( const OUString& rPrinterName,
     896             :                                                 const OUString* pDriver )
     897             : {
     898         430 :     ImplSVData* pSVData = ImplGetSVData();
     899         430 :     if ( !pSVData->maGDIData.mpPrinterQueueList )
     900          48 :         ImplInitPrnQueueList();
     901             : 
     902         430 :     ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
     903         430 :     if ( pPrnList && pPrnList->m_aQueueInfos.size() )
     904             :     {
     905             :         // first search for the printer name directly
     906         430 :         ImplPrnQueueData* pInfo = pPrnList->Get( rPrinterName );
     907         430 :         if( pInfo )
     908         316 :             return pInfo->mpSalQueueInfo;
     909             : 
     910             :         // then search case insensitive
     911         228 :         for( size_t i = 0; i < pPrnList->m_aQueueInfos.size(); i++ )
     912             :         {
     913         114 :             if( pPrnList->m_aQueueInfos[i].mpSalQueueInfo->maPrinterName.equalsIgnoreAsciiCase( rPrinterName ) )
     914           0 :                 return pPrnList->m_aQueueInfos[i].mpSalQueueInfo;
     915             :         }
     916             : 
     917             :         // then search for driver name
     918         114 :         if ( pDriver )
     919             :         {
     920           0 :             for( size_t i = 0; i < pPrnList->m_aQueueInfos.size(); i++ )
     921             :             {
     922           0 :                 if( pPrnList->m_aQueueInfos[i].mpSalQueueInfo->maDriver == *pDriver )
     923           0 :                     return pPrnList->m_aQueueInfos[i].mpSalQueueInfo;
     924             :             }
     925             :         }
     926             : 
     927             :         // then the default printer
     928         114 :         pInfo = pPrnList->Get( GetDefaultPrinterName() );
     929         114 :         if( pInfo )
     930         114 :             return pInfo->mpSalQueueInfo;
     931             : 
     932             :         // last chance: the first available printer
     933           0 :         return pPrnList->m_aQueueInfos[0].mpSalQueueInfo;
     934             :     }
     935             : 
     936           0 :     return NULL;
     937             : }
     938             : 
     939         495 : void Printer::ImplUpdatePageData()
     940             : {
     941             :     // we need a graphics
     942         495 :     if ( !AcquireGraphics() )
     943         495 :         return;
     944             : 
     945         495 :     mpGraphics->GetResolution( mnDPIX, mnDPIY );
     946         495 :     mpInfoPrinter->GetPageInfo( maJobSetup.ImplGetConstData(),
     947             :                                 mnOutWidth, mnOutHeight,
     948         495 :                                 maPageOffset.X(), maPageOffset.Y(),
     949        1485 :                                 maPaperSize.Width(), maPaperSize.Height() );
     950             : }
     951             : 
     952          65 : void Printer::ImplUpdateFontList()
     953             : {
     954          65 :     ImplUpdateFontData( true );
     955          65 : }
     956             : 
     957           0 : long Printer::GetGradientStepCount( long nMinRect )
     958             : {
     959             :     // use display-equivalent step size calculation
     960           0 :     long nInc = (nMinRect < 800) ? 10 : 20;
     961             : 
     962           0 :     return nInc;
     963             : }
     964             : 
     965         251 : Printer::Printer()
     966             : {
     967         251 :     ImplInitData();
     968         251 :     SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( GetDefaultPrinterName(), NULL );
     969         251 :     if ( pInfo )
     970             :     {
     971         251 :         ImplInit( pInfo );
     972         251 :         if ( !IsDisplayPrinter() )
     973         251 :             mbDefPrinter = true;
     974             :     }
     975             :     else
     976           0 :         ImplInitDisplay( NULL );
     977         251 : }
     978             : 
     979           0 : Printer::Printer( const JobSetup& rJobSetup ) :
     980           0 :     maJobSetup( rJobSetup )
     981             : {
     982           0 :     ImplInitData();
     983             :     SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rJobSetup.mpData->maPrinterName,
     984           0 :                                                    &rJobSetup.mpData->maDriver );
     985           0 :     if ( pInfo )
     986             :     {
     987           0 :         ImplInit( pInfo );
     988           0 :         SetJobSetup( rJobSetup );
     989             :     }
     990             :     else
     991             :     {
     992           0 :         ImplInitDisplay( NULL );
     993           0 :         maJobSetup = JobSetup();
     994             :     }
     995           0 : }
     996             : 
     997           0 : Printer::Printer( const QueueInfo& rQueueInfo )
     998             : {
     999           0 :     ImplInitData();
    1000           0 :     SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rQueueInfo.GetPrinterName(),
    1001           0 :                                                    &rQueueInfo.GetDriver() );
    1002           0 :     if ( pInfo )
    1003           0 :         ImplInit( pInfo );
    1004             :     else
    1005           0 :         ImplInitDisplay( NULL );
    1006           0 : }
    1007             : 
    1008         179 : Printer::Printer( const OUString& rPrinterName )
    1009             : {
    1010         179 :     ImplInitData();
    1011         179 :     SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rPrinterName, NULL );
    1012         179 :     if ( pInfo )
    1013         179 :         ImplInit( pInfo );
    1014             :     else
    1015           0 :         ImplInitDisplay( NULL );
    1016         179 : }
    1017             : 
    1018         875 : Printer::~Printer()
    1019             : {
    1020         424 :     disposeOnce();
    1021         451 : }
    1022             : 
    1023         424 : void Printer::dispose()
    1024             : {
    1025             :     DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
    1026             :     DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
    1027             : 
    1028         424 :     delete mpPrinterOptions;
    1029         424 :     mpPrinterOptions = NULL;
    1030             : 
    1031         424 :     ReleaseGraphics();
    1032         424 :     if ( mpInfoPrinter )
    1033         424 :         ImplGetSVData()->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
    1034         424 :     if ( mpDisplayDev )
    1035           0 :         mpDisplayDev.disposeAndClear();
    1036             :     else
    1037             :     {
    1038             :         // OutputDevice Dtor is tryig the same thing; that why we need to set
    1039             :         // the FontEntry to NULL here
    1040             :         // TODO: consolidate duplicate cleanup by Printer and OutputDevice
    1041         424 :         if ( mpFontEntry )
    1042             :         {
    1043           0 :             mpFontCache->Release( mpFontEntry );
    1044           0 :             mpFontEntry = NULL;
    1045             :         }
    1046         424 :         if ( mpGetDevFontList )
    1047             :         {
    1048           0 :             delete mpGetDevFontList;
    1049           0 :             mpGetDevFontList = NULL;
    1050             :         }
    1051         424 :         if ( mpGetDevSizeList )
    1052             :         {
    1053           0 :             delete mpGetDevSizeList;
    1054           0 :             mpGetDevSizeList = NULL;
    1055             :         }
    1056         424 :         delete mpFontCache;
    1057         424 :         mpFontCache = NULL;
    1058             :         // font list deleted by OutputDevice dtor
    1059             :     }
    1060             : 
    1061             :     // Add printer from the list
    1062         424 :     ImplSVData* pSVData = ImplGetSVData();
    1063         424 :     if ( mpPrev )
    1064          25 :         mpPrev->mpNext = mpNext;
    1065             :     else
    1066         399 :         pSVData->maGDIData.mpFirstPrinter = mpNext;
    1067         424 :     if ( mpNext )
    1068         194 :         mpNext->mpPrev = mpPrev;
    1069             :     else
    1070         230 :         pSVData->maGDIData.mpLastPrinter = mpPrev;
    1071             : 
    1072         424 :     mpPrev.clear();
    1073         424 :     mpNext.clear();
    1074         424 :     OutputDevice::dispose();
    1075         424 : }
    1076             : 
    1077           0 : sal_uLong Printer::GetCapabilities( PrinterCapType nType ) const
    1078             : {
    1079           0 :     if ( IsDisplayPrinter() )
    1080           0 :         return 0;
    1081             : 
    1082           0 :     if( mpInfoPrinter )
    1083           0 :         return mpInfoPrinter->GetCapabilities( maJobSetup.ImplGetConstData(), nType );
    1084             :     else
    1085           0 :         return 0;
    1086             : }
    1087             : 
    1088           0 : bool Printer::HasSupport( PrinterSupport eFeature ) const
    1089             : {
    1090           0 :     switch ( eFeature )
    1091             :     {
    1092             :         case SUPPORT_SET_ORIENTATION:
    1093           0 :             return GetCapabilities( PrinterCapType::SetOrientation ) != 0;
    1094             :         case SUPPORT_SET_PAPERBIN:
    1095           0 :             return GetCapabilities( PrinterCapType::SetPaperBin ) != 0;
    1096             :         case SUPPORT_SET_PAPERSIZE:
    1097           0 :             return GetCapabilities( PrinterCapType::SetPaperSize ) != 0;
    1098             :         case SUPPORT_SET_PAPER:
    1099           0 :             return GetCapabilities( PrinterCapType::SetPaper ) != 0;
    1100             :         case SUPPORT_COPY:
    1101           0 :             return (GetCapabilities( PrinterCapType::Copies ) != 0);
    1102             :         case SUPPORT_COLLATECOPY:
    1103           0 :             return (GetCapabilities( PrinterCapType::CollateCopies ) != 0);
    1104             :         case SUPPORT_SETUPDIALOG:
    1105           0 :             return GetCapabilities( PrinterCapType::SupportDialog ) != 0;
    1106             :         case SUPPORT_FAX:
    1107           0 :             return GetCapabilities( PrinterCapType::Fax ) != 0;
    1108             :         case SUPPORT_PDF:
    1109           0 :             return GetCapabilities( PrinterCapType::PDF ) != 0;
    1110             :     }
    1111             : 
    1112           0 :     return true;
    1113             : }
    1114             : 
    1115          65 : bool Printer::SetJobSetup( const JobSetup& rSetup )
    1116             : {
    1117          65 :     if ( IsDisplayPrinter() || mbInPrintPage )
    1118           0 :         return false;
    1119             : 
    1120          65 :     JobSetup aJobSetup = rSetup;
    1121             : 
    1122          65 :     ReleaseGraphics();
    1123          65 :     if ( mpInfoPrinter->SetPrinterData( aJobSetup.ImplGetData() ) )
    1124             :     {
    1125          65 :         ImplUpdateJobSetupPaper( aJobSetup );
    1126          65 :         mbNewJobSetup = true;
    1127          65 :         maJobSetup = aJobSetup;
    1128          65 :         ImplUpdatePageData();
    1129          65 :         ImplUpdateFontList();
    1130          65 :         return true;
    1131             :     }
    1132             : 
    1133           0 :     return false;
    1134             : }
    1135             : 
    1136           0 : bool Printer::Setup( vcl::Window* pWindow )
    1137             : {
    1138           0 :     if ( IsDisplayPrinter() )
    1139           0 :         return false;
    1140             : 
    1141           0 :     if ( IsJobActive() || IsPrinting() )
    1142           0 :         return false;
    1143             : 
    1144           0 :     JobSetup aJobSetup = maJobSetup;
    1145             :     SalFrame* pFrame;
    1146           0 :     if ( !pWindow )
    1147           0 :         pWindow = ImplGetDefaultWindow();
    1148           0 :     if( !pWindow )
    1149           0 :         return false;
    1150             : 
    1151           0 :     pFrame = pWindow->ImplGetFrame();
    1152           0 :     ReleaseGraphics();
    1153           0 :     ImplSVData* pSVData = ImplGetSVData();
    1154           0 :     pSVData->maAppData.mnModalMode++;
    1155           0 :     nImplSysDialog++;
    1156           0 :     bool bSetup = mpInfoPrinter->Setup( pFrame, aJobSetup.ImplGetData() );
    1157           0 :     pSVData->maAppData.mnModalMode--;
    1158           0 :     nImplSysDialog--;
    1159           0 :     if ( bSetup )
    1160             :     {
    1161           0 :         ImplUpdateJobSetupPaper( aJobSetup );
    1162           0 :         mbNewJobSetup = true;
    1163           0 :         maJobSetup = aJobSetup;
    1164           0 :         ImplUpdatePageData();
    1165           0 :         ImplUpdateFontList();
    1166           0 :         return true;
    1167             :     }
    1168           0 :     return false;
    1169             : }
    1170             : 
    1171           0 : bool Printer::SetPrinterProps( const Printer* pPrinter )
    1172             : {
    1173           0 :     if ( IsJobActive() || IsPrinting() )
    1174           0 :         return false;
    1175             : 
    1176           0 :     ImplSVData* pSVData = ImplGetSVData();
    1177             : 
    1178           0 :     mbDefPrinter        = pPrinter->mbDefPrinter;
    1179           0 :     maPrintFile         = pPrinter->maPrintFile;
    1180           0 :     mbPrintFile         = pPrinter->mbPrintFile;
    1181           0 :     mnCopyCount         = pPrinter->mnCopyCount;
    1182           0 :     mbCollateCopy       = pPrinter->mbCollateCopy;
    1183           0 :     mnPageQueueSize     = pPrinter->mnPageQueueSize;
    1184           0 :     *mpPrinterOptions   = *pPrinter->mpPrinterOptions;
    1185             : 
    1186           0 :     if ( pPrinter->IsDisplayPrinter() )
    1187             :     {
    1188             :         // Destroy old printer
    1189           0 :         if ( !IsDisplayPrinter() )
    1190             :         {
    1191           0 :             ReleaseGraphics();
    1192           0 :             pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
    1193           0 :             if ( mpFontEntry )
    1194             :             {
    1195           0 :                 mpFontCache->Release( mpFontEntry );
    1196           0 :                 mpFontEntry = NULL;
    1197             :             }
    1198           0 :             if ( mpGetDevFontList )
    1199             :             {
    1200           0 :                 delete mpGetDevFontList;
    1201           0 :                 mpGetDevFontList = NULL;
    1202             :             }
    1203           0 :             if ( mpGetDevSizeList )
    1204             :             {
    1205           0 :                 delete mpGetDevSizeList;
    1206           0 :                 mpGetDevSizeList = NULL;
    1207             :             }
    1208             :             // clean up font list
    1209           0 :             delete mpFontCache;
    1210           0 :             delete mpFontCollection;
    1211           0 :             mpFontCache = NULL;
    1212           0 :             mpFontCollection = NULL;
    1213             : 
    1214           0 :             mbInitFont = true;
    1215           0 :             mbNewFont = true;
    1216           0 :             mpInfoPrinter = NULL;
    1217             :         }
    1218             : 
    1219             :         // Construct new printer
    1220           0 :         ImplInitDisplay( NULL );
    1221           0 :         return true;
    1222             :     }
    1223             : 
    1224             :     // Destroy old printer?
    1225           0 :     if ( GetName() != pPrinter->GetName() )
    1226             :     {
    1227           0 :         ReleaseGraphics();
    1228           0 :         if ( mpDisplayDev )
    1229             :         {
    1230           0 :             mpDisplayDev.disposeAndClear();
    1231             :         }
    1232             :         else
    1233             :         {
    1234           0 :             pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
    1235             : 
    1236           0 :             if ( mpFontEntry )
    1237             :             {
    1238           0 :                 mpFontCache->Release( mpFontEntry );
    1239           0 :                 mpFontEntry = NULL;
    1240             :             }
    1241           0 :             if ( mpGetDevFontList )
    1242             :             {
    1243           0 :                 delete mpGetDevFontList;
    1244           0 :                 mpGetDevFontList = NULL;
    1245             :             }
    1246           0 :             if ( mpGetDevSizeList )
    1247             :             {
    1248           0 :                 delete mpGetDevSizeList;
    1249           0 :                 mpGetDevSizeList = NULL;
    1250             :             }
    1251           0 :             delete mpFontCache;
    1252           0 :             delete mpFontCollection;
    1253           0 :             mpFontCache = NULL;
    1254           0 :             mpFontCollection = NULL;
    1255           0 :             mbInitFont = true;
    1256           0 :             mbNewFont = true;
    1257           0 :             mpInfoPrinter = NULL;
    1258             :         }
    1259             : 
    1260             :         // Construct new printer
    1261           0 :         OUString aDriver = pPrinter->GetDriverName();
    1262           0 :         SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( pPrinter->GetName(), &aDriver );
    1263           0 :         if ( pInfo )
    1264             :         {
    1265           0 :             ImplInit( pInfo );
    1266           0 :             SetJobSetup( pPrinter->GetJobSetup() );
    1267             :         }
    1268             :         else
    1269           0 :             ImplInitDisplay( NULL );
    1270             :     }
    1271             :     else
    1272           0 :         SetJobSetup( pPrinter->GetJobSetup() );
    1273             : 
    1274           0 :     return false;
    1275             : }
    1276             : 
    1277           0 : bool Printer::SetOrientation( Orientation eOrientation )
    1278             : {
    1279           0 :     if ( mbInPrintPage )
    1280           0 :         return false;
    1281             : 
    1282           0 :     if ( maJobSetup.ImplGetConstData()->meOrientation != eOrientation )
    1283             :     {
    1284           0 :         JobSetup        aJobSetup = maJobSetup;
    1285           0 :         ImplJobSetup*   pSetupData = aJobSetup.ImplGetData();
    1286           0 :         pSetupData->meOrientation = eOrientation;
    1287             : 
    1288           0 :         if ( IsDisplayPrinter() )
    1289             :         {
    1290           0 :             mbNewJobSetup = true;
    1291           0 :             maJobSetup = aJobSetup;
    1292           0 :             return true;
    1293             :         }
    1294             : 
    1295           0 :         ReleaseGraphics();
    1296           0 :         if ( mpInfoPrinter->SetData( SAL_JOBSET_ORIENTATION, pSetupData ) )
    1297             :         {
    1298           0 :             ImplUpdateJobSetupPaper( aJobSetup );
    1299           0 :             mbNewJobSetup = true;
    1300           0 :             maJobSetup = aJobSetup;
    1301           0 :             ImplUpdatePageData();
    1302           0 :             ImplUpdateFontList();
    1303           0 :             return true;
    1304             :         }
    1305             :         else
    1306           0 :             return false;
    1307             :     }
    1308             : 
    1309           0 :     return true;
    1310             : }
    1311             : 
    1312         238 : Orientation Printer::GetOrientation() const
    1313             : {
    1314         238 :     return maJobSetup.ImplGetConstData()->meOrientation;
    1315             : }
    1316             : 
    1317           0 : bool Printer::SetPaperBin( sal_uInt16 nPaperBin )
    1318             : {
    1319           0 :     if ( mbInPrintPage )
    1320           0 :         return false;
    1321             : 
    1322           0 :     if ( (maJobSetup.ImplGetConstData()->mnPaperBin != nPaperBin) &&
    1323           0 :          (nPaperBin < GetPaperBinCount()) )
    1324             :     {
    1325           0 :         JobSetup        aJobSetup = maJobSetup;
    1326           0 :         ImplJobSetup*   pSetupData = aJobSetup.ImplGetData();
    1327           0 :         pSetupData->mnPaperBin = nPaperBin;
    1328             : 
    1329           0 :         if ( IsDisplayPrinter() )
    1330             :         {
    1331           0 :             mbNewJobSetup = true;
    1332           0 :             maJobSetup = aJobSetup;
    1333           0 :             return true;
    1334             :         }
    1335             : 
    1336           0 :         ReleaseGraphics();
    1337           0 :         if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERBIN, pSetupData ) )
    1338             :         {
    1339           0 :             ImplUpdateJobSetupPaper( aJobSetup );
    1340           0 :             mbNewJobSetup = true;
    1341           0 :             maJobSetup = aJobSetup;
    1342           0 :             ImplUpdatePageData();
    1343           0 :             ImplUpdateFontList();
    1344           0 :             return true;
    1345             :         }
    1346             :         else
    1347           0 :             return false;
    1348             :     }
    1349             : 
    1350           0 :     return true;
    1351             : }
    1352             : 
    1353           0 : sal_uInt16 Printer::GetPaperBin() const
    1354             : {
    1355           0 :     return maJobSetup.ImplGetConstData()->mnPaperBin;
    1356             : }
    1357             : 
    1358             : // Map user paper format to a available printer paper formats
    1359           0 : void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup, bool bMatchNearest )
    1360             : {
    1361           0 :     ImplJobSetup*   pSetupData = aJobSetup.ImplGetData();
    1362             : 
    1363           0 :     int     nLandscapeAngle = GetLandscapeAngle();
    1364           0 :     int     nPaperCount     = GetPaperInfoCount();
    1365           0 :     bool    bFound = false;
    1366             : 
    1367           0 :     PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight);
    1368             : 
    1369             :     // Compare all paper formats and get the appropriate one
    1370           0 :     for ( int i = 0; i < nPaperCount; i++ )
    1371             :     {
    1372           0 :         const PaperInfo& rPaperInfo = GetPaperInfo( i );
    1373             : 
    1374           0 :         if ( aInfo.sloppyEqual(rPaperInfo) )
    1375             :         {
    1376             :             pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
    1377           0 :                                                             rPaperInfo.getHeight() );
    1378           0 :             pSetupData->meOrientation = ORIENTATION_PORTRAIT;
    1379           0 :             bFound = true;
    1380           0 :             break;
    1381             :         }
    1382             :     }
    1383             : 
    1384             :     // If the printer supports landscape orientation, check paper sizes again
    1385             :     // with landscape orientation. This is necessary as a printer driver provides
    1386             :     // all paper sizes with portrait orientation only!!
    1387           0 :     if ( pSetupData->mePaperFormat == PAPER_USER &&
    1388           0 :          nLandscapeAngle != 0 &&
    1389           0 :          HasSupport( SUPPORT_SET_ORIENTATION ))
    1390             :     {
    1391           0 :         const long nRotatedWidth = pSetupData->mnPaperHeight;
    1392           0 :         const long nRotatedHeight = pSetupData->mnPaperWidth;
    1393           0 :         PaperInfo aRotatedInfo(nRotatedWidth, nRotatedHeight);
    1394             : 
    1395           0 :         for ( int i = 0; i < nPaperCount; i++ )
    1396             :         {
    1397           0 :             const PaperInfo& rPaperInfo = GetPaperInfo( i );
    1398             : 
    1399           0 :             if ( aRotatedInfo.sloppyEqual( rPaperInfo ) )
    1400             :             {
    1401             :                 pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
    1402           0 :                                                                 rPaperInfo.getHeight() );
    1403           0 :                 pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
    1404           0 :                 bFound = true;
    1405           0 :                 break;
    1406             :             }
    1407             :         }
    1408             :     }
    1409             : 
    1410           0 :     if( ! bFound && bMatchNearest )
    1411             :     {
    1412           0 :          sal_Int64 nBestMatch = SAL_MAX_INT64;
    1413           0 :          int nBestIndex = 0;
    1414           0 :          Orientation eBestOrientation = ORIENTATION_PORTRAIT;
    1415           0 :          for( int i = 0; i < nPaperCount; i++ )
    1416             :          {
    1417           0 :              const PaperInfo& rPaperInfo = GetPaperInfo( i );
    1418             : 
    1419             :              // check portrait match
    1420           0 :              sal_Int64 nDX = pSetupData->mnPaperWidth - rPaperInfo.getWidth();
    1421           0 :              sal_Int64 nDY = pSetupData->mnPaperHeight - rPaperInfo.getHeight();
    1422           0 :              sal_Int64 nMatch = nDX*nDX + nDY*nDY;
    1423           0 :              if( nMatch < nBestMatch )
    1424             :              {
    1425           0 :                  nBestMatch = nMatch;
    1426           0 :                  nBestIndex = i;
    1427           0 :                  eBestOrientation = ORIENTATION_PORTRAIT;
    1428             :              }
    1429             : 
    1430             :              // check landscape match
    1431           0 :              nDX = pSetupData->mnPaperWidth - rPaperInfo.getHeight();
    1432           0 :              nDY = pSetupData->mnPaperHeight - rPaperInfo.getWidth();
    1433           0 :              nMatch = nDX*nDX + nDY*nDY;
    1434           0 :              if( nMatch < nBestMatch )
    1435             :              {
    1436           0 :                  nBestMatch = nMatch;
    1437           0 :                  nBestIndex = i;
    1438           0 :                  eBestOrientation = ORIENTATION_LANDSCAPE;
    1439             :              }
    1440             :          }
    1441           0 :          const PaperInfo& rBestInfo = GetPaperInfo( nBestIndex );
    1442             :          pSetupData->mePaperFormat = ImplGetPaperFormat( rBestInfo.getWidth(),
    1443           0 :                                                          rBestInfo.getHeight() );
    1444           0 :          pSetupData->meOrientation = eBestOrientation;
    1445             :     }
    1446           0 : }
    1447             : 
    1448           0 : bool Printer::SetPaper( Paper ePaper )
    1449             : {
    1450           0 :     if ( mbInPrintPage )
    1451           0 :         return false;
    1452             : 
    1453           0 :     if ( maJobSetup.ImplGetConstData()->mePaperFormat != ePaper )
    1454             :     {
    1455           0 :         JobSetup        aJobSetup = maJobSetup;
    1456           0 :         ImplJobSetup*   pSetupData = aJobSetup.ImplGetData();
    1457           0 :         pSetupData->mePaperFormat = ePaper;
    1458           0 :         if ( ePaper != PAPER_USER )
    1459             :         {
    1460           0 :             PaperInfo aInfo(ePaper);
    1461           0 :             pSetupData->mnPaperWidth  = aInfo.getWidth();
    1462           0 :             pSetupData->mnPaperHeight = aInfo.getHeight();
    1463             :         }
    1464             : 
    1465           0 :         if ( IsDisplayPrinter() )
    1466             :         {
    1467           0 :             mbNewJobSetup = true;
    1468           0 :             maJobSetup = aJobSetup;
    1469           0 :             return true;
    1470             :         }
    1471             : 
    1472           0 :         ReleaseGraphics();
    1473           0 :         if ( ePaper == PAPER_USER )
    1474           0 :             ImplFindPaperFormatForUserSize( aJobSetup, false );
    1475           0 :         if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
    1476             :         {
    1477           0 :             ImplUpdateJobSetupPaper( aJobSetup );
    1478           0 :             mbNewJobSetup = true;
    1479           0 :             maJobSetup = aJobSetup;
    1480           0 :             ImplUpdatePageData();
    1481           0 :             ImplUpdateFontList();
    1482           0 :             return true;
    1483             :         }
    1484             :         else
    1485           0 :             return false;
    1486             :     }
    1487             : 
    1488           0 :     return true;
    1489             : }
    1490             : 
    1491           0 : bool Printer::SetPaperSizeUser( const Size& rSize )
    1492             : {
    1493           0 :     return SetPaperSizeUser( rSize, false );
    1494             : }
    1495             : 
    1496           0 : bool Printer::SetPaperSizeUser( const Size& rSize, bool bMatchNearest )
    1497             : {
    1498           0 :     if ( mbInPrintPage )
    1499           0 :         return false;
    1500             : 
    1501           0 :     const Size aPixSize = LogicToPixel( rSize );
    1502           0 :     const Size aPageSize = PixelToLogic( aPixSize, MAP_100TH_MM );
    1503           0 :     bool bNeedToChange(maJobSetup.ImplGetConstData()->mnPaperWidth != aPageSize.Width() ||
    1504           0 :         maJobSetup.ImplGetConstData()->mnPaperHeight != aPageSize.Height());
    1505             : 
    1506           0 :     if(!bNeedToChange)
    1507             :     {
    1508             :         // #i122984# only need to change when Paper is different from PAPER_USER and
    1509             :         // the mapped Paper which will created below in the call to ImplFindPaperFormatForUserSize
    1510             :         // and will replace maJobSetup.ImplGetConstData()->mePaperFormat. This leads to
    1511             :         // unnecessary JobSetups, e.g. when printing a multi-page fax, but also with
    1512             :         // normal print
    1513           0 :         const Paper aPaper = ImplGetPaperFormat(aPageSize.Width(), aPageSize.Height());
    1514             : 
    1515           0 :         bNeedToChange = maJobSetup.ImplGetConstData()->mePaperFormat != PAPER_USER &&
    1516           0 :             maJobSetup.ImplGetConstData()->mePaperFormat != aPaper;
    1517             :     }
    1518             : 
    1519           0 :     if(bNeedToChange)
    1520             :     {
    1521           0 :         JobSetup        aJobSetup = maJobSetup;
    1522           0 :         ImplJobSetup*   pSetupData = aJobSetup.ImplGetData();
    1523           0 :         pSetupData->mePaperFormat   = PAPER_USER;
    1524           0 :         pSetupData->mnPaperWidth    = aPageSize.Width();
    1525           0 :         pSetupData->mnPaperHeight   = aPageSize.Height();
    1526             : 
    1527           0 :         if ( IsDisplayPrinter() )
    1528             :         {
    1529           0 :             mbNewJobSetup = true;
    1530           0 :             maJobSetup = aJobSetup;
    1531           0 :             return true;
    1532             :         }
    1533             : 
    1534           0 :         ReleaseGraphics();
    1535           0 :         ImplFindPaperFormatForUserSize( aJobSetup, bMatchNearest );
    1536             : 
    1537             :         // Changing the paper size can also change the orientation!
    1538           0 :         if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
    1539             :         {
    1540           0 :             ImplUpdateJobSetupPaper( aJobSetup );
    1541           0 :             mbNewJobSetup = true;
    1542           0 :             maJobSetup = aJobSetup;
    1543           0 :             ImplUpdatePageData();
    1544           0 :             ImplUpdateFontList();
    1545           0 :             return true;
    1546             :         }
    1547             :         else
    1548           0 :             return false;
    1549             :     }
    1550             : 
    1551           0 :     return true;
    1552             : }
    1553             : 
    1554           0 : int Printer::GetPaperInfoCount() const
    1555             : {
    1556           0 :     if( ! mpInfoPrinter )
    1557           0 :         return 0;
    1558           0 :     if( ! mpInfoPrinter->m_bPapersInit )
    1559           0 :         mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
    1560           0 :     return mpInfoPrinter->m_aPaperFormats.size();
    1561             : }
    1562             : 
    1563           0 : OUString Printer::GetPaperName( Paper ePaper )
    1564             : {
    1565           0 :     ImplSVData* pSVData = ImplGetSVData();
    1566           0 :     if( ! pSVData->mpPaperNames )
    1567             :     {
    1568           0 :         pSVData->mpPaperNames = new std::unordered_map< int, OUString >();
    1569           0 :         if( ImplGetResMgr() )
    1570             :         {
    1571           0 :             ResStringArray aPaperStrings( VclResId( RID_STR_PAPERNAMES ) );
    1572             :             static const int PaperIndex[] =
    1573             :             {
    1574             :                 PAPER_A0, PAPER_A1, PAPER_A2, PAPER_A3, PAPER_A4, PAPER_A5,
    1575             :                 PAPER_B4_ISO, PAPER_B5_ISO, PAPER_LETTER, PAPER_LEGAL, PAPER_TABLOID,
    1576             :                 PAPER_USER, PAPER_B6_ISO, PAPER_ENV_C4, PAPER_ENV_C5, PAPER_ENV_C6, PAPER_ENV_C65,
    1577             :                 PAPER_ENV_DL, PAPER_SLIDE_DIA, PAPER_C, PAPER_D, PAPER_E,
    1578             :                 PAPER_EXECUTIVE, PAPER_FANFOLD_LEGAL_DE, PAPER_ENV_MONARCH, PAPER_ENV_PERSONAL,
    1579             :                 PAPER_ENV_9, PAPER_ENV_10, PAPER_ENV_11, PAPER_ENV_12, PAPER_KAI16,
    1580             :                 PAPER_KAI32, PAPER_KAI32BIG, PAPER_B4_JIS, PAPER_B5_JIS, PAPER_B6_JIS,
    1581             :                 PAPER_POSTCARD_JP
    1582             :             };
    1583             :             OSL_ENSURE( sal_uInt32(SAL_N_ELEMENTS(PaperIndex)) == aPaperStrings.Count(), "localized paper name count wrong" );
    1584           0 :             for( int i = 0; i < int(SAL_N_ELEMENTS(PaperIndex)); i++ )
    1585           0 :                 (*pSVData->mpPaperNames)[PaperIndex[i]] = aPaperStrings.GetString(i);
    1586             :         }
    1587             :     }
    1588             : 
    1589           0 :     std::unordered_map<int,OUString>::const_iterator it = pSVData->mpPaperNames->find( (int)ePaper );
    1590           0 :     return (it != pSVData->mpPaperNames->end()) ? it->second : OUString();
    1591             : }
    1592             : 
    1593           0 : OUString Printer::GetPaperName( bool i_bPaperUser ) const
    1594             : {
    1595           0 :     Size  aPageSize = PixelToLogic( GetPaperSizePixel(), MAP_100TH_MM );
    1596           0 :     Paper ePaper    = ImplGetPaperFormat( aPageSize.Width(), aPageSize.Height() );
    1597           0 :     if( ePaper == PAPER_USER )
    1598           0 :         ePaper = ImplGetPaperFormat( aPageSize.Height(), aPageSize.Width() );
    1599           0 :     return (ePaper != PAPER_USER || i_bPaperUser ) ? GetPaperName( ePaper ) : OUString();
    1600             : }
    1601             : 
    1602           0 : const PaperInfo& Printer::GetPaperInfo( int nPaper ) const
    1603             : {
    1604           0 :     if( ! mpInfoPrinter )
    1605           0 :         return ImplGetEmptyPaper();
    1606           0 :     if( ! mpInfoPrinter->m_bPapersInit )
    1607           0 :         mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
    1608           0 :     if( mpInfoPrinter->m_aPaperFormats.empty() || nPaper < 0 || nPaper >= int(mpInfoPrinter->m_aPaperFormats.size()) )
    1609           0 :         return ImplGetEmptyPaper();
    1610           0 :     return mpInfoPrinter->m_aPaperFormats[nPaper];
    1611             : }
    1612             : 
    1613           0 : bool Printer::SetDuplexMode( DuplexMode eDuplex )
    1614             : {
    1615           0 :     if ( mbInPrintPage )
    1616           0 :         return false;
    1617             : 
    1618           0 :     if ( maJobSetup.ImplGetConstData()->meDuplexMode != eDuplex )
    1619             :     {
    1620           0 :         JobSetup        aJobSetup = maJobSetup;
    1621           0 :         ImplJobSetup*   pSetupData = aJobSetup.ImplGetData();
    1622           0 :         pSetupData->meDuplexMode = eDuplex;
    1623             : 
    1624           0 :         if ( IsDisplayPrinter() )
    1625             :         {
    1626           0 :             mbNewJobSetup = true;
    1627           0 :             maJobSetup = aJobSetup;
    1628           0 :             return true;
    1629             :         }
    1630             : 
    1631           0 :         ReleaseGraphics();
    1632           0 :         if ( mpInfoPrinter->SetData( SAL_JOBSET_DUPLEXMODE, pSetupData ) )
    1633             :         {
    1634           0 :             ImplUpdateJobSetupPaper( aJobSetup );
    1635           0 :             mbNewJobSetup = true;
    1636           0 :             maJobSetup = aJobSetup;
    1637           0 :             ImplUpdatePageData();
    1638           0 :             ImplUpdateFontList();
    1639           0 :             return true;
    1640             :         }
    1641             :         else
    1642           0 :             return false;
    1643             :     }
    1644             : 
    1645           0 :     return true;
    1646             : }
    1647             : 
    1648           0 : int Printer::GetLandscapeAngle() const
    1649             : {
    1650           0 :     return mpInfoPrinter ? mpInfoPrinter->GetLandscapeAngle( maJobSetup.ImplGetConstData() ) : 900;
    1651             : }
    1652             : 
    1653         130 : Paper Printer::GetPaper() const
    1654             : {
    1655         130 :     return maJobSetup.ImplGetConstData()->mePaperFormat;
    1656             : }
    1657             : 
    1658           0 : sal_uInt16 Printer::GetPaperBinCount() const
    1659             : {
    1660           0 :     if ( IsDisplayPrinter() )
    1661           0 :         return 0;
    1662             : 
    1663           0 :     return (sal_uInt16)mpInfoPrinter->GetPaperBinCount( maJobSetup.ImplGetConstData() );
    1664             : }
    1665             : 
    1666           0 : OUString Printer::GetPaperBinName( sal_uInt16 nPaperBin ) const
    1667             : {
    1668           0 :     if ( IsDisplayPrinter() )
    1669           0 :         return OUString();
    1670             : 
    1671           0 :     if ( nPaperBin < GetPaperBinCount() )
    1672           0 :         return mpInfoPrinter->GetPaperBinName( maJobSetup.ImplGetConstData(), nPaperBin );
    1673             :     else
    1674           0 :         return OUString();
    1675             : }
    1676             : 
    1677           0 : bool Printer::SetCopyCount( sal_uInt16 nCopy, bool bCollate )
    1678             : {
    1679           0 :     mnCopyCount = nCopy;
    1680           0 :     mbCollateCopy = bCollate;
    1681           0 :     return true;
    1682             : }
    1683             : 
    1684           0 : void Printer::Error()
    1685             : {
    1686           0 :     maErrorHdl.Call( this );
    1687           0 : }
    1688             : 
    1689           0 : sal_uLong Printer::ImplSalPrinterErrorCodeToVCL( sal_uLong nError )
    1690             : {
    1691             :     sal_uLong nVCLError;
    1692           0 :     switch ( nError )
    1693             :     {
    1694             :         case 0:
    1695           0 :             nVCLError = PRINTER_OK;
    1696           0 :             break;
    1697             :         case SAL_PRINTER_ERROR_ABORT:
    1698           0 :             nVCLError = PRINTER_ABORT;
    1699           0 :             break;
    1700             :         default:
    1701           0 :             nVCLError = PRINTER_GENERALERROR;
    1702           0 :             break;
    1703             :     }
    1704             : 
    1705           0 :     return nVCLError;
    1706             : }
    1707             : 
    1708           0 : bool Printer::EndJob()
    1709             : {
    1710           0 :     bool bRet = false;
    1711           0 :     if ( !IsJobActive() )
    1712           0 :         return bRet;
    1713             : 
    1714             :     DBG_ASSERT( !mbInPrintPage, "Printer::EndJob() - StartPage() without EndPage() called" );
    1715             : 
    1716           0 :     mbJobActive = false;
    1717             : 
    1718           0 :     if ( mpPrinter )
    1719             :     {
    1720           0 :         ReleaseGraphics();
    1721             : 
    1722           0 :         mnCurPage = 0;
    1723             : 
    1724           0 :         mbPrinting      = false;
    1725           0 :         mnCurPrintPage  = 0;
    1726           0 :         maJobName.clear();
    1727             : 
    1728           0 :         mbDevOutput = false;
    1729           0 :         bRet = mpPrinter->EndJob();
    1730             :         // FIXME: Do not destroy the printer asynchronously as Win95
    1731             :         // can't handle destroying a printer object and printing
    1732             :         // at the same time
    1733           0 :         ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
    1734           0 :         mpPrinter = NULL;
    1735             :     }
    1736             : 
    1737           0 :     return bRet;
    1738             : }
    1739             : 
    1740           0 : void Printer::ImplStartPage()
    1741             : {
    1742           0 :     if ( !IsJobActive() )
    1743           0 :         return;
    1744             : 
    1745           0 :     if ( mpPrinter )
    1746             :     {
    1747           0 :         SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
    1748           0 :         if ( pGraphics )
    1749             :         {
    1750           0 :             ReleaseGraphics();
    1751           0 :             mpJobGraphics = pGraphics;
    1752             :         }
    1753           0 :         mbDevOutput = true;
    1754             : 
    1755             :         // PrintJob not aborted ???
    1756           0 :         if ( IsJobActive() )
    1757             :         {
    1758           0 :             mbInPrintPage = true;
    1759           0 :             mnCurPage++;
    1760           0 :             mnCurPrintPage++;
    1761             :         }
    1762             :     }
    1763             : }
    1764             : 
    1765           0 : void Printer::ImplEndPage()
    1766             : {
    1767           0 :     if ( !IsJobActive() )
    1768           0 :         return;
    1769             : 
    1770           0 :     mbInPrintPage = false;
    1771             : 
    1772           0 :     if ( mpPrinter )
    1773             :     {
    1774           0 :         mpPrinter->EndPage();
    1775           0 :         ReleaseGraphics();
    1776           0 :         mbDevOutput = false;
    1777             : 
    1778           0 :         mpJobGraphics = NULL;
    1779           0 :         mbNewJobSetup = false;
    1780             :     }
    1781             : }
    1782             : 
    1783           0 : void Printer::updatePrinters()
    1784             : {
    1785           0 :     ImplSVData*         pSVData = ImplGetSVData();
    1786           0 :     ImplPrnQueueList*   pPrnList = pSVData->maGDIData.mpPrinterQueueList;
    1787             : 
    1788           0 :     if ( pPrnList )
    1789             :     {
    1790           0 :         ImplPrnQueueList* pNewList = new ImplPrnQueueList;
    1791           0 :         pSVData->mpDefInst->GetPrinterQueueInfo( pNewList );
    1792             : 
    1793           0 :         bool bChanged = pPrnList->m_aQueueInfos.size() != pNewList->m_aQueueInfos.size();
    1794           0 :         for( unsigned int i = 0; ! bChanged && i < pPrnList->m_aQueueInfos.size(); i++ )
    1795             :         {
    1796           0 :             ImplPrnQueueData& rInfo     = pPrnList->m_aQueueInfos[i];
    1797           0 :             ImplPrnQueueData& rNewInfo  = pNewList->m_aQueueInfos[i];
    1798           0 :             if( ! rInfo.mpSalQueueInfo || ! rNewInfo.mpSalQueueInfo || // sanity check
    1799           0 :                 rInfo.mpSalQueueInfo->maPrinterName != rNewInfo.mpSalQueueInfo->maPrinterName )
    1800             :             {
    1801           0 :                 bChanged = true;
    1802             :             }
    1803             :         }
    1804           0 :         if( bChanged )
    1805             :         {
    1806           0 :             ImplDeletePrnQueueList();
    1807           0 :             pSVData->maGDIData.mpPrinterQueueList = pNewList;
    1808             : 
    1809           0 :             Application* pApp = GetpApp();
    1810           0 :             if( pApp )
    1811             :             {
    1812           0 :                 DataChangedEvent aDCEvt( DataChangedEventType::PRINTER );
    1813           0 :                 Application::NotifyAllWindows( aDCEvt );
    1814             :             }
    1815             :         }
    1816             :         else
    1817           0 :             delete pNewList;
    1818             :     }
    1819           0 : }
    1820             : 
    1821           0 : bool Printer::UsePolyPolygonForComplexGradient()
    1822             : {
    1823           0 :     return true;
    1824             : }
    1825             : 
    1826           0 : void Printer::ClipAndDrawGradientMetafile ( const Gradient &rGradient, const tools::PolyPolygon &rPolyPoly )
    1827             : {
    1828           0 :     const Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
    1829             : 
    1830           0 :     Push( PushFlags::CLIPREGION );
    1831           0 :     IntersectClipRegion(vcl::Region(rPolyPoly));
    1832           0 :     DrawGradient( aBoundRect, rGradient );
    1833           0 :     Pop();
    1834           0 : }
    1835             : 
    1836         753 : void Printer::InitFont() const
    1837             : {
    1838             :     DBG_TESTSOLARMUTEX();
    1839             : 
    1840         753 :     if (!mpFontEntry)
    1841         753 :         return;
    1842             : 
    1843         753 :     if ( mbInitFont )
    1844             :     {
    1845             :         // select font in the device layers
    1846         753 :         mpFontEntry->mnSetFontFlags = mpGraphics->SetFont( &(mpFontEntry->maFontSelData), 0 );
    1847         753 :         mbInitFont = false;
    1848             :     }
    1849             : }
    1850             : 
    1851         271 : void Printer::SetFontOrientation( ImplFontEntry* const pFontEntry ) const
    1852             : {
    1853         271 :     pFontEntry->mnOrientation = pFontEntry->maMetric.mnOrientation;
    1854         271 : }
    1855             : 
    1856           0 : void Printer::DrawImage( const Point&, const Image&, DrawImageFlags )
    1857             : {
    1858             :     SAL_WARN ("vcl.gdi", "DrawImage(): Images can't be drawn on any Printer instance");
    1859             :     assert(false);
    1860           0 : }
    1861             : 
    1862           0 : void Printer::DrawImage( const Point&, const Size&, const Image&, DrawImageFlags )
    1863             : {
    1864             :     SAL_WARN ("vcl.gdi", "DrawImage(): Images can't be drawn on any Printer instance");
    1865             :     assert(false);
    1866           0 : }
    1867             : 
    1868             : 
    1869           0 : Bitmap Printer::GetBitmap( const Point& rSrcPt, const Size& rSize ) const
    1870             : {
    1871             :     SAL_WARN("vcl.gdi", "GetBitmap(): This should never be called on by a Printer instance");
    1872             : 
    1873           0 :     return OutputDevice::GetBitmap( rSrcPt, rSize );
    1874         801 : }
    1875             : 
    1876             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11