summaryrefslogtreecommitdiff
path: root/Tests/LibGfx
diff options
context:
space:
mode:
authorTim Ledbetter <timledbetter@gmail.com>2023-03-10 17:29:00 +0000
committerJelle Raaijmakers <jelle@gmta.nl>2023-03-21 00:29:33 +0100
commitd5c913082b5efd7f8985ba9b76979edb28bc507a (patch)
treec9088b374d8c3378df3d934f5710fb43f22575ab /Tests/LibGfx
parent5a6b995444694db2379753de604042393913c3b0 (diff)
downloadserenity-d5c913082b5efd7f8985ba9b76979edb28bc507a.zip
Tests: Add tests to verify alpha values are premultiplied when scaling
Diffstat (limited to 'Tests/LibGfx')
-rw-r--r--Tests/LibGfx/CMakeLists.txt1
-rw-r--r--Tests/LibGfx/TestScalingFunctions.cpp66
2 files changed, 67 insertions, 0 deletions
diff --git a/Tests/LibGfx/CMakeLists.txt b/Tests/LibGfx/CMakeLists.txt
index b5b928039f..f86093f911 100644
--- a/Tests/LibGfx/CMakeLists.txt
+++ b/Tests/LibGfx/CMakeLists.txt
@@ -3,6 +3,7 @@ set(TEST_SOURCES
TestFontHandling.cpp
TestICCProfile.cpp
TestImageDecoder.cpp
+ TestScalingFunctions.cpp
)
foreach(source IN LISTS TEST_SOURCES)
diff --git a/Tests/LibGfx/TestScalingFunctions.cpp b/Tests/LibGfx/TestScalingFunctions.cpp
new file mode 100644
index 0000000000..1890c7fcd6
--- /dev/null
+++ b/Tests/LibGfx/TestScalingFunctions.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2023, Tim Ledbetter <timledbetter@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibGfx/Bitmap.h>
+#include <LibGfx/Painter.h>
+#include <LibTest/TestCase.h>
+
+// Scaling modes which use linear interpolation should use premultiplied alpha.
+// This prevents colors from changing hue unexpectedly when there is a change in opacity.
+// This test uses an image that transitions from a completely opaque pixel in the top left to a completely transparent background.
+// We ensure that premultipled alpha is used by checking that the RGB values of the interpolated pixels do not change, just the alpha values.
+TEST_CASE(test_painter_scaling_uses_premultiplied_alpha)
+{
+ auto test_scaling_mode = [](auto scaling_mode) {
+ auto src_bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { 2, 2 }));
+ src_bitmap->fill(Color::Transparent);
+ src_bitmap->set_pixel({ 0, 0 }, Color::White);
+
+ auto scaled_bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { 5, 5 }));
+ scaled_bitmap->fill(Color::Transparent);
+
+ Gfx::Painter painter(scaled_bitmap);
+ painter.draw_scaled_bitmap(scaled_bitmap->rect(), src_bitmap, src_bitmap->rect(), 1.0f, scaling_mode);
+
+ auto top_left_pixel = scaled_bitmap->get_pixel(0, 0);
+ EXPECT_EQ(top_left_pixel, Color::White);
+
+ auto center_pixel = scaled_bitmap->get_pixel(scaled_bitmap->rect().center());
+ EXPECT(center_pixel.alpha() > 0);
+ EXPECT(center_pixel.alpha() < 255);
+ EXPECT_EQ(center_pixel.with_alpha(0), Color(Color::White).with_alpha(0));
+
+ auto bottom_right_pixel = scaled_bitmap->get_pixel(scaled_bitmap->rect().bottom_right());
+ EXPECT_EQ(bottom_right_pixel, Color::Transparent);
+ };
+
+ test_scaling_mode(Gfx::Painter::ScalingMode::BilinearBlend);
+ // FIXME: Include ScalingMode::SmoothPixels as part of this test
+ // This mode does not currently pass this test, as it behave according to the spec
+ // defined here: https://drafts.csswg.org/css-images/#valdef-image-rendering-pixelated
+ // test_scaling_mode(Gfx::Painter::ScalingMode::SmoothPixels);
+}
+
+TEST_CASE(test_bitmap_scaling_uses_premultiplied_alpha)
+{
+ auto src_bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { 2, 2 }));
+ src_bitmap->fill(Color::Transparent);
+ src_bitmap->set_pixel({ 0, 0 }, Color::White);
+
+ auto scaled_bitmap = MUST(src_bitmap->scaled(2.5f, 2.5f));
+ EXPECT_EQ(scaled_bitmap->width(), 5);
+ EXPECT_EQ(scaled_bitmap->height(), 5);
+ auto top_left_pixel = scaled_bitmap->get_pixel(0, 0);
+ EXPECT_EQ(top_left_pixel, Color::White);
+
+ auto center_pixel = scaled_bitmap->get_pixel(scaled_bitmap->rect().center());
+ EXPECT(center_pixel.alpha() > 0);
+ EXPECT(center_pixel.alpha() < 255);
+ EXPECT_EQ(center_pixel.with_alpha(0), Color(Color::White).with_alpha(0));
+
+ auto bottom_right_pixel = scaled_bitmap->get_pixel(scaled_bitmap->rect().bottom_right());
+ EXPECT_EQ(bottom_right_pixel, Color::Transparent);
+}