summaryrefslogtreecommitdiff
path: root/vcl
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 /vcl
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>
Diffstat (limited to 'vcl')
-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 )