drawinglayer/source/primitive2d/metafileprimitive2d.cxx | 7 emfio/inc/wmfreader.hxx | 8 emfio/source/emfuno/xemfparser.cxx | 161 - emfio/source/reader/mtftools.cxx | 3 emfio/source/reader/wmfreader.cxx | 54 include/drawinglayer/primitive2d/metafileprimitive2d.hxx | 6 include/oox/helper/graphichelper.hxx | 8 include/vcl/gdimetafiletools.hxx | 9 include/vcl/graphicfilter.hxx | 6 include/vcl/vectorgraphicdata.hxx | 11 include/vcl/wmf.hxx | 33 include/vcl/wmfexternal.hxx | 55 offapi/com/sun/star/graphic/XEmfParser.idl | 8 oox/source/drawingml/shape.cxx | 2 oox/source/helper/graphichelper.cxx | 6 oox/source/vml/vmlshape.cxx | 2 svtools/source/graphic/provider.cxx | 4 vcl/Library_vcl.mk | 4 vcl/qa/cppunit/wmf/wmfimporttest.cxx | 1 vcl/source/filter/graphicfilter.cxx | 72 vcl/source/filter/wmf/enhwmf.cxx | 1966 ------------- vcl/source/filter/wmf/winmtf.cxx | 2248 --------------- vcl/source/filter/wmf/winmtf.hxx | 723 ---- vcl/source/filter/wmf/winwmf.cxx | 1836 ------------ vcl/source/filter/wmf/wmf.cxx | 73 vcl/source/filter/wmf/wmfexternal.cxx | 76 vcl/source/gdi/impgraph.cxx | 27 vcl/source/gdi/vectorgraphicdata.cxx | 32 writerfilter/source/rtftok/rtfdocumentimpl.cxx | 4 xmlsecurity/workben/pdfverify.cxx | 2 30 files changed, 408 insertions(+), 7039 deletions(-)
New commits: commit e76f931777616c10660ef11d3b348efb3107a23b Author: Armin Le Grand <[email protected]> Date: Fri Jun 16 17:16:22 2017 +0200 emfplus: completed isolation/migration of Emf/Wmf Decided to keep the migrated/isolated Emf/Wmf reader which are now hidden behind a Uno Api. Had to re-implement WMF_EXTERNALHEADER (now WmfExternal, own file/header) to not break anything. It *seems* to just scale something and could be done after import, but I could not be sure. Also needed a callback hook to allow getting the Metafile out of a MetafilePrimitive in a lower module (vcl relative to drawinglayer) which is needed as long as primitives are not completely on Uno Api. Deleted all Emf/Wmf reader stuff from vcl. Change-Id: Ic5540defa8ec770728280df4df3f12e1f48cfc3a diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx index e07033aa50d5..4737f78c765b 100644 --- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx @@ -3244,6 +3244,13 @@ namespace drawinglayer return aRetval; } + // from MetafileAccessor + bool MetafilePrimitive2D::accessMetafile(GDIMetaFile& rTargetMetafile) const + { + rTargetMetafile = maMetaFile; + return true; + } + // provide unique ID ImplPrimitive2DIDBlock(MetafilePrimitive2D, PRIMITIVE2D_ID_METAFILEPRIMITIVE2D) diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx index e0566bb95cfb..1cd6077b05d8 100644 --- a/emfio/inc/wmfreader.hxx +++ b/emfio/inc/wmfreader.hxx @@ -23,6 +23,9 @@ #include <mtftools.hxx> #include <tools/stream.hxx> +// predefines +struct WmfExternal; + namespace emfio { class WmfReader : public MtfTools @@ -46,6 +49,9 @@ namespace emfio sal_uInt32 mnSkipActions; sal_uInt32 mnCurrentAction; + // eventually handed over external header + const WmfExternal* mpExternalHeader; + // reads header of the WMF-Datei bool ReadHeader(); @@ -59,7 +65,7 @@ namespace emfio void GetPlaceableBound(tools::Rectangle& rSize, SvStream* pStrm); public: - WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile); + WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader); // read WMF file from stream and fill the GDIMetaFile void ReadWMF(); diff --git a/emfio/source/emfuno/xemfparser.cxx b/emfio/source/emfuno/xemfparser.cxx index 89d34dff1521..433210c5ecd2 100644 --- a/emfio/source/emfuno/xemfparser.cxx +++ b/emfio/source/emfuno/xemfparser.cxx @@ -33,7 +33,6 @@ #include <vcl/svapp.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> -#include <vcl/wmf.hxx> #include <unotools/ucbstreamhelper.hxx> #include <drawinglayer/primitive2d/metafileprimitive2d.hxx> @@ -69,7 +68,8 @@ namespace emfio // XEmfParser virtual uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > SAL_CALL getDecomposition( const uno::Reference< ::io::XInputStream >& xEmfStream, - const OUString& aAbsolutePath) override; + const OUString& aAbsolutePath, + const uno::Sequence< ::beans::PropertyValue >& rProperties) override; // XServiceInfo virtual OUString SAL_CALL getImplementationName() override; @@ -113,114 +113,85 @@ namespace emfio uno::Sequence< uno::Reference< ::graphic::XPrimitive2D > > XEmfParser::getDecomposition( const uno::Reference< ::io::XInputStream >& xEmfStream, - const OUString& aAbsolutePath ) + const OUString& aAbsolutePath, + const uno::Sequence< ::beans::PropertyValue >& rProperties) { drawinglayer::primitive2d::Primitive2DContainer aRetval; if (xEmfStream.is()) { - static bool bTestCode(false); + WmfExternal aExternalHeader; + const bool bExternalHeaderUsed(aExternalHeader.setSequence(rProperties)); - if (bTestCode) + // rough check - import and conv to primitive + GDIMetaFile aMtf; + std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream)); + sal_uInt32 nMetaType(0); + sal_uInt32 nOrgPos = pStream->Tell(); + + SvStreamEndian nOrigNumberFormat = pStream->GetEndian(); + pStream->SetEndian(SvStreamEndian::LITTLE); + + pStream->Seek(0x28); + pStream->ReadUInt32(nMetaType); + pStream->Seek(nOrgPos); + + if (nMetaType == 0x464d4520) + { + emfio::EmfReader(*pStream, aMtf).ReadEnhWMF(); + } + else + { + emfio::WmfReader(*pStream, aMtf, bExternalHeaderUsed ? &aExternalHeader : nullptr).ReadWMF(); + } + + pStream->SetEndian(nOrigNumberFormat); + Size aSize(aMtf.GetPrefSize()); + + if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel) { - static bool bUseOldFilterEmbedded(true); - - if (bUseOldFilterEmbedded) - { - GDIMetaFile aMtf; - std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream)); - - if (pStream && ConvertWMFToGDIMetaFile(*pStream, aMtf, nullptr, nullptr)) - { - - Size aSize(aMtf.GetPrefSize()); - - if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel) - { - aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM); - } - else - { - aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)); - } - - const basegfx::B2DHomMatrix aMetafileTransform( - basegfx::tools::createScaleB2DHomMatrix( - aSize.Width(), - aSize.Height())); - - aRetval.push_back( - new drawinglayer::primitive2d::MetafilePrimitive2D( - aMetafileTransform, - aMtf)); - } - } - - if(aRetval.empty()) - { - // for test, just create some graphic data that will get visualized - const basegfx::B2DRange aRange(1000, 1000, 5000, 5000); - const basegfx::BColor aColor(1.0, 0.0, 0.0); - const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange)); - - aRetval.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aColor)); - } + aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM); } else { - // new parser here - bool bBla = true; - - // rouch check - import and conv to primitive - GDIMetaFile aMtf; - std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream(xEmfStream)); - sal_uInt32 nMetaType(0); - sal_uInt32 nOrgPos = pStream->Tell(); - - SvStreamEndian nOrigNumberFormat = pStream->GetEndian(); - pStream->SetEndian(SvStreamEndian::LITTLE); - - pStream->Seek(0x28); - pStream->ReadUInt32(nMetaType); - pStream->Seek(nOrgPos); - - if (nMetaType == 0x464d4520) - { - emfio::EmfReader(*pStream, aMtf).ReadEnhWMF(); - } - else - { - emfio::WmfReader(*pStream, aMtf).ReadWMF(); - } - - pStream->SetEndian(nOrigNumberFormat); - Size aSize(aMtf.GetPrefSize()); - - if (aMtf.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel) - { - aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, MapUnit::Map100thMM); - } - else - { - aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)); - } - - const basegfx::B2DHomMatrix aMetafileTransform( - basegfx::tools::createScaleB2DHomMatrix( - aSize.Width(), - aSize.Height())); - - // force to use decomposition directly to get rid of the metafile - const css::uno::Sequence< css::beans::PropertyValue > aViewParameters; - drawinglayer::primitive2d::MetafilePrimitive2D aMetafilePrimitive2D( + aSize = OutputDevice::LogicToLogic(aSize, aMtf.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)); + } + + // use size + const basegfx::B2DHomMatrix aMetafileTransform( + basegfx::tools::createScaleB2DHomMatrix( + aSize.Width(), + aSize.Height())); + + // ...and create a single MetafilePrimitive2D containing the Metafile. + // CAUTION: Currently, ReadWindowMetafile uses the local VectorGraphicData + // and a MetafileAccessor hook at the MetafilePrimitive2D inside of + // ImpGraphic::ImplGetGDIMetaFile to get the Metafile. Thus, the first + // and only primitive in this case *has to be* a MetafilePrimitive2D. + aRetval.push_back( + new drawinglayer::primitive2d::MetafilePrimitive2D( aMetafileTransform, - aMtf); - aRetval.append(aMetafilePrimitive2D.getDecomposition(aViewParameters)); + aMtf)); + // // force to use decomposition directly to get rid of the metafile + // const css::uno::Sequence< css::beans::PropertyValue > aViewParameters; + // drawinglayer::primitive2d::MetafilePrimitive2D aMetafilePrimitive2D( + // aMetafileTransform, + // aMtf); + // aRetval.append(aMetafilePrimitive2D.getDecomposition(aViewParameters)); + + // if (aRetval.empty()) + // { + // // for test, just create some graphic data that will get visualized + // const basegfx::B2DRange aRange(1000, 1000, 5000, 5000); + // const basegfx::BColor aColor(1.0, 0.0, 0.0); + // const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aRange)); + // + // aRetval.push_back(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aColor)); + // } - } } else { diff --git a/emfio/source/reader/mtftools.cxx b/emfio/source/reader/mtftools.cxx index 96d4d5232e7e..05b8cf43bed0 100644 --- a/emfio/source/reader/mtftools.cxx +++ b/emfio/source/reader/mtftools.cxx @@ -20,13 +20,10 @@ #include <mtftools.hxx> #include <memory> -//#include "winmtf.hxx" #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> -//#include <vcl/metaact.hxx> #include <vcl/graphictools.hxx> #include <vcl/canvastools.hxx> -//#include <vcl/metric.hxx> #include <vcl/svapp.hxx> #include <tools/fract.hxx> #include <rtl/strbuf.hxx> diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx index dd41a7a1abbb..9cbe518d7e28 100644 --- a/emfio/source/reader/wmfreader.cxx +++ b/emfio/source/reader/wmfreader.cxx @@ -1242,26 +1242,45 @@ namespace emfio { mnUnitsPerInch = 96; + if (mpExternalHeader != nullptr + && mpExternalHeader->xExt > 0 + && mpExternalHeader->yExt > 0 + && (mpExternalHeader->mapMode == MM_ISOTROPIC || mpExternalHeader->mapMode == MM_ANISOTROPIC)) + { + // #n417818#: If we have an external header then overwrite the bounds! + tools::Rectangle aExtRect(0, 0, + (double)mpExternalHeader->xExt * 567 * mnUnitsPerInch / 1440000, + (double)mpExternalHeader->yExt * 567 * mnUnitsPerInch / 1440000); + aPlaceableBound = aExtRect; + + SAL_INFO("vcl.wmf", "External header size " + " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top() + << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom()); - mpInputStream->Seek( nStrmPos + 18 ); // set the streampos to the start of the metaactions - GetPlaceableBound( aPlaceableBound, mpInputStream ); - - // The image size is not known so normalize the calculated bounds so that the - // resulting image is not too big - const double fMaxWidth = static_cast<double>(aMaxWidth); - if (aPlaceableBound.GetWidth() > aMaxWidth) + SetMapMode(mpExternalHeader->mapMode); + } + else { - double fRatio = aPlaceableBound.GetWidth() / fMaxWidth; + mpInputStream->Seek(nStrmPos + 18); // set the streampos to the start of the metaactions + GetPlaceableBound(aPlaceableBound, mpInputStream); - aPlaceableBound = tools::Rectangle( - aPlaceableBound.Left() / fRatio, - aPlaceableBound.Top() / fRatio, - aPlaceableBound.Right() / fRatio, - aPlaceableBound.Bottom() / fRatio); + // The image size is not known so normalize the calculated bounds so that the + // resulting image is not too big + const double fMaxWidth = static_cast<double>(aMaxWidth); + if (aPlaceableBound.GetWidth() > aMaxWidth) + { + double fRatio = aPlaceableBound.GetWidth() / fMaxWidth; - SAL_INFO("vcl.wmf", "Placeable bounds " - " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top() - << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom()); + aPlaceableBound = tools::Rectangle( + aPlaceableBound.Left() / fRatio, + aPlaceableBound.Top() / fRatio, + aPlaceableBound.Right() / fRatio, + aPlaceableBound.Bottom() / fRatio); + + SAL_INFO("vcl.wmf", "Placeable bounds " + " t: " << aPlaceableBound.Left() << " l: " << aPlaceableBound.Top() + << " b: " << aPlaceableBound.Right() << " r: " << aPlaceableBound.Bottom()); + } } mpInputStream->Seek( nStrmPos ); @@ -1800,7 +1819,7 @@ namespace emfio } } - WmfReader::WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile) + WmfReader::WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader) : MtfTools(rGDIMetaFile, rStreamWMF) , mnUnitsPerInch(96) , mnRecSize(0) @@ -1810,6 +1829,7 @@ namespace emfio , mnEMFSize(0) , mnSkipActions(0) , mnCurrentAction(0) + , mpExternalHeader(pExternalHeader) { } } diff --git a/include/drawinglayer/primitive2d/metafileprimitive2d.hxx b/include/drawinglayer/primitive2d/metafileprimitive2d.hxx index 0d1503809a81..e849e38b5752 100644 --- a/include/drawinglayer/primitive2d/metafileprimitive2d.hxx +++ b/include/drawinglayer/primitive2d/metafileprimitive2d.hxx @@ -25,6 +25,7 @@ #include <drawinglayer/primitive2d/baseprimitive2d.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <vcl/gdimtf.hxx> +#include <vcl/gdimetafiletools.hxx> // MetafilePrimitive2D class @@ -53,7 +54,7 @@ namespace drawinglayer have many advantages; Metafile would no longer have to be rendered by sub-systems and a standard way for converting Metafiles would exist. */ - class DRAWINGLAYER_DLLPUBLIC MetafilePrimitive2D : public BufferedDecompositionPrimitive2D + class DRAWINGLAYER_DLLPUBLIC MetafilePrimitive2D : public BufferedDecompositionPrimitive2D, public MetafileAccessor { private: /// the geometry definition @@ -81,6 +82,9 @@ namespace drawinglayer /// get range virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override; + /// from MetafileAccessor + virtual bool accessMetafile(GDIMetaFile& rTargetMetafile) const; + /// provide unique ID DeclPrimitive2DIDBlock() }; diff --git a/include/oox/helper/graphichelper.hxx b/include/oox/helper/graphichelper.hxx index 651e9407b4ec..545bdd0fd938 100644 --- a/include/oox/helper/graphichelper.hxx +++ b/include/oox/helper/graphichelper.hxx @@ -33,7 +33,7 @@ #include <sal/types.h> #include <com/sun/star/graphic/XGraphicProvider2.hpp> -struct WMF_EXTERNALHEADER; +struct WmfExternal; namespace com { namespace sun { namespace star { namespace awt { struct Point; } @@ -113,7 +113,7 @@ public: css::uno::Reference< css::graphic::XGraphic > importGraphic( const css::uno::Reference< css::io::XInputStream >& rxInStrm, - const WMF_EXTERNALHEADER* pExtHeader = nullptr ) const; + const WmfExternal* pExtHeader = nullptr ) const; /** Imports graphics from the passed input streams. */ std::vector< css::uno::Reference<css::graphic::XGraphic> > @@ -127,7 +127,7 @@ public: css::uno::Reference< css::graphic::XGraphic > importEmbeddedGraphic( const OUString& rStreamName, - const WMF_EXTERNALHEADER* pExtHeader = nullptr ) const; + const WmfExternal* pExtHeader = nullptr ) const; /** Imports graphics from the storage with the passed stream names. */ void importEmbeddedGraphics(const std::vector<OUString>& rStreamNames) const; @@ -141,7 +141,7 @@ public: @return The URL of the created and internally cached graphic object. */ OUString importGraphicObject( const css::uno::Reference< css::io::XInputStream >& rxInStrm, - const WMF_EXTERNALHEADER* pExtHeader ) const; + const WmfExternal* pExtHeader ) const; /** Creates a persistent graphic object from the passed binary memory block. @return The URL of the created and internally cached graphic object. */ diff --git a/include/vcl/gdimetafiletools.hxx b/include/vcl/gdimetafiletools.hxx index 592c70714bfd..ea47ced5032e 100644 --- a/include/vcl/gdimetafiletools.hxx +++ b/include/vcl/gdimetafiletools.hxx @@ -39,6 +39,15 @@ void VCL_DLLPUBLIC clipMetafileContentAgainstOwnRegions(GDIMetaFile& rSource); bool VCL_DLLPUBLIC usesClipActions(const GDIMetaFile& rSource); +// hook to access metafile members in classes of modules above vcl. Currently +// used in MetafilePrimitive2D to be able to access the local Metafile member +// e.g. from vcl module +class VCL_DLLPUBLIC MetafileAccessor +{ +public: + virtual bool accessMetafile(GDIMetaFile& rTargetMetafile) const = 0; +}; + #endif // INCLUDED_VCL_GDIMETAFILETOOLS_HXX diff --git a/include/vcl/graphicfilter.hxx b/include/vcl/graphicfilter.hxx index 01b6e07f58d0..73adc2013e0b 100644 --- a/include/vcl/graphicfilter.hxx +++ b/include/vcl/graphicfilter.hxx @@ -33,7 +33,7 @@ class FilterConfigCache; class SvStream; -struct WMF_EXTERNALHEADER; +struct WmfExternal; struct ConvertData; #define ERRCODE_GRFILTER_OPENERROR (ERRCODE_AREA_VCL | ERRCODE_CLASS_GENERAL | 1) @@ -281,7 +281,7 @@ public: SvStream& rStream, sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW, sal_uInt16 * pDeterminedFormat = nullptr, GraphicFilterImportFlags nImportFlags = GraphicFilterImportFlags::NONE, - WMF_EXTERNALHEADER *pExtHeader = nullptr ); + WmfExternal *pExtHeader = nullptr ); /// Imports multiple graphics. /// @@ -293,7 +293,7 @@ public: sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, GraphicFilterImportFlags nImportFlags, css::uno::Sequence< css::beans::PropertyValue >* pFilterData, - WMF_EXTERNALHEADER *pExtHeader = nullptr ); + WmfExternal *pExtHeader = nullptr ); const FilterErrorEx& GetLastError() const { return *pErrorEx;} void ResetLastError(); diff --git a/include/vcl/vectorgraphicdata.hxx b/include/vcl/vectorgraphicdata.hxx index 6a259a5567e3..a045b01ee46e 100644 --- a/include/vcl/vectorgraphicdata.hxx +++ b/include/vcl/vectorgraphicdata.hxx @@ -23,6 +23,7 @@ #include <basegfx/range/b2drange.hxx> #include <com/sun/star/graphic/XPrimitive2D.hpp> #include <vcl/bitmapex.hxx> +#include <vcl/wmfexternal.hxx> #include <rtl/ustring.hxx> #include <deque> @@ -57,12 +58,14 @@ private: // on demand created content basegfx::B2DRange maRange; - std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > - maSequence; + std::deque< css::uno::Reference< css::graphic::XPrimitive2D > > maSequence; BitmapEx maReplacement; size_t mNestedBitmapSize; VectorGraphicDataType meVectorGraphicDataType; + // extra: + WmfExternal* mpExternalHeader; + // on demand creators void ensureReplacement(); void ensureSequenceAndRange(); @@ -78,10 +81,14 @@ public: VectorGraphicData( const OUString& rPath, VectorGraphicDataType eVectorDataType); + ~VectorGraphicData(); /// compare op bool operator==(const VectorGraphicData& rCandidate) const; + /// special: needed for emf/wmf, maybe replaced by scaling the result later (?) + void setWmfExternalHeader(const WmfExternal& aExtHeader); + /// data read const VectorGraphicDataArray& getVectorGraphicDataArray() const { return maVectorGraphicDataArray; } sal_uInt32 getVectorGraphicDataArrayLength() const { return maVectorGraphicDataArray.getLength(); } diff --git a/include/vcl/wmf.hxx b/include/vcl/wmf.hxx index 67d6aa4f122b..c172cd45e86b 100644 --- a/include/vcl/wmf.hxx +++ b/include/vcl/wmf.hxx @@ -25,38 +25,7 @@ class FilterConfigItem; class GDIMetaFile; class SvStream; - -struct WMF_EXTERNALHEADER -{ - sal_uInt16 xExt; - sal_uInt16 yExt; - - /** One of the following values: - <ul> - <li>MM_TEXT</li> - <li>MM_LOMETRIC</li> - <li>MM_HIMETRIC</li> - <li>MM_LOENGLISH</li> - <li>MM_HIENGLISH</li> - <li>MM_TWIPS</li> - <li>MM_ISOTROPIC</li> - <li>MM_ANISOTROPIC</li> - </ul> - If this value is 0, then no external mapmode has been defined, - the internal one should then be used. - */ - sal_uInt16 mapMode; - - WMF_EXTERNALHEADER() : - xExt( 0 ), - yExt( 0 ), - mapMode( 0 ) - { - } -}; - -// for 1st test, export -VCL_DLLPUBLIC bool ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, FilterConfigItem* pConfigItem, WMF_EXTERNALHEADER *pExtHeader ); +struct WmfExternal; VCL_DLLPUBLIC bool ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF ); diff --git a/include/vcl/wmfexternal.hxx b/include/vcl/wmfexternal.hxx new file mode 100644 index 000000000000..30c58ab0bcb0 --- /dev/null +++ b/include/vcl/wmfexternal.hxx @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_WMFEXTERNAL_HXX +#define INCLUDED_VCL_WMFEXTERNAL_HXX + +#include <vcl/dllapi.h> +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> + +struct VCL_DLLPUBLIC WmfExternal +{ + sal_uInt16 xExt; + sal_uInt16 yExt; + + /** One of the following values: + <ul> + <li>MM_TEXT</li> + <li>MM_LOMETRIC</li> + <li>MM_HIMETRIC</li> + <li>MM_LOENGLISH</li> + <li>MM_HIENGLISH</li> + <li>MM_TWIPS</li> + <li>MM_ISOTROPIC</li> + <li>MM_ANISOTROPIC</li> + </ul> + If this value is 0, then no external mapmode has been defined, + the internal one should then be used. + */ + sal_uInt16 mapMode; + + WmfExternal(); + css::uno::Sequence< css::beans::PropertyValue > getSequence() const; + bool setSequence(const css::uno::Sequence< css::beans::PropertyValue >& rSequence); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/offapi/com/sun/star/graphic/XEmfParser.idl b/offapi/com/sun/star/graphic/XEmfParser.idl index 6c55a8a0b963..42cb2cbe6459 100644 --- a/offapi/com/sun/star/graphic/XEmfParser.idl +++ b/offapi/com/sun/star/graphic/XEmfParser.idl @@ -41,10 +41,14 @@ interface XEmfParser : ::com::sun::star::uno::XInterface @param aAbsolutePath The path containing the WMF/EMF/EMF+ data - */ + + @param Properties + Optional values to override MapMode and size +*/ sequence< XPrimitive2D > getDecomposition( [in] io::XInputStream xEmfStream, - [in] string aAbsolutePath); + [in] string aAbsolutePath, + [in] ::com::sun::star::beans::PropertyValues Properties); }; }; }; }; }; diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 7d04518b5f25..72927d116cd0 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1291,7 +1291,7 @@ OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rSe if( !aGraphicPath.isEmpty() ) { // Transfer shape's width and height to graphicsfilter (can be used by WMF/EMF) - WMF_EXTERNALHEADER aExtHeader; + WmfExternal aExtHeader; aExtHeader.mapMode = 8; // MM_ANISOTROPIC aExtHeader.xExt = rShapeRect.Width; aExtHeader.yExt = rShapeRect.Height; diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx index 30c570b01eec..6c150729a589 100644 --- a/oox/source/helper/graphichelper.cxx +++ b/oox/source/helper/graphichelper.cxx @@ -234,7 +234,7 @@ awt::Size GraphicHelper::convertHmmToAppFont( const awt::Size& rHmm ) const // Graphics and graphic objects ---------------------------------------------- Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm, - const WMF_EXTERNALHEADER* pExtHeader ) const + const WmfExternal* pExtHeader ) const { Reference< XGraphic > xGraphic; if( rxInStrm.is() && mxGraphicProvider.is() ) try @@ -331,7 +331,7 @@ void GraphicHelper::importEmbeddedGraphics(const std::vector<OUString>& rStreamN } } -Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WMF_EXTERNALHEADER* pExtHeader ) const +Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WmfExternal* pExtHeader ) const { Reference< XGraphic > xGraphic; OSL_ENSURE( !rStreamName.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" ); @@ -367,7 +367,7 @@ OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGrap } OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm, - const WMF_EXTERNALHEADER* pExtHeader ) const + const WmfExternal* pExtHeader ) const { return createGraphicObject( importGraphic( rxInStrm, pExtHeader ) ); } diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 8d85b14701fb..c51afb75d40b 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -1141,7 +1141,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes // set the replacement graphic if( !aGraphicPath.isEmpty() ) { - WMF_EXTERNALHEADER aExtHeader; + WmfExternal aExtHeader; aExtHeader.mapMode = 8; aExtHeader.xExt = rShapeRect.Width; aExtHeader.yExt = rShapeRect.Height; diff --git a/svtools/source/graphic/provider.cxx b/svtools/source/graphic/provider.cxx index 1bdcee7812a9..f837b0b9ef0a 100644 --- a/svtools/source/graphic/provider.cxx +++ b/svtools/source/graphic/provider.cxx @@ -413,11 +413,11 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co ::Graphic aVCLGraphic; // Define APM Header if goal height and width are defined - WMF_EXTERNALHEADER aExtHeader; + WmfExternal aExtHeader; aExtHeader.xExt = nExtWidth; aExtHeader.yExt = nExtHeight; aExtHeader.mapMode = nExtMapMode; - WMF_EXTERNALHEADER *pExtHeader = nullptr; + WmfExternal *pExtHeader = nullptr; if ( nExtMapMode > 0 ) pExtHeader = &aExtHeader; diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 9735c606a1a8..2ad89aced588 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -373,10 +373,8 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/filter/jpeg/JpegWriter \ vcl/source/filter/jpeg/JpegTransform \ vcl/source/filter/wmf/emfwr \ - vcl/source/filter/wmf/enhwmf \ - vcl/source/filter/wmf/winmtf \ - vcl/source/filter/wmf/winwmf \ vcl/source/filter/wmf/wmf \ + vcl/source/filter/wmf/wmfexternal \ vcl/source/filter/wmf/wmfwr \ vcl/source/font/PhysicalFontCollection \ vcl/source/font/PhysicalFontFace \ diff --git a/vcl/qa/cppunit/wmf/wmfimporttest.cxx b/vcl/qa/cppunit/wmf/wmfimporttest.cxx index ca9900c18ad9..40ac1d5b02af 100644 --- a/vcl/qa/cppunit/wmf/wmfimporttest.cxx +++ b/vcl/qa/cppunit/wmf/wmfimporttest.cxx @@ -23,7 +23,6 @@ #include <unotest/bootstrapfixturebase.hxx> #include <vcl/wmf.hxx> #include <vcl/metaact.hxx> -#include <winmtf.hxx> using namespace css; diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 84314080e265..491d27645d68 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -1312,7 +1312,7 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rP } sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream, - sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, WMF_EXTERNALHEADER *pExtHeader ) + sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, WmfExternal *pExtHeader ) { return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, nullptr, pExtHeader ); } @@ -1467,7 +1467,7 @@ void GraphicFilter::ImportGraphics(std::vector< std::shared_ptr<Graphic> >& rGra ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, GraphicFilterImportFlags nImportFlags, css::uno::Sequence< css::beans::PropertyValue >* pFilterData, - WMF_EXTERNALHEADER *pExtHeader ) + WmfExternal *pExtHeader ) { OUString aFilterName; OUString aExternalFilterName; @@ -1771,52 +1771,46 @@ ErrCode GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, else if( aFilterName.equalsIgnoreAsciiCase( IMP_WMF ) || aFilterName.equalsIgnoreAsciiCase( IMP_EMF ) ) { - static bool bCheckEmfWmf = true; - if (bCheckEmfWmf) - { - if (rGraphic.IsDummyContext()) - rGraphic.SetDummyContext(false); + // use new UNO API service, do not directly import but create a + // Graphic that contains the original data and decomposes to + // primitives on demand + if (rGraphic.IsDummyContext()) + rGraphic.SetDummyContext(false); - const sal_uInt32 nStreamPosition(rIStream.Tell()); - const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition); - VectorGraphicDataArray aNewData(nStreamLength); - bool bOkay(false); + const sal_uInt32 nStreamPosition(rIStream.Tell()); + const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition); + VectorGraphicDataArray aNewData(nStreamLength); + bool bOkay(false); - rIStream.Seek(nStreamPosition); - rIStream.ReadBytes(aNewData.begin(), nStreamLength); + rIStream.Seek(nStreamPosition); + rIStream.ReadBytes(aNewData.begin(), nStreamLength); - if (!rIStream.GetError()) + if (!rIStream.GetError()) + { + const bool bIsWmf(aFilterName.equalsIgnoreAsciiCase(IMP_WMF)); + const VectorGraphicDataType aDataType(bIsWmf ? VectorGraphicDataType::Wmf : VectorGraphicDataType::Emf); + VectorGraphicDataPtr aVectorGraphicDataPtr( + new VectorGraphicData( + aNewData, + rPath, + aDataType)); + + if (pExtHeader) { - const bool bIsWmf(aFilterName.equalsIgnoreAsciiCase(IMP_WMF)); - const VectorGraphicDataType aDataType(bIsWmf ? VectorGraphicDataType::Wmf : VectorGraphicDataType::Emf); - VectorGraphicDataPtr aVectorGraphicDataPtr( - new VectorGraphicData( - aNewData, - rPath, - aDataType)); - rGraphic = Graphic(aVectorGraphicDataPtr); - bOkay = true; + aVectorGraphicDataPtr->setWmfExternalHeader(*pExtHeader); } - if (bOkay) - { - eLinkType = GfxLinkType::NativeWmf; - } - else - { - nStatus = ERRCODE_GRFILTER_FILTERERROR; - } + rGraphic = Graphic(aVectorGraphicDataPtr); + bOkay = true; + } + + if (bOkay) + { + eLinkType = GfxLinkType::NativeWmf; } else { - GDIMetaFile aMtf; - if (!ConvertWMFToGDIMetaFile(rIStream, aMtf, nullptr, pExtHeader)) - nStatus = ERRCODE_GRFILTER_FORMATERROR; - else - { - rGraphic = aMtf; - eLinkType = GfxLinkType::NativeWmf; - } + nStatus = ERRCODE_GRFILTER_FILTERERROR; } } else if( aFilterName.equalsIgnoreAsciiCase( IMP_SVSGF ) diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx deleted file mode 100644 index 22125d747dbe..000000000000 --- a/vcl/source/filter/wmf/enhwmf.cxx +++ /dev/null @@ -1,1966 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <osl/endian.h> -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <vcl/dibtools.hxx> -#include <o3tl/make_unique.hxx> - -#include "winmtf.hxx" - -#include <memory> - -#ifdef DBG_UTIL -#include <tools/stream.hxx> -#include <vcl/pngwrite.hxx> -#endif - -using namespace std; - -// GDI-Array - -#define EMR_HEADER 1 -#define EMR_POLYBEZIER 2 -#define EMR_POLYGON 3 -#define EMR_POLYLINE 4 -#define EMR_POLYBEZIERTO 5 -#define EMR_POLYLINETO 6 -#define EMR_POLYPOLYLINE 7 -#define EMR_POLYPOLYGON 8 -#define EMR_SETWINDOWEXTEX 9 -#define EMR_SETWINDOWORGEX 10 -#define EMR_SETVIEWPORTEXTEX 11 -#define EMR_SETVIEWPORTORGEX 12 -#define EMR_SETBRUSHORGEX 13 -#define EMR_EOF 14 -#define EMR_SETPIXELV 15 -#define EMR_SETMAPPERFLAGS 16 -#define EMR_SETMAPMODE 17 -#define EMR_SETBKMODE 18 -#define EMR_SETPOLYFILLMODE 19 -#define EMR_SETROP2 20 -#define EMR_SETSTRETCHBLTMODE 21 -#define EMR_SETTEXTALIGN 22 -#define EMR_SETCOLORADJUSTMENT 23 -#define EMR_SETTEXTCOLOR 24 -#define EMR_SETBKCOLOR 25 -#define EMR_OFFSETCLIPRGN 26 -#define EMR_MOVETOEX 27 -#define EMR_SETMETARGN 28 -#define EMR_EXCLUDECLIPRECT 29 -#define EMR_INTERSECTCLIPRECT 30 -#define EMR_SCALEVIEWPORTEXTEX 31 -#define EMR_SCALEWINDOWEXTEX 32 -#define EMR_SAVEDC 33 -#define EMR_RESTOREDC 34 -#define EMR_SETWORLDTRANSFORM 35 -#define EMR_MODIFYWORLDTRANSFORM 36 -#define EMR_SELECTOBJECT 37 -#define EMR_CREATEPEN 38 -#define EMR_CREATEBRUSHINDIRECT 39 -#define EMR_DELETEOBJECT 40 -#define EMR_ANGLEARC 41 -#define EMR_ELLIPSE 42 -#define EMR_RECTANGLE 43 -#define EMR_ROUNDRECT 44 -#define EMR_ARC 45 -#define EMR_CHORD 46 -#define EMR_PIE 47 -#define EMR_SELECTPALETTE 48 -#define EMR_CREATEPALETTE 49 -#define EMR_SETPALETTEENTRIES 50 -#define EMR_RESIZEPALETTE 51 -#define EMR_REALIZEPALETTE 52 -#define EMR_EXTFLOODFILL 53 -#define EMR_LINETO 54 -#define EMR_ARCTO 55 -#define EMR_POLYDRAW 56 -#define EMR_SETARCDIRECTION 57 -#define EMR_SETMITERLIMIT 58 -#define EMR_BEGINPATH 59 -#define EMR_ENDPATH 60 -#define EMR_CLOSEFIGURE 61 -#define EMR_FILLPATH 62 -#define EMR_STROKEANDFILLPATH 63 -#define EMR_STROKEPATH 64 -#define EMR_FLATTENPATH 65 -#define EMR_WIDENPATH 66 -#define EMR_SELECTCLIPPATH 67 -#define EMR_ABORTPATH 68 - -#define EMR_COMMENT 70 // Contains arbitrary private data. -// Comment Identifiers: -#define EMR_COMMENT_EMFPLUS 0x2B464D45 // Contains embedded EMF+ records. -#define EMR_COMMENT_EMFSPOOL 0x00000000 // Contains embedded EMFSPOOL records. -#define EMR_COMMENT_PUBLIC 0x43494447 // Specify extensions to EMF processing. - -#define EMR_FILLRGN 71 -#define EMR_FRAMERGN 72 -#define EMR_INVERTRGN 73 -#define EMR_PAINTRGN 74 -#define EMR_EXTSELECTCLIPRGN 75 -#define EMR_BITBLT 76 -#define EMR_STRETCHBLT 77 -#define EMR_MASKBLT 78 -#define EMR_PLGBLT 79 -#define EMR_SETDIBITSTODEVICE 80 -#define EMR_STRETCHDIBITS 81 -#define EMR_EXTCREATEFONTINDIRECTW 82 -#define EMR_EXTTEXTOUTA 83 -#define EMR_EXTTEXTOUTW 84 -#define EMR_POLYBEZIER16 85 -#define EMR_POLYGON16 86 -#define EMR_POLYLINE16 87 -#define EMR_POLYBEZIERTO16 88 -#define EMR_POLYLINETO16 89 -#define EMR_POLYPOLYLINE16 90 -#define EMR_POLYPOLYGON16 91 -#define EMR_POLYDRAW16 92 -#define EMR_CREATEMONOBRUSH 93 -#define EMR_CREATEDIBPATTERNBRUSHPT 94 -#define EMR_EXTCREATEPEN 95 -#define EMR_POLYTEXTOUTA 96 -#define EMR_POLYTEXTOUTW 97 - -// WINDOWS VERSION >= 0x400 -#define EMR_SETICMMODE 98 -#define EMR_CREATECOLORSPACE 99 -#define EMR_SETCOLORSPACE 100 -#define EMR_DELETECOLORSPACE 101 -#define EMR_GLSRECORD 102 -#define EMR_GLSBOUNDEDRECORD 103 -#define EMR_PIXELFORMAT 104 - -// WINDOWS VERSION >= 0x500 -#define EMR_DRAWESCAPE 105 -#define EMR_EXTESCAPE 106 -#define EMR_STARTDOC 107 -#define EMR_SMALLTEXTOUT 108 -#define EMR_FORCEUFIMAPPING 109 -#define EMR_NAMEDESCAPE 110 -#define EMR_COLORCORRECTPALETTE 111 -#define EMR_SETICMPROFILEA 112 -#define EMR_SETICMPROFILEW 113 -#define EMR_ALPHABLEND 114 -#define EMR_ALPHADIBBLEND 115 -#define EMR_TRANSPARENTBLT 116 -#define EMR_TRANSPARENTDIB 117 -#define EMR_GRADIENTFILL 118 -#define EMR_SETLINKEDUFIS 119 -#define EMR_SETTEXTJUSTIFICATION 120 - -namespace -{ - -const char * -record_type_name(sal_uInt32 nRecType) -{ -#ifndef SAL_LOG_INFO - (void) nRecType; - return ""; -#else - switch( nRecType ) - { - case EMR_HEADER: return "HEADER"; - case EMR_POLYBEZIER: return "POLYBEZIER"; - case EMR_POLYGON: return "POLYGON"; - case EMR_POLYLINE: return "POLYLINE"; - case EMR_POLYBEZIERTO: return "POLYBEZIERTO"; - case EMR_POLYLINETO: return "POLYLINETO"; - case EMR_POLYPOLYLINE: return "POLYPOLYLINE"; - case EMR_POLYPOLYGON: return "POLYPOLYGON"; - case EMR_SETWINDOWEXTEX: return "SETWINDOWEXTEX"; - case EMR_SETWINDOWORGEX: return "SETWINDOWORGEX"; - case EMR_SETVIEWPORTEXTEX: return "SETVIEWPORTEXTEX"; - case EMR_SETVIEWPORTORGEX: return "SETVIEWPORTORGEX"; - case EMR_SETBRUSHORGEX: return "SETBRUSHORGEX"; - case EMR_EOF: return "EOF"; - case EMR_SETPIXELV: return "SETPIXELV"; - case EMR_SETMAPPERFLAGS: return "SETMAPPERFLAGS"; - case EMR_SETMAPMODE: return "SETMAPMODE"; - case EMR_SETBKMODE: return "SETBKMODE"; - case EMR_SETPOLYFILLMODE: return "SETPOLYFILLMODE"; - case EMR_SETROP2: return "SETROP2"; - case EMR_SETSTRETCHBLTMODE: return "SETSTRETCHBLTMODE"; - case EMR_SETTEXTALIGN: return "SETTEXTALIGN"; - case EMR_SETCOLORADJUSTMENT: return "SETCOLORADJUSTMENT"; - case EMR_SETTEXTCOLOR: return "SETTEXTCOLOR"; - case EMR_SETBKCOLOR: return "SETBKCOLOR"; - case EMR_OFFSETCLIPRGN: return "OFFSETCLIPRGN"; - case EMR_MOVETOEX: return "MOVETOEX"; - case EMR_SETMETARGN: return "SETMETARGN"; - case EMR_EXCLUDECLIPRECT: return "EXCLUDECLIPRECT"; - case EMR_INTERSECTCLIPRECT: return "INTERSECTCLIPRECT"; - case EMR_SCALEVIEWPORTEXTEX: return "SCALEVIEWPORTEXTEX"; - case EMR_SCALEWINDOWEXTEX: return "SCALEWINDOWEXTEX"; - case EMR_SAVEDC: return "SAVEDC"; - case EMR_RESTOREDC: return "RESTOREDC"; - case EMR_SETWORLDTRANSFORM: return "SETWORLDTRANSFORM"; - case EMR_MODIFYWORLDTRANSFORM: return "MODIFYWORLDTRANSFORM"; - case EMR_SELECTOBJECT: return "SELECTOBJECT"; - case EMR_CREATEPEN: return "CREATEPEN"; - case EMR_CREATEBRUSHINDIRECT: return "CREATEBRUSHINDIRECT"; - case EMR_DELETEOBJECT: return "DELETEOBJECT"; - case EMR_ANGLEARC: return "ANGLEARC"; - case EMR_ELLIPSE: return "ELLIPSE"; - case EMR_RECTANGLE: return "RECTANGLE"; - case EMR_ROUNDRECT: return "ROUNDRECT"; - case EMR_ARC: return "ARC"; - case EMR_CHORD: return "CHORD"; - case EMR_PIE: return "PIE"; - case EMR_SELECTPALETTE: return "SELECTPALETTE"; - case EMR_CREATEPALETTE: return "CREATEPALETTE"; - case EMR_SETPALETTEENTRIES: return "SETPALETTEENTRIES"; - case EMR_RESIZEPALETTE: return "RESIZEPALETTE"; - case EMR_REALIZEPALETTE: return "REALIZEPALETTE"; - case EMR_EXTFLOODFILL: return "EXTFLOODFILL"; - case EMR_LINETO: return "LINETO"; - case EMR_ARCTO: return "ARCTO"; - case EMR_POLYDRAW: return "POLYDRAW"; - case EMR_SETARCDIRECTION: return "SETARCDIRECTION"; - case EMR_SETMITERLIMIT: return "SETMITERLIMIT"; - case EMR_BEGINPATH: return "BEGINPATH"; - case EMR_ENDPATH: return "ENDPATH"; - case EMR_CLOSEFIGURE: return "CLOSEFIGURE"; - case EMR_FILLPATH: return "FILLPATH"; - case EMR_STROKEANDFILLPATH: return "STROKEANDFILLPATH"; - case EMR_STROKEPATH: return "STROKEPATH"; - case EMR_FLATTENPATH: return "FLATTENPATH"; - case EMR_WIDENPATH: return "WIDENPATH"; - case EMR_SELECTCLIPPATH: return "SELECTCLIPPATH"; - case EMR_ABORTPATH: return "ABORTPATH"; - case EMR_COMMENT: return "COMMENT"; - case EMR_FILLRGN: return "FILLRGN"; - case EMR_FRAMERGN: return "FRAMERGN"; - case EMR_INVERTRGN: return "INVERTRGN"; - case EMR_PAINTRGN: return "PAINTRGN"; - case EMR_EXTSELECTCLIPRGN: return "EXTSELECTCLIPRGN"; - case EMR_BITBLT: return "BITBLT"; - case EMR_STRETCHBLT: return "STRETCHBLT"; - case EMR_MASKBLT: return "MASKBLT"; - case EMR_PLGBLT: return "PLGBLT"; - case EMR_SETDIBITSTODEVICE: return "SETDIBITSTODEVICE"; - case EMR_STRETCHDIBITS: return "STRETCHDIBITS"; - case EMR_EXTCREATEFONTINDIRECTW: return "EXTCREATEFONTINDIRECTW"; - case EMR_EXTTEXTOUTA: return "EXTTEXTOUTA"; - case EMR_EXTTEXTOUTW: return "EXTTEXTOUTW"; - case EMR_POLYBEZIER16: return "POLYBEZIER16"; - case EMR_POLYGON16: return "POLYGON16"; - case EMR_POLYLINE16: return "POLYLINE16"; - case EMR_POLYBEZIERTO16: return "POLYBEZIERTO16"; - case EMR_POLYLINETO16: return "POLYLINETO16"; - case EMR_POLYPOLYLINE16: return "POLYPOLYLINE16"; - case EMR_POLYPOLYGON16: return "POLYPOLYGON16"; - case EMR_POLYDRAW16: return "POLYDRAW16"; - case EMR_CREATEMONOBRUSH: return "CREATEMONOBRUSH"; - case EMR_CREATEDIBPATTERNBRUSHPT: return "CREATEDIBPATTERNBRUSHPT"; - case EMR_EXTCREATEPEN: return "EXTCREATEPEN"; - case EMR_POLYTEXTOUTA: return "POLYTEXTOUTA"; - case EMR_POLYTEXTOUTW: return "POLYTEXTOUTW"; - case EMR_SETICMMODE: return "SETICMMODE"; - case EMR_CREATECOLORSPACE: return "CREATECOLORSPACE"; - case EMR_SETCOLORSPACE: return "SETCOLORSPACE"; - case EMR_DELETECOLORSPACE: return "DELETECOLORSPACE"; - case EMR_GLSRECORD: return "GLSRECORD"; - case EMR_GLSBOUNDEDRECORD: return "GLSBOUNDEDRECORD"; - case EMR_PIXELFORMAT: return "PIXELFORMAT"; - case EMR_DRAWESCAPE: return "DRAWESCAPE"; - case EMR_EXTESCAPE: return "EXTESCAPE"; - case EMR_STARTDOC: return "STARTDOC"; - case EMR_SMALLTEXTOUT: return "SMALLTEXTOUT"; - case EMR_FORCEUFIMAPPING: return "FORCEUFIMAPPING"; - case EMR_NAMEDESCAPE: return "NAMEDESCAPE"; - case EMR_COLORCORRECTPALETTE: return "COLORCORRECTPALETTE"; - case EMR_SETICMPROFILEA: return "SETICMPROFILEA"; - case EMR_SETICMPROFILEW: return "SETICMPROFILEW"; - case EMR_ALPHABLEND: return "ALPHABLEND"; - case EMR_ALPHADIBBLEND: return "ALPHADIBBLEND"; - case EMR_TRANSPARENTBLT: return "TRANSPARENTBLT"; - case EMR_TRANSPARENTDIB: return "TRANSPARENTDIB"; - case EMR_GRADIENTFILL: return "GRADIENTFILL"; - case EMR_SETLINKEDUFIS: return "SETLINKEDUFIS"; - case EMR_SETTEXTJUSTIFICATION: return "SETTEXTJUSTIFICATION"; - default: - // Yes, return a pointer to a static buffer. This is a very - // local debugging output function, so no big deal. - static char buffer[11]; - sprintf(buffer, "0x%08" SAL_PRIxUINT32, nRecType); - return buffer; - } -#endif -} - -#ifdef OSL_BIGENDIAN -// little endian <-> big endian switch -static float GetSwapFloat(SvStream& rStream) -{ - float fTmp; - sal_Int8* pPtr = (sal_Int8*)&fTmp; - rStream.ReadSChar(pPtr[3]); - rStream.ReadSChar(pPtr[2]); - rStream.ReadSChar(pPtr[1]); - rStream.ReadSChar(pPtr[0]); - return fTmp; -} -#endif - -struct BLENDFUNCTION -{ - unsigned char aBlendOperation; - unsigned char aBlendFlags; - unsigned char aSrcConstantAlpha; - unsigned char aAlphaFormat; - - friend SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun); -}; - -SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun) -{ - rInStream.ReadUChar(rBlendFun.aBlendOperation); - rInStream.ReadUChar(rBlendFun.aBlendFlags); - rInStream.ReadUChar(rBlendFun.aSrcConstantAlpha); - rInStream.ReadUChar(rBlendFun.aAlphaFormat); - return rInStream; -} - -SvStream& operator>>(SvStream& rInStream, XForm& rXForm) -{ - if (sizeof(float) != 4) - { - OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" ); - rXForm = XForm(); - } - else - { -#ifdef OSL_BIGENDIAN - rXForm.eM11 = GetSwapFloat(rInStream); - rXForm.eM12 = GetSwapFloat(rInStream); - rXForm.eM21 = GetSwapFloat(rInStream); - rXForm.eM22 = GetSwapFloat(rInStream); - rXForm.eDx = GetSwapFloat(rInStream); - rXForm.eDy = GetSwapFloat(rInStream); -#else - rInStream.ReadFloat(rXForm.eM11); - rInStream.ReadFloat(rXForm.eM12); - rInStream.ReadFloat(rXForm.eM21); - rInStream.ReadFloat(rXForm.eM22); - rInStream.ReadFloat(rXForm.eDx); - rInStream.ReadFloat(rXForm.eDy); -#endif - } - return rInStream; -} - -bool ImplReadRegion( tools::PolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen ) -{ - if (nLen == 0) - return false; - - sal_uInt32 nHdSize, nType, nCount, nRgnSize, i; - rStream.ReadUInt32(nHdSize); - rStream.ReadUInt32(nType); - rStream.ReadUInt32(nCount); - rStream.ReadUInt32(nRgnSize); - - if ( nCount > 0 - && nType == RDH_RECTANGLES - && nLen >= ((nCount << 4) + (nHdSize - 16))) - { - sal_Int32 nx1, ny1, nx2, ny2; - - for (i = 0; i < nCount; i++) - { - rStream.ReadInt32(nx1); - rStream.ReadInt32(ny1); - rStream.ReadInt32(nx2); - rStream.ReadInt32(ny2); - - tools::Rectangle aRectangle(Point(nx1, ny1), Point(nx2, ny2)); - - tools::Polygon aPolygon(aRectangle); - tools::PolyPolygon aPolyPolyOr1(aPolygon); - tools::PolyPolygon aPolyPolyOr2(rPolyPoly); - rPolyPoly.GetUnion(aPolyPolyOr1, aPolyPolyOr2); - rPolyPoly = aPolyPolyOr2; - } - return true; - } - return false; -} - -} // anonymous namespace - -EnhWMFReader::EnhWMFReader(SvStream& rStream,GDIMetaFile& rGDIMetaFile,FilterConfigItem* pConfigItem) - : WinMtf(rGDIMetaFile, rStream , pConfigItem) - , bRecordPath(false) - , nRecordCount(0) - , bEMFPlus(false) -{} - -EnhWMFReader::~EnhWMFReader() -{} - -void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC) -{ - if (!bEMFPlus) { - pOut->PassEMFPlusHeaderInfo(); - -#if OSL_DEBUG_LEVEL > 1 - // debug code - write the stream to debug file /tmp/emf-stream.emf - sal_uInt64 const pos = pWMF->Tell(); - pWMF->Seek(0); - SvFileStream file( OUString( "/tmp/emf-stream.emf" ), StreamMode::WRITE | StreamMode::TRUNC ); - - pWMF->WriteStream(file); - file.Flush(); - file.Close(); - - pWMF->Seek( pos ); -#endif - - } - bEMFPlus = true; - - sal_uInt64 const pos = pWMF->Tell(); - void *buffer = malloc( length ); - pOut->PassEMFPlus( buffer, pWMF->ReadBytes(buffer, length) ); - free( buffer ); - pWMF->Seek( pos ); - - bHaveDC = false; - - // skip in SeekRel if impossibly unavailable - sal_uInt32 nRemainder = length; - - const size_t nRequiredHeaderSize = 12; - while (nRemainder >= nRequiredHeaderSize) - { - sal_uInt16 type(0), flags(0); - sal_uInt32 size(0), dataSize(0); - - pWMF->ReadUInt16( type ).ReadUInt16( flags ).ReadUInt32( size ).ReadUInt32( dataSize ); - nRemainder -= nRequiredHeaderSize; - - SAL_INFO ("vcl.emf", "\t\tEMF+ record type: " << std::hex << type << std::dec); - - // Get Device Context - // TODO We should use EmfPlusRecordType::GetDC instead - if( type == 0x4004 ) - { - bHaveDC = true; - SAL_INFO ("vcl.emf", "\t\tEMF+ lock DC (device context)"); - } - - // Get the length of the remaining data of this record based - // on the alleged size - sal_uInt32 nRemainingRecordData = size >= nRequiredHeaderSize ? - size-nRequiredHeaderSize : 0; - // clip to available size - nRemainingRecordData = std::min(nRemainingRecordData, nRemainder); - pWMF->SeekRel(nRemainingRecordData); - nRemainder -= nRemainingRecordData; - } - pWMF->SeekRel(nRemainder); -} - -/** - * Reads polygons from the stream. - * The \<class T> parameter is for the type of the points (sal_uInt32 or sal_uInt16). - * The \<class Drawer> parameter is a c++11 lambda for the method that will draw the polygon. - * skipFirst: if the first point read is the 0th point or the 1st point in the array. - * */ -template <class T, class Drawer> -void EnhWMFReader::ReadAndDrawPolygon(Drawer drawer, const bool skipFirst) -{ - sal_uInt32 nPoints(0), nStartIndex(0); - pWMF->SeekRel( 16 ); - pWMF->ReadUInt32( nPoints ); - if (skipFirst) - { - nPoints ++; - nStartIndex ++; - } - - tools::Polygon aPolygon = ReadPolygon<T>(nStartIndex, nPoints); - drawer(pOut, aPolygon, skipFirst, bRecordPath); -} - -/** - * Reads polygons from the stream. - * The \<class T> parameter is for the type of the points - * nStartIndex: which is the starting index in the polygon of the first point read - * nPoints: number of points - * pWMF: the stream containing the polygons - * */ -template <class T> -tools::Polygon EnhWMFReader::ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints) -{ - bool bRecordOk = nPoints <= SAL_MAX_UINT16; - SAL_WARN_IF(!bRecordOk, "vcl.emf", "polygon record has more polygons than we can handle"); - if (!bRecordOk) - return tools::Polygon(); - - tools::Polygon aPolygon(nPoints); - for (sal_uInt32 i = nStartIndex ; i < nPoints && pWMF->good(); i++ ) - { - T nX, nY; - *pWMF >> nX >> nY; - if (!pWMF->good()) - { - SAL_WARN("vcl.emf", "short read on polygon, truncating"); - aPolygon.SetSize(i); - break; - } - aPolygon[ i ] = Point( nX, nY ); - } - - return aPolygon; -} - -/** - * Reads a polyline from the WMF file and draws it - * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32) - * */ -template <class T> -void EnhWMFReader::ReadAndDrawPolyLine() -{ - sal_uInt32 nPoints; - sal_uInt32 i, nNumberOfPolylines( 0 ), nCount( 0 ); - pWMF->SeekRel( 0x10 ); // TODO Skipping Bounds. A 128-bit WMF RectL object (specifies the bounding rectangle in device units.) - pWMF->ReadUInt32( nNumberOfPolylines ); - pWMF->ReadUInt32( nCount ); // total number of points in all polylines - if (pWMF->Tell() >= nEndPos) - return; - - // taking the amount of points of each polygon, retrieving the total number of points - if ( pWMF->good() && - ( nNumberOfPolylines < SAL_MAX_UINT32 / sizeof( sal_uInt16 ) ) && - ( nNumberOfPolylines * sizeof( sal_uInt16 ) ) <= ( nEndPos - pWMF->Tell() ) - ) - { - std::unique_ptr< sal_uInt32[] > pnPolylinePointCount( new sal_uInt32[ nNumberOfPolylines ] ); - for ( i = 0; i < nNumberOfPolylines && pWMF->good(); i++ ) - { - pWMF->ReadUInt32( nPoints ); - pnPolylinePointCount[ i ] = nPoints; - } - // Get polyline points: - for ( i = 0; ( i < nNumberOfPolylines ) && pWMF->good(); i++ ) - { - tools::Polygon aPolygon = ReadPolygon< T >( 0, pnPolylinePointCount[ i ] ); - pOut->DrawPolyLine( aPolygon, false, bRecordPath ); - } - } -} - -// these are referenced from inside the templates - -SvStream& operator>>(SvStream& rStream, sal_Int16 &n) -{ - return rStream.ReadInt16(n); -} - -SvStream& operator>>(SvStream& rStream, sal_Int32 &n) -{ - return rStream.ReadInt32(n); -} - -/** - * Reads a poly polygon from the WMF file and draws it. - * The \<class T> parameter refers to the type of the points. (e.g. sal_uInt16 or sal_uInt32) - * */ -template <class T> -void EnhWMFReader::ReadAndDrawPolyPolygon() -{ - sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0); - pWMF->SeekRel( 0x10 ); - // Number of polygons - pWMF->ReadUInt32( nPoly ).ReadUInt32( nGesPoints ); - if (pWMF->Tell() >= nEndPos) - return; - if (!pWMF->good()) - return; - //check against numeric overflowing - if (nGesPoints >= SAL_MAX_UINT32 / sizeof(Point)) - return; - if (nPoly >= SAL_MAX_UINT32 / sizeof(sal_uInt16)) - return; - if (nPoly * sizeof(sal_uInt16) > nEndPos - pWMF->Tell()) - return; - - // Get number of points in each polygon - std::vector<sal_uInt16> aPoints(nPoly); - for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i) - { - sal_uInt32 nPoints(0); - pWMF->ReadUInt32( nPoints ); - aPoints[i] = (sal_uInt16)nPoints; - } - if ( pWMF->good() && ( nGesPoints * (sizeof(T)+sizeof(T)) ) <= ( nEndPos - pWMF->Tell() ) ) - { - // Get polygon points - tools::PolyPolygon aPolyPoly(nPoly, nPoly); - for (sal_uInt32 i = 0; i < nPoly && pWMF->good(); ++i) - { - const sal_uInt16 nPointCount(aPoints[i]); - std::vector<Point> aPtAry(nPointCount); - for (sal_uInt16 j = 0; j < nPointCount && pWMF->good(); ++j) - { - T nX(0), nY(0); - *pWMF >> nX >> nY; - aPtAry[j] = Point( nX, nY ); - ++nReadPoints; - } - - aPolyPoly.Insert(tools::Polygon(aPtAry.size(), aPtAry.data())); - } - - pOut->DrawPolyPolygon(aPolyPoly, bRecordPath); - } - - OSL_ENSURE(nReadPoints == nGesPoints, "The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)"); -} - -bool EnhWMFReader::ReadEnhWMF() -{ - sal_uInt32 nStretchBltMode = 0; - sal_uInt32 nNextPos(0), - nW(0), nH(0), nColor(0), nIndex(0), - nDat32(0), nNom1(0), nDen1(0), nNom2(0), nDen2(0); - sal_Int32 nX32(0), nY32(0), nx32(0), ny32(0); - - bool bStatus = ReadHeader(); - bool bHaveDC = false; - - static bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == nullptr ); - - while( bStatus && nRecordCount-- && pWMF->good()) - { - sal_uInt32 nRecType(0), nRecSize(0); - pWMF->ReadUInt32(nRecType).ReadUInt32(nRecSize); - - if ( !pWMF->good() || ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameters are always divisible by 4 - { - bStatus = false; - break; - } - - auto nCurPos = pWMF->Tell(); - - if (nEndPos < nCurPos - 8) - { - bStatus = false; - break; - } - - const sal_uInt32 nMaxPossibleRecSize = nEndPos - (nCurPos - 8); - if (nRecSize > nMaxPossibleRecSize) - { - bStatus = false; - break; - } - - nNextPos = nCurPos + (nRecSize - 8); - - if( !aBmpSaveList.empty() - && ( nRecType != EMR_STRETCHBLT ) - && ( nRecType != EMR_STRETCHDIBITS ) - ) { - pOut->ResolveBitmapActions( aBmpSaveList ); - } - - bool bFlag = false; - - SAL_INFO ("vcl.emf", "0x" << std::hex << (nNextPos - nRecSize) << "-0x" << nNextPos << " " << record_type_name(nRecType) << " size: " << nRecSize << std::dec); - - if( bEnableEMFPlus && nRecType == EMR_COMMENT ) { - sal_uInt32 length; - - pWMF->ReadUInt32( length ); - - SAL_INFO("vcl.emf", "\tGDI comment, length: " << length); - - if( pWMF->good() && length >= 4 && length <= pWMF->remainingSize() ) { - sal_uInt32 nCommentId; - - pWMF->ReadUInt32( nCommentId ); - - SAL_INFO ("vcl.emf", "\t\tbegin " << (char)(nCommentId & 0xff) << (char)((nCommentId & 0xff00) >> 8) << (char)((nCommentId & 0xff0000) >> 16) << (char)((nCommentId & 0xff000000) >> 24) << " id: 0x" << std::hex << nCommentId << std::dec); - - if( nCommentId == EMR_COMMENT_EMFPLUS && nRecSize >= 12 ) - { - // [MS-EMF] 2.3.3: DataSize includes both CommentIdentifier and CommentRecordParm fields. - // We have already read 4-byte CommentIdentifier, so reduce length appropriately - ReadEMFPlusComment( length-4, bHaveDC ); - } - else if( nCommentId == EMR_COMMENT_PUBLIC && nRecSize >= 12 ) - { - // TODO: ReadGDIComment() - } - else if( nCommentId == EMR_COMMENT_EMFSPOOL && nRecSize >= 12 ) - { - // TODO Implement reading EMFSPOOL comment - - } - else - { - SAL_INFO ("vcl.emf", "\t\tunknown id: 0x" << std::hex << nCommentId << std::dec); - } - } - } - else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF ) - { - switch( nRecType ) - { - case EMR_POLYBEZIERTO : - ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath ) - { pWinMtfOutput->DrawPolyBezier( rPolygon, aTo, aRecordPath ); }, true ); - break; - case EMR_POLYBEZIER : - ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath ) - { pWinMtfOutput->DrawPolyBezier( rPolygon, aTo, aRecordPath ); }, false ); - break; - - case EMR_POLYGON : - ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool /*aTo*/, bool aRecordPath ) - { pWinMtfOutput->DrawPolygon( rPolygon, aRecordPath ); }, false ); - break; - - case EMR_POLYLINETO : - ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath ) - { pWinMtfOutput->DrawPolyLine( rPolygon, aTo, aRecordPath ); }, true ); - break; - - case EMR_POLYLINE : - ReadAndDrawPolygon<sal_Int32>( [] ( std::unique_ptr<WinMtfOutput> &pWinMtfOutput, tools::Polygon& rPolygon, bool aTo, bool aRecordPath ) - { pWinMtfOutput->DrawPolyLine( rPolygon, aTo, aRecordPath ); }, false ); - break; - - case EMR_POLYPOLYLINE : - ReadAndDrawPolyLine<sal_Int32>(); - break; - - case EMR_POLYPOLYGON : - ReadAndDrawPolyPolygon<sal_Int32>(); - break; - - case EMR_SETWINDOWEXTEX : - { - pWMF->ReadUInt32( nW ).ReadUInt32( nH ); - pOut->SetWinExt( Size( nW, nH ), true); - } - break; - - case EMR_SETWINDOWORGEX : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ); - pOut->SetWinOrg( Point( nX32, nY32 ), true); - } - break; - - case EMR_SCALEWINDOWEXTEX : - { - pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 ); - pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); - } - break; - - case EMR_SETVIEWPORTORGEX : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ); - pOut->SetDevOrg( Point( nX32, nY32 ) ); - } - break; - - case EMR_SCALEVIEWPORTEXTEX : - { - pWMF->ReadUInt32( nNom1 ).ReadUInt32( nDen1 ).ReadUInt32( nNom2 ).ReadUInt32( nDen2 ); - pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 ); - } - break; - - case EMR_SETVIEWPORTEXTEX : - { - pWMF->ReadUInt32( nW ).ReadUInt32( nH ); - pOut->SetDevExt( Size( nW, nH ) ); - } - break; - - case EMR_EOF : - nRecordCount = 0; - break; - - case EMR_SETPIXELV : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ); - pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() ); - } - break; - - case EMR_SETMAPMODE : - { - sal_uInt32 nMapMode; - pWMF->ReadUInt32( nMapMode ); - pOut->SetMapMode( nMapMode ); - } - break; - - case EMR_SETBKMODE : - { - pWMF->ReadUInt32( nDat32 ); - pOut->SetBkMode( static_cast<BkMode>(nDat32) ); - } - break; - - case EMR_SETPOLYFILLMODE : - break; - - case EMR_SETROP2 : - { - pWMF->ReadUInt32( nDat32 ); - pOut->SetRasterOp( (WMFRasterOp)nDat32 ); - } - break; - - case EMR_SETSTRETCHBLTMODE : - { - pWMF->ReadUInt32( nStretchBltMode ); - } - break; - - case EMR_SETTEXTALIGN : - { - pWMF->ReadUInt32( nDat32 ); - pOut->SetTextAlign( nDat32 ); - } - break; - - case EMR_SETTEXTCOLOR : - { - pOut->SetTextColor( ReadColor() ); - } - break; - - case EMR_SETBKCOLOR : - { - pOut->SetBkColor( ReadColor() ); - } - break; - - case EMR_OFFSETCLIPRGN : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ); - pOut->MoveClipRegion( Size( nX32, nY32 ) ); - } - break; - - case EMR_MOVETOEX : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ); - pOut->MoveTo( Point( nX32, nY32 ), bRecordPath ); - } - break; - - case EMR_INTERSECTCLIPRECT : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ); - pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); - } - break; - - case EMR_SAVEDC : - { - pOut->Push(); - } - break; - - case EMR_RESTOREDC : - { - pOut->Pop(); - } - break; - - case EMR_SETWORLDTRANSFORM : - { - XForm aTempXForm; - *pWMF >> aTempXForm; - pOut->SetWorldTransform( aTempXForm ); - } - break; - - case EMR_MODIFYWORLDTRANSFORM : - { - sal_uInt32 nMode; - XForm aTempXForm; - *pWMF >> aTempXForm; - pWMF->ReadUInt32( nMode ); - pOut->ModifyWorldTransform( aTempXForm, nMode ); - } - break; - - case EMR_SELECTOBJECT : - { - pWMF->ReadUInt32( nIndex ); - pOut->SelectObject( nIndex ); - } - break; - - case EMR_CREATEPEN : - { - pWMF->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) - { - - LineInfo aLineInfo; - sal_uInt32 nStyle; - Size aSize; - // #fdo39428 Remove SvStream operator>>(long&) - sal_Int32 nTmpW(0), nTmpH(0); - - pWMF->ReadUInt32( nStyle ).ReadInt32( nTmpW ).ReadInt32( nTmpH ); - aSize.Width() = nTmpW; - aSize.Height() = nTmpH; - - if ( aSize.Width() ) - aLineInfo.SetWidth( aSize.Width() ); - - bool bTransparent = false; - switch( nStyle & PS_STYLE_MASK ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - case PS_INSIDEFRAME : - case PS_SOLID : - default : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & PS_ENDCAP_STYLE_MASK ) - { - case PS_ENDCAP_ROUND : - if ( aSize.Width() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - } - SAL_FALLTHROUGH; - case PS_ENDCAP_SQUARE : - if ( aSize.Width() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - } - SAL_FALLTHROUGH; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & PS_JOIN_STYLE_MASK ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfLineStyle>( ReadColor(), aLineInfo, bTransparent )); - } - } - break; - - case EMR_EXTCREATEPEN : - { - sal_Int32 elpHatch; - sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; - Color aColorRef; - - pWMF->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) - { - pWMF->ReadUInt32( offBmi ).ReadUInt32( cbBmi ).ReadUInt32( offBits ).ReadUInt32( cbBits ). ReadUInt32( nStyle ).ReadUInt32( nWidth ).ReadUInt32( nBrushStyle ); - aColorRef = ReadColor(); - pWMF->ReadInt32( elpHatch ).ReadUInt32( elpNumEntries ); - - LineInfo aLineInfo; - if ( nWidth ) - aLineInfo.SetWidth( nWidth ); - - bool bTransparent = false; - - switch( nStyle & PS_STYLE_MASK ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - - case PS_INSIDEFRAME : - case PS_SOLID : - default : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & PS_ENDCAP_STYLE_MASK ) - { - case PS_ENDCAP_ROUND : - if ( aLineInfo.GetWidth() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - } - SAL_FALLTHROUGH; - case PS_ENDCAP_SQUARE : - if ( aLineInfo.GetWidth() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - } - SAL_FALLTHROUGH; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & PS_JOIN_STYLE_MASK ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfLineStyle>( aColorRef, aLineInfo, bTransparent )); - } - } - break; - - case EMR_CREATEBRUSHINDIRECT : - { - sal_uInt32 nStyle; - pWMF->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) - { - pWMF->ReadUInt32( nStyle ); - pOut->CreateObjectIndexed(nIndex, o3tl::make_unique<WinMtfFillStyle>( ReadColor(), ( nStyle == BS_HOLLOW ) )); - } - } - break; - - case EMR_DELETEOBJECT : - { - pWMF->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) - pOut->DeleteObject( nIndex ); - } - break; - - case EMR_ELLIPSE : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ); - pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) ); - } - break; - - case EMR_RECTANGLE : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ); - pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) ); - } - break; - - case EMR_ROUNDRECT : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nW ).ReadUInt32( nH ); - Size aSize( Size( nW, nH ) ); - pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize ); - } - break; - - case EMR_ARC : - { - sal_uInt32 nStartX, nStartY, nEndX, nEndY; - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY ); - pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); - } - break; - - case EMR_CHORD : - { - sal_uInt32 nStartX, nStartY, nEndX, nEndY; - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY ); - pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); - } - break; - - case EMR_PIE : - { - sal_uInt32 nStartX, nStartY, nEndX, nEndY; - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY ); - const tools::Rectangle aRect( ReadRectangle( nX32, nY32, nx32, ny32 )); - - // #i73608# OutputDevice deviates from WMF - // semantics. start==end means full ellipse here. - if( nStartX == nEndX && nStartY == nEndY ) - pOut->DrawEllipse( aRect ); - else - pOut->DrawPie( aRect, Point( nStartX, nStartY ), Point( nEndX, nEndY ) ); - } - break; - - case EMR_LINETO : - { - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ); - pOut->LineTo( Point( nX32, nY32 ), bRecordPath ); - } - break; - - case EMR_ARCTO : - { - sal_uInt32 nStartX, nStartY, nEndX, nEndY; - pWMF->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nStartX ).ReadUInt32( nStartY ).ReadUInt32( nEndX ).ReadUInt32( nEndY ); - pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), true ); - } - break; - - case EMR_BEGINPATH : - { - pOut->ClearPath(); - bRecordPath = true; - } - break; - - case EMR_ABORTPATH : - pOut->ClearPath(); - SAL_FALLTHROUGH; - case EMR_ENDPATH : - bRecordPath = false; - break; - - case EMR_CLOSEFIGURE : - pOut->ClosePath(); - break; - - case EMR_FILLPATH : - pOut->StrokeAndFillPath( false, true ); - break; - - case EMR_STROKEANDFILLPATH : - pOut->StrokeAndFillPath( true, true ); - break; - - case EMR_STROKEPATH : - pOut->StrokeAndFillPath( true, false ); - break; - - case EMR_SELECTCLIPPATH : - { - sal_Int32 nClippingMode; - pWMF->ReadInt32(nClippingMode); - pOut->SetClipPath(pOut->GetPathObj(), nClippingMode, true); - } - break; - - case EMR_EXTSELECTCLIPRGN : - { - sal_Int32 nClippingMode, cbRgnData; - pWMF->ReadInt32(cbRgnData); - pWMF->ReadInt32(nClippingMode); - - // This record's region data should be ignored if mode - // is RGN_COPY - see EMF spec section 2.3.2.2 - if (nClippingMode == RGN_COPY) - { - pOut->SetDefaultClipPath(); - } - else - { - tools::PolyPolygon aPolyPoly; - if (cbRgnData) - ImplReadRegion(aPolyPoly, *pWMF, nRecSize); - pOut->SetClipPath(aPolyPoly, nClippingMode, false); - } - - } - break; - - case EMR_ALPHABLEND: - { - sal_Int32 xDest(0), yDest(0), cxDest(0), cyDest(0); - - BLENDFUNCTION aFunc; - sal_Int32 xSrc(0), ySrc(0), cxSrc(0), cySrc(0); - XForm xformSrc; - sal_uInt32 BkColorSrc(0), iUsageSrc(0), offBmiSrc(0); - sal_uInt32 cbBmiSrc(0), offBitsSrc(0), cbBitsSrc(0); - - sal_uInt32 nStart = pWMF->Tell() - 8; - pWMF->SeekRel( 0x10 ); - - pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ); - *pWMF >> aFunc; - pWMF->ReadInt32( xSrc ).ReadInt32( ySrc ); - *pWMF >> xformSrc; - pWMF->ReadUInt32( BkColorSrc ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc ) - .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc ).ReadInt32( cxSrc ).ReadInt32( cySrc ) ; - - sal_uInt32 dwRop = SRCAND|SRCINVERT; - tools::Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) ); - - if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) - bStatus = false; - else - { - const sal_uInt32 nSourceSize = cbBmiSrc + cbBitsSrc + 14; - bool bSafeRead = nSourceSize <= (nEndPos - nStartPos); - sal_uInt32 nDeltaToDIB5HeaderSize(0); - const bool bReadAlpha(0x01 == aFunc.aAlphaFormat); - if (bSafeRead && bReadAlpha) - { - // we need to read alpha channel data if AlphaFormat of BLENDFUNCTION is - // AC_SRC_ALPHA (==0x01). To read it, create a temp DIB-File which is ready - // for DIB-5 format - const sal_uInt32 nHeaderSize = getDIBV5HeaderSize(); - if (cbBmiSrc > nHeaderSize) - bSafeRead = false; - else - nDeltaToDIB5HeaderSize = nHeaderSize - cbBmiSrc; - } - if (bSafeRead) - { - const sal_uInt32 nTargetSize(cbBmiSrc + nDeltaToDIB5HeaderSize + cbBitsSrc + 14); - char* pBuf = new char[ nTargetSize ]; - SvMemoryStream aTmp( pBuf, nTargetSize, StreamMode::READ | StreamMode::WRITE ); - - aTmp.ObjectOwnsMemory( true ); - - // write BM-Header (14 bytes) - aTmp.WriteUChar( 'B' ) - .WriteUChar( 'M' ) - .WriteUInt32( cbBitsSrc ) - .WriteUInt16( 0 ) - .WriteUInt16( 0 ) - .WriteUInt32( cbBmiSrc + nDeltaToDIB5HeaderSize + 14 ); - - // copy DIBInfoHeader from source (cbBmiSrc bytes) - pWMF->Seek( nStart + offBmiSrc ); - pWMF->ReadBytes(pBuf + 14, cbBmiSrc); - - if (bReadAlpha) - { - // need to add values for all stuff that DIBV5Header is bigger - // than DIBInfoHeader, all values are correctly initialized to zero, - // so we can use memset here - memset(pBuf + cbBmiSrc + 14, 0, nDeltaToDIB5HeaderSize); - } - - // copy bitmap data from source (offBitsSrc bytes) - pWMF->Seek( nStart + offBitsSrc ); - pWMF->ReadBytes(pBuf + 14 + nDeltaToDIB5HeaderSize + cbBmiSrc, cbBitsSrc); - aTmp.Seek( 0 ); - - // prepare to read and fill BitmapEx - BitmapEx aBitmapEx; - - if(bReadAlpha) - { - Bitmap aBitmap; - AlphaMask aAlpha; - - if(ReadDIBV5(aBitmap, aAlpha, aTmp)) - { - aBitmapEx = BitmapEx(aBitmap, aAlpha); - } - } - else - { - Bitmap aBitmap; - - if(ReadDIB(aBitmap, aTmp, true)) - { - if(0xff != aFunc.aSrcConstantAlpha) - { - // add const alpha channel - aBitmapEx = BitmapEx( - aBitmap, - AlphaMask(aBitmap.GetSizePixel(), &aFunc.aSrcConstantAlpha)); - } - else - { - // just use Bitmap - aBitmapEx = BitmapEx(aBitmap); - } - } - } - - if(!aBitmapEx.IsEmpty()) - { - // test if it is sensible to crop - if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && - ( xSrc >= 0 ) && ( ySrc >= 0 ) && - ( xSrc + cxSrc < aBitmapEx.GetSizePixel().Width() ) && - ( ySrc + cySrc < aBitmapEx.GetSizePixel().Height() ) ) - { - const tools::Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); - - aBitmapEx.Crop( aCropRect ); - } - -#ifdef DBG_UTIL - static bool bDoSaveForVisualControl(false); - - if(bDoSaveForVisualControl) - { - SvFileStream aNew("c:\\metafile_content.png", StreamMode::WRITE|StreamMode::TRUNC); - vcl::PNGWriter aPNGWriter(aBitmapEx); - aPNGWriter.Write(aNew); - } -#endif - aBmpSaveList.emplace_back(new BSaveStruct(aBitmapEx, aRect, dwRop)); - } - } - } - } - break; - - case EMR_BITBLT : // PASSTHROUGH INTENDED - case EMR_STRETCHBLT : - { - sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc; - sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc; - XForm xformSrc; - - sal_uInt32 nStart = pWMF->Tell() - 8; - - pWMF->SeekRel( 0x10 ); - pWMF->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ).ReadUInt32( dwRop ).ReadInt32( xSrc ).ReadInt32( ySrc ) - >> xformSrc; - pWMF->ReadUInt32( nColor ).ReadUInt32( iUsageSrc ).ReadUInt32( offBmiSrc ).ReadUInt32( cbBmiSrc ) - .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc ); - - if ( nRecType == EMR_STRETCHBLT ) - pWMF->ReadInt32( cxSrc ).ReadInt32( cySrc ); - else - cxSrc = cySrc = 0; - - Bitmap aBitmap; - tools::Rectangle aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) ); - - if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) ) - bStatus = false; - else - { - sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; - if ( nSize <= ( nEndPos - nStartPos ) ) - { - char* pBuf = new char[ nSize ]; - SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE ); - aTmp.ObjectOwnsMemory( true ); - aTmp.WriteUChar( 'B' ) - .WriteUChar( 'M' ) - .WriteUInt32( cbBitsSrc ) - .WriteUInt16( 0 ) - .WriteUInt16( 0 ) - .WriteUInt32( cbBmiSrc + 14 ); - pWMF->Seek( nStart + offBmiSrc ); - pWMF->ReadBytes(pBuf + 14, cbBmiSrc); - pWMF->Seek( nStart + offBitsSrc ); - pWMF->ReadBytes(pBuf + 14 + cbBmiSrc, cbBitsSrc); - aTmp.Seek( 0 ); - ReadDIB(aBitmap, aTmp, true); - - // test if it is sensible to crop - if ( ( cxSrc > 0 ) && ( cySrc > 0 ) && - ( xSrc >= 0 ) && ( ySrc >= 0 ) && - ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) && - ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) ) - { - tools::Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) ); - aBitmap.Crop( aCropRect ); - } - aBmpSaveList.emplace_back(new BSaveStruct(aBitmap, aRect, dwRop)); - } - } - } - break; - - case EMR_STRETCHDIBITS : - { - sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest; - sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop; - sal_uInt32 nStart = pWMF->Tell() - 8; - - pWMF->SeekRel( 0x10 ); - pWMF->ReadInt32( xDest ) - .ReadInt32( yDest ) - .ReadInt32( xSrc ) - .ReadInt32( ySrc ) - .ReadInt32( cxSrc ) - .ReadInt32( cySrc ) - .ReadUInt32( offBmiSrc ) - .ReadUInt32( cbBmiSrc ) - .ReadUInt32( offBitsSrc ) - .ReadUInt32( cbBitsSrc ) - .ReadUInt32( iUsageSrc ) - .ReadUInt32( dwRop ) - .ReadInt32( cxDest ) - .ReadInt32( cyDest ); - - Bitmap aBitmap; - tools::Rectangle aRect( Point( xDest, yDest ), Size( cxDest, cyDest ) ); - - if ( ((SAL_MAX_UINT32 - 14) < cbBitsSrc) - || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc ) - ) - { - bStatus = false; - } - else - { - sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14; - if ( nSize <= ( nEndPos - nStartPos ) ) - { - char* pBuf = new char[ nSize ]; - SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE ); - aTmp.ObjectOwnsMemory( true ); ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
