[Libreoffice-commits] core.git: Branch 'distro/vector/vector-7.0-10.0' - 2 commits - emfio/inc emfio/source vcl/qa vcl/source
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Tue Jun 15 15:56:41 UTC 2021
emfio/inc/wmfreader.hxx | 5 +
emfio/source/emfuno/xemfparser.cxx | 5 +
emfio/source/reader/emfreader.cxx | 2
emfio/source/reader/wmfreader.cxx | 1
vcl/qa/cppunit/GraphicTest.cxx | 81 +++++++++++++++++++++++++++
vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf |binary
vcl/source/filter/wmf/wmf.cxx | 12 ++--
7 files changed, 100 insertions(+), 6 deletions(-)
New commits:
commit 1193a0bb63ab3cc3601b4afcbbf095ef91202da6
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Jun 11 15:51:32 2021 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Jun 15 17:55:43 2021 +0200
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 at collabora.com>
(cherry picked from commit 6b349bcc32336664a31deed3f4463e40dd028f63)
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
Binary files /dev/null and b/vcl/qa/cppunit/data/wmf-embedded-emfplus.wmf 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.
commit e47ab1464692c5130e19db5a027d694ea5b8c12a
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Jun 11 15:48:32 2021 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Jun 15 17:55:00 2021 +0200
drop EMF+ also when converting WMF, not just EMF
A WMF may have EMF with EMF+ actions embedded. When we read that,
we drop drawing non-EMF+ actions if we use EMF+. But EMF+ actions
are stored as MetaCommentAction in the metafile, and WMF writer
(unlike EMF) writer simply ignores comments. So when writing WMF,
make sure to read non-EMF actions so that something is written.
This is an extension of 295626a0bd39540544b774094a63df23e5376839.
Change-Id: I37355f694fe656b661abe54274ea203934e68151
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117062
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
(cherry picked from commit b342a445cd8b115e76d261860088b012b74c0b0e)
diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx
index 9e1059d63760..85b7c9f0b604 100644
--- a/emfio/inc/wmfreader.hxx
+++ b/emfio/inc/wmfreader.hxx
@@ -51,6 +51,8 @@ namespace emfio
// eventually handed over external header
const WmfExternal* mpExternalHeader;
+ bool mbEnableEMFPlus = true;
+
// reads header of the WMF-Datei
bool ReadHeader();
@@ -68,6 +70,9 @@ namespace emfio
// read WMF file from stream and fill the GDIMetaFile
void ReadWMF();
+
+ // Allows disabling EMF+ if EMF is embedded in this WMF.
+ void SetEnableEMFPlus(bool bEnableEMFPlus) { mbEnableEMFPlus = bEnableEMFPlus; }
};
}
diff --git a/emfio/source/emfuno/xemfparser.cxx b/emfio/source/emfuno/xemfparser.cxx
index 0fd49da1c097..dd5277a7941c 100644
--- a/emfio/source/emfuno/xemfparser.cxx
+++ b/emfio/source/emfuno/xemfparser.cxx
@@ -151,7 +151,10 @@ namespace emfio::emfreader
}
else
{
- emfio::WmfReader(*pStream, aMtf, bExternalHeaderUsed ? &aExternalHeader : nullptr).ReadWMF();
+ emfio::WmfReader aReader(*pStream, aMtf, bExternalHeaderUsed ? &aExternalHeader : nullptr);
+ if (!bEnableEMFPlus)
+ aReader.SetEnableEMFPlus(bEnableEMFPlus);
+ aReader.ReadWMF();
// Need to check for ErrCode at stream to not lose former work.
// This may contain important information and will behave the
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx
index 56349bf0774c..c32ee1e84041 100644
--- a/emfio/source/reader/emfreader.cxx
+++ b/emfio/source/reader/emfreader.cxx
@@ -735,7 +735,7 @@ namespace emfio
bEnableEMFPlus = mbEnableEMFPlus;
}
- SAL_INFO("emfio", "EMF_PLUS_DISABLE is " << (bEnableEMFPlus ? "enabled" : "disabled"));
+ SAL_INFO("emfio", "EMF+ reading is " << (bEnableEMFPlus ? "enabled" : "disabled"));
while( bStatus && mnRecordCount-- && mpInputStream->good())
{
diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx
index aa1c2be7a00e..1a505ae46a3f 100644
--- a/emfio/source/reader/wmfreader.cxx
+++ b/emfio/source/reader/wmfreader.cxx
@@ -1443,6 +1443,7 @@ namespace emfio
GDIMetaFile aMeta;
mpEMFStream->Seek( 0 );
std::unique_ptr<EmfReader> pEMFReader(std::make_unique<EmfReader>( *mpEMFStream, aMeta ));
+ pEMFReader->SetEnableEMFPlus(mbEnableEMFPlus);
bEMFAvailable = pEMFReader->ReadEnhWMF();
pEMFReader.reset(); // destroy first!!!
diff --git a/vcl/source/filter/wmf/wmf.cxx b/vcl/source/filter/wmf/wmf.cxx
index 8a04bc1d3025..17e7634bd756 100644
--- a/vcl/source/filter/wmf/wmf.cxx
+++ b/vcl/source/filter/wmf/wmf.cxx
@@ -90,14 +90,16 @@ bool ConvertGraphicToWMF(const Graphic& rGraphic, SvStream& rTargetStream,
FilterConfigItem const* pConfigItem, bool bPlaceable)
{
GfxLink aLink = rGraphic.GetGfxLink();
- if (aLink.IsEMF() && aLink.GetData() && aLink.GetDataSize())
+ if (aLink.GetType() == GfxLinkType::NativeWmf && aLink.GetData() && aLink.GetDataSize())
{
- // This may be an EMF+ file, converting that to WMF is better done by re-parsing EMF+ as EMF
- // and converting that to WMF.
+ // 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.
uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8*>(aLink.GetData()),
aLink.GetDataSize());
auto aVectorGraphicData
- = std::make_shared<VectorGraphicData>(aData, OUString(), VectorGraphicDataType::Emf);
+ = std::make_shared<VectorGraphicData>(aData, OUString(),
+ aLink.IsEMF() ? VectorGraphicDataType::Emf : VectorGraphicDataType::Wmf);
aVectorGraphicData->setEnableEMFPlus(false);
Graphic aGraphic(aVectorGraphicData);
bool bRet = ConvertGDIMetaFileToWMF(aGraphic.GetGDIMetaFile(), rTargetStream, pConfigItem,
More information about the Libreoffice-commits
mailing list