diff options
author | Tim Ledbetter <timledbetter@gmail.com> | 2023-03-10 17:29:00 +0000 |
---|---|---|
committer | Jelle Raaijmakers <jelle@gmta.nl> | 2023-03-21 00:29:33 +0100 |
commit | d5c913082b5efd7f8985ba9b76979edb28bc507a (patch) | |
tree | c9088b374d8c3378df3d934f5710fb43f22575ab /Tests/LibGfx | |
parent | 5a6b995444694db2379753de604042393913c3b0 (diff) | |
download | serenity-d5c913082b5efd7f8985ba9b76979edb28bc507a.zip |
Tests: Add tests to verify alpha values are premultiplied when scaling
Diffstat (limited to 'Tests/LibGfx')
-rw-r--r-- | Tests/LibGfx/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Tests/LibGfx/TestScalingFunctions.cpp | 66 |
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); +} |