mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-29 13:46:31 +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/DistinctNumeric.h>
|
||||||
#include <AK/Variant.h>
|
#include <AK/Variant.h>
|
||||||
|
#include <LibGfx/Forward.h>
|
||||||
#include <LibIPC/Forward.h>
|
#include <LibIPC/Forward.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@ class DisplayListRecorder;
|
||||||
class SVGGradientPaintStyle;
|
class SVGGradientPaintStyle;
|
||||||
class ScrollStateSnapshot;
|
class ScrollStateSnapshot;
|
||||||
using PaintStyle = RefPtr<SVGGradientPaintStyle>;
|
using PaintStyle = RefPtr<SVGGradientPaintStyle>;
|
||||||
|
using PaintStyleOrColor = Variant<PaintStyle, Gfx::Color>;
|
||||||
using ScrollStateSnapshotByDisplayList = HashMap<NonnullRefPtr<DisplayList>, ScrollStateSnapshot>;
|
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(FillRectWithRoundedCorners, fill_rect_with_rounded_corners)
|
||||||
else HANDLE_COMMAND(FillPathUsingColor, fill_path_using_color)
|
else HANDLE_COMMAND(FillPathUsingColor, fill_path_using_color)
|
||||||
else HANDLE_COMMAND(FillPathUsingPaintStyle, fill_path_using_paint_style)
|
else HANDLE_COMMAND(FillPathUsingPaintStyle, fill_path_using_paint_style)
|
||||||
else HANDLE_COMMAND(StrokePathUsingColor, stroke_path_using_color)
|
else HANDLE_COMMAND(StrokePath, stroke_path)
|
||||||
else HANDLE_COMMAND(StrokePathUsingPaintStyle, stroke_path_using_paint_style)
|
|
||||||
else HANDLE_COMMAND(DrawEllipse, draw_ellipse)
|
else HANDLE_COMMAND(DrawEllipse, draw_ellipse)
|
||||||
else HANDLE_COMMAND(FillEllipse, fill_ellipse)
|
else HANDLE_COMMAND(FillEllipse, fill_ellipse)
|
||||||
else HANDLE_COMMAND(DrawLine, draw_line)
|
else HANDLE_COMMAND(DrawLine, draw_line)
|
||||||
|
|
|
@ -57,8 +57,7 @@ private:
|
||||||
virtual void fill_rect_with_rounded_corners(FillRectWithRoundedCorners const&) = 0;
|
virtual void fill_rect_with_rounded_corners(FillRectWithRoundedCorners const&) = 0;
|
||||||
virtual void fill_path_using_color(FillPathUsingColor const&) = 0;
|
virtual void fill_path_using_color(FillPathUsingColor const&) = 0;
|
||||||
virtual void fill_path_using_paint_style(FillPathUsingPaintStyle 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(StrokePath const&) = 0;
|
||||||
virtual void stroke_path_using_paint_style(StrokePathUsingPaintStyle const&) = 0;
|
|
||||||
virtual void draw_ellipse(DrawEllipse const&) = 0;
|
virtual void draw_ellipse(DrawEllipse const&) = 0;
|
||||||
virtual void fill_ellipse(FillEllipse const&) = 0;
|
virtual void fill_ellipse(FillEllipse const&) = 0;
|
||||||
virtual void draw_line(DrawLine const&) = 0;
|
virtual void draw_line(DrawLine const&) = 0;
|
||||||
|
|
|
@ -147,14 +147,9 @@ void FillPathUsingPaintStyle::dump(StringBuilder& builder) const
|
||||||
builder.appendff("FillPathUsingPaintStyle");
|
builder.appendff("FillPathUsingPaintStyle");
|
||||||
}
|
}
|
||||||
|
|
||||||
void StrokePathUsingColor::dump(StringBuilder& builder) const
|
void StrokePath::dump(StringBuilder& builder) const
|
||||||
{
|
{
|
||||||
builder.appendff("StrokePathUsingColor");
|
builder.appendff("StrokePath");
|
||||||
}
|
|
||||||
|
|
||||||
void StrokePathUsingPaintStyle::dump(StringBuilder& builder) const
|
|
||||||
{
|
|
||||||
builder.appendff("StrokePathUsingPaintStyle");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawEllipse::dump(StringBuilder& builder) const
|
void DrawEllipse::dump(StringBuilder& builder) const
|
||||||
|
|
|
@ -246,7 +246,7 @@ struct FillPathUsingPaintStyle {
|
||||||
void dump(StringBuilder&) const;
|
void dump(StringBuilder&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StrokePathUsingColor {
|
struct StrokePath {
|
||||||
Gfx::Path::CapStyle cap_style;
|
Gfx::Path::CapStyle cap_style;
|
||||||
Gfx::Path::JoinStyle join_style;
|
Gfx::Path::JoinStyle join_style;
|
||||||
float miter_limit;
|
float miter_limit;
|
||||||
|
@ -254,7 +254,8 @@ struct StrokePathUsingColor {
|
||||||
float dash_offset;
|
float dash_offset;
|
||||||
Gfx::IntRect path_bounding_rect;
|
Gfx::IntRect path_bounding_rect;
|
||||||
Gfx::Path path;
|
Gfx::Path path;
|
||||||
Color color;
|
float opacity;
|
||||||
|
PaintStyleOrColor paint_style_or_color;
|
||||||
float thickness;
|
float thickness;
|
||||||
Gfx::FloatPoint aa_translation;
|
Gfx::FloatPoint aa_translation;
|
||||||
|
|
||||||
|
@ -268,29 +269,6 @@ struct StrokePathUsingColor {
|
||||||
void dump(StringBuilder&) const;
|
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 {
|
struct DrawEllipse {
|
||||||
Gfx::IntRect rect;
|
Gfx::IntRect rect;
|
||||||
Color color;
|
Color color;
|
||||||
|
@ -508,8 +486,7 @@ using DisplayListCommand = Variant<
|
||||||
FillRectWithRoundedCorners,
|
FillRectWithRoundedCorners,
|
||||||
FillPathUsingColor,
|
FillPathUsingColor,
|
||||||
FillPathUsingPaintStyle,
|
FillPathUsingPaintStyle,
|
||||||
StrokePathUsingColor,
|
StrokePath,
|
||||||
StrokePathUsingPaintStyle,
|
|
||||||
DrawEllipse,
|
DrawEllipse,
|
||||||
FillEllipse,
|
FillEllipse,
|
||||||
DrawLine,
|
DrawLine,
|
||||||
|
|
|
@ -660,30 +660,20 @@ void DisplayListPlayerSkia::fill_path_using_paint_style(FillPathUsingPaintStyle
|
||||||
surface().canvas().drawPath(path, paint);
|
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;
|
SkPaint paint;
|
||||||
|
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.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);
|
|
||||||
paint.setAlphaf(command.opacity);
|
|
||||||
paint.setStyle(SkPaint::Style::kStroke_Style);
|
paint.setStyle(SkPaint::Style::kStroke_Style);
|
||||||
paint.setStrokeWidth(command.thickness);
|
paint.setStrokeWidth(command.thickness);
|
||||||
paint.setStrokeCap(to_skia_cap(command.cap_style));
|
paint.setStrokeCap(to_skia_cap(command.cap_style));
|
||||||
|
|
|
@ -42,8 +42,7 @@ private:
|
||||||
void fill_rect_with_rounded_corners(FillRectWithRoundedCorners const&) override;
|
void fill_rect_with_rounded_corners(FillRectWithRoundedCorners const&) override;
|
||||||
void fill_path_using_color(FillPathUsingColor const&) override;
|
void fill_path_using_color(FillPathUsingColor const&) override;
|
||||||
void fill_path_using_paint_style(FillPathUsingPaintStyle const&) override;
|
void fill_path_using_paint_style(FillPathUsingPaintStyle const&) override;
|
||||||
void stroke_path_using_color(StrokePathUsingColor const&) override;
|
void stroke_path(StrokePath const&) override;
|
||||||
void stroke_path_using_paint_style(StrokePathUsingPaintStyle const&) override;
|
|
||||||
void draw_ellipse(DrawEllipse const&) override;
|
void draw_ellipse(DrawEllipse const&) override;
|
||||||
void fill_ellipse(FillEllipse const&) override;
|
void fill_ellipse(FillEllipse const&) override;
|
||||||
void draw_line(DrawLine 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.
|
// Skia treats zero thickness as a special case and will draw a hairline, while we want to draw nothing.
|
||||||
if (!params.thickness)
|
if (!params.thickness)
|
||||||
return;
|
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;
|
return;
|
||||||
auto aa_translation = params.translation.value_or(Gfx::FloatPoint {});
|
auto aa_translation = params.translation.value_or(Gfx::FloatPoint {});
|
||||||
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation);
|
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);
|
auto path_bounding_int_rect = enclosing_int_rect(path_bounding_rect);
|
||||||
if (path_bounding_int_rect.is_empty())
|
if (path_bounding_int_rect.is_empty())
|
||||||
return;
|
return;
|
||||||
APPEND(StrokePathUsingColor {
|
APPEND(StrokePath {
|
||||||
.cap_style = params.cap_style,
|
.cap_style = params.cap_style,
|
||||||
.join_style = params.join_style,
|
.join_style = params.join_style,
|
||||||
.miter_limit = params.miter_limit,
|
.miter_limit = params.miter_limit,
|
||||||
|
@ -121,35 +121,9 @@ void DisplayListRecorder::stroke_path(StrokePathUsingColorParams params)
|
||||||
.dash_offset = params.dash_offset,
|
.dash_offset = params.dash_offset,
|
||||||
.path_bounding_rect = path_bounding_int_rect,
|
.path_bounding_rect = path_bounding_int_rect,
|
||||||
.path = move(params.path),
|
.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,
|
.opacity = params.opacity,
|
||||||
|
.paint_style_or_color = params.paint_style_or_color,
|
||||||
|
.thickness = params.thickness,
|
||||||
.aa_translation = aa_translation,
|
.aa_translation = aa_translation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,32 +56,19 @@ public:
|
||||||
};
|
};
|
||||||
void fill_path(FillPathUsingPaintStyleParams params);
|
void fill_path(FillPathUsingPaintStyleParams params);
|
||||||
|
|
||||||
struct StrokePathUsingColorParams {
|
struct StrokePathParams {
|
||||||
Gfx::Path::CapStyle cap_style;
|
Gfx::Path::CapStyle cap_style;
|
||||||
Gfx::Path::JoinStyle join_style;
|
Gfx::Path::JoinStyle join_style;
|
||||||
float miter_limit;
|
float miter_limit;
|
||||||
Vector<float> dash_array;
|
Vector<float> dash_array;
|
||||||
float dash_offset;
|
float dash_offset;
|
||||||
Gfx::Path path;
|
Gfx::Path path;
|
||||||
Gfx::Color color;
|
float opacity = 1.0f;
|
||||||
|
PaintStyleOrColor paint_style_or_color;
|
||||||
float thickness;
|
float thickness;
|
||||||
Optional<Gfx::FloatPoint> translation = {};
|
Optional<Gfx::FloatPoint> translation = {};
|
||||||
};
|
};
|
||||||
void stroke_path(StrokePathUsingColorParams params);
|
void stroke_path(StrokePathParams);
|
||||||
|
|
||||||
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 draw_ellipse(Gfx::IntRect const& a_rect, Color color, int thickness);
|
void draw_ellipse(Gfx::IntRect const& a_rect, Color color, int thickness);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWeb/Painting/DisplayListRecorder.h>
|
#include <LibWeb/Painting/DisplayListRecorder.h>
|
||||||
#include <LibWeb/Painting/MediaPaintable.h>
|
#include <LibWeb/Painting/MediaPaintable.h>
|
||||||
|
#include <LibWeb/Painting/PaintStyle.h>
|
||||||
#include <LibWeb/UIEvents/MouseButton.h>
|
#include <LibWeb/UIEvents/MouseButton.h>
|
||||||
|
|
||||||
namespace Web::Painting {
|
namespace Web::Painting {
|
||||||
|
@ -242,7 +243,7 @@ void MediaPaintable::paint_control_bar_speaker(DisplayListRecordingContext& cont
|
||||||
.dash_array = {},
|
.dash_array = {},
|
||||||
.dash_offset = 0,
|
.dash_offset = 0,
|
||||||
.path = path,
|
.path = path,
|
||||||
.color = speaker_button_color,
|
.paint_style_or_color = speaker_button_color,
|
||||||
.thickness = 1,
|
.thickness = 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -904,7 +904,7 @@ void paint_text_decoration(DisplayListRecordingContext& context, TextPaintable c
|
||||||
.dash_array = {},
|
.dash_array = {},
|
||||||
.dash_offset = 0,
|
.dash_offset = 0,
|
||||||
.path = build_triangle_wave_path(line_start_point.to_type<int>(), line_end_point.to_type<int>(), amplitude),
|
.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()),
|
.thickness = static_cast<float>(device_line_thickness.value()),
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -176,9 +176,9 @@ void SVGPathPaintable::paint(DisplayListRecordingContext& context, PaintPhase ph
|
||||||
.dash_array = stroke_dasharray,
|
.dash_array = stroke_dasharray,
|
||||||
.dash_offset = stroke_dashoffset,
|
.dash_offset = stroke_dashoffset,
|
||||||
.path = path,
|
.path = path,
|
||||||
.paint_style = *paint_style,
|
|
||||||
.thickness = stroke_thickness,
|
|
||||||
.opacity = stroke_opacity,
|
.opacity = stroke_opacity,
|
||||||
|
.paint_style_or_color = *paint_style,
|
||||||
|
.thickness = stroke_thickness,
|
||||||
.translation = offset,
|
.translation = offset,
|
||||||
});
|
});
|
||||||
} else if (auto stroke_color = graphics_element.stroke_color(); stroke_color.has_value()) {
|
} 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_array = stroke_dasharray,
|
||||||
.dash_offset = stroke_dashoffset,
|
.dash_offset = stroke_dashoffset,
|
||||||
.path = path,
|
.path = path,
|
||||||
.color = stroke_color->with_opacity(stroke_opacity),
|
.paint_style_or_color = stroke_color->with_opacity(stroke_opacity),
|
||||||
.thickness = stroke_thickness,
|
.thickness = stroke_thickness,
|
||||||
.translation = offset,
|
.translation = offset,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue