LibGfx: Make Painter::target() return a Bitmap&
Painter always has a target bitmap, so let's return a reference.
This commit is contained in:
parent
a1a59ec3ab
commit
f42c18bc4c
Notes:
sideshowbarker
2024-07-17 17:06:59 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/f42c18bc4c Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/50
7 changed files with 44 additions and 44 deletions
Userland/Libraries
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue