diff options
author | Vladimir Glazunov <vg@openoffice.org> | 2010-10-14 14:43:27 +0200 |
---|---|---|
committer | Vladimir Glazunov <vg@openoffice.org> | 2010-10-14 14:43:27 +0200 |
commit | f330de104e33e41150d46578e786d522aa1d3822 (patch) | |
tree | c0ff841eb8965f08f7e4c1395c98d3cadca0f23d | |
parent | 230ae5e24da02822247a301d0582d0aaa722bf34 (diff) | |
parent | 039c16253801f3d2e3d446765863f406d633a6c9 (diff) |
CWS-TOOLING: integrate CWS pdfprint
29 files changed, 1823 insertions, 1033 deletions
diff --git a/padmin/source/prtsetup.cxx b/padmin/source/prtsetup.cxx index 17d28515e540..8165b8015403 100644 --- a/padmin/source/prtsetup.cxx +++ b/padmin/source/prtsetup.cxx @@ -198,6 +198,7 @@ IMPL_LINK( RTSDialog, ClickButton, Button*, pButton ) m_aJobData.m_nColorDepth = m_pDevicePage->getDepth(); m_aJobData.m_nColorDevice = m_pDevicePage->getColorDevice(); m_aJobData.m_nPSLevel = m_pDevicePage->getLevel(); + m_aJobData.m_nPDFDevice = m_pDevicePage->getPDFDevice(); } if( m_pOtherPage ) // write other settings @@ -363,8 +364,8 @@ RTSDevicePage::RTSDevicePage( RTSDialog* pParent ) : m_aPPDKeyBox( this, PaResId( RID_RTS_DEVICE_PPDKEY_BOX ) ), m_aPPDValueText( this, PaResId( RID_RTS_DEVICE_PPDVALUE_TXT ) ), m_aPPDValueBox( this, PaResId( RID_RTS_DEVICE_PPDVALUE_BOX ) ), - m_aLevelText( this, PaResId( RID_RTS_DEVICE_LEVEL_TXT ) ), - m_aLevelBox( this, PaResId( RID_RTS_DEVICE_LEVEL_BOX ) ), + m_aLevelText( this, PaResId( RID_RTS_DEVICE_PRINTLANG_TXT ) ), + m_aLevelBox( this, PaResId( RID_RTS_DEVICE_PRINTLANG_BOX ) ), m_aSpaceText( this, PaResId( RID_RTS_DEVICE_SPACE_TXT ) ), m_aSpaceBox( this, PaResId( RID_RTS_DEVICE_SPACE_BOX ) ), m_aDepthText( this, PaResId( RID_RTS_DEVICE_DEPTH_TXT ) ), @@ -385,13 +386,19 @@ RTSDevicePage::RTSDevicePage( RTSDialog* pParent ) : case 1: m_aSpaceBox.SelectEntry( m_aSpaceColor );break; } - m_aLevelBox.InsertEntry( m_pParent->m_aFromDriverString ); - m_aLevelBox.InsertEntry( String( RTL_CONSTASCII_USTRINGPARAM( "1" ) ) ); - m_aLevelBox.InsertEntry( String( RTL_CONSTASCII_USTRINGPARAM( "2" ) ) ); - if( m_pParent->m_aJobData.m_nPSLevel == 0 ) - m_aLevelBox.SelectEntry( m_pParent->m_aFromDriverString ); + ULONG nLevelEntryData = 0; + if( m_pParent->m_aJobData.m_nPDFDevice > 0 ) + nLevelEntryData = 10; else - m_aLevelBox.SelectEntry( String::CreateFromInt32( m_pParent->m_aJobData.m_nPSLevel ) ); + nLevelEntryData = m_pParent->m_aJobData.m_nPSLevel+1; + for( USHORT i = 0; i < m_aLevelBox.GetEntryCount(); i++ ) + { + if( (ULONG)m_aLevelBox.GetEntryData( i ) == nLevelEntryData ) + { + m_aLevelBox.SelectEntryPos( i ); + break; + } + } m_aDepthBox.SelectEntry( String::CreateFromInt32( m_pParent->m_aJobData.m_nColorDepth ).AppendAscii( " Bit" ) ); @@ -430,6 +437,22 @@ void RTSDevicePage::update() // ------------------------------------------------------------------ +ULONG RTSDevicePage::getLevel() +{ + ULONG nLevel = (ULONG)m_aLevelBox.GetEntryData( m_aLevelBox.GetSelectEntryPos() ); + return nLevel < 10 ? nLevel-1 : 0; +} + +// ------------------------------------------------------------------ + +ULONG RTSDevicePage::getPDFDevice() +{ + ULONG nLevel = (ULONG)m_aLevelBox.GetEntryData( m_aLevelBox.GetSelectEntryPos() ); + return nLevel > 9 ? 1 : 0; +} + +// ------------------------------------------------------------------ + IMPL_LINK( RTSDevicePage, SelectHdl, ListBox*, pBox ) { if( pBox == &m_aPPDKeyBox ) diff --git a/padmin/source/prtsetup.hxx b/padmin/source/prtsetup.hxx index 65288f738482..72e3d81ee8d7 100644 --- a/padmin/source/prtsetup.hxx +++ b/padmin/source/prtsetup.hxx @@ -147,7 +147,8 @@ public: void update(); - ULONG getLevel() { return m_aLevelBox.GetSelectEntry().ToInt32(); } + ULONG getLevel(); + ULONG getPDFDevice(); ULONG getDepth() { return m_aDepthBox.GetSelectEntry().ToInt32(); } ULONG getColorDevice() { diff --git a/padmin/source/rtsetup.hrc b/padmin/source/rtsetup.hrc index 30439088de8e..7b6677de7ec4 100644 --- a/padmin/source/rtsetup.hrc +++ b/padmin/source/rtsetup.hrc @@ -48,13 +48,13 @@ #define RID_RTS_DEVICEPAGE 4003 #define RID_RTS_DEVICE_COLOR_TXT 1 -#define RID_RTS_DEVICE_GRAY_TXT 2 +#define RID_RTS_DEVICE_GRAY_TXT 2 #define RID_RTS_DEVICE_PPDKEY_TXT 3 #define RID_RTS_DEVICE_PPDKEY_BOX 4 -#define RID_RTS_DEVICE_PPDVALUE_TXT 5 -#define RID_RTS_DEVICE_PPDVALUE_BOX 6 -#define RID_RTS_DEVICE_LEVEL_TXT 7 -#define RID_RTS_DEVICE_LEVEL_BOX 8 +#define RID_RTS_DEVICE_PPDVALUE_TXT 5 +#define RID_RTS_DEVICE_PPDVALUE_BOX 6 +#define RID_RTS_DEVICE_PRINTLANG_TXT 7 +#define RID_RTS_DEVICE_PRINTLANG_BOX 8 #define RID_RTS_DEVICE_SPACE_TXT 9 #define RID_RTS_DEVICE_SPACE_BOX 10 #define RID_RTS_DEVICE_DEPTH_TXT 11 diff --git a/padmin/source/rtsetup.src b/padmin/source/rtsetup.src index e04374a72245..e2e9a4c8aea3 100644 --- a/padmin/source/rtsetup.src +++ b/padmin/source/rtsetup.src @@ -173,17 +173,25 @@ TabPage RID_RTS_DEVICEPAGE Size = MAP_APPFONT( 105, 111 ); }; - FixedText RID_RTS_DEVICE_LEVEL_TXT + FixedText RID_RTS_DEVICE_PRINTLANG_TXT { Pos = MAP_APPFONT( 5, 130 ); Size = MAP_APPFONT( 80, 8 ); - Text [ en-US ] = "PostScript ~Level"; + Text [ en-US ] = "Printer ~Language type"; }; - ListBox RID_RTS_DEVICE_LEVEL_BOX + ListBox RID_RTS_DEVICE_PRINTLANG_BOX { DropDown = TRUE; Pos = MAP_APPFONT( 120, 130 ); Size = MAP_APPFONT( 105, 200 ); + StringList [en-US] = + { + < "PostScript (Level from driver)" ; 1; > ; + < "PostScript Level 1" ; 2; > ; + < "PostScript Level 2"; 3; > ; + < "PostScript Level 3"; 3; > ; + < "PDF"; 10; > ; + }; }; FixedText RID_RTS_DEVICE_SPACE_TXT { diff --git a/svtools/inc/svtools/filter.hxx b/svtools/inc/svtools/filter.hxx index 49ec77adfea5..8c6f014d4219 100644 --- a/svtools/inc/svtools/filter.hxx +++ b/svtools/inc/svtools/filter.hxx @@ -134,16 +134,6 @@ class Graphic; #define GFF_EMF ( (USHORT)0x00f8 ) #define GFF_XXX ( (USHORT)0xffff ) -// --------------- -// - RequestInfo - -// --------------- - -struct RequestInfo -{ - BYTE* pBuffer; - ULONG nRealBufferSize; -}; - // --------------------- // - GraphicDescriptor - // --------------------- @@ -151,29 +141,18 @@ struct RequestInfo class SVT_DLLPUBLIC GraphicDescriptor { SvStream* pFileStm; - Link aReqLink; + String aPathExt; Size aPixSize; Size aLogSize; - SvStream* pMemStm; - SvStream* pBaseStm; - ULONG nStmPos; USHORT nBitsPerPixel; USHORT nPlanes; USHORT nFormat; BOOL bCompressed; - BOOL bDataReady; - BOOL bLinked; - BOOL bLinkChanged; - BOOL bWideSearch; - BOOL bBaseStm; - long nExtra1; - long nExtra2; + BOOL bOwnStream; void ImpConstruct(); -//#if 0 // _SOLAR__PRIVATE - BOOL ImpDetectBMP( SvStream& rStm, BOOL bExtendedInfo ); BOOL ImpDetectGIF( SvStream& rStm, BOOL bExtendedInfo ); BOOL ImpDetectJPG( SvStream& rStm, BOOL bExtendedInfo ); @@ -199,27 +178,11 @@ class SVT_DLLPUBLIC GraphicDescriptor BOOL ImpDetectSGV( SvStream& rStm, BOOL bExtendedInfo ); BOOL ImpDetectEMF( SvStream& rStm, BOOL bExtendedInfo ); -//#endif - GraphicDescriptor( const GraphicDescriptor& ); GraphicDescriptor& operator=( const GraphicDescriptor& ); -protected: - - BOOL IsDataReady() const; - BOOL IsWideSearch() const; - SvStream& GetSearchStream() const; - const String& GetPathExtension() const; - public: - // Default-Ctor, um anschliessend einen Link zu setzen, mit dem - // die Daten vom Aufrufer im ::Detect() angefordert werden. - // da einige Formate ( Mtf's ) keinen eindeutigen Header besitzen, - // ist es sinnvoll den vollen Filenamen (inkl. Ext. ) mitanzugeben, - // da so das Format ueber die Extension ermittelt werden kann - GraphicDescriptor( const String* pPath = NULL ); - // Ctor, um einen Filenamen zu setzen. Es muss ::Detect() gerufen werden, // um das File zu identifizieren; // wenn das File keinen eindeutigen Header besitzt ( Mtf's ) wird das @@ -261,21 +224,6 @@ public: // zeigt an, ob das Bild evtl. komprimiert (wie auch immer) ist BOOL IsCompressed() const { return bCompressed; } - // setzt den LinkHdl zum Setzen der Bytes; - // der Handler muss einen Pointer auf die RequestInfo-Struktur - // zurueckgeben; die Anzahl der minimal zur Verfuegung zu stellenden - // Daten muss im Handler ueber ::GetRequestedByteCount() erfragt werden; - // die tatsaechlich zur Verfuegung gestellte BYTE-Anzahl - // wird in der RequestInfo-Struktur gesetzt - void SetRequestHdl( const Link& rRequestHdl ); - - // gibt den LinkHdl zum Setzen der Bytes zurueck - const Link& GetRequestHdl() const { return aReqLink; } - - // muss im ReqHdl gerufen werden, um zu erfahren, wieviele - // Bytes _mindestens_ bereitgestellt werden muessen - ULONG GetRequestedByteCount() const; - // gibt die Filternummer des Filters zurueck, // der im GraphicFilter zum Lesen dieses Formats // benoetigt wird diff --git a/svtools/source/filter.vcl/filter/filter2.cxx b/svtools/source/filter.vcl/filter/filter2.cxx index 6abab2626516..d91ec1a19772 100644 --- a/svtools/source/filter.vcl/filter/filter2.cxx +++ b/svtools/source/filter.vcl/filter/filter2.cxx @@ -42,29 +42,6 @@ BYTE* ImplSearchEntry( BYTE* , BYTE* , ULONG , ULONG ); - -/************************************************************************* -|* -|* -|* -\************************************************************************/ - -GraphicDescriptor::GraphicDescriptor( const String* pPath ) : - pFileStm ( NULL ) -{ - ImpConstruct(); - - if ( pPath ) - { - INetURLObject aURL( *pPath, INET_PROT_FILE ); - aPathExt = aURL.GetFileExtension().toAsciiLowerCase(); - } - bLinked = TRUE; - bLinkChanged = FALSE; - bWideSearch = FALSE; -} - - /************************************************************************* |* |* @@ -73,19 +50,10 @@ GraphicDescriptor::GraphicDescriptor( const String* pPath ) : GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) : pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ) ), - aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ) + aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ), + bOwnStream( TRUE ) { - if ( pFileStm ) - { - nStmPos = 0; - pFileStm->Seek( nStmPos ); - bDataReady = TRUE; - } - ImpConstruct(); - - if ( pFileStm && !pFileStm->GetError() ) - bDataReady = TRUE; } /************************************************************************* @@ -95,7 +63,8 @@ GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) : \************************************************************************/ GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) : - pFileStm ( NULL ) + pFileStm ( &rInStream ), + bOwnStream ( FALSE ) { ImpConstruct(); @@ -104,15 +73,8 @@ GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) INetURLObject aURL( *pPath ); aPathExt = aURL.GetFileExtension().toAsciiLowerCase(); } - nStmPos = rInStream.Tell(); - pBaseStm = &rInStream; - bBaseStm = TRUE; - - if ( !pBaseStm->GetError() ) - bDataReady = TRUE; } - /************************************************************************* |* |* @@ -121,10 +83,10 @@ GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) GraphicDescriptor::~GraphicDescriptor() { - delete pFileStm; + if ( bOwnStream ) + delete pFileStm; } - /************************************************************************* |* |* @@ -134,22 +96,9 @@ GraphicDescriptor::~GraphicDescriptor() BOOL GraphicDescriptor::Detect( BOOL bExtendedInfo ) { BOOL bRet = FALSE; - - // Link-Status ueberpruefen - if ( bLinked && bLinkChanged ) - { - DBG_ASSERT( aReqLink.IsSet(), "Wo ist der RequestHandler???" ); - pMemStm = (SvStream*) aReqLink.Call( this ); - if ( pMemStm ) - { - nStmPos = pMemStm->Tell(); - bDataReady = TRUE; - } - } - - if ( bDataReady ) + if ( pFileStm && !pFileStm->GetError() ) { - SvStream& rStm = GetSearchStream(); + SvStream& rStm = *pFileStm; UINT16 nOldFormat = rStm.GetNumberFormatInt(); if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = TRUE; @@ -175,96 +124,13 @@ BOOL GraphicDescriptor::Detect( BOOL bExtendedInfo ) else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = TRUE; else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = TRUE; else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = TRUE; - - // diese Formate lassen sich nur bei WideSearch im gesamten - // Stream ermitteln - else if ( bWideSearch ) - { - if ( ImpDetectPCD( rStm, bExtendedInfo ) ) - bRet = TRUE; - } + else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = TRUE; rStm.SetNumberFormatInt( nOldFormat ); - rStm.Seek( nStmPos ); } - return bRet; } - -/************************************************************************* -|* -|* -|* -\************************************************************************/ - -BOOL GraphicDescriptor::IsDataReady() const -{ - return bDataReady; -} - - -/************************************************************************* -|* -|* -|* -\************************************************************************/ - -BOOL GraphicDescriptor::IsWideSearch() const -{ - return bWideSearch; -} - - -/************************************************************************* -|* -|* -|* -\************************************************************************/ - -SvStream& GraphicDescriptor::GetSearchStream() const -{ - DBG_ASSERT( bDataReady, "Was laeuft hier falsch???" ); - - if ( bLinked ) - return *pMemStm; - else if ( bBaseStm ) - return *pBaseStm; - else - return *pFileStm; -} - - -/************************************************************************* -|* -|* -|* -\************************************************************************/ - -void GraphicDescriptor::SetRequestHdl( const Link& rRequestLink ) -{ - aReqLink = rRequestLink; - bLinkChanged = TRUE; -} - - -/************************************************************************* -|* -|* -|* -\************************************************************************/ - -ULONG GraphicDescriptor::GetRequestedByteCount() const -{ - return DATA_SIZE; -} - - -/******************************************************************************/ -/* IMP-Methoden */ -/* */ - - /************************************************************************* |* |* @@ -273,17 +139,10 @@ ULONG GraphicDescriptor::GetRequestedByteCount() const void GraphicDescriptor::ImpConstruct() { - if ( !pFileStm ) - pFileStm = new SvStream(); nFormat = GFF_NOT; nBitsPerPixel = 0; nPlanes = 0; bCompressed = FALSE; - bDataReady = FALSE; - bLinked = FALSE; - bWideSearch = TRUE; - bBaseStm = FALSE; - pMemStm = NULL; } @@ -297,10 +156,9 @@ BOOL GraphicDescriptor::ImpDetectBMP( SvStream& rStm, BOOL bExtendedInfo ) { UINT16 nTemp16; BOOL bRet = FALSE; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - rStm.Seek( nStmPos ); - rStm >> nTemp16; // OS/2-BitmapArray @@ -364,7 +222,7 @@ BOOL GraphicDescriptor::ImpDetectBMP( SvStream& rStm, BOOL bExtendedInfo ) } } } - + rStm.Seek( nStmPos ); return bRet; } @@ -382,10 +240,10 @@ BOOL GraphicDescriptor::ImpDetectGIF( SvStream& rStm, BOOL bExtendedInfo ) BOOL bRet = FALSE; BYTE cByte; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - rStm.Seek( nStmPos ); - rStm >> n32; + if ( n32 == 0x38464947 ) { rStm >> n16; @@ -412,7 +270,7 @@ BOOL GraphicDescriptor::ImpDetectGIF( SvStream& rStm, BOOL bExtendedInfo ) } } } - + rStm.Seek( nStmPos ); return bRet; } @@ -423,125 +281,188 @@ BOOL GraphicDescriptor::ImpDetectGIF( SvStream& rStm, BOOL bExtendedInfo ) |* \************************************************************************/ +// returns the next jpeg marker, a return value of 0 represents an error +sal_uInt8 ImpDetectJPG_GetNextMarker( SvStream& rStm ) +{ + sal_uInt8 nByte; + do + { + do + { + rStm >> nByte; + if ( rStm.IsEof() || rStm.GetError() ) // as 0 is not allowed as marker, + return 0; // we can use it as errorcode + } + while ( nByte != 0xff ); + do + { + rStm >> nByte; + if ( rStm.IsEof() || rStm.GetError() ) + return 0; + } + while( nByte == 0xff ); + } + while( nByte == 0 ); // 0xff00 represents 0xff and not a marker, + // the marker detection has to be restartet. + return nByte; +} + BOOL GraphicDescriptor::ImpDetectJPG( SvStream& rStm, BOOL bExtendedInfo ) { UINT32 nTemp32; BOOL bRet = FALSE; - BYTE cByte = 0; - BOOL bM_COM; - rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); - rStm.Seek( nStmPos ); + sal_Int32 nStmPos = rStm.Tell(); + rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); rStm >> nTemp32; - // compare upper 28 bits + // compare upper 24 bits if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) ) { nFormat = GFF_JPG; - return TRUE; - } - - bM_COM = ( nTemp32 == 0xffd8fffe ); - if ( ( nTemp32 == 0xffd8ffe0 ) || bM_COM ) - { - if( !bM_COM ) - { - rStm.SeekRel( 2 ); - rStm >> nTemp32; - } + bRet = TRUE; - if( bM_COM || ( nTemp32 == 0x4a464946 ) ) + if ( bExtendedInfo ) { - nFormat = GFF_JPG; - bRet = TRUE; + rStm.SeekRel( -2 ); - if( bExtendedInfo ) - { - MapMode aMap; - UINT16 nTemp16; - ULONG nCount = 9; - ULONG nMax; - ULONG nResX; - ULONG nResY; - BYTE cUnit; - - // Groesse des verbleibenden Puffers ermitteln - if ( bLinked ) - nMax = static_cast< SvMemoryStream& >(rStm).GetEndOfData() - - 16; - else - nMax = DATA_SIZE - 16; - - // max. 8K - nMax = Min( nMax, (ULONG) 8192 ); + sal_uInt32 nError( rStm.GetError() ); - // Res-Unit ermitteln - rStm.SeekRel( 3 ); - rStm >> cUnit; - - // ResX ermitteln - rStm >> nTemp16; - nResX = nTemp16; + sal_Bool bScanFailure = sal_False; + sal_Bool bScanFinished = sal_False; - // ResY ermitteln - rStm >> nTemp16; - nResY = nTemp16; - - // SOF0/1-Marker finden, aber dabei - // nicht mehr als DATA_SIZE Pixel lesen, falls - // kein WideSearch - do + while( !bScanFailure && !bScanFinished && !rStm.IsEof() && !rStm.GetError() ) + { + sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm ); + switch( nMarker ) { - while ( ( cByte != 0xff ) && - ( bWideSearch || ( nCount++ < nMax ) ) ) + // fixed size marker, not having a two byte length parameter + case 0xd0 : // RST0 + case 0xd1 : + case 0xd2 : + case 0xd3 : + case 0xd4 : + case 0xd5 : + case 0xd6 : + case 0xd7 : // RST7 + case 0x01 : // TEM + break; + + case 0xd8 : // SOI (has already been checked, there should not be a second one) + case 0x00 : // marker is invalid, we should stop now + bScanFailure = sal_True; + break; + + case 0xd9 : // EOI + bScanFinished = sal_True; + break; + + // per default we assume marker segments conaining a length parameter + default : { - rStm >> cByte; - } - - while ( ( cByte == 0xff ) && - ( bWideSearch || ( nCount++ < nMax ) ) ) - { - rStm >> cByte; - } - } - while ( ( cByte != 0xc0 ) && - ( cByte != 0xc1 ) && - ( bWideSearch || ( nCount < nMax ) ) ); - - // wir haben den SOF0/1-Marker - if ( ( cByte == 0xc0 ) || ( cByte == 0xc1 ) ) - { - // Hoehe einlesen - rStm.SeekRel( 3 ); - rStm >> nTemp16; - aPixSize.Height() = nTemp16; + sal_uInt16 nLength; + rStm >> nLength; - // Breite einlesen - rStm >> nTemp16; - aPixSize.Width() = nTemp16; - - // Bit/Pixel einlesen - rStm >> cByte; - nBitsPerPixel = ( cByte == 3 ? 24 : cByte == 1 ? 8 : 0 ); + if ( nLength < 2 ) + bScanFailure = sal_True; + else + { + sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2; + switch( nMarker ) + { + case 0xe0 : // APP0 Marker + { + if ( nLength == 16 ) + { + sal_Int32 nIdentifier; + rStm >> nIdentifier; + if ( nIdentifier == 0x4a464946 ) // JFIF Identifier + { + sal_uInt8 nStringTerminator; + sal_uInt8 nMajorRevision; + sal_uInt8 nMinorRevision; + sal_uInt8 nUnits; + sal_uInt16 nHorizontalResolution; + sal_uInt16 nVerticalResolution; + sal_uInt8 nHorzThumbnailPixelCount; + sal_uInt8 nVertThumbnailPixelCount; + + rStm >> nStringTerminator + >> nMajorRevision + >> nMinorRevision + >> nUnits + >> nHorizontalResolution + >> nVerticalResolution + >> nHorzThumbnailPixelCount + >> nVertThumbnailPixelCount; + + // setting the logical size + if ( nUnits && nHorizontalResolution && nVerticalResolution ) + { + MapMode aMap; + aMap.SetMapUnit( nUnits == 1 ? MAP_INCH : MAP_CM ); + aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) ); + aMap.SetScaleY( Fraction( 1, nVerticalResolution ) ); + aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MAP_100TH_MM ) ); + } + } + } + } + break; - // logische Groesse setzen - if ( cUnit && nResX && nResY ) - { - aMap.SetMapUnit( cUnit == 1 ? MAP_INCH : MAP_CM ); - aMap.SetScaleX( Fraction( 1, nResX ) ); - aMap.SetScaleY( Fraction( 1, nResY ) ); - aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, - MapMode( MAP_100TH_MM ) ); + // Start of Frame Markers + case 0xc0 : // SOF0 + case 0xc1 : // SOF1 + case 0xc2 : // SOF2 + case 0xc3 : // SOF3 + case 0xc5 : // SOF5 + case 0xc6 : // SOF6 + case 0xc7 : // SOF7 + case 0xc9 : // SOF9 + case 0xca : // SOF10 + case 0xcb : // SOF11 + case 0xcd : // SOF13 + case 0xce : // SOF14 + case 0xcf : // SOF15 + { + sal_uInt8 nSamplePrecision; + sal_uInt16 nNumberOfLines; + sal_uInt16 nSamplesPerLine; + sal_uInt8 nNumberOfImageComponents; + sal_uInt8 nComponentsIdentifier; + sal_uInt8 nHorizontalSamplingFactor; + sal_uInt8 nVerticalSamplingFactor; + sal_uInt8 nQuantizationTableDestinationSelector; + rStm >> nSamplePrecision + >> nNumberOfLines + >> nSamplesPerLine + >> nNumberOfImageComponents + >> nComponentsIdentifier + >> nHorizontalSamplingFactor + >> nQuantizationTableDestinationSelector; + nVerticalSamplingFactor = nHorizontalSamplingFactor & 0xf; + nHorizontalSamplingFactor >>= 4; + + aPixSize.Height() = nNumberOfLines; + aPixSize.Width() = nSamplesPerLine; + nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 ); + nPlanes = 1; + + bScanFinished = sal_True; + } + break; + } + rStm.Seek( nNextMarkerPos ); + } } - - // Planes immer 1 - nPlanes = 1; + break; } } + rStm.SetError( nError ); } } - + rStm.Seek( nStmPos ); return bRet; } @@ -556,37 +477,26 @@ BOOL GraphicDescriptor::ImpDetectPCD( SvStream& rStm, BOOL ) { BOOL bRet = FALSE; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - rStm.Seek( nStmPos ); - if ( bWideSearch ) - { - UINT32 nTemp32; - UINT16 nTemp16; - BYTE cByte; + UINT32 nTemp32; + UINT16 nTemp16; + BYTE cByte; - rStm.SeekRel( 2048 ); - rStm >> nTemp32; - rStm >> nTemp16; - rStm >> cByte; + rStm.SeekRel( 2048 ); + rStm >> nTemp32; + rStm >> nTemp16; + rStm >> cByte; - if ( ( nTemp32 == 0x5f444350 ) && - ( nTemp16 == 0x5049 ) && - ( cByte == 0x49 ) ) - { - nFormat = GFF_PCD; - bRet = TRUE; - } - } - else + if ( ( nTemp32 == 0x5f444350 ) && + ( nTemp16 == 0x5049 ) && + ( cByte == 0x49 ) ) { - bRet = aPathExt.CompareToAscii( "pcd", 3 ) == COMPARE_EQUAL; - if ( bRet ) - { - nFormat = GFF_PCD; - } + nFormat = GFF_PCD; + bRet = TRUE; } - + rStm.Seek( nStmPos ); return bRet; } @@ -608,10 +518,10 @@ BOOL GraphicDescriptor::ImpDetectPCX( SvStream& rStm, BOOL bExtendedInfo ) BOOL bRet = FALSE; BYTE cByte; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - rStm.Seek( nStmPos ); - rStm >> cByte; + if ( cByte == 0x0a ) { nFormat = GFF_PCX; @@ -675,6 +585,7 @@ BOOL GraphicDescriptor::ImpDetectPCX( SvStream& rStm, BOOL bExtendedInfo ) } } + rStm.Seek( nStmPos ); return bRet; } @@ -690,10 +601,10 @@ BOOL GraphicDescriptor::ImpDetectPNG( SvStream& rStm, BOOL bExtendedInfo ) UINT32 nTemp32; BOOL bRet = FALSE; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); - rStm.Seek( nStmPos ); - rStm >> nTemp32; + if ( nTemp32 == 0x89504e47 ) { rStm >> nTemp32; @@ -726,55 +637,52 @@ BOOL GraphicDescriptor::ImpDetectPNG( SvStream& rStm, BOOL bExtendedInfo ) nPlanes = 1; bCompressed = TRUE; - if ( bWideSearch ) - { - UINT32 nLen32; + UINT32 nLen32; - rStm.SeekRel( 8 ); + rStm.SeekRel( 8 ); - // so lange ueberlesen, bis wir den pHYs-Chunk haben oder - // den Anfang der Bilddaten + // so lange ueberlesen, bis wir den pHYs-Chunk haben oder + // den Anfang der Bilddaten + rStm >> nLen32; + rStm >> nTemp32; + while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) ) + { + rStm.SeekRel( 4 + nLen32 ); rStm >> nLen32; rStm >> nTemp32; - while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) ) - { - rStm.SeekRel( 4 + nLen32 ); - rStm >> nLen32; - rStm >> nTemp32; - } + } - if ( nTemp32 == 0x70485973 ) - { - ULONG nXRes; - ULONG nYRes; + if ( nTemp32 == 0x70485973 ) + { + ULONG nXRes; + ULONG nYRes; - // horizontale Aufloesung - rStm >> nTemp32; - nXRes = nTemp32; + // horizontale Aufloesung + rStm >> nTemp32; + nXRes = nTemp32; - // vertikale Aufloesung - rStm >> nTemp32; - nYRes = nTemp32; + // vertikale Aufloesung + rStm >> nTemp32; + nYRes = nTemp32; - // Unit einlesen - rStm >> cByte; + // Unit einlesen + rStm >> cByte; - if ( cByte ) - { - if ( nXRes ) - aLogSize.Width() = ( aPixSize.Width() * 100000 ) / - nTemp32; + if ( cByte ) + { + if ( nXRes ) + aLogSize.Width() = ( aPixSize.Width() * 100000 ) / + nTemp32; - if ( nYRes ) - aLogSize.Height() = ( aPixSize.Height() * 100000 ) / - nTemp32; - } + if ( nYRes ) + aLogSize.Height() = ( aPixSize.Height() * 100000 ) / + nTemp32; } } } } } - + rStm.Seek( nStmPos ); return bRet; } @@ -792,7 +700,7 @@ BOOL GraphicDescriptor::ImpDetectTIF( SvStream& rStm, BOOL bExtendedInfo ) BYTE cByte1; BYTE cByte2; - rStm.Seek( nStmPos ); + sal_Int32 nStmPos = rStm.Tell(); rStm >> cByte1; rStm >> cByte2; if ( cByte1 == cByte2 ) @@ -829,14 +737,14 @@ BOOL GraphicDescriptor::ImpDetectTIF( SvStream& rStm, BOOL bExtendedInfo ) rStm >> nTemp32; rStm.SeekRel( ( nCount = ( nTemp32 + 2 ) ) - 0x08 ); - if ( bWideSearch || ( nCount < nMax ) ) + if ( nCount < nMax ) { // Tag's lesen, bis wir auf Tag256 ( Width ) treffen // nicht mehr Bytes als DATA_SIZE lesen rStm >> nTemp16; while ( nTemp16 != 256 ) { - bOk = bWideSearch || ( nCount < nMax ); + bOk = nCount < nMax; if ( !bOk ) { break; @@ -912,7 +820,7 @@ BOOL GraphicDescriptor::ImpDetectTIF( SvStream& rStm, BOOL bExtendedInfo ) } } } - + rStm.Seek( nStmPos ); return bRet; } @@ -965,11 +873,12 @@ BOOL GraphicDescriptor::ImpDetectPBM( SvStream& rStm, BOOL ) bRet = TRUE; else { + sal_Int32 nStmPos = rStm.Tell(); BYTE nFirst, nSecond; - rStm.Seek( nStmPos ); rStm >> nFirst >> nSecond; if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) ) bRet = TRUE; + rStm.Seek( nStmPos ); } if ( bRet ) @@ -992,11 +901,12 @@ BOOL GraphicDescriptor::ImpDetectPGM( SvStream& rStm, BOOL ) bRet = TRUE; else { - BYTE nFirst, nSecond; - rStm.Seek( nStmPos ); + BYTE nFirst, nSecond; + sal_Int32 nStmPos = rStm.Tell(); rStm >> nFirst >> nSecond; if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) ) bRet = TRUE; + rStm.Seek( nStmPos ); } if ( bRet ) @@ -1020,10 +930,11 @@ BOOL GraphicDescriptor::ImpDetectPPM( SvStream& rStm, BOOL ) else { BYTE nFirst, nSecond; - rStm.Seek( nStmPos ); + sal_Int32 nStmPos = rStm.Tell(); rStm >> nFirst >> nSecond; if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) ) bRet = TRUE; + rStm.Seek( nStmPos ); } if ( bRet ) @@ -1041,16 +952,17 @@ BOOL GraphicDescriptor::ImpDetectPPM( SvStream& rStm, BOOL ) BOOL GraphicDescriptor::ImpDetectRAS( SvStream& rStm, BOOL ) { UINT32 nMagicNumber; - rStm.Seek( nStmPos ); + BOOL bRet = FALSE; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); rStm >> nMagicNumber; if ( nMagicNumber == 0x59a66a95 ) { nFormat = GFF_RAS; - return TRUE; + bRet = TRUE; } - else - return FALSE; + rStm.Seek( nStmPos ); + return bRet; } /************************************************************************* @@ -1079,7 +991,7 @@ BOOL GraphicDescriptor::ImpDetectPSD( SvStream& rStm, BOOL bExtendedInfo ) BOOL bRet = FALSE; UINT32 nMagicNumber; - rStm.Seek( nStmPos ); + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); rStm >> nMagicNumber; if ( nMagicNumber == 0x38425053 ) @@ -1123,6 +1035,7 @@ BOOL GraphicDescriptor::ImpDetectPSD( SvStream& rStm, BOOL bExtendedInfo ) if ( bRet ) nFormat = GFF_PSD; + rStm.Seek( nStmPos ); return bRet; } @@ -1139,8 +1052,9 @@ BOOL GraphicDescriptor::ImpDetectEPS( SvStream& rStm, BOOL ) sal_uInt32 nFirstLong; sal_uInt8 nFirstBytes[20]; + BOOL bRet = FALSE; - rStm.Seek( nStmPos ); + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); rStm >> nFirstLong; rStm.SeekRel( -4 ); @@ -1151,10 +1065,10 @@ BOOL GraphicDescriptor::ImpDetectEPS( SvStream& rStm, BOOL ) && ImplSearchEntry( &nFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) ) { nFormat = GFF_EPS; - return TRUE; + bRet = TRUE; } - else - return FALSE; + rStm.Seek( nStmPos ); + return bRet; } /************************************************************************* @@ -1201,9 +1115,11 @@ BOOL GraphicDescriptor::ImpDetectPCT( SvStream& rStm, BOOL ) nFormat = GFF_PCT; else { - BYTE sBuf[3]={0}; + sal_Int32 nStmPos = rStm.Tell(); + + BYTE sBuf[4]; - rStm.Seek( nStmPos + 522 ); + rStm.SeekRel( 522 ); rStm.Read( sBuf, 3 ); if( !rStm.GetError() ) @@ -1215,6 +1131,7 @@ BOOL GraphicDescriptor::ImpDetectPCT( SvStream& rStm, BOOL ) nFormat = GFF_PCT; } } + rStm.Seek( nStmPos ); } return bRet; @@ -1230,18 +1147,20 @@ BOOL GraphicDescriptor::ImpDetectPCT( SvStream& rStm, BOOL ) BOOL GraphicDescriptor::ImpDetectSGF( SvStream& rStm, BOOL ) { BOOL bRet = FALSE; - if( aPathExt.CompareToAscii( "sgf", 3 ) == COMPARE_EQUAL ) bRet = TRUE; else { + sal_Int32 nStmPos = rStm.Tell(); + BYTE nFirst, nSecond; - rStm.Seek( nStmPos ); rStm >> nFirst >> nSecond; if( nFirst == 'J' && nSecond == 'J' ) bRet = TRUE; + + rStm.Seek( nStmPos ); } if( bRet ) @@ -1279,9 +1198,8 @@ BOOL GraphicDescriptor::ImpDetectSVM( SvStream& rStm, BOOL bExtendedInfo ) BOOL bRet = FALSE; BYTE cByte; + sal_Int32 nStmPos = rStm.Tell(); rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); - rStm.Seek( nStmPos ); - rStm >> n32; if ( n32 == 0x44475653 ) { @@ -1342,7 +1260,7 @@ BOOL GraphicDescriptor::ImpDetectSVM( SvStream& rStm, BOOL bExtendedInfo ) } } } - + rStm.Seek( nStmPos ); return bRet; } @@ -1417,3 +1335,5 @@ String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat ) return String( aKeyName, RTL_TEXTENCODING_ASCII_US ); } + + diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx index cce018ac6229..2ebb24437c24 100644 --- a/vcl/aqua/source/app/salinst.cxx +++ b/vcl/aqua/source/app/salinst.cxx @@ -450,7 +450,6 @@ SalInstance* CreateSalInstance() ImplGetSVData()->maNWFData.mbProgressNeedsErase = true; ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase = true; ImplGetSVData()->maNWFData.mnStatusBarLowerRightOffset = 10; - ImplGetSVData()->maGDIData.mbPrinterPullModel = true; ImplGetSVData()->maGDIData.mbNoXORClipping = true; ImplGetSVData()->maWinData.mbNoSaveBackground = true; diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx index ff4edcbf83f9..c79add81d791 100644 --- a/vcl/aqua/source/gdi/salprn.cxx +++ b/vcl/aqua/source/gdi/salprn.cxx @@ -460,6 +460,8 @@ ULONG AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup* i_pSetupData, USH return getUseNativeDialog() ? 1 : 0; case PRINTER_CAPABILITIES_PDF: return 1; + case PRINTER_CAPABILITIES_USEPULLMODEL: + return 1; default: break; }; return 0; diff --git a/vcl/inc/cupsmgr.hxx b/vcl/inc/cupsmgr.hxx index b413184f477f..0250cece817e 100644 --- a/vcl/inc/cupsmgr.hxx +++ b/vcl/inc/cupsmgr.hxx @@ -70,7 +70,7 @@ class CUPSManager : public PrinterInfoManager virtual void initialize(); - void getOptionsFromDocumentSetup( const JobData& rJob, int& rNumOptions, void** rOptions ) const; + void getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner, int& rNumOptions, void** rOptions ) const; void runDests(); public: // public for stub @@ -84,7 +84,7 @@ public: const char* authenticateUser( const char* ); virtual FILE* startSpool( const rtl::OUString& rPrinterName, bool bQuickCommand ); - virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData ); + virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner ); virtual void setupJobContextData( JobData& rData ); // changes the info about a named printer diff --git a/vcl/inc/vcl/jobdata.hxx b/vcl/inc/vcl/jobdata.hxx index f576b816dab0..18330ae3508d 100644 --- a/vcl/inc/vcl/jobdata.hxx +++ b/vcl/inc/vcl/jobdata.hxx @@ -50,6 +50,7 @@ struct JobData int m_nColorDepth; int m_nPSLevel; // 0: no override, else languaglevel to use int m_nColorDevice; // 0: no override, -1 grey scale, +1 color + int m_nPDFDevice; // 0: PostScript, 1: PDF orientation::type m_eOrientation; ::rtl::OUString m_aPrinterName; const PPDParser* m_pParser; @@ -64,6 +65,7 @@ struct JobData m_nColorDepth( 24 ), m_nPSLevel( 0 ), m_nColorDevice( 0 ), + m_nPDFDevice( 0 ), m_eOrientation( orientation::Portrait ), m_pParser( NULL ) {} @@ -72,6 +74,8 @@ struct JobData JobData( const JobData& rData ) { *this = rData; } void setCollate( bool bCollate ); + bool setPaper( int nWidth, int nHeight ); // dimensions in pt + bool setPaperBin( int nPaperBin ); // dimensions in pt // creates a new buffer using new // it is up to the user to delete it again diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx index 419814e5ce97..27dbbfc80c72 100644 --- a/vcl/inc/vcl/pdfwriter.hxx +++ b/vcl/inc/vcl/pdfwriter.hxx @@ -47,6 +47,7 @@ class Font; class Point; class OutputDevice; +class GDIMetaFile; class MapMode; class Polygon; class LineInfo; @@ -61,6 +62,8 @@ class Wallpaper; namespace vcl { +class PDFExtOutDevData; + struct PDFDocInfo { String Title; // document title @@ -578,6 +581,8 @@ The following structure describes the permissions used in PDF security rtl::OUString UserPassword; // user password for PDF, in clear text com::sun::star::lang::Locale DocumentLocale; // defines the document default language + sal_uInt32 DPIx, DPIy; // how to handle MapMode( MAP_PIXEL ) + // 0 here specifies a default handling PDFWriterContext() : RelFsys( false ), //i56629, i49415?, i64585? @@ -606,7 +611,9 @@ The following structure describes the permissions used in PDF security OpenBookmarkLevels( -1 ), AccessPermissions( ), Encrypt( false ), - Security128bit( true ) + Security128bit( true ), + DPIx( 0 ), + DPIy( 0 ) {} }; @@ -635,6 +642,24 @@ The following structure describes the permissions used in PDF security returns the page id of the new page */ sal_Int32 NewPage( sal_Int32 nPageWidth = 0, sal_Int32 nPageHeight = 0, Orientation eOrientation = Inherit ); + /** Play a metafile like an outputdevice would do + */ + struct PlayMetafileContext + { + int m_nMaxImageResolution; + bool m_bOnlyLosslessCompression; + int m_nJPEGQuality; + bool m_bTransparenciesWereRemoved; + + PlayMetafileContext() + : m_nMaxImageResolution( 0 ) + , m_bOnlyLosslessCompression( false ) + , m_nJPEGQuality( 90 ) + , m_bTransparenciesWereRemoved( false ) + {} + + }; + void PlayMetafile( const GDIMetaFile&, const PlayMetafileContext&, vcl::PDFExtOutDevData* pDevDat = NULL ); /* * set document info; due to the use of document information in building the PDF document ID, must be called before diff --git a/vcl/inc/vcl/print.hxx b/vcl/inc/vcl/print.hxx index be7633f13d53..c389034d918f 100644 --- a/vcl/inc/vcl/print.hxx +++ b/vcl/inc/vcl/print.hxx @@ -514,21 +514,24 @@ public: bool isDirectPrint() const; // implementation details, not usable outside vcl - SAL_DLLPRIVATE int getFilteredPageCount(); + // don't use outside vcl. Some of these ar exported for + // the benefit of vcl's plugins. + // Still: DO NOT USE OUTSIDE VCL + int getFilteredPageCount(); SAL_DLLPRIVATE PageSize getPageFile( int i_inUnfilteredPage, GDIMetaFile& rMtf, bool i_bMayUseCache = false ); - SAL_DLLPRIVATE PageSize getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache = false ); + PageSize getFilteredPageFile( int i_nFilteredPage, GDIMetaFile& o_rMtf, bool i_bMayUseCache = false ); SAL_DLLPRIVATE void printFilteredPage( int i_nPage ); SAL_DLLPRIVATE void setPrinter( const boost::shared_ptr<Printer>& ); SAL_DLLPRIVATE void setOptionChangeHdl( const Link& ); - SAL_DLLPRIVATE void createProgressDialog(); - SAL_DLLPRIVATE bool isProgressCanceled() const; + void createProgressDialog(); + bool isProgressCanceled() const; SAL_DLLPRIVATE void setMultipage( const MultiPageSetup& ); SAL_DLLPRIVATE const MultiPageSetup& getMultipage() const; - SAL_DLLPRIVATE void setLastPage( sal_Bool i_bLastPage ); + void setLastPage( sal_Bool i_bLastPage ); SAL_DLLPRIVATE void setReversePrint( sal_Bool i_bReverse ); SAL_DLLPRIVATE bool getReversePrint() const; SAL_DLLPRIVATE void pushPropertiesToPrinter(); - SAL_DLLPRIVATE void setJobState( com::sun::star::view::PrintableState ); + void setJobState( com::sun::star::view::PrintableState ); SAL_DLLPRIVATE bool setupPrinter( Window* i_pDlgParent ); SAL_DLLPRIVATE int getPageCountProtected() const; diff --git a/vcl/inc/vcl/printerinfomanager.hxx b/vcl/inc/vcl/printerinfomanager.hxx index f03234db3268..5e94ed919a4e 100644 --- a/vcl/inc/vcl/printerinfomanager.hxx +++ b/vcl/inc/vcl/printerinfomanager.hxx @@ -219,8 +219,10 @@ public: // this may either be a regular file or the result of popen() virtual FILE* startSpool( const rtl::OUString& rPrinterName, bool bQuickCommand ); // close the FILE* returned by startSpool and does the actual spooling + // set bBanner to "false" will attempt to suppress banner printing + // set bBanner to "true" will rely on the system default // returns a numerical job id - virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData ); + virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner ); // for spadmin: whether adding or removing a printer is possible virtual bool addOrRemovePossible() const; diff --git a/vcl/inc/vcl/prntypes.hxx b/vcl/inc/vcl/prntypes.hxx index 6b2af991f2dd..244154360f3b 100644 --- a/vcl/inc/vcl/prntypes.hxx +++ b/vcl/inc/vcl/prntypes.hxx @@ -91,5 +91,6 @@ enum Orientation { ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE }; #define PRINTER_CAPABILITIES_PDF ((USHORT)9) #define PRINTER_CAPABILITIES_EXTERNALDIALOG ((USHORT)10) #define PRINTER_CAPABILITIES_SETDUPLEX ((USHORT)11) +#define PRINTER_CAPABILITIES_USEPULLMODEL ((USHORT)12) #endif // _SV_PRNTYPES_HXX diff --git a/vcl/inc/vcl/svdata.hxx b/vcl/inc/vcl/svdata.hxx index fe69b0c0b4d4..0d54a82a1937 100644 --- a/vcl/inc/vcl/svdata.hxx +++ b/vcl/inc/vcl/svdata.hxx @@ -208,7 +208,6 @@ struct ImplSVGDIData BOOL mbFontSubChanged; // TRUE: FontSubstitution wurde zwischen Begin/End geaendert utl::DefaultFontConfiguration* mpDefaultFontConfiguration; utl::FontSubstConfiguration* mpFontSubstConfiguration; - bool mbPrinterPullModel; // true: use pull model instead of normal push model when printing bool mbNativeFontConfig; // true: do not override UI font bool mbNoXORClipping; // true: do not use XOR to achieve clipping effects }; diff --git a/vcl/source/gdi/impprn.cxx b/vcl/source/gdi/impprn.cxx deleted file mode 100644 index 5224286cdad1..000000000000 --- a/vcl/source/gdi/impprn.cxx +++ /dev/null @@ -1,584 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_vcl.hxx" - -#define _SPOOLPRINTER_EXT -#include "tools/queue.hxx" -#include "vcl/svapp.hxx" -#include "vcl/metaact.hxx" -#include "vcl/gdimtf.hxx" -#include "vcl/timer.hxx" -#include "vcl/impprn.hxx" -#include "vcl/jobset.h" - -#include "vcl/svdata.hxx" -#include "vcl/salprn.hxx" - -// ----------- -// - Defines - -// ----------- - -#define OPTIMAL_BMP_RESOLUTION 300 -#define NORMAL_BMP_RESOLUTION 200 - -// ======================================================================= - -struct QueuePage -{ - GDIMetaFile* mpMtf; - JobSetup* mpSetup; - USHORT mnPage; - BOOL mbEndJob; - - QueuePage() { mpMtf = NULL; mpSetup = NULL; } - ~QueuePage() { delete mpMtf; if ( mpSetup ) delete mpSetup; } -}; - -// ======================================================================= - -ImplQPrinter::ImplQPrinter( Printer* pParent ) : - Printer( pParent->GetName() ), - mpParent( pParent ), - mbAborted( false ), - mbUserCopy( false ), - mbDestroyAllowed( true ), - mbDestroyed( false ), - mnMaxBmpDPIX( mnDPIX ), - mnMaxBmpDPIY( mnDPIY ), - mnCurCopyCount( 0 ) -{ - SetSelfAsQueuePrinter( TRUE ); - SetPrinterProps( pParent ); - SetPageQueueSize( 0 ); - mnCopyCount = pParent->mnCopyCount; - mbCollateCopy = pParent->mbCollateCopy; -} - -// ----------------------------------------------------------------------- - -ImplQPrinter::~ImplQPrinter() -{ - for( std::vector< QueuePage* >::iterator it = maQueue.begin(); - it != maQueue.end(); ++it ) - delete (*it); -} - -// ----------------------------------------------------------------------------- - -void ImplQPrinter::Destroy() -{ - if( mbDestroyAllowed ) - delete this; - else - mbDestroyed = TRUE; -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::ImplPrintMtf( GDIMetaFile& rPrtMtf, long nMaxBmpDPIX, long nMaxBmpDPIY ) -{ - for( MetaAction* pAct = rPrtMtf.FirstAction(); pAct && !mbAborted; pAct = rPrtMtf.NextAction() ) - { - const ULONG nType = pAct->GetType(); - sal_Bool bExecuted = sal_False; - - if( nType == META_COMMENT_ACTION ) - { - // search for special comments ( ..._BEGIN/..._END ) - MetaCommentAction* pComment = (MetaCommentAction*) pAct; - - if( pComment->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL ) - { - pAct = rPrtMtf.NextAction(); - - // if next action is a GradientEx action, execute this and - // skip actions until a XGRAD_SEQ_END comment is found - if( pAct && ( pAct->GetType() == META_GRADIENTEX_ACTION ) ) - { - MetaGradientExAction* pGradientExAction = (MetaGradientExAction*) pAct; - DrawGradientEx( this, pGradientExAction->GetPolyPolygon(), pGradientExAction->GetGradient() ); - - // seek to end of this comment - do - { - pAct = rPrtMtf.NextAction(); - } - while( pAct && - ( ( pAct->GetType() != META_COMMENT_ACTION ) || - ( ( (MetaCommentAction*) pAct )->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) != COMPARE_EQUAL ) ) ); - - bExecuted = sal_True; - } - } - else if( pComment->GetComment().CompareIgnoreCaseToAscii( "PRNSPOOL_TRANSPARENTBITMAP_BEGIN" ) == COMPARE_EQUAL ) - { - pAct = rPrtMtf.NextAction(); - - if( pAct && ( pAct->GetType() == META_BMPSCALE_ACTION ) ) - { - // execute action here to avoid DPI processing of bitmap; - pAct->Execute( this ); - -#ifdef VERBOSE_DEBUG - Push(); - SetLineColor(COL_RED); - SetFillColor(); - DrawRect( Rectangle( - static_cast<MetaBmpScaleAction*>(pAct)->GetPoint(), - static_cast<MetaBmpScaleAction*>(pAct)->GetSize()) ); - Pop(); -#endif - - // seek to end of this comment - do - { - pAct = rPrtMtf.NextAction(); - } - while( pAct && - ( ( pAct->GetType() != META_COMMENT_ACTION ) || - ( ( (MetaCommentAction*) pAct )->GetComment().CompareIgnoreCaseToAscii( "PRNSPOOL_TRANSPARENTBITMAP_END" ) != COMPARE_EQUAL ) ) ); - - bExecuted = sal_True; - } - } - } - else if( nType == META_GRADIENT_ACTION ) - { - MetaGradientAction* pGradientAction = (MetaGradientAction*) pAct; - DrawGradientEx( this, pGradientAction->GetRect(), pGradientAction->GetGradient() ); - bExecuted = sal_True; - } - else if( nType == META_BMPSCALE_ACTION ) - { - MetaBmpScaleAction* pBmpScaleAction = (MetaBmpScaleAction*) pAct; - const Bitmap& rBmp = pBmpScaleAction->GetBitmap(); - - DrawBitmap( pBmpScaleAction->GetPoint(), pBmpScaleAction->GetSize(), - GetDownsampledBitmap( pBmpScaleAction->GetSize(), - Point(), rBmp.GetSizePixel(), - rBmp, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_BMPSCALEPART_ACTION ) - { - MetaBmpScalePartAction* pBmpScalePartAction = (MetaBmpScalePartAction*) pAct; - const Bitmap& rBmp = pBmpScalePartAction->GetBitmap(); - - DrawBitmap( pBmpScalePartAction->GetDestPoint(), pBmpScalePartAction->GetDestSize(), - GetDownsampledBitmap( pBmpScalePartAction->GetDestSize(), - pBmpScalePartAction->GetSrcPoint(), pBmpScalePartAction->GetSrcSize(), - rBmp, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_BMPEXSCALE_ACTION ) - { - MetaBmpExScaleAction* pBmpExScaleAction = (MetaBmpExScaleAction*) pAct; - const BitmapEx& rBmpEx = pBmpExScaleAction->GetBitmapEx(); - - DrawBitmapEx( pBmpExScaleAction->GetPoint(), pBmpExScaleAction->GetSize(), - GetDownsampledBitmapEx( pBmpExScaleAction->GetSize(), - Point(), rBmpEx.GetSizePixel(), - rBmpEx, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_BMPEXSCALEPART_ACTION ) - { - MetaBmpExScalePartAction* pBmpExScalePartAction = (MetaBmpExScalePartAction*) pAct; - const BitmapEx& rBmpEx = pBmpExScalePartAction->GetBitmapEx(); - - DrawBitmapEx( pBmpExScalePartAction->GetDestPoint(), pBmpExScalePartAction->GetDestSize(), - GetDownsampledBitmapEx( pBmpExScalePartAction->GetDestSize(), - pBmpExScalePartAction->GetSrcPoint(), pBmpExScalePartAction->GetSrcSize(), - rBmpEx, nMaxBmpDPIX, nMaxBmpDPIY ) ); - - bExecuted = sal_True; - } - else if( nType == META_TRANSPARENT_ACTION ) - { - MetaTransparentAction* pTransAct = static_cast<MetaTransparentAction*>(pAct); - USHORT nTransparency( pTransAct->GetTransparence() ); - - // #i10613# Respect transparency for draw color - if( nTransparency ) - { - Push( PUSH_LINECOLOR|PUSH_FILLCOLOR ); - - // assume white background for alpha blending - Color aLineColor( GetLineColor() ); - aLineColor.SetRed( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetRed()) / 100L ) ); - aLineColor.SetGreen( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetGreen()) / 100L ) ); - aLineColor.SetBlue( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aLineColor.GetBlue()) / 100L ) ); - SetLineColor( aLineColor ); - - Color aFillColor( GetFillColor() ); - aFillColor.SetRed( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetRed()) / 100L ) ); - aFillColor.SetGreen( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetGreen()) / 100L ) ); - aFillColor.SetBlue( static_cast<UINT8>( (255L*nTransparency + (100L - nTransparency)*aFillColor.GetBlue()) / 100L ) ); - SetFillColor( aFillColor ); - } - - DrawPolyPolygon( pTransAct->GetPolyPolygon() ); - - if( nTransparency ) - Pop(); - - bExecuted = sal_True; - } - else if( nType == META_FLOATTRANSPARENT_ACTION ) - { - MetaFloatTransparentAction* pFloatAction = (MetaFloatTransparentAction*) pAct; - GDIMetaFile& rMtf = (GDIMetaFile&) pFloatAction->GetGDIMetaFile(); - MapMode aDrawMap( rMtf.GetPrefMapMode() ); - Point aDestPoint( LogicToPixel( pFloatAction->GetPoint() ) ); - Size aDestSize( LogicToPixel( pFloatAction->GetSize() ) ); - - if( aDestSize.Width() && aDestSize.Height() ) - { - Size aTmpPrefSize( LogicToPixel( rMtf.GetPrefSize(), aDrawMap ) ); - - if( !aTmpPrefSize.Width() ) - aTmpPrefSize.Width() = aDestSize.Width(); - - if( !aTmpPrefSize.Height() ) - aTmpPrefSize.Height() = aDestSize.Height(); - - Fraction aScaleX( aDestSize.Width(), aTmpPrefSize.Width() ); - Fraction aScaleY( aDestSize.Height(), aTmpPrefSize.Height() ); - - aDrawMap.SetScaleX( aScaleX *= aDrawMap.GetScaleX() ); - aDrawMap.SetScaleY( aScaleY *= aDrawMap.GetScaleY() ); - aDrawMap.SetOrigin( PixelToLogic( aDestPoint, aDrawMap ) ); - - Push(); - SetMapMode( aDrawMap ); - ImplPrintMtf( rMtf, nMaxBmpDPIX, nMaxBmpDPIY ); - Pop(); - } - - bExecuted = sal_True; - } - - if( !bExecuted && pAct ) - pAct->Execute( this ); - - if( ! ImplGetSVData()->maGDIData.mbPrinterPullModel ) - Application::Reschedule(); - } -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::PrePrintPage( QueuePage* pPage ) -{ - mnRestoreDrawMode = GetDrawMode(); - mnMaxBmpDPIX = mnDPIX; - mnMaxBmpDPIY = mnDPIY; - - const PrinterOptions& rPrinterOptions = GetPrinterOptions(); - - if( rPrinterOptions.IsReduceBitmaps() ) - { - // calculate maximum resolution for bitmap graphics - if( PRINTER_BITMAP_OPTIMAL == rPrinterOptions.GetReducedBitmapMode() ) - { - mnMaxBmpDPIX = Min( (long) OPTIMAL_BMP_RESOLUTION, mnMaxBmpDPIX ); - mnMaxBmpDPIY = Min( (long) OPTIMAL_BMP_RESOLUTION, mnMaxBmpDPIY ); - } - else if( PRINTER_BITMAP_NORMAL == rPrinterOptions.GetReducedBitmapMode() ) - { - mnMaxBmpDPIX = Min( (long) NORMAL_BMP_RESOLUTION, mnMaxBmpDPIX ); - mnMaxBmpDPIY = Min( (long) NORMAL_BMP_RESOLUTION, mnMaxBmpDPIY ); - } - else - { - mnMaxBmpDPIX = Min( (long) rPrinterOptions.GetReducedBitmapResolution(), mnMaxBmpDPIX ); - mnMaxBmpDPIY = Min( (long) rPrinterOptions.GetReducedBitmapResolution(), mnMaxBmpDPIY ); - } - } - - // convert to greysacles - if( rPrinterOptions.IsConvertToGreyscales() ) - { - SetDrawMode( GetDrawMode() | ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | - DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); - } - - // disable transparency output - if( rPrinterOptions.IsReduceTransparency() && ( PRINTER_TRANSPARENCY_NONE == rPrinterOptions.GetReducedTransparencyMode() ) ) - { - SetDrawMode( GetDrawMode() | DRAWMODE_NOTRANSPARENCY ); - } - - maCurPageMetaFile = GDIMetaFile(); - RemoveTransparenciesFromMetaFile( *pPage->mpMtf, maCurPageMetaFile, mnMaxBmpDPIX, mnMaxBmpDPIY, - rPrinterOptions.IsReduceTransparency(), - rPrinterOptions.GetReducedTransparencyMode() == PRINTER_TRANSPARENCY_AUTO, - rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency() - ); -} - -void ImplQPrinter::PostPrintPage() -{ - SetDrawMode( mnRestoreDrawMode ); -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::PrintPage( unsigned int nPage ) -{ - if( nPage >= maQueue.size() ) - return; - mnCurCopyCount = (mbUserCopy && !mbCollateCopy) ? mnCopyCount : 1; - QueuePage* pActPage = maQueue[nPage]; - PrePrintPage( pActPage ); - if ( pActPage->mpSetup ) - SetJobSetup( *pActPage->mpSetup ); - - StartPage(); - ImplPrintMtf( maCurPageMetaFile, mnMaxBmpDPIX, mnMaxBmpDPIY ); - EndPage(); - - mnCurCopyCount--; - if( mnCurCopyCount == 0 ) - PostPrintPage(); -} - -// ----------------------------------------------------------------------- - -ImplJobSetup* ImplQPrinter::GetPageSetup( unsigned int nPage ) const -{ - return nPage >= maQueue.size() ? NULL : - ( maQueue[nPage]->mpSetup ? maQueue[nPage]->mpSetup->ImplGetData() : NULL ); -} - -// ----------------------------------------------------------------------- -ULONG ImplQPrinter::GetPrintPageCount() const -{ - ULONG nPageCount = maQueue.size() * ((mbUserCopy && !mbCollateCopy) ? mnCopyCount : 1); - return nPageCount; -} - -// ----------------------------------------------------------------------- - -IMPL_LINK( ImplQPrinter, ImplPrintHdl, Timer*, EMPTYARG ) -{ - // Ist Drucken abgebrochen wurden? - if( !IsPrinting() || ( mpParent->IsJobActive() && ( maQueue.size() < (ULONG)mpParent->GetPageQueueSize() ) ) ) - return 0; - - // Druck-Job zuende? - QueuePage* pActPage = maQueue.front(); - maQueue.erase( maQueue.begin() ); - - - vcl::DeletionListener aDel( this ); - if ( pActPage->mbEndJob ) - { - maTimer.Stop(); - delete pActPage; - if( ! EndJob() ) - mpParent->Error(); - if( ! aDel.isDeleted() ) - mpParent->ImplEndPrint(); - } - else - { - mbDestroyAllowed = FALSE; - - PrePrintPage( pActPage ); - - USHORT nCopyCount = 1; - if( mbUserCopy && !mbCollateCopy ) - nCopyCount = mnCopyCount; - - for ( USHORT i = 0; i < nCopyCount; i++ ) - { - if ( pActPage->mpSetup ) - { - SetJobSetup( *pActPage->mpSetup ); - if ( mbAborted ) - break; - } - - StartPage(); - - if ( mbAborted ) - break; - - ImplPrintMtf( maCurPageMetaFile, mnMaxBmpDPIX, mnMaxBmpDPIY ); - - if( !mbAborted ) - EndPage(); - else - break; - } - - PostPrintPage(); - - delete pActPage; - mbDestroyAllowed = TRUE; - - if( mbDestroyed ) - Destroy(); - } - - return 0; -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::StartQueuePrint() -{ - if( ! ImplGetSVData()->maGDIData.mbPrinterPullModel ) - { - maTimer.SetTimeout( 50 ); - maTimer.SetTimeoutHdl( LINK( this, ImplQPrinter, ImplPrintHdl ) ); - maTimer.Start(); - } -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::EndQueuePrint() -{ - if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) - { - DBG_ASSERT( mpPrinter, "no SalPrinter in ImplQPrinter" ); - if( mpPrinter ) - { - #if 0 - mpPrinter->StartJob( mbPrintFile ? &maPrintFile : NULL, - Application::GetDisplayName(), - maJobSetup.ImplGetConstData(), - this ); - #endif - EndJob(); - mpParent->ImplEndPrint(); - } - } - else - { - QueuePage* pQueuePage = new QueuePage; - pQueuePage->mbEndJob = TRUE; - maQueue.push_back( pQueuePage ); - } -} - -// ----------------------------------------------------------------------- - -bool ImplQPrinter::GetPaperRanges( std::vector< ULONG >& o_rRanges, bool i_bIncludeOrientationChanges ) const -{ - bool bRet = false; - - if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) - { - bRet = true; - o_rRanges.clear(); - - if( ! maQueue.empty() ) - { - ULONG nCurPage = 0; - - // get first job data - const ImplJobSetup* pLastFormat = NULL; - if( maQueue.front()->mpSetup ) - pLastFormat = maQueue.front()->mpSetup->ImplGetConstData(); - - // begin first range - o_rRanges.push_back( 0 ); - for( std::vector< QueuePage* >::const_iterator it = maQueue.begin(); - it != maQueue.end(); ++it, ++nCurPage ) - { - const ImplJobSetup* pNewSetup = (*it)->mpSetup ? (*it)->mpSetup->ImplGetConstData() : NULL; - if( pNewSetup && pNewSetup != pLastFormat ) - { - bool bChange = false; - if( pLastFormat == NULL ) - { - bChange = true; - } - else if( ! i_bIncludeOrientationChanges && - pNewSetup->meOrientation != pLastFormat->meOrientation ) - { - bChange = true; - } - else if( pNewSetup->mePaperFormat != pLastFormat->mePaperFormat || - ( pNewSetup->mePaperFormat == PAPER_USER && - ( pNewSetup->mnPaperWidth != pLastFormat->mnPaperWidth || - pNewSetup->mnPaperHeight != pLastFormat->mnPaperHeight ) ) ) - { - bChange = true; - } - else if( pNewSetup->mnPaperBin != pLastFormat->mnPaperBin ) - { - bChange = true; - } - if( bChange ) - { - o_rRanges.push_back( nCurPage ); - pLastFormat = pNewSetup; - } - } - } - - o_rRanges.push_back( nCurPage ); - } - } - - return bRet; -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::AbortQueuePrint() -{ - maTimer.Stop(); - mbAborted = TRUE; - AbortJob(); -} - -// ----------------------------------------------------------------------- - -void ImplQPrinter::AddQueuePage( GDIMetaFile* pPage, USHORT nPage, BOOL bNewJobSetup ) -{ - QueuePage* pQueuePage = new QueuePage; - pQueuePage->mpMtf = pPage; - pQueuePage->mnPage = nPage; - pQueuePage->mbEndJob = FALSE; - // ensure that the first page has a valid setup, this is needed - // in GetPaperRanges (used in pullmodel) - // caution: this depends on mnCurPage in Printer being - // 0: not printing 1: after StartJob, 2 after first EndPage, 3+ at following EndPage calls - if ( bNewJobSetup || (nPage == 2 && ImplGetSVData()->maGDIData.mbPrinterPullModel) ) - pQueuePage->mpSetup = new JobSetup( mpParent->GetJobSetup() ); - maQueue.push_back( pQueuePage ); -} diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index 77df20976c73..ac2e586a41cb 100755 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -63,6 +63,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/impgraph.obj \ $(SLO)$/metric.obj \ $(SLO)$/pdfwriter_impl.obj \ + $(SLO)$/pdfwriter_impl2.obj \ $(SLO)$/pdffontcache.obj\ $(SLO)$/bmpconv.obj \ $(SLO)$/pdfextoutdevdata.obj \ diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index 5dcce25a0315..969bc51b3cac 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -40,7 +40,7 @@ PDFWriter::AnyWidget::~AnyWidget() PDFWriter::PDFWriter( const PDFWriter::PDFWriterContext& rContext ) : - pImplementation( new PDFWriterImpl( rContext ) ) + pImplementation( new PDFWriterImpl( rContext, *this ) ) { } @@ -569,3 +569,8 @@ std::set< PDFWriter::ErrorCode > PDFWriter::GetErrors() { return ((PDFWriterImpl*)pImplementation)->getErrors(); } + +void PDFWriter::PlayMetafile( const GDIMetaFile& i_rMTF, const vcl::PDFWriter::PlayMetafileContext& i_rPlayContext, PDFExtOutDevData* i_pData ) +{ + ((PDFWriterImpl*)pImplementation)->playMetafile( i_rMTF, i_pData, i_rPlayContext, NULL); +} diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 7e023297fa74..5d75c829da8a 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -1693,7 +1693,7 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal * class PDFWriterImpl */ -PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) +PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, PDFWriter& i_rOuterFace ) : m_pReferenceDevice( NULL ), m_aMapMode( MAP_POINT, Point(), Fraction( 1L, pointToPixel(1) ), Fraction( 1L, pointToPixel(1) ) ), @@ -1719,7 +1719,8 @@ PDFWriterImpl::PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ) m_aCreationMetaDateString( 64 ), m_pEncryptionBuffer( NULL ), m_nEncryptionBufferSize( 0 ), - m_bIsPDF_A1( false ) + m_bIsPDF_A1( false ), + m_rOuterFace( i_rOuterFace ) { #ifdef DO_TEST_PDF static bool bOnce = true; @@ -2138,7 +2139,10 @@ OutputDevice* PDFWriterImpl::getReferenceDevice() m_pReferenceDevice = pVDev; - pVDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_PDF1 ); + if( m_aContext.DPIx == 0 || m_aContext.DPIy == 0 ) + pVDev->SetReferenceDevice( VirtualDevice::REFDEV_MODE_PDF1 ); + else + pVDev->SetReferenceDevice( m_aContext.DPIx, m_aContext.DPIy ); pVDev->SetOutputSizePixel( Size( 640, 480 ) ); pVDev->SetMapMode( MAP_MM ); diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 2eacdc215dd8..9457aea5f0c2 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -1095,6 +1095,7 @@ i12626 /* true if PDF/A-1a or PDF/A-1b is output */ sal_Bool m_bIsPDF_A1; + PDFWriter& m_rOuterFace; /* i12626 @@ -1109,8 +1110,14 @@ methods for PDF security /* algorithm 3.4 or 3.5: computing the encryption dictionary's user password value ( /U ) revision 2 or 3 of the standard security handler */ void computeUDictionaryValue(); + // helper for playMetafile + void implWriteGradient( const PolyPolygon& rPolyPoly, const Gradient& rGradient, + VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& ); + void implWriteBitmapEx( const Point& rPoint, const Size& rSize, const BitmapEx& rBitmapEx, + VirtualDevice* pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& ); + public: - PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext ); + PDFWriterImpl( const PDFWriter::PDFWriterContext& rContext, PDFWriter& ); ~PDFWriterImpl(); /* for OutputDevice so the reference device can have a list @@ -1134,6 +1141,7 @@ public: bool emit(); std::set< PDFWriter::ErrorCode > getErrors(); void insertError( PDFWriter::ErrorCode eErr ) { m_aErrors.insert( eErr ); } + void playMetafile( const GDIMetaFile&, vcl::PDFExtOutDevData*, const vcl::PDFWriter::PlayMetafileContext&, VirtualDevice* pDummyDev = NULL ); Size getCurPageSize() const { diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx new file mode 100644 index 000000000000..c01b8a9771d8 --- /dev/null +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -0,0 +1,1035 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_vcl.hxx" + +#include "pdfwriter_impl.hxx" +#include "vcl/pdfextoutdevdata.hxx" +#include "vcl/virdev.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/metaact.hxx" +#include "vcl/graph.hxx" +#include "vcl/svdata.hxx" +#include "unotools/streamwrap.hxx" +#include "unotools/processfactory.hxx" + +#include "comphelper/processfactory.hxx" +#include "com/sun/star/beans/PropertyValue.hpp" +#include "com/sun/star/io/XSeekable.hpp" +#include "com/sun/star/graphic/XGraphicProvider.hpp" + +using namespace vcl; +using namespace rtl; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; + +// ----------------------------------------------------------------------------- + +void PDFWriterImpl::implWriteGradient( const PolyPolygon& i_rPolyPoly, const Gradient& i_rGradient, + VirtualDevice* i_pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& i_rContext ) +{ + GDIMetaFile aTmpMtf; + + i_pDummyVDev->AddGradientActions( i_rPolyPoly.GetBoundRect(), i_rGradient, aTmpMtf ); + + m_rOuterFace.Push(); + m_rOuterFace.IntersectClipRegion( i_rPolyPoly.getB2DPolyPolygon() ); + playMetafile( aTmpMtf, NULL, i_rContext, i_pDummyVDev ); + m_rOuterFace.Pop(); +} + +// ----------------------------------------------------------------------------- + +void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSize, const BitmapEx& i_rBitmapEx, + VirtualDevice* i_pDummyVDev, const vcl::PDFWriter::PlayMetafileContext& i_rContext ) +{ + if ( !i_rBitmapEx.IsEmpty() && i_rSize.Width() && i_rSize.Height() ) + { + BitmapEx aBitmapEx( i_rBitmapEx ); + Point aPoint( i_rPoint ); + Size aSize( i_rSize ); + + // #i19065# Negative sizes have mirror semantics on + // OutputDevice. BitmapEx and co. have no idea about that, so + // perform that _before_ doing anything with aBitmapEx. + ULONG nMirrorFlags(BMP_MIRROR_NONE); + if( aSize.Width() < 0 ) + { + aSize.Width() *= -1; + aPoint.X() -= aSize.Width(); + nMirrorFlags |= BMP_MIRROR_HORZ; + } + if( aSize.Height() < 0 ) + { + aSize.Height() *= -1; + aPoint.Y() -= aSize.Height(); + nMirrorFlags |= BMP_MIRROR_VERT; + } + + if( nMirrorFlags != BMP_MIRROR_NONE ) + { + aBitmapEx.Mirror( nMirrorFlags ); + } + if( i_rContext.m_nMaxImageResolution > 50 ) + { + // do downsampling if neccessary + const Size aDstSizeTwip( i_pDummyVDev->PixelToLogic( i_pDummyVDev->LogicToPixel( aSize ), MAP_TWIP ) ); + const Size aBmpSize( aBitmapEx.GetSizePixel() ); + const double fBmpPixelX = aBmpSize.Width(); + const double fBmpPixelY = aBmpSize.Height(); + const double fMaxPixelX = aDstSizeTwip.Width() * i_rContext.m_nMaxImageResolution / 1440.0; + const double fMaxPixelY = aDstSizeTwip.Height() * i_rContext.m_nMaxImageResolution / 1440.0; + + // check, if the bitmap DPI exceeds the maximum DPI (allow 4 pixel rounding tolerance) + if( ( ( fBmpPixelX > ( fMaxPixelX + 4 ) ) || + ( fBmpPixelY > ( fMaxPixelY + 4 ) ) ) && + ( fBmpPixelY > 0.0 ) && ( fMaxPixelY > 0.0 ) ) + { + // do scaling + Size aNewBmpSize; + const double fBmpWH = fBmpPixelX / fBmpPixelY; + const double fMaxWH = fMaxPixelX / fMaxPixelY; + + if( fBmpWH < fMaxWH ) + { + aNewBmpSize.Width() = FRound( fMaxPixelY * fBmpWH ); + aNewBmpSize.Height() = FRound( fMaxPixelY ); + } + else if( fBmpWH > 0.0 ) + { + aNewBmpSize.Width() = FRound( fMaxPixelX ); + aNewBmpSize.Height() = FRound( fMaxPixelX / fBmpWH); + } + if( aNewBmpSize.Width() && aNewBmpSize.Height() ) + aBitmapEx.Scale( aNewBmpSize ); + else + aBitmapEx.SetEmpty(); + } + } + + const Size aSizePixel( aBitmapEx.GetSizePixel() ); + if ( aSizePixel.Width() && aSizePixel.Height() ) + { + sal_Bool bUseJPGCompression = !i_rContext.m_bOnlyLosslessCompression; + if ( ( aSizePixel.Width() < 32 ) || ( aSizePixel.Height() < 32 ) ) + bUseJPGCompression = sal_False; + + SvMemoryStream aStrm; + Bitmap aMask; + + bool bTrueColorJPG = true; + if ( bUseJPGCompression ) + { + sal_uInt32 nZippedFileSize; // sj: we will calculate the filesize of a zipped bitmap + { // to determine if jpeg compression is usefull + SvMemoryStream aTemp; + aTemp.SetCompressMode( aTemp.GetCompressMode() | COMPRESSMODE_ZBITMAP ); + aTemp.SetVersion( SOFFICE_FILEFORMAT_40 ); // sj: up from version 40 our bitmap stream operator + aTemp << aBitmapEx; // is capable of zlib stream compression + aTemp.Seek( STREAM_SEEK_TO_END ); + nZippedFileSize = aTemp.Tell(); + } + if ( aBitmapEx.IsTransparent() ) + { + if ( aBitmapEx.IsAlpha() ) + aMask = aBitmapEx.GetAlpha().GetBitmap(); + else + aMask = aBitmapEx.GetMask(); + } + Graphic aGraphic( aBitmapEx.GetBitmap() ); + sal_Int32 nColorMode = 0; + + Sequence< PropertyValue > aFilterData( 2 ); + aFilterData[ 0 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Quality" ) ); + aFilterData[ 0 ].Value <<= sal_Int32(i_rContext.m_nJPEGQuality); + aFilterData[ 1 ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "ColorMode" ) ); + aFilterData[ 1 ].Value <<= nColorMode; + + try + { + uno::Reference < io::XStream > xStream = new utl::OStreamWrapper( aStrm ); + Reference< io::XSeekable > xSeekable( xStream, UNO_QUERY_THROW ); + Reference< graphic::XGraphicProvider > xGraphicProvider( ImplGetSVData()->maAppData.mxMSF->createInstance( + OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ); + if ( xGraphicProvider.is() ) + { + Reference< graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() ); + Reference < io::XOutputStream > xOut( xStream->getOutputStream() ); + rtl::OUString aMimeType( ::rtl::OUString::createFromAscii( "image/jpeg" ) ); + uno::Sequence< beans::PropertyValue > aOutMediaProperties( 3 ); + aOutMediaProperties[0].Name = ::rtl::OUString::createFromAscii( "OutputStream" ); + aOutMediaProperties[0].Value <<= xOut; + aOutMediaProperties[1].Name = ::rtl::OUString::createFromAscii( "MimeType" ); + aOutMediaProperties[1].Value <<= aMimeType; + aOutMediaProperties[2].Name = ::rtl::OUString::createFromAscii( "FilterData" ); + aOutMediaProperties[2].Value <<= aFilterData; + xGraphicProvider->storeGraphic( xGraphic, aOutMediaProperties ); + xOut->flush(); + if ( xSeekable->getLength() > nZippedFileSize ) + { + bUseJPGCompression = sal_False; + } + else + { + aStrm.Seek( STREAM_SEEK_TO_END ); + + xSeekable->seek( 0 ); + Sequence< PropertyValue > aArgs( 1 ); + aArgs[ 0 ].Name = ::rtl::OUString::createFromAscii( "InputStream" ); + aArgs[ 0 ].Value <<= xStream; + Reference< XPropertySet > xPropSet( xGraphicProvider->queryGraphicDescriptor( aArgs ) ); + if ( xPropSet.is() ) + { + sal_Int16 nBitsPerPixel = 24; + if ( xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "BitsPerPixel" ) ) >>= nBitsPerPixel ) + { + bTrueColorJPG = nBitsPerPixel != 8; + } + } + } + } + else + bUseJPGCompression = sal_False; + } + catch( uno::Exception& ) + { + bUseJPGCompression = sal_False; + } + } + if ( bUseJPGCompression ) + m_rOuterFace.DrawJPGBitmap( aStrm, bTrueColorJPG, aSizePixel, Rectangle( aPoint, aSize ), aMask ); + else if ( aBitmapEx.IsTransparent() ) + m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx ); + else + m_rOuterFace.DrawBitmap( aPoint, aSize, aBitmapEx.GetBitmap() ); + } + } +} + + +// ----------------------------------------------------------------------------- + +void PDFWriterImpl::playMetafile( const GDIMetaFile& i_rMtf, vcl::PDFExtOutDevData* i_pOutDevData, const vcl::PDFWriter::PlayMetafileContext& i_rContext, VirtualDevice* pDummyVDev ) +{ + bool bAssertionFired( false ); + + VirtualDevice* pPrivateDevice = NULL; + if( ! pDummyVDev ) + { + pPrivateDevice = pDummyVDev = new VirtualDevice(); + pDummyVDev->EnableOutput( sal_False ); + pDummyVDev->SetMapMode( i_rMtf.GetPrefMapMode() ); + } + GDIMetaFile aMtf( i_rMtf ); + + for( sal_uInt32 i = 0, nCount = aMtf.GetActionCount(); i < nCount; ) + { + if ( !i_pOutDevData || !i_pOutDevData->PlaySyncPageAct( m_rOuterFace, i ) ) + { + const MetaAction* pAction = aMtf.GetAction( i ); + const USHORT nType = pAction->GetType(); + + switch( nType ) + { + case( META_PIXEL_ACTION ): + { + const MetaPixelAction* pA = (const MetaPixelAction*) pAction; + m_rOuterFace.DrawPixel( pA->GetPoint(), pA->GetColor() ); + } + break; + + case( META_POINT_ACTION ): + { + const MetaPointAction* pA = (const MetaPointAction*) pAction; + m_rOuterFace.DrawPixel( pA->GetPoint() ); + } + break; + + case( META_LINE_ACTION ): + { + const MetaLineAction* pA = (const MetaLineAction*) pAction; + if ( pA->GetLineInfo().IsDefault() ) + m_rOuterFace.DrawLine( pA->GetStartPoint(), pA->GetEndPoint() ); + else + m_rOuterFace.DrawLine( pA->GetStartPoint(), pA->GetEndPoint(), pA->GetLineInfo() ); + } + break; + + case( META_RECT_ACTION ): + { + const MetaRectAction* pA = (const MetaRectAction*) pAction; + m_rOuterFace.DrawRect( pA->GetRect() ); + } + break; + + case( META_ROUNDRECT_ACTION ): + { + const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction; + m_rOuterFace.DrawRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() ); + } + break; + + case( META_ELLIPSE_ACTION ): + { + const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction; + m_rOuterFace.DrawEllipse( pA->GetRect() ); + } + break; + + case( META_ARC_ACTION ): + { + const MetaArcAction* pA = (const MetaArcAction*) pAction; + m_rOuterFace.DrawArc( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); + } + break; + + case( META_PIE_ACTION ): + { + const MetaArcAction* pA = (const MetaArcAction*) pAction; + m_rOuterFace.DrawPie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); + } + break; + + case( META_CHORD_ACTION ): + { + const MetaChordAction* pA = (const MetaChordAction*) pAction; + m_rOuterFace.DrawChord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() ); + } + break; + + case( META_POLYGON_ACTION ): + { + const MetaPolygonAction* pA = (const MetaPolygonAction*) pAction; + m_rOuterFace.DrawPolygon( pA->GetPolygon() ); + } + break; + + case( META_POLYLINE_ACTION ): + { + const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pAction; + if ( pA->GetLineInfo().IsDefault() ) + m_rOuterFace.DrawPolyLine( pA->GetPolygon() ); + else + m_rOuterFace.DrawPolyLine( pA->GetPolygon(), pA->GetLineInfo() ); + } + break; + + case( META_POLYPOLYGON_ACTION ): + { + const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pAction; + m_rOuterFace.DrawPolyPolygon( pA->GetPolyPolygon() ); + } + break; + + case( META_GRADIENT_ACTION ): + { + const MetaGradientAction* pA = (const MetaGradientAction*) pAction; + const PolyPolygon aPolyPoly( pA->GetRect() ); + + implWriteGradient( aPolyPoly, pA->GetGradient(), pDummyVDev, i_rContext ); + } + break; + + case( META_GRADIENTEX_ACTION ): + { + const MetaGradientExAction* pA = (const MetaGradientExAction*) pAction; + implWriteGradient( pA->GetPolyPolygon(), pA->GetGradient(), pDummyVDev, i_rContext ); + } + break; + + case META_HATCH_ACTION: + { + const MetaHatchAction* pA = (const MetaHatchAction*) pAction; + m_rOuterFace.DrawHatch( pA->GetPolyPolygon(), pA->GetHatch() ); + } + break; + + case( META_TRANSPARENT_ACTION ): + { + const MetaTransparentAction* pA = (const MetaTransparentAction*) pAction; + m_rOuterFace.DrawTransparent( pA->GetPolyPolygon(), pA->GetTransparence() ); + } + break; + + case( META_FLOATTRANSPARENT_ACTION ): + { + const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction; + + GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() ); + const Point& rPos = pA->GetPoint(); + const Size& rSize= pA->GetSize(); + const Gradient& rTransparenceGradient = pA->GetGradient(); + + // special case constant alpha value + if( rTransparenceGradient.GetStartColor() == rTransparenceGradient.GetEndColor() ) + { + const Color aTransCol( rTransparenceGradient.GetStartColor() ); + const USHORT nTransPercent = aTransCol.GetLuminance() * 100 / 255; + m_rOuterFace.BeginTransparencyGroup(); + playMetafile( aTmpMtf, NULL, i_rContext, pDummyVDev ); + m_rOuterFace.EndTransparencyGroup( Rectangle( rPos, rSize ), nTransPercent ); + } + else + { + const Size aDstSizeTwip( pDummyVDev->PixelToLogic( pDummyVDev->LogicToPixel( rSize ), MAP_TWIP ) ); + sal_Int32 nMaxBmpDPI = i_rContext.m_bOnlyLosslessCompression ? 300 : 72; + if( i_rContext.m_nMaxImageResolution > 50 ) + { + if ( nMaxBmpDPI > i_rContext.m_nMaxImageResolution ) + nMaxBmpDPI = i_rContext.m_nMaxImageResolution; + } + const sal_Int32 nPixelX = (sal_Int32)((double)aDstSizeTwip.Width() * (double)nMaxBmpDPI / 1440.0); + const sal_Int32 nPixelY = (sal_Int32)((double)aDstSizeTwip.Height() * (double)nMaxBmpDPI / 1440.0); + if ( nPixelX && nPixelY ) + { + Size aDstSizePixel( nPixelX, nPixelY ); + VirtualDevice* pVDev = new VirtualDevice; + if( pVDev->SetOutputSizePixel( aDstSizePixel ) ) + { + Bitmap aPaint, aMask; + AlphaMask aAlpha; + Point aPoint; + + MapMode aMapMode( pDummyVDev->GetMapMode() ); + aMapMode.SetOrigin( aPoint ); + pVDev->SetMapMode( aMapMode ); + Size aDstSize( pVDev->PixelToLogic( aDstSizePixel ) ); + + Point aMtfOrigin( aTmpMtf.GetPrefMapMode().GetOrigin() ); + if ( aMtfOrigin.X() || aMtfOrigin.Y() ) + aTmpMtf.Move( -aMtfOrigin.X(), -aMtfOrigin.Y() ); + double fScaleX = (double)aDstSize.Width() / (double)aTmpMtf.GetPrefSize().Width(); + double fScaleY = (double)aDstSize.Height() / (double)aTmpMtf.GetPrefSize().Height(); + if( fScaleX != 1.0 || fScaleY != 1.0 ) + aTmpMtf.Scale( fScaleX, fScaleY ); + aTmpMtf.SetPrefMapMode( aMapMode ); + + // create paint bitmap + aTmpMtf.WindStart(); + aTmpMtf.Play( pVDev, aPoint, aDstSize ); + aTmpMtf.WindStart(); + + pVDev->EnableMapMode( FALSE ); + aPaint = pVDev->GetBitmap( aPoint, aDstSizePixel ); + pVDev->EnableMapMode( TRUE ); + + // create mask bitmap + pVDev->SetLineColor( COL_BLACK ); + pVDev->SetFillColor( COL_BLACK ); + pVDev->DrawRect( Rectangle( aPoint, aDstSize ) ); + pVDev->SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT | + DRAWMODE_WHITEBITMAP | DRAWMODE_WHITEGRADIENT ); + aTmpMtf.WindStart(); + aTmpMtf.Play( pVDev, aPoint, aDstSize ); + aTmpMtf.WindStart(); + pVDev->EnableMapMode( FALSE ); + aMask = pVDev->GetBitmap( aPoint, aDstSizePixel ); + pVDev->EnableMapMode( TRUE ); + + // create alpha mask from gradient + pVDev->SetDrawMode( DRAWMODE_GRAYGRADIENT ); + pVDev->DrawGradient( Rectangle( aPoint, aDstSize ), rTransparenceGradient ); + pVDev->SetDrawMode( DRAWMODE_DEFAULT ); + pVDev->EnableMapMode( FALSE ); + pVDev->DrawMask( aPoint, aDstSizePixel, aMask, Color( COL_WHITE ) ); + aAlpha = pVDev->GetBitmap( aPoint, aDstSizePixel ); + implWriteBitmapEx( rPos, rSize, BitmapEx( aPaint, aAlpha ), pDummyVDev, i_rContext ); + } + delete pVDev; + } + } + } + break; + + case( META_EPS_ACTION ): + { + const MetaEPSAction* pA = (const MetaEPSAction*) pAction; + const GDIMetaFile aSubstitute( pA->GetSubstitute() ); + + m_rOuterFace.Push(); + pDummyVDev->Push(); + + MapMode aMapMode( aSubstitute.GetPrefMapMode() ); + Size aOutSize( pDummyVDev->LogicToLogic( pA->GetSize(), pDummyVDev->GetMapMode(), aMapMode ) ); + aMapMode.SetScaleX( Fraction( aOutSize.Width(), aSubstitute.GetPrefSize().Width() ) ); + aMapMode.SetScaleY( Fraction( aOutSize.Height(), aSubstitute.GetPrefSize().Height() ) ); + aMapMode.SetOrigin( pDummyVDev->LogicToLogic( pA->GetPoint(), pDummyVDev->GetMapMode(), aMapMode ) ); + + m_rOuterFace.SetMapMode( aMapMode ); + pDummyVDev->SetMapMode( aMapMode ); + playMetafile( aSubstitute, NULL, i_rContext, pDummyVDev ); + pDummyVDev->Pop(); + m_rOuterFace.Pop(); + } + break; + + case( META_COMMENT_ACTION ): + if( ! i_rContext.m_bTransparenciesWereRemoved ) + { + const MetaCommentAction* pA = (const MetaCommentAction*) pAction; + String aSkipComment; + + if( pA->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_BEGIN" ) == COMPARE_EQUAL ) + { + const MetaGradientExAction* pGradAction = NULL; + sal_Bool bDone = sal_False; + + while( !bDone && ( ++i < nCount ) ) + { + pAction = aMtf.GetAction( i ); + + if( pAction->GetType() == META_GRADIENTEX_ACTION ) + pGradAction = (const MetaGradientExAction*) pAction; + else if( ( pAction->GetType() == META_COMMENT_ACTION ) && + ( ( (const MetaCommentAction*) pAction )->GetComment().CompareIgnoreCaseToAscii( "XGRAD_SEQ_END" ) == COMPARE_EQUAL ) ) + { + bDone = sal_True; + } + } + + if( pGradAction ) + implWriteGradient( pGradAction->GetPolyPolygon(), pGradAction->GetGradient(), pDummyVDev, i_rContext ); + } + else + { + const BYTE* pData = pA->GetData(); + if ( pData ) + { + SvMemoryStream aMemStm( (void*)pData, pA->GetDataSize(), STREAM_READ ); + sal_Bool bSkipSequence = sal_False; + ByteString sSeqEnd; + + if( pA->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ) ) + { + sSeqEnd = ByteString( "XPATHSTROKE_SEQ_END" ); + SvtGraphicStroke aStroke; + aMemStm >> aStroke; + + Polygon aPath; + aStroke.getPath( aPath ); + + PolyPolygon aStartArrow; + PolyPolygon aEndArrow; + double fTransparency( aStroke.getTransparency() ); + double fStrokeWidth( aStroke.getStrokeWidth() ); + SvtGraphicStroke::DashArray aDashArray; + + aStroke.getStartArrow( aStartArrow ); + aStroke.getEndArrow( aEndArrow ); + aStroke.getDashArray( aDashArray ); + + bSkipSequence = sal_True; + if ( aStartArrow.Count() || aEndArrow.Count() ) + bSkipSequence = sal_False; + if ( aDashArray.size() && ( fStrokeWidth != 0.0 ) && ( fTransparency == 0.0 ) ) + bSkipSequence = sal_False; + if ( bSkipSequence ) + { + PDFWriter::ExtLineInfo aInfo; + aInfo.m_fLineWidth = fStrokeWidth; + aInfo.m_fTransparency = fTransparency; + aInfo.m_fMiterLimit = aStroke.getMiterLimit(); + switch( aStroke.getCapType() ) + { + default: + case SvtGraphicStroke::capButt: aInfo.m_eCap = PDFWriter::capButt;break; + case SvtGraphicStroke::capRound: aInfo.m_eCap = PDFWriter::capRound;break; + case SvtGraphicStroke::capSquare: aInfo.m_eCap = PDFWriter::capSquare;break; + } + switch( aStroke.getJoinType() ) + { + default: + case SvtGraphicStroke::joinMiter: aInfo.m_eJoin = PDFWriter::joinMiter;break; + case SvtGraphicStroke::joinRound: aInfo.m_eJoin = PDFWriter::joinRound;break; + case SvtGraphicStroke::joinBevel: aInfo.m_eJoin = PDFWriter::joinBevel;break; + case SvtGraphicStroke::joinNone: + aInfo.m_eJoin = PDFWriter::joinMiter; + aInfo.m_fMiterLimit = 0.0; + break; + } + aInfo.m_aDashArray = aDashArray; + + if(SvtGraphicStroke::joinNone == aStroke.getJoinType() + && fStrokeWidth > 0.0) + { + // emulate no edge rounding by handling single edges + const sal_uInt16 nPoints(aPath.GetSize()); + const bool bCurve(aPath.HasFlags()); + + for(sal_uInt16 a(0); a + 1 < nPoints; a++) + { + if(bCurve + && POLY_NORMAL != aPath.GetFlags(a + 1) + && a + 2 < nPoints + && POLY_NORMAL != aPath.GetFlags(a + 2) + && a + 3 < nPoints) + { + const Polygon aSnippet(4, + aPath.GetConstPointAry() + a, + aPath.GetConstFlagAry() + a); + m_rOuterFace.DrawPolyLine( aSnippet, aInfo ); + a += 2; + } + else + { + const Polygon aSnippet(2, + aPath.GetConstPointAry() + a); + m_rOuterFace.DrawPolyLine( aSnippet, aInfo ); + } + } + } + else + { + m_rOuterFace.DrawPolyLine( aPath, aInfo ); + } + } + } + else if ( pA->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) ) + { + sSeqEnd = ByteString( "XPATHFILL_SEQ_END" ); + SvtGraphicFill aFill; + aMemStm >> aFill; + + if ( ( aFill.getFillType() == SvtGraphicFill::fillSolid ) && ( aFill.getFillRule() == SvtGraphicFill::fillEvenOdd ) ) + { + double fTransparency = aFill.getTransparency(); + if ( fTransparency == 0.0 ) + { + PolyPolygon aPath; + aFill.getPath( aPath ); + + bSkipSequence = sal_True; + m_rOuterFace.DrawPolyPolygon( aPath ); + } + else if ( fTransparency == 1.0 ) + bSkipSequence = sal_True; + } +/* #i81548# removing optimization for fill textures, because most of the texture settings are not + exported properly. In OpenOffice 3.1 the drawing layer will support graphic primitives, then it + will not be a problem to optimize the filltexture export. But for wysiwyg is more important than + filesize. + else if( aFill.getFillType() == SvtGraphicFill::fillTexture && aFill.isTiling() ) + { + sal_Int32 nPattern = mnCachePatternId; + Graphic aPatternGraphic; + aFill.getGraphic( aPatternGraphic ); + bool bUseCache = false; + SvtGraphicFill::Transform aPatTransform; + aFill.getTransform( aPatTransform ); + + if( mnCachePatternId >= 0 ) + { + SvtGraphicFill::Transform aCacheTransform; + maCacheFill.getTransform( aCacheTransform ); + if( aCacheTransform.matrix[0] == aPatTransform.matrix[0] && + aCacheTransform.matrix[1] == aPatTransform.matrix[1] && + aCacheTransform.matrix[2] == aPatTransform.matrix[2] && + aCacheTransform.matrix[3] == aPatTransform.matrix[3] && + aCacheTransform.matrix[4] == aPatTransform.matrix[4] && + aCacheTransform.matrix[5] == aPatTransform.matrix[5] + ) + { + Graphic aCacheGraphic; + maCacheFill.getGraphic( aCacheGraphic ); + if( aCacheGraphic == aPatternGraphic ) + bUseCache = true; + } + } + + if( ! bUseCache ) + { + + // paint graphic to metafile + GDIMetaFile aPattern; + pDummyVDev->SetConnectMetaFile( &aPattern ); + pDummyVDev->Push(); + pDummyVDev->SetMapMode( aPatternGraphic.GetPrefMapMode() ); + + aPatternGraphic.Draw( &rDummyVDev, Point( 0, 0 ) ); + pDummyVDev->Pop(); + pDummyVDev->SetConnectMetaFile( NULL ); + aPattern.WindStart(); + + MapMode aPatternMapMode( aPatternGraphic.GetPrefMapMode() ); + // prepare pattern from metafile + Size aPrefSize( aPatternGraphic.GetPrefSize() ); + // FIXME: this magic -1 shouldn't be necessary + aPrefSize.Width() -= 1; + aPrefSize.Height() -= 1; + aPrefSize = m_rOuterFace.GetReferenceDevice()-> + LogicToLogic( aPrefSize, + &aPatternMapMode, + &m_rOuterFace.GetReferenceDevice()->GetMapMode() ); + // build bounding rectangle of pattern + Rectangle aBound( Point( 0, 0 ), aPrefSize ); + m_rOuterFace.BeginPattern( aBound ); + m_rOuterFace.Push(); + pDummyVDev->Push(); + m_rOuterFace.SetMapMode( aPatternMapMode ); + pDummyVDev->SetMapMode( aPatternMapMode ); + ImplWriteActions( m_rOuterFace, NULL, aPattern, rDummyVDev ); + pDummyVDev->Pop(); + m_rOuterFace.Pop(); + + nPattern = m_rOuterFace.EndPattern( aPatTransform ); + + // try some caching and reuse pattern + mnCachePatternId = nPattern; + maCacheFill = aFill; + } + + // draw polypolygon with pattern fill + PolyPolygon aPath; + aFill.getPath( aPath ); + m_rOuterFace.DrawPolyPolygon( aPath, nPattern, aFill.getFillRule() == SvtGraphicFill::fillEvenOdd ); + + bSkipSequence = sal_True; + } +*/ + } + if ( bSkipSequence ) + { + while( ++i < nCount ) + { + pAction = aMtf.GetAction( i ); + if ( pAction->GetType() == META_COMMENT_ACTION ) + { + ByteString sComment( ((MetaCommentAction*)pAction)->GetComment() ); + if ( sComment.Equals( sSeqEnd ) ) + break; + } + // #i44496# + // the replacement action for stroke is a filled rectangle + // the set fillcolor of the replacement is part of the graphics + // state and must not be skipped + else if( pAction->GetType() == META_FILLCOLOR_ACTION ) + { + const MetaFillColorAction* pMA = (const MetaFillColorAction*) pAction; + if( pMA->IsSetting() ) + m_rOuterFace.SetFillColor( pMA->GetColor() ); + else + m_rOuterFace.SetFillColor(); + } + } + } + } + } + } + break; + + case( META_BMP_ACTION ): + { + const MetaBmpAction* pA = (const MetaBmpAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmap() ); + Size aSize( OutputDevice::LogicToLogic( aBitmapEx.GetPrefSize(), + aBitmapEx.GetPrefMapMode(), pDummyVDev->GetMapMode() ) ); + if( ! ( aSize.Width() && aSize.Height() ) ) + aSize = pDummyVDev->PixelToLogic( aBitmapEx.GetSizePixel() ); + implWriteBitmapEx( pA->GetPoint(), aSize, aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_BMPSCALE_ACTION ): + { + const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction; + implWriteBitmapEx( pA->GetPoint(), pA->GetSize(), BitmapEx( pA->GetBitmap() ), pDummyVDev, i_rContext ); + } + break; + + case( META_BMPSCALEPART_ACTION ): + { + const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmap() ); + aBitmapEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ); + implWriteBitmapEx( pA->GetDestPoint(), pA->GetDestSize(), aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_BMPEX_ACTION ): + { + const MetaBmpExAction* pA = (const MetaBmpExAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmapEx() ); + Size aSize( OutputDevice::LogicToLogic( aBitmapEx.GetPrefSize(), + aBitmapEx.GetPrefMapMode(), pDummyVDev->GetMapMode() ) ); + implWriteBitmapEx( pA->GetPoint(), aSize, aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_BMPEXSCALE_ACTION ): + { + const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction; + implWriteBitmapEx( pA->GetPoint(), pA->GetSize(), pA->GetBitmapEx(), pDummyVDev, i_rContext ); + } + break; + + case( META_BMPEXSCALEPART_ACTION ): + { + const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction; + BitmapEx aBitmapEx( pA->GetBitmapEx() ); + aBitmapEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ); + implWriteBitmapEx( pA->GetDestPoint(), pA->GetDestSize(), aBitmapEx, pDummyVDev, i_rContext ); + } + break; + + case( META_MASK_ACTION ): + case( META_MASKSCALE_ACTION ): + case( META_MASKSCALEPART_ACTION ): + { + DBG_ERROR( "MetaMask...Action not supported yet" ); + } + break; + + case( META_TEXT_ACTION ): + { + const MetaTextAction* pA = (const MetaTextAction*) pAction; + m_rOuterFace.DrawText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ) ); + } + break; + + case( META_TEXTRECT_ACTION ): + { + const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction; + m_rOuterFace.DrawText( pA->GetRect(), String( pA->GetText() ), pA->GetStyle() ); + } + break; + + case( META_TEXTARRAY_ACTION ): + { + const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction; + m_rOuterFace.DrawTextArray( pA->GetPoint(), pA->GetText(), pA->GetDXArray(), pA->GetIndex(), pA->GetLen() ); + } + break; + + case( META_STRETCHTEXT_ACTION ): + { + const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction; + m_rOuterFace.DrawStretchText( pA->GetPoint(), pA->GetWidth(), pA->GetText(), pA->GetIndex(), pA->GetLen() ); + } + break; + + + case( META_TEXTLINE_ACTION ): + { + const MetaTextLineAction* pA = (const MetaTextLineAction*) pAction; + m_rOuterFace.DrawTextLine( pA->GetStartPoint(), pA->GetWidth(), pA->GetStrikeout(), pA->GetUnderline(), pA->GetOverline() ); + + } + break; + + case( META_CLIPREGION_ACTION ): + { + const MetaClipRegionAction* pA = (const MetaClipRegionAction*) pAction; + + if( pA->IsClipping() ) + { + if( pA->GetRegion().IsEmpty() ) + m_rOuterFace.SetClipRegion( basegfx::B2DPolyPolygon() ); + else + { + Region aReg( pA->GetRegion() ); + m_rOuterFace.SetClipRegion( aReg.ConvertToB2DPolyPolygon() ); + } + } + else + m_rOuterFace.SetClipRegion(); + } + break; + + case( META_ISECTRECTCLIPREGION_ACTION ): + { + const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pAction; + m_rOuterFace.IntersectClipRegion( pA->GetRect() ); + } + break; + + case( META_ISECTREGIONCLIPREGION_ACTION ): + { + const MetaISectRegionClipRegionAction* pA = (const MetaISectRegionClipRegionAction*) pAction; + Region aReg( pA->GetRegion() ); + m_rOuterFace.IntersectClipRegion( aReg.ConvertToB2DPolyPolygon() ); + } + break; + + case( META_MOVECLIPREGION_ACTION ): + { + const MetaMoveClipRegionAction* pA = (const MetaMoveClipRegionAction*) pAction; + m_rOuterFace.MoveClipRegion( pA->GetHorzMove(), pA->GetVertMove() ); + } + break; + + case( META_MAPMODE_ACTION ): + { + const_cast< MetaAction* >( pAction )->Execute( pDummyVDev ); + m_rOuterFace.SetMapMode( pDummyVDev->GetMapMode() ); + } + break; + + case( META_LINECOLOR_ACTION ): + { + const MetaLineColorAction* pA = (const MetaLineColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetLineColor( pA->GetColor() ); + else + m_rOuterFace.SetLineColor(); + } + break; + + case( META_FILLCOLOR_ACTION ): + { + const MetaFillColorAction* pA = (const MetaFillColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetFillColor( pA->GetColor() ); + else + m_rOuterFace.SetFillColor(); + } + break; + + case( META_TEXTLINECOLOR_ACTION ): + { + const MetaTextLineColorAction* pA = (const MetaTextLineColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetTextLineColor( pA->GetColor() ); + else + m_rOuterFace.SetTextLineColor(); + } + break; + + case( META_OVERLINECOLOR_ACTION ): + { + const MetaOverlineColorAction* pA = (const MetaOverlineColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetOverlineColor( pA->GetColor() ); + else + m_rOuterFace.SetOverlineColor(); + } + break; + + case( META_TEXTFILLCOLOR_ACTION ): + { + const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pAction; + + if( pA->IsSetting() ) + m_rOuterFace.SetTextFillColor( pA->GetColor() ); + else + m_rOuterFace.SetTextFillColor(); + } + break; + + case( META_TEXTCOLOR_ACTION ): + { + const MetaTextColorAction* pA = (const MetaTextColorAction*) pAction; + m_rOuterFace.SetTextColor( pA->GetColor() ); + } + break; + + case( META_TEXTALIGN_ACTION ): + { + const MetaTextAlignAction* pA = (const MetaTextAlignAction*) pAction; + m_rOuterFace.SetTextAlign( pA->GetTextAlign() ); + } + break; + + case( META_FONT_ACTION ): + { + const MetaFontAction* pA = (const MetaFontAction*) pAction; + m_rOuterFace.SetFont( pA->GetFont() ); + } + break; + + case( META_PUSH_ACTION ): + { + const MetaPushAction* pA = (const MetaPushAction*) pAction; + + pDummyVDev->Push( pA->GetFlags() ); + m_rOuterFace.Push( pA->GetFlags() ); + } + break; + + case( META_POP_ACTION ): + { + pDummyVDev->Pop(); + m_rOuterFace.Pop(); + } + break; + + case( META_LAYOUTMODE_ACTION ): + { + const MetaLayoutModeAction* pA = (const MetaLayoutModeAction*) pAction; + m_rOuterFace.SetLayoutMode( pA->GetLayoutMode() ); + } + break; + + case META_TEXTLANGUAGE_ACTION: + { + const MetaTextLanguageAction* pA = (const MetaTextLanguageAction*) pAction; + m_rOuterFace.SetDigitLanguage( pA->GetTextLanguage() ); + } + break; + + case( META_WALLPAPER_ACTION ): + { + const MetaWallpaperAction* pA = (const MetaWallpaperAction*) pAction; + m_rOuterFace.DrawWallpaper( pA->GetRect(), pA->GetWallpaper() ); + } + break; + + case( META_RASTEROP_ACTION ): + { + // !!! >>> we don't want to support this actions + } + break; + + case( META_REFPOINT_ACTION ): + { + // !!! >>> we don't want to support this actions + } + break; + + default: + // #i24604# Made assertion fire only once per + // metafile. The asserted actions here are all + // deprecated + if( !bAssertionFired ) + { + bAssertionFired = true; + DBG_ERROR( "PDFExport::ImplWriteActions: deprecated and unsupported MetaAction encountered" ); + } + break; + } + i++; + } + } + + delete pPrivateDevice; +} + + diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index d8581cc3fa7a..9d8f3bf2f9a0 100755 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -558,7 +558,7 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: mnCurPage = 1; mnCurPrintPage = 1; mbPrinting = TRUE; - if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) + if( GetCapabilities( PRINTER_CAPABILITIES_USEPULLMODEL ) ) { mbJobActive = TRUE; // sallayer does all necessary page printing diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index a0be94674328..9a22aa913ded 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -2575,6 +2575,7 @@ void PrintProgressDialog::tick() void PrintProgressDialog::reset() { + mbCanceled = false; setProgress( 0 ); } diff --git a/vcl/unx/inc/salprn.h b/vcl/unx/inc/salprn.h index fa68f1b38e73..6e6ca0a2f1cc 100644 --- a/vcl/unx/inc/salprn.h +++ b/vcl/unx/inc/salprn.h @@ -71,6 +71,7 @@ public: bool m_bFax:1; bool m_bPdf:1; bool m_bSwallowFaxNo:1; + bool m_bIsPDFWriterJob:1; PspGraphics* m_pGraphics; psp::PrinterJob m_aPrintJob; psp::JobData m_aJobData; @@ -91,6 +92,11 @@ public: bool bCollate, bool bDirect, ImplJobSetup* pSetupData ); + virtual BOOL StartJob( const String*, + const String&, + const String&, + ImplJobSetup*, + vcl::PrinterController& i_rController ); virtual BOOL EndJob(); virtual BOOL AbortJob(); virtual SalGraphics* StartPage( ImplJobSetup* pSetupData, BOOL bNewJobData ); diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx index 8617bc4e5bfa..417704eb3b69 100644 --- a/vcl/unx/source/gdi/salprnpsp.cxx +++ b/vcl/unx/source/gdi/salprnpsp.cxx @@ -54,6 +54,8 @@ #include "vcl/svapp.hxx" #include "vcl/jobset.h" #include "vcl/print.h" +#include "vcl/print.hxx" +#include "vcl/pdfwriter.hxx" #include "vcl/salptype.hxx" #include "vcl/printerinfomanager.hxx" @@ -63,6 +65,7 @@ using namespace psp; using namespace rtl; +using namespace com::sun::star; /* * static helpers @@ -892,9 +895,26 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT case PRINTER_CAPABILITIES_FAX: return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "fax" ) ? 1 : 0; case PRINTER_CAPABILITIES_PDF: - return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "pdf" ) ? 1 : 0; + if( PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "pdf" ) ) + return 1; + else + { + // see if the PPD contains a value to set Collate to True + JobData aData = PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ); + if( pJobSetup->mpDriverData ) + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + return aData.m_nPDFDevice > 0 ? 1 : 0; + } case PRINTER_CAPABILITIES_EXTERNALDIALOG: return PrinterInfoManager::get().checkFeatureToken( pJobSetup->maPrinterName, "external_dialog" ) ? 1 : 0; + case PRINTER_CAPABILITIES_USEPULLMODEL: + { + // see if the PPD contains a value to set Collate to True + JobData aData = PrinterInfoManager::get().getPrinterInfo( pJobSetup->maPrinterName ); + if( pJobSetup->mpDriverData ) + JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData ); + return aData.m_nPDFDevice > 0 ? 1 : 0; + } default: break; }; return 0; @@ -910,6 +930,7 @@ ULONG PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT : m_bFax( false ), m_bPdf( false ), m_bSwallowFaxNo( false ), + m_bIsPDFWriterJob( false ), m_pGraphics( NULL ), m_nCopies( 1 ), m_bCollate( false ), @@ -1021,22 +1042,28 @@ BOOL PspSalPrinter::StartJob( BOOL PspSalPrinter::EndJob() { - BOOL bSuccess = m_aPrintJob.EndJob(); - - if( bSuccess ) + BOOL bSuccess = FALSE; + if( m_bIsPDFWriterJob ) + bSuccess = TRUE; + else { - // check for fax - if( m_bFax ) - { + bSuccess = m_aPrintJob.EndJob(); - const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); - // sendAFax removes the file after use - bSuccess = sendAFax( m_aFaxNr, m_aTmpFile, rInfo.m_aCommand ); - } - else if( m_bPdf ) + if( bSuccess ) { - const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); - bSuccess = createPdf( m_aFileName, m_aTmpFile, rInfo.m_aCommand ); + // check for fax + if( m_bFax ) + { + + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + // sendAFax removes the file after use + bSuccess = sendAFax( m_aFaxNr, m_aTmpFile, rInfo.m_aCommand ); + } + else if( m_bPdf ) + { + const PrinterInfo& rInfo( PrinterInfoManager::get().getPrinterInfo( m_aJobData.m_aPrinterName ) ); + bSuccess = createPdf( m_aFileName, m_aTmpFile, rInfo.m_aCommand ); + } } } vcl_sal::PrinterUpdate::jobEnded(); @@ -1089,6 +1116,274 @@ ULONG PspSalPrinter::GetErrorCode() return 0; } +// ----------------------------------------------------------------------- + +struct PDFNewJobParameters +{ + Size maPageSize; + USHORT mnPaperBin; + + PDFNewJobParameters( const Size& i_rSize = Size(), + USHORT i_nPaperBin = 0xffff ) + : maPageSize( i_rSize ), mnPaperBin( i_nPaperBin ) {} + + bool operator!=(const PDFNewJobParameters& rComp ) const + { + Size aCompLSSize( rComp.maPageSize.Height(), rComp.maPageSize.Width() ); + return + (maPageSize != rComp.maPageSize && maPageSize != aCompLSSize) + || mnPaperBin != rComp.mnPaperBin + ; + } + + bool operator==(const PDFNewJobParameters& rComp) const + { + return ! this->operator!=(rComp); + } +}; + +struct PDFPrintFile +{ + rtl::OUString maTmpURL; + PDFNewJobParameters maParameters; + + PDFPrintFile( const rtl::OUString& i_rURL, const PDFNewJobParameters& i_rNewParameters ) + : maTmpURL( i_rURL ) + , maParameters( i_rNewParameters ) {} +}; + +BOOL PspSalPrinter::StartJob( const String* i_pFileName, const String& i_rJobName, const String& i_rAppName, + ImplJobSetup* i_pSetupData, vcl::PrinterController& i_rController ) +{ + OSL_TRACE( "StartJob with controller: pFilename = %s", i_pFileName ? rtl::OUStringToOString( *i_pFileName, RTL_TEXTENCODING_UTF8 ).getStr() : "<nil>" ); + // mark for endjob + m_bIsPDFWriterJob = true; + // reset IsLastPage + i_rController.setLastPage( sal_False ); + + // update job data + if( i_pSetupData ) + JobData::constructFromStreamBuffer( i_pSetupData->mpDriverData, i_pSetupData->mnDriverDataLen, m_aJobData ); + + OSL_ASSERT( m_aJobData.m_nPDFDevice > 0 ); + m_aJobData.m_nPDFDevice = 1; + + // possibly create one job for collated output + sal_Bool bSinglePrintJobs = sal_False; + beans::PropertyValue* pSingleValue = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) ); + if( pSingleValue ) + { + pSingleValue->Value >>= bSinglePrintJobs; + } + + int nCopies = i_rController.getPrinter()->GetCopyCount(); + bool bCollate = i_rController.getPrinter()->IsCollateCopy(); + + // notify start of real print job + i_rController.jobStarted(); + + // setup PDFWriter context + vcl::PDFWriter::PDFWriterContext aContext; + aContext.Version = vcl::PDFWriter::PDF_1_4; + aContext.Tagged = false; + aContext.EmbedStandardFonts = true; + aContext.Encrypt = false; + aContext.DocumentLocale = Application::GetSettings().GetLocale(); + + // prepare doc info + vcl::PDFDocInfo aDocInfo; + aDocInfo.Title = i_rJobName; + aDocInfo.Creator = i_rAppName; + aDocInfo.Producer = i_rAppName; + + // define how we handle metafiles in PDFWriter + vcl::PDFWriter::PlayMetafileContext aMtfContext; + aMtfContext.m_bOnlyLosslessCompression = true; + + boost::shared_ptr<vcl::PDFWriter> pWriter; + std::vector< PDFPrintFile > aPDFFiles; + boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() ); + int nAllPages = i_rController.getFilteredPageCount(); + i_rController.createProgressDialog(); + bool bAborted = false; + PDFNewJobParameters aLastParm; + + aContext.DPIx = pPrinter->ImplGetDPIX(); + aContext.DPIy = pPrinter->ImplGetDPIY(); + for( int nPage = 0; nPage < nAllPages && ! bAborted; nPage++ ) + { + if( nPage == nAllPages-1 ) + i_rController.setLastPage( sal_True ); + + // get the page's metafile + GDIMetaFile aPageFile; + vcl::PrinterController::PageSize aPageSize = i_rController.getFilteredPageFile( nPage, aPageFile ); + if( i_rController.isProgressCanceled() ) + { + bAborted = true; + if( nPage != nAllPages-1 ) + { + i_rController.createProgressDialog(); + i_rController.setLastPage( sal_True ); + i_rController.getFilteredPageFile( nPage, aPageFile ); + } + } + else + { + pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); + pPrinter->SetPaperSizeUser( aPageSize.aSize, true ); + PDFNewJobParameters aNewParm( pPrinter->GetPaperSize(), pPrinter->GetPaperBin() ); + + // create PDF writer on demand + // either on first page + // or on paper format change - cups does not support multiple paper formats per job (yet?) + // so we need to start a new job to get a new paper format from the printer + // orientation switches (that is switch of height and width) is handled transparently by CUPS + if( ! pWriter || + (aNewParm != aLastParm && ! i_pFileName ) ) + { + if( pWriter ) + { + pWriter->Emit(); + } + // produce PDF file + OUString aPDFUrl; + if( i_pFileName ) + aPDFUrl = *i_pFileName; + else + osl_createTempFile( NULL, NULL, &aPDFUrl.pData ); + // normalize to file URL + if( aPDFUrl.compareToAscii( "file:", 5 ) != 0 ) + { + // this is not a file URL, but it should + // form it into a osl friendly file URL + rtl::OUString aTmp; + osl_getFileURLFromSystemPath( aPDFUrl.pData, &aTmp.pData ); + aPDFUrl = aTmp; + } + // save current file and paper format + aLastParm = aNewParm; + aPDFFiles.push_back( PDFPrintFile( aPDFUrl, aNewParm ) ); + // update context + aContext.URL = aPDFUrl; + + // create and initialize PDFWriter + #if defined __SUNPRO_CC + #pragma disable_warn + #endif + pWriter.reset( new vcl::PDFWriter( aContext ) ); + #if defined __SUNPRO_CC + #pragma enable_warn + #endif + pWriter->SetDocInfo( aDocInfo ); + } + + pWriter->NewPage( TenMuToPt( aNewParm.maPageSize.Width() ), + TenMuToPt( aNewParm.maPageSize.Height() ), + vcl::PDFWriter::Portrait ); + + pWriter->PlayMetafile( aPageFile, aMtfContext, NULL ); + } + } + + // emit the last file + if( pWriter ) + pWriter->Emit(); + + // handle collate, copy count and multiple jobs correctly + int nOuterJobs = 1; + if( bSinglePrintJobs ) + { + nOuterJobs = nCopies; + m_aJobData.m_nCopies = 1; + } + else + { + if( bCollate ) + { + if( aPDFFiles.size() == 1 && pPrinter->HasSupport( SUPPORT_COLLATECOPY ) ) + { + m_aJobData.setCollate( true ); + m_aJobData.m_nCopies = nCopies; + } + else + { + nOuterJobs = nCopies; + m_aJobData.m_nCopies = 1; + } + } + else + { + m_aJobData.setCollate( false ); + m_aJobData.m_nCopies = nCopies; + } + } + + // spool files + if( ! i_pFileName && ! bAborted ) + { + bool bFirstJob = true; + for( int nCurJob = 0; nCurJob < nOuterJobs; nCurJob++ ) + { + for( size_t i = 0; i < aPDFFiles.size(); i++ ) + { + oslFileHandle pFile = NULL; + osl_openFile( aPDFFiles[i].maTmpURL.pData, &pFile, osl_File_OpenFlag_Read ); + if( pFile ) + { + osl_setFilePos( pFile, osl_Pos_Absolut, 0 ); + std::vector< char > buffer( 0x10000, 0 ); + // update job data with current page size + Size aPageSize( aPDFFiles[i].maParameters.maPageSize ); + m_aJobData.setPaper( TenMuToPt( aPageSize.Width() ), TenMuToPt( aPageSize.Height() ) ); + // update job data with current paperbin + m_aJobData.setPaperBin( aPDFFiles[i].maParameters.mnPaperBin ); + + // spool current file + FILE* fp = PrinterInfoManager::get().startSpool( pPrinter->GetName(), i_rController.isDirectPrint() ); + if( fp ) + { + sal_uInt64 nBytesRead = 0; + do + { + osl_readFile( pFile, &buffer[0], buffer.size(), &nBytesRead ); + if( nBytesRead > 0 ) + fwrite( &buffer[0], 1, nBytesRead, fp ); + } while( nBytesRead == buffer.size() ); + rtl::OUStringBuffer aBuf( i_rJobName.Len() + 8 ); + aBuf.append( i_rJobName ); + if( i > 0 || nCurJob > 0 ) + { + aBuf.append( sal_Unicode(' ') ); + aBuf.append( sal_Int32( i + nCurJob * aPDFFiles.size() ) ); + } + PrinterInfoManager::get().endSpool( pPrinter->GetName(), aBuf.makeStringAndClear(), fp, m_aJobData, bFirstJob ); + bFirstJob = false; + } + } + osl_closeFile( pFile ); + } + } + } + + // job has been spooled + i_rController.setJobState( bAborted ? view::PrintableState_JOB_ABORTED : view::PrintableState_JOB_SPOOLED ); + + // clean up the temporary PDF files + if( ! i_pFileName || bAborted ) + { + for( size_t i = 0; i < aPDFFiles.size(); i++ ) + { + osl_removeFile( aPDFFiles[i].maTmpURL.pData ); + OSL_TRACE( "removed print PDF file %s\n", rtl::OUStringToOString( aPDFFiles[i].maTmpURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + + return TRUE; +} + + + /* * vcl::PrinterUpdate */ diff --git a/vcl/unx/source/printer/cupsmgr.cxx b/vcl/unx/source/printer/cupsmgr.cxx index e245b2548c79..caf3249b5f46 100644 --- a/vcl/unx/source/printer/cupsmgr.cxx +++ b/vcl/unx/source/printer/cupsmgr.cxx @@ -524,12 +524,18 @@ void CUPSManager::initialize() // introduced in dests with 1.2 // this is needed to check for %%IncludeFeature support // (#i65684#, #i65491#) + bool bUsePDF = false; cups_dest_t* pDest = ((cups_dest_t*)m_pDests); const char* pOpt = m_pCUPSWrapper->cupsGetOption( "printer-info", pDest->num_options, pDest->options ); if( pOpt ) + { m_bUseIncludeFeature = true; + bUsePDF = true; + if( m_aGlobalDefaults.m_nPSLevel == 0 && m_aGlobalDefaults.m_nPDFDevice == 0 ) + m_aGlobalDefaults.m_nPDFDevice = 1; + } // do not send include JobPatch; CUPS will insert that itself // TODO: currently unknwon which versions of CUPS insert JobPatches // so currently it is assumed CUPS = don't insert JobPatch files @@ -593,6 +599,8 @@ void CUPSManager::initialize() aPrinter.m_aInfo.m_pParser = c_it->second.getParser(); aPrinter.m_aInfo.m_aContext = c_it->second; } + if( bUsePDF && aPrinter.m_aInfo.m_nPSLevel == 0 && aPrinter.m_aInfo.m_nPDFDevice == 0 ) + aPrinter.m_aInfo.m_nPDFDevice = 1; aPrinter.m_aInfo.m_aDriverName = aBuf.makeStringAndClear(); aPrinter.m_bModified = false; @@ -826,8 +834,15 @@ void CUPSManager::setupJobContextData( FILE* CUPSManager::startSpool( const OUString& rPrintername, bool bQuickCommand ) { + OSL_TRACE( "endSpool: %s, %s", + rtl::OUStringToOString( rPrintername, RTL_TEXTENCODING_UTF8 ).getStr(), + bQuickCommand ? "true" : "false" ); + if( m_aCUPSDestMap.find( rPrintername ) == m_aCUPSDestMap.end() ) + { + OSL_TRACE( "defer to PrinterInfoManager::startSpool" ); return PrinterInfoManager::startSpool( rPrintername, bQuickCommand ); + } #ifdef ENABLE_CUPS OUString aTmpURL, aTmpFile; @@ -850,7 +865,7 @@ struct less_ppd_key : public ::std::binary_function<double, double, bool> { return left->getOrderDependency() < right->getOrderDependency(); } }; -void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, int& rNumOptions, void** rOptions ) const +void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner, int& rNumOptions, void** rOptions ) const { rNumOptions = 0; *rOptions = NULL; @@ -880,10 +895,26 @@ void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, int& rNumOpt } } } + + if( rJob.m_nPDFDevice > 0 && rJob.m_nCopies > 1 ) + { + rtl::OString aVal( rtl::OString::valueOf( sal_Int32( rJob.m_nCopies ) ) ); + rNumOptions = m_pCUPSWrapper->cupsAddOption( "copies", aVal.getStr(), rNumOptions, (cups_option_t**)rOptions ); + } + if( ! bBanner ) + { + rNumOptions = m_pCUPSWrapper->cupsAddOption( "job-sheets", "none", rNumOptions, (cups_option_t**)rOptions ); + } } -int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData ) +int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner ) { + OSL_TRACE( "endSpool: %s, %s, copy count = %d", + rtl::OUStringToOString( rPrintername, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( rJobTitle, RTL_TEXTENCODING_UTF8 ).getStr(), + rDocumentJobData.m_nCopies + ); + int nJobID = 0; osl::MutexGuard aGuard( m_aCUPSMutex ); @@ -891,7 +922,10 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit std::hash_map< OUString, int, OUStringHash >::iterator dest_it = m_aCUPSDestMap.find( rPrintername ); if( dest_it == m_aCUPSDestMap.end() ) - return PrinterInfoManager::endSpool( rPrintername, rJobTitle, pFile, rDocumentJobData ); + { + OSL_TRACE( "defer to PrinterInfoManager::endSpool" ); + return PrinterInfoManager::endSpool( rPrintername, rJobTitle, pFile, rDocumentJobData, bBanner ); + } #ifdef ENABLE_CUPS std::hash_map< FILE*, OString, FPtrHash >::const_iterator it = m_aSpoolFiles.find( pFile ); @@ -903,7 +937,7 @@ int CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTit // setup cups options int nNumOptions = 0; cups_option_t* pOptions = NULL; - getOptionsFromDocumentSetup( rDocumentJobData, nNumOptions, (void**)&pOptions ); + getOptionsFromDocumentSetup( rDocumentJobData, bBanner, nNumOptions, (void**)&pOptions ); cups_dest_t* pDest = ((cups_dest_t*)m_pDests) + dest_it->second; nJobID = m_pCUPSWrapper->cupsPrintFile( pDest->name, diff --git a/vcl/unx/source/printer/jobdata.cxx b/vcl/unx/source/printer/jobdata.cxx index a1bca9441f77..d4211eae31df 100644 --- a/vcl/unx/source/printer/jobdata.cxx +++ b/vcl/unx/source/printer/jobdata.cxx @@ -51,6 +51,7 @@ JobData& JobData::operator=(const JobData& rRight) m_pParser = rRight.m_pParser; m_aContext = rRight.m_aContext; m_nPSLevel = rRight.m_nPSLevel; + m_nPDFDevice = rRight.m_nPDFDevice; m_nColorDevice = rRight.m_nColorDevice; if( ! m_pParser && m_aPrinterName.getLength() ) @@ -83,6 +84,34 @@ void JobData::setCollate( bool bCollate ) } } +bool JobData::setPaper( int i_nWidth, int i_nHeight ) +{ + bool bSuccess = false; + if( m_pParser ) + { + rtl::OUString aPaper( m_pParser->matchPaper( i_nWidth, i_nHeight ) ); + + const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); + const PPDValue* pValue = pKey ? pKey->getValueCaseInsensitive( aPaper ) : NULL; + + bSuccess = pKey && pValue && m_aContext.setValue( pKey, pValue, false ); + } + return bSuccess; +} + +bool JobData::setPaperBin( int i_nPaperBin ) +{ + bool bSuccess = false; + if( m_pParser ) + { + const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ); + const PPDValue* pValue = pKey ? pKey->getValue( i_nPaperBin ) : NULL; + + bSuccess = pKey && pValue && m_aContext.setValue( pKey, pValue, false ); + } + return bSuccess; +} + bool JobData::getStreamBuffer( void*& pData, int& bytes ) { // consistency checks @@ -128,6 +157,10 @@ bool JobData::getStreamBuffer( void*& pData, int& bytes ) aLine += ByteString::CreateFromInt32( m_nPSLevel ); aStream.WriteLine( aLine ); + aLine = "pdfdevice="; + aLine += ByteString::CreateFromInt32( m_nPDFDevice ); + aStream.WriteLine( aLine ); + aLine = "colordevice="; aLine += ByteString::CreateFromInt32( m_nColorDevice ); aStream.WriteLine( aLine ); @@ -158,6 +191,7 @@ bool JobData::constructFromStreamBuffer( void* pData, int bytes, JobData& rJobDa bool bColorDepth = false; bool bColorDevice = false; bool bPSLevel = false; + bool bPDFDevice = false; while( ! aStream.IsEof() ) { aStream.ReadLine( aLine ); @@ -202,6 +236,11 @@ bool JobData::constructFromStreamBuffer( void* pData, int bytes, JobData& rJobDa bPSLevel = true; rJobData.m_nPSLevel = aLine.Copy( 8 ).ToInt32(); } + else if( aLine.CompareTo( "pdfdevice=", 10 ) == COMPARE_EQUAL ) + { + bPDFDevice = true; + rJobData.m_nPDFDevice = aLine.Copy( 10 ).ToInt32(); + } else if( aLine.Equals( "PPDContexData" ) ) { if( bPrinter ) @@ -222,5 +261,5 @@ bool JobData::constructFromStreamBuffer( void* pData, int bytes, JobData& rJobDa } } - return bVersion && bPrinter && bOrientation && bCopies && bContext && bMargin && bPSLevel && bColorDevice && bColorDepth; + return bVersion && bPrinter && bOrientation && bCopies && bContext && bMargin && bPSLevel && bPDFDevice && bColorDevice && bColorDepth; } diff --git a/vcl/unx/source/printer/printerinfomanager.cxx b/vcl/unx/source/printer/printerinfomanager.cxx index c534461ea95c..bd6ce761e989 100644 --- a/vcl/unx/source/printer/printerinfomanager.cxx +++ b/vcl/unx/source/printer/printerinfomanager.cxx @@ -293,6 +293,10 @@ void PrinterInfoManager::initialize() if( aValue.Len() ) m_aGlobalDefaults.m_nPSLevel = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PDFDevice" ); + if( aValue.Len() ) + m_aGlobalDefaults.m_nPDFDevice = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PerformFontSubstitution" ); if( aValue.Len() ) { @@ -504,6 +508,10 @@ void PrinterInfoManager::initialize() if( aValue.Len() ) aPrinter.m_aInfo.m_nPSLevel = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PDFDevice" ); + if( aValue.Len() ) + aPrinter.m_aInfo.m_nPDFDevice = aValue.ToInt32(); + aValue = aConfig.ReadKey( "PerformFontSubstitution" ); if( ! aValue.Equals( "0" ) && ! aValue.EqualsIgnoreCaseAscii( "false" ) ) aPrinter.m_aInfo.m_bPerformFontSubstitution = true; @@ -768,6 +776,7 @@ bool PrinterInfoManager::writePrinterConfig() pConfig->WriteKey( "Copies", ByteString::CreateFromInt32( it->second.m_aInfo.m_nCopies ) ); pConfig->WriteKey( "Orientation", it->second.m_aInfo.m_eOrientation == orientation::Landscape ? "Landscape" : "Portrait" ); pConfig->WriteKey( "PSLevel", ByteString::CreateFromInt32( it->second.m_aInfo.m_nPSLevel ) ); + pConfig->WriteKey( "PDFDevice", ByteString::CreateFromInt32( it->second.m_aInfo.m_nPDFDevice ) ); pConfig->WriteKey( "ColorDevice", ByteString::CreateFromInt32( it->second.m_aInfo.m_nColorDevice ) ); pConfig->WriteKey( "ColorDepth", ByteString::CreateFromInt32( it->second.m_aInfo.m_nColorDepth ) ); aValue = ByteString::CreateFromInt32( it->second.m_aInfo.m_nLeftMarginAdjust ); @@ -855,9 +864,10 @@ bool PrinterInfoManager::addPrinter( const OUString& rPrinterName, const OUStrin m_aPrinters[ rPrinterName ] = aPrinter; bSuccess = true; #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "new printer %s, level = %d, colordevice = %d, depth = %d\n", + fprintf( stderr, "new printer %s, level = %d, pdfdevice = %d, colordevice = %d, depth = %d\n", OUStringToOString( rPrinterName, osl_getThreadTextEncoding() ).getStr(), m_aPrinters[rPrinterName].m_aInfo.m_nPSLevel, + m_aPrinters[rPrinterName].m_aInfo.m_nPDFDevice, m_aPrinters[rPrinterName].m_aInfo.m_nColorDevice, m_aPrinters[rPrinterName].m_aInfo.m_nColorDepth ); #endif @@ -1105,7 +1115,7 @@ FILE* PrinterInfoManager::startSpool( const OUString& rPrintername, bool bQuickC return popen (aShellCommand.getStr(), "w"); } -int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/ ) +int PrinterInfoManager::endSpool( const OUString& /*rPrintername*/, const OUString& /*rJobTitle*/, FILE* pFile, const JobData& /*rDocumentJobData*/, bool /*bBanner*/ ) { return (0 == pclose( pFile )); } diff --git a/vcl/unx/source/printergfx/printerjob.cxx b/vcl/unx/source/printergfx/printerjob.cxx index 5e18849b8dfe..26a1d75f68c2 100644 --- a/vcl/unx/source/printergfx/printerjob.cxx +++ b/vcl/unx/source/printergfx/printerjob.cxx @@ -341,7 +341,8 @@ PrinterJob::~PrinterJob () delete mpJobTrailer; // XXX should really call osl::remove routines - removeSpoolDir (maSpoolDirName); + if( maSpoolDirName.getLength() ) + removeSpoolDir (maSpoolDirName); // osl::Directory::remove (maSpoolDirName); } @@ -610,7 +611,7 @@ PrinterJob::EndJob () { PrinterInfoManager& rPrinterInfoManager = PrinterInfoManager::get(); if (0 == rPrinterInfoManager.endSpool( m_aLastJobData.m_aPrinterName, - maJobTitle, pDestFILE, m_aDocumentJobData )) + maJobTitle, pDestFILE, m_aDocumentJobData, true )) { bSuccess = sal_False; } |