diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-06-11 15:51:32 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-06-11 23:59:46 +0200 |
commit | 6b349bcc32336664a31deed3f4463e40dd028f63 (patch) | |
tree | 796115d4b49deb879f23b961563a9ceb174730e5 | |
parent | b342a445cd8b115e76d261860088b012b74c0b0e (diff) |
when converting WMF to WMF, simply do a direct copy
Actually, if we have the graphics data, just copy the graphics data,
that'll keep both the EMF+ and non-EMF+ content.
Change-Id: Ia14df0ba2a94d4310ee745b49de1d2190e425f05
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117063
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r-- | vcl/qa/cppunit/GraphicTest.cxx | 79 | ||||
-rw-r--r-- | vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf | bin | 0 -> 10610 bytes | |||
-rw-r--r-- | vcl/source/filter/wmf/wmf.cxx | 11 |
3 files changed, 85 insertions, 5 deletions
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx index 608c5f4de85d..e9af574aa5a4 100644 --- a/vcl/qa/cppunit/GraphicTest.cxx +++ b/vcl/qa/cppunit/GraphicTest.cxx @@ -28,6 +28,7 @@ #include <unotools/tempfile.hxx> #include <vcl/cvtgrf.hxx> #include <vcl/metaact.hxx> +#include <vcl/wmf.hxx> #include <impgraph.hxx> #include <graphic/GraphicFormatDetector.hxx> @@ -53,6 +54,7 @@ private: void testUnloadedGraphicSizeUnit(); void testWMFRoundtrip(); + void testWMFWithEmfPlusRoundtrip(); void testEmfToWmfConversion(); void testSwappingGraphic_PNG_WithGfxLink(); @@ -89,6 +91,7 @@ private: CPPUNIT_TEST(testUnloadedGraphicAlpha); CPPUNIT_TEST(testUnloadedGraphicSizeUnit); CPPUNIT_TEST(testWMFRoundtrip); + CPPUNIT_TEST(testWMFWithEmfPlusRoundtrip); CPPUNIT_TEST(testEmfToWmfConversion); CPPUNIT_TEST(testSwappingGraphic_PNG_WithGfxLink); @@ -411,6 +414,82 @@ void GraphicTest::testWMFRoundtrip() CPPUNIT_ASSERT_EQUAL(nExpectedSize, nActualSize); } +int getEmfPlusActionsCount(const Graphic& graphic) +{ + const GDIMetaFile& metafile = graphic.GetGDIMetaFile(); + int emfPlusCount = 0; + for (size_t i = 0; i < metafile.GetActionSize(); ++i) + { + MetaAction* action = metafile.GetAction(i); + if (action->GetType() == MetaActionType::COMMENT) + { + const MetaCommentAction* commentAction = static_cast<const MetaCommentAction*>(action); + if (commentAction->GetComment() == "EMF_PLUS") + ++emfPlusCount; + } + } + return emfPlusCount; +} + +int getPolygonActionsCount(const Graphic& graphic) +{ + const GDIMetaFile& metafile = graphic.GetGDIMetaFile(); + int polygonCount = 0; + for (size_t i = 0; i < metafile.GetActionSize(); ++i) + { + MetaAction* action = metafile.GetAction(i); + if (action->GetType() == MetaActionType::POLYGON) + ++polygonCount; + } + return polygonCount; +} + +void GraphicTest::testWMFWithEmfPlusRoundtrip() +{ + // Load a WMF file. + test::Directories aDirectories; + OUString aURL = aDirectories.getURLFromSrc(u"vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf"); + SvFileStream aStream(aURL, StreamMode::READ); + sal_uInt64 nExpectedSize = aStream.TellEnd(); + GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); + Graphic aGraphic = rGraphicFilter.ImportUnloadedGraphic(aStream); + + CPPUNIT_ASSERT_GREATER(0, getEmfPlusActionsCount(aGraphic)); + CPPUNIT_ASSERT_EQUAL(0, getPolygonActionsCount(aGraphic)); + + for (bool useConvertMetafile : { false, true }) + { + // Save as WMF. + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + SvStream& rOutStream = *aTempFile.GetStream(StreamMode::READWRITE); + if (useConvertMetafile) + ConvertGraphicToWMF(aGraphic, rOutStream, nullptr); + else + { + sal_uInt16 nFormat = rGraphicFilter.GetExportFormatNumberForShortName(u"WMF"); + rGraphicFilter.ExportGraphic(aGraphic, OUString(), rOutStream, nFormat); + } + CPPUNIT_ASSERT_EQUAL(nExpectedSize, rOutStream.TellEnd()); + + rOutStream.Seek(0); + Graphic aNewGraphic = rGraphicFilter.ImportUnloadedGraphic(rOutStream); + // Check that reading the WMF back preserves the EMF+ actions in it. + CPPUNIT_ASSERT_GREATER(0, getEmfPlusActionsCount(aNewGraphic)); + // EmfReader::ReadEnhWMF() drops non-EMF+ drawing actions if EMF+ is found. + CPPUNIT_ASSERT_EQUAL(0, getPolygonActionsCount(aNewGraphic)); + + // With EMF+ disabled there should be no EMF+ actions. + auto& rDataContainer = aNewGraphic.GetGfxLink().getDataContainer(); + auto aVectorGraphicData + = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Wmf); + aVectorGraphicData->setEnableEMFPlus(false); + Graphic aNoEmfPlusGraphic(aVectorGraphicData); + CPPUNIT_ASSERT_EQUAL(0, getEmfPlusActionsCount(aNoEmfPlusGraphic)); + CPPUNIT_ASSERT_GREATER(0, getPolygonActionsCount(aNoEmfPlusGraphic)); + } +} + void GraphicTest::testEmfToWmfConversion() { // Load EMF data. diff --git a/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf Binary files differnew file mode 100644 index 000000000000..1e7f75b19809 --- /dev/null +++ b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf diff --git a/vcl/source/filter/wmf/wmf.cxx b/vcl/source/filter/wmf/wmf.cxx index ee1ce77e4185..bf91502b426e 100644 --- a/vcl/source/filter/wmf/wmf.cxx +++ b/vcl/source/filter/wmf/wmf.cxx @@ -90,13 +90,14 @@ bool ConvertGraphicToWMF(const Graphic& rGraphic, SvStream& rTargetStream, GfxLink aLink = rGraphic.GetGfxLink(); if (aLink.GetType() == GfxLinkType::NativeWmf && aLink.GetData() && aLink.GetDataSize()) { - // This may be an EMF+ file or WMF file with EMF+ embedded. In EmfReader::ReadEnhWMF() - // we normally drop non-EMF commands when reading EMF+, so converting that to WMF - // is better done by re-parsing with EMF+ disabled. + if(!aLink.IsEMF()) // If WMF, just write directly. + return rTargetStream.WriteBytes(aLink.GetData(), aLink.GetDataSize()) == aLink.GetDataSize(); + + // This may be an EMF+ file. In EmfReader::ReadEnhWMF() we normally drop non-EMF commands + // when reading EMF+, so converting that to WMF is better done by re-parsing with EMF+ disabled. auto & rDataContainer = aLink.getDataContainer(); auto aVectorGraphicData - = std::make_shared<VectorGraphicData>(rDataContainer, - aLink.IsEMF() ? VectorGraphicDataType::Emf : VectorGraphicDataType::Wmf); + = std::make_shared<VectorGraphicData>(rDataContainer, VectorGraphicDataType::Emf); aVectorGraphicData->setEnableEMFPlus(false); Graphic aGraphic(aVectorGraphicData); bool bRet = ConvertGDIMetaFileToWMF(aGraphic.GetGDIMetaFile(), rTargetStream, pConfigItem, |