From 4be6ee85e0a6b440cafb7125dac6d16302906f23 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Thu, 5 Jan 2023 12:26:13 +0000 Subject: [PATCH] PixelPaint: Ensure layers are positioned correctly when painting Previously, layer bitmaps could move slightly relative to their boundary and the image background when panning and zooming. --- Userland/Applications/PixelPaint/Image.cpp | 13 ++++++------- Userland/Applications/PixelPaint/Image.h | 2 +- Userland/Applications/PixelPaint/ImageEditor.cpp | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Userland/Applications/PixelPaint/Image.cpp b/Userland/Applications/PixelPaint/Image.cpp index a9af2c36ac..42b5b70fb3 100644 --- a/Userland/Applications/PixelPaint/Image.cpp +++ b/Userland/Applications/PixelPaint/Image.cpp @@ -37,17 +37,16 @@ Image::Image(Gfx::IntSize size) { } -void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect) const +void Image::paint_into(GUI::Painter& painter, Gfx::IntRect const& dest_rect, float scale) const { - float scale = (float)dest_rect.width() / (float)rect().width(); Gfx::PainterStateSaver saver(painter); painter.add_clip_rect(dest_rect); for (auto const& layer : m_layers) { if (!layer.is_visible()) continue; - auto target = dest_rect.translated(layer.location().x() * scale, layer.location().y() * scale); + auto target = dest_rect.to_type().translated(layer.location().x() * scale, layer.location().y() * scale); target.set_size(layer.size().width() * scale, layer.size().height() * scale); - painter.draw_scaled_bitmap(target, layer.display_bitmap(), layer.rect(), (float)layer.opacity_percent() / 100.0f); + painter.draw_scaled_bitmap(target.to_type(), layer.display_bitmap(), layer.rect(), (float)layer.opacity_percent() / 100.0f); } } @@ -150,7 +149,7 @@ ErrorOr> Image::compose_bitmap(Gfx::BitmapFormat form { auto bitmap = TRY(Gfx::Bitmap::create(format, m_size)); GUI::Painter painter(bitmap); - paint_into(painter, { 0, 0, m_size.width(), m_size.height() }); + paint_into(painter, { 0, 0, m_size.width(), m_size.height() }, 1.0f); return bitmap; } @@ -343,7 +342,7 @@ void Image::flatten_all_layers() auto& bottom_layer = m_layers.at(0); GUI::Painter painter(bottom_layer.content_bitmap()); - paint_into(painter, { 0, 0, m_size.width(), m_size.height() }); + paint_into(painter, { 0, 0, m_size.width(), m_size.height() }, 1.0f); for (size_t index = m_layers.size() - 1; index > 0; index--) { auto& layer = m_layers.at(index); @@ -364,7 +363,7 @@ void Image::merge_visible_layers() if (m_layers.at(index).is_visible()) { auto& bottom_layer = m_layers.at(index); GUI::Painter painter(bottom_layer.content_bitmap()); - paint_into(painter, { 0, 0, m_size.width(), m_size.height() }); + paint_into(painter, { 0, 0, m_size.width(), m_size.height() }, 1.0f); select_layer(&bottom_layer); index++; break; diff --git a/Userland/Applications/PixelPaint/Image.h b/Userland/Applications/PixelPaint/Image.h index ed34314425..599ad95036 100644 --- a/Userland/Applications/PixelPaint/Image.h +++ b/Userland/Applications/PixelPaint/Image.h @@ -69,7 +69,7 @@ public: ErrorOr> take_snapshot() const; ErrorOr restore_snapshot(Image const&); - void paint_into(GUI::Painter&, Gfx::IntRect const& dest_rect) const; + void paint_into(GUI::Painter&, Gfx::IntRect const& dest_rect, float scale) const; ErrorOr serialize_as_json(JsonObjectSerializer& json) const; ErrorOr export_bmp_to_file(NonnullOwnPtr, bool preserve_alpha_channel) const; diff --git a/Userland/Applications/PixelPaint/ImageEditor.cpp b/Userland/Applications/PixelPaint/ImageEditor.cpp index 962bd3e9f8..0e058e8515 100644 --- a/Userland/Applications/PixelPaint/ImageEditor.cpp +++ b/Userland/Applications/PixelPaint/ImageEditor.cpp @@ -163,10 +163,10 @@ void ImageEditor::paint_event(GUI::PaintEvent& event) Gfx::StylePainter::paint_transparency_grid(painter, content_rect(), palette()); painter.draw_rect(content_rect().inflated(2, 2), Color::Black); - m_image->paint_into(painter, content_rect()); + m_image->paint_into(painter, content_rect(), scale()); if (m_active_layer && m_show_active_layer_boundary) - painter.draw_rect(content_to_frame_rect(m_active_layer->relative_rect()).to_rounded().inflated(2, 2), Color::Black); + painter.draw_rect(content_to_frame_rect(m_active_layer->relative_rect()).to_type().inflated(2, 2), Color::Black); if (m_show_pixel_grid && scale() > m_pixel_grid_threshold) { auto event_image_rect = enclosing_int_rect(frame_to_content_rect(event.rect())).inflated(1, 1);