mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-23 08:30:50 +00:00
This way we don't have to allocate separate vector with both scroll and sticky frame that is used for display list player (scroll and sticky frames share id pool), so player could access offset by frame id. No behavior change.
112 lines
5 KiB
C++
112 lines
5 KiB
C++
/*
|
|
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/Painting/DisplayList.h>
|
|
|
|
namespace Web::Painting {
|
|
|
|
void DisplayList::append(Command&& command, Optional<i32> scroll_frame_id)
|
|
{
|
|
m_commands.append({ scroll_frame_id, move(command) });
|
|
}
|
|
|
|
static Optional<Gfx::IntRect> command_bounding_rectangle(Command const& command)
|
|
{
|
|
return command.visit(
|
|
[&](auto const& command) -> Optional<Gfx::IntRect> {
|
|
if constexpr (requires { command.bounding_rect(); })
|
|
return command.bounding_rect();
|
|
else
|
|
return {};
|
|
});
|
|
}
|
|
|
|
void DisplayListPlayer::execute(DisplayList& display_list)
|
|
{
|
|
auto const& commands = display_list.commands();
|
|
auto const& scroll_state = display_list.scroll_state();
|
|
auto device_pixels_per_css_pixel = display_list.device_pixels_per_css_pixel();
|
|
|
|
size_t next_command_index = 0;
|
|
while (next_command_index < commands.size()) {
|
|
auto scroll_frame_id = commands[next_command_index].scroll_frame_id;
|
|
auto command = commands[next_command_index++].command;
|
|
|
|
if (command.has<PaintScrollBar>()) {
|
|
auto& paint_scroll_bar = command.get<PaintScrollBar>();
|
|
auto scroll_offset = scroll_state.own_offset_for_frame_with_id(paint_scroll_bar.scroll_frame_id);
|
|
if (paint_scroll_bar.vertical) {
|
|
auto offset = scroll_offset.y() * paint_scroll_bar.scroll_size;
|
|
paint_scroll_bar.rect.translate_by(0, -offset.to_int() * device_pixels_per_css_pixel);
|
|
} else {
|
|
auto offset = scroll_offset.x() * paint_scroll_bar.scroll_size;
|
|
paint_scroll_bar.rect.translate_by(-offset.to_int() * device_pixels_per_css_pixel, 0);
|
|
}
|
|
}
|
|
|
|
if (scroll_frame_id.has_value()) {
|
|
auto cumulative_offset = scroll_state.cumulative_offset_for_frame_with_id(scroll_frame_id.value());
|
|
auto scroll_offset = cumulative_offset.to_type<double>().scaled(device_pixels_per_css_pixel).to_type<int>();
|
|
command.visit(
|
|
[&](auto& command) {
|
|
if constexpr (requires { command.translate_by(scroll_offset); }) {
|
|
command.translate_by(scroll_offset);
|
|
}
|
|
});
|
|
}
|
|
|
|
auto bounding_rect = command_bounding_rectangle(command);
|
|
if (bounding_rect.has_value() && (bounding_rect->is_empty() || would_be_fully_clipped_by_painter(*bounding_rect))) {
|
|
continue;
|
|
}
|
|
|
|
#define HANDLE_COMMAND(command_type, executor_method) \
|
|
if (command.has<command_type>()) { \
|
|
executor_method(command.get<command_type>()); \
|
|
}
|
|
|
|
// clang-format off
|
|
HANDLE_COMMAND(DrawGlyphRun, draw_glyph_run)
|
|
else HANDLE_COMMAND(FillRect, fill_rect)
|
|
else HANDLE_COMMAND(DrawScaledBitmap, draw_scaled_bitmap)
|
|
else HANDLE_COMMAND(DrawScaledImmutableBitmap, draw_scaled_immutable_bitmap)
|
|
else HANDLE_COMMAND(DrawRepeatedImmutableBitmap, draw_repeated_immutable_bitmap)
|
|
else HANDLE_COMMAND(AddClipRect, add_clip_rect)
|
|
else HANDLE_COMMAND(Save, save)
|
|
else HANDLE_COMMAND(Restore, restore)
|
|
else HANDLE_COMMAND(Translate, translate)
|
|
else HANDLE_COMMAND(PushStackingContext, push_stacking_context)
|
|
else HANDLE_COMMAND(PopStackingContext, pop_stacking_context)
|
|
else HANDLE_COMMAND(PaintLinearGradient, paint_linear_gradient)
|
|
else HANDLE_COMMAND(PaintRadialGradient, paint_radial_gradient)
|
|
else HANDLE_COMMAND(PaintConicGradient, paint_conic_gradient)
|
|
else HANDLE_COMMAND(PaintOuterBoxShadow, paint_outer_box_shadow)
|
|
else HANDLE_COMMAND(PaintInnerBoxShadow, paint_inner_box_shadow)
|
|
else HANDLE_COMMAND(PaintTextShadow, paint_text_shadow)
|
|
else HANDLE_COMMAND(FillRectWithRoundedCorners, fill_rect_with_rounded_corners)
|
|
else HANDLE_COMMAND(FillPathUsingColor, fill_path_using_color)
|
|
else HANDLE_COMMAND(FillPathUsingPaintStyle, fill_path_using_paint_style)
|
|
else HANDLE_COMMAND(StrokePathUsingColor, stroke_path_using_color)
|
|
else HANDLE_COMMAND(StrokePathUsingPaintStyle, stroke_path_using_paint_style)
|
|
else HANDLE_COMMAND(DrawEllipse, draw_ellipse)
|
|
else HANDLE_COMMAND(FillEllipse, fill_ellipse)
|
|
else HANDLE_COMMAND(DrawLine, draw_line)
|
|
else HANDLE_COMMAND(ApplyBackdropFilter, apply_backdrop_filter)
|
|
else HANDLE_COMMAND(DrawRect, draw_rect)
|
|
else HANDLE_COMMAND(DrawTriangleWave, draw_triangle_wave)
|
|
else HANDLE_COMMAND(AddRoundedRectClip, add_rounded_rect_clip)
|
|
else HANDLE_COMMAND(AddMask, add_mask)
|
|
else HANDLE_COMMAND(PaintScrollBar, paint_scrollbar)
|
|
else HANDLE_COMMAND(PaintNestedDisplayList, paint_nested_display_list)
|
|
else HANDLE_COMMAND(ApplyOpacity, apply_opacity)
|
|
else HANDLE_COMMAND(ApplyTransform, apply_transform)
|
|
else HANDLE_COMMAND(ApplyMaskBitmap, apply_mask_bitmap)
|
|
else VERIFY_NOT_REACHED();
|
|
// clang-format on
|
|
}
|
|
}
|
|
|
|
}
|