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: */
|