diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2010-01-26 16:17:30 +0100 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2010-01-26 16:17:30 +0100 |
commit | 20c9b2305c7f9c2341961a1aa32bdc151aead3b4 (patch) | |
tree | 0bd3c6123baef73e15de01001c552d20f84f9a90 | |
parent | 6c662eef5c3516155b001865a3512f8ca705390a (diff) | |
parent | 81f4386da532ba62e5e2381e57485197ce5da0bf (diff) |
CWS-TOOLING: integrate CWS impress181
-rwxr-xr-x | canvas/source/directx/dx_winstuff.hxx | 12 | ||||
-rw-r--r-- | goodies/source/filter.vcl/ipbm/ipbm.cxx | 11 | ||||
-rw-r--r-- | svtools/source/filter.vcl/jpeg/jpeg.cxx | 39 | ||||
-rw-r--r-- | svtools/source/filter.vcl/jpeg/jpeg.h | 2 | ||||
-rw-r--r-- | svtools/source/filter.vcl/jpeg/jpegc.c | 14 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/emfwr.cxx | 103 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/emfwr.hxx | 1 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winmtf.cxx | 9 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winmtf.hxx | 15 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winwmf.cxx | 216 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/wmfwr.cxx | 80 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/wmfwr.hxx | 9 | ||||
-rw-r--r-- | svtools/source/misc/ehdl.cxx | 26 |
13 files changed, 408 insertions, 129 deletions
diff --git a/canvas/source/directx/dx_winstuff.hxx b/canvas/source/directx/dx_winstuff.hxx index 1c64506c0f21..47658991e74b 100755 --- a/canvas/source/directx/dx_winstuff.hxx +++ b/canvas/source/directx/dx_winstuff.hxx @@ -89,7 +89,7 @@ #include <d3d9.h> #include <d3dx9.h> - #include <dxerr9.h> +// #include <dxerr9.h> #i107614# removing include, it has been changed in the latest sdk fron August2009 from dxerr9.h into dxerr.h typedef IDirect3DSurface9 surface_type; @@ -97,11 +97,11 @@ #undef DrawText -#ifdef __MINGW32__
-using ::std::max;
-using ::std::min;
-#endif
-
+#ifdef __MINGW32__ +using ::std::max; +using ::std::min; +#endif + #include <gdiplus.h> #ifdef min diff --git a/goodies/source/filter.vcl/ipbm/ipbm.cxx b/goodies/source/filter.vcl/ipbm/ipbm.cxx index 227490fc9d8e..3c30dd0c2ba3 100644 --- a/goodies/source/filter.vcl/ipbm/ipbm.cxx +++ b/goodies/source/filter.vcl/ipbm/ipbm.cxx @@ -106,7 +106,7 @@ BOOL PBMReader::ReadPBM( SvStream & rPBM, Graphic & rGraphic ) if ( ( mbStatus = ImplReadHeader() ) == FALSE ) return FALSE; - if ( mnWidth == 0 || mnHeight == 0 ) + if ( ( mnMaxVal == 0 ) || ( mnWidth == 0 ) || ( mnHeight == 0 ) ) return FALSE; // 0->PBM, 1->PGM, 2->PPM @@ -172,6 +172,7 @@ BOOL PBMReader::ImplReadHeader() *mpPBM >> nID[ 0 ] >> nID[ 1 ]; if ( nID[ 0 ] != 'P' ) return FALSE; + mnMaxVal = mnWidth = mnHeight = 0; switch ( nID[ 1 ] ) { case '1' : @@ -179,6 +180,7 @@ BOOL PBMReader::ImplReadHeader() case '4' : mnMode = 0; nMax = 2; // number of parameters in Header + mnMaxVal = 1; break; case '2' : mbRaw = FALSE; @@ -195,9 +197,6 @@ BOOL PBMReader::ImplReadHeader() default: return FALSE; } - - mnMaxVal = mnWidth = mnHeight = 0; - while ( bFinished == FALSE ) { if ( mpPBM->GetError() ) @@ -466,7 +465,9 @@ BOOL PBMReader::ImplReadBody() if ( nCount == 3 ) { nCount = 0; - mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( (BYTE)nRGB[ 0 ], (BYTE)nRGB[ 1 ], (BYTE)nRGB[ 2 ] ) ); + mpAcc->SetPixel( nHeight, nWidth++, BitmapColor( static_cast< BYTE >( ( nRGB[ 0 ] * 255 ) / mnMaxVal ), + static_cast< BYTE >( ( nRGB[ 1 ] * 255 ) / mnMaxVal ), + static_cast< BYTE >( ( nRGB[ 2 ] * 255 ) / mnMaxVal ) ) ); nCount = 0; nRGB[ 0 ] = nRGB[ 1 ] = nRGB[ 2 ] = 0; if ( nWidth == mnWidth ) diff --git a/svtools/source/filter.vcl/jpeg/jpeg.cxx b/svtools/source/filter.vcl/jpeg/jpeg.cxx index 81d07ccd5e79..ee2b2baebee0 100644 --- a/svtools/source/filter.vcl/jpeg/jpeg.cxx +++ b/svtools/source/filter.vcl/jpeg/jpeg.cxx @@ -656,10 +656,14 @@ void* JPEGWriter::GetScanline( long nY ) aColor = pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) ); #ifndef SYSTEM_JPEG *pTmp++ = aColor.GetBlue(); + if ( bGreys ) + continue; *pTmp++ = aColor.GetGreen(); *pTmp++ = aColor.GetRed(); #else *pTmp++ = aColor.GetRed(); + if ( bGreys ) + continue; *pTmp++ = aColor.GetGreen(); *pTmp++ = aColor.GetBlue(); #endif @@ -672,10 +676,14 @@ void* JPEGWriter::GetScanline( long nY ) aColor = pAcc->GetPixel( nY, nX ); #ifndef SYSTEM_JPEG *pTmp++ = aColor.GetBlue(); + if ( bGreys ) + continue; *pTmp++ = aColor.GetGreen(); *pTmp++ = aColor.GetRed(); #else *pTmp++ = aColor.GetRed(); + if ( bGreys ) + continue; *pTmp++ = aColor.GetGreen(); *pTmp++ = aColor.GetBlue(); #endif @@ -711,20 +719,43 @@ BOOL JPEGWriter::Write( const Graphic& rGraphic ) pAcc = aGraphicBmp.AcquireReadAccess(); + if ( !bGreys ) // bitmap was not explicitely converted into greyscale, + { // check if source is greyscale only + + sal_Bool bIsGrey = sal_True; + + long nWidth = pAcc->Width(); + for ( long nY = 0; bIsGrey && ( nY < pAcc->Height() ); nY++ ) + { + BitmapColor aColor; + for( long nX = 0L; bIsGrey && ( nX < nWidth ); nX++ ) + { + aColor = pAcc->HasPalette() ? pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) ) + : pAcc->GetPixel( nY, nX ); + bIsGrey = ( aColor.GetRed() == aColor.GetGreen() ) && ( aColor.GetRed() == aColor.GetBlue() ); + } + } + if ( bIsGrey ) + bGreys = sal_True; + } + if( pAcc ) { + if ( bGreys ) + bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ); + else #ifndef SYSTEM_JPEG - bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR ); + bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR ); #else - bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB ); + bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB ); #endif if( !bNative ) - pBuffer = new BYTE[ AlignedWidth4Bytes( pAcc->Width() * 24L ) ]; + pBuffer = new BYTE[ AlignedWidth4Bytes( bGreys ? pAcc->Width() * 8L : pAcc->Width() * 24L ) ]; JPEGCallbackStruct aCallbackData; aCallbackData.xStatusIndicator = xStatusIndicator; - bRet = (BOOL) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), nQuality, &aCallbackData ); + bRet = (BOOL) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), bGreys, nQuality, &aCallbackData ); delete[] pBuffer; pBuffer = NULL; diff --git a/svtools/source/filter.vcl/jpeg/jpeg.h b/svtools/source/filter.vcl/jpeg/jpeg.h index eaeaa503b5e9..4d5aafe413bb 100644 --- a/svtools/source/filter.vcl/jpeg/jpeg.h +++ b/svtools/source/filter.vcl/jpeg/jpeg.h @@ -64,7 +64,7 @@ void* JPEGMalloc( size_t size ); void JPEGFree( void *ptr ); long JPEGCallback( void* pCallbackData, long nPercent ); -long WriteJPEG( void* pJPEGWriter, void* pOStm, long nWidth, long nHeight, +long WriteJPEG( void* pJPEGWriter, void* pOStm, long nWidth, long nHeight, long bGreyScale, long nQualityPercent, void* pCallbackData ); void* GetScanline( void* pJPEGWriter, long nY ); diff --git a/svtools/source/filter.vcl/jpeg/jpegc.c b/svtools/source/filter.vcl/jpeg/jpegc.c index 84394d945f79..0525877f2614 100644 --- a/svtools/source/filter.vcl/jpeg/jpegc.c +++ b/svtools/source/filter.vcl/jpeg/jpegc.c @@ -182,7 +182,7 @@ Exit: } long WriteJPEG( void* pJPEGWriter, void* pOStm, - long nWidth, long nHeight, + long nWidth, long nHeight, long bGreys, long nQualityPercent, void* pCallbackData ) { struct jpeg_compress_struct cinfo; @@ -208,8 +208,16 @@ long WriteJPEG( void* pJPEGWriter, void* pOStm, cinfo.image_width = (JDIMENSION) nWidth; cinfo.image_height = (JDIMENSION) nHeight; - cinfo.input_components = 3; - cinfo.in_color_space = JCS_RGB; + if ( bGreys ) + { + cinfo.input_components = 1; + cinfo.in_color_space = JCS_GRAYSCALE; + } + else + { + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + } jpeg_set_defaults( &cinfo ); jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE ); diff --git a/svtools/source/filter.vcl/wmf/emfwr.cxx b/svtools/source/filter.vcl/wmf/emfwr.cxx index e011dde1a0e8..1bc5364a191a 100644 --- a/svtools/source/filter.vcl/wmf/emfwr.cxx +++ b/svtools/source/filter.vcl/wmf/emfwr.cxx @@ -165,6 +165,8 @@ #define TA_RTLREADING 256 #define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING) +#define MM_ANISOTROPIC 8 + // ------------- // - EMFWriter - // ------------- @@ -184,19 +186,37 @@ BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfig maVDev.SetMapMode( rMtf.GetPrefMapMode() ); mpFilterConfigItem = pFilterConfigItem; + // don't work with pixel as destination map mode -> higher resolution preferrable + maDestMapMode.SetMapUnit( MAP_100TH_MM ); + const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) ); const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) ); // seek over header - rOStm.SeekRel( 100 ); + // use [MS-EMF 2.2.11] HeaderExtension2 Object, otherwise resulting EMF cannot be converted with GetWinMetaFileBits() + rOStm.SeekRel( 108 ); // write initial values - ImplBeginRecord( WIN_EMR_SETWINDOWORGEX ); - (*mpStm) << (INT32) 0 << (INT32) 0; + + // set 100th mm map mode in EMF + ImplBeginRecord( WIN_EMR_SETMAPMODE ); + (*mpStm) << (INT32) MM_ANISOTROPIC; + ImplEndRecord(); + + ImplBeginRecord( WIN_EMR_SETVIEWPORTEXTEX ); + (*mpStm) << (INT32) maVDev.ImplGetDPIX() << (INT32) maVDev.ImplGetDPIY(); ImplEndRecord(); ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX ); - (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height(); + (*mpStm) << (INT32) 2540 << (INT32) 2540; + ImplEndRecord(); + + ImplBeginRecord( WIN_EMR_SETVIEWPORTORGEX ); + (*mpStm) << (INT32) 0 << (INT32) 0; + ImplEndRecord(); + + ImplBeginRecord( WIN_EMR_SETWINDOWORGEX ); + (*mpStm) << (INT32) 0 << (INT32) 0; ImplEndRecord(); ImplWriteRasterOp( ROP_OVERPAINT ); @@ -210,7 +230,7 @@ BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfig ImplBeginRecord( WIN_EMR_EOF ); (*mpStm)<< (sal_uInt32)0 // nPalEntries - << (sal_uInt32)0x16 // offPalEntries + << (sal_uInt32)0x10 // offPalEntries << (sal_uInt32)0x14; // nSizeLast ImplEndRecord(); @@ -218,14 +238,15 @@ BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfig // write header const ULONG nEndPos = mpStm->Tell(); mpStm->Seek( nHeaderPos ); - (*mpStm) << (UINT32) 0x00000001 << (UINT32) 100; - (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 ); - (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 ); - (*mpStm) << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos ); - (*mpStm) << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0; - (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height(); - (*mpStm) << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 ); - (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0; + (*mpStm) << (UINT32) 0x00000001 << (UINT32) 108 //use [MS-EMF 2.2.11] HeaderExtension2 Object + << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 ) + << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 ) + << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos ) + << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 + << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height() + << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 ) + << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 + << (INT32) ( aMtfSizeLog.Width() * 10 ) << (INT32) ( aMtfSizeLog.Height() * 10 ); //use [MS-EMF 2.2.11] HeaderExtension2 Object mpStm->Seek( nEndPos ); delete[] mpHandlesUsed; @@ -523,35 +544,32 @@ void EMFWriter::ImplWriteRasterOp( RasterOp eRop ) void EMFWriter::ImplWriteExtent( long nExtent ) { - const Size aSize( maVDev.LogicToPixel( Size( nExtent, nExtent ) ) ); - (*mpStm) << (INT32) aSize.Width(); + nExtent = maVDev.LogicToLogic( Size( nExtent, 0 ), maVDev.GetMapMode(), maDestMapMode ).Width(); + (*mpStm) << (INT32) nExtent; } // ----------------------------------------------------------------------------- void EMFWriter::ImplWritePoint( const Point& rPoint ) { - const Point aPoint( maVDev.LogicToPixel( rPoint ) ); - - (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y(); + const Point aPoint( maVDev.LogicToLogic( rPoint, maVDev.GetMapMode(), maDestMapMode )); + (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y(); } // ----------------------------------------------------------------------------- void EMFWriter::ImplWriteSize( const Size& rSize) { - const Size aSize( maVDev.LogicToPixel( rSize ) ); - - (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height(); + const Size aSize( maVDev.LogicToLogic( rSize, maVDev.GetMapMode(), maDestMapMode )); + (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height(); } // ----------------------------------------------------------------------------- void EMFWriter::ImplWriteRect( const Rectangle& rRect ) { - const Rectangle aRect( maVDev.LogicToPixel( rRect ) ); - - (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom(); + const Rectangle aRect( maVDev.LogicToLogic ( rRect, maVDev.GetMapMode(), maDestMapMode )); + (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom(); } // ----------------------------------------------------------------------------- @@ -650,12 +668,20 @@ void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed ) const Polygon& rPoly = rPolyPoly[ i ]; while ( n < rPoly.GetSize() ) { - sal_uInt16 nBezPoints = 0; - if ( n ) + if( n == 0 ) { - while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) ) - nBezPoints += 3; + ImplBeginRecord( WIN_EMR_MOVETOEX ); + ImplWritePoint( rPoly[ 0 ] ); + ImplEndRecord(); + n++; + continue; } + + sal_uInt16 nBezPoints = 0; + + while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) ) + nBezPoints += 3; + if ( nBezPoints ) { ImplBeginRecord( WIN_EMR_POLYBEZIERTO ); @@ -675,22 +701,26 @@ void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed ) sal_uInt16 nPoints = 1; while( ( nPoints + n ) < rPoly.GetSize() && ( rPoly.GetFlags( nPoints + n ) != POLY_CONTROL ) ) nPoints++; - ImplBeginRecord( WIN_EMR_MOVETOEX ); - ImplWritePoint( rPoly[ n ] ); - ImplEndRecord(); + if ( nPoints > 1 ) { ImplBeginRecord( WIN_EMR_POLYLINETO ); - Polygon aNewPoly( nPoints ); - aNewPoly[ 0 ] = rPoly[ n ]; - for ( o = 1; o < nPoints; o++ ) - aNewPoly[ o ] = rPoly[ n + o ]; + Polygon aNewPoly( nPoints + 1 ); + aNewPoly[ 0 ] = rPoly[ n - 1]; + for ( o = 1; o <= nPoints; o++ ) + aNewPoly[ o ] = rPoly[ n - 1 + o ]; ImplWriteRect( aNewPoly.GetBoundRect() ); - (*mpStm) << (sal_uInt32)( nPoints - 1 ); + (*mpStm) << (sal_uInt32)( nPoints ); for( o = 1; o < aNewPoly.GetSize(); o++ ) ImplWritePoint( aNewPoly[ o ] ); ImplEndRecord(); } + else + { + ImplBeginRecord( WIN_EMR_LINETO ); + ImplWritePoint( rPoly[ n ] ); + ImplEndRecord(); + } n = n + nPoints; } if ( bClosed && ( n == rPoly.GetSize() ) ) @@ -703,6 +733,7 @@ void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed ) ImplBeginRecord( WIN_EMR_ENDPATH ); ImplEndRecord(); ImplBeginRecord( bClosed ? WIN_EMR_FILLPATH : WIN_EMR_STROKEPATH ); + ImplWriteRect( rPolyPoly.GetBoundRect() ); ImplEndRecord(); } diff --git a/svtools/source/filter.vcl/wmf/emfwr.hxx b/svtools/source/filter.vcl/wmf/emfwr.hxx index 2d3c8801ba49..29715c59df0f 100644 --- a/svtools/source/filter.vcl/wmf/emfwr.hxx +++ b/svtools/source/filter.vcl/wmf/emfwr.hxx @@ -50,6 +50,7 @@ class EMFWriter private: VirtualDevice maVDev; + MapMode maDestMapMode; FilterConfigItem* mpFilterConfigItem; SvStream* mpStm; BOOL* mpHandlesUsed; diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx index 6f1caae18750..58dfdec45ee1 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.cxx +++ b/svtools/source/filter.vcl/wmf/winmtf.cxx @@ -1522,9 +1522,9 @@ void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry aTmp.SetFillColor( maBkColor ); if( mnBkMode == TRANSPARENT ) - maFont.SetTransparent( sal_True ); + aTmp.SetTransparent( sal_True ); else - maFont.SetTransparent( sal_False ); + aTmp.SetTransparent( sal_False ); if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE ) aTmp.SetAlign( ALIGN_BASELINE ); @@ -2195,3 +2195,8 @@ void WinMtfOutput::Pop() } } +void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile ) +{ + rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF ); +} + diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx index ada590a19675..f3b2482f63bc 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.hxx +++ b/svtools/source/filter.vcl/wmf/winmtf.hxx @@ -672,6 +672,7 @@ class WinMtfOutput void MoveClipRegion( const Size& rSize ); void SetClipPath( const PolyPolygon& rPolyPoly, sal_Int32 nClippingMode, sal_Bool bIsMapped ); void UpdateClipRegion(); + void AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile ); WinMtfOutput( GDIMetaFile& rGDIMetaFile ); virtual ~WinMtfOutput(); @@ -734,6 +735,18 @@ private: UINT16 nUnitsPerInch; sal_uInt32 nRecSize; + // embedded EMF data + SvMemoryStream* pEMFStream; + + // total number of comment records containing EMF data + sal_uInt32 nEMFRecCount; + + // number of EMF records read + sal_uInt32 nEMFRec; + + // total size of embedded EMF data + sal_uInt32 nEMFSize; + sal_uInt32 nSkipActions; sal_uInt32 nCurrentAction; sal_uInt32 nUnicodeEscapeAction; @@ -755,6 +768,8 @@ public: WMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, FilterConfigItem* pConfigItem = NULL ) : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ) {}; + ~WMFReader(); + // Liesst aus dem Stream eine WMF-Datei und fuellt das GDIMetaFile void ReadWMF(); }; diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter.vcl/wmf/winwmf.cxx index 0930b0ece8a8..f9ae46e98e12 100644 --- a/svtools/source/filter.vcl/wmf/winwmf.cxx +++ b/svtools/source/filter.vcl/wmf/winwmf.cxx @@ -32,6 +32,7 @@ #include "precompiled_svtools.hxx" #include "winmtf.hxx" +#include <vcl/gdimtf.hxx> #include <rtl/crc.h> #include <rtl/tencinfo.h> #include <osl/endian.h> @@ -831,81 +832,136 @@ void WMFReader::ReadRecordParams( USHORT nFunc ) pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); break; } - if ( nRecSize >= 12 ) // minimal escape lenght + if ( nRecSize >= 4 ) // minimal escape lenght { - sal_uInt16 nMode, nLen, OO; - sal_uInt32 Magic, nCheck,nEsc; + sal_uInt16 nMode, nLen; *pWMF >> nMode - >> nLen - >> OO - >> Magic - >> nCheck - >> nEsc; - if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 14 ) && ( OO == 0x4f4f ) && ( Magic == 0xa2c2a ) ) + >> nLen; + if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 4 ) ) { - sal_uInt32 nEscLen = nLen - 14; - if ( nEscLen <= ( nRecSize * 2 ) ) + sal_uInt32 nNewMagic; // we have to read int32 for + *pWMF >> nNewMagic; // META_ESCAPE_ENHANCED_METAFILE CommentIdentifier + + if( nNewMagic == 0x2c2a4f4f && nLen >= 14 ) { + sal_uInt16 nMagic2; + *pWMF >> nMagic2; + if( nMagic2 == 0x0a ) // 2nd half of magic + { // continue with private escape + sal_uInt32 nCheck, nEsc; + *pWMF >> nCheck + >> nEsc; + + sal_uInt32 nEscLen = nLen - 14; + if ( nEscLen <= ( nRecSize * 2 ) ) + { #ifdef OSL_BIGENDIAN - sal_uInt32 nTmp = SWAPLONG( nEsc ); - sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 ); + sal_uInt32 nTmp = SWAPLONG( nEsc ); + sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 ); #else - sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 ); + sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 ); #endif - sal_Int8* pData = NULL; + sal_Int8* pData = NULL; - if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos ) - { - pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); - break; - } - if ( nEscLen > 0 ) - { - pData = new sal_Int8[ nEscLen ]; - pWMF->Read( pData, nEscLen ); - nCheckSum = rtl_crc32( nCheckSum, pData, nEscLen ); - } - if ( nCheck == nCheckSum ) - { - switch( nEsc ) - { - case PRIVATE_ESCAPE_UNICODE : - { // we will use text instead of polygons only if we have the correct font - if ( aVDev.IsFontAvailable( pOut->GetFont().GetName() ) ) + if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos ) + { + pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR ); + break; + } + if ( nEscLen > 0 ) + { + pData = new sal_Int8[ nEscLen ]; + pWMF->Read( pData, nEscLen ); + nCheckSum = rtl_crc32( nCheckSum, pData, nEscLen ); + } + if ( nCheck == nCheckSum ) + { + switch( nEsc ) { - Point aPt; - String aString; - sal_uInt32 i, nStringLen, nDXCount; - sal_Int32* pDXAry = NULL; - SvMemoryStream aMemoryStream( nEscLen ); - aMemoryStream.Write( pData, nEscLen ); - aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN ); - aMemoryStream >> aPt.X() - >> aPt.Y() - >> nStringLen; - - if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) ) - { - sal_Unicode* pBuf = aString.AllocBuffer( (xub_StrLen)nStringLen ); - for ( i = 0; i < nStringLen; i++ ) - aMemoryStream >> pBuf[ i ]; - aMemoryStream >> nDXCount; - if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) ) - nDXCount = 0; - if ( nDXCount ) - pDXAry = new sal_Int32[ nDXCount ]; - for ( i = 0; i < nDXCount; i++ ) - aMemoryStream >> pDXAry[ i ]; - aMemoryStream >> nSkipActions; - pOut->DrawText( aPt, aString, pDXAry ); - delete[] pDXAry; + case PRIVATE_ESCAPE_UNICODE : + { // we will use text instead of polygons only if we have the correct font + if ( aVDev.IsFontAvailable( pOut->GetFont().GetName() ) ) + { + Point aPt; + String aString; + sal_uInt32 i, nStringLen, nDXCount; + sal_Int32* pDXAry = NULL; + SvMemoryStream aMemoryStream( nEscLen ); + aMemoryStream.Write( pData, nEscLen ); + aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN ); + aMemoryStream >> aPt.X() + >> aPt.Y() + >> nStringLen; + + if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) ) + { + sal_Unicode* pBuf = aString.AllocBuffer( (xub_StrLen)nStringLen ); + for ( i = 0; i < nStringLen; i++ ) + aMemoryStream >> pBuf[ i ]; + aMemoryStream >> nDXCount; + if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) ) + nDXCount = 0; + if ( nDXCount ) + pDXAry = new sal_Int32[ nDXCount ]; + for ( i = 0; i < nDXCount; i++ ) + aMemoryStream >> pDXAry[ i ]; + aMemoryStream >> nSkipActions; + pOut->DrawText( aPt, aString, pDXAry ); + delete[] pDXAry; + } + } } + break; } } - break; + delete[] pData; + } + } + } + else if ( (nNewMagic == static_cast< sal_uInt32 >(0x43464D57)) && (nLen >= 34) && ( (sal_Int32)(nLen + 10) <= (sal_Int32)(nRecSize * 2) )) + { + sal_uInt32 nComType, nVersion, nFlags, nComRecCount, + nCurRecSize, nRemainingSize, nEMFTotalSize; + sal_uInt16 nCheck; + + *pWMF >> nComType >> nVersion >> nCheck >> nFlags + >> nComRecCount >> nCurRecSize + >> nRemainingSize >> nEMFTotalSize; // the nRemainingSize is not mentioned in MSDN documentation + // but it seems to be required to read in data produced by OLE + + if( nComType == 0x01 && nVersion == 0x10000 && nComRecCount ) + { + if( !nEMFRec ) + { // first EMF comment + nEMFRecCount = nComRecCount; + nEMFSize = nEMFTotalSize; + pEMFStream = new SvMemoryStream( nEMFSize ); + } + else if( ( nEMFRecCount != nComRecCount ) || ( nEMFSize != nEMFTotalSize ) ) // add additional checks here + { + // total records should be the same as in previous comments + nEMFRecCount = 0xFFFFFFFF; + delete pEMFStream; + pEMFStream = NULL; + } + nEMFRec++; + + if( pEMFStream && nCurRecSize + 34 > nLen ) + { + nEMFRecCount = 0xFFFFFFFF; + delete pEMFStream; + pEMFStream = NULL; + } + + if( pEMFStream ) + { + sal_Int8* pBuf = new sal_Int8[ nCurRecSize ]; + sal_uInt32 nCount = pWMF->Read( pBuf, nCurRecSize ); + if( nCount == nCurRecSize ) + pEMFStream->Write( pBuf, nCount ); + delete[] pBuf; } } - delete[] pData; } } } @@ -1023,6 +1079,11 @@ void WMFReader::ReadWMF() nCurrentAction = 0; nUnicodeEscapeAction = 0; + pEMFStream = NULL; + nEMFRecCount = 0; + nEMFRec = 0; + nEMFSize = 0; + pOut->SetMapMode( MM_ANISOTROPIC ); pOut->SetWinOrg( Point() ); pOut->SetWinExt( Size( 1, 1 ) ); @@ -1070,6 +1131,33 @@ void WMFReader::ReadWMF() ReadRecordParams( nFunction ); else nSkipActions--; + + if( pEMFStream && nEMFRecCount == nEMFRec ) + { + GDIMetaFile aMeta; + pEMFStream->Seek( 0 ); + EnhWMFReader* pEMFReader = new EnhWMFReader ( *pEMFStream, aMeta ); + BOOL bRead = pEMFReader->ReadEnhWMF(); + delete pEMFReader; // destroy first!!! + + if( bRead ) + { + pOut->AddFromGDIMetaFile( aMeta ); + pOut->SetrclFrame( Rectangle(0, 0, aMeta.GetPrefSize().Width(), aMeta.GetPrefSize().Height() )); + // we have successfully read the embedded EMF data + // no need to process WMF data further + break; + } + else + { + // something went wrong + // continue with WMF, don't try this again + delete pEMFStream; + pEMFStream = NULL; + } + + } + nPos += nRecSize * 2; if ( nPos <= nEndPos ) pWMF->Seek( nPos ); @@ -1333,3 +1421,9 @@ sal_Bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pSt return bRet; } +WMFReader::~WMFReader() +{ + if( pEMFStream ) + delete pEMFStream; +} + diff --git a/svtools/source/filter.vcl/wmf/wmfwr.cxx b/svtools/source/filter.vcl/wmf/wmfwr.cxx index 30d4ff06c0d2..ba812780d97c 100644 --- a/svtools/source/filter.vcl/wmf/wmfwr.cxx +++ b/svtools/source/filter.vcl/wmf/wmfwr.cxx @@ -34,6 +34,7 @@ #include <vcl/salbtype.hxx> #include "wmfwr.hxx" #include <unotools/fontcvt.hxx> +#include "emfwr.hxx" #include <rtl/crc.h> #include <rtl/tencinfo.h> #include <tools/tenccvt.hxx> @@ -1875,6 +1876,7 @@ BOOL WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream, { WMFWriterAttrStackMember * pAt; + bEmbedEMF = TRUE; bStatus=TRUE; pConvert = 0; pVirDev = new VirtualDevice; @@ -1938,6 +1940,8 @@ BOOL WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream, CountActionsAndBitmaps(rMTF); WriteHeader(rMTF,bPlaceable); + if( bEmbedEMF ) + WriteEmbeddedEMF( rMTF ); WMFRecord_SetWindowOrg(Point(0,0)); WMFRecord_SetWindowExt(rMTF.GetPrefSize()); WMFRecord_SetBkMode( TRUE ); @@ -2016,3 +2020,79 @@ USHORT WMFWriter::CalcSaveTargetMapMode(MapMode& rMapMode, return nDivisor; } + +// ------------------------------------------------------------------------ + +void WMFWriter::WriteEmbeddedEMF( const GDIMetaFile& rMTF ) +{ + EMFWriter aEMFWriter; + SvMemoryStream aStream; + if( aEMFWriter.WriteEMF( rMTF, aStream ) ) + { + aStream.Seek( 0 ); + sal_Size nTotalSize = aStream.GetSize(); + if( nTotalSize > SAL_MAX_UINT32 ) + return; + sal_uInt32 nRemainingSize = static_cast< sal_uInt32 >( nTotalSize ); + sal_uInt32 nRecCounts = ( (nTotalSize - 1) / 0x2000 ) + 1; + sal_uInt16 nCheckSum = 0, nWord; + + sal_uInt32 nPos = 0; + + while( nPos + 1 < nTotalSize ) + { + aStream >> nWord; + nCheckSum ^= nWord; + nPos += 2; + } + + nCheckSum = static_cast< sal_uInt16 >( nCheckSum * -1 ); + + aStream.Seek( 0 ); + while( nRemainingSize > 0 ) + { + sal_uInt32 nCurSize; + if( nRemainingSize > 0x2000 ) + { + nCurSize = 0x2000; + nRemainingSize -= 0x2000; + } + else + { + nCurSize = nRemainingSize; + nRemainingSize = 0; + } + WriteEMFRecord( aStream, + nCurSize, + nRemainingSize, + nTotalSize, + nRecCounts, + nCheckSum ); + nCheckSum = 0; + } + } +} + +// ------------------------------------------------------------------------ + +void WMFWriter::WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize, + sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum ) +{ + // according to http://msdn.microsoft.com/en-us/library/dd366152%28PROT.13%29.aspx + WriteRecordHeader( 0, W_META_ESCAPE ); + *pWMF << (sal_uInt16)W_MFCOMMENT // same as META_ESCAPE_ENHANCED_METAFILE + << (sal_uInt16)( nCurSize + 34 ) // we will always have a 34 byte escape header: + << (sal_uInt32) 0x43464D57 // WMFC + << (sal_uInt32) 0x00000001 // Comment type + << (sal_uInt32) 0x00010000 // version + << nCheckSum // check sum + << (sal_uInt32) 0 // flags = 0 + << nRecCounts // total number of records + << nCurSize // size of this record's data + << nRemainingSize // remaining size of data in following records, missing in MSDN documentation + << nTotalSize; // total size of EMF stream + + pWMF->Write( static_cast< const sal_Char* >( rStream.GetData() ) + rStream.Tell(), nCurSize ); + rStream.SeekRel( nCurSize ); + UpdateRecordHeader(); +} diff --git a/svtools/source/filter.vcl/wmf/wmfwr.hxx b/svtools/source/filter.vcl/wmf/wmfwr.hxx index 03ca14e7633f..6b2ff0b04e0a 100644 --- a/svtools/source/filter.vcl/wmf/wmfwr.hxx +++ b/svtools/source/filter.vcl/wmf/wmfwr.hxx @@ -131,6 +131,8 @@ private: ULONG nWrittenBitmaps; // Anzahl der bereits geschriebenen Bitmaps ULONG nActBitmapPercent; // Wieviel Prozent die naechste Bitmap schon geschrieben ist. + BOOL bEmbedEMF; // optionally embedd EMF data into WMF + void MayCallback(); // Berechnet anhand der obigen 5 Parameter eine Prozentzahl // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen @@ -211,6 +213,13 @@ private: void WriteHeader(const GDIMetaFile & rMTF, BOOL bPlaceable); void UpdateHeader(); + void WriteEmbeddedEMF( const GDIMetaFile& rMTF ); + void WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, + sal_uInt32 nRemainingSize, + sal_uInt32 nTotalSize, + sal_uInt32 nRecCounts, + sal_uInt16 nCheckSum ); + USHORT CalcSaveTargetMapMode(MapMode& rMapMode, const Size& rPrefSize); public: diff --git a/svtools/source/misc/ehdl.cxx b/svtools/source/misc/ehdl.cxx index 4084aa47bc80..3a31c1b812a6 100644 --- a/svtools/source/misc/ehdl.cxx +++ b/svtools/source/misc/ehdl.cxx @@ -321,16 +321,21 @@ BOOL SfxErrorHandler::GetClassString(ULONG lClassId, String &rStr) const */ { - - ResId aId(RID_ERRHDL, *pMgr); - ErrorResource_Impl aEr(aId, (USHORT)lClassId); - if(aEr) + BOOL bRet = FALSE; + com::sun::star::lang::Locale aLocale( Application::GetSettings().GetUILocale() ); + ResMgr* pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale ); + if( pResMgr ) { - rStr=((ResString)aEr).GetString(); - return TRUE; + ResId aId(RID_ERRHDL, *pResMgr ); + ErrorResource_Impl aEr(aId, (USHORT)lClassId); + if(aEr) + { + rStr=((ResString)aEr).GetString(); + bRet = TRUE; + } } - else - return FALSE; + delete pResMgr; + return bRet; } //------------------------------------------------------------------------- @@ -379,10 +384,10 @@ BOOL SfxErrorHandler::GetErrorString( BOOL bRet = FALSE; rStr=String(SvtResId(RID_ERRHDL_CLASS)); - ResId *pResId = new ResId(nId, *pMgr); + ResId aResId(nId, *pMgr); { - ErrorResource_Impl aEr(*pResId, (USHORT)lErrId); + ErrorResource_Impl aEr(aResId, (USHORT)lErrId); if(aEr) { ResString aErrorString(aEr); @@ -408,7 +413,6 @@ BOOL SfxErrorHandler::GetErrorString( rStr.SearchAndReplace(String::CreateFromAscii( "$(CLASS)" ),aErrStr); } - delete pResId; return bRet; } |