diff options
-rw-r--r-- | sw/qa/extras/htmlexport/htmlexport.cxx | 28 | ||||
-rw-r--r-- | sw/source/filter/html/htmlplug.cxx | 4 | ||||
-rw-r--r-- | sw/source/filter/html/htmlreqifreader.cxx | 51 | ||||
-rw-r--r-- | sw/source/filter/html/htmlreqifreader.hxx | 3 |
4 files changed, 82 insertions, 4 deletions
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. |