summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2018-11-15 14:05:38 +0100
committerMiklos Vajna <vmiklos@collabora.com>2018-11-16 11:44:29 +0100
commit9e80e42c27441ee9cb2ca2cc7ffae440acc5dc4c (patch)
tree26b4bce3b9f9c080eed854c1d550c30567b13056
parentff67eb92954823ee0bc850917a9ead8a1aa03854 (diff)
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. Reviewed-on: https://gerrit.libreoffice.org/63419 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit e807d6158e5bb030e2f884571493f65b285875f8) Conflicts: sw/source/filter/html/htmlreqifreader.hxx Change-Id: I3391303248d2792a4c370e8fc84db0f22185312e
-rw-r--r--sw/qa/extras/htmlexport/htmlexport.cxx28
-rw-r--r--sw/source/filter/html/htmlplug.cxx4
-rw-r--r--sw/source/filter/html/htmlreqifreader.cxx53
-rw-r--r--sw/source/filter/html/htmlreqifreader.hxx3
4 files changed, 84 insertions, 4 deletions
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 3d046d028fa6..a79cc2df55c6 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
{
@@ -578,6 +580,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.remainingSize()));
+ // 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 ad08834ac59a..85865878e88b 100644
--- a/sw/source/filter/html/htmlplug.cxx
+++ b/sw/source/filter/html/htmlplug.cxx
@@ -1548,7 +1548,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";
@@ -1567,7 +1567,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 c39739dfd3b3..f952a06c9c2e 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -19,6 +19,8 @@
#include <svtools/rtftoken.h>
#include <tools/stream.hxx>
#include <filter/msfilter/msdffimp.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <ndole.hxx>
namespace
{
@@ -134,6 +136,44 @@ 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 nCurrent = aGraphicStream.Tell();
+ sal_uInt64 nSize = aGraphicStream.Seek(STREAM_SEEK_TO_END);
+ aGraphicStream.Seek(nCurrent);
+ 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
@@ -179,7 +219,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); });
@@ -198,6 +238,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);
@@ -205,6 +252,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 3b24a4f28311..11818e89761a 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& rOle, SvStream& rRtf);
+bool WrapOleInRtf(SvStream& rOle, SvStream& rRtf, SwOLENode& rOLENode);
/**
* Wraps an image in an RTF fragment.