From 783269e91e2166357a9fb095e64a1d48e6f0601a Mon Sep 17 00:00:00 2001 From: Armin Le Grand Date: Fri, 16 Jun 2017 17:16:22 +0200 Subject: 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 --- emfio/source/emfuno/xemfparser.cxx | 161 +++++++++++++++---------------------- emfio/source/reader/mtftools.cxx | 9 +-- emfio/source/reader/wmfreader.cxx | 54 +++++++++---- 3 files changed, 106 insertions(+), 118 deletions(-) (limited to 'emfio/source') 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 #include -#include #include #include @@ -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 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 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 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..7c2938730b42 100644 --- a/emfio/source/reader/mtftools.cxx +++ b/emfio/source/reader/mtftools.cxx @@ -20,13 +20,10 @@ #include #include -//#include "winmtf.hxx" #include #include -//#include #include #include -//#include #include #include #include @@ -1249,7 +1246,7 @@ namespace emfio } } - void MtfTools::DrawPolygon( tools::Polygon& rPolygon, bool bRecordPath ) + void MtfTools::DrawPolygon( tools::Polygon rPolygon, bool bRecordPath ) { UpdateClipRegion(); ImplMap( rPolygon ); @@ -1354,7 +1351,7 @@ namespace emfio } } - void MtfTools::DrawPolyLine( tools::Polygon& rPolygon, bool bTo, bool bRecordPath ) + void MtfTools::DrawPolyLine( tools::Polygon rPolygon, bool bTo, bool bRecordPath ) { UpdateClipRegion(); @@ -1377,7 +1374,7 @@ namespace emfio } } - void MtfTools::DrawPolyBezier( tools::Polygon& rPolygon, bool bTo, bool bRecordPath ) + void MtfTools::DrawPolyBezier( tools::Polygon rPolygon, bool bTo, bool bRecordPath ) { sal_uInt16 nPoints = rPolygon.GetSize(); if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) ) diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx index 3784153b1499..d71e234826d9 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(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(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) { } } -- cgit