diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.h
index fc44d6b2e20..1d31c657370 100644
--- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.h
+++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.h
@@ -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 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 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;
diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.idl b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.idl
index 07a5f87824a..86fe9f13a97 100644
--- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.idl
+++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasPathDrawingStyles.idl
@@ -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 segments);
sequence getLineDash();
- [FIXME] attribute unrestricted double lineDashOffset;
+ attribute unrestricted double lineDashOffset;
};
diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h
index 3d33e336c65..f028a2e7a15 100644
--- a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h
+++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasState.h
@@ -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 dash_list;
+ float line_dash_offset { 0 };
bool image_smoothing_enabled { true };
Bindings::ImageSmoothingQuality image_smoothing_quality { Bindings::ImageSmoothingQuality::Low };
float global_alpha = { 1 };
diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp
index 0b6013f16a6..eb7ec32d8e3 100644
--- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp
+++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp
@@ -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 {
diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl
index b06cc0422ef..45cf988b1e5 100644
--- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl
+++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl
@@ -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" };