[Libreoffice-commits] core.git: vcl/qa vcl/skia
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Wed Sep 2 10:44:12 UTC 2020
vcl/qa/cppunit/BackendTest.cxx | 26 ++++++++++++++++++++++++++
vcl/skia/salbmp.cxx | 19 +++++++++++++++----
2 files changed, 41 insertions(+), 4 deletions(-)
New commits:
commit 2e3111838b7fc27065138850cafbb0f0e606d6f3
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Sep 1 21:59:50 2020 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Sep 2 12:43:25 2020 +0200
handle properly cleared bitmap used as alpha for Skia (tdf#136171)
Change-Id: I2c9e5d58247d5fd85aac539728fa857462785090
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101895
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 7a9cf89fceaf..45793434dd1b 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -549,6 +549,31 @@ public:
CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(51, 20)));
}
+ void testTdf136171()
+ {
+ // Create virtual device with alpha.
+ ScopedVclPtr<VirtualDevice> device
+ = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+ device->SetOutputSizePixel(Size(10, 10));
+ device->SetBackground(Wallpaper(COL_WHITE));
+ device->Erase();
+ Bitmap bitmap(Size(10, 10), 24);
+ bitmap.Erase(COL_BLUE);
+ basegfx::B2DHomMatrix matrix;
+ matrix.scale(bitmap.GetSizePixel().Width(),
+ bitmap.GetSizePixel().Height()); // draw as 10x10
+ // Draw a blue bitmap to the device. The bug was that there was no alpha, but OutputDevice::DrawTransformBitmapExDirect()
+ // supplied a fully opaque alpha done with Erase() on the alpha bitmap, and Skia backend didn't handle such alpha correctly.
+ device->DrawTransformedBitmapEx(matrix, BitmapEx(bitmap));
+ exportDevice("/tmp/tdf136171.png", device);
+ // The whole virtual device content now should be blue.
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(9, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(0, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLUE, device->GetPixel(Point(4, 4)));
+ }
+
CPPUNIT_TEST_SUITE(BackendTest);
CPPUNIT_TEST(testDrawRectWithRectangle);
CPPUNIT_TEST(testDrawRectWithPixel);
@@ -602,6 +627,7 @@ public:
CPPUNIT_TEST(testDashedLine);
CPPUNIT_TEST(testTdf124848);
+ CPPUNIT_TEST(testTdf136171);
CPPUNIT_TEST_SUITE_END();
};
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 0da11b1c57d8..378f5557de4e 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -565,6 +565,17 @@ static SkColor toSkColor(Color color)
color.GetBlue());
}
+// If mEraseColor is set, this is the color to use when the bitmap is used as alpha bitmap.
+// E.g. COL_BLACK actually means fully opaque and COL_WHITE means fully transparent.
+// This is because the alpha value is set as the color itself, not the alpha of the color.
+// Additionally VCL actually uses transparency and not opacity, so we should use "255 - value",
+// but we account for this by doing SkBlendMode::kDstOut when using alpha images (which
+// basically does another "255 - alpha"), so do not do it here.
+static SkColor fromEraseColorToAlphaImageColor(Color color)
+{
+ return SkColorSetARGB(color.GetBlue(), 0, 0, 0);
+}
+
const sk_sp<SkImage>& SkiaSalBitmap::GetSkImage() const
{
#ifdef DBG_UTIL
@@ -655,7 +666,7 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const
SkiaZone zone;
sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize, kAlpha_8_SkColorType);
assert(surface);
- surface->getCanvas()->clear(SkColorSetARGB(255 - mEraseColor.GetBlue(), 0, 0, 0));
+ surface->getCanvas()->clear(fromEraseColorToAlphaImageColor(mEraseColor));
SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this);
thisPtr->mAlphaImage = surface->makeImageSnapshot();
SAL_INFO("vcl.skia.trace",
@@ -758,7 +769,7 @@ sk_sp<SkShader> SkiaSalBitmap::GetSkShader() const
sk_sp<SkShader> SkiaSalBitmap::GetAlphaSkShader() const
{
if (mEraseColorSet)
- return SkShaders::Color(toSkColor(mEraseColor));
+ return SkShaders::Color(fromEraseColorToAlphaImageColor(mEraseColor));
return GetAlphaSkImage()->makeShader();
}
@@ -999,8 +1010,8 @@ OString SkiaSalBitmap::GetAlphaImageKey() const
if (mEraseColorSet)
{
std::stringstream ss;
- ss << std::hex << std::setfill('0') << std::setw(2) << (255 - mEraseColor.GetTransparency())
- << std::setw(6) << sal_uInt32(mEraseColor.GetRGBColor());
+ ss << std::hex << std::setfill('0') << std::setw(2)
+ << (255 - SkColorGetA(fromEraseColorToAlphaImageColor(mEraseColor)));
return OStringLiteral("E") + ss.str().c_str();
}
return OStringLiteral("I") + OString::number(GetAlphaSkImage()->uniqueID());
More information about the Libreoffice-commits
mailing list