sw/qa/extras/htmlexport/htmlexport.cxx    |   28 ++++++++++++++++
 sw/source/filter/html/htmlplug.cxx        |    4 +-
 sw/source/filter/html/htmlreqifreader.cxx |   51 +++++++++++++++++++++++++++++-
 sw/source/filter/html/htmlreqifreader.hxx |    3 +
 4 files changed, 82 insertions(+), 4 deletions(-)

New commits:
commit e807d6158e5bb030e2f884571493f65b285875f8
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Nov 15 14:05:38 2018 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Nov 15 19:29:46 2018 +0100

    sw reqif-xhtml export: write graphic of OLE object at an RTF level as well
    
    An embedded object have have its replacement graphic at 3 levels in
    reqif-xhtml: PNG at HTML level, WMF at RTF level and as a stream in the
    OLE2 storage. Some reqif readers depend on having the replacement
    graphic at an RTF level, so write that variant, too.
    
    Change-Id: I3391303248d2792a4c370e8fc84db0f22185312e
    Reviewed-on: https://gerrit.libreoffice.org/63419
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx 
b/sw/qa/extras/htmlexport/htmlexport.cxx
index 81d851a7f831..5ae05a172078 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -23,6 +23,8 @@
 #include <usrpref.hxx>
 
 #include <test/htmltesttools.hxx>
+#include <tools/urlobj.hxx>
+#include <svtools/rtfkeywd.hxx>
 
 class HtmlExportTest : public SwModelTestBase, public HtmlTestTools
 {
@@ -564,6 +566,32 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2, 
"reqif-ole2.xhtml")
     // Finally the export also failed as it tried to open the stream from the
     // document storage, but the embedded object already opened it, so an
     // exception of type com.sun.star.io.IOException was thrown.
+
+    if (mbExported)
+    {
+        // Check that the replacement graphic is exported at RTF level.
+        SvMemoryStream aStream;
+        wrapFragment(aStream);
+        xmlDocPtr pDoc = parseXmlStream(&aStream);
+        CPPUNIT_ASSERT(pDoc);
+        // Get the path of the RTF data.
+        OUString aOlePath = getXPath(
+            pDoc, 
"/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p/reqif-xhtml:object", "data");
+        OUString aOleSuffix(".ole");
+        CPPUNIT_ASSERT(aOlePath.endsWith(aOleSuffix));
+        INetURLObject aUrl(maTempFile.GetURL());
+        aUrl.setBase(aOlePath.copy(0, aOlePath.getLength() - 
aOleSuffix.getLength()));
+        aUrl.setExtension("ole");
+        OUString aOleUrl = 
aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+
+        // Search for \result in the RTF data.
+        SvFileStream aOleStream(aOleUrl, StreamMode::READ);
+        CPPUNIT_ASSERT(aOleStream.IsOpen());
+        OString aOleString(read_uInt8s_ToOString(aOleStream, 
aOleStream.TellEnd()));
+        // Without the accompanying fix in place, this test would have failed,
+        // replacement graphic was missing at RTF level.
+        CPPUNIT_ASSERT(aOleString.indexOf(OOO_STRING_SVTOOLS_RTF_RESULT) != 
-1);
+    }
 }
 
 DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2Odg, "reqif-ole-odg.xhtml")
diff --git a/sw/source/filter/html/htmlplug.cxx 
b/sw/source/filter/html/htmlplug.cxx
index f067d18be3b3..f71e81b9a8cc 100644
--- a/sw/source/filter/html/htmlplug.cxx
+++ b/sw/source/filter/html/htmlplug.cxx
@@ -1534,7 +1534,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, 
const SwFrameFormat& rFrame
             if (xStream.is())
             {
                 std::unique_ptr<SvStream> 
pStream(utl::UcbStreamHelper::CreateStream(xStream));
-                if (SwReqIfReader::WrapOleInRtf(*pStream, aOutStream))
+                if (SwReqIfReader::WrapOleInRtf(*pStream, aOutStream, *pOLENd))
                 {
                     // Data always wrapped in RTF.
                     aFileType = "text/rtf";
@@ -1553,7 +1553,7 @@ Writer& OutHTML_FrameFormatOLENodeGrf( Writer& rWrt, 
const SwFrameFormat& rFrame
             aOLEExp.ExportOLEObject(rOLEObj.GetObject(), *pStorage);
             pStorage->Commit();
             aMemory.Seek(0);
-            if (SwReqIfReader::WrapOleInRtf(aMemory, aOutStream))
+            if (SwReqIfReader::WrapOleInRtf(aMemory, aOutStream, *pOLENd))
             {
                 // Data always wrapped in RTF.
                 aFileType = "text/rtf";
diff --git a/sw/source/filter/html/htmlreqifreader.cxx 
b/sw/source/filter/html/htmlreqifreader.cxx
index cdc443f42cee..fc2c11705b80 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -18,6 +18,8 @@
 #include <svtools/rtftoken.h>
 #include <tools/stream.hxx>
 #include <filter/msfilter/msdffimp.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <ndole.hxx>
 
 namespace
 {
@@ -132,6 +134,42 @@ OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1)
 
     return aClassName;
 }
+
+/// Writes rGraphic with size from rOLENode to rRtf as an RTF hexdump.
+void WrapOleGraphicInRtf(SvStream& rRtf, SwOLENode& rOLENode, const Graphic& 
rGraphic)
+{
+    // Start result.
+    rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT);
+
+    // Start pict.
+    rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT);
+
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_WMETAFILE "8");
+    Size aSize(rOLENode.GetTwipSize());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICW);
+    rRtf.WriteCharPtr(OString::number(aSize.getWidth()).getStr());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICH);
+    rRtf.WriteCharPtr(OString::number(aSize.getHeight()).getStr());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
+    rRtf.WriteCharPtr(OString::number(aSize.getWidth()).getStr());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
+    rRtf.WriteCharPtr(OString::number(aSize.getHeight()).getStr());
+    SvMemoryStream aGraphicStream;
+    if (GraphicConverter::Export(aGraphicStream, rGraphic, 
ConvertDataFormat::WMF) == ERRCODE_NONE)
+    {
+        const sal_uInt8* pGraphicAry = static_cast<const 
sal_uInt8*>(aGraphicStream.GetData());
+        sal_uInt64 nSize = aGraphicStream.TellEnd();
+        msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize);
+        rRtf.WriteCharPtr(SAL_NEWLINE_STRING);
+        msfilter::rtfutil::WriteHex(pGraphicAry, nSize, &rRtf);
+    }
+
+    // End pict.
+    rRtf.WriteCharPtr("}");
+
+    // End result.
+    rRtf.WriteCharPtr("}");
+}
 }
 
 namespace SwReqIfReader
@@ -177,7 +215,7 @@ bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle, 
bool& bOwnFormat)
     return true;
 }
 
-bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf)
+bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode)
 {
     sal_uInt64 nPos = rOle2.Tell();
     comphelper::ScopeGuard g([&rOle2, nPos] { rOle2.Seek(nPos); });
@@ -196,6 +234,13 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf)
     // End objclass.
     rRtf.WriteCharPtr("}");
 
+    // Object size.
+    Size aSize(rOLENode.GetTwipSize());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJW);
+    rRtf.WriteCharPtr(OString::number(aSize.getWidth()).getStr());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJH);
+    rRtf.WriteCharPtr(OString::number(aSize.getHeight()).getStr());
+
     // Start objdata.
     rRtf.WriteCharPtr(
         "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_OBJDATA 
SAL_NEWLINE_STRING);
@@ -203,6 +248,10 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf)
                                 &rRtf);
     // End objdata.
     rRtf.WriteCharPtr("}");
+
+    if (const Graphic* pGraphic = rOLENode.GetGraphic())
+        WrapOleGraphicInRtf(rRtf, rOLENode, *pGraphic);
+
     // End object.
     rRtf.WriteCharPtr("}");
 
diff --git a/sw/source/filter/html/htmlreqifreader.hxx 
b/sw/source/filter/html/htmlreqifreader.hxx
index 494fdbd0ecc6..3d0816739d6a 100644
--- a/sw/source/filter/html/htmlreqifreader.hxx
+++ b/sw/source/filter/html/htmlreqifreader.hxx
@@ -12,6 +12,7 @@
 class Graphic;
 class Size;
 class SvStream;
+class SwOLENode;
 
 namespace SwReqIfReader
 {
@@ -23,7 +24,7 @@ namespace SwReqIfReader
 bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle, bool& bOwnFormat);
 
 /// Wraps an OLE2 container binary in an RTF fragment.
-bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf);
+bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode);
 
 /**
  * Wraps an image in an RTF fragment.
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to