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 Binary files /dev/null and b/sw/qa/extras/htmlexport/data/transparent.png differ diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx index 8642b5baa4f5..5d9232c8b286 100644 --- a/sw/qa/extras/htmlexport/htmlexport.cxx +++ b/sw/qa/extras/htmlexport/htmlexport.cxx @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -141,6 +142,7 @@ bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE) struct OLE1Reader { sal_uInt32 m_nNativeDataSize; + std::vector m_aNativeData; sal_uInt32 m_nPresentationDataSize; OLE1Reader(SvStream& rStream); @@ -162,7 +164,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()); @@ -1801,6 +1804,49 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqifEmbedShapeAsPNGCustomDPI) OUString::number(aPixelSize.getWidth())); } +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 aArgs = { + comphelper::makePropertyValue("FileName", aImageURL), + }; + dispatchCommand(mxComponent, ".uno:InsertGraphic", aArgs); + + // When exporting to reqif with ExportImagesAsOLE=true: + uno::Reference xStorable(mxComponent, uno::UNO_QUERY); + uno::Sequence 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 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 8cd2728ef7c6..30c027edb351 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"); }