[Libreoffice-commits] core.git: sw/qa sw/source vcl/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Mar 17 20:42:42 UTC 2021


 sw/qa/extras/htmlexport/data/ole1-pres-data-wmf.odt |binary
 sw/qa/extras/htmlexport/htmlexport.cxx              |   93 +++++++++++++-------
 sw/source/filter/html/htmlreqifreader.cxx           |   11 +-
 vcl/source/filter/wmf/wmfwr.cxx                     |    8 +
 4 files changed, 80 insertions(+), 32 deletions(-)

New commits:
commit 5c7255d3a98568a2965f840b76371cf03eb0d99a
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Mar 17 17:30:52 2021 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Mar 17 21:41:56 2021 +0100

    sw reqif-xhtml export: make sure OLE1 preview is WMF-only
    
    reqif-xhtml has previews for embedded objects at 4 levels:
    
    - png preview
    - RTF preview
    - OLE1 preview
    - OLE2 preview
    
    The OLE1 preview has to be a WMF one, and in case our WMF export tries
    to inject EMF into it, Word will refuse to open the embedded object. So
    add a new flag to allow opting out of the EMF embedding for reqif-xhtml
    export purposes.
    
    The other option would be what Word does to just omit the OLE1 preview,
    but then this would break reqif-xhtml consumers who take the preview
    from the OLE1 data.
    
    Change-Id: Ia8d4626aefb6309743c9f4023f289c9a7b872035
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112648
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/htmlexport/data/ole1-pres-data-wmf.odt b/sw/qa/extras/htmlexport/data/ole1-pres-data-wmf.odt
new file mode 100644
index 000000000000..9bcca729bc52
Binary files /dev/null and b/sw/qa/extras/htmlexport/data/ole1-pres-data-wmf.odt differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index f749c363880e..295acb34f04c 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -119,6 +119,43 @@ bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE)
     rOLE.WriteStream(aStream);
     return true;
 }
+
+/// Parser for [MS-OLEDS] 2.2.5 EmbeddedObject, aka OLE1.
+struct OLE1Reader
+{
+    sal_uInt32 m_nNativeDataSize;
+    sal_uInt32 m_nPresentationDataSize;
+
+    OLE1Reader(SvStream& rStream);
+};
+
+OLE1Reader::OLE1Reader(SvStream& rStream)
+{
+    // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
+    rStream.Seek(0);
+    sal_uInt32 nData;
+    rStream.ReadUInt32(nData); // OLEVersion
+    rStream.ReadUInt32(nData); // FormatID
+    rStream.ReadUInt32(nData); // ClassName
+    rStream.SeekRel(nData);
+    rStream.ReadUInt32(nData); // TopicName
+    rStream.SeekRel(nData);
+    rStream.ReadUInt32(nData); // ItemName
+    rStream.SeekRel(nData);
+
+    rStream.ReadUInt32(m_nNativeDataSize);
+    rStream.SeekRel(m_nNativeDataSize);
+
+    rStream.ReadUInt32(nData); // OLEVersion for presentation data
+    CPPUNIT_ASSERT(rStream.good());
+    rStream.ReadUInt32(nData); // FormatID
+    rStream.ReadUInt32(nData); // ClassName
+    rStream.SeekRel(nData);
+    rStream.ReadUInt32(nData); // Width
+    rStream.ReadUInt32(nData); // Height
+    rStream.ReadUInt32(nData); // PresentationDataSize
+    m_nPresentationDataSize = nData;
+}
 }
 
 class HtmlExportTest : public SwModelTestBase, public HtmlTestTools
@@ -1080,25 +1117,14 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PDF)
     ParseOle1FromRtfUrl(aRtfUrl, aOle1);
 
     // Check the content of the ole1 data.
-    // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
-    aOle1.Seek(0);
-    sal_uInt32 nData;
-    aOle1.ReadUInt32(nData); // OLEVersion
-    aOle1.ReadUInt32(nData); // FormatID
-    aOle1.ReadUInt32(nData); // ClassName
-    aOle1.SeekRel(nData);
-    aOle1.ReadUInt32(nData); // TopicName
-    aOle1.SeekRel(nData);
-    aOle1.ReadUInt32(nData); // ItemName
-    aOle1.SeekRel(nData);
-    aOle1.ReadUInt32(nData); // NativeDataSize
+    OLE1Reader aOle1Reader(aOle1);
 
     // Without the accompanying fix in place, this test would have failed with:
     // - Expected: 39405
     // - Actual  : 43008
     // i.e. we did not work with the Ole10Native stream, rather created an OLE1 wrapper around the
     // OLE1-in-OLE2 data, resulting in additional size.
-    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0x99ed), nData);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0x99ed), aOle1Reader.m_nNativeDataSize);
 
     // Now import this back and check the ODT result.
     mxComponent->dispose();
@@ -1285,26 +1311,33 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PresDataNoOle2)
     ParseOle1FromRtfUrl(aRtfUrl, aOle1);
 
     // Check the content of the ole1 data.
-    // Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
-    aOle1.Seek(0);
-    sal_uInt32 nData;
-    aOle1.ReadUInt32(nData); // OLEVersion
-    aOle1.ReadUInt32(nData); // FormatID
-    aOle1.ReadUInt32(nData); // ClassName
-    aOle1.SeekRel(nData);
-    aOle1.ReadUInt32(nData); // TopicName
-    aOle1.SeekRel(nData);
-    aOle1.ReadUInt32(nData); // ItemName
-    aOle1.SeekRel(nData);
-    aOle1.ReadUInt32(nData); // NativeDataSize
-    aOle1.SeekRel(nData);
-
-    aOle1.ReadUInt32(nData); // OLEVersion for presentation data
-
     // Without the accompanying fix in place, this test would have failed as there was no
     // presentation data after the native data in the OLE1 container. The result was not editable in
     // Word.
-    CPPUNIT_ASSERT(aOle1.good());
+    OLE1Reader aOle1Reader(aOle1);
+}
+
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOle1PresDataWmfOnly)
+{
+    // Save to reqif-xhtml.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "ole1-pres-data-wmf.odt";
+    mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", {});
+    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValue> aStoreProperties = {
+        comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
+        comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")),
+    };
+    xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
+    OUString aRtfUrl = GetOlePath();
+    SvMemoryStream aOle1;
+    ParseOle1FromRtfUrl(aRtfUrl, aOle1);
+
+    OLE1Reader aOle1Reader(aOle1);
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 135660
+    // - Actual  : 272376
+    // i.e. we wrote some additional EMF data into the WMF output, which broke Word.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(135660), aOle1Reader.m_nPresentationDataSize);
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index d656f51bc0cb..40c932ad6332 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -21,6 +21,11 @@
 #include <vcl/cvtgrf.hxx>
 #include <ndole.hxx>
 #include <sal/log.hxx>
+#include <vcl/FilterConfigItem.hxx>
+#include <vcl/wmf.hxx>
+#include <comphelper/propertyvalue.hxx>
+
+using namespace com::sun::star;
 
 namespace
 {
@@ -431,8 +436,10 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode)
     SvMemoryStream aGraphicStream;
     if (pGraphic)
     {
-        if (GraphicConverter::Export(aGraphicStream, *pGraphic, ConvertDataFormat::WMF)
-            == ERRCODE_NONE)
+        uno::Sequence<beans::PropertyValue> aFilterData
+            = { comphelper::makePropertyValue("EmbedEMF", false) };
+        FilterConfigItem aConfigItem(&aFilterData);
+        if (ConvertGraphicToWMF(*pGraphic, aGraphicStream, &aConfigItem))
         {
             pPresentationData = static_cast<const sal_uInt8*>(aGraphicStream.GetData());
             nPresentationData = aGraphicStream.TellEnd();
diff --git a/vcl/source/filter/wmf/wmfwr.cxx b/vcl/source/filter/wmf/wmfwr.cxx
index 6b3d2c248baa..480063e7967b 100644
--- a/vcl/source/filter/wmf/wmfwr.cxx
+++ b/vcl/source/filter/wmf/wmfwr.cxx
@@ -38,6 +38,7 @@
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 #include <memory>
 #include <vcl/fontcharmap.hxx>
+#include <comphelper/sequenceashashmap.hxx>
 
 // MS Windows defines
 
@@ -1691,6 +1692,13 @@ bool WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
         {
             xStatusIndicator->start( OUString(), 100 );
         }
+
+        comphelper::SequenceAsHashMap aMap(pFConfigItem->GetFilterData());
+        auto it = aMap.find("EmbedEMF");
+        if (it != aMap.end())
+        {
+            it->second >>= bEmbedEMF;
+        }
     }
     nLastPercent=0;
 


More information about the Libreoffice-commits mailing list