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>
diff --git a/vcl/qa/cppunit/GraphicTest.cxx b/vcl/qa/cppunit/GraphicTest.cxx
index 608c5f4..e9af574 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 0000000..1e7f75b
--- /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 ee1ce77..bf91502 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,