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.

Change-Id: I1b5e9ed37369b541425cfcd7f690e1b0bba97ddc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117144
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
Miklos Vajna 2021-06-14 12:09:01 +02:00
parent 02eea6593e
commit 547386eef9
3 changed files with 54 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -41,6 +41,7 @@
#include <unotools/ucbstreamhelper.hxx>
#include <comphelper/processfactory.hxx>
#include <vcl/graphicfilter.hxx>
#include <vcl/dibtools.hxx>
#include <swmodule.hxx>
#include <swdll.hxx>
@ -141,6 +142,7 @@ bool TestReqIfRtfReader::WriteObjectData(SvStream& rOLE)
struct OLE1Reader
{
sal_uInt32 m_nNativeDataSize;
std::vector<char> 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<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: */

View File

@ -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");
}