summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-06-11 15:51:32 +0200
committerLuboš Luňák <l.lunak@collabora.com>2021-06-11 23:59:46 +0200
commit6b349bcc32336664a31deed3f4463e40dd028f63 (patch)
tree796115d4b49deb879f23b961563a9ceb174730e5
parentb342a445cd8b115e76d261860088b012b74c0b0e (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.cxx79
-rw-r--r--vcl/qa/cppunit/data/wmf-embedded-emfplus.wmfbin0 -> 10610 bytes
-rw-r--r--vcl/source/filter/wmf/wmf.cxx11
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
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 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,