diff options
Diffstat (limited to 'vcl/source/gdi')
-rw-r--r-- | vcl/source/gdi/bitmap3.cxx | 8 | ||||
-rw-r--r-- | vcl/source/gdi/gdimtf.cxx | 43 | ||||
-rw-r--r-- | vcl/source/gdi/gfxlink.cxx | 59 | ||||
-rw-r--r-- | vcl/source/gdi/imgcons.cxx | 574 | ||||
-rw-r--r-- | vcl/source/gdi/impimage.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/impprn.cxx | 584 | ||||
-rwxr-xr-x[-rw-r--r--] | vcl/source/gdi/makefile.mk | 4 | ||||
-rw-r--r-- | vcl/source/gdi/metaact.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/metric.cxx | 72 | ||||
-rwxr-xr-x[-rw-r--r--] | vcl/source/gdi/outdev2.cxx | 82 | ||||
-rw-r--r-- | vcl/source/gdi/outdev3.cxx | 300 | ||||
-rw-r--r-- | vcl/source/gdi/outdev6.cxx | 42 | ||||
-rw-r--r-- | vcl/source/gdi/outdevnative.cxx | 214 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter.cxx | 7 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 20 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 10 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl2.cxx | 1035 | ||||
-rw-r--r-- | vcl/source/gdi/print2.cxx | 29 | ||||
-rwxr-xr-x[-rw-r--r--] | vcl/source/gdi/print3.cxx | 143 | ||||
-rwxr-xr-x[-rw-r--r--] | vcl/source/gdi/salgdilayout.cxx | 77 | ||||
-rw-r--r-- | vcl/source/gdi/salnativewidgets-none.cxx | 12 |
21 files changed, 1764 insertions, 1559 deletions
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx index 9e2a21b43e37..ec476157fbeb 100644 --- a/vcl/source/gdi/bitmap3.cxx +++ b/vcl/source/gdi/bitmap3.cxx @@ -961,8 +961,8 @@ BOOL Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY ) const long nScanlineSize = pWriteAcc->GetScanlineSize(); const long nNewWidth1 = nNewWidth - 1L; const long nNewHeight1 = nNewHeight - 1L; - const long nWidth1 = pReadAcc->Width() - 1L; - const long nHeight1 = pReadAcc->Height() - 1L; + const long nWidth = pReadAcc->Width(); + const long nHeight = pReadAcc->Height(); long* pLutX = new long[ nNewWidth ]; long* pLutY = new long[ nNewHeight ]; long nX, nY, nMapY, nActY = 0L; @@ -970,10 +970,10 @@ BOOL Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY ) if( nNewWidth1 && nNewHeight1 ) { for( nX = 0L; nX < nNewWidth; nX++ ) - pLutX[ nX ] = nX * nWidth1 / nNewWidth1; + pLutX[ nX ] = nX * nWidth / nNewWidth; for( nY = 0L; nY < nNewHeight; nY++ ) - pLutY[ nY ] = nY * nHeight1 / nNewHeight1; + pLutY[ nY ] = nY * nHeight / nNewHeight; while( nActY < nNewHeight ) { diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 01b34286a086..d36a18a1afba 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -841,6 +841,49 @@ void GDIMetaFile::Move( long nX, long nY ) } } +void GDIMetaFile::Move( long nX, long nY, long nDPIX, long nDPIY ) +{ + const Size aBaseOffset( nX, nY ); + Size aOffset( aBaseOffset ); + VirtualDevice aMapVDev; + + aMapVDev.EnableOutput( FALSE ); + aMapVDev.SetReferenceDevice( nDPIX, nDPIY ); + aMapVDev.SetMapMode( GetPrefMapMode() ); + + for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() ) + { + const long nType = pAct->GetType(); + MetaAction* pModAct; + + if( pAct->GetRefCount() > 1 ) + { + Replace( pModAct = pAct->Clone(), GetCurPos() ); + pAct->Delete(); + } + else + pModAct = pAct; + + if( ( META_MAPMODE_ACTION == nType ) || + ( META_PUSH_ACTION == nType ) || + ( META_POP_ACTION == nType ) ) + { + pModAct->Execute( &aMapVDev ); + if( aMapVDev.GetMapMode().GetMapUnit() == MAP_PIXEL ) + { + aOffset = aMapVDev.LogicToPixel( aBaseOffset, GetPrefMapMode() ); + MapMode aMap( aMapVDev.GetMapMode() ); + aOffset.Width() = static_cast<long>(aOffset.Width() * (double)aMap.GetScaleX()); + aOffset.Height() = static_cast<long>(aOffset.Height() * (double)aMap.GetScaleY()); + } + else + aOffset = aMapVDev.LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev.GetMapMode() ); + } + + pModAct->Move( aOffset.Width(), aOffset.Height() ); + } +} + // ------------------------------------------------------------------------ void GDIMetaFile::Scale( double fScaleX, double fScaleY ) diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx index 4d32990f9335..60ad94a63273 100644 --- a/vcl/source/gdi/gfxlink.cxx +++ b/vcl/source/gdi/gfxlink.cxx @@ -28,6 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" +#include <osl/file.h> #include <tools/vcompat.hxx> #include <tools/urlobj.hxx> #include <tools/debug.hxx> @@ -398,12 +399,10 @@ ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) : { ::utl::TempFile aTempFile; - maURL = INetURLObject(aTempFile.GetURL()); - - if( maURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() ) + maURL = aTempFile.GetURL(); + if( maURL.getLength() ) { - SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); - + SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); if( pOStm ) { pOStm->Write( pData, mnDataSize ); @@ -412,28 +411,8 @@ ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) : if( bError ) { - try - { - ::ucbhelper::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ), - ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); - - aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), - ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); - } - catch( const ::com::sun::star::ucb::ContentCreationException& ) - { - } - catch( const ::com::sun::star::uno::RuntimeException& ) - { - } - catch( const ::com::sun::star::ucb::CommandAbortedException& ) - { - } - catch( const ::com::sun::star::uno::Exception& ) - { - } - - maURL = INetURLObject(); + osl_removeFile( maURL.pData ); + maURL = String(); } } } @@ -445,28 +424,7 @@ ImpSwap::ImpSwap( BYTE* pData, ULONG nDataSize ) : ImpSwap::~ImpSwap() { if( IsSwapped() ) - { - try - { - ::ucbhelper::Content aCnt( maURL.GetMainURL( INetURLObject::NO_DECODE ), - ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); - - aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ), - ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); - } - catch( const ::com::sun::star::ucb::ContentCreationException& ) - { - } - catch( const ::com::sun::star::uno::RuntimeException& ) - { - } - catch( const ::com::sun::star::ucb::CommandAbortedException& ) - { - } - catch( const ::com::sun::star::uno::Exception& ) - { - } - } + osl_removeFile( maURL.pData ); } // ------------------------------------------------------------------------ @@ -477,8 +435,7 @@ BYTE* ImpSwap::GetData() const if( IsSwapped() ) { - SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE ); - + SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE ); if( pIStm ) { pData = new BYTE[ mnDataSize ]; diff --git a/vcl/source/gdi/imgcons.cxx b/vcl/source/gdi/imgcons.cxx deleted file mode 100644 index 0826c5f2310b..000000000000 --- a/vcl/source/gdi/imgcons.cxx +++ /dev/null @@ -1,574 +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" - -#include <tools/stream.hxx> -#include <vcl/bmpacc.hxx> -#include <vcl/bitmapex.hxx> -#include <vcl/image.hxx> -#include <vcl/imgcons.hxx> - -// ------------------- -// - ImplColorMapper - -// ------------------- - -class ImplColorMapper -{ - Color maCol; - ULONG mnR; - ULONG mnG; - ULONG mnB; - ULONG mnT; - ULONG mnRShift; - ULONG mnGShift; - ULONG mnBShift; - ULONG mnTShift; - - ULONG ImplCalcMaskShift( ULONG nVal ); - -public: - - ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask ); - ~ImplColorMapper(); - - const Color& ImplGetColor( ULONG nColor ) - { - maCol.SetRed( (UINT8) ( ( nColor & mnR ) >> mnRShift ) ); - maCol.SetGreen( (UINT8) ( ( nColor & mnG ) >> mnGShift ) ); - maCol.SetBlue( (UINT8) ( ( nColor & mnB ) >> mnBShift ) ); - maCol.SetTransparency( (UINT8) ( ( nColor & mnT ) >> mnTShift ) ); - return maCol; - } -}; - -// ----------------------------------------------------------------------------- - -ImplColorMapper::ImplColorMapper( ULONG nRMask, ULONG nGMask, ULONG nBMask, ULONG nTMask ) : - mnR( nRMask ), - mnG( nGMask ), - mnB( nBMask ), - mnT( nTMask ) -{ - mnRShift = ImplCalcMaskShift( mnR ); - mnGShift = ImplCalcMaskShift( mnG ); - mnBShift = ImplCalcMaskShift( mnB ); - mnTShift = ImplCalcMaskShift( mnT ); -} - -// ----------------------------------------------------------------------------- - -ImplColorMapper::~ImplColorMapper() -{ -} - -// ----------------------------------------------------------------------------- - -ULONG ImplColorMapper::ImplCalcMaskShift( ULONG nVal ) -{ - DBG_ASSERT( nVal > 0, "Mask has no value!" ); - - ULONG nRet = 0UL; - - for( ULONG i = 0UL; i < 32; i++ ) - { - if( nVal & ( 1UL << i ) ) - { - nRet = i; - break; - } - } - - return nRet; -} - -// ----------------- -// - ImageConsumer - -// ----------------- - -ImageConsumer::ImageConsumer() : - mpMapper( NULL ), - mpPal ( NULL ), - mnStatus( 0UL ), - mbTrans ( FALSE ) -{ -} - -// ----------------------------------------------------------------------------- - -ImageConsumer::~ImageConsumer() -{ - delete[] mpPal; - delete mpMapper; -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::Init( sal_uInt32 nWidth, sal_uInt32 nHeight ) -{ - maSize = Size( nWidth, nHeight ); - maBitmap = maMask = Bitmap(); - mnStatus = 0UL; - mbTrans = FALSE; -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::SetColorModel( USHORT nBitCount, - sal_uInt32 nPalEntries, const sal_uInt32* pRGBAPal, - sal_uInt32 nRMask, sal_uInt32 nGMask, sal_uInt32 nBMask, sal_uInt32 nAMask ) -{ - DBG_ASSERT( maSize.Width() && maSize.Height(), "Missing call to ImageConsumer::Init(...)!" ); - - BitmapPalette aPal( Min( (USHORT) nPalEntries, (USHORT) 256 ) ); - - if( nPalEntries ) - { - BitmapColor aCol; - const sal_Int32* pTmp = (sal_Int32*) pRGBAPal; - - delete mpMapper; - mpMapper = NULL; - - delete[] mpPal; - mpPal = new Color[ nPalEntries ]; - - for( ULONG i = 0; i < nPalEntries; i++, pTmp++ ) - { - Color& rCol = mpPal[ i ]; - BYTE cVal; - - cVal = (BYTE) ( ( *pTmp & 0xff000000UL ) >> 24L ); - rCol.SetRed( cVal ); - - if( i < (ULONG) aPal.GetEntryCount() ) - aPal[ (USHORT) i ].SetRed( cVal ); - - cVal = (BYTE) ( ( *pTmp & 0x00ff0000UL ) >> 16L ); - rCol.SetGreen( cVal ); - - if( i < (ULONG) aPal.GetEntryCount() ) - aPal[ (USHORT) i ].SetGreen( cVal ); - - cVal = (BYTE) ( ( *pTmp & 0x0000ff00UL ) >> 8L ); - rCol.SetBlue( cVal ); - - if( i < (ULONG) aPal.GetEntryCount() ) - aPal[ (USHORT) i ].SetBlue( cVal ); - - rCol.SetTransparency( (BYTE) ( ( *pTmp & 0x000000ffL ) ) ); - } - - if( nBitCount <= 1 ) - nBitCount = 1; - else if( nBitCount <= 4 ) - nBitCount = 4; - else if( nBitCount <= 8 ) - nBitCount = 8; - else - nBitCount = 24; - } - else - { - delete mpMapper; - mpMapper = new ImplColorMapper( nRMask, nGMask, nBMask, nAMask ); - - delete[] mpPal; - mpPal = NULL; - - nBitCount = 24; - } - - if( !maBitmap ) - { - - maBitmap = Bitmap( maSize, nBitCount, &aPal ); - maMask = Bitmap( maSize, 1 ); - maMask.Erase( COL_BLACK ); - mbTrans = FALSE; - } -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::SetPixelsByBytes( sal_uInt32 nConsX, sal_uInt32 nConsY, - sal_uInt32 nConsWidth, sal_uInt32 nConsHeight, - const BYTE* pData, sal_uInt32 nOffset, sal_uInt32 nScanSize ) -{ - DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" ); - - BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess(); - BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess(); - sal_Bool bDataChanged = sal_False; - - if( pBmpAcc && pMskAcc ) - { - const long nWidth = pBmpAcc->Width(); - const long nHeight = pBmpAcc->Height(); - - maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) ); - maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) ); - - if( !maChangedRect.IsEmpty() ) - { - const long nStartX = maChangedRect.Left(); - const long nEndX = maChangedRect.Right(); - const long nStartY = maChangedRect.Top(); - const long nEndY = maChangedRect.Bottom(); - - if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const Color& rCol = mpMapper->ImplGetColor( *pTmp++ ); - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) ) - { - BitmapColor aIndex( (BYTE) 0 ); - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const BYTE cIndex = *pTmp++; - const Color& rCol = mpPal[ cIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aIndex.SetIndex( cIndex ); - pBmpAcc->SetPixel( nY, nX, aIndex ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const BYTE* pTmp = pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const BYTE cIndex = *pTmp++; - const Color& rCol = mpPal[ cIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else - { - DBG_ERROR( "Producer format error!" ); - maChangedRect.SetEmpty(); - } - } - } - else - maChangedRect.SetEmpty(); - - maBitmap.ReleaseAccess( pBmpAcc ); - maMask.ReleaseAccess( pMskAcc ); - - if( bDataChanged ) - DataChanged(); -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::SetPixelsByLongs( sal_uInt32 nConsX, sal_uInt32 nConsY, - sal_uInt32 nConsWidth, sal_uInt32 nConsHeight, - const sal_uInt32* pData, sal_uInt32 nOffset, sal_uInt32 nScanSize ) -{ - DBG_ASSERT( !!maBitmap && !!maMask, "Missing call to ImageConsumer::SetColorModel(...)!" ); - - BitmapWriteAccess* pBmpAcc = maBitmap.AcquireWriteAccess(); - BitmapWriteAccess* pMskAcc = maMask.AcquireWriteAccess(); - sal_Bool bDataChanged = sal_False; - - if( pBmpAcc && pMskAcc ) - { - const long nWidth = pBmpAcc->Width(); - const long nHeight = pBmpAcc->Height(); - - maChangedRect = Rectangle( Point(), Size( nWidth, nHeight ) ); - maChangedRect.Intersection( Rectangle( Point( nConsX, nConsY ), Size( nConsWidth, nConsHeight ) ) ); - - if( !maChangedRect.IsEmpty() ) - { - const long nStartX = maChangedRect.Left(); - const long nEndX = maChangedRect.Right(); - const long nStartY = maChangedRect.Top(); - const long nEndY = maChangedRect.Bottom(); - - if( mpMapper && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const Color& rCol = mpMapper->ImplGetColor( *pTmp++ ); - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() <= 8 ) ) - { - BitmapColor aIndex( (BYTE) 0 ); - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const sal_Int32 nIndex = *pTmp++; - const Color& rCol = mpPal[ nIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aIndex.SetIndex( (BYTE) nIndex ); - pBmpAcc->SetPixel( nY, nX, aIndex ); - } - } - } - - bDataChanged = sal_True; - } - else if( mpPal && ( pBmpAcc->GetBitCount() > 8 ) ) - { - BitmapColor aCol; - BitmapColor aMskWhite( pMskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); - - for( long nY = nStartY; nY <= nEndY; nY++ ) - { - const sal_Int32* pTmp = (sal_Int32*) pData + ( nY - nStartY ) * nScanSize + nOffset; - - for( long nX = nStartX; nX <= nEndX; nX++ ) - { - const sal_Int32 nIndex = *pTmp++; - const Color& rCol = mpPal[ nIndex ]; - - // 0: Transparent; >0: Non-Transparent - if( !rCol.GetTransparency() ) - { - pMskAcc->SetPixel( nY, nX, aMskWhite ); - mbTrans = TRUE; - } - else - { - aCol.SetRed( rCol.GetRed() ); - aCol.SetGreen( rCol.GetGreen() ); - aCol.SetBlue( rCol.GetBlue() ); - pBmpAcc->SetPixel( nY, nX, aCol ); - } - } - } - - bDataChanged = sal_True; - } - else - { - DBG_ERROR( "Producer format error!" ); - maChangedRect.SetEmpty(); - } - } - } - else - maChangedRect.SetEmpty(); - - maBitmap.ReleaseAccess( pBmpAcc ); - maMask.ReleaseAccess( pMskAcc ); - - if( bDataChanged ) - DataChanged(); -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::Completed( sal_uInt32 nStatus /*, ImageProducer& rProducer */ ) -{ - delete mpMapper; - mpMapper = NULL; - delete[] mpPal; - mpPal = NULL; - maSize = Size(); - mnStatus = nStatus; - - switch( nStatus ) - { - case( SINGLEFRAMEDONE ): - case( STATICIMAGEDONE ): - { - if( !mbTrans ) - maMask = Bitmap(); - } - break; - - case( IMAGEERROR ): - case( IMAGEABORTED ): - maBitmap = maMask = Bitmap(); - break; - - default: - break; - } - -// rProducer.RemoveConsumer( *this ); - - if( maDoneLink.IsSet() ) - maDoneLink.Call( this ); -} - -// ----------------------------------------------------------------------------- - -void ImageConsumer::DataChanged() -{ - if( maChgLink.IsSet() ) - maChgLink.Call( this ); -} - -// ----------------------------------------------------------------------------- - -sal_uInt32 ImageConsumer::GetStatus() const -{ - return mnStatus; -} - -// ----------------------------------------------------------------------------- - -BOOL ImageConsumer::GetData( BitmapEx& rBmpEx ) const -{ - const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus ); - - if( bRet ) - { - if( !!maMask ) - rBmpEx = BitmapEx( maBitmap, maMask ); - else - rBmpEx = BitmapEx( maBitmap ); - } - - return bRet; -} - -// ----------------------------------------------------------------------------- - -BOOL ImageConsumer::GetData( Image& rImage ) const -{ - const BOOL bRet = ( SINGLEFRAMEDONE == mnStatus || STATICIMAGEDONE == mnStatus ); - - if( bRet ) - { - if( !!maMask ) - rImage = Image( maBitmap, maMask ); - else - rImage = Image( maBitmap ); - } - - return bRet; -} diff --git a/vcl/source/gdi/impimage.cxx b/vcl/source/gdi/impimage.cxx index 476ac3ca44a9..3105850c4fbf 100644 --- a/vcl/source/gdi/impimage.cxx +++ b/vcl/source/gdi/impimage.cxx @@ -553,14 +553,14 @@ void ImplImageBmp::Draw( USHORT nPos, OutputDevice* pOutDev, // ----------------------------------------------------------------------- void ImplImageBmp::ImplUpdateDisplayBmp( OutputDevice* -#if defined WIN || defined WNT +#if defined WNT pOutDev #endif ) { if( !mpDisplayBmp && !maBmpEx.IsEmpty() ) { -#if defined WIN || defined WNT +#if defined WNT if( maBmpEx.IsAlpha() ) mpDisplayBmp = new BitmapEx( maBmpEx ); else 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 f069828f25f9..ac2e586a41cb 100644..100755 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -50,6 +50,7 @@ CDEFS+=-DENABLE_GRAPHITE EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/outdev.obj \ $(SLO)$/outdev3.obj \ + $(SLO)$/outdevnative.obj \ $(SLO)$/gfxlink.obj \ $(SLO)$/print.obj \ $(SLO)$/print2.obj \ @@ -62,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 \ @@ -84,7 +86,6 @@ SLOFILES= $(EXCEPTIONSFILES) \ $(SLO)$/bitmap4.obj \ $(SLO)$/alpha.obj \ $(SLO)$/bitmapex.obj \ - $(SLO)$/imgcons.obj \ $(SLO)$/bmpacc.obj \ $(SLO)$/bmpacc2.obj \ $(SLO)$/bmpacc3.obj \ @@ -106,7 +107,6 @@ SLOFILES= $(EXCEPTIONSFILES) \ $(SLO)$/outdev4.obj \ $(SLO)$/outdev5.obj \ $(SLO)$/outdev6.obj \ - $(SLO)$/outdevnative.obj \ $(SLO)$/regband.obj \ $(SLO)$/region.obj \ $(SLO)$/wall.obj \ diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index 752a4222bcb2..8c1545758c3b 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -3793,7 +3793,6 @@ MetaAction* MetaFloatTransparentAction::Clone() void MetaFloatTransparentAction::Move( long nHorzMove, long nVertMove ) { maPoint.Move( nHorzMove, nVertMove ); - maMtf.Move(nHorzMove, nVertMove); } // ------------------------------------------------------------------------ @@ -3804,7 +3803,6 @@ void MetaFloatTransparentAction::Scale( double fScaleX, double fScaleY ) ImplScaleRect( aRectangle, fScaleX, fScaleY ); maPoint = aRectangle.TopLeft(); maSize = aRectangle.GetSize(); - maMtf.Scale(fScaleX, fScaleY); } // ------------------------------------------------------------------------ @@ -4078,7 +4076,7 @@ void MetaCommentAction::Move( long nXMove, long nYMove ) aMemStm >> aFill; PolyPolygon aPath; aFill.getPath( aPath ); - aPath.Scale( nXMove, nYMove ); + aPath.Move( nXMove, nYMove ); aFill.setPath( aPath ); aDest << aFill; } diff --git a/vcl/source/gdi/metric.cxx b/vcl/source/gdi/metric.cxx index 325146b6be8a..6d225ad7e0dc 100644 --- a/vcl/source/gdi/metric.cxx +++ b/vcl/source/gdi/metric.cxx @@ -34,6 +34,8 @@ #include <vector> #include <set> +#include <cstdio> + // ======================================================================= ImplFontMetric::ImplFontMetric() @@ -51,6 +53,7 @@ ImplFontMetric::ImplFontMetric() inline void ImplFontMetric::AddReference() { + // TODO: disable refcounting on the default maps? ++mnRefCount; } @@ -58,6 +61,7 @@ inline void ImplFontMetric::AddReference() inline void ImplFontMetric::DeReference() { + // TODO: disable refcounting on the default maps? if( --mnRefCount <= 0 ) delete this; } @@ -252,7 +256,7 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR ) , mpGlyphIds( rCR.mpGlyphIds ) , mnRangeCount( rCR.mnRangeCount ) , mnCharCount( 0 ) -, mnRefCount( 1 ) +, mnRefCount( 0 ) { const sal_uInt32* pRangePtr = mpRangeCodes; for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 ) @@ -263,7 +267,8 @@ ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR ) } } -static ImplFontCharMap* pDefaultImplFontCharMap = NULL; +static ImplFontCharMap* pDefaultUnicodeImplFontCharMap = NULL; +static ImplFontCharMap* pDefaultSymbolImplFontCharMap = NULL; static const sal_uInt32 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0}; static const sal_uInt32 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100}; @@ -284,44 +289,60 @@ ImplFontCharMap::~ImplFontCharMap() delete[] mpRangeCodes; delete[] mpStartGlyphs; delete[] mpGlyphIds; -} + } // ----------------------------------------------------------------------- -ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols) +namespace { - if( pDefaultImplFontCharMap ) - pDefaultImplFontCharMap->AddReference(); - else + ImplFontCharMap *GetDefaultUnicodeMap() { - const sal_uInt32* pRangeCodes = aDefaultUnicodeRanges; - int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes); - if( bSymbols ) + if( !pDefaultUnicodeImplFontCharMap ) { - pRangeCodes = aDefaultSymbolRanges; - nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes); + const sal_uInt32* pRangeCodes = aDefaultUnicodeRanges; + int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes); + CmapResult aDefaultCR( false, pRangeCodes, nCodesCount/2 ); + pDefaultUnicodeImplFontCharMap = new ImplFontCharMap( aDefaultCR ); + pDefaultUnicodeImplFontCharMap->AddReference(); } - CmapResult aDefaultCR( bSymbols, pRangeCodes, nCodesCount/2 ); - pDefaultImplFontCharMap = new ImplFontCharMap( aDefaultCR ); + return pDefaultUnicodeImplFontCharMap; } - return pDefaultImplFontCharMap; + ImplFontCharMap *GetDefaultSymbolMap() + { + if( !pDefaultSymbolImplFontCharMap ) + { + const sal_uInt32* pRangeCodes = aDefaultSymbolRanges; + int nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes); + CmapResult aDefaultCR( true, pRangeCodes, nCodesCount/2 ); + pDefaultSymbolImplFontCharMap = new ImplFontCharMap( aDefaultCR ); + pDefaultSymbolImplFontCharMap->AddReference(); + } + + return pDefaultSymbolImplFontCharMap; + } +} + +ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols) +{ + return bSymbols ? GetDefaultSymbolMap() : GetDefaultUnicodeMap(); } // ----------------------------------------------------------------------- -void ImplFontCharMap::AddReference() +void ImplFontCharMap::AddReference( void ) const { + // TODO: disable refcounting on the default maps? ++mnRefCount; } // ----------------------------------------------------------------------- -void ImplFontCharMap::DeReference() +void ImplFontCharMap::DeReference( void ) const { if( --mnRefCount <= 0 ) - if( this != pDefaultImplFontCharMap ) + if( (this != pDefaultUnicodeImplFontCharMap) && (this != pDefaultSymbolImplFontCharMap) ) delete this; } @@ -815,7 +836,9 @@ bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult ) FontCharMap::FontCharMap() : mpImpl( ImplFontCharMap::GetDefaultMap() ) -{} +{ + mpImpl->AddReference(); +} // ----------------------------------------------------------------------- @@ -841,19 +864,14 @@ int FontCharMap::CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const // ----------------------------------------------------------------------- -void FontCharMap::Reset( ImplFontCharMap* pNewMap ) +void FontCharMap::Reset( const ImplFontCharMap* pNewMap ) { + mpImpl->DeReference(); if( pNewMap == NULL ) - { - mpImpl->DeReference(); mpImpl = ImplFontCharMap::GetDefaultMap(); - } else if( pNewMap != mpImpl ) - { - mpImpl->DeReference(); mpImpl = pNewMap; - mpImpl->AddReference(); - } + mpImpl->AddReference(); } // ----------------------------------------------------------------------- diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx index 3826a3dbc7b0..06dcd73cc3d4 100644..100755 --- a/vcl/source/gdi/outdev2.cxx +++ b/vcl/source/gdi/outdev2.cxx @@ -1614,6 +1614,18 @@ void OutputDevice::DrawPixel( const Polygon& rPts, const Color& rColor ) // ------------------------------------------------------------------------ +namespace +{ + BYTE lcl_calcColor( const BYTE nSourceColor, const BYTE nSourceOpaq, const BYTE nDestColor ) + { + int c = ( (int)nDestColor * ( 255 - nSourceOpaq ) ) + + (int)nSourceOpaq * (int)nSourceColor; + return BYTE( c / 255 ); + } +} + +// ------------------------------------------------------------------------ + Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, BitmapReadAccess* pP, BitmapReadAccess* pA, @@ -1626,7 +1638,6 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, const long* pMapY ) { BitmapColor aDstCol,aSrcCol; - BYTE nSrcAlpha, nDstAlpha; Bitmap res; int nX, nOutX, nY, nOutY; @@ -1660,36 +1671,23 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, aSrcCol = pP->GetColor( nMapY, nMapX ); aDstCol = pB->GetColor( nY, nX ); - nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); - nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); + const BYTE nSrcOpaq = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); + const BYTE nDstOpaq = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); - if( nSrcAlpha + nDstAlpha == 0 ) - { - // #i70653# zero alpha -> zero color values - aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ 0 ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ 0 ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ 0 ] + nD ) >> 16UL ] ) ); - } - else - { - aDstCol.SetRed( (BYTE)(((int)(aSrcCol.GetRed())*nSrcAlpha + (int)(aDstCol.GetRed())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetGreen( (BYTE)(((int)(aSrcCol.GetGreen())*nSrcAlpha + (int)(aDstCol.GetGreen())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetBlue( (BYTE)(((int)(aSrcCol.GetBlue())*nSrcAlpha + (int)(aDstCol.GetBlue())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - - aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + - nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + - nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); - } + aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) ); + aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) ); + aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) ); + + aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ aDstCol.GetRed() ] + nD ) >> 16UL ] + + nVCLGLut[ ( nVCLLut[ aDstCol.GetGreen() ] + nD ) >> 16UL ] + + nVCLBLut[ ( nVCLLut[ aDstCol.GetBlue() ] + nD ) >> 16UL ] ) ); pW->SetPixel( nY, nX, aIndex ); // Have to perform the compositing 'algebra' in // the inverse alpha space (with 255 meaning // opaque), otherwise, transitivity is not // achieved. - nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstAlpha, nSrcAlpha ); + const BYTE nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstOpaq, nSrcOpaq ); aIndex.SetIndex( (BYTE) ( nVCLRLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] + nVCLGLut[ ( nVCLLut[ nSrcAlpha ] + nD ) >> 16UL ] + @@ -1718,25 +1716,12 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, aSrcCol = pP->GetColor( nMapY, nMapX ); aDstCol = pB->GetColor( nY, nX ); - nSrcAlpha = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); - nDstAlpha = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); + const BYTE nSrcOpaq = 255 - pA->GetPixel( nMapY, nMapX ).GetBlueOrIndex(); + const BYTE nDstOpaq = 255 - pAlphaW->GetPixel( nY, nX ).GetBlueOrIndex(); - if( nSrcAlpha + nDstAlpha == 0 ) - { - // #i70653# zero alpha -> zero color values - aDstCol.SetRed(0); - aDstCol.SetGreen(0); - aDstCol.SetBlue(0); - } - else - { - aDstCol.SetRed( (BYTE)(((int)(aSrcCol.GetRed())*nSrcAlpha + (int)(aDstCol.GetRed())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetGreen( (BYTE)(((int)(aSrcCol.GetGreen())*nSrcAlpha + (int)(aDstCol.GetGreen())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - aDstCol.SetBlue( (BYTE)(((int)(aSrcCol.GetBlue())*nSrcAlpha + (int)(aDstCol.GetBlue())*nDstAlpha) / - (nSrcAlpha+nDstAlpha)) ); - } + aDstCol.SetRed( lcl_calcColor( aSrcCol.GetRed(), nSrcOpaq, aDstCol.GetRed() ) ); + aDstCol.SetBlue( lcl_calcColor( aSrcCol.GetBlue(), nSrcOpaq, aDstCol.GetBlue() ) ); + aDstCol.SetGreen( lcl_calcColor( aSrcCol.GetGreen(), nSrcOpaq, aDstCol.GetGreen() ) ); pB->SetPixel( nY, nX, aDstCol ); @@ -1744,7 +1729,7 @@ Bitmap OutputDevice::ImplBlendWithAlpha( Bitmap aBmp, // the inverse alpha space (with 255 meaning // opaque), otherwise, transitivity is not // achieved. - nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstAlpha, nSrcAlpha ); + const BYTE nSrcAlpha = 255-COLOR_CHANNEL_MERGE( 255, (BYTE)nDstOpaq, nSrcOpaq ); pAlphaW->SetPixel( nY, nX, Color(nSrcAlpha, nSrcAlpha, nSrcAlpha) ); } @@ -2003,7 +1988,15 @@ void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha, const long nSrcWidth = aBmpRect.GetWidth(), nSrcHeight = aBmpRect.GetHeight(); const long nDstWidth = aDstRect.GetWidth(), nDstHeight = aDstRect.GetHeight(); const long nOutWidth = aOutSz.Width(), nOutHeight = aOutSz.Height(); - const long nOffX = aDstRect.Left() - aOutPt.X(), nOffY = aDstRect.Top() - aOutPt.Y(); + // calculate offset in original bitmap + // in RTL case this is a little more complicated since the contents of the + // bitmap is not mirrored (it never is), however the paint region and bmp region + // are in mirrored coordinates, so the intersection of (aOutPt,aOutSz) with these + // is content wise somewhere else and needs to take mirroring into account + const long nOffX = IsRTLEnabled() + ? aOutSz.Width() - aDstRect.GetWidth() - (aDstRect.Left() - aOutPt.X()) + : aDstRect.Left() - aOutPt.X(), + nOffY = aDstRect.Top() - aOutPt.Y(); long nX, nOutX, nY, nOutY; long nMirrOffX = 0; long nMirrOffY = 0; @@ -2017,7 +2010,6 @@ void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha, for( nX = 0L, nOutX = nOffX; nX < nDstWidth; nX++, nOutX++ ) { pMapX[ nX ] = aBmpRect.Left() + nOutX * nSrcWidth / nOutWidth; - if( bHMirr ) pMapX[ nX ] = nMirrOffX - pMapX[ nX ]; } diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 949d3df5275f..f4ea98484c33 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -27,62 +27,57 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#include <cstring> -#include <i18npool/mslangid.hxx> -#ifndef _SV_SVSYS_HXX -#include <svsys.h> -#endif -#include <vcl/salgdi.hxx> -#include <vcl/sallayout.hxx> -#include <rtl/tencinfo.h> -#include <tools/debug.hxx> -#include <vcl/svdata.hxx> -#include <vcl/metric.hxx> -#include <vcl/impfont.hxx> -#include <vcl/metaact.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/outdata.hxx> -#include <vcl/outfont.hxx> -#include <basegfx/polygon/b2dpolygon.hxx> -#include <basegfx/polygon/b2dpolypolygon.hxx> -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <tools/poly.hxx> -#include <vcl/outdev.h> -#include <vcl/virdev.hxx> -#include <vcl/print.hxx> -#include <vcl/event.hxx> -#include <vcl/window.h> -#include <vcl/window.hxx> -#include <vcl/svapp.hxx> -#include <vcl/bmpacc.hxx> -#include <unotools/fontcvt.hxx> -#include <vcl/outdev.hxx> -#include <vcl/edit.hxx> -#include <unotools/fontcfg.hxx> -#include <vcl/sysdata.hxx> -#include <vcl/textlayout.hxx> -#ifndef _OSL_FILE_H -#include <osl/file.h> -#endif +#include "i18npool/mslangid.hxx" + +#include "svsys.h" +#include "vcl/salgdi.hxx" +#include "vcl/sallayout.hxx" +#include "rtl/tencinfo.h" +#include "tools/debug.hxx" +#include "vcl/svdata.hxx" +#include "vcl/metric.hxx" +#include "vcl/impfont.hxx" +#include "vcl/metaact.hxx" +#include "vcl/gdimtf.hxx" +#include "vcl/outdata.hxx" +#include "vcl/outfont.hxx" +#include "basegfx/polygon/b2dpolygon.hxx" +#include "basegfx/polygon/b2dpolypolygon.hxx" +#include "basegfx/matrix/b2dhommatrix.hxx" +#include "tools/poly.hxx" +#include "vcl/outdev.h" +#include "vcl/virdev.hxx" +#include "vcl/print.hxx" +#include "vcl/event.hxx" +#include "vcl/window.h" +#include "vcl/window.hxx" +#include "vcl/svapp.hxx" +#include "vcl/bmpacc.hxx" +#include "unotools/fontcvt.hxx" +#include "vcl/outdev.hxx" +#include "vcl/edit.hxx" +#include "unotools/fontcfg.hxx" +#include "vcl/sysdata.hxx" +#include "vcl/textlayout.hxx" +#include "vcl/svids.hrc" +#include "osl/file.h" #ifdef ENABLE_GRAPHITE -#include <vcl/graphite_features.hxx> +#include "vcl/graphite_features.hxx" #endif #ifdef USE_BUILTIN_RASTERIZER -#include <vcl/glyphcache.hxx> +#include "vcl/glyphcache.hxx" #endif -#include <vcl/unohelp.hxx> -#include <pdfwriter_impl.hxx> -#include <vcl/controllayout.hxx> -#include <rtl/logfile.hxx> +#include "vcl/unohelp.hxx" +#include "pdfwriter_impl.hxx" +#include "vcl/controllayout.hxx" +#include "rtl/logfile.hxx" -#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HDL_ -#include <com/sun/star/beans/PropertyValues.hdl> -#endif -#include <com/sun/star/i18n/XBreakIterator.hpp> -#include <com/sun/star/i18n/WordType.hpp> -#include <com/sun/star/linguistic2/XLinguServiceManager.hpp> +#include "com/sun/star/beans/PropertyValues.hpp" +#include "com/sun/star/i18n/XBreakIterator.hpp" +#include "com/sun/star/i18n/WordType.hpp" +#include "com/sun/star/linguistic2/XLinguServiceManager.hpp" #if defined UNX #define GLYPH_FONT_HEIGHT 128 @@ -92,7 +87,7 @@ #define GLYPH_FONT_HEIGHT 256 #endif -#include <sal/alloca.h> +#include "sal/alloca.h" #include <cmath> #include <cstring> @@ -1327,11 +1322,11 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const "msmincho", "fzmingti", "fzheiti", "ipamincho", "sazanamimincho", "kochimincho", "", "sunbatang", "sundotum", "baekmukdotum", "gulim", "batang", "dotum", "", "hgmincholightj", "msunglightsc", "msunglighttc", "hymyeongjolightk", "", - "tahoma", "dejavusans", "timesnewroman", "lucidatypewriter", "lucidasans", "nimbussansl", "", + "tahoma", "dejavusans", "timesnewroman", "liberationsans", "", "shree", "mangal", "", "raavi", "shruti", "tunga", "", "latha", "gautami", "kartika", "vrinda", "", - "shayyalmt", "naskmt", "", + "shayyalmt", "naskmt", "scheherazade", "", "david", "nachlieli", "lucidagrande", "", "norasi", "angsanaupc", "", "khmerossystem", "", @@ -1381,6 +1376,7 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const } } +#ifdef SAL_FONTENUM_STABLE_ON_PLATFORM // #i113472# // sort the list of fonts for glyph fallback by quality (highest first) // #i33947# keep the EUDC font at the front of the list // an insertion sort is good enough for this short list @@ -1396,6 +1392,7 @@ void ImplDevFontList::InitGenericGlyphFallback( void ) const break; pFallbackList[ j+1 ] = pTestFont; } +#endif #if defined(HDU_DEBUG) for( int i = 0; i < nMaxLevel; ++i ) @@ -1529,7 +1526,7 @@ void ImplDevFontList::Add( ImplFontData* pNewData ) // add font alias if available // a font alias should never win against an original font with similar quality - if( aMapNames.Len() >= nMapNameIndex ) + if( aMapNames.Len() <= nMapNameIndex ) break; if( bKeepNewData ) // try to recycle obsoleted object pNewData = pNewData->CreateAlias(); @@ -1645,10 +1642,25 @@ ImplDevFontListData* ImplDevFontList::ImplFindBySubstFontAttr( const utl::FontNa pFoundData = ImplFindBySearchName( aSearchName ); if( pFoundData ) - break; + return pFoundData; } - return pFoundData; + // use known attributes from the configuration to find a matching substitute + const ULONG nSearchType = rFontAttr.Type; + if( nSearchType != 0 ) + { + const FontWeight eSearchWeight = rFontAttr.Weight; + const FontWidth eSearchWidth = rFontAttr.Width; + const FontItalic eSearchSlant = ITALIC_DONTKNOW; + const FontFamily eSearchFamily = FAMILY_DONTKNOW; + const String aSearchName; + pFoundData = ImplFindByAttributes( nSearchType, + eSearchWeight, eSearchWidth, eSearchFamily, eSearchSlant, aSearchName ); + if( pFoundData ) + return pFoundData; + } + + return NULL; } // ----------------------------------------------------------------------- @@ -1889,10 +1901,11 @@ ImplDevFontListData* ImplDevFontList::ImplFindByAttributes( ULONG nSearchType, nTestMatch -= 1000000; // test font name substrings - if( (rSearchFamilyName.Len() && pData->maMatchFamilyName.Len()) + // TODO: calculate name matching score using e.g. Levenstein distance + if( (rSearchFamilyName.Len() >= 4) && (pData->maMatchFamilyName.Len() >= 4) && ((rSearchFamilyName.Search( pData->maMatchFamilyName ) != STRING_NOTFOUND) || (pData->maMatchFamilyName.Search( rSearchFamilyName ) != STRING_NOTFOUND)) ) - nTestMatch += 100000*2; + nTestMatch += 5000; // test SERIF attribute if( nSearchType & IMPL_FONT_ATTR_SERIF ) @@ -2909,6 +2922,18 @@ void OutputDevice::ImplInitFontList() const mpGraphics->GetDevFontList( mpFontList ); } } + if( meOutDevType == OUTDEV_WINDOW && ! mpFontList->Count() ) + { + String aError( RTL_CONSTASCII_USTRINGPARAM( "Application error: no fonts and no vcl resource found on your system" ) ); + ResMgr* pMgr = ImplGetResMgr(); + if( pMgr ) + { + String aResStr( ResId( SV_ACCESSERROR_NO_FONTS, *pMgr ) ); + if( aResStr.Len() ) + aError = aResStr; + } + Application::Abort( aError ); + } } // ======================================================================= @@ -3130,17 +3155,17 @@ long OutputDevice::ImplGetTextWidth( const SalLayout& rSalLayout ) const // ----------------------------------------------------------------------- void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, long nHeight ) + long nDistX, long nDistY, long nWidth, long nHeight ) { + long nX = nDistX; + long nY = nDistY; + short nOrientation = mpFontEntry->mnOrientation; if ( nOrientation ) { // Rotate rect without rounding problems for 90 degree rotations if ( !(nOrientation % 900) ) { - nX -= nBaseX; - nY -= nBaseY; - if ( nOrientation == 900 ) { long nTemp = nX; @@ -3168,12 +3193,11 @@ void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY, nHeight = nTemp; nX -= nWidth; } - - nX += nBaseX; - nY += nBaseY; } else { + nX += nBaseX; + nY += nBaseY; // inflate because polygons are drawn smaller Rectangle aRect( Point( nX, nY ), Size( nWidth+1, nHeight+1 ) ); Polygon aPoly( aRect ); @@ -3183,6 +3207,8 @@ void OutputDevice::ImplDrawTextRect( long nBaseX, long nBaseY, } } + nX += nBaseX; + nY += nBaseY; mpGraphics->DrawRect( nX, nY, nWidth, nHeight, this ); } @@ -3203,7 +3229,7 @@ void OutputDevice::ImplDrawTextBackground( const SalLayout& rSalLayout ) mpGraphics->SetFillColor( ImplColorToSal( GetTextFillColor() ) ); mbInitFillColor = TRUE; - ImplDrawTextRect( nX, nY, nX, nY-mpFontEntry->maMetric.mnAscent-mnEmphasisAscent, + ImplDrawTextRect( nX, nY, 0, -(mpFontEntry->maMetric.mnAscent + mnEmphasisAscent), nWidth, mpFontEntry->mnLineHeight+mnEmphasisAscent+mnEmphasisDescent ); } @@ -3488,7 +3514,7 @@ static void ImplDrawWavePixel( long nOriginX, long nOriginY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, - long nStartX, long nStartY, + long nDistX, long nDistY, long nWidth, long nHeight, long nLineWidth, short nOrientation, const Color& rColor ) @@ -3496,6 +3522,9 @@ void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, if ( !nHeight ) return; + long nStartX = nBaseX + nDistX; + long nStartY = nBaseY + nDistY; + // Bei Hoehe von 1 Pixel reicht es, eine Linie auszugeben if ( (nLineWidth == 1) && (nHeight == 1) ) { @@ -3510,7 +3539,6 @@ void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, ImplRotatePos( nBaseX, nBaseY, nEndX, nEndY, nOrientation ); } mpGraphics->DrawLine( nStartX, nStartY, nEndX, nEndY, this ); - } else { @@ -3610,7 +3638,7 @@ void OutputDevice::ImplDrawWaveLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontUnderline eTextLine, Color aColor, BOOL bIsAbove ) @@ -3636,7 +3664,7 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, nLineWidth = 1; if ( eTextLine == UNDERLINE_BOLDWAVE ) nLineWidth *= 2; - nLinePos += nY - (nLineHeight / 2); + nLinePos += nDistY - (nLineHeight / 2); long nLineWidthHeight = ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY; if ( eTextLine == UNDERLINE_DOUBLEWAVE ) { @@ -3657,16 +3685,16 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, nLineDY2 = 1; nLinePos -= nLineWidthHeight-nLineDY2; - ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight, + ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight, nLineWidth, mpFontEntry->mnOrientation, aColor ); nLinePos += nLineWidthHeight+nLineDY; - ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight, + ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight, nLineWidth, mpFontEntry->mnOrientation, aColor ); } else { nLinePos -= nLineWidthHeight/2; - ImplDrawWaveLine( nBaseX, nBaseY, nX, nLinePos, nWidth, nLineHeight, + ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight, nLineWidth, mpFontEntry->mnOrientation, aColor ); } } @@ -3674,7 +3702,7 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontUnderline eTextLine, Color aColor, BOOL bIsAbove ) @@ -3684,6 +3712,8 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, long nLinePos = 0; long nLinePos2 = 0; + const long nY = nDistY; + if ( eTextLine > UNDERLINE_LAST ) eTextLine = UNDERLINE_SINGLE; @@ -3751,7 +3781,7 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, mpGraphics->SetFillColor( ImplColorToSal( aColor ) ); mbInitFillColor = TRUE; - long nLeft = nX; + long nLeft = nDistX; switch ( eTextLine ) { @@ -3904,7 +3934,7 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontStrikeout eStrikeout, Color aColor ) { @@ -3913,6 +3943,8 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, long nLinePos = 0; long nLinePos2 = 0; + long nY = nDistY; + if ( eStrikeout > STRIKEOUT_LAST ) eStrikeout = STRIKEOUT_SINGLE; @@ -3945,7 +3977,7 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, mpGraphics->SetFillColor( ImplColorToSal( aColor ) ); mbInitFillColor = TRUE; - long nLeft = nX; + const long& nLeft = nDistX; switch ( eStrikeout ) { @@ -3966,7 +3998,7 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, - long nX, long nY, long nWidth, + long nDistX, long nDistY, long nWidth, FontStrikeout eStrikeout, Color aColor ) { @@ -4000,12 +4032,12 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, // calculate acceptable strikeout length // allow the strikeout to be one pixel larger than the text it strikes out - long nMaxWidth = nStrikeoutWidth / 2; + long nMaxWidth = nStrikeoutWidth * 3 / 4; if ( nMaxWidth < 2 ) nMaxWidth = 2; nMaxWidth += nWidth + 1; - int nStrikeStrLen = (nMaxWidth + nStrikeoutWidth - 1) / nStrikeoutWidth; + int nStrikeStrLen = (nMaxWidth - 1) / nStrikeoutWidth; // if the text width is smaller than the strikeout text, then do not // strike out at all. This case requires user interaction, e.g. adding // a space to the text @@ -4020,7 +4052,9 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, const String aStrikeoutText( aChars, xub_StrLen(nStrikeStrLen) ); if( mpFontEntry->mnOrientation ) - ImplRotatePos( nBaseX, nBaseY, nX, nY, mpFontEntry->mnOrientation ); + ImplRotatePos( 0, 0, nDistX, nDistY, mpFontEntry->mnOrientation ); + nBaseX += nDistX; + nBaseY += nDistY; // strikeout text has to be left aligned ULONG nOrigTLM = mnTextLayoutMode; @@ -4036,7 +4070,7 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, SetTextColor( aColor ); ImplInitTextColor(); - pLayout->DrawBase() = Point( nX+mnTextOffX, nY+mnTextOffY ); + pLayout->DrawBase() = Point( nBaseX+mnTextOffX, nBaseY+mnTextOffY ); pLayout->DrawText( *mpGraphics ); pLayout->Release(); @@ -4046,8 +4080,8 @@ void OutputDevice::ImplDrawStrikeoutChar( long nBaseX, long nBaseY, // ----------------------------------------------------------------------- -void OutputDevice::ImplDrawTextLine( long nBaseX, - long nX, long nY, long nWidth, +void OutputDevice::ImplDrawTextLine( long nX, long nY, + long nDistX, long nWidth, FontStrikeout eStrikeout, FontUnderline eUnderline, FontUnderline eOverline, @@ -4063,10 +4097,14 @@ void OutputDevice::ImplDrawTextLine( long nBaseX, BOOL bUnderlineDone = FALSE; BOOL bOverlineDone = FALSE; - // TODO: fix rotated text if ( IsRTLEnabled() ) + { // --- RTL --- mirror at basex - nX = nBaseX - nWidth - (nX - nBaseX - 1); + long nXAdd = nWidth - nDistX; + if( mpFontEntry->mnOrientation ) + nXAdd = FRound( nXAdd * cos( mpFontEntry->mnOrientation * F_PI1800 ) ); + nX += nXAdd - 1; + } if ( !IsTextLineColor() ) aUnderlineColor = GetTextColor(); @@ -4079,7 +4117,7 @@ void OutputDevice::ImplDrawTextLine( long nBaseX, (eUnderline == UNDERLINE_DOUBLEWAVE) || (eUnderline == UNDERLINE_BOLDWAVE) ) { - ImplDrawWaveTextLine( nBaseX, nY, nX, nY, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); + ImplDrawWaveTextLine( nX, nY, nDistX, 0, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); bUnderlineDone = TRUE; } if ( (eOverline == UNDERLINE_SMALLWAVE) || @@ -4087,25 +4125,25 @@ void OutputDevice::ImplDrawTextLine( long nBaseX, (eOverline == UNDERLINE_DOUBLEWAVE) || (eOverline == UNDERLINE_BOLDWAVE) ) { - ImplDrawWaveTextLine( nBaseX, nY, nX, nY, nWidth, eOverline, aOverlineColor, TRUE ); + ImplDrawWaveTextLine( nX, nY, nDistX, 0, nWidth, eOverline, aOverlineColor, TRUE ); bOverlineDone = TRUE; } if ( (eStrikeout == STRIKEOUT_SLASH) || (eStrikeout == STRIKEOUT_X) ) { - ImplDrawStrikeoutChar( nBaseX, nY, nX, nY, nWidth, eStrikeout, aStrikeoutColor ); + ImplDrawStrikeoutChar( nX, nY, nDistX, 0, nWidth, eStrikeout, aStrikeoutColor ); bStrikeoutDone = TRUE; } if ( !bUnderlineDone ) - ImplDrawStraightTextLine( nBaseX, nY, nX, nY, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); + ImplDrawStraightTextLine( nX, nY, nDistX, 0, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove ); if ( !bOverlineDone ) - ImplDrawStraightTextLine( nBaseX, nY, nX, nY, nWidth, eOverline, aOverlineColor, TRUE ); + ImplDrawStraightTextLine( nX, nY, nDistX, 0, nWidth, eOverline, aOverlineColor, TRUE ); if ( !bStrikeoutDone ) - ImplDrawStrikeoutLine( nBaseX, nY, nX, nY, nWidth, eStrikeout, aStrikeoutColor ); + ImplDrawStrikeoutLine( nX, nY, nDistX, 0, nWidth, eStrikeout, aStrikeoutColor ); } // ----------------------------------------------------------------------- @@ -4115,34 +4153,49 @@ void OutputDevice::ImplDrawTextLines( SalLayout& rSalLayout, { if( bWordLine ) { - Point aPos, aStartPt; - sal_Int32 nWidth = 0, nAdvance=0; + // draw everything relative to the layout base point + const Point aStartPt = rSalLayout.DrawBase(); + // calculate distance of each word from the base point + Point aPos; + sal_Int32 nDist = 0, nWidth = 0, nAdvance=0; for( int nStart = 0;;) { + // iterate through the layouted glyphs sal_GlyphId nGlyphIndex; if( !rSalLayout.GetNextGlyphs( 1, &nGlyphIndex, aPos, nStart, &nAdvance ) ) break; + // calculate the boundaries of each word if( !rSalLayout.IsSpacingGlyph( nGlyphIndex ) ) { if( !nWidth ) { - aStartPt = aPos;//rSalLayout.DrawBase() - (aPos - rSalLayout.DrawOffset()); + // get the distance to the base point (as projected to baseline) + nDist = aPos.X() - aStartPt.X(); + if( mpFontEntry->mnOrientation ) + { + const long nDY = aPos.Y() - aStartPt.Y(); + const double fRad = mpFontEntry->mnOrientation * F_PI1800; + nDist = FRound( nDist*cos(fRad) - nDY*sin(fRad) ); + } } + // update the length of the textline nWidth += nAdvance; } else if( nWidth > 0 ) { - ImplDrawTextLine( rSalLayout.DrawBase().X(), aStartPt.X(), aStartPt.Y(), nWidth, + // draw the textline for each word + ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); nWidth = 0; } } + // draw textline for the last word if( nWidth > 0 ) { - ImplDrawTextLine( rSalLayout.DrawBase().X(), aStartPt.X(), aStartPt.Y(), nWidth, + ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); } } @@ -4150,7 +4203,7 @@ void OutputDevice::ImplDrawTextLines( SalLayout& rSalLayout, { Point aStartPt = rSalLayout.GetDrawPosition(); int nWidth = rSalLayout.GetTextWidth() / rSalLayout.GetUnitsPerPixel(); - ImplDrawTextLine( rSalLayout.DrawBase().X(), aStartPt.X(), aStartPt.Y(), nWidth, + ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), 0, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); } } @@ -4169,7 +4222,7 @@ void OutputDevice::ImplDrawMnemonicLine( long nX, long nY, long nWidth ) nX = nBaseX - nWidth - (nX - nBaseX - 1); } - ImplDrawTextLine( nBaseX, nX, nY, nWidth, STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, FALSE ); + ImplDrawTextLine( nX, nY, 0, nWidth, STRIKEOUT_NONE, UNDERLINE_SINGLE, UNDERLINE_NONE, FALSE ); } // ----------------------------------------------------------------------- @@ -5417,7 +5470,7 @@ void OutputDevice::DrawTextLine( const Point& rPos, long nWidth, Point aPos = ImplLogicToDevicePixel( rPos ); nWidth = ImplLogicWidthToDevicePixel( nWidth ); aPos += Point( mnTextOffX, mnTextOffY ); - ImplDrawTextLine( aPos.X(), aPos.X(), aPos.Y(), nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); + ImplDrawTextLine( aPos.X(), aPos.X(), 0, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); if( mpAlphaVDev ) mpAlphaVDev->DrawTextLine( rPos, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove ); @@ -5494,7 +5547,7 @@ void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos, if( nWaveHeight > pFontEntry->maMetric.mnWUnderlineSize ) nWaveHeight = pFontEntry->maMetric.mnWUnderlineSize; - ImplDrawWaveLine( nStartX, nStartY, nStartX, nStartY, + ImplDrawWaveLine( nStartX, nStartY, 0, 0, nEndX-nStartX, nWaveHeight, 1, nOrientation, GetLineColor() ); if( mpAlphaVDev ) @@ -6057,6 +6110,11 @@ SalLayout* OutputDevice::ImplGlyphFallbackLayout( SalLayout* pSalLayout, ImplLay rtl::OUString aMissingCodes = aMissingCodeBuf.makeStringAndClear(); ImplFontSelectData aFontSelData = mpFontEntry->maFontSelData; + + ImplFontMetricData aOrigMetric( aFontSelData ); + // TODO: use cached metric in fontentry + mpGraphics->GetFontMetric( &aOrigMetric ); + // when device specific font substitution may have been performed for // the originally selected font then make sure that a fallback to that // font is performed first @@ -6101,7 +6159,27 @@ SalLayout* OutputDevice::ImplGlyphFallbackLayout( SalLayout* pSalLayout, ImplLay } #endif + // TODO: try to get the metric data from the GFB's mpFontEntry + ImplFontMetricData aSubstituteMetric( aFontSelData ); pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); + mpGraphics->GetFontMetric( &aSubstituteMetric, nFallbackLevel ); + + const long nOriginalHeight = aOrigMetric.mnAscent + aOrigMetric.mnDescent; + const long nSubstituteHeight = aSubstituteMetric.mnAscent + aSubstituteMetric.mnDescent; + // Too tall, shrink it a bit. Need a better calculation to include extra + // factors and any extra wriggle room we might have available? + // TODO: should we scale by max-ascent/max-descent instead of design height? + if( nSubstituteHeight > nOriginalHeight ) + { + const float fScale = nOriginalHeight / (float)nSubstituteHeight; + const float fOrigHeight = aFontSelData.mfExactHeight; + const int nOrigHeight = aFontSelData.mnHeight; + aFontSelData.mfExactHeight *= fScale; + aFontSelData.mnHeight = static_cast<int>(aFontSelData.mfExactHeight); + pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); + aFontSelData.mnHeight = nOrigHeight; + aFontSelData.mfExactHeight = fOrigHeight; + } // create and add glyph fallback layout to multilayout rLayoutArgs.ResetPos(); @@ -6763,7 +6841,20 @@ String OutputDevice::ImplGetEllipsisString( const OutputDevice& rTargetDevice, c if ( nIndex != STRING_LEN ) { - if ( nStyle & TEXT_DRAW_ENDELLIPSIS ) + if( (nStyle & TEXT_DRAW_CENTERELLIPSIS) == TEXT_DRAW_CENTERELLIPSIS ) + { + String aTmpStr( aStr ); + xub_StrLen nEraseChars = 4; + while( nEraseChars < aStr.Len() && _rLayout.GetTextWidth( aTmpStr, 0, aTmpStr.Len() ) > nMaxWidth ) + { + aTmpStr = aStr; + xub_StrLen i = (aTmpStr.Len() - nEraseChars)/2; + aTmpStr.Erase( i, nEraseChars++ ); + aTmpStr.InsertAscii( "...", i ); + } + aStr = aTmpStr; + } + else if ( nStyle & TEXT_DRAW_ENDELLIPSIS ) { aStr.Erase( nIndex ); if ( nIndex > 1 ) @@ -7946,7 +8037,7 @@ BOOL OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const if( !mpFontEntry ) return FALSE; - // a little font charmap cache helps considerably +#ifdef ENABLE_IFC_CACHE // a little font charmap cache helps considerably static const int NMAXITEMS = 16; static int nUsedItems = 0, nCurItem = 0; @@ -7964,10 +8055,12 @@ BOOL OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const rFontCharMap.Reset( aCache[i].maCharMap.mpImpl ); } else // need to cache +#endif // ENABLE_IFC_CACHE { - ImplFontCharMap* pNewMap = mpGraphics->GetImplFontCharMap(); + const ImplFontCharMap* pNewMap = mpGraphics->GetImplFontCharMap(); rFontCharMap.Reset( pNewMap ); +#ifdef ENABLE_IFC_CACHE // manage cache round-robin and insert data CharMapCacheItem& rItem = aCache[ nCurItem ]; rItem.mpFontData = pFontData; @@ -7978,6 +8071,7 @@ BOOL OutputDevice::GetFontCharMap( FontCharMap& rFontCharMap ) const if( ++nUsedItems >= NMAXITEMS ) nUsedItems = NMAXITEMS; +#endif // ENABLE_IFC_CACHE } if( rFontCharMap.IsDefaultMap() ) diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx index 47b150ddc4c5..5b8d228bb141 100644 --- a/vcl/source/gdi/outdev6.cxx +++ b/vcl/source/gdi/outdev6.cxx @@ -345,6 +345,12 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly, if( OUTDEV_PRINTER == meOutDevType ) { + if(100 <= nTransparencePercent) + { + // #i112959# 100% transparent, draw nothing + return; + } + Rectangle aPolyRect( LogicToPixel( rPolyPoly ).GetBoundRect() ); const Size aDPISize( LogicToPixel( Size( 1, 1 ), MAP_INCH ) ); const long nBaseExtent = Max( FRound( aDPISize.Width() / 300. ), 1L ); @@ -359,30 +365,40 @@ void OutputDevice::DrawTransparent( const PolyPolygon& rPolyPoly, case( 25 ): nMove = nBaseExtent * 3; break; case( 50 ): nMove = nBaseExtent * 4; break; case( 75 ): nMove = nBaseExtent * 6; break; - // TODO What is the correct VALUE??? + + // #i112959# very transparent (88 < nTransparencePercent <= 99) + case( 100 ): nMove = nBaseExtent * 8; break; + + // #i112959# not transparent (nTransparencePercent < 13) default: nMove = 0; break; } Push( PUSH_CLIPREGION | PUSH_LINECOLOR ); IntersectClipRegion( rPolyPoly ); SetLineColor( GetFillColor() ); - - Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) ); - const BOOL bOldMap = mbMap; EnableMapMode( FALSE ); - while( aRect.Top() <= aPolyRect.Bottom() ) + if(nMove) { - DrawRect( aRect ); - aRect.Move( 0, nMove ); - } + Rectangle aRect( aPolyRect.TopLeft(), Size( aPolyRect.GetWidth(), nBaseExtent ) ); + while( aRect.Top() <= aPolyRect.Bottom() ) + { + DrawRect( aRect ); + aRect.Move( 0, nMove ); + } - aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) ); - while( aRect.Left() <= aPolyRect.Right() ) + aRect = Rectangle( aPolyRect.TopLeft(), Size( nBaseExtent, aPolyRect.GetHeight() ) ); + while( aRect.Left() <= aPolyRect.Right() ) + { + DrawRect( aRect ); + aRect.Move( nMove, 0 ); + } + } + else { - DrawRect( aRect ); - aRect.Move( nMove, 0 ); + // #i112959# if not transparent, draw full rectangle in clip region + DrawRect( aPolyRect ); } EnableMapMode( bOldMap ); @@ -1135,7 +1151,7 @@ void OutputDevice::Erase() { ImplControlValue aControlValue; Point aGcc3WorkaroundTemporary; - Region aCtrlRegion( Rectangle( aGcc3WorkaroundTemporary, GetOutputSizePixel() ) ); + Rectangle aCtrlRegion( aGcc3WorkaroundTemporary, GetOutputSizePixel() ); ControlState nState = 0; if( pWindow->IsEnabled() ) nState |= CTRL_STATE_ENABLED; diff --git a/vcl/source/gdi/outdevnative.cxx b/vcl/source/gdi/outdevnative.cxx index fed41ec4de85..521f4d7ea62d 100644 --- a/vcl/source/gdi/outdevnative.cxx +++ b/vcl/source/gdi/outdevnative.cxx @@ -59,6 +59,38 @@ static bool lcl_enableNativeWidget( const OutputDevice& i_rDevice ) } } +ImplControlValue::~ImplControlValue() +{ +} + +ScrollbarValue::~ScrollbarValue() +{ +} + +SliderValue::~SliderValue() +{ +} + +TabitemValue::~TabitemValue() +{ +} + +SpinbuttonValue::~SpinbuttonValue() +{ +} + +ToolbarValue::~ToolbarValue() +{ +} + +MenubarValue::~MenubarValue() +{ +} + +PushButtonValue::~PushButtonValue() +{ +} + // ----------------------------------------------------------------------- // These functions are mainly passthrough functions that allow access to // the SalFrame behind a Window object for native widget rendering purposes. @@ -83,7 +115,7 @@ BOOL OutputDevice::IsNativeControlSupported( ControlType nType, ControlPart nPar BOOL OutputDevice::HitTestNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside ) { @@ -95,7 +127,7 @@ BOOL OutputDevice::HitTestNativeControl( ControlType nType, return FALSE; Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); + Rectangle screenRegion( rControlRegion ); screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); return( mpGraphics->HitTestNativeControl(nType, nPart, screenRegion, Point( aPos.X() + mnOutOffX, aPos.Y() + mnOutOffY ), @@ -104,47 +136,117 @@ BOOL OutputDevice::HitTestNativeControl( ControlType nType, // ----------------------------------------------------------------------- -static void lcl_moveControlValue( ControlType nType, const ImplControlValue& aValue, const Point& rDelta ) +static boost::shared_ptr< ImplControlValue > lcl_transformControlValue( const ImplControlValue& rVal, OutputDevice& rDev ) { - if( aValue.getOptionalVal() ) + boost::shared_ptr< ImplControlValue > aResult; + switch( rVal.getType() ) { - switch( nType ) + case CTRL_SLIDER: { - case CTRL_SLIDER: - { - SliderValue* pSlVal = reinterpret_cast<SliderValue*>(aValue.getOptionalVal()); - pSlVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); - } - break; - case CTRL_SCROLLBAR: - { - ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(aValue.getOptionalVal()); - pScVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); - pScVal->maButton1Rect.Move( rDelta.X(), rDelta.Y() ); - pScVal->maButton2Rect.Move( rDelta.X(), rDelta.Y() ); - } - break; - case CTRL_SPINBOX: - case CTRL_SPINBUTTONS: - { - SpinbuttonValue* pSpVal = reinterpret_cast<SpinbuttonValue*>(aValue.getOptionalVal()); - pSpVal->maUpperRect.Move( rDelta.X(), rDelta.Y() ); - pSpVal->maLowerRect.Move( rDelta.X(), rDelta.Y() ); - } - break; - case CTRL_TOOLBAR: - { - ToolbarValue* pTVal = reinterpret_cast<ToolbarValue*>(aValue.getOptionalVal()); - pTVal->maGripRect.Move( rDelta.X(), rDelta.Y() ); - } + const SliderValue* pSlVal = static_cast<const SliderValue*>(&rVal); + SliderValue* pNew = new SliderValue( *pSlVal ); + aResult.reset( pNew ); + pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pSlVal->maThumbRect ); + } + break; + case CTRL_SCROLLBAR: + { + const ScrollbarValue* pScVal = static_cast<const ScrollbarValue*>(&rVal); + ScrollbarValue* pNew = new ScrollbarValue( *pScVal ); + aResult.reset( pNew ); + pNew->maThumbRect = rDev.ImplLogicToDevicePixel( pScVal->maThumbRect ); + pNew->maButton1Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton1Rect ); + pNew->maButton2Rect = rDev.ImplLogicToDevicePixel( pScVal->maButton2Rect ); + } + break; + case CTRL_SPINBUTTONS: + { + const SpinbuttonValue* pSpVal = static_cast<const SpinbuttonValue*>(&rVal); + SpinbuttonValue* pNew = new SpinbuttonValue( *pSpVal ); + aResult.reset( pNew ); + pNew->maUpperRect = rDev.ImplLogicToDevicePixel( pSpVal->maUpperRect ); + pNew->maLowerRect = rDev.ImplLogicToDevicePixel( pSpVal->maLowerRect ); + } + break; + case CTRL_TOOLBAR: + { + const ToolbarValue* pTVal = static_cast<const ToolbarValue*>(&rVal); + ToolbarValue* pNew = new ToolbarValue( *pTVal ); + aResult.reset( pNew ); + pNew->maGripRect = rDev.ImplLogicToDevicePixel( pTVal->maGripRect ); + } + break; + case CTRL_TAB_ITEM: + { + const TabitemValue* pTIVal = static_cast<const TabitemValue*>(&rVal); + TabitemValue* pNew = new TabitemValue( *pTIVal ); + aResult.reset( pNew ); + } + break; + case CTRL_MENUBAR: + { + const MenubarValue* pMVal = static_cast<const MenubarValue*>(&rVal); + MenubarValue* pNew = new MenubarValue( *pMVal ); + aResult.reset( pNew ); + } + break; + case CTRL_PUSHBUTTON: + { + const PushButtonValue* pBVal = static_cast<const PushButtonValue*>(&rVal); + PushButtonValue* pNew = new PushButtonValue( *pBVal ); + aResult.reset( pNew ); + } + break; + case CTRL_GENERIC: + aResult.reset( new ImplControlValue( rVal ) ); break; + default: + OSL_ENSURE( 0, "unknown ImplControlValue type !" ); + break; + } + return aResult; +} + +#if 0 +static void lcl_moveControlValue( ControlType nType, const ImplControlValue& aValue, const Point& rDelta ) +{ + switch( aValue.getType() ) + { + case CTRL_SLIDER: + { + SliderValue* pSlVal = static_cast<SliderValue*>(const_cast<ImplControlValue*>(&aValue)); + pSlVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); + } + break; + case CTRL_SCROLLBAR: + { + ScrollbarValue* pScVal = static_cast<ScrollbarValue*>(const_cast<ImplControlValue*>(&aValue)); + pScVal->maThumbRect.Move( rDelta.X(), rDelta.Y() ); + pScVal->maButton1Rect.Move( rDelta.X(), rDelta.Y() ); + pScVal->maButton2Rect.Move( rDelta.X(), rDelta.Y() ); + } + break; + case CTRL_SPINBOX: + case CTRL_SPINBUTTONS: + { + SpinbuttonValue* pSpVal = static_cast<SpinbuttonValue*>(const_cast<ImplControlValue*>(&aValue)); + pSpVal->maUpperRect.Move( rDelta.X(), rDelta.Y() ); + pSpVal->maLowerRect.Move( rDelta.X(), rDelta.Y() ); + } + break; + case CTRL_TOOLBAR: + { + ToolbarValue* pTVal = static_cast<ToolbarValue*>(const_cast<ImplControlValue*>(&aValue)); + pTVal->maGripRect.Move( rDelta.X(), rDelta.Y() ); } + break; } } +#endif BOOL OutputDevice::DrawNativeControl( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption ) @@ -183,22 +285,15 @@ BOOL OutputDevice::DrawNativeControl( ControlType nType, // Convert the coordinates from relative to Window-absolute, so we draw // in the correct place in platform code - Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); - screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); - - // do so for ImplControlValue members, also - lcl_moveControlValue( nType, aValue, aWinOffs ); + boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) ); + Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); Region aTestRegion( GetActiveClipRegion() ); aTestRegion.Intersect( rControlRegion ); if( aTestRegion == rControlRegion ) nState |= CTRL_CACHING_ALLOWED; // control is not clipped, caching allowed - BOOL bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, aValue, aCaption, this ); - - // transform back ImplControlValue members - lcl_moveControlValue( nType, aValue, Point()-aWinOffs ); + BOOL bRet = mpGraphics->DrawNativeControl(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this ); return bRet; } @@ -208,7 +303,7 @@ BOOL OutputDevice::DrawNativeControl( ControlType nType, BOOL OutputDevice::DrawNativeControlText(ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption ) @@ -233,15 +328,10 @@ BOOL OutputDevice::DrawNativeControlText(ControlType nType, // Convert the coordinates from relative to Window-absolute, so we draw // in the correct place in platform code - Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); - screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); - lcl_moveControlValue( nType, aValue, aWinOffs ); - - BOOL bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, aValue, aCaption, this ); + boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) ); + Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); - // transform back ImplControlValue members - lcl_moveControlValue( nType, aValue, Point()-aWinOffs ); + BOOL bRet = mpGraphics->DrawNativeControlText(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, this ); return bRet; } @@ -251,12 +341,12 @@ BOOL OutputDevice::DrawNativeControlText(ControlType nType, BOOL OutputDevice::GetNativeControlRegion( ControlType nType, ControlPart nPart, - const Region& rControlRegion, + const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, ::rtl::OUString aCaption, - Region &rNativeBoundingRegion, - Region &rNativeContentRegion ) + Rectangle &rNativeBoundingRegion, + Rectangle &rNativeContentRegion ) { if( !lcl_enableNativeWidget( *this ) ) return FALSE; @@ -267,22 +357,18 @@ BOOL OutputDevice::GetNativeControlRegion( ControlType nType, // Convert the coordinates from relative to Window-absolute, so we draw // in the correct place in platform code - Point aWinOffs( mnOutOffX, mnOutOffY ); - Region screenRegion( rControlRegion ); - screenRegion.Move( aWinOffs.X(), aWinOffs.Y()); - lcl_moveControlValue( nType, aValue, aWinOffs ); + boost::shared_ptr< ImplControlValue > aScreenCtrlValue( lcl_transformControlValue( aValue, *this ) ); + Rectangle screenRegion( ImplLogicToDevicePixel( rControlRegion ) ); - BOOL bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, aValue, + BOOL bRet = mpGraphics->GetNativeControlRegion(nType, nPart, screenRegion, nState, *aScreenCtrlValue, aCaption, rNativeBoundingRegion, rNativeContentRegion, this ); if( bRet ) { // transform back native regions - rNativeBoundingRegion.Move( -aWinOffs.X(), -aWinOffs.Y() ); - rNativeContentRegion.Move( -aWinOffs.X(), -aWinOffs.Y() ); + rNativeBoundingRegion = ImplDevicePixelToLogic( rNativeBoundingRegion ); + rNativeContentRegion = ImplDevicePixelToLogic( rNativeContentRegion ); } - // transform back ImplControlValue members - lcl_moveControlValue( nType, aValue, Point()-aWinOffs ); return bRet; } 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 6cb0a7d07697..5d75c829da8a 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -32,6 +32,7 @@ #include <math.h> #include <algorithm> +#include <tools/urlobj.hxx> #include <pdfwriter_impl.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> @@ -66,6 +67,7 @@ #include "cppuhelper/implbase1.hxx" #include <icc/sRGB-IEC61966-2.1.hxx> #include <vcl/lineinfo.hxx> +#include "vcl/strhelper.hxx" using namespace vcl; using namespace rtl; @@ -1691,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) ) ), @@ -1717,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; @@ -2136,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 ); @@ -8498,6 +8504,7 @@ void PDFWriterImpl::beginRedirect( SvStream* pStream, const Rectangle& rTargetRe { push( PUSH_ALL ); + // force reemitting clip region clearClipRegion(); updateGraphicsState(); @@ -8541,7 +8548,10 @@ SvStream* PDFWriterImpl::endRedirect() } pop(); - // force reemitting colors + // force reemitting colors and clip region + clearClipRegion(); + m_aCurrentPDFState.m_bClipRegion = m_aGraphicsStack.front().m_bClipRegion; + m_aCurrentPDFState.m_aClipRegion = m_aGraphicsStack.front().m_aClipRegion; m_aCurrentPDFState.m_aLineColor = Color( COL_TRANSPARENT ); m_aCurrentPDFState.m_aFillColor = Color( COL_TRANSPARENT ); @@ -10838,7 +10848,7 @@ sal_Int32 PDFWriterImpl::setOutlineItemText( sal_Int32 nItem, const OUString& rT if( nItem < 1 || nItem >= (sal_Int32)m_aOutline.size() ) return -1; - m_aOutline[ nItem ].m_aTitle = rText; + m_aOutline[ nItem ].m_aTitle = psp::WhitespaceToSpace( rText ); return 0; } 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/print2.cxx b/vcl/source/gdi/print2.cxx index d560b0b6e7cc..25ba80003fd7 100644 --- a/vcl/source/gdi/print2.cxx +++ b/vcl/source/gdi/print2.cxx @@ -404,9 +404,20 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic break; case META_LINE_ACTION: - aActionBounds = Rectangle( static_cast<const MetaLineAction&>(rAct).GetStartPoint(), - static_cast<const MetaLineAction&>(rAct).GetEndPoint() ); + { + const MetaLineAction& rMetaLineAction = static_cast<const MetaLineAction&>(rAct); + aActionBounds = Rectangle( rMetaLineAction.GetStartPoint(), rMetaLineAction.GetEndPoint() ); + const long nLineWidth(rMetaLineAction.GetLineInfo().GetWidth()); + if(nLineWidth) + { + const long nHalfLineWidth((nLineWidth + 1) / 2); + aActionBounds.Left() -= nHalfLineWidth; + aActionBounds.Top() -= nHalfLineWidth; + aActionBounds.Right() += nHalfLineWidth; + aActionBounds.Bottom() += nHalfLineWidth; + } break; + } case META_RECT_ACTION: aActionBounds = static_cast<const MetaRectAction&>(rAct).GetRect(); @@ -446,8 +457,20 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic break; case META_POLYLINE_ACTION: - aActionBounds = static_cast<const MetaPolyLineAction&>(rAct).GetPolygon().GetBoundRect(); + { + const MetaPolyLineAction& rMetaPolyLineAction = static_cast<const MetaPolyLineAction&>(rAct); + aActionBounds = rMetaPolyLineAction.GetPolygon().GetBoundRect(); + const long nLineWidth(rMetaPolyLineAction.GetLineInfo().GetWidth()); + if(nLineWidth) + { + const long nHalfLineWidth((nLineWidth + 1) / 2); + aActionBounds.Left() -= nHalfLineWidth; + aActionBounds.Top() -= nHalfLineWidth; + aActionBounds.Right() += nHalfLineWidth; + aActionBounds.Bottom() += nHalfLineWidth; + } break; + } case META_POLYGON_ACTION: aActionBounds = static_cast<const MetaPolygonAction&>(rAct).GetPolygon().GetBoundRect(); diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index 191f8f26dc75..98eac5e982d3 100644..100755 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -150,6 +150,7 @@ public: typedef std::hash_map< rtl::OUString, size_t, rtl::OUStringHash > PropertyToIndexMap; typedef std::hash_map< rtl::OUString, ControlDependency, rtl::OUStringHash > ControlDependencyMap; + typedef std::hash_map< rtl::OUString, Sequence< sal_Bool >, rtl::OUStringHash > ChoiceDisableMap; boost::shared_ptr<Printer> mpPrinter; Sequence< PropertyValue > maUIOptions; @@ -158,6 +159,7 @@ public: PropertyToIndexMap maPropertyToIndex; Link maOptionChangeHdl; ControlDependencyMap maControlDependencies; + ChoiceDisableMap maChoiceDisableMap; sal_Bool mbFirstPage; sal_Bool mbLastPage; sal_Bool mbReversePageOrder; @@ -173,6 +175,7 @@ public: // if set, pages are centered and trimmed onto the fixed page Size maFixedPageSize; sal_Int32 mnDefaultPaperBin; + sal_Int32 mnFixedPaperBin; ImplPrinterControllerData() : mbFirstPage( sal_True ), @@ -180,21 +183,22 @@ public: mbReversePageOrder( sal_False ), meJobState( view::PrintableState_JOB_STARTED ), mpProgress( NULL ), - mnDefaultPaperBin( -1 ) + mnDefaultPaperBin( -1 ), + mnFixedPaperBin( -1 ) {} ~ImplPrinterControllerData() { delete mpProgress; } - Size getRealPaperSize( const Size& i_rPageSize ) const + Size getRealPaperSize( const Size& i_rPageSize, bool bNoNUP ) const { if( maFixedPageSize.Width() > 0 && maFixedPageSize.Height() > 0 ) return maFixedPageSize; - if( maMultiPage.nRows * maMultiPage.nColumns > 1 ) + if( maMultiPage.nRows * maMultiPage.nColumns > 1 && ! bNoNUP ) return maMultiPage.aPaperSize; return i_rPageSize; } bool isFixedPageSize() const { return maFixedPageSize.Width() != 0 && maFixedPageSize.Height() != 0; } - PrinterController::PageSize modifyJobSetup( const Sequence< PropertyValue >& i_rProps ); + PrinterController::PageSize modifyJobSetup( const Sequence< PropertyValue >& i_rProps, bool bNoNUP ); }; PrinterController::PrinterController() @@ -444,8 +448,7 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr if( ! aDlg.Execute() ) { GDIMetaFile aPageFile; - i_pController->setLastPage( sal_True ); - i_pController->getFilteredPageFile( 0, aPageFile ); + i_pController->abortJob(); return; } if( aDlg.isPrintToFile() ) @@ -453,9 +456,7 @@ void Printer::ImplPrintJob( const boost::shared_ptr<PrinterController>& i_pContr rtl::OUString aFile = queryFile( pController->getPrinter().get() ); if( ! aFile.getLength() ) { - GDIMetaFile aPageFile; - i_pController->setLastPage( sal_True ); - i_pController->getFilteredPageFile( 0, aPageFile ); + i_pController->abortJob(); return; } pController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalFileName" ) ), @@ -557,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 @@ -594,17 +595,25 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: i_pController->jobStarted(); int nJobs = 1; - int nRepeatCount = bUserCopy ? mnCopyCount : 1; + int nOuterRepeatCount = 1; + int nInnerRepeatCount = 1; + if( bUserCopy ) + { + if( mbCollateCopy ) + nOuterRepeatCount = mnCopyCount; + else + nInnerRepeatCount = mnCopyCount; + } if( bSinglePrintJobs ) { nJobs = mnCopyCount; nCopies = 1; - nRepeatCount = 1; + nOuterRepeatCount = nInnerRepeatCount = 1; } for( int nJobIteration = 0; nJobIteration < nJobs; nJobIteration++ ) { - bool bError = false; + bool bError = false, bAborted = false; if( mpPrinter->StartJob( pPrintFile, i_rJobName, Application::GetDisplayName(), @@ -616,13 +625,26 @@ bool Printer::StartJob( const rtl::OUString& i_rJobName, boost::shared_ptr<vcl:: mbJobActive = TRUE; i_pController->createProgressDialog(); int nPages = i_pController->getFilteredPageCount(); - for( int nIteration = 0; nIteration < nRepeatCount; nIteration++ ) + for( int nOuterIteration = 0; nOuterIteration < nOuterRepeatCount && ! bAborted; nOuterIteration++ ) { - for( int nPage = 0; nPage < nPages; nPage++ ) + for( int nPage = 0; nPage < nPages && ! bAborted; nPage++ ) { - if( nPage == nPages-1 && nIteration == nRepeatCount-1 && nJobIteration == nJobs-1 ) - i_pController->setLastPage( sal_True ); - i_pController->printFilteredPage( nPage ); + for( int nInnerIteration = 0; nInnerIteration < nInnerRepeatCount && ! bAborted; nInnerIteration++ ) + { + if( nPage == nPages-1 && + nOuterIteration == nOuterRepeatCount-1 && + nInnerIteration == nInnerRepeatCount-1 && + nJobIteration == nJobs-1 ) + { + i_pController->setLastPage( sal_True ); + } + i_pController->printFilteredPage( nPage ); + if( i_pController->isProgressCanceled() ) + { + i_pController->abortJob(); + bAborted = true; + } + } } // FIXME: duplex ? } @@ -708,6 +730,7 @@ void PrinterController::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ), makeAny( rtl::OUString( i_rPrinter->GetName() ) ) ); mpImplData->mnDefaultPaperBin = mpImplData->mpPrinter->GetPaperBin(); + mpImplData->mnFixedPaperBin = -1; } bool PrinterController::setupPrinter( Window* i_pParent ) @@ -715,15 +738,20 @@ bool PrinterController::setupPrinter( Window* i_pParent ) bool bRet = false; if( mpImplData->mpPrinter.get() ) { + // get old data Size aPaperSize( mpImplData->mpPrinter->PixelToLogic( mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) ); + USHORT nPaperBin = mpImplData->mpPrinter->GetPaperBin(); + + // call driver setup bRet = mpImplData->mpPrinter->Setup( i_pParent ); if( bRet ) { - // was the papersize overridden ? if so we need to take action + // was papersize or bin overridden ? if so we need to take action Size aNewPaperSize( mpImplData->mpPrinter->PixelToLogic( mpImplData->mpPrinter->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) ); - if( aNewPaperSize != aPaperSize ) + USHORT nNewPaperBin = mpImplData->mpPrinter->GetPaperBin(); + if( aNewPaperSize != aPaperSize || nNewPaperBin != nPaperBin ) { mpImplData->maFixedPageSize = aNewPaperSize; mpImplData->maPageCache.invalidate(); @@ -732,13 +760,14 @@ bool PrinterController::setupPrinter( Window* i_pParent ) aOverrideSize.Height = aNewPaperSize.Height(); setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OverridePageSize" ) ), makeAny( aOverrideSize ) ); + mpImplData->mnFixedPaperBin = nNewPaperBin; } } } return bRet; } -PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const Sequence< PropertyValue >& i_rProps ) +PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( const Sequence< PropertyValue >& i_rProps, bool bNoNUP ) { PrinterController::PageSize aPageSize; aPageSize.aSize = mpPrinter->GetPaperSize(); @@ -773,7 +802,7 @@ PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( cons if( aSetSize.Width && aSetSize.Height ) { Size aSetPaperSize( aSetSize.Width, aSetSize.Height ); - Size aRealPaperSize( getRealPaperSize( aSetPaperSize ) ); + Size aRealPaperSize( getRealPaperSize( aSetPaperSize, bNoNUP ) ); if( aRealPaperSize != aCurSize ) aIsSize = aSetSize; } @@ -783,7 +812,7 @@ PrinterController::PageSize vcl::ImplPrinterControllerData::modifyJobSetup( cons aPageSize.aSize.Width() = aIsSize.Width; aPageSize.aSize.Height() = aIsSize.Height; - Size aRealPaperSize( getRealPaperSize( aPageSize.aSize ) ); + Size aRealPaperSize( getRealPaperSize( aPageSize.aSize, bNoNUP ) ); if( aRealPaperSize != aCurSize ) mpPrinter->SetPaperSizeUser( aRealPaperSize, ! isFixedPageSize() ); } @@ -849,7 +878,7 @@ PrinterController::PageSize PrinterController::getPageFile( int i_nUnfilteredPag mpImplData->mpPrinter->SetMapMode( aMapMode ); // modify job setup if necessary - PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm ); + PrinterController::PageSize aPageSize = mpImplData->modifyJobSetup( aPageParm, true ); o_rMtf.SetPrefSize( aPageSize.aSize ); o_rMtf.SetPrefMapMode( aMapMode ); @@ -931,7 +960,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte rMPS.nTopMargin == 0 && rMPS.nBottomMargin == 0 ) { PrinterController::PageSize aPageSize = getPageFile( i_nFilteredPage, o_rMtf, i_bMayUseCache ); - Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize ); + Size aPaperSize = mpImplData->getRealPaperSize( aPageSize.aSize, true ); mpImplData->mpPrinter->SetMapMode( MapMode( MAP_100TH_MM ) ); mpImplData->mpPrinter->SetPaperSizeUser( aPaperSize, ! mpImplData->isFixedPageSize() ); if( aPaperSize != aPageSize.aSize ) @@ -940,7 +969,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte o_rMtf.WindStart(); long nDX = (aPaperSize.Width() - aPageSize.aSize.Width()) / 2; long nDY = (aPaperSize.Height() - aPageSize.aSize.Height()) / 2; - o_rMtf.Move( nDX, nDY ); + o_rMtf.Move( nDX, nDY, mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() ); o_rMtf.WindStart(); o_rMtf.SetPrefSize( aPaperSize ); aPageSize.aSize = aPaperSize; @@ -953,7 +982,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte sal_Bool bIsLastPage = mpImplData->mbLastPage; mpImplData->mbLastPage = sal_False; - Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize ) ); + Size aPaperSize( mpImplData->getRealPaperSize( mpImplData->maMultiPage.aPaperSize, false ) ); // multi page area: page size minus margins + one time spacing right and down // the added spacing is so each subpage can be calculated including its spacing @@ -1002,6 +1031,14 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte nCellX = (nSubPage / rMPS.nRows); nCellY = (nSubPage % rMPS.nRows); break; + case PrinterController::RLTB: + nCellX = rMPS.nColumns - 1 - (nSubPage % rMPS.nColumns); + nCellY = (nSubPage / rMPS.nColumns); + break; + case PrinterController::TBRL: + nCellX = rMPS.nColumns - 1 - (nSubPage / rMPS.nRows); + nCellY = (nSubPage % rMPS.nRows); + break; } // scale the metafile down to a sub page size double fScaleX = double(aSubPageSize.Width())/double(aPageSize.aSize.Width()); @@ -1015,7 +1052,7 @@ PrinterController::PageSize PrinterController::getFilteredPageFile( int i_nFilte long nOffY = (aSubPageSize.Height() - long(double(aPageSize.aSize.Height()) * fScale)) / 2; long nX = rMPS.nLeftMargin + nOffX + nAdvX * nCellX; long nY = rMPS.nTopMargin + nOffY + nAdvY * nCellY; - aPageFile.Move( nX, nY ); + aPageFile.Move( nX, nY, mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() ); aPageFile.WindStart(); // calculate border rectangle Rectangle aSubPageRect( Point( nX, nY ), @@ -1129,13 +1166,18 @@ void PrinterController::printFilteredPage( int i_nPage ) mpImplData->mpPrinter->SetMapMode( MAP_100TH_MM ); // aPageSize was filtered through mpImplData->getRealPaperSize already by getFilteredPageFile() mpImplData->mpPrinter->SetPaperSizeUser( aPageSize.aSize, ! mpImplData->isFixedPageSize() ); + if( mpImplData->mnFixedPaperBin != -1 && + mpImplData->mpPrinter->GetPaperBin() != mpImplData->mnFixedPaperBin ) + { + mpImplData->mpPrinter->SetPaperBin( mpImplData->mnFixedPaperBin ); + } - // if full paper are is meant, move the output to accomodate for pageoffset + // if full paper is meant to be used, move the output to accomodate for pageoffset if( aPageSize.bFullPaper ) { Point aPageOffset( mpImplData->mpPrinter->GetPageOffset() ); aPageFile.WindStart(); - aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y() ); + aPageFile.Move( -aPageOffset.X(), -aPageOffset.Y(), mpImplData->mpPrinter->ImplGetDPIX(), mpImplData->mpPrinter->ImplGetDPIY() ); } GDIMetaFile aCleanedFile; @@ -1167,6 +1209,13 @@ void PrinterController::jobFinished( view::PrintableState ) void PrinterController::abortJob() { setJobState( view::PrintableState_JOB_ABORTED ); + // applications (well, sw) depend on a page request with "IsLastPage" = true + // to free resources, else they (well, sw) will crash eventually + setLastPage( sal_True ); + delete mpImplData->mpProgress; + mpImplData->mpProgress = NULL; + GDIMetaFile aMtf; + getPageFile( 0, aMtf, false ); } void PrinterController::setLastPage( sal_Bool i_bLastPage ) @@ -1299,6 +1348,7 @@ void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_ bool bHaveProperty = false; rtl::OUString aPropName; vcl::ImplPrinterControllerData::ControlDependency aDep; + Sequence< sal_Bool > aChoicesDisabled; for( int n = 0; n < aOptProp.getLength(); n++ ) { const beans::PropertyValue& rEntry( aOptProp[ n ] ); @@ -1326,6 +1376,10 @@ void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_ { rEntry.Value >>= aDep.mnDependsOnEntry; } + else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) ) + { + rEntry.Value >>= aChoicesDisabled; + } } if( bHaveProperty ) { @@ -1338,6 +1392,8 @@ void PrinterController::setUIOptions( const Sequence< beans::PropertyValue >& i_ } if( aDep.maDependsOnName.getLength() > 0 ) mpImplData->maControlDependencies[ aPropName ] = aDep; + if( aChoicesDisabled.getLength() > 0 ) + mpImplData->maChoiceDisableMap[ aPropName ] = aChoicesDisabled; } } } @@ -1413,6 +1469,20 @@ bool PrinterController::isUIOptionEnabled( const rtl::OUString& i_rProperty ) co return bEnabled; } +bool PrinterController::isUIChoiceEnabled( const rtl::OUString& i_rProperty, sal_Int32 i_nValue ) const +{ + bool bEnabled = true; + ImplPrinterControllerData::ChoiceDisableMap::const_iterator it = + mpImplData->maChoiceDisableMap.find( i_rProperty ); + if(it != mpImplData->maChoiceDisableMap.end() ) + { + const Sequence< sal_Bool >& rDisabled( it->second ); + if( i_nValue >= 0 && i_nValue < rDisabled.getLength() ) + bEnabled = ! rDisabled[i_nValue]; + } + return bEnabled; +} + rtl::OUString PrinterController::getDependency( const rtl::OUString& i_rProperty ) const { rtl::OUString aDependency; @@ -1499,6 +1569,11 @@ void PrinterController::createProgressDialog() mpImplData->mpProgress->reset(); } +bool PrinterController::isProgressCanceled() const +{ + return mpImplData->mpProgress && mpImplData->mpProgress->isCanceled(); +} + void PrinterController::setMultipage( const MultiPageSetup& i_rMPS ) { mpImplData->maMultiPage = i_rMPS; @@ -1789,14 +1864,20 @@ Any PrinterOptionsHelper::getChoiceControlOpt( const rtl::OUString& i_rTitle, const Sequence< rtl::OUString >& i_rChoices, sal_Int32 i_nValue, const rtl::OUString& i_rType, + const Sequence< sal_Bool >& i_rDisabledChoices, const PrinterOptionsHelper::UIControlOptions& i_rControlOptions ) { UIControlOptions aOpt( i_rControlOptions ); sal_Int32 nUsed = aOpt.maAddProps.getLength(); - aOpt.maAddProps.realloc( nUsed + 1 ); + aOpt.maAddProps.realloc( nUsed + 1 + (i_rDisabledChoices.getLength() ? 1 : 0) ); aOpt.maAddProps[nUsed].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Choices" ) ); aOpt.maAddProps[nUsed].Value = makeAny( i_rChoices ); + if( i_rDisabledChoices.getLength() ) + { + aOpt.maAddProps[nUsed+1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ChoicesDisabled" ) ); + aOpt.maAddProps[nUsed+1].Value = makeAny( i_rDisabledChoices ); + } PropertyValue aVal; aVal.Name = i_rProperty; diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 7a6808a0e392..97e11c5a6aa4 100644..100755 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -669,13 +669,13 @@ BOOL SalGraphics::DrawEPS( long nX, long nY, long nWidth, long nHeight, void* return drawEPS( nX, nY, nWidth, nHeight, pPtr, nSize ); } -BOOL SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, const Point& aPos, BOOL& rIsInside, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { Point pt( aPos ); - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( pt.X(), pOutDev ); mirror( rgn, pOutDev ); return hitTestNativeControl( nType, nPart, rgn, pt, rIsInside ); @@ -684,51 +684,48 @@ BOOL SalGraphics::HitTestNativeControl( ControlType nType, ControlPart nPart, co return hitTestNativeControl( nType, nPart, rControlRegion, aPos, rIsInside ); } -void SalGraphics::mirror( ControlType nType, const ImplControlValue& rVal, const OutputDevice* pOutDev, bool bBack ) const +void SalGraphics::mirror( ControlType , const ImplControlValue& rVal, const OutputDevice* pOutDev, bool bBack ) const { - if( rVal.getOptionalVal() ) + switch( rVal.getType() ) { - switch( nType ) + case CTRL_SLIDER: { - case CTRL_SLIDER: - { - SliderValue* pSlVal = reinterpret_cast<SliderValue*>(rVal.getOptionalVal()); - mirror(pSlVal->maThumbRect,pOutDev,bBack); - } - break; - case CTRL_SCROLLBAR: - { - ScrollbarValue* pScVal = reinterpret_cast<ScrollbarValue*>(rVal.getOptionalVal()); - mirror(pScVal->maThumbRect,pOutDev,bBack); - mirror(pScVal->maButton1Rect,pOutDev,bBack); - mirror(pScVal->maButton2Rect,pOutDev,bBack); - } - break; - case CTRL_SPINBOX: - case CTRL_SPINBUTTONS: - { - SpinbuttonValue* pSpVal = reinterpret_cast<SpinbuttonValue*>(rVal.getOptionalVal()); - mirror(pSpVal->maUpperRect,pOutDev,bBack); - mirror(pSpVal->maLowerRect,pOutDev,bBack); - } - break; - case CTRL_TOOLBAR: - { - ToolbarValue* pTVal = reinterpret_cast<ToolbarValue*>(rVal.getOptionalVal()); - mirror(pTVal->maGripRect,pOutDev,bBack); - } - break; + SliderValue* pSlVal = static_cast<SliderValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pSlVal->maThumbRect,pOutDev,bBack); + } + break; + case CTRL_SCROLLBAR: + { + ScrollbarValue* pScVal = static_cast<ScrollbarValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pScVal->maThumbRect,pOutDev,bBack); + mirror(pScVal->maButton1Rect,pOutDev,bBack); + mirror(pScVal->maButton2Rect,pOutDev,bBack); + } + break; + case CTRL_SPINBOX: + case CTRL_SPINBUTTONS: + { + SpinbuttonValue* pSpVal = static_cast<SpinbuttonValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pSpVal->maUpperRect,pOutDev,bBack); + mirror(pSpVal->maLowerRect,pOutDev,bBack); + } + break; + case CTRL_TOOLBAR: + { + ToolbarValue* pTVal = static_cast<ToolbarValue*>(const_cast<ImplControlValue*>(&rVal)); + mirror(pTVal->maGripRect,pOutDev,bBack); } + break; } } -BOOL SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( rgn, pOutDev ); mirror( nType, aValue, pOutDev ); BOOL bRet = drawNativeControl( nType, nPart, rgn, nState, aValue, aCaption ); @@ -739,13 +736,13 @@ BOOL SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const return drawNativeControl( nType, nPart, rControlRegion, nState, aValue, aCaption ); } -BOOL SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion, +BOOL SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( rgn, pOutDev ); mirror( nType, aValue, pOutDev ); BOOL bRet = drawNativeControlText( nType, nPart, rgn, nState, aValue, aCaption ); @@ -756,13 +753,13 @@ BOOL SalGraphics::DrawNativeControlText( ControlType nType, ControlPart nPart, c return drawNativeControlText( nType, nPart, rControlRegion, nState, aValue, aCaption ); } -BOOL SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState, +BOOL SalGraphics::GetNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState nState, const ImplControlValue& aValue, const OUString& aCaption, - Region &rNativeBoundingRegion, Region &rNativeContentRegion, const OutputDevice *pOutDev ) + Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - Region rgn( rControlRegion ); + Rectangle rgn( rControlRegion ); mirror( rgn, pOutDev ); mirror( nType, aValue, pOutDev ); if( getNativeControlRegion( nType, nPart, rgn, nState, aValue, aCaption, diff --git a/vcl/source/gdi/salnativewidgets-none.cxx b/vcl/source/gdi/salnativewidgets-none.cxx index 7faf12d062fe..8aa0e47f1a35 100644 --- a/vcl/source/gdi/salnativewidgets-none.cxx +++ b/vcl/source/gdi/salnativewidgets-none.cxx @@ -58,7 +58,7 @@ BOOL SalGraphics::IsNativeControlSupported( ControlType, ControlPart ) */ BOOL SalGraphics::hitTestNativeControl( ControlType, ControlPart, - const Region&, + const Rectangle&, const Point&, BOOL& ) { @@ -77,7 +77,7 @@ BOOL SalGraphics::hitTestNativeControl( ControlType, */ BOOL SalGraphics::drawNativeControl( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) @@ -98,7 +98,7 @@ BOOL SalGraphics::drawNativeControl( ControlType, */ BOOL SalGraphics::drawNativeControlText( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString& ) @@ -122,12 +122,12 @@ BOOL SalGraphics::drawNativeControlText( ControlType, */ BOOL SalGraphics::getNativeControlRegion( ControlType, ControlPart, - const Region&, + const Rectangle&, ControlState, const ImplControlValue&, const OUString&, - Region &, - Region & ) + Rectangle &, + Rectangle & ) { return( FALSE ); } |