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 0 : void ImplUpdateJobSetupPaper( JobSetup& rJobSetup )
81 : {
82 0 : const ImplJobSetup* pConstData = rJobSetup.ImplGetConstData();
83 :
84 0 : if ( !pConstData->mnPaperWidth || !pConstData->mnPaperHeight )
85 : {
86 0 : if ( pConstData->mePaperFormat != PAPER_USER )
87 : {
88 0 : ImplJobSetup* pData = rJobSetup.ImplGetData();
89 0 : PaperInfo aInfo(pConstData->mePaperFormat);
90 0 : pData->mnPaperWidth = aInfo.getWidth();
91 0 : pData->mnPaperHeight = aInfo.getHeight();
92 0 : }
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 0 : }
101 :
102 : // PrinterOptions
103 0 : 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 0 : mbPDFAsStandardPrintJobFormat( false )
115 : {
116 0 : }
117 :
118 0 : PrinterOptions::~PrinterOptions()
119 : {
120 0 : }
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 hierachical 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::TransformReduceBitmapExTargetRange(
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 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( PUSH_CLIPREGION | PUSH_LINECOLOR );
291 0 : IntersectClipRegion(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 : sal_uInt16 /*nFlags*/ )
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 = 0;
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, STREAM_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( 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, STREAM_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 0 : rIStream.ReadUInt32( rInfo.mnStatus );
413 0 : rIStream.ReadUInt32( rInfo.mnJobs );
414 :
415 0 : return rIStream;
416 : }
417 :
418 0 : SalPrinterQueueInfo::SalPrinterQueueInfo()
419 : {
420 0 : mnStatus = 0;
421 0 : mnJobs = QUEUE_JOBS_DONTKNOW;
422 0 : mpSysData = NULL;
423 0 : }
424 :
425 0 : SalPrinterQueueInfo::~SalPrinterQueueInfo()
426 : {
427 0 : }
428 :
429 0 : ImplPrnQueueList::~ImplPrnQueueList()
430 : {
431 0 : ImplSVData* pSVData = ImplGetSVData();
432 0 : for( unsigned int i = 0; i < m_aQueueInfos.size(); i++ )
433 : {
434 0 : delete m_aQueueInfos[i].mpQueueInfo;
435 0 : pSVData->mpDefInst->DeletePrinterQueueInfo( m_aQueueInfos[i].mpSalQueueInfo );
436 : }
437 0 : }
438 :
439 0 : void ImplPrnQueueList::Add( SalPrinterQueueInfo* pData )
440 : {
441 : boost::unordered_map< OUString, sal_Int32, OUStringHash >::iterator it =
442 0 : m_aNameToIndex.find( pData->maPrinterName );
443 0 : if( it == m_aNameToIndex.end() )
444 : {
445 0 : m_aNameToIndex[ pData->maPrinterName ] = m_aQueueInfos.size();
446 0 : m_aQueueInfos.push_back( ImplPrnQueueData() );
447 0 : m_aQueueInfos.back().mpQueueInfo = NULL;
448 0 : m_aQueueInfos.back().mpSalQueueInfo = pData;
449 0 : m_aPrinterList.push_back( pData->maPrinterName );
450 : }
451 : else // this should not happen, but ...
452 : {
453 0 : ImplPrnQueueData& rData = m_aQueueInfos[ it->second ];
454 0 : delete rData.mpQueueInfo;
455 0 : rData.mpQueueInfo = NULL;
456 0 : ImplGetSVData()->mpDefInst->DeletePrinterQueueInfo( rData.mpSalQueueInfo );
457 0 : rData.mpSalQueueInfo = pData;
458 : }
459 0 : }
460 :
461 0 : ImplPrnQueueData* ImplPrnQueueList::Get( const OUString& rPrinter )
462 : {
463 0 : ImplPrnQueueData* pData = NULL;
464 : boost::unordered_map<OUString,sal_Int32,OUStringHash>::iterator it =
465 0 : m_aNameToIndex.find( rPrinter );
466 0 : if( it != m_aNameToIndex.end() )
467 0 : pData = &m_aQueueInfos[it->second];
468 0 : return pData;
469 : }
470 :
471 0 : static void ImplInitPrnQueueList()
472 : {
473 0 : ImplSVData* pSVData = ImplGetSVData();
474 :
475 0 : pSVData->maGDIData.mpPrinterQueueList = new ImplPrnQueueList;
476 :
477 0 : static const char* pEnv = getenv( "SAL_DISABLE_PRINTERLIST" );
478 0 : if( !pEnv || !*pEnv )
479 0 : pSVData->mpDefInst->GetPrinterQueueInfo( pSVData->maGDIData.mpPrinterQueueList );
480 0 : }
481 :
482 1 : void ImplDeletePrnQueueList()
483 : {
484 1 : ImplSVData* pSVData = ImplGetSVData();
485 1 : ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
486 :
487 1 : if ( pPrnList )
488 : {
489 0 : delete pPrnList;
490 0 : pSVData->maGDIData.mpPrinterQueueList = NULL;
491 : }
492 1 : }
493 :
494 0 : const std::vector<OUString>& Printer::GetPrinterQueues()
495 : {
496 0 : ImplSVData* pSVData = ImplGetSVData();
497 0 : if ( !pSVData->maGDIData.mpPrinterQueueList )
498 0 : ImplInitPrnQueueList();
499 0 : return pSVData->maGDIData.mpPrinterQueueList->m_aPrinterList;
500 : }
501 :
502 0 : const QueueInfo* Printer::GetQueueInfo( const OUString& rPrinterName, bool bStatusUpdate )
503 : {
504 0 : ImplSVData* pSVData = ImplGetSVData();
505 :
506 0 : if ( !pSVData->maGDIData.mpPrinterQueueList )
507 0 : ImplInitPrnQueueList();
508 :
509 0 : if ( !pSVData->maGDIData.mpPrinterQueueList )
510 0 : return NULL;
511 :
512 0 : ImplPrnQueueData* pInfo = pSVData->maGDIData.mpPrinterQueueList->Get( rPrinterName );
513 0 : if( pInfo )
514 : {
515 0 : if( !pInfo->mpQueueInfo || bStatusUpdate )
516 0 : pSVData->mpDefInst->GetPrinterQueueState( pInfo->mpSalQueueInfo );
517 :
518 0 : if ( !pInfo->mpQueueInfo )
519 0 : pInfo->mpQueueInfo = new QueueInfo;
520 :
521 0 : pInfo->mpQueueInfo->maPrinterName = pInfo->mpSalQueueInfo->maPrinterName;
522 0 : pInfo->mpQueueInfo->maDriver = pInfo->mpSalQueueInfo->maDriver;
523 0 : pInfo->mpQueueInfo->maLocation = pInfo->mpSalQueueInfo->maLocation;
524 0 : pInfo->mpQueueInfo->maComment = pInfo->mpSalQueueInfo->maComment;
525 0 : pInfo->mpQueueInfo->mnStatus = pInfo->mpSalQueueInfo->mnStatus;
526 0 : pInfo->mpQueueInfo->mnJobs = pInfo->mpSalQueueInfo->mnJobs;
527 0 : return pInfo->mpQueueInfo;
528 : }
529 0 : return NULL;
530 : }
531 :
532 0 : OUString Printer::GetDefaultPrinterName()
533 : {
534 0 : static const char* pEnv = getenv( "SAL_DISABLE_DEFAULTPRINTER" );
535 0 : if( !pEnv || !*pEnv )
536 : {
537 0 : ImplSVData* pSVData = ImplGetSVData();
538 :
539 0 : return pSVData->mpDefInst->GetDefaultPrinter();
540 : }
541 0 : return OUString();
542 : }
543 :
544 0 : void Printer::ImplInitData()
545 : {
546 0 : mbDevOutput = false;
547 0 : meOutDevType = OUTDEV_PRINTER;
548 0 : mbDefPrinter = false;
549 0 : mnError = 0;
550 0 : mnCurPage = 0;
551 0 : mnCurPrintPage = 0;
552 0 : mnPageQueueSize = 0;
553 0 : mnCopyCount = 1;
554 0 : mbCollateCopy = false;
555 0 : mbPrinting = false;
556 0 : mbJobActive = false;
557 0 : mbPrintFile = false;
558 0 : mbInPrintPage = false;
559 0 : mbNewJobSetup = false;
560 0 : mpInfoPrinter = NULL;
561 0 : mpPrinter = NULL;
562 0 : mpDisplayDev = NULL;
563 0 : mbIsQueuePrinter = false;
564 0 : mpPrinterOptions = new PrinterOptions;
565 :
566 : // Add printer to the list
567 0 : ImplSVData* pSVData = ImplGetSVData();
568 0 : mpNext = pSVData->maGDIData.mpFirstPrinter;
569 0 : mpPrev = NULL;
570 0 : if ( mpNext )
571 0 : mpNext->mpPrev = this;
572 : else
573 0 : pSVData->maGDIData.mpLastPrinter = this;
574 0 : pSVData->maGDIData.mpFirstPrinter = this;
575 0 : }
576 :
577 0 : bool Printer::ImplInitGraphics() const
578 : {
579 : DBG_TESTSOLARMUTEX();
580 :
581 0 : if ( mpGraphics )
582 0 : return true;
583 :
584 0 : mbInitLineColor = true;
585 0 : mbInitFillColor = true;
586 0 : mbInitFont = true;
587 0 : mbInitTextColor = true;
588 0 : mbInitClipRegion = true;
589 :
590 0 : ImplSVData* pSVData = ImplGetSVData();
591 :
592 0 : if ( mpJobGraphics )
593 0 : mpGraphics = mpJobGraphics;
594 0 : else if ( mpDisplayDev )
595 : {
596 0 : const VirtualDevice* pVirDev = mpDisplayDev;
597 0 : mpGraphics = pVirDev->mpVirDev->AcquireGraphics();
598 : // if needed retry after releasing least recently used virtual device graphics
599 0 : while ( !mpGraphics )
600 : {
601 0 : if ( !pSVData->maGDIData.mpLastVirGraphics )
602 0 : break;
603 0 : pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
604 0 : mpGraphics = pVirDev->mpVirDev->AcquireGraphics();
605 : }
606 : // update global LRU list of virtual device graphics
607 0 : if ( mpGraphics )
608 : {
609 0 : mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
610 0 : pSVData->maGDIData.mpFirstVirGraphics = const_cast<Printer*>(this);
611 0 : if ( mpNextGraphics )
612 0 : mpNextGraphics->mpPrevGraphics = const_cast<Printer*>(this);
613 0 : if ( !pSVData->maGDIData.mpLastVirGraphics )
614 0 : pSVData->maGDIData.mpLastVirGraphics = const_cast<Printer*>(this);
615 : }
616 : }
617 : else
618 : {
619 0 : mpGraphics = mpInfoPrinter->AcquireGraphics();
620 : // if needed retry after releasing least recently used printer graphics
621 0 : while ( !mpGraphics )
622 : {
623 0 : if ( !pSVData->maGDIData.mpLastPrnGraphics )
624 0 : break;
625 0 : pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
626 0 : mpGraphics = mpInfoPrinter->AcquireGraphics();
627 : }
628 : // update global LRU list of printer graphics
629 0 : if ( mpGraphics )
630 : {
631 0 : mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
632 0 : pSVData->maGDIData.mpFirstPrnGraphics = const_cast<Printer*>(this);
633 0 : if ( mpNextGraphics )
634 0 : mpNextGraphics->mpPrevGraphics = const_cast<Printer*>(this);
635 0 : if ( !pSVData->maGDIData.mpLastPrnGraphics )
636 0 : pSVData->maGDIData.mpLastPrnGraphics = const_cast<Printer*>(this);
637 : }
638 : }
639 :
640 0 : if ( mpGraphics )
641 : {
642 0 : mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
643 0 : mpGraphics->setAntiAliasB2DDraw(mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW);
644 : }
645 :
646 0 : return mpGraphics ? true : false;
647 : }
648 :
649 0 : void Printer::ImplReleaseFonts()
650 : {
651 : #ifndef UNX
652 : // HACK to fix an urgent P1 printing issue fast
653 : // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions
654 : // so Printer::mpGraphics often points to a dead WinSalGraphics
655 : // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling
656 : mpGraphics->ReleaseFonts();
657 : #endif
658 0 : mbNewFont = true;
659 0 : mbInitFont = true;
660 :
661 0 : if ( mpFontEntry )
662 : {
663 0 : mpFontCache->Release( mpFontEntry );
664 0 : mpFontEntry = NULL;
665 : }
666 :
667 0 : if ( mpGetDevFontList )
668 : {
669 0 : delete mpGetDevFontList;
670 0 : mpGetDevFontList = NULL;
671 : }
672 :
673 0 : if ( mpGetDevSizeList )
674 : {
675 0 : delete mpGetDevSizeList;
676 0 : mpGetDevSizeList = NULL;
677 : }
678 0 : }
679 :
680 0 : void Printer::ImplReleaseGraphics( bool bRelease )
681 : {
682 : DBG_TESTSOLARMUTEX();
683 :
684 0 : if ( !mpGraphics )
685 0 : return;
686 :
687 : // release the fonts of the physically released graphics device
688 0 : if( bRelease )
689 0 : ImplReleaseFonts();
690 :
691 0 : ImplSVData* pSVData = ImplGetSVData();
692 :
693 0 : Printer* pPrinter = (Printer*)this;
694 :
695 0 : if ( !pPrinter->mpJobGraphics )
696 : {
697 0 : if ( pPrinter->mpDisplayDev )
698 : {
699 0 : VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
700 0 : if ( bRelease )
701 0 : pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
702 : // remove from global LRU list of virtual device graphics
703 0 : if ( mpPrevGraphics )
704 0 : mpPrevGraphics->mpNextGraphics = mpNextGraphics;
705 : else
706 0 : pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
707 0 : if ( mpNextGraphics )
708 0 : mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
709 : else
710 0 : pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
711 : }
712 : else
713 : {
714 0 : if ( bRelease )
715 0 : pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
716 : // remove from global LRU list of printer graphics
717 0 : if ( mpPrevGraphics )
718 0 : mpPrevGraphics->mpNextGraphics = mpNextGraphics;
719 : else
720 0 : pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
721 0 : if ( mpNextGraphics )
722 0 : mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
723 : else
724 0 : pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
725 : }
726 : }
727 :
728 0 : mpGraphics = NULL;
729 0 : mpPrevGraphics = NULL;
730 0 : mpNextGraphics = NULL;
731 : }
732 :
733 0 : void Printer::ImplInit( SalPrinterQueueInfo* pInfo )
734 : {
735 0 : ImplSVData* pSVData = ImplGetSVData();
736 : // #i74084# update info for this specific SalPrinterQueueInfo
737 0 : pSVData->mpDefInst->GetPrinterQueueState( pInfo );
738 :
739 : // Test whether the driver actually matches the JobSetup
740 0 : ImplJobSetup* pJobSetup = maJobSetup.ImplGetData();
741 :
742 0 : if ( pJobSetup->mpDriverData )
743 : {
744 0 : if ( (pJobSetup->maPrinterName != pInfo->maPrinterName) ||
745 0 : (pJobSetup->maDriver != pInfo->maDriver) )
746 : {
747 0 : rtl_freeMemory( pJobSetup->mpDriverData );
748 0 : pJobSetup->mpDriverData = NULL;
749 0 : pJobSetup->mnDriverDataLen = 0;
750 : }
751 : }
752 :
753 : // Remember printer name
754 0 : maPrinterName = pInfo->maPrinterName;
755 0 : maDriver = pInfo->maDriver;
756 :
757 : // Add printer name to JobSetup
758 0 : pJobSetup->maPrinterName = maPrinterName;
759 0 : pJobSetup->maDriver = maDriver;
760 :
761 0 : mpInfoPrinter = pSVData->mpDefInst->CreateInfoPrinter( pInfo, pJobSetup );
762 0 : mpPrinter = NULL;
763 0 : mpJobGraphics = NULL;
764 0 : ImplUpdateJobSetupPaper( maJobSetup );
765 :
766 0 : if ( !mpInfoPrinter )
767 : {
768 0 : ImplInitDisplay( NULL );
769 0 : return;
770 : }
771 :
772 : // we need a graphics
773 0 : if ( !ImplGetGraphics() )
774 : {
775 0 : ImplInitDisplay( NULL );
776 0 : return;
777 : }
778 :
779 : // Init data
780 0 : ImplUpdatePageData();
781 0 : mpFontCollection = new PhysicalFontCollection();
782 0 : mpFontCache = new ImplFontCache();
783 0 : mpGraphics->GetDevFontList( mpFontCollection );
784 : }
785 :
786 0 : void Printer::ImplInitDisplay( const Window* pWindow )
787 : {
788 0 : ImplSVData* pSVData = ImplGetSVData();
789 :
790 0 : mpInfoPrinter = NULL;
791 0 : mpPrinter = NULL;
792 0 : mpJobGraphics = NULL;
793 :
794 0 : if ( pWindow )
795 0 : mpDisplayDev = new VirtualDevice( *pWindow );
796 : else
797 0 : mpDisplayDev = new VirtualDevice();
798 0 : mpFontCollection = pSVData->maGDIData.mpScreenFontList;
799 0 : mpFontCache = pSVData->maGDIData.mpScreenFontCache;
800 0 : mnDPIX = mpDisplayDev->mnDPIX;
801 0 : mnDPIY = mpDisplayDev->mnDPIY;
802 0 : }
803 :
804 0 : void Printer::ImplPrintMask( const Bitmap& rMask, const Color& rMaskColor,
805 : const Point& rDestPt, const Size& rDestSize,
806 : const Point& rSrcPtPixel, const Size& rSrcSizePixel )
807 : {
808 0 : Point aPt;
809 0 : Point aDestPt( LogicToPixel( rDestPt ) );
810 0 : Size aDestSz( LogicToPixel( rDestSize ) );
811 0 : Rectangle aSrcRect( rSrcPtPixel, rSrcSizePixel );
812 :
813 0 : aSrcRect.Justify();
814 :
815 0 : if( !rMask.IsEmpty() && aSrcRect.GetWidth() && aSrcRect.GetHeight() && aDestSz.Width() && aDestSz.Height() )
816 : {
817 0 : Bitmap aMask( rMask );
818 0 : sal_uLong nMirrFlags = 0UL;
819 :
820 0 : if( aMask.GetBitCount() > 1 )
821 0 : aMask.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
822 :
823 : // mirrored horizontically
824 0 : if( aDestSz.Width() < 0L )
825 : {
826 0 : aDestSz.Width() = -aDestSz.Width();
827 0 : aDestPt.X() -= ( aDestSz.Width() - 1L );
828 0 : nMirrFlags |= BMP_MIRROR_HORZ;
829 : }
830 :
831 : // mirrored vertically
832 0 : if( aDestSz.Height() < 0L )
833 : {
834 0 : aDestSz.Height() = -aDestSz.Height();
835 0 : aDestPt.Y() -= ( aDestSz.Height() - 1L );
836 0 : nMirrFlags |= BMP_MIRROR_VERT;
837 : }
838 :
839 : // source cropped?
840 0 : if( aSrcRect != Rectangle( aPt, aMask.GetSizePixel() ) )
841 0 : aMask.Crop( aSrcRect );
842 :
843 : // destination mirrored
844 0 : if( nMirrFlags )
845 0 : aMask.Mirror( nMirrFlags );
846 :
847 : // do painting
848 0 : const long nSrcWidth = aSrcRect.GetWidth(), nSrcHeight = aSrcRect.GetHeight();
849 : long nX, nY; //, nWorkX, nWorkY, nWorkWidth, nWorkHeight;
850 0 : long* pMapX = new long[ nSrcWidth + 1 ];
851 0 : long* pMapY = new long[ nSrcHeight + 1 ];
852 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
853 0 : const bool bOldMap = mbMap;
854 :
855 0 : mpMetaFile = NULL;
856 0 : mbMap = false;
857 0 : Push( PUSH_FILLCOLOR | PUSH_LINECOLOR );
858 0 : SetLineColor( rMaskColor );
859 0 : SetFillColor( rMaskColor );
860 0 : ImplInitLineColor();
861 0 : ImplInitFillColor();
862 :
863 : // create forward mapping tables
864 0 : for( nX = 0L; nX <= nSrcWidth; nX++ )
865 0 : pMapX[ nX ] = aDestPt.X() + FRound( (double) aDestSz.Width() * nX / nSrcWidth );
866 :
867 0 : for( nY = 0L; nY <= nSrcHeight; nY++ )
868 0 : pMapY[ nY ] = aDestPt.Y() + FRound( (double) aDestSz.Height() * nY / nSrcHeight );
869 :
870 : // walk through all rectangles of mask
871 0 : const Region aWorkRgn(aMask.CreateRegion(COL_BLACK, Rectangle(Point(), aMask.GetSizePixel())));
872 0 : RectangleVector aRectangles;
873 0 : aWorkRgn.GetRegionRectangles(aRectangles);
874 :
875 0 : for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
876 : {
877 0 : const Point aMapPt(pMapX[aRectIter->Left()], pMapY[aRectIter->Top()]);
878 : const Size aMapSz(
879 0 : pMapX[aRectIter->Right() + 1] - aMapPt.X(), // pMapX[L + W] -> L + ((R - L) + 1) -> R + 1
880 0 : pMapY[aRectIter->Bottom() + 1] - aMapPt.Y()); // same for Y
881 :
882 0 : DrawRect(Rectangle(aMapPt, aMapSz));
883 : }
884 :
885 0 : Pop();
886 0 : delete[] pMapX;
887 0 : delete[] pMapY;
888 0 : mbMap = bOldMap;
889 0 : mpMetaFile = pOldMetaFile;
890 : }
891 0 : }
892 :
893 0 : SalPrinterQueueInfo* Printer::ImplGetQueueInfo( const OUString& rPrinterName,
894 : const OUString* pDriver )
895 : {
896 0 : ImplSVData* pSVData = ImplGetSVData();
897 0 : if ( !pSVData->maGDIData.mpPrinterQueueList )
898 0 : ImplInitPrnQueueList();
899 :
900 0 : ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
901 0 : if ( pPrnList && pPrnList->m_aQueueInfos.size() )
902 : {
903 : // first search for the printer name driectly
904 0 : ImplPrnQueueData* pInfo = pPrnList->Get( rPrinterName );
905 0 : if( pInfo )
906 0 : return pInfo->mpSalQueueInfo;
907 :
908 : // then search case insensitive
909 0 : for( unsigned int i = 0; i < pPrnList->m_aQueueInfos.size(); i++ )
910 : {
911 0 : if( pPrnList->m_aQueueInfos[i].mpSalQueueInfo->maPrinterName.equalsIgnoreAsciiCase( rPrinterName ) )
912 0 : return pPrnList->m_aQueueInfos[i].mpSalQueueInfo;
913 : }
914 :
915 : // then search for driver name
916 0 : if ( pDriver )
917 : {
918 0 : for( unsigned int i = 0; i < pPrnList->m_aQueueInfos.size(); i++ )
919 : {
920 0 : if( pPrnList->m_aQueueInfos[i].mpSalQueueInfo->maDriver == *pDriver )
921 0 : return pPrnList->m_aQueueInfos[i].mpSalQueueInfo;
922 : }
923 : }
924 :
925 : // then the default printer
926 0 : pInfo = pPrnList->Get( GetDefaultPrinterName() );
927 0 : if( pInfo )
928 0 : return pInfo->mpSalQueueInfo;
929 :
930 : // last chance: the first available printer
931 0 : return pPrnList->m_aQueueInfos[0].mpSalQueueInfo;
932 : }
933 :
934 0 : return NULL;
935 : }
936 :
937 0 : void Printer::ImplUpdatePageData()
938 : {
939 : // we need a graphics
940 0 : if ( !ImplGetGraphics() )
941 0 : return;
942 :
943 0 : mpGraphics->GetResolution( mnDPIX, mnDPIY );
944 0 : mpInfoPrinter->GetPageInfo( maJobSetup.ImplGetConstData(),
945 : mnOutWidth, mnOutHeight,
946 0 : maPageOffset.X(), maPageOffset.Y(),
947 0 : maPaperSize.Width(), maPaperSize.Height() );
948 : }
949 :
950 0 : void Printer::ImplUpdateFontList()
951 : {
952 0 : ImplUpdateFontData( true );
953 0 : }
954 :
955 0 : long Printer::ImplGetGradientStepCount( long nMinRect )
956 : {
957 : // use display-equivalent step size calculation
958 0 : long nInc = (nMinRect < 800) ? 10 : 20;
959 :
960 0 : return nInc;
961 : }
962 :
963 0 : Printer::Printer()
964 : {
965 0 : ImplInitData();
966 0 : SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( GetDefaultPrinterName(), NULL );
967 0 : if ( pInfo )
968 : {
969 0 : ImplInit( pInfo );
970 0 : if ( !IsDisplayPrinter() )
971 0 : mbDefPrinter = true;
972 : }
973 : else
974 0 : ImplInitDisplay( NULL );
975 0 : }
976 :
977 0 : Printer::Printer( const JobSetup& rJobSetup ) :
978 0 : maJobSetup( rJobSetup )
979 : {
980 0 : ImplInitData();
981 : SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rJobSetup.mpData->maPrinterName,
982 0 : &rJobSetup.mpData->maDriver );
983 0 : if ( pInfo )
984 : {
985 0 : ImplInit( pInfo );
986 0 : SetJobSetup( rJobSetup );
987 : }
988 : else
989 : {
990 0 : ImplInitDisplay( NULL );
991 0 : maJobSetup = JobSetup();
992 : }
993 0 : }
994 :
995 0 : Printer::Printer( const QueueInfo& rQueueInfo )
996 : {
997 0 : ImplInitData();
998 0 : SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rQueueInfo.GetPrinterName(),
999 0 : &rQueueInfo.GetDriver() );
1000 0 : if ( pInfo )
1001 0 : ImplInit( pInfo );
1002 : else
1003 0 : ImplInitDisplay( NULL );
1004 0 : }
1005 :
1006 0 : Printer::Printer( const OUString& rPrinterName )
1007 : {
1008 0 : ImplInitData();
1009 0 : SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( rPrinterName, NULL );
1010 0 : if ( pInfo )
1011 0 : ImplInit( pInfo );
1012 : else
1013 0 : ImplInitDisplay( NULL );
1014 0 : }
1015 :
1016 0 : Printer::~Printer()
1017 : {
1018 : DBG_ASSERT( !IsPrinting(), "Printer::~Printer() - Job is printing" );
1019 : DBG_ASSERT( !IsJobActive(), "Printer::~Printer() - Job is active" );
1020 :
1021 0 : delete mpPrinterOptions;
1022 :
1023 0 : ImplReleaseGraphics();
1024 0 : if ( mpInfoPrinter )
1025 0 : ImplGetSVData()->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
1026 0 : if ( mpDisplayDev )
1027 0 : delete mpDisplayDev;
1028 : else
1029 : {
1030 : // OutputDevice Dtor is tryig the same thing; that why we need to set
1031 : // the FontEntry to NULL here
1032 : // TODO: consolidate duplicate cleanup by Printer and OutputDevice
1033 0 : if ( mpFontEntry )
1034 : {
1035 0 : mpFontCache->Release( mpFontEntry );
1036 0 : mpFontEntry = NULL;
1037 : }
1038 0 : if ( mpGetDevFontList )
1039 : {
1040 0 : delete mpGetDevFontList;
1041 0 : mpGetDevFontList = NULL;
1042 : }
1043 0 : if ( mpGetDevSizeList )
1044 : {
1045 0 : delete mpGetDevSizeList;
1046 0 : mpGetDevSizeList = NULL;
1047 : }
1048 0 : delete mpFontCache;
1049 0 : mpFontCache = NULL;
1050 : // font list deleted by OutputDevice dtor
1051 : }
1052 :
1053 : // Add printer from the list
1054 0 : ImplSVData* pSVData = ImplGetSVData();
1055 0 : if ( mpPrev )
1056 0 : mpPrev->mpNext = mpNext;
1057 : else
1058 0 : pSVData->maGDIData.mpFirstPrinter = mpNext;
1059 0 : if ( mpNext )
1060 0 : mpNext->mpPrev = mpPrev;
1061 : else
1062 0 : pSVData->maGDIData.mpLastPrinter = mpPrev;
1063 0 : }
1064 :
1065 0 : sal_uLong Printer::GetCapabilities( sal_uInt16 nType ) const
1066 : {
1067 0 : if ( IsDisplayPrinter() )
1068 0 : return 0;
1069 :
1070 0 : if( mpInfoPrinter )
1071 0 : return mpInfoPrinter->GetCapabilities( maJobSetup.ImplGetConstData(), nType );
1072 : else
1073 0 : return 0;
1074 : }
1075 :
1076 0 : bool Printer::HasSupport( PrinterSupport eFeature ) const
1077 : {
1078 0 : switch ( eFeature )
1079 : {
1080 : case SUPPORT_SET_ORIENTATION:
1081 0 : return GetCapabilities( PRINTER_CAPABILITIES_SETORIENTATION ) != 0;
1082 : case SUPPORT_SET_PAPERBIN:
1083 0 : return GetCapabilities( PRINTER_CAPABILITIES_SETPAPERBIN ) != 0;
1084 : case SUPPORT_SET_PAPERSIZE:
1085 0 : return GetCapabilities( PRINTER_CAPABILITIES_SETPAPERSIZE ) != 0;
1086 : case SUPPORT_SET_PAPER:
1087 0 : return GetCapabilities( PRINTER_CAPABILITIES_SETPAPER ) != 0;
1088 : case SUPPORT_COPY:
1089 0 : return (GetCapabilities( PRINTER_CAPABILITIES_COPIES ) != 0);
1090 : case SUPPORT_COLLATECOPY:
1091 0 : return (GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES ) != 0);
1092 : case SUPPORT_SETUPDIALOG:
1093 0 : return GetCapabilities( PRINTER_CAPABILITIES_SUPPORTDIALOG ) != 0;
1094 : case SUPPORT_FAX:
1095 0 : return GetCapabilities( PRINTER_CAPABILITIES_FAX ) != 0;
1096 : case SUPPORT_PDF:
1097 0 : return GetCapabilities( PRINTER_CAPABILITIES_PDF ) != 0;
1098 : }
1099 :
1100 0 : return true;
1101 : }
1102 :
1103 0 : bool Printer::SetJobSetup( const JobSetup& rSetup )
1104 : {
1105 0 : if ( IsDisplayPrinter() || mbInPrintPage )
1106 0 : return false;
1107 :
1108 0 : JobSetup aJobSetup = rSetup;
1109 :
1110 0 : ImplReleaseGraphics();
1111 0 : if ( mpInfoPrinter->SetPrinterData( aJobSetup.ImplGetData() ) )
1112 : {
1113 0 : ImplUpdateJobSetupPaper( aJobSetup );
1114 0 : mbNewJobSetup = true;
1115 0 : maJobSetup = aJobSetup;
1116 0 : ImplUpdatePageData();
1117 0 : ImplUpdateFontList();
1118 0 : return true;
1119 : }
1120 :
1121 0 : return false;
1122 : }
1123 :
1124 0 : bool Printer::Setup( Window* pWindow )
1125 : {
1126 0 : if ( IsDisplayPrinter() )
1127 0 : return false;
1128 :
1129 0 : if ( IsJobActive() || IsPrinting() )
1130 0 : return false;
1131 :
1132 0 : JobSetup aJobSetup = maJobSetup;
1133 : SalFrame* pFrame;
1134 0 : if ( !pWindow )
1135 0 : pWindow = ImplGetDefaultWindow();
1136 0 : if( !pWindow )
1137 0 : return false;
1138 :
1139 0 : pFrame = pWindow->ImplGetFrame();
1140 0 : ImplReleaseGraphics();
1141 0 : ImplSVData* pSVData = ImplGetSVData();
1142 0 : pSVData->maAppData.mnModalMode++;
1143 0 : nImplSysDialog++;
1144 0 : bool bSetup = mpInfoPrinter->Setup( pFrame, aJobSetup.ImplGetData() );
1145 0 : pSVData->maAppData.mnModalMode--;
1146 0 : nImplSysDialog--;
1147 0 : if ( bSetup )
1148 : {
1149 0 : ImplUpdateJobSetupPaper( aJobSetup );
1150 0 : mbNewJobSetup = true;
1151 0 : maJobSetup = aJobSetup;
1152 0 : ImplUpdatePageData();
1153 0 : ImplUpdateFontList();
1154 0 : return true;
1155 : }
1156 0 : return false;
1157 : }
1158 :
1159 0 : bool Printer::SetPrinterProps( const Printer* pPrinter )
1160 : {
1161 0 : if ( IsJobActive() || IsPrinting() )
1162 0 : return false;
1163 :
1164 0 : ImplSVData* pSVData = ImplGetSVData();
1165 :
1166 0 : mbDefPrinter = pPrinter->mbDefPrinter;
1167 0 : maPrintFile = pPrinter->maPrintFile;
1168 0 : mbPrintFile = pPrinter->mbPrintFile;
1169 0 : mnCopyCount = pPrinter->mnCopyCount;
1170 0 : mbCollateCopy = pPrinter->mbCollateCopy;
1171 0 : mnPageQueueSize = pPrinter->mnPageQueueSize;
1172 0 : *mpPrinterOptions = *pPrinter->mpPrinterOptions;
1173 :
1174 0 : if ( pPrinter->IsDisplayPrinter() )
1175 : {
1176 : // Destroy old printer
1177 0 : if ( !IsDisplayPrinter() )
1178 : {
1179 0 : ImplReleaseGraphics();
1180 0 : pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
1181 0 : if ( mpFontEntry )
1182 : {
1183 0 : mpFontCache->Release( mpFontEntry );
1184 0 : mpFontEntry = NULL;
1185 : }
1186 0 : if ( mpGetDevFontList )
1187 : {
1188 0 : delete mpGetDevFontList;
1189 0 : mpGetDevFontList = NULL;
1190 : }
1191 0 : if ( mpGetDevSizeList )
1192 : {
1193 0 : delete mpGetDevSizeList;
1194 0 : mpGetDevSizeList = NULL;
1195 : }
1196 : // clean up font list
1197 0 : delete mpFontCache;
1198 0 : delete mpFontCollection;
1199 0 : mpFontCache = NULL;
1200 0 : mpFontCollection = NULL;
1201 :
1202 0 : mbInitFont = true;
1203 0 : mbNewFont = true;
1204 0 : mpInfoPrinter = NULL;
1205 : }
1206 :
1207 : // Construct new printer
1208 0 : ImplInitDisplay( NULL );
1209 0 : return true;
1210 : }
1211 :
1212 : // Destroy old printer?
1213 0 : if ( GetName() != pPrinter->GetName() )
1214 : {
1215 0 : ImplReleaseGraphics();
1216 0 : if ( mpDisplayDev )
1217 : {
1218 0 : delete mpDisplayDev;
1219 0 : mpDisplayDev = NULL;
1220 : }
1221 : else
1222 : {
1223 0 : pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter );
1224 :
1225 0 : if ( mpFontEntry )
1226 : {
1227 0 : mpFontCache->Release( mpFontEntry );
1228 0 : mpFontEntry = NULL;
1229 : }
1230 0 : if ( mpGetDevFontList )
1231 : {
1232 0 : delete mpGetDevFontList;
1233 0 : mpGetDevFontList = NULL;
1234 : }
1235 0 : if ( mpGetDevSizeList )
1236 : {
1237 0 : delete mpGetDevSizeList;
1238 0 : mpGetDevSizeList = NULL;
1239 : }
1240 0 : delete mpFontCache;
1241 0 : delete mpFontCollection;
1242 0 : mpFontCache = NULL;
1243 0 : mpFontCollection = NULL;
1244 0 : mbInitFont = true;
1245 0 : mbNewFont = true;
1246 0 : mpInfoPrinter = NULL;
1247 : }
1248 :
1249 : // Construct new printer
1250 0 : OUString aDriver = pPrinter->GetDriverName();
1251 0 : SalPrinterQueueInfo* pInfo = ImplGetQueueInfo( pPrinter->GetName(), &aDriver );
1252 0 : if ( pInfo )
1253 : {
1254 0 : ImplInit( pInfo );
1255 0 : SetJobSetup( pPrinter->GetJobSetup() );
1256 : }
1257 : else
1258 0 : ImplInitDisplay( NULL );
1259 : }
1260 : else
1261 0 : SetJobSetup( pPrinter->GetJobSetup() );
1262 :
1263 0 : return false;
1264 : }
1265 :
1266 0 : bool Printer::SetOrientation( Orientation eOrientation )
1267 : {
1268 0 : if ( mbInPrintPage )
1269 0 : return false;
1270 :
1271 0 : if ( maJobSetup.ImplGetConstData()->meOrientation != eOrientation )
1272 : {
1273 0 : JobSetup aJobSetup = maJobSetup;
1274 0 : ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1275 0 : pSetupData->meOrientation = eOrientation;
1276 :
1277 0 : if ( IsDisplayPrinter() )
1278 : {
1279 0 : mbNewJobSetup = true;
1280 0 : maJobSetup = aJobSetup;
1281 0 : return true;
1282 : }
1283 :
1284 0 : ImplReleaseGraphics();
1285 0 : if ( mpInfoPrinter->SetData( SAL_JOBSET_ORIENTATION, pSetupData ) )
1286 : {
1287 0 : ImplUpdateJobSetupPaper( aJobSetup );
1288 0 : mbNewJobSetup = true;
1289 0 : maJobSetup = aJobSetup;
1290 0 : ImplUpdatePageData();
1291 0 : ImplUpdateFontList();
1292 0 : return true;
1293 : }
1294 : else
1295 0 : return false;
1296 : }
1297 :
1298 0 : return true;
1299 : }
1300 :
1301 0 : Orientation Printer::GetOrientation() const
1302 : {
1303 0 : return maJobSetup.ImplGetConstData()->meOrientation;
1304 : }
1305 :
1306 0 : bool Printer::SetPaperBin( sal_uInt16 nPaperBin )
1307 : {
1308 0 : if ( mbInPrintPage )
1309 0 : return false;
1310 :
1311 0 : if ( (maJobSetup.ImplGetConstData()->mnPaperBin != nPaperBin) &&
1312 0 : (nPaperBin < GetPaperBinCount()) )
1313 : {
1314 0 : JobSetup aJobSetup = maJobSetup;
1315 0 : ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1316 0 : pSetupData->mnPaperBin = nPaperBin;
1317 :
1318 0 : if ( IsDisplayPrinter() )
1319 : {
1320 0 : mbNewJobSetup = true;
1321 0 : maJobSetup = aJobSetup;
1322 0 : return true;
1323 : }
1324 :
1325 0 : ImplReleaseGraphics();
1326 0 : if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERBIN, pSetupData ) )
1327 : {
1328 0 : ImplUpdateJobSetupPaper( aJobSetup );
1329 0 : mbNewJobSetup = true;
1330 0 : maJobSetup = aJobSetup;
1331 0 : ImplUpdatePageData();
1332 0 : ImplUpdateFontList();
1333 0 : return true;
1334 : }
1335 : else
1336 0 : return false;
1337 : }
1338 :
1339 0 : return true;
1340 : }
1341 :
1342 0 : sal_uInt16 Printer::GetPaperBin() const
1343 : {
1344 0 : return maJobSetup.ImplGetConstData()->mnPaperBin;
1345 : }
1346 :
1347 : // Map user paper format to a available printer paper formats
1348 0 : void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup, bool bMatchNearest )
1349 : {
1350 0 : ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1351 :
1352 0 : int nLandscapeAngle = GetLandscapeAngle();
1353 0 : int nPaperCount = GetPaperInfoCount();
1354 0 : bool bFound = false;
1355 :
1356 0 : PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight);
1357 :
1358 : // Compare all paper formats and get the appropriate one
1359 0 : for ( int i = 0; i < nPaperCount; i++ )
1360 : {
1361 0 : const PaperInfo& rPaperInfo = GetPaperInfo( i );
1362 :
1363 0 : if ( aInfo.sloppyEqual(rPaperInfo) )
1364 : {
1365 : pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
1366 0 : rPaperInfo.getHeight() );
1367 0 : pSetupData->meOrientation = ORIENTATION_PORTRAIT;
1368 0 : bFound = true;
1369 0 : break;
1370 : }
1371 : }
1372 :
1373 : // If the printer supports landscape orientation, check paper sizes again
1374 : // with landscape orientation. This is necessary as a printer driver provides
1375 : // all paper sizes with portrait orientation only!!
1376 0 : if ( pSetupData->mePaperFormat == PAPER_USER &&
1377 0 : nLandscapeAngle != 0 &&
1378 0 : HasSupport( SUPPORT_SET_ORIENTATION ))
1379 : {
1380 :
1381 0 : PaperInfo aRotatedInfo(pSetupData->mnPaperHeight, pSetupData->mnPaperWidth);
1382 :
1383 0 : for ( int i = 0; i < nPaperCount; i++ )
1384 : {
1385 0 : const PaperInfo& rPaperInfo = GetPaperInfo( i );
1386 :
1387 0 : if ( aRotatedInfo.sloppyEqual( rPaperInfo ) )
1388 : {
1389 : pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(),
1390 0 : rPaperInfo.getHeight() );
1391 0 : pSetupData->meOrientation = ORIENTATION_LANDSCAPE;
1392 0 : bFound = true;
1393 0 : break;
1394 : }
1395 : }
1396 : }
1397 :
1398 0 : if( ! bFound && bMatchNearest )
1399 : {
1400 0 : sal_Int64 nBestMatch = SAL_MAX_INT64;
1401 0 : int nBestIndex = 0;
1402 0 : Orientation eBestOrientation = ORIENTATION_PORTRAIT;
1403 0 : for( int i = 0; i < nPaperCount; i++ )
1404 : {
1405 0 : const PaperInfo& rPaperInfo = GetPaperInfo( i );
1406 :
1407 : // check portrait match
1408 0 : sal_Int64 nDX = pSetupData->mnPaperWidth - rPaperInfo.getWidth();
1409 0 : sal_Int64 nDY = pSetupData->mnPaperHeight - rPaperInfo.getHeight();
1410 0 : sal_Int64 nMatch = nDX*nDX + nDY*nDY;
1411 0 : if( nMatch < nBestMatch )
1412 : {
1413 0 : nBestMatch = nMatch;
1414 0 : nBestIndex = i;
1415 0 : eBestOrientation = ORIENTATION_PORTRAIT;
1416 : }
1417 :
1418 : // check landscape match
1419 0 : nDX = pSetupData->mnPaperWidth - rPaperInfo.getHeight();
1420 0 : nDY = pSetupData->mnPaperHeight - rPaperInfo.getWidth();
1421 0 : nMatch = nDX*nDX + nDY*nDY;
1422 0 : if( nMatch < nBestMatch )
1423 : {
1424 0 : nBestMatch = nMatch;
1425 0 : nBestIndex = i;
1426 0 : eBestOrientation = ORIENTATION_LANDSCAPE;
1427 : }
1428 : }
1429 0 : const PaperInfo& rBestInfo = GetPaperInfo( nBestIndex );
1430 : pSetupData->mePaperFormat = ImplGetPaperFormat( rBestInfo.getWidth(),
1431 0 : rBestInfo.getHeight() );
1432 0 : pSetupData->meOrientation = eBestOrientation;
1433 : }
1434 0 : }
1435 :
1436 0 : bool Printer::SetPaper( Paper ePaper )
1437 : {
1438 0 : if ( mbInPrintPage )
1439 0 : return false;
1440 :
1441 0 : if ( maJobSetup.ImplGetConstData()->mePaperFormat != ePaper )
1442 : {
1443 0 : JobSetup aJobSetup = maJobSetup;
1444 0 : ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1445 0 : pSetupData->mePaperFormat = ePaper;
1446 0 : if ( ePaper != PAPER_USER )
1447 : {
1448 0 : PaperInfo aInfo(ePaper);
1449 0 : pSetupData->mnPaperWidth = aInfo.getWidth();
1450 0 : pSetupData->mnPaperHeight = aInfo.getHeight();
1451 : }
1452 :
1453 0 : if ( IsDisplayPrinter() )
1454 : {
1455 0 : mbNewJobSetup = true;
1456 0 : maJobSetup = aJobSetup;
1457 0 : return true;
1458 : }
1459 :
1460 0 : ImplReleaseGraphics();
1461 0 : if ( ePaper == PAPER_USER )
1462 0 : ImplFindPaperFormatForUserSize( aJobSetup, false );
1463 0 : if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
1464 : {
1465 0 : ImplUpdateJobSetupPaper( aJobSetup );
1466 0 : mbNewJobSetup = true;
1467 0 : maJobSetup = aJobSetup;
1468 0 : ImplUpdatePageData();
1469 0 : ImplUpdateFontList();
1470 0 : return true;
1471 : }
1472 : else
1473 0 : return false;
1474 : }
1475 :
1476 0 : return true;
1477 : }
1478 :
1479 0 : bool Printer::SetPaperSizeUser( const Size& rSize )
1480 : {
1481 0 : return SetPaperSizeUser( rSize, false );
1482 : }
1483 :
1484 0 : bool Printer::SetPaperSizeUser( const Size& rSize, bool bMatchNearest )
1485 : {
1486 0 : if ( mbInPrintPage )
1487 0 : return false;
1488 :
1489 0 : const Size aPixSize = LogicToPixel( rSize );
1490 0 : const Size aPageSize = PixelToLogic( aPixSize, MAP_100TH_MM );
1491 0 : bool bNeedToChange(maJobSetup.ImplGetConstData()->mnPaperWidth != aPageSize.Width() ||
1492 0 : maJobSetup.ImplGetConstData()->mnPaperHeight != aPageSize.Height());
1493 :
1494 0 : if(!bNeedToChange)
1495 : {
1496 : // #i122984# only need to change when Paper is different from PAPER_USER and
1497 : // the mapped Paper which will created below in the call to ImplFindPaperFormatForUserSize
1498 : // and will replace maJobSetup.ImplGetConstData()->mePaperFormat. This leads to
1499 : // unnecessary JobSetups, e.g. when printing a multi-page fax, but also with
1500 : // normal print
1501 0 : const Paper aPaper = ImplGetPaperFormat(aPageSize.Width(), aPageSize.Height());
1502 :
1503 0 : bNeedToChange = maJobSetup.ImplGetConstData()->mePaperFormat != PAPER_USER &&
1504 0 : maJobSetup.ImplGetConstData()->mePaperFormat != aPaper;
1505 : }
1506 :
1507 0 : if(bNeedToChange)
1508 : {
1509 0 : JobSetup aJobSetup = maJobSetup;
1510 0 : ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1511 0 : pSetupData->mePaperFormat = PAPER_USER;
1512 0 : pSetupData->mnPaperWidth = aPageSize.Width();
1513 0 : pSetupData->mnPaperHeight = aPageSize.Height();
1514 :
1515 0 : if ( IsDisplayPrinter() )
1516 : {
1517 0 : mbNewJobSetup = true;
1518 0 : maJobSetup = aJobSetup;
1519 0 : return true;
1520 : }
1521 :
1522 0 : ImplReleaseGraphics();
1523 0 : ImplFindPaperFormatForUserSize( aJobSetup, bMatchNearest );
1524 :
1525 : // Changing the paper size can also change the orientation!
1526 0 : if ( mpInfoPrinter->SetData( SAL_JOBSET_PAPERSIZE|SAL_JOBSET_ORIENTATION, pSetupData ) )
1527 : {
1528 0 : ImplUpdateJobSetupPaper( aJobSetup );
1529 0 : mbNewJobSetup = true;
1530 0 : maJobSetup = aJobSetup;
1531 0 : ImplUpdatePageData();
1532 0 : ImplUpdateFontList();
1533 0 : return true;
1534 : }
1535 : else
1536 0 : return false;
1537 : }
1538 :
1539 0 : return true;
1540 : }
1541 :
1542 0 : int Printer::GetPaperInfoCount() const
1543 : {
1544 0 : if( ! mpInfoPrinter )
1545 0 : return 0;
1546 0 : if( ! mpInfoPrinter->m_bPapersInit )
1547 0 : mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
1548 0 : return mpInfoPrinter->m_aPaperFormats.size();
1549 : }
1550 :
1551 0 : OUString Printer::GetPaperName( Paper ePaper )
1552 : {
1553 0 : ImplSVData* pSVData = ImplGetSVData();
1554 0 : if( ! pSVData->mpPaperNames )
1555 : {
1556 0 : pSVData->mpPaperNames = new boost::unordered_map< int, OUString >();
1557 0 : if( ImplGetResMgr() )
1558 : {
1559 0 : ResStringArray aPaperStrings( VclResId( RID_STR_PAPERNAMES ) );
1560 : static const int PaperIndex[] =
1561 : {
1562 : PAPER_A0, PAPER_A1, PAPER_A2, PAPER_A3, PAPER_A4, PAPER_A5,
1563 : PAPER_B4_ISO, PAPER_B5_ISO, PAPER_LETTER, PAPER_LEGAL, PAPER_TABLOID,
1564 : PAPER_USER, PAPER_B6_ISO, PAPER_ENV_C4, PAPER_ENV_C5, PAPER_ENV_C6, PAPER_ENV_C65,
1565 : PAPER_ENV_DL, PAPER_SLIDE_DIA, PAPER_C, PAPER_D, PAPER_E,
1566 : PAPER_EXECUTIVE, PAPER_FANFOLD_LEGAL_DE, PAPER_ENV_MONARCH, PAPER_ENV_PERSONAL,
1567 : PAPER_ENV_9, PAPER_ENV_10, PAPER_ENV_11, PAPER_ENV_12, PAPER_KAI16,
1568 : PAPER_KAI32, PAPER_KAI32BIG, PAPER_B4_JIS, PAPER_B5_JIS, PAPER_B6_JIS,
1569 : PAPER_POSTCARD_JP
1570 : };
1571 : OSL_ENSURE( sal_uInt32(SAL_N_ELEMENTS(PaperIndex)) == aPaperStrings.Count(), "localized paper name count wrong" );
1572 0 : for( int i = 0; i < int(SAL_N_ELEMENTS(PaperIndex)); i++ )
1573 0 : (*pSVData->mpPaperNames)[PaperIndex[i]] = aPaperStrings.GetString(i);
1574 : }
1575 : }
1576 :
1577 0 : boost::unordered_map<int,OUString>::const_iterator it = pSVData->mpPaperNames->find( (int)ePaper );
1578 0 : return (it != pSVData->mpPaperNames->end()) ? it->second : OUString();
1579 : }
1580 :
1581 0 : OUString Printer::GetPaperName( bool i_bPaperUser ) const
1582 : {
1583 0 : Size aPageSize = PixelToLogic( GetPaperSizePixel(), MAP_100TH_MM );
1584 0 : Paper ePaper = ImplGetPaperFormat( aPageSize.Width(), aPageSize.Height() );
1585 0 : if( ePaper == PAPER_USER )
1586 0 : ePaper = ImplGetPaperFormat( aPageSize.Height(), aPageSize.Width() );
1587 0 : return (ePaper != PAPER_USER || i_bPaperUser ) ? GetPaperName( ePaper ) : OUString();
1588 : }
1589 :
1590 0 : const PaperInfo& Printer::GetPaperInfo( int nPaper ) const
1591 : {
1592 0 : if( ! mpInfoPrinter )
1593 0 : return ImplGetEmptyPaper();
1594 0 : if( ! mpInfoPrinter->m_bPapersInit )
1595 0 : mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() );
1596 0 : if( mpInfoPrinter->m_aPaperFormats.empty() || nPaper < 0 || nPaper >= int(mpInfoPrinter->m_aPaperFormats.size()) )
1597 0 : return ImplGetEmptyPaper();
1598 0 : return mpInfoPrinter->m_aPaperFormats[nPaper];
1599 : }
1600 :
1601 0 : bool Printer::SetDuplexMode( DuplexMode eDuplex )
1602 : {
1603 0 : if ( mbInPrintPage )
1604 0 : return false;
1605 :
1606 0 : if ( maJobSetup.ImplGetConstData()->meDuplexMode != eDuplex )
1607 : {
1608 0 : JobSetup aJobSetup = maJobSetup;
1609 0 : ImplJobSetup* pSetupData = aJobSetup.ImplGetData();
1610 0 : pSetupData->meDuplexMode = eDuplex;
1611 :
1612 0 : if ( IsDisplayPrinter() )
1613 : {
1614 0 : mbNewJobSetup = true;
1615 0 : maJobSetup = aJobSetup;
1616 0 : return true;
1617 : }
1618 :
1619 0 : ImplReleaseGraphics();
1620 0 : if ( mpInfoPrinter->SetData( SAL_JOBSET_DUPLEXMODE, pSetupData ) )
1621 : {
1622 0 : ImplUpdateJobSetupPaper( aJobSetup );
1623 0 : mbNewJobSetup = true;
1624 0 : maJobSetup = aJobSetup;
1625 0 : ImplUpdatePageData();
1626 0 : ImplUpdateFontList();
1627 0 : return true;
1628 : }
1629 : else
1630 0 : return false;
1631 : }
1632 :
1633 0 : return true;
1634 : }
1635 :
1636 0 : int Printer::GetLandscapeAngle() const
1637 : {
1638 0 : return mpInfoPrinter ? mpInfoPrinter->GetLandscapeAngle( maJobSetup.ImplGetConstData() ) : 900;
1639 : }
1640 :
1641 0 : Paper Printer::GetPaper() const
1642 : {
1643 0 : return maJobSetup.ImplGetConstData()->mePaperFormat;
1644 : }
1645 :
1646 0 : sal_uInt16 Printer::GetPaperBinCount() const
1647 : {
1648 0 : if ( IsDisplayPrinter() )
1649 0 : return 0;
1650 :
1651 0 : return (sal_uInt16)mpInfoPrinter->GetPaperBinCount( maJobSetup.ImplGetConstData() );
1652 : }
1653 :
1654 0 : OUString Printer::GetPaperBinName( sal_uInt16 nPaperBin ) const
1655 : {
1656 0 : if ( IsDisplayPrinter() )
1657 0 : return OUString();
1658 :
1659 0 : if ( nPaperBin < GetPaperBinCount() )
1660 0 : return mpInfoPrinter->GetPaperBinName( maJobSetup.ImplGetConstData(), nPaperBin );
1661 : else
1662 0 : return OUString();
1663 : }
1664 :
1665 0 : bool Printer::SetCopyCount( sal_uInt16 nCopy, bool bCollate )
1666 : {
1667 0 : mnCopyCount = nCopy;
1668 0 : mbCollateCopy = bCollate;
1669 0 : return true;
1670 : }
1671 :
1672 0 : void Printer::Error()
1673 : {
1674 0 : maErrorHdl.Call( this );
1675 0 : }
1676 :
1677 0 : sal_uLong Printer::ImplSalPrinterErrorCodeToVCL( sal_uLong nError )
1678 : {
1679 : sal_uLong nVCLError;
1680 0 : switch ( nError )
1681 : {
1682 : case 0:
1683 0 : nVCLError = PRINTER_OK;
1684 0 : break;
1685 : case SAL_PRINTER_ERROR_ABORT:
1686 0 : nVCLError = PRINTER_ABORT;
1687 0 : break;
1688 : default:
1689 0 : nVCLError = PRINTER_GENERALERROR;
1690 0 : break;
1691 : }
1692 :
1693 0 : return nVCLError;
1694 : }
1695 :
1696 0 : bool Printer::EndJob()
1697 : {
1698 0 : bool bRet = false;
1699 0 : if ( !IsJobActive() )
1700 0 : return bRet;
1701 :
1702 : DBG_ASSERT( !mbInPrintPage, "Printer::EndJob() - StartPage() without EndPage() called" );
1703 :
1704 0 : mbJobActive = false;
1705 :
1706 0 : if ( mpPrinter )
1707 : {
1708 0 : ImplReleaseGraphics();
1709 :
1710 0 : mnCurPage = 0;
1711 :
1712 0 : mbPrinting = false;
1713 0 : mnCurPrintPage = 0;
1714 0 : maJobName = OUString();
1715 :
1716 0 : mbDevOutput = false;
1717 0 : bRet = mpPrinter->EndJob();
1718 : // FIXME: Do not destroy the printer asynchronously as Win95
1719 : // can't handle destroying a printer object and printing
1720 : // at the same time
1721 0 : ImplGetSVData()->mpDefInst->DestroyPrinter( mpPrinter );
1722 0 : mpPrinter = NULL;
1723 : }
1724 :
1725 0 : return bRet;
1726 : }
1727 :
1728 0 : void Printer::ImplStartPage()
1729 : {
1730 0 : if ( !IsJobActive() )
1731 0 : return;
1732 :
1733 0 : if ( mpPrinter )
1734 : {
1735 0 : SalGraphics* pGraphics = mpPrinter->StartPage( maJobSetup.ImplGetConstData(), mbNewJobSetup );
1736 0 : if ( pGraphics )
1737 : {
1738 0 : ImplReleaseGraphics();
1739 0 : mpJobGraphics = pGraphics;
1740 : }
1741 0 : mbDevOutput = true;
1742 :
1743 : // PrintJob not aborted ???
1744 0 : if ( IsJobActive() )
1745 : {
1746 0 : mbInPrintPage = true;
1747 0 : mnCurPage++;
1748 0 : mnCurPrintPage++;
1749 : }
1750 : }
1751 : }
1752 :
1753 0 : void Printer::ImplEndPage()
1754 : {
1755 0 : if ( !IsJobActive() )
1756 0 : return;
1757 :
1758 0 : mbInPrintPage = false;
1759 :
1760 0 : if ( mpPrinter )
1761 : {
1762 0 : mpPrinter->EndPage();
1763 0 : ImplReleaseGraphics();
1764 0 : mbDevOutput = false;
1765 :
1766 0 : mpJobGraphics = NULL;
1767 0 : mbNewJobSetup = false;
1768 : }
1769 : }
1770 :
1771 0 : void Printer::updatePrinters()
1772 : {
1773 0 : ImplSVData* pSVData = ImplGetSVData();
1774 0 : ImplPrnQueueList* pPrnList = pSVData->maGDIData.mpPrinterQueueList;
1775 :
1776 0 : if ( pPrnList )
1777 : {
1778 0 : ImplPrnQueueList* pNewList = new ImplPrnQueueList;
1779 0 : pSVData->mpDefInst->GetPrinterQueueInfo( pNewList );
1780 :
1781 0 : bool bChanged = pPrnList->m_aQueueInfos.size() != pNewList->m_aQueueInfos.size();
1782 0 : for( unsigned int i = 0; ! bChanged && i < pPrnList->m_aQueueInfos.size(); i++ )
1783 : {
1784 0 : ImplPrnQueueData& rInfo = pPrnList->m_aQueueInfos[i];
1785 0 : ImplPrnQueueData& rNewInfo = pNewList->m_aQueueInfos[i];
1786 0 : if( ! rInfo.mpSalQueueInfo || ! rNewInfo.mpSalQueueInfo || // sanity check
1787 0 : rInfo.mpSalQueueInfo->maPrinterName != rNewInfo.mpSalQueueInfo->maPrinterName )
1788 : {
1789 0 : bChanged = true;
1790 : }
1791 : }
1792 0 : if( bChanged )
1793 : {
1794 0 : ImplDeletePrnQueueList();
1795 0 : pSVData->maGDIData.mpPrinterQueueList = pNewList;
1796 :
1797 0 : Application* pApp = GetpApp();
1798 0 : if( pApp )
1799 : {
1800 0 : DataChangedEvent aDCEvt( DATACHANGED_PRINTER );
1801 0 : pApp->DataChanged( aDCEvt );
1802 0 : pApp->NotifyAllWindows( aDCEvt );
1803 : }
1804 : }
1805 : else
1806 0 : delete pNewList;
1807 : }
1808 0 : }
1809 :
1810 0 : bool Printer::UsePolyPolygonForComplexGradient()
1811 : {
1812 0 : return true;
1813 : }
1814 :
1815 0 : void Printer::ClipAndDrawGradientMetafile ( const Gradient &rGradient, const PolyPolygon &rPolyPoly )
1816 : {
1817 0 : const Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
1818 :
1819 0 : Push( PUSH_CLIPREGION );
1820 0 : IntersectClipRegion(Region(rPolyPoly));
1821 0 : DrawGradient( aBoundRect, rGradient );
1822 0 : Pop();
1823 3 : }
1824 :
1825 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|