[Libreoffice-commits] core.git: Branch 'distro/vector/vector-7.0' - 3 commits - sw/qa sw/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Mon May 31 08:06:40 UTC 2021
sw/qa/extras/htmlexport/htmlexport.cxx | 44 ++++++++
sw/source/filter/html/htmlflywriter.cxx | 2
sw/source/filter/html/htmlreqifreader.cxx | 156 ++++++++++++++++++++++--------
sw/source/filter/html/htmlreqifreader.hxx | 4
4 files changed, 162 insertions(+), 44 deletions(-)
New commits:
commit 7a5717cb8ad4c6b30d46ad86326fa4274bd84f12
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri May 28 16:02:50 2021 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon May 31 10:04:24 2021 +0200
sw XHTML / reqif export, RTF markup of images: write OLE1 presentation data
With this, images are exported as PBrush OLE objects, to please some
consumers (e.g. IBM Doors).
(cherry picked from commit 5fbd20682f34c817359156889ecbc3ad8290d72c)
Conflicts:
sw/source/filter/html/htmlreqifreader.cxx
Change-Id: I89805cd66709d96cbe71853d65671f76a3fc871f
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 5074c5e54e0d..50e001c72890 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -152,11 +152,6 @@ OLE1Reader::OLE1Reader(SvStream& rStream)
rStream.ReadUInt32(m_nNativeDataSize);
rStream.SeekRel(m_nNativeDataSize);
- if (!rStream.remainingSize())
- {
- return;
- }
-
rStream.ReadUInt32(nData); // OLEVersion for presentation data
CPPUNIT_ASSERT(rStream.good());
rStream.ReadUInt32(nData); // FormatID
@@ -1492,6 +1487,11 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifImageToOle)
// Without the accompanying fix in place, this test would have failed, as aOle1 was empty.
OLE1Reader aOle1Reader(aOle1);
CPPUNIT_ASSERT(aOle1Reader.m_nNativeDataSize);
+
+ // Make sure that the presentation data byte array is not empty.
+ // Without the accompanying fix in place, this test would have failed, as aOle1 only contained
+ // the native data.
+ CPPUNIT_ASSERT(aOle1Reader.m_nPresentationDataSize);
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index 70b0d697ea4a..8a6101fa93ee 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -555,18 +555,7 @@ bool WrapGraphicInRtf(const Graphic& rGraphic, const SwFrameFormat& rFormat, SvS
aNativeData.Seek(0);
aOle1.WriteStream(aNativeData);
- // TODO Write Presentation.
-
- // End objdata.
- msfilter::rtfutil::WriteHex(static_cast<const sal_uInt8*>(aOle1.GetData()), aOle1.GetSize(),
- &rRtf);
- rRtf.WriteCharPtr("}");
- rRtf.WriteOString(SAL_NEWLINE_STRING);
-
- rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT);
- rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT);
-
- // Prepare presendation data.
+ // Prepare presentation data.
const sal_uInt8* pPresentationData = nullptr;
sal_uInt64 nPresentationData = 0;
SvMemoryStream aGraphicStream;
@@ -580,6 +569,43 @@ bool WrapGraphicInRtf(const Graphic& rGraphic, const SwFrameFormat& rFormat, SvS
msfilter::rtfutil::StripMetafileHeader(pPresentationData, nPresentationData);
}
+ // Write Presentation.
+ // OLEVersion.
+ aOle1.WriteUInt32(0x00000501);
+ // FormatID: constant means the ClassName field is present.
+ aOle1.WriteUInt32(0x00000005);
+ // ClassName: null terminated pascal string.
+ OString aPresentationClassName("METAFILEPICT");
+ aOle1.WriteUInt32(aPresentationClassName.getLength() + 1);
+ aOle1.WriteOString(aPresentationClassName);
+ aOle1.WriteChar(0);
+ const sal_uInt8* pBytes = nullptr;
+ sal_uInt64 nBytes = 0;
+ // Take presentation data for OLE1 from RTF.
+ pBytes = pPresentationData;
+ nBytes = nPresentationData;
+ // Width.
+ aOle1.WriteUInt32(nWidth);
+ // Height.
+ aOle1.WriteUInt32(nHeight * -1);
+ // PresentationDataSize: size of (reserved fields + pBytes).
+ aOle1.WriteUInt32(8 + nBytes);
+ // Reserved1-4.
+ aOle1.WriteUInt16(0x0008);
+ aOle1.WriteUInt16(0x31b1);
+ aOle1.WriteUInt16(0x1dd9);
+ aOle1.WriteUInt16(0x0000);
+ aOle1.WriteBytes(pBytes, nBytes);
+
+ // End objdata.
+ msfilter::rtfutil::WriteHex(static_cast<const sal_uInt8*>(aOle1.GetData()), aOle1.GetSize(),
+ &rRtf);
+ rRtf.WriteCharPtr("}");
+ rRtf.WriteOString(SAL_NEWLINE_STRING);
+
+ rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT);
+ rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT);
+
Size aMapped(rGraphic.GetPrefSize());
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICW);
rRtf.WriteOString(OString::number(aMapped.Width()));
commit ffbf6916e2bd7de4daa862e11e52c9ff24929260
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu May 27 16:54:59 2021 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri May 28 16:20:07 2021 +0200
sw XHTML / reqif export, RTF markup of images: write objdata
The native data is BMP, presentation data is not yet done.
(cherry picked from commit ff1f80e025a7c235e3960affe1b9db844c89c214)
Change-Id: I30ef9f0c3b4dc7801e600ac751c32179372d5e4e
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 105d90d39b18..5074c5e54e0d 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -138,6 +138,7 @@ OLE1Reader::OLE1Reader(SvStream& rStream)
{
// Skip ObjectHeader, see [MS-OLEDS] 2.2.4.
rStream.Seek(0);
+ CPPUNIT_ASSERT(rStream.remainingSize());
sal_uInt32 nData;
rStream.ReadUInt32(nData); // OLEVersion
rStream.ReadUInt32(nData); // FormatID
@@ -151,6 +152,11 @@ OLE1Reader::OLE1Reader(SvStream& rStream)
rStream.ReadUInt32(m_nNativeDataSize);
rStream.SeekRel(m_nNativeDataSize);
+ if (!rStream.remainingSize())
+ {
+ return;
+ }
+
rStream.ReadUInt32(nData); // OLEVersion for presentation data
CPPUNIT_ASSERT(rStream.good());
rStream.ReadUInt32(nData); // FormatID
@@ -1479,6 +1485,13 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifImageToOle)
// - Actual : 0
// i.e. the image was exported as PNG, not as WMF (with a version).
CPPUNIT_ASSERT_EQUAL(8, xReader->getWmetafile());
+
+ // Make sure that the native data byte array is not empty.
+ SvMemoryStream aOle1;
+ CPPUNIT_ASSERT(xReader->WriteObjectData(aOle1));
+ // Without the accompanying fix in place, this test would have failed, as aOle1 was empty.
+ OLE1Reader aOle1Reader(aOle1);
+ CPPUNIT_ASSERT(aOle1Reader.m_nNativeDataSize);
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx
index 184c911956a9..e5a3b482bd61 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -1881,7 +1881,7 @@ static Writer& OutHTML_FrameFormatGrfNode( Writer& rWrt, const SwFrameFormat& rF
aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
SvFileStream aOutStream(aFileName, StreamMode::WRITE);
- if (!SwReqIfReader::WrapGraphicInRtf(aGraphic, pGrfNd->GetTwipSize(), aOutStream))
+ if (!SwReqIfReader::WrapGraphicInRtf(aGraphic, rFrameFormat, aOutStream))
SAL_WARN("sw.html", "SwReqIfReader::WrapGraphicInRtf() failed");
// Refer to this data.
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index 16be43358972..70b0d697ea4a 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -496,12 +496,73 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode,
return true;
}
-bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream& rRtf)
+bool WrapGraphicInRtf(const Graphic& rGraphic, const SwFrameFormat& rFormat, SvStream& rRtf)
{
// Start object.
rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_OBJECT);
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJEMB);
+ // Object size: as used in the document model (not pixel size)
+ Size aSize = rFormat.GetFrameSize().GetSize();
+ sal_uInt32 nWidth = aSize.getWidth();
+ sal_uInt32 nHeight = aSize.getHeight();
+ rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJW);
+ rRtf.WriteOString(OString::number(nWidth));
+ rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJH);
+ rRtf.WriteOString(OString::number(nHeight));
+ rRtf.WriteOString(SAL_NEWLINE_STRING);
+
+ // Start objclass.
+ rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_OBJCLASS " ");
+ OString aClassName("PBrush");
+ rRtf.WriteOString(aClassName);
+ // End objclass.
+ rRtf.WriteCharPtr("}");
+ rRtf.WriteOString(SAL_NEWLINE_STRING);
+
+ // Start objdata.
+ rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_OBJDATA " ");
+
+ SvMemoryStream aOle1;
+ // Write ObjectHeader, see [MS-OLEDS] 2.2.4.
+ // OLEVersion.
+ aOle1.WriteUInt32(0x00000501);
+
+ // FormatID is EmbeddedObject.
+ aOle1.WriteUInt32(0x00000002);
+
+ // ClassName
+ aOle1.WriteUInt32(aClassName.getLength() + 1);
+ aOle1.WriteOString(aClassName);
+ // Null terminated pascal string.
+ aOle1.WriteChar(0);
+
+ // TopicName.
+ aOle1.WriteUInt32(0);
+
+ // ItemName.
+ aOle1.WriteUInt32(0);
+
+ // NativeDataSize
+ SvMemoryStream aNativeData;
+ if (GraphicConverter::Export(aNativeData, rGraphic, ConvertDataFormat::BMP) != ERRCODE_NONE)
+ {
+ SAL_WARN("sw.html", "WrapGraphicInRtf: bmp conversion failed");
+ }
+ aOle1.WriteUInt32(aNativeData.TellEnd());
+
+ // Write the actual native data.
+ aNativeData.Seek(0);
+ aOle1.WriteStream(aNativeData);
+
+ // TODO Write Presentation.
+
+ // End objdata.
+ msfilter::rtfutil::WriteHex(static_cast<const sal_uInt8*>(aOle1.GetData()), aOle1.GetSize(),
+ &rRtf);
+ rRtf.WriteCharPtr("}");
+ rRtf.WriteOString(SAL_NEWLINE_STRING);
+
rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT);
rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT);
@@ -526,9 +587,9 @@ bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream&
rRtf.WriteOString(OString::number(aMapped.Height()));
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
- rRtf.WriteOString(OString::number(rLogicSize.Width()));
+ rRtf.WriteOString(OString::number(nWidth));
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
- rRtf.WriteOString(OString::number(rLogicSize.Height()));
+ rRtf.WriteOString(OString::number(nHeight));
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_WMETAFILE "8");
rRtf.WriteOString(SAL_NEWLINE_STRING);
diff --git a/sw/source/filter/html/htmlreqifreader.hxx b/sw/source/filter/html/htmlreqifreader.hxx
index 5f757d0fbf1d..84169bb7c087 100644
--- a/sw/source/filter/html/htmlreqifreader.hxx
+++ b/sw/source/filter/html/htmlreqifreader.hxx
@@ -30,10 +30,8 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode,
/**
* Wraps an image in an RTF fragment.
- *
- * @param rLogicSize the size used in the document model (not pixel size)
*/
-bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream& rRtf);
+bool WrapGraphicInRtf(const Graphic& rGraphic, const SwFrameFormat& rFormat, SvStream& rRtf);
}
#endif // INCLUDED_SW_SOURCE_FILTER_HTML_HTMLREQIFREADER_HXX
commit 0b4b0fcd873d62bec9e826c174d8334a1d7d3228
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed May 26 17:46:53 2021 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri May 28 16:12:38 2021 +0200
sw XHTML / reqif export, RTF markup of images: write WMF in \pict
Some consumers (e.g. IBM Doors) can only consume the RTF snippet if it's
an OLE object and can't deal with plain images.
Wrap \pict inside \object and unconditionally use WMF as the RTF-level
preview format. The actual \objdata is not yet written.
(cherry picked from commit 0e459bb3eb840ac1cab14c070973fb3b79bc13d8)
Conflicts:
sw/qa/extras/htmlexport/htmlexport.cxx
Change-Id: I203fcd8709b25a4dd543047bd804af8181df9940
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index ad64b6404007..105d90d39b18 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -50,12 +50,14 @@ public:
bool WriteObjectData(SvStream& rOLE);
long GetObjw() const { return m_nObjw; }
long GetObjh() const { return m_nObjh; }
+ int getWmetafile() const { return m_nWmetafile; }
private:
bool m_bInObjData = false;
OStringBuffer m_aHex;
long m_nObjw = 0;
long m_nObjh = 0;
+ int m_nWmetafile = 0;
};
TestReqIfRtfReader::TestReqIfRtfReader(SvStream& rStream)
@@ -83,6 +85,9 @@ void TestReqIfRtfReader::NextToken(int nToken)
case RTF_OBJH:
m_nObjh = nTokenValue;
break;
+ case RTF_WMETAFILE:
+ m_nWmetafile = nTokenValue;
+ break;
}
}
@@ -1450,6 +1455,32 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testBlockQuoteNoMargin)
"string");
}
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifImageToOle)
+{
+ // Given a document with an image:
+ loadURL("private:factory/swriter", nullptr);
+ OUString aImageURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "ole2.png";
+ uno::Sequence<beans::PropertyValue> aArgs = {
+ comphelper::makePropertyValue("FileName", aImageURL),
+ };
+ dispatchCommand(mxComponent, ".uno:InsertGraphic", aArgs);
+
+ // When exporting to XHTML:
+ ExportToReqif();
+
+ // Then make sure we export that PNG as WMF in ReqIF mode:
+ OUString aRtfUrl = GetOlePath();
+ SvMemoryStream aRtf;
+ HtmlExportTest::wrapRtfFragment(aRtfUrl, aRtf);
+ tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
+ CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+ // Without the accompanying fix in place, this test would have failed:
+ // - Expected: 8
+ // - Actual : 0
+ // i.e. the image was exported as PNG, not as WMF (with a version).
+ CPPUNIT_ASSERT_EQUAL(8, xReader->getWmetafile());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index 47cf2341e1e5..16be43358972 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -498,42 +498,27 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf, SwOLENode& rOLENode,
bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream& rRtf)
{
+ // Start object.
+ rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_OBJECT);
+ rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_OBJEMB);
+
+ rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_RESULT);
rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT);
- GfxLink aLink = rGraphic.GetGfxLink();
- const sal_uInt8* pGraphicAry = aLink.GetData();
- sal_uInt64 nSize = aLink.GetDataSize();
- OString aBlipType;
- bool bIsWMF = false;
- switch (aLink.GetType())
+ // Prepare presendation data.
+ const sal_uInt8* pPresentationData = nullptr;
+ sal_uInt64 nPresentationData = 0;
+ SvMemoryStream aGraphicStream;
+ uno::Sequence<beans::PropertyValue> aFilterData
+ = { comphelper::makePropertyValue("EmbedEMF", false) };
+ FilterConfigItem aConfigItem(&aFilterData);
+ if (ConvertGraphicToWMF(rGraphic, aGraphicStream, &aConfigItem))
{
- case GfxLinkType::NativeBmp:
- aBlipType = OOO_STRING_SVTOOLS_RTF_WBITMAP;
- break;
- case GfxLinkType::NativeJpg:
- aBlipType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
- break;
- case GfxLinkType::NativePng:
- aBlipType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
- break;
- case GfxLinkType::NativeWmf:
- if (aLink.IsEMF())
- aBlipType = OOO_STRING_SVTOOLS_RTF_EMFBLIP;
- else
- {
- aBlipType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
- bIsWMF = true;
- }
- break;
- default:
- break;
+ pPresentationData = static_cast<const sal_uInt8*>(aGraphicStream.GetData());
+ nPresentationData = aGraphicStream.TellEnd();
+ msfilter::rtfutil::StripMetafileHeader(pPresentationData, nPresentationData);
}
- if (aBlipType.isEmpty())
- return false;
-
- rRtf.WriteOString(aBlipType);
-
Size aMapped(rGraphic.GetPrefSize());
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICW);
rRtf.WriteOString(OString::number(aMapped.Width()));
@@ -544,19 +529,23 @@ bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream&
rRtf.WriteOString(OString::number(rLogicSize.Width()));
rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
rRtf.WriteOString(OString::number(rLogicSize.Height()));
+ rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_WMETAFILE "8");
+ rRtf.WriteOString(SAL_NEWLINE_STRING);
- if (bIsWMF)
+ if (pPresentationData)
{
- rRtf.WriteOString(OString::number(8));
- msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize);
+ msfilter::rtfutil::WriteHex(pPresentationData, nPresentationData, &rRtf);
+ rRtf.WriteOString(SAL_NEWLINE_STRING);
}
- rRtf.WriteOString(SAL_NEWLINE_STRING);
-
- msfilter::rtfutil::WriteHex(pGraphicAry, nSize, &rRtf);
- rRtf.WriteOString(SAL_NEWLINE_STRING);
// End pict.
rRtf.WriteCharPtr("}");
+
+ // End result.
+ rRtf.WriteCharPtr("}");
+
+ // End object.
+ rRtf.WriteCharPtr("}");
return true;
}
}
More information about the Libreoffice-commits
mailing list