From ac9fbf25dad680195005524902daeb5d48dc6c28 Mon Sep 17 00:00:00 2001 From: Florian Reuter Date: Wed, 4 May 2011 11:39:43 +0200 Subject: external-apm-header.diff: fix WMF scaling in RTF import, n#417818 --- svtools/inc/svtools/filter.hxx | 7 +++++-- svtools/inc/svtools/wmf.hxx | 25 ++++++++++++++++++++++- svtools/source/filter.vcl/filter/exportdialog.cxx | 2 +- svtools/source/filter.vcl/filter/filter.cxx | 9 ++++---- svtools/source/filter.vcl/wmf/winmtf.hxx | 5 +++-- svtools/source/filter.vcl/wmf/winwmf.cxx | 22 +++++++++++++------- svtools/source/filter.vcl/wmf/wmf.cxx | 4 ++-- 7 files changed, 55 insertions(+), 19 deletions(-) diff --git a/svtools/inc/svtools/filter.hxx b/svtools/inc/svtools/filter.hxx index 4380eb3605..256e934884 100644 --- a/svtools/inc/svtools/filter.hxx +++ b/svtools/inc/svtools/filter.hxx @@ -39,6 +39,7 @@ #include #include +struct WMF_APMFILEHEADER; // ----------------------- // - GraphicFilter-Types - // ----------------------- @@ -341,13 +342,15 @@ public: sal_uInt16 ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rStream, sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW, - sal_uInt16 * pDeterminedFormat = NULL, sal_uInt32 nImportFlags = 0 ); + sal_uInt16 * pDeterminedFormat = NULL, sal_uInt32 nImportFlags = 0, + WMF_APMFILEHEADER *pAPMHeader = NULL ); sal_uInt16 ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rStream, sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, sal_uInt32 nImportFlags, - com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData ); + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData, + WMF_APMFILEHEADER *pAPMHeader = NULL ); sal_Bool Setup( sal_uInt16 nFormat ); diff --git a/svtools/inc/svtools/wmf.hxx b/svtools/inc/svtools/wmf.hxx index ef0cbaf5a5..335e17859a 100644 --- a/svtools/inc/svtools/wmf.hxx +++ b/svtools/inc/svtools/wmf.hxx @@ -32,7 +32,30 @@ #include "svtools/svtdllapi.h" #include -sal_Bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem = NULL ); +struct WMF_APMFILEHEADER { + sal_uInt32 key; + sal_uInt16 hmf; + sal_uInt16 left; + sal_uInt16 top; + sal_uInt16 right; + sal_uInt16 bottom; + sal_uInt16 inch; + sal_uInt32 reserved; + sal_uInt16 checksum; + + WMF_APMFILEHEADER() : key(0x9ac6cdd7L), + hmf(0), + left(0), + top(0), + right(0), + bottom(0), + inch(96), + reserved(0), + checksum(0) { + } +}; + +sal_Bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem = NULL, WMF_APMFILEHEADER *pAPMHeader = NULL ); SVT_DLLPUBLIC sal_Bool ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF, FilterConfigItem* pConfigItem ); diff --git a/svtools/source/filter.vcl/filter/exportdialog.cxx b/svtools/source/filter.vcl/filter/exportdialog.cxx index 860f0657d1..37e091ece1 100644 --- a/svtools/source/filter.vcl/filter/exportdialog.cxx +++ b/svtools/source/filter.vcl/filter/exportdialog.cxx @@ -522,7 +522,7 @@ Bitmap ExportDialog::GetGraphicBitmap( SvStream& rInputStream ) Bitmap aRet; Graphic aGraphic; GraphicFilter aFilter( sal_False ); - if ( aFilter.ImportGraphic( aGraphic, String(), rInputStream, GRFILTER_FORMAT_NOTFOUND, NULL, 0, NULL ) == GRFILTER_OK ) + if ( aFilter.ImportGraphic( aGraphic, String(), rInputStream, GRFILTER_FORMAT_NOTFOUND, NULL, 0, NULL, NULL ) == GRFILTER_OK ) { aRet = aGraphic.GetBitmap(); } diff --git a/svtools/source/filter.vcl/filter/filter.cxx b/svtools/source/filter.vcl/filter/filter.cxx index 211ea6b4b1..14832b29bf 100644 --- a/svtools/source/filter.vcl/filter/filter.cxx +++ b/svtools/source/filter.vcl/filter/filter.cxx @@ -1304,16 +1304,17 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& } sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream, - sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags ) + sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags, WMF_APMFILEHEADER *pAPMHeader ) { - return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL ); + return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL, pAPMHeader ); } //------------------------------------------------------------------------- sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags, - com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData ) + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData, + WMF_APMFILEHEADER *pAPMHeader ) { String aFilterName; sal_uLong nStmBegin; @@ -1510,7 +1511,7 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) ) { GDIMetaFile aMtf; - if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL ) ) + if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL, pAPMHeader ) ) nStatus = GRFILTER_FORMATERROR; else { diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx index 0db1d65672..76dcfd676e 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.hxx +++ b/svtools/source/filter.vcl/wmf/winmtf.hxx @@ -157,6 +157,7 @@ struct LOGFONTW sal_uInt8 lfPitchAndFamily; String alfFaceName; }; +struct WMF_APMFILEHEADER; #define TA_NOUPDATECP 0x0000 #define TA_UPDATECP 0x0001 @@ -767,7 +768,7 @@ private: sal_uInt32 nUnicodeEscapeAction; // Liesst den Kopf der WMF-Datei - sal_Bool ReadHeader(); + sal_Bool ReadHeader(WMF_APMFILEHEADER *pAPMHeader); // Liesst die Parameter des Rocords mit der Funktionsnummer nFunction. void ReadRecordParams( sal_uInt16 nFunction ); @@ -788,7 +789,7 @@ public: ~WMFReader(); // Liesst aus dem Stream eine WMF-Datei und fuellt das GDIMetaFile - void ReadWMF(); + void ReadWMF(WMF_APMFILEHEADER *pAPMHeader=NULL); }; #endif diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter.vcl/wmf/winwmf.cxx index 00bcd95c99..c5326335e3 100644 --- a/svtools/source/filter.vcl/wmf/winwmf.cxx +++ b/svtools/source/filter.vcl/wmf/winwmf.cxx @@ -31,6 +31,7 @@ #include "winmtf.hxx" #include +#include #include #include #include @@ -997,7 +998,7 @@ void WMFReader::ReadRecordParams( sal_uInt16 nFunc ) // ------------------------------------------------------------------------ -sal_Bool WMFReader::ReadHeader() +sal_Bool WMFReader::ReadHeader(WMF_APMFILEHEADER *pAPMHeader) { Rectangle aPlaceableBound; sal_uInt32 nl, nStrmPos = pWMF->Tell(); @@ -1030,10 +1031,17 @@ sal_Bool WMFReader::ReadHeader() } else { - nUnitsPerInch = 96; - pWMF->Seek( nStrmPos + 18 ); // set the streampos to the start of the the metaactions - GetPlaceableBound( aPlaceableBound, pWMF ); - pWMF->Seek( nStrmPos ); + nUnitsPerInch = (pAPMHeader!=NULL?pAPMHeader->inch:96); + pWMF->Seek( nStrmPos + 18 ); // set the streampos to the start of the the metaactions + GetPlaceableBound( aPlaceableBound, pWMF ); + pWMF->Seek( nStrmPos ); + if (pAPMHeader!=NULL) { + // #n417818#: If we have an external header then overwrite the bounds! + aPlaceableBound=Rectangle(pAPMHeader->left*567*nUnitsPerInch/1440/1000, + pAPMHeader->top*567*nUnitsPerInch/1440/1000, + pAPMHeader->right*567*nUnitsPerInch/1440/1000, + pAPMHeader->bottom*567*nUnitsPerInch/1440/1000); + } } pOut->SetWinOrg( aPlaceableBound.TopLeft() ); @@ -1068,7 +1076,7 @@ sal_Bool WMFReader::ReadHeader() return sal_True; } -void WMFReader::ReadWMF() +void WMFReader::ReadWMF(WMF_APMFILEHEADER *pAPMHeader) { sal_uInt16 nFunction; sal_uLong nPos, nPercent, nLastPercent; @@ -1093,7 +1101,7 @@ void WMFReader::ReadWMF() pWMF->Seek( nStartPos ); Callback( (sal_uInt16) ( nLastPercent = 0 ) ); - if ( ReadHeader() ) + if ( ReadHeader( pAPMHeader ) ) { nPos = pWMF->Tell(); diff --git a/svtools/source/filter.vcl/wmf/wmf.cxx b/svtools/source/filter.vcl/wmf/wmf.cxx index 256b2e2bf6..c65c691263 100644 --- a/svtools/source/filter.vcl/wmf/wmf.cxx +++ b/svtools/source/filter.vcl/wmf/wmf.cxx @@ -36,7 +36,7 @@ // ----------------------------------------------------------------------------- -sal_Bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem ) +sal_Bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem, WMF_APMFILEHEADER *pAPMHeader ) { sal_uInt32 nMetaType; sal_uInt32 nOrgPos = rStreamWMF.Tell(); @@ -52,7 +52,7 @@ sal_Bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaF } else { - WMFReader( rStreamWMF, rGDIMetaFile, pConfigItem ).ReadWMF(); + WMFReader( rStreamWMF, rGDIMetaFile, pConfigItem ).ReadWMF( pAPMHeader ); } rStreamWMF.SetNumberFormatInt( nOrigNumberFormat ); return !rStreamWMF.GetError(); -- cgit v1.2.3