Ver Fonte

LibGfx: Make Painter::target() return a Bitmap&

Painter always has a target bitmap, so let's return a reference.
Andreas Kling há 1 ano atrás
pai
commit
f42c18bc4c

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

@@ -395,8 +395,8 @@ FLATTEN __attribute__((hot)) void EdgeFlagPathRasterizer<SamplesPerPixel>::write
     });
 
     // Get pointer to current scanline pixels.
-    auto dest_format = painter.target()->format();
-    auto dest_ptr = painter.target()->scanline(scanline + m_blit_origin.y());
+    auto dest_format = painter.target().format();
+    auto dest_ptr = painter.target().scanline(scanline + m_blit_origin.y());
 
     // Simple case: Handle each pixel individually.
     // Used for PaintStyle fills and semi-transparent colors.

+ 32 - 32
Userland/Libraries/LibGfx/Painter.cpp

@@ -66,10 +66,10 @@ void Painter::clear_rect(IntRect const& a_rect, Color color)
     if (rect.is_empty())
         return;
 
-    VERIFY(m_target->rect().contains(rect));
+    VERIFY(target().rect().contains(rect));
 
-    ARGB32* dst = m_target->scanline(rect.top()) + rect.left();
-    size_t const dst_skip = m_target->pitch() / sizeof(ARGB32);
+    ARGB32* dst = target().scanline(rect.top()) + rect.left();
+    size_t const dst_skip = target().pitch() / sizeof(ARGB32);
 
     for (int i = rect.height() - 1; i >= 0; --i) {
         fast_u32_fill(dst, color.value(), rect.width());
@@ -80,10 +80,10 @@ void Painter::clear_rect(IntRect const& a_rect, Color color)
 void Painter::fill_physical_rect(IntRect const& physical_rect, Color color)
 {
     // Callers must do clipping.
-    ARGB32* dst = m_target->scanline(physical_rect.top()) + physical_rect.left();
-    size_t const dst_skip = m_target->pitch() / sizeof(ARGB32);
+    ARGB32* dst = target().scanline(physical_rect.top()) + physical_rect.left();
+    size_t const dst_skip = target().pitch() / sizeof(ARGB32);
 
-    auto dst_format = target()->format();
+    auto dst_format = target().format();
     for (int i = physical_rect.height() - 1; i >= 0; --i) {
         for (int j = 0; j < physical_rect.width(); ++j)
             dst[j] = color_for_format(dst_format, dst[j]).blend(color).value();
@@ -104,7 +104,7 @@ void Painter::fill_rect(IntRect const& a_rect, Color color)
     auto rect = a_rect.translated(translation()).intersected(clip_rect());
     if (rect.is_empty())
         return;
-    VERIFY(m_target->rect().contains(rect));
+    VERIFY(target().rect().contains(rect));
 
     fill_physical_rect(rect, color);
 }
@@ -237,7 +237,7 @@ void Painter::fill_rounded_corner(IntRect const& a_rect, int radius, Color color
 
     if (rect.is_empty())
         return;
-    VERIFY(m_target->rect().contains(rect));
+    VERIFY(target().rect().contains(rect));
 
     // We got cut on the top!
     // FIXME: Also account for clipping on the x-axis
@@ -245,8 +245,8 @@ void Painter::fill_rounded_corner(IntRect const& a_rect, int radius, Color color
     if (translated_a_rect.y() < rect.y())
         clip_offset = rect.y() - translated_a_rect.y();
 
-    ARGB32* dst = m_target->scanline(rect.top()) + rect.left();
-    size_t const dst_skip = m_target->pitch() / sizeof(ARGB32);
+    ARGB32* dst = target().scanline(rect.top()) + rect.left();
+    size_t const dst_skip = target().pitch() / sizeof(ARGB32);
 
     IntPoint circle_center;
     switch (orientation) {
@@ -274,7 +274,7 @@ void Painter::fill_rounded_corner(IntRect const& a_rect, int radius, Color color
         return distance2 <= (radius2 + radius + 0.25);
     };
 
-    auto dst_format = target()->format();
+    auto dst_format = target().format();
     for (int i = rect.height() - 1; i >= 0; --i) {
         for (int j = 0; j < rect.width(); ++j)
             if (is_in_circle(j, rect.height() - i + clip_offset))
@@ -338,7 +338,7 @@ void Painter::fill_ellipse(IntRect const& a_rect, Color color)
     if (rect.is_empty())
         return;
 
-    VERIFY(m_target->rect().contains(rect));
+    VERIFY(target().rect().contains(rect));
 
     auto const center = a_rect.center();
 
@@ -398,13 +398,13 @@ void Painter::draw_rect(IntRect const& a_rect, Color color, bool rough)
     if (draw_left_side && draw_right_side) {
         // Specialized loop when drawing both sides.
         for (int y = min_y; y <= max_y; ++y) {
-            auto* bits = m_target->scanline(y);
+            auto* bits = target().scanline(y);
             set_physical_pixel(bits[rect.left()], color);
             set_physical_pixel(bits[(rect.right() - 1)], color);
         }
     } else {
         for (int y = min_y; y <= max_y; ++y) {
-            auto* bits = m_target->scanline(y);
+            auto* bits = target().scanline(y);
             if (draw_left_side)
                 set_physical_pixel(bits[rect.left()], color);
             if (draw_right_side)
@@ -488,9 +488,9 @@ void Painter::blit_with_opacity(IntPoint position, Gfx::Bitmap const& source, In
 
     BlitState blit_state {
         .src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column,
-        .dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x(),
+        .dst = target().scanline(clipped_rect.y()) + clipped_rect.x(),
         .src_pitch = source.pitch() / sizeof(ARGB32),
-        .dst_pitch = m_target->pitch() / sizeof(ARGB32),
+        .dst_pitch = target().pitch() / sizeof(ARGB32),
         .row_count = last_row - first_row,
         .column_count = last_column - first_column,
         .opacity = opacity,
@@ -498,12 +498,12 @@ void Painter::blit_with_opacity(IntPoint position, Gfx::Bitmap const& source, In
     };
 
     if (source.has_alpha_channel() && apply_alpha) {
-        if (m_target->has_alpha_channel())
+        if (target().has_alpha_channel())
             do_blit_with_opacity<BlitState::BothAlpha>(blit_state);
         else
             do_blit_with_opacity<BlitState::SrcAlpha>(blit_state);
     } else {
-        if (m_target->has_alpha_channel())
+        if (target().has_alpha_channel())
             do_blit_with_opacity<BlitState::DstAlpha>(blit_state);
         else
             do_blit_with_opacity<BlitState::NoAlpha>(blit_state);
@@ -522,9 +522,9 @@ void Painter::blit_filtered(IntPoint position, Gfx::Bitmap const& source, IntRec
     int const last_row = clipped_rect.bottom() - dst_rect.top();
     int const first_column = clipped_rect.left() - dst_rect.left();
     int const last_column = clipped_rect.right() - dst_rect.left();
-    ARGB32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
-    size_t const dst_skip = m_target->pitch() / sizeof(ARGB32);
-    auto dst_format = target()->format();
+    ARGB32* dst = target().scanline(clipped_rect.y()) + clipped_rect.x();
+    size_t const dst_skip = target().pitch() / sizeof(ARGB32);
+    auto dst_format = target().format();
     auto src_format = source.format();
 
     ARGB32 const* src = source.scanline(safe_src_rect.top() + first_row) + safe_src_rect.left() + first_column;
@@ -563,8 +563,8 @@ void Painter::blit(IntPoint position, Gfx::Bitmap const& source, IntRect const&
     int const first_row = clipped_rect.top() - dst_rect.top();
     int const last_row = clipped_rect.bottom() - dst_rect.top();
     int const first_column = clipped_rect.left() - dst_rect.left();
-    ARGB32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
-    size_t const dst_skip = m_target->pitch() / sizeof(ARGB32);
+    ARGB32* dst = target().scanline(clipped_rect.y()) + clipped_rect.x();
+    size_t const dst_skip = target().pitch() / sizeof(ARGB32);
 
     if (source.format() == BitmapFormat::BGRx8888 || source.format() == BitmapFormat::BGRA8888) {
         ARGB32 const* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column;
@@ -1192,11 +1192,11 @@ void Painter::set_physical_pixel(IntPoint physical_point, Color color, bool blen
 {
     // This function should only be called after translation, clipping, etc has been handled elsewhere
     // if not use set_pixel().
-    auto& dst = m_target->scanline(physical_point.y())[physical_point.x()];
+    auto& dst = target().scanline(physical_point.y())[physical_point.x()];
     if (!blend || color.alpha() == 255)
         dst = color.value();
     else if (color.alpha())
-        dst = color_for_format(target()->format(), dst).blend(color).value();
+        dst = color_for_format(target().format(), dst).blend(color).value();
 }
 
 Optional<Color> Painter::get_pixel(IntPoint p)
@@ -1205,15 +1205,15 @@ Optional<Color> Painter::get_pixel(IntPoint p)
     point.translate_by(state().translation);
     if (!clip_rect().contains(point))
         return {};
-    return m_target->get_pixel(point);
+    return target().get_pixel(point);
 }
 
 ErrorOr<NonnullRefPtr<Bitmap>> Painter::get_region_bitmap(IntRect const& region, BitmapFormat format, Optional<IntRect&> actual_region)
 {
-    auto bitmap_region = region.translated(state().translation).intersected(m_target->rect());
+    auto bitmap_region = region.translated(state().translation).intersected(target().rect());
     if (actual_region.has_value())
         actual_region.value() = bitmap_region.translated(-state().translation);
-    return m_target->cropped(bitmap_region, format);
+    return target().cropped(bitmap_region, format);
 }
 
 ALWAYS_INLINE void Painter::set_physical_pixel(u32& pixel, Color color)
@@ -1227,7 +1227,7 @@ ALWAYS_INLINE void Painter::fill_physical_scanline(int y, int x, int width, Colo
 {
     // This always draws a single physical scanline, independent of scale().
     // This should only be called by routines that already handle scale.
-    fast_u32_fill(m_target->scanline(y) + x, color.value(), width);
+    fast_u32_fill(target().scanline(y) + x, color.value(), width);
 }
 
 void Painter::draw_physical_pixel(IntPoint physical_position, Color color, int thickness)
@@ -1239,8 +1239,8 @@ void Painter::draw_physical_pixel(IntPoint physical_position, Color color, int t
         return;
 
     if (thickness == 1) { // Implies scale() == 1.
-        auto& pixel = m_target->scanline(physical_position.y())[physical_position.x()];
-        return set_physical_pixel(pixel, color_for_format(m_target->format(), pixel).blend(color));
+        auto& pixel = target().scanline(physical_position.y())[physical_position.x()];
+        return set_physical_pixel(pixel, color_for_format(target().format(), pixel).blend(color));
     }
 
     IntRect rect { physical_position, { thickness, thickness } };
@@ -1549,7 +1549,7 @@ void Painter::for_each_line_segment_on_cubic_bezier_curve(FloatPoint control_poi
 void Painter::add_clip_rect(IntRect const& rect)
 {
     state().clip_rect.intersect(rect.translated(translation()));
-    state().clip_rect.intersect(m_target->rect()); // FIXME: This shouldn't be necessary?
+    state().clip_rect.intersect(target().rect()); // FIXME: This shouldn't be necessary?
 }
 
 void Painter::clear_clip_rect()

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

@@ -105,7 +105,7 @@ public:
 
     IntPoint translation() const { return state().translation; }
 
-    Gfx::Bitmap* target() { return m_target.ptr(); }
+    [[nodiscard]] Gfx::Bitmap& target() { return *m_target; }
 
     void save() { m_state_stack.append(m_state_stack.last()); }
     void restore()

+ 2 - 2
Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp

@@ -387,7 +387,7 @@ void CanvasRenderingContext2D::reset_to_default_state()
 
     // 1. Clear canvas's bitmap to transparent black.
     if (painter)
-        painter->clear_rect(painter->target()->rect(), Color::Transparent);
+        painter->clear_rect(painter->target().rect(), Color::Transparent);
 
     // 2. Empty the list of subpaths in context's current default path.
     path().clear();
@@ -399,7 +399,7 @@ void CanvasRenderingContext2D::reset_to_default_state()
     reset_drawing_state();
 
     if (painter)
-        did_draw(painter->target()->rect().to_type<float>());
+        did_draw(painter->target().rect().to_type<float>());
 }
 
 // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-measuretext

+ 1 - 1
Userland/Libraries/LibWeb/Painting/BorderRadiusCornerClipper.cpp

@@ -78,7 +78,7 @@ void BorderRadiusCornerClipper::sample_under_corners(Gfx::Painter& page_painter)
                     position.translate_by(translation);
                     if (!clip_rect.contains(position))
                         continue;
-                    auto page_pixel = page_painter.target()->get_pixel<Gfx::StorageFormat::BGRA8888>(position.x(), position.y());
+                    auto page_pixel = page_painter.target().get_pixel<Gfx::StorageFormat::BGRA8888>(position.x(), position.y());
                     final_pixel = page_pixel.with_alpha(mask_alpha);
                 }
                 m_corner_bitmap->set_pixel<Gfx::StorageFormat::BGRA8888>(corner_location.x(), corner_location.y(), final_pixel);

+ 5 - 5
Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp

@@ -227,14 +227,14 @@ CommandResult CommandExecutorCPU::pop_stacking_context(PopStackingContext const&
     auto stacking_context = stacking_contexts.take_last();
     // Stacking contexts that don't own their painter are simple translations, and don't need to blit anything back.
     if (stacking_context.painter.is_owned()) {
-        auto bitmap = stacking_context.painter->target();
+        auto& bitmap = stacking_context.painter->target();
         if (stacking_context.mask.has_value())
-            bitmap->apply_mask(*stacking_context.mask->mask_bitmap, stacking_context.mask->mask_kind);
+            bitmap.apply_mask(*stacking_context.mask->mask_bitmap, stacking_context.mask->mask_kind);
         auto destination_rect = stacking_context.destination;
-        if (destination_rect.size() == bitmap->size()) {
-            painter().blit(destination_rect.location(), *bitmap, bitmap->rect(), stacking_context.opacity);
+        if (destination_rect.size() == bitmap.size()) {
+            painter().blit(destination_rect.location(), bitmap, bitmap.rect(), stacking_context.opacity);
         } else {
-            painter().draw_scaled_bitmap(destination_rect, *bitmap, bitmap->rect(), stacking_context.opacity, stacking_context.scaling_mode);
+            painter().draw_scaled_bitmap(destination_rect, bitmap, bitmap.rect(), stacking_context.opacity, stacking_context.scaling_mode);
         }
     }
     return CommandResult::Continue;

+ 1 - 1
Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp

@@ -489,7 +489,7 @@ void paint_outer_box_shadow(Gfx::Painter& painter, PaintOuterBoxShadowParams par
     // FIXME: Could reduce the shadow paints from 8 to 4 for shadows with all corner radii 50%.
 
     // FIXME: We use this since we want the clip rect to include everything after a certain x or y.
-    // Note: Using painter.target()->width() or height() does not work, when the painter is a small
+    // Note: Using painter.target().width() or height() does not work, when the painter is a small
     // translated bitmap rather than full screen, as the clip rect may not intersect.
     constexpr auto really_large_number = NumericLimits<int>::max() / 2;