summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-06-14 12:09:01 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-06-16 10:19:28 +0200
commit296e438f7ac3ea221c0e94e0726c30285c3f2509 (patch)
treeab2179ed14349c28ad62e232b556f80e81b7838f
parent1193a0bb63ab3cc3601b4afcbbf095ef91202da6 (diff)
sw XHTML/reqif export, OLE data for transparent images: avoid black background
Once a semi-transparent images is exported to reqif in OLE mode, the native data is 24bit BMP. This needs some solid color as a background for the transparent pixels. The OLE presentation data had white, the OLE native data had black, so this was inconsistent. Fix the problem by going with white for the native data as well. (cherry picked from commit 547386eef9b1723812dfdab5aed33e9025a372c6) Change-Id: I1b5e9ed37369b541425cfcd7f690e1b0bba97ddc
-rw-r--r--sw/qa/extras/htmlexport/data/transparent.pngbin0 -> 2950 bytes
-rw-r--r--sw/qa/extras/htmlexport/htmlexport.cxx48
-rw-r--r--sw/source/filter/html/htmlreqifreader.cxx8
3 files changed, 54 insertions, 2 deletions
diff --git a/sw/qa/extras/htmlexport/data/transparent.png b/sw/qa/extras/htmlexport/data/transparent.png
new file mode 100644
index 000000000000..936980b0a19b
--- /dev/null
+++ b/sw/qa/extras/htmlexport/data/transparent.png
Binary files differ
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index 50e001c72890..fd9e4ee06583 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -38,6 +38,7 @@
#include <filter/msfilter/rtfutil.hxx>
#include <sot/storage.hxx>
#include <svl/eitem.hxx>
+#include <vcl/dibtools.hxx>
namespace
{
@@ -129,6 +130,7 @@ bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE)
struct OLE1Reader
{
sal_uInt32 m_nNativeDataSize;
+ std::vector<char> m_aNativeData;
sal_uInt32 m_nPresentationDataSize;
OLE1Reader(SvStream& rStream);
@@ -150,7 +152,8 @@ OLE1Reader::OLE1Reader(SvStream& rStream)
rStream.SeekRel(nData);
rStream.ReadUInt32(m_nNativeDataSize);
- rStream.SeekRel(m_nNativeDataSize);
+ m_aNativeData.resize(m_nNativeDataSize);
+ rStream.ReadBytes(m_aNativeData.data(), m_aNativeData.size());
rStream.ReadUInt32(nData); // OLEVersion for presentation data
CPPUNIT_ASSERT(rStream.good());
@@ -1494,6 +1497,49 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifImageToOle)
CPPUNIT_ASSERT(aOle1Reader.m_nPresentationDataSize);
}
+CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifOleBmpTransparent)
+{
+ // Given a document with a transparent image:
+ loadURL("private:factory/swriter", nullptr);
+ OUString aImageURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "transparent.png";
+ uno::Sequence<beans::PropertyValue> aArgs = {
+ comphelper::makePropertyValue("FileName", aImageURL),
+ };
+ dispatchCommand(mxComponent, ".uno:InsertGraphic", aArgs);
+
+ // When exporting to reqif with ExportImagesAsOLE=true:
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aStoreProperties = {
+ comphelper::makePropertyValue("FilterName", OUString("HTML (StarWriter)")),
+ comphelper::makePropertyValue("FilterOptions", OUString("xhtmlns=reqif-xhtml")),
+ comphelper::makePropertyValue("ExportImagesAsOLE", true),
+ };
+ xStorable->storeToURL(maTempFile.GetURL(), aStoreProperties);
+
+ // Then make sure the transparent pixel turns into white:
+ OUString aRtfUrl = GetOlePath();
+ SvMemoryStream aRtf;
+ HtmlExportTest::wrapRtfFragment(aRtfUrl, aRtf);
+ tools::SvRef<TestReqIfRtfReader> xReader(new TestReqIfRtfReader(aRtf));
+ CPPUNIT_ASSERT(xReader->CallParser() != SvParserState::Error);
+ SvMemoryStream aOle1;
+ CPPUNIT_ASSERT(xReader->WriteObjectData(aOle1));
+ OLE1Reader aOle1Reader(aOle1);
+ SvMemoryStream aBitmapStream(aOle1Reader.m_aNativeData.data(), aOle1Reader.m_aNativeData.size(),
+ StreamMode::READ);
+ Bitmap aBitmap;
+ ReadDIB(aBitmap, aBitmapStream, /*bFileHeader=*/true);
+ Size aBitmapSize = aBitmap.GetSizePixel();
+ BitmapEx aBitmapEx(aBitmap);
+ Color nActualColor
+ = aBitmapEx.GetPixelColor(aBitmapSize.getWidth() - 1, aBitmapSize.getHeight() - 1);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: Color: R:255 G:255 B:255 A:0
+ // - Actual : Color: R:0 G:0 B:0 A:0
+ // i.e. the bitmap without an alpha channel was black, not white.
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, nActualColor);
+}
+
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 8a6101fa93ee..a091183b9f69 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -545,7 +545,13 @@ bool WrapGraphicInRtf(const Graphic& rGraphic, const SwFrameFormat& rFormat, SvS
// NativeDataSize
SvMemoryStream aNativeData;
- if (GraphicConverter::Export(aNativeData, rGraphic, ConvertDataFormat::BMP) != ERRCODE_NONE)
+
+ // Set white background for the semi-transparent pixels.
+ BitmapEx aBitmapEx = rGraphic.GetBitmapEx();
+ Bitmap aBitmap = aBitmapEx.GetBitmap(/*aTransparentReplaceColor=*/COL_WHITE);
+
+ if (GraphicConverter::Export(aNativeData, BitmapEx(aBitmap), ConvertDataFormat::BMP)
+ != ERRCODE_NONE)
{
SAL_WARN("sw.html", "WrapGraphicInRtf: bmp conversion failed");
}