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" };