Pārlūkot izejas kodu

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.
MacDue 2 gadi atpakaļ
vecāks
revīzija
60356c8dde

+ 2 - 2
Userland/Libraries/LibGfx/Bitmap.cpp

@@ -449,9 +449,9 @@ ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::scaled(float sx, float sy) const
     return new_bitmap;
 }
 
-ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::cropped(Gfx::IntRect crop) const
+ErrorOr<NonnullRefPtr<Gfx::Bitmap>> Bitmap::cropped(Gfx::IntRect crop, Optional<BitmapFormat> 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) {

+ 1 - 1
Userland/Libraries/LibGfx/Bitmap.h

@@ -115,7 +115,7 @@ public:
     ErrorOr<NonnullRefPtr<Gfx::Bitmap>> flipped(Gfx::Orientation) const;
     ErrorOr<NonnullRefPtr<Gfx::Bitmap>> scaled(int sx, int sy) const;
     ErrorOr<NonnullRefPtr<Gfx::Bitmap>> scaled(float sx, float sy) const;
-    ErrorOr<NonnullRefPtr<Gfx::Bitmap>> cropped(Gfx::IntRect) const;
+    ErrorOr<NonnullRefPtr<Gfx::Bitmap>> cropped(Gfx::IntRect, Optional<BitmapFormat> new_bitmap_format = {}) const;
     ErrorOr<NonnullRefPtr<Gfx::Bitmap>> to_bitmap_backed_by_anonymous_buffer() const;
     [[nodiscard]] ByteBuffer serialize_to_byte_buffer() const;
 

+ 9 - 0
Userland/Libraries/LibGfx/Painter.cpp

@@ -1799,6 +1799,15 @@ Optional<Color> Painter::get_pixel(IntPoint const& p)
     return Color::from_argb(m_target->scanline(point.y())[point.x()]);
 }
 
+ErrorOr<NonnullRefPtr<Bitmap>> Painter::get_region_bitmap(IntRect const& region, BitmapFormat format, Optional<IntRect&> 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().

+ 1 - 0
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<Color> get_pixel(IntPoint const&);
+    ErrorOr<NonnullRefPtr<Bitmap>> get_region_bitmap(IntRect const&, BitmapFormat format, Optional<IntRect&> 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);