diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-09-01 13:36:48 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-09-02 01:37:53 +0200 |
commit | 4d33262b1b652b57f222c9f1cce7d976725399d4 (patch) | |
tree | 8eea102563f014640d92242d64a4443cd3542fe3 | |
parent | 6a9e01ed889e92772e32ad5255fc60bd6dd7ee2a (diff) |
sw reqif-xhtml export, embedded objects: prepare pres data earlier
If an embedded object has some native data, we provide presentation data
(replacement graphic) for it in the OLE1 container. We usually take this
from the OLE2 container, but it's OK to omit the presentation data
there.
So refactor to have the presentation data available from the OLE node
(already used for RTF purposes) earlier, that'll allow taking the OLE1
presentation data from RTF if it's missing from OLE2.
Change-Id: Ib6b1b5e843308b0f7af04499de5a1ef5461f7b00
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101840
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/source/filter/html/htmlreqifreader.cxx | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx index 523bc973c587..87368da014bd 100644 --- a/sw/source/filter/html/htmlreqifreader.cxx +++ b/sw/source/filter/html/htmlreqifreader.cxx @@ -231,7 +231,8 @@ OString InsertOLE1HeaderFromOle10NativeStream(tools::SvRef<SotStorage>& xStorage /// Inserts an OLE1 header before an OLE2 storage. OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1, sal_uInt32& nWidth, sal_uInt32& nHeight, - SwOLENode& rOLENode) + SwOLENode& rOLENode, const sal_uInt8* /*pPresentationData*/, + sal_uInt64 /*nPresentationData*/) { rOle2.Seek(0); tools::SvRef<SotStorage> xStorage(new SotStorage(rOle2)); @@ -279,6 +280,7 @@ OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1, sal_uInt32& nWidth, s SvMemoryStream aPresentationData; if (ParseOLE2Presentation(rOle2, nWidth, nHeight, aPresentationData)) { + // Take presentation data for OLE1 from OLE2. // OLEVersion. rOle1.WriteUInt32(0x00000501); // FormatID: constant means the ClassName field is present. @@ -307,8 +309,9 @@ OString InsertOLE1Header(SvStream& rOle2, SvStream& rOle1, sal_uInt32& nWidth, s return aClassName; } -/// Writes rGraphic with size from rOLENode to rRtf as an RTF hexdump. -void WrapOleGraphicInRtf(SvStream& rRtf, const SwOLENode& rOLENode, const Graphic& rGraphic) +/// Writes presentation data with the specified size to rRtf as an RTF hexdump. +void WrapOleGraphicInRtf(SvStream& rRtf, sal_uInt32 nWidth, sal_uInt32 nHeight, + const sal_uInt8* pPresentationData, sal_uInt64 nPresentationData) { // Start result. rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT); @@ -317,23 +320,18 @@ void WrapOleGraphicInRtf(SvStream& rRtf, const SwOLENode& rOLENode, const Graphi 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.WriteOString(OString::number(aSize.getWidth())); + rRtf.WriteOString(OString::number(nWidth)); rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICH); - rRtf.WriteOString(OString::number(aSize.getHeight())); + rRtf.WriteOString(OString::number(nHeight)); rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL); - rRtf.WriteOString(OString::number(aSize.getWidth())); + rRtf.WriteOString(OString::number(nWidth)); rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL); - rRtf.WriteOString(OString::number(aSize.getHeight())); - SvMemoryStream aGraphicStream; - if (GraphicConverter::Export(aGraphicStream, rGraphic, ConvertDataFormat::WMF) == ERRCODE_NONE) + rRtf.WriteOString(OString::number(nHeight)); + if (pPresentationData) { - auto 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); + msfilter::rtfutil::WriteHex(pPresentationData, nPresentationData, &rRtf); } // End pict. @@ -394,9 +392,27 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode) // Write OLE1 header, then the RTF wrapper. SvMemoryStream aOLE1; - sal_uInt32 nWidth = 0; - sal_uInt32 nHeight = 0; - OString aClassName = InsertOLE1Header(rOle2, aOLE1, nWidth, nHeight, rOLENode); + + // Prepare presentation data early, so it's available to both OLE1 and RTF. + Size aSize(rOLENode.GetTwipSize()); + sal_uInt32 nWidth = aSize.getWidth(); + sal_uInt32 nHeight = aSize.getHeight(); + const Graphic* pGraphic = rOLENode.GetGraphic(); + const sal_uInt8* pPresentationData = nullptr; + sal_uInt64 nPresentationData = 0; + SvMemoryStream aGraphicStream; + if (pGraphic) + { + if (GraphicConverter::Export(aGraphicStream, *pGraphic, ConvertDataFormat::WMF) + == ERRCODE_NONE) + { + pPresentationData = static_cast<const sal_uInt8*>(aGraphicStream.GetData()); + nPresentationData = aGraphicStream.TellEnd(); + msfilter::rtfutil::StripMetafileHeader(pPresentationData, nPresentationData); + } + } + OString aClassName = InsertOLE1Header(rOle2, aOLE1, nWidth, nHeight, rOLENode, + pPresentationData, nPresentationData); // Start object. rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_OBJECT); @@ -422,8 +438,10 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode) // End objdata. rRtf.WriteCharPtr("}"); - if (const Graphic* pGraphic = rOLENode.GetGraphic()) - WrapOleGraphicInRtf(rRtf, rOLENode, *pGraphic); + if (pPresentationData) + { + WrapOleGraphicInRtf(rRtf, nWidth, nHeight, pPresentationData, nPresentationData); + } // End object. rRtf.WriteCharPtr("}"); |