diff --git a/Userland/Applications/PixelPaint/Layer.cpp b/Userland/Applications/PixelPaint/Layer.cpp index 6a8c38cb90..87d6221549 100644 --- a/Userland/Applications/PixelPaint/Layer.cpp +++ b/Userland/Applications/PixelPaint/Layer.cpp @@ -230,7 +230,11 @@ void Layer::resize(Gfx::IntSize const& new_size, Gfx::IntPoint const& new_locati auto dst = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size).release_value_but_fixme_should_propagate_errors(); Gfx::Painter painter(dst); - painter.draw_scaled_bitmap(dst_rect, *m_content_bitmap, src_rect, 1.0f, scaling_mode); + if (scaling_mode == Gfx::Painter::ScalingMode::None) { + painter.blit(src_rect.top_left(), *m_content_bitmap, src_rect, 1.0f); + } else { + painter.draw_scaled_bitmap(dst_rect, *m_content_bitmap, src_rect, 1.0f, scaling_mode); + } m_content_bitmap = move(dst); } @@ -239,7 +243,12 @@ void Layer::resize(Gfx::IntSize const& new_size, Gfx::IntPoint const& new_locati auto dst = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, new_size).release_value_but_fixme_should_propagate_errors(); Gfx::Painter painter(dst); - painter.draw_scaled_bitmap(dst_rect, *m_mask_bitmap, src_rect, 1.0f, scaling_mode); + if (scaling_mode == Gfx::Painter::ScalingMode::None) { + painter.blit(src_rect.top_left(), *m_content_bitmap, src_rect, 1.0f); + } else { + painter.draw_scaled_bitmap(dst_rect, *m_mask_bitmap, src_rect, 1.0f, scaling_mode); + } + m_mask_bitmap = move(dst); } diff --git a/Userland/Applications/PixelPaint/ResizeImageDialog.cpp b/Userland/Applications/PixelPaint/ResizeImageDialog.cpp index 9fa8151269..643658e65a 100644 --- a/Userland/Applications/PixelPaint/ResizeImageDialog.cpp +++ b/Userland/Applications/PixelPaint/ResizeImageDialog.cpp @@ -70,10 +70,12 @@ ResizeImageDialog::ResizeImageDialog(Gfx::IntSize const& suggested_size, GUI::Wi auto nearest_neighbor_radio = main_widget.find_descendant_of_type_named("nearest_neighbor_radio"); auto smooth_pixels_radio = main_widget.find_descendant_of_type_named("smooth_pixels_radio"); auto bilinear_radio = main_widget.find_descendant_of_type_named("bilinear_radio"); + auto resize_canvas_radio = main_widget.find_descendant_of_type_named("resize_canvas"); VERIFY(nearest_neighbor_radio); VERIFY(smooth_pixels_radio); VERIFY(bilinear_radio); + VERIFY(resize_canvas_radio); m_scaling_mode = Gfx::Painter::ScalingMode::NearestNeighbor; if (bilinear_radio->is_checked()) { @@ -92,6 +94,10 @@ ResizeImageDialog::ResizeImageDialog(Gfx::IntSize const& suggested_size, GUI::Wi if (is_checked) m_scaling_mode = Gfx::Painter::ScalingMode::BilinearBlend; }; + resize_canvas_radio->on_checked = [this](bool is_checked) { + if (is_checked) + m_scaling_mode = Gfx::Painter::ScalingMode::None; + }; auto ok_button = main_widget.find_descendant_of_type_named("ok_button"); auto cancel_button = main_widget.find_descendant_of_type_named("cancel_button"); diff --git a/Userland/Applications/PixelPaint/ResizeImageDialog.gml b/Userland/Applications/PixelPaint/ResizeImageDialog.gml index 990f6ea634..fa743b49ec 100644 --- a/Userland/Applications/PixelPaint/ResizeImageDialog.gml +++ b/Userland/Applications/PixelPaint/ResizeImageDialog.gml @@ -1,7 +1,7 @@ @GUI::Widget { fill_with_background_color: true min_width: 260 - min_height: 210 + min_height: 260 layout: @GUI::VerticalBoxLayout { margins: [4] } @@ -92,6 +92,12 @@ text: "Bilinear" autosize: true } + + @GUI::RadioButton { + name: "resize_canvas" + text: "Resize Canvas (None)" + autosize: true + } } @GUI::Widget { diff --git a/Userland/Applications/PixelPaint/ResizeImageDialog.h b/Userland/Applications/PixelPaint/ResizeImageDialog.h index 17887128e0..b74ae3d037 100644 --- a/Userland/Applications/PixelPaint/ResizeImageDialog.h +++ b/Userland/Applications/PixelPaint/ResizeImageDialog.h @@ -17,6 +17,7 @@ class ResizeImageDialog final : public GUI::Dialog { public: Gfx::IntSize const& desired_size() const { return m_desired_size; } Gfx::Painter::ScalingMode scaling_mode() const { return m_scaling_mode; } + bool should_rescale() const { return m_rescale_image; } private: ResizeImageDialog(Gfx::IntSize const& starting_size, GUI::Window* parent_window); @@ -24,6 +25,7 @@ private: Gfx::IntSize m_desired_size; Gfx::Painter::ScalingMode m_scaling_mode; float m_starting_aspect_ratio; + bool m_rescale_image; }; } diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp index bfd566709b..9773b58fc3 100644 --- a/Userland/Libraries/LibGfx/Painter.cpp +++ b/Userland/Libraries/LibGfx/Painter.cpp @@ -1248,6 +1248,9 @@ ALWAYS_INLINE static void do_draw_scaled_bitmap(Gfx::Bitmap& target, IntRect con case Painter::ScalingMode::BilinearBlend: do_draw_scaled_bitmap(target, dst_rect, clipped_rect, source, src_rect, get_pixel, opacity); break; + case Painter::ScalingMode::None: + do_draw_scaled_bitmap(target, dst_rect, clipped_rect, source, src_rect, get_pixel, opacity); + break; } } @@ -1262,6 +1265,11 @@ void Painter::draw_scaled_bitmap(IntRect const& a_dst_rect, Gfx::Bitmap const& s if (scale() == source.scale() && a_src_rect == int_src_rect && a_dst_rect.size() == int_src_rect.size()) return blit(a_dst_rect.location(), source, int_src_rect, opacity); + if (scaling_mode == ScalingMode::None) { + IntRect clipped_draw_rect { (int)a_src_rect.location().x(), (int)a_src_rect.location().y(), a_dst_rect.size().width(), a_dst_rect.size().height() }; + return blit(a_dst_rect.location(), source, clipped_draw_rect, opacity); + } + auto dst_rect = to_physical(a_dst_rect); auto src_rect = a_src_rect * source.scale(); auto clipped_rect = dst_rect.intersected(clip_rect() * scale()); diff --git a/Userland/Libraries/LibGfx/Painter.h b/Userland/Libraries/LibGfx/Painter.h index 3405d0befd..845978ce1b 100644 --- a/Userland/Libraries/LibGfx/Painter.h +++ b/Userland/Libraries/LibGfx/Painter.h @@ -38,6 +38,7 @@ public: NearestNeighbor, SmoothPixels, BilinearBlend, + None, }; void clear_rect(IntRect const&, Color);