LibWeb: Plumbing for lineCap, lineJoin, miterLimit, lineDashOffset

Not used for painting yet, but adds a FIXME for what's missing.

Also tweak some existing spec comments minorly.
This commit is contained in:
Nico Weber 2024-11-07 09:27:55 -05:00 committed by Andreas Kling
parent 96ded779e2
commit 7ac3806a1d
Notes: github-actions[bot] 2024-11-07 18:55:02 +00:00
5 changed files with 75 additions and 7 deletions

View file

@ -31,10 +31,52 @@ public:
return my_drawing_state().line_width;
}
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap
void set_line_cap(Bindings::CanvasLineCap line_cap)
{
// On setting, the current value must be changed to the new value.
my_drawing_state().line_cap = line_cap;
}
Bindings::CanvasLineCap line_cap() const
{
// On getting, it must return the current value.
return my_drawing_state().line_cap;
}
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linejoin
void set_line_join(Bindings::CanvasLineJoin line_join)
{
// On setting, the current value must be changed to the new value.
my_drawing_state().line_join = line_join;
}
Bindings::CanvasLineJoin line_join() const
{
// On getting, it must return the current value.
return my_drawing_state().line_join;
}
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-miterlimit
void set_miter_limit(float miter_limit)
{
// On setting, zero, negative, infinite, and NaN values must be ignored, leaving the value unchanged;
if (miter_limit <= 0 || !isfinite(miter_limit))
return;
// other values must change the current value to the new value.
my_drawing_state().miter_limit = miter_limit;
}
float miter_limit() const
{
// On getting, it must return the current value.
return my_drawing_state().miter_limit;
}
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-setlinedash
void set_line_dash(Vector<double> segments)
{
// 1. If any value in segments is not finite (e.g. an Infinity or a NaN value), or if any value is negative (less than zero), then return (without throwing an exception; user agents could show a message on a developer console, though, as that would be helpful for debugging).
// The setLineDash(segments) method, when invoked, must run these steps:
// 1. If any value in segments is not finite (e.g. an Infinity or a NaN value), or if any value is negative (less than zero), then return
// (without throwing an exception; user agents could show a message on a developer console, though, as that would be helpful for debugging).
for (auto const& segment : segments) {
if (!isfinite(segment) || segment < 0)
return;
@ -51,9 +93,25 @@ public:
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-getlinedash
Vector<double> get_line_dash()
{
// When the getLineDash() method is invoked, it must return a sequence whose values are the values of the object's dash list, in the same order.
return my_drawing_state().dash_list;
}
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linedashoffset
void set_line_dash_offset(float line_dash_offset)
{
// On setting, infinite and NaN values must be ignored, leaving the value unchanged;
if (!isfinite(line_dash_offset))
return;
// other values must change the current value to the new value.
my_drawing_state().line_dash_offset = line_dash_offset;
}
float line_dash_offset() const
{
// On getting, it must return the current value.
return my_drawing_state().line_dash_offset;
}
protected:
CanvasPathDrawingStyles() = default;

View file

@ -1,15 +1,15 @@
// https://html.spec.whatwg.org/multipage/canvas.html#canvaslinecap
enum CanvasLineCap { "butt", "round", "square" };
enum CanvasLineJoin { "round", "bevel", "miter" };
// enum CanvasLineCap { "butt", "round", "square" };
// enum CanvasLineJoin { "round", "bevel", "miter" };
// https://html.spec.whatwg.org/multipage/canvas.html#canvaspathdrawingstyles
interface mixin CanvasPathDrawingStyles {
attribute unrestricted double lineWidth;
[FIXME] attribute CanvasLineCap lineCap;
[FIXME] attribute CanvasLineJoin lineJoin;
[FIXME] attribute unrestricted double miterLimit;
attribute CanvasLineCap lineCap;
attribute CanvasLineJoin lineJoin;
attribute unrestricted double miterLimit;
undefined setLineDash(sequence<unrestricted double> segments);
sequence<unrestricted double> getLineDash();
[FIXME] attribute unrestricted double lineDashOffset;
attribute unrestricted double lineDashOffset;
};

View file

@ -84,7 +84,11 @@ public:
float shadow_offset_y { 0.0f };
Gfx::Color shadow_color { Gfx::Color::Transparent };
float line_width { 1 };
Bindings::CanvasLineCap line_cap { Bindings::CanvasLineCap::Butt };
Bindings::CanvasLineJoin line_join { Bindings::CanvasLineJoin::Miter };
float miter_limit { 10 };
Vector<double> dash_list;
float line_dash_offset { 0 };
bool image_smoothing_enabled { true };
Bindings::ImageSmoothingQuality image_smoothing_quality { Bindings::ImageSmoothingQuality::Low };
float global_alpha = { 1 };

View file

@ -272,6 +272,8 @@ void CanvasRenderingContext2D::stroke_internal(Gfx::Path const& path)
auto& state = drawing_state();
// FIXME: Honor state's line_cap, line_join, miter_limit, dash_list, and line_dash_offset.
if (auto color = state.stroke_style.as_color(); color.has_value()) {
painter->stroke_path(path, color->with_opacity(state.global_alpha), state.line_width);
} else {

View file

@ -27,6 +27,10 @@ dictionary CanvasRenderingContext2DSettings {
enum ImageSmoothingQuality { "low", "medium", "high" };
// FIXME: This should be in CanvasPathDrawingStyles.idl but then it is not exported
enum CanvasLineCap { "butt", "round", "square" };
enum CanvasLineJoin { "round", "bevel", "miter" };
// FIXME: This should be in CanvasTextDrawingStyles.idl but then it is not exported
enum CanvasTextAlign { "start", "end", "left", "right", "center" };
enum CanvasTextBaseline { "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" };