From 60356c8ddeb1916cac0172f17b4fcf1c2f17dae0 Mon Sep 17 00:00:00 2001 From: MacDue Date: Thu, 15 Sep 2022 08:31:29 +0100 Subject: [PATCH] LibGfx: Support getting a bitmap for a region of painter This will be needed so we can apply filter effects to the backdrop of an element in LibWeb. This now also allows getting a crop of a bitmap in a different format than the source bitmap. This is for if the painter's bitmap does not have an alpha channel, but you want to ensure the cropped bitmap does. --- Userland/Libraries/LibGfx/Bitmap.cpp | 4 ++-- Userland/Libraries/LibGfx/Bitmap.h | 2 +- Userland/Libraries/LibGfx/Painter.cpp | 9 +++++++++ Userland/Libraries/LibGfx/Painter.h | 1 + 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibGfx/Bitmap.cpp b/Userland/Libraries/LibGfx/Bitmap.cpp index d3338dcb61c..3a6f1cb9412 100644 --- a/Userland/Libraries/LibGfx/Bitmap.cpp +++ b/Userland/Libraries/LibGfx/Bitmap.cpp @@ -449,9 +449,9 @@ ErrorOr> Bitmap::scaled(float sx, float sy) const return new_bitmap; } -ErrorOr> Bitmap::cropped(Gfx::IntRect crop) const +ErrorOr> Bitmap::cropped(Gfx::IntRect crop, Optional new_bitmap_format) const { - auto new_bitmap = TRY(Gfx::Bitmap::try_create(format(), { crop.width(), crop.height() }, 1)); + auto new_bitmap = TRY(Gfx::Bitmap::try_create(new_bitmap_format.value_or(format()), { crop.width(), crop.height() }, 1)); for (int y = 0; y < crop.height(); ++y) { for (int x = 0; x < crop.width(); ++x) { diff --git a/Userland/Libraries/LibGfx/Bitmap.h b/Userland/Libraries/LibGfx/Bitmap.h index 62d5f362ece..c34f2b620f3 100644 --- a/Userland/Libraries/LibGfx/Bitmap.h +++ b/Userland/Libraries/LibGfx/Bitmap.h @@ -115,7 +115,7 @@ public: ErrorOr> flipped(Gfx::Orientation) const; ErrorOr> scaled(int sx, int sy) const; ErrorOr> scaled(float sx, float sy) const; - ErrorOr> cropped(Gfx::IntRect) const; + ErrorOr> cropped(Gfx::IntRect, Optional new_bitmap_format = {}) const; ErrorOr> to_bitmap_backed_by_anonymous_buffer() const; [[nodiscard]] ByteBuffer serialize_to_byte_buffer() const; diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp index c005ee2cd57..c2d34683417 100644 --- a/Userland/Libraries/LibGfx/Painter.cpp +++ b/Userland/Libraries/LibGfx/Painter.cpp @@ -1799,6 +1799,15 @@ Optional Painter::get_pixel(IntPoint const& p) return Color::from_argb(m_target->scanline(point.y())[point.x()]); } +ErrorOr> Painter::get_region_bitmap(IntRect const& region, BitmapFormat format, Optional actual_region) +{ + VERIFY(scale() == 1); + auto bitmap_region = region.translated(state().translation).intersected(m_target->rect()); + if (actual_region.has_value()) + actual_region.value() = bitmap_region.translated(-state().translation); + return m_target->cropped(bitmap_region, format); +} + ALWAYS_INLINE void Painter::set_physical_pixel_with_draw_op(u32& pixel, Color const& color) { // This always sets a single physical pixel, independent of scale(). diff --git a/Userland/Libraries/LibGfx/Painter.h b/Userland/Libraries/LibGfx/Painter.h index 72cd8c1efd1..238ad0d0c32 100644 --- a/Userland/Libraries/LibGfx/Painter.h +++ b/Userland/Libraries/LibGfx/Painter.h @@ -62,6 +62,7 @@ public: void set_pixel(IntPoint const&, Color, bool blend = false); void set_pixel(int x, int y, Color color, bool blend = false) { set_pixel({ x, y }, color, blend); } Optional get_pixel(IntPoint const&); + ErrorOr> get_region_bitmap(IntRect const&, BitmapFormat format, Optional actual_region = {}); void draw_line(IntPoint const&, IntPoint const&, Color, int thickness = 1, LineStyle style = LineStyle::Solid, Color alternate_color = Color::Transparent); void draw_triangle_wave(IntPoint const&, IntPoint const&, Color color, int amplitude, int thickness = 1); void draw_quadratic_bezier_curve(IntPoint const& control_point, IntPoint const&, IntPoint const&, Color, int thickness = 1, LineStyle style = LineStyle::Solid);