mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 13:18:19 +00:00
LibWeb: Merge StrokePathUsingPaintStyle and StrokePathUsingColor
Use `Variant<PaintStyle, Gfx::Color>` in new `StrokePath` instead of duplicating two almost identical display list items.
This commit is contained in:
parent
e41c85ec47
commit
5c11a541d3
Notes:
github-actions[bot]
2025-08-03 08:43:52 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 5c11a541d3
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5685
Reviewed-by: https://github.com/gmta ✅
12 changed files with 37 additions and 114 deletions
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibJS/Forward.h>
|
||||
|
||||
|
@ -42,6 +43,7 @@ class DisplayListRecorder;
|
|||
class SVGGradientPaintStyle;
|
||||
class ScrollStateSnapshot;
|
||||
using PaintStyle = RefPtr<SVGGradientPaintStyle>;
|
||||
using PaintStyleOrColor = Variant<PaintStyle, Gfx::Color>;
|
||||
using ScrollStateSnapshotByDisplayList = HashMap<NonnullRefPtr<DisplayList>, ScrollStateSnapshot>;
|
||||
|
||||
}
|
||||
|
|
|
@ -216,8 +216,7 @@ void DisplayListPlayer::execute_impl(DisplayList& display_list, ScrollStateSnaps
|
|||
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(StrokePath, stroke_path)
|
||||
else HANDLE_COMMAND(DrawEllipse, draw_ellipse)
|
||||
else HANDLE_COMMAND(FillEllipse, fill_ellipse)
|
||||
else HANDLE_COMMAND(DrawLine, draw_line)
|
||||
|
|
|
@ -57,8 +57,7 @@ private:
|
|||
virtual void fill_rect_with_rounded_corners(FillRectWithRoundedCorners const&) = 0;
|
||||
virtual void fill_path_using_color(FillPathUsingColor const&) = 0;
|
||||
virtual void fill_path_using_paint_style(FillPathUsingPaintStyle const&) = 0;
|
||||
virtual void stroke_path_using_color(StrokePathUsingColor const&) = 0;
|
||||
virtual void stroke_path_using_paint_style(StrokePathUsingPaintStyle const&) = 0;
|
||||
virtual void stroke_path(StrokePath const&) = 0;
|
||||
virtual void draw_ellipse(DrawEllipse const&) = 0;
|
||||
virtual void fill_ellipse(FillEllipse const&) = 0;
|
||||
virtual void draw_line(DrawLine const&) = 0;
|
||||
|
|
|
@ -147,14 +147,9 @@ void FillPathUsingPaintStyle::dump(StringBuilder& builder) const
|
|||
builder.appendff("FillPathUsingPaintStyle");
|
||||
}
|
||||
|
||||
void StrokePathUsingColor::dump(StringBuilder& builder) const
|
||||
void StrokePath::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("StrokePathUsingColor");
|
||||
}
|
||||
|
||||
void StrokePathUsingPaintStyle::dump(StringBuilder& builder) const
|
||||
{
|
||||
builder.appendff("StrokePathUsingPaintStyle");
|
||||
builder.appendff("StrokePath");
|
||||
}
|
||||
|
||||
void DrawEllipse::dump(StringBuilder& builder) const
|
||||
|
|
|
@ -246,7 +246,7 @@ struct FillPathUsingPaintStyle {
|
|||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct StrokePathUsingColor {
|
||||
struct StrokePath {
|
||||
Gfx::Path::CapStyle cap_style;
|
||||
Gfx::Path::JoinStyle join_style;
|
||||
float miter_limit;
|
||||
|
@ -254,7 +254,8 @@ struct StrokePathUsingColor {
|
|||
float dash_offset;
|
||||
Gfx::IntRect path_bounding_rect;
|
||||
Gfx::Path path;
|
||||
Color color;
|
||||
float opacity;
|
||||
PaintStyleOrColor paint_style_or_color;
|
||||
float thickness;
|
||||
Gfx::FloatPoint aa_translation;
|
||||
|
||||
|
@ -268,29 +269,6 @@ struct StrokePathUsingColor {
|
|||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct StrokePathUsingPaintStyle {
|
||||
Gfx::Path::CapStyle cap_style;
|
||||
Gfx::Path::JoinStyle join_style;
|
||||
float miter_limit;
|
||||
Vector<float> dash_array;
|
||||
float dash_offset;
|
||||
Gfx::IntRect path_bounding_rect;
|
||||
Gfx::Path path;
|
||||
PaintStyle paint_style;
|
||||
float thickness;
|
||||
float opacity = 1.0f;
|
||||
Gfx::FloatPoint aa_translation;
|
||||
|
||||
[[nodiscard]] Gfx::IntRect bounding_rect() const { return path_bounding_rect; }
|
||||
|
||||
void translate_by(Gfx::IntPoint const& offset)
|
||||
{
|
||||
path_bounding_rect.translate_by(offset);
|
||||
aa_translation.translate_by(offset.to_type<float>());
|
||||
}
|
||||
void dump(StringBuilder&) const;
|
||||
};
|
||||
|
||||
struct DrawEllipse {
|
||||
Gfx::IntRect rect;
|
||||
Color color;
|
||||
|
@ -508,8 +486,7 @@ using DisplayListCommand = Variant<
|
|||
FillRectWithRoundedCorners,
|
||||
FillPathUsingColor,
|
||||
FillPathUsingPaintStyle,
|
||||
StrokePathUsingColor,
|
||||
StrokePathUsingPaintStyle,
|
||||
StrokePath,
|
||||
DrawEllipse,
|
||||
FillEllipse,
|
||||
DrawLine,
|
||||
|
|
|
@ -660,30 +660,20 @@ void DisplayListPlayerSkia::fill_path_using_paint_style(FillPathUsingPaintStyle
|
|||
surface().canvas().drawPath(path, paint);
|
||||
}
|
||||
|
||||
void DisplayListPlayerSkia::stroke_path_using_color(StrokePathUsingColor const& command)
|
||||
void DisplayListPlayerSkia::stroke_path(StrokePath const& command)
|
||||
{
|
||||
auto& canvas = surface().canvas();
|
||||
auto path = to_skia_path(command.path);
|
||||
path.offset(command.aa_translation.x(), command.aa_translation.y());
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
paint.setStrokeWidth(command.thickness);
|
||||
paint.setStrokeCap(to_skia_cap(command.cap_style));
|
||||
paint.setStrokeJoin(to_skia_join(command.join_style));
|
||||
paint.setColor(to_skia_color(command.color));
|
||||
paint.setStrokeMiter(command.miter_limit);
|
||||
paint.setPathEffect(SkDashPathEffect::Make(command.dash_array.data(), command.dash_array.size(), command.dash_offset));
|
||||
auto path = to_skia_path(command.path);
|
||||
path.offset(command.aa_translation.x(), command.aa_translation.y());
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
||||
|
||||
void DisplayListPlayerSkia::stroke_path_using_paint_style(StrokePathUsingPaintStyle const& command)
|
||||
{
|
||||
auto path = to_skia_path(command.path);
|
||||
path.offset(command.aa_translation.x(), command.aa_translation.y());
|
||||
auto paint = paint_style_to_skia_paint(*command.paint_style, command.bounding_rect().to_type<float>());
|
||||
paint.setAntiAlias(true);
|
||||
if (command.paint_style_or_color.has<PaintStyle>()) {
|
||||
auto const& paint_style = command.paint_style_or_color.get<PaintStyle>();
|
||||
paint = paint_style_to_skia_paint(*paint_style, command.bounding_rect().to_type<float>());
|
||||
paint.setAlphaf(command.opacity);
|
||||
} else {
|
||||
auto const& color = command.paint_style_or_color.get<Color>();
|
||||
paint.setColor(to_skia_color(color));
|
||||
}
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(SkPaint::Style::kStroke_Style);
|
||||
paint.setStrokeWidth(command.thickness);
|
||||
paint.setStrokeCap(to_skia_cap(command.cap_style));
|
||||
|
|
|
@ -42,8 +42,7 @@ private:
|
|||
void fill_rect_with_rounded_corners(FillRectWithRoundedCorners const&) override;
|
||||
void fill_path_using_color(FillPathUsingColor const&) override;
|
||||
void fill_path_using_paint_style(FillPathUsingPaintStyle const&) override;
|
||||
void stroke_path_using_color(StrokePathUsingColor const&) override;
|
||||
void stroke_path_using_paint_style(StrokePathUsingPaintStyle const&) override;
|
||||
void stroke_path(StrokePath const&) override;
|
||||
void draw_ellipse(DrawEllipse const&) override;
|
||||
void fill_ellipse(FillEllipse const&) override;
|
||||
void draw_line(DrawLine const&) override;
|
||||
|
|
|
@ -99,12 +99,12 @@ void DisplayListRecorder::fill_path(FillPathUsingPaintStyleParams params)
|
|||
});
|
||||
}
|
||||
|
||||
void DisplayListRecorder::stroke_path(StrokePathUsingColorParams params)
|
||||
void DisplayListRecorder::stroke_path(StrokePathParams params)
|
||||
{
|
||||
// Skia treats zero thickness as a special case and will draw a hairline, while we want to draw nothing.
|
||||
if (!params.thickness)
|
||||
return;
|
||||
if (params.color.alpha() == 0)
|
||||
if (params.paint_style_or_color.has<Gfx::Color>() && params.paint_style_or_color.get<Gfx::Color>().alpha() == 0)
|
||||
return;
|
||||
auto aa_translation = params.translation.value_or(Gfx::FloatPoint {});
|
||||
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation);
|
||||
|
@ -113,7 +113,7 @@ void DisplayListRecorder::stroke_path(StrokePathUsingColorParams params)
|
|||
auto path_bounding_int_rect = enclosing_int_rect(path_bounding_rect);
|
||||
if (path_bounding_int_rect.is_empty())
|
||||
return;
|
||||
APPEND(StrokePathUsingColor {
|
||||
APPEND(StrokePath {
|
||||
.cap_style = params.cap_style,
|
||||
.join_style = params.join_style,
|
||||
.miter_limit = params.miter_limit,
|
||||
|
@ -121,35 +121,9 @@ void DisplayListRecorder::stroke_path(StrokePathUsingColorParams params)
|
|||
.dash_offset = params.dash_offset,
|
||||
.path_bounding_rect = path_bounding_int_rect,
|
||||
.path = move(params.path),
|
||||
.color = params.color,
|
||||
.thickness = params.thickness,
|
||||
.aa_translation = aa_translation,
|
||||
});
|
||||
}
|
||||
|
||||
void DisplayListRecorder::stroke_path(StrokePathUsingPaintStyleParams params)
|
||||
{
|
||||
// Skia treats zero thickness as a special case and will draw a hairline, while we want to draw nothing.
|
||||
if (!params.thickness)
|
||||
return;
|
||||
auto aa_translation = params.translation.value_or(Gfx::FloatPoint {});
|
||||
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation);
|
||||
// Increase path bounding box by `thickness` to account for stroke.
|
||||
path_bounding_rect.inflate(params.thickness, params.thickness);
|
||||
auto path_bounding_int_rect = enclosing_int_rect(path_bounding_rect);
|
||||
if (path_bounding_int_rect.is_empty())
|
||||
return;
|
||||
APPEND(StrokePathUsingPaintStyle {
|
||||
.cap_style = params.cap_style,
|
||||
.join_style = params.join_style,
|
||||
.miter_limit = params.miter_limit,
|
||||
.dash_array = move(params.dash_array),
|
||||
.dash_offset = params.dash_offset,
|
||||
.path_bounding_rect = path_bounding_int_rect,
|
||||
.path = move(params.path),
|
||||
.paint_style = params.paint_style,
|
||||
.thickness = params.thickness,
|
||||
.opacity = params.opacity,
|
||||
.paint_style_or_color = params.paint_style_or_color,
|
||||
.thickness = params.thickness,
|
||||
.aa_translation = aa_translation,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -56,32 +56,19 @@ public:
|
|||
};
|
||||
void fill_path(FillPathUsingPaintStyleParams params);
|
||||
|
||||
struct StrokePathUsingColorParams {
|
||||
struct StrokePathParams {
|
||||
Gfx::Path::CapStyle cap_style;
|
||||
Gfx::Path::JoinStyle join_style;
|
||||
float miter_limit;
|
||||
Vector<float> dash_array;
|
||||
float dash_offset;
|
||||
Gfx::Path path;
|
||||
Gfx::Color color;
|
||||
float opacity = 1.0f;
|
||||
PaintStyleOrColor paint_style_or_color;
|
||||
float thickness;
|
||||
Optional<Gfx::FloatPoint> translation = {};
|
||||
};
|
||||
void stroke_path(StrokePathUsingColorParams params);
|
||||
|
||||
struct StrokePathUsingPaintStyleParams {
|
||||
Gfx::Path::CapStyle cap_style;
|
||||
Gfx::Path::JoinStyle join_style;
|
||||
float miter_limit;
|
||||
Vector<float> dash_array;
|
||||
float dash_offset;
|
||||
Gfx::Path path;
|
||||
PaintStyle paint_style;
|
||||
float thickness;
|
||||
float opacity;
|
||||
Optional<Gfx::FloatPoint> translation = {};
|
||||
};
|
||||
void stroke_path(StrokePathUsingPaintStyleParams params);
|
||||
void stroke_path(StrokePathParams);
|
||||
|
||||
void draw_ellipse(Gfx::IntRect const& a_rect, Color color, int thickness);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/Painting/DisplayListRecorder.h>
|
||||
#include <LibWeb/Painting/MediaPaintable.h>
|
||||
#include <LibWeb/Painting/PaintStyle.h>
|
||||
#include <LibWeb/UIEvents/MouseButton.h>
|
||||
|
||||
namespace Web::Painting {
|
||||
|
@ -242,7 +243,7 @@ void MediaPaintable::paint_control_bar_speaker(DisplayListRecordingContext& cont
|
|||
.dash_array = {},
|
||||
.dash_offset = 0,
|
||||
.path = path,
|
||||
.color = speaker_button_color,
|
||||
.paint_style_or_color = speaker_button_color,
|
||||
.thickness = 1,
|
||||
});
|
||||
|
||||
|
|
|
@ -904,7 +904,7 @@ void paint_text_decoration(DisplayListRecordingContext& context, TextPaintable c
|
|||
.dash_array = {},
|
||||
.dash_offset = 0,
|
||||
.path = build_triangle_wave_path(line_start_point.to_type<int>(), line_end_point.to_type<int>(), amplitude),
|
||||
.color = line_color,
|
||||
.paint_style_or_color = line_color,
|
||||
.thickness = static_cast<float>(device_line_thickness.value()),
|
||||
});
|
||||
break;
|
||||
|
|
|
@ -176,9 +176,9 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
|||
.dash_array = stroke_dasharray,
|
||||
.dash_offset = stroke_dashoffset,
|
||||
.path = path,
|
||||
.paint_style = *paint_style,
|
||||
.thickness = stroke_thickness,
|
||||
.opacity = stroke_opacity,
|
||||
.paint_style_or_color = *paint_style,
|
||||
.thickness = stroke_thickness,
|
||||
.translation = offset,
|
||||
});
|
||||
} else if (auto stroke_color = graphics_element.stroke_color(); stroke_color.has_value()) {
|
||||
|
@ -189,7 +189,7 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
|||
.dash_array = stroke_dasharray,
|
||||
.dash_offset = stroke_dashoffset,
|
||||
.path = path,
|
||||
.color = stroke_color->with_opacity(stroke_opacity),
|
||||
.paint_style_or_color = stroke_color->with_opacity(stroke_opacity),
|
||||
.thickness = stroke_thickness,
|
||||
.translation = offset,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue