summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-06-11 15:51:32 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-06-15 17:55:43 +0200
commit1193a0bb63ab3cc3601b4afcbbf095ef91202da6 (patch)
treef747b0a9b200a30760b3d372b91325f40478db01
parente47ab1464692c5130e19db5a027d694ea5b8c12a (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> (cherry picked from commit 6b349bcc32336664a31deed3f4463e40dd028f63)
-rw-r--r--vcl/qa/cppunit/GraphicTest.cxx81
-rw-r--r--vcl/qa/cppunit/data/wmf-embedded-emfplus.wmfbin0 -> 10610 bytes
-rw-r--r--vcl/source/filter/wmf/wmf.cxx2
3 files changed, 83 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index acabc316bc4b..e4a1f9b53f81 100644
--- a/vcl/qa/cppunit/GraphicTest.cxx
+++ b/vcl/qa/cppunit/GraphicTest.cxx
@@ -27,6 +27,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 testSwapping();
void testSwappingVectorGraphic();
void testWMFRoundtrip();
+ void testWMFWithEmfPlusRoundtrip();
void testEmfToWmfConversion();
CPPUNIT_TEST_SUITE(GraphicTest);
@@ -64,6 +66,7 @@ private:
CPPUNIT_TEST(testSwapping);
CPPUNIT_TEST(testSwappingVectorGraphic);
CPPUNIT_TEST(testWMFRoundtrip);
+ CPPUNIT_TEST(testWMFWithEmfPlusRoundtrip);
CPPUNIT_TEST(testEmfToWmfConversion);
CPPUNIT_TEST_SUITE_END();
};
@@ -303,6 +306,84 @@ void GraphicTest::testUnloadedGraphicSizeUnit()
CPPUNIT_ASSERT_EQUAL(Size(400, 363), aGraphic.GetPrefSize());
}
+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.
+ const GfxLink& rLink = aNewGraphic.GetGfxLink();
+ uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8*>(rLink.GetData()),
+ rLink.GetDataSize());
+ auto aVectorGraphicData
+ = std::make_shared<VectorGraphicData>(aData, OUString(), 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
new file mode 100644
index 000000000000..1e7f75b19809
--- /dev/null
+++ b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf
Binary files differ
diff --git a/vcl/source/filter/wmf/wmf.cxx b/vcl/source/filter/wmf/wmf.cxx
index 17e7634bd756..b729f7a5ec88 100644
--- a/vcl/source/filter/wmf/wmf.cxx
+++ b/vcl/source/filter/wmf/wmf.cxx
@@ -92,6 +92,8 @@ bool ConvertGraphicToWMF(const Graphic& rGraphic, SvStream& rTargetStream,
GfxLink aLink = rGraphic.GetGfxLink();
if (aLink.GetType() == GfxLinkType::NativeWmf && aLink.GetData() && aLink.GetDataSize())
{
+ if(!aLink.IsEMF()) // If WMF, just write directly.
+ return rTargetStream.WriteBytes(aLink.GetData(), aLink.GetDataSize()) == 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.