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.lu...@collabora.com> AuthorDate: Tue Sep 1 21:59:50 2020 +0200 Commit: Luboš Luňák <l.lu...@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.lu...@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()); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits