mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-28 05:35:52 +03:00
LibGfx: Fix off-by-some in Painter::draw_scaled_bitmap_with_transform()
Before this, drawing a 1x1 bitmap scaled up to MxN would only fill M/2 x N/2 pixel, due to source_point going outside (0, 0).
This commit is contained in:
parent
822b7720e1
commit
7fb32b6682
Notes:
sideshowbarker
2024-07-17 05:01:20 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/7fb32b6682 Pull-request: https://github.com/SerenityOS/serenity/pull/22678
@ -6,6 +6,7 @@ set(TEST_SOURCES
|
||||
TestGfxBitmap.cpp
|
||||
TestICCProfile.cpp
|
||||
TestImageDecoder.cpp
|
||||
TestPainter.cpp
|
||||
TestParseISOBMFF.cpp
|
||||
TestRect.cpp
|
||||
TestScalingFunctions.cpp
|
||||
|
48
Tests/LibGfx/TestPainter.cpp
Normal file
48
Tests/LibGfx/TestPainter.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Nico Weber <thakis@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibTest/TestCase.h>
|
||||
|
||||
#include <LibGfx/Painter.h>
|
||||
|
||||
TEST_CASE(draw_scaled_bitmap_with_transform)
|
||||
{
|
||||
auto bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { 40, 30 }));
|
||||
bitmap->fill(Gfx::Color::White);
|
||||
Gfx::Painter painter(bitmap);
|
||||
|
||||
auto source_bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::BGRx8888, { 1, 1 }));
|
||||
source_bitmap->fill(Gfx::Color::Black);
|
||||
|
||||
auto dest_rect = source_bitmap->rect();
|
||||
auto source_rect = source_bitmap->rect().to_rounded<float>();
|
||||
|
||||
// Identity transform: Lower left pixel is black, rest stays white.
|
||||
Gfx::AffineTransform transform;
|
||||
painter.draw_scaled_bitmap_with_transform(dest_rect, source_bitmap, source_rect, transform);
|
||||
for (int y = 0; y < bitmap->height(); ++y) {
|
||||
for (int x = 0; x < bitmap->width(); ++x) {
|
||||
if (x == 0 && y == 0)
|
||||
EXPECT_EQ(bitmap->get_pixel(x, y), Color::Black);
|
||||
else
|
||||
EXPECT_EQ(bitmap->get_pixel(x, y), Color::White);
|
||||
}
|
||||
}
|
||||
|
||||
// Scale up 1x1 source bitmap 10x in x and 5x in y and paint at 10, 20. Should fill that rect:
|
||||
bitmap->fill(Gfx::Color::White);
|
||||
transform = transform.translate(10, 20).scale(10, 5);
|
||||
painter.draw_scaled_bitmap_with_transform(dest_rect, source_bitmap, source_rect, transform);
|
||||
for (int y = 0; y < bitmap->height(); ++y) {
|
||||
for (int x = 0; x < bitmap->width(); ++x) {
|
||||
dbgln("{} {}: {}", x, y, bitmap->get_pixel(x, y));
|
||||
if (x >= 10 && x < 10 + 10 && y >= 20 && y < 20 + 5)
|
||||
EXPECT_EQ(bitmap->get_pixel(x, y), Color::Black);
|
||||
else
|
||||
EXPECT_EQ(bitmap->get_pixel(x, y), Color::White);
|
||||
}
|
||||
}
|
||||
}
|
@ -2489,7 +2489,10 @@ void Painter::draw_scaled_bitmap_with_transform(IntRect const& dst_rect, Bitmap
|
||||
for (int x = 0; x < clipped_bounding_rect.width(); ++x) {
|
||||
auto point = Gfx::IntPoint { x, y };
|
||||
auto sample_point = point + start_offset;
|
||||
auto source_point = sample_transform.map(sample_point).to_rounded<int>();
|
||||
|
||||
// AffineTransform::map(IntPoint) rounds internally, which is wrong here. So explicitly call the FloatPoint version, and then truncate the result.
|
||||
auto source_point = Gfx::IntPoint { sample_transform.map(Gfx::FloatPoint { sample_point }) };
|
||||
|
||||
if (!source_rect.contains(source_point))
|
||||
continue;
|
||||
auto source_color = bitmap.get_pixel(source_point);
|
||||
|
Loading…
Reference in New Issue
Block a user