summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-09-02 11:45:10 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-09-04 17:29:13 +0200
commitc5b6f8d6469850e14362f2c8f08cdf8c956cbf07 (patch)
treec2805f3ce0e36c26e88d9ba3e44de2d47e0e3461
parentc4ea034beb2fa0f1e874a39391a9498bdd7c7aad (diff)
fix erasing virtual device with alpha
The background cannot be simply set as background also for the internal alpha virtual device, since this hackish alpha uses black = opaque and white = transparent. So e.g. setting to background to COL_WHITE actually resulted in the content being transparent. Try to map to what the alpha virtual device actually needs. Change-Id: Ie5179769d9bce989eddfc96f5cbd2b94d1d88d53 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101927 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r--vcl/qa/cppunit/BackendTest.cxx69
-rw-r--r--vcl/source/outdev/outdevstate.cxx39
2 files changed, 106 insertions, 2 deletions
diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 45793434dd1b..0e3d9c54dd08 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -49,7 +49,7 @@ class BackendTest : public test::BootstrapFixture
{
if (mbExportBitmap)
{
- BitmapEx aBitmapEx(device->GetBitmap(Point(0, 0), device->GetOutputSizePixel()));
+ BitmapEx aBitmapEx(device->GetBitmapEx(Point(0, 0), device->GetOutputSizePixel()));
SvFileStream aStream(filename, StreamMode::WRITE | StreamMode::TRUNC);
GraphicFilter::GetGraphicFilter().compressAsPNG(aBitmapEx, aStream);
}
@@ -517,6 +517,71 @@ public:
// vcl::test::OutputDeviceTestGradient does not verify anything, cannot test here
+ void testErase()
+ {
+ {
+ // Create normal virtual device (no alpha).
+ ScopedVclPtr<VirtualDevice> device
+ = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT);
+ device->SetOutputSizePixel(Size(10, 10));
+ // Erase with white, check it's white.
+ device->SetBackground(Wallpaper(COL_WHITE));
+ device->Erase();
+ exportDevice("/tmp/12-01_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(5, 5)));
+ // Erase with black, check it's black.
+ device->SetBackground(Wallpaper(COL_BLACK));
+ device->Erase();
+ exportDevice("/tmp/12-02_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(5, 5)));
+ // Erase with cyan, check it's cyan.
+ device->SetBackground(Wallpaper(COL_CYAN));
+ device->Erase();
+ exportDevice("/tmp/12-03_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(5, 5)));
+ }
+ {
+ // Create virtual device with alpha.
+ ScopedVclPtr<VirtualDevice> device
+ = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+ device->SetOutputSizePixel(Size(10, 10));
+ // Erase with white, check it's white.
+ device->SetBackground(Wallpaper(COL_WHITE));
+ device->Erase();
+ exportDevice("/tmp/12-04_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_WHITE, device->GetPixel(Point(5, 5)));
+ // Erase with black, check it's black.
+ device->SetBackground(Wallpaper(COL_BLACK));
+ device->Erase();
+ exportDevice("/tmp/12-05_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_BLACK, device->GetPixel(Point(5, 5)));
+ // Erase with cyan, check it's cyan.
+ device->SetBackground(Wallpaper(COL_CYAN));
+ device->Erase();
+ exportDevice("/tmp/12-06_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(0, 0)));
+ CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(9, 9)));
+ CPPUNIT_ASSERT_EQUAL(COL_CYAN, device->GetPixel(Point(5, 5)));
+ // Erase with transparent, check it's transparent.
+ device->SetBackground(Wallpaper(COL_TRANSPARENT));
+ device->Erase();
+ exportDevice("/tmp/12-07_erase.png", device);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), device->GetPixel(Point(0, 0)).GetTransparency());
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), device->GetPixel(Point(9, 9)).GetTransparency());
+ CPPUNIT_ASSERT_EQUAL(sal_uInt8(255), device->GetPixel(Point(5, 5)).GetTransparency());
+ }
+ }
+
void testTdf124848()
{
ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT);
@@ -626,6 +691,8 @@ public:
CPPUNIT_TEST(testDashedLine);
+ CPPUNIT_TEST(testErase);
+
CPPUNIT_TEST(testTdf124848);
CPPUNIT_TEST(testTdf136171);
diff --git a/vcl/source/outdev/outdevstate.cxx b/vcl/source/outdev/outdevstate.cxx
index 804ba883c210..4ab3093b573b 100644
--- a/vcl/source/outdev/outdevstate.cxx
+++ b/vcl/source/outdev/outdevstate.cxx
@@ -455,7 +455,44 @@ void OutputDevice::SetBackground( const Wallpaper& rBackground )
mbBackground = true;
if( mpAlphaVDev )
- mpAlphaVDev->SetBackground( rBackground );
+ {
+ // Some of these are probably wrong (e.g. if the gradient has transparency),
+ // but hopefully nobody uses that. If you do, feel free to implement it properly.
+ if( rBackground.GetStyle() == WallpaperStyle::NONE )
+ mpAlphaVDev->SetBackground( rBackground );
+ else if( rBackground.IsBitmap())
+ {
+ BitmapEx bitmap = rBackground.GetBitmap();
+ if( bitmap.IsAlpha())
+ mpAlphaVDev->SetBackground( Wallpaper( BitmapEx( Bitmap( bitmap.GetAlpha()))));
+ else
+ {
+ switch( bitmap.GetTransparentType())
+ {
+ case TransparentType::NONE:
+ mpAlphaVDev->SetBackground( Wallpaper( COL_BLACK ));
+ break;
+ case TransparentType::Color:
+ {
+ AlphaMask mask( bitmap.GetBitmap().CreateMask( bitmap.GetTransparentColor()));
+ mpAlphaVDev->SetBackground( Wallpaper( BitmapEx( bitmap.GetBitmap(), mask )));
+ break;
+ }
+ case TransparentType::Bitmap:
+ mpAlphaVDev->SetBackground( Wallpaper( BitmapEx( bitmap.GetMask())));
+ break;
+ }
+ }
+ }
+ else if( rBackground.IsGradient())
+ mpAlphaVDev->SetBackground( Wallpaper( COL_BLACK ));
+ else
+ {
+ // Color background.
+ int transparency = rBackground.GetColor().GetTransparency();
+ mpAlphaVDev->SetBackground( Wallpaper( Color( transparency, transparency, transparency )));
+ }
+ }
}
void OutputDevice::SetFont( const vcl::Font& rNewFont )