Jelajahi Sumber

LibWeb: Teach CRC2D to draw Path2Ds :^)

Sam Atkins 3 tahun lalu
induk
melakukan
6644f3ab44

+ 31 - 8
Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp

@@ -320,33 +320,56 @@ void CanvasRenderingContext2D::begin_path()
     path().clear();
 }
 
-void CanvasRenderingContext2D::stroke()
+void CanvasRenderingContext2D::stroke_internal(Gfx::Path const& path)
 {
     auto painter = this->painter();
     if (!painter)
         return;
 
-    painter->stroke_path(path(), m_drawing_state.stroke_style, m_drawing_state.line_width);
-    did_draw(path().bounding_box());
+    painter->stroke_path(path, m_drawing_state.stroke_style, m_drawing_state.line_width);
+    did_draw(path.bounding_box());
+}
+
+void CanvasRenderingContext2D::stroke()
+{
+    stroke_internal(path());
+}
+
+void CanvasRenderingContext2D::stroke(Path2D const& path)
+{
+    auto transformed_path = path.path().copy_transformed(m_drawing_state.transform);
+    stroke_internal(transformed_path);
 }
 
-void CanvasRenderingContext2D::fill(Gfx::Painter::WindingRule winding)
+void CanvasRenderingContext2D::fill_internal(Gfx::Path& path, String const& fill_rule)
 {
     auto painter = this->painter();
     if (!painter)
         return;
 
-    auto path = this->path();
     path.close_all_subpaths();
+
+    auto winding = Gfx::Painter::WindingRule::Nonzero;
+    if (fill_rule == "evenodd")
+        winding = Gfx::Painter::WindingRule::EvenOdd;
+    else if (fill_rule == "nonzero")
+        winding = Gfx::Painter::WindingRule::Nonzero;
+    else
+        dbgln("Unrecognized fillRule for CRC2D.fill() - this problem goes away once we pass an enum instead of a string");
+
     painter->fill_path(path, m_drawing_state.fill_style, winding);
     did_draw(path.bounding_box());
 }
 
 void CanvasRenderingContext2D::fill(String const& fill_rule)
 {
-    if (fill_rule == "evenodd")
-        return fill(Gfx::Painter::WindingRule::EvenOdd);
-    return fill(Gfx::Painter::WindingRule::Nonzero);
+    return fill_internal(path(), fill_rule);
+}
+
+void CanvasRenderingContext2D::fill(Path2D& path, String const& fill_rule)
+{
+    auto transformed_path = path.path().copy_transformed(m_drawing_state.transform);
+    return fill_internal(transformed_path, fill_rule);
 }
 
 RefPtr<ImageData> CanvasRenderingContext2D::create_image_data(int width, int height) const

+ 5 - 2
Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h

@@ -64,13 +64,13 @@ public:
 
     void begin_path();
     void stroke();
+    void stroke(Path2D const& path);
 
     void fill_text(String const&, float x, float y, Optional<double> max_width);
     void stroke_text(String const&, float x, float y, Optional<double> max_width);
 
-    // FIXME: We should only have one fill(), really. Fix the wrapper generator!
-    void fill(Gfx::Painter::WindingRule);
     void fill(String const& fill_rule);
+    void fill(Path2D& path, String const& fill_rule);
 
     RefPtr<ImageData> create_image_data(int width, int height) const;
     DOM::ExceptionOr<RefPtr<ImageData>> get_image_data(int x, int y, int width, int height) const;
@@ -118,6 +118,9 @@ private:
     HTMLCanvasElement& canvas_element();
     HTMLCanvasElement const& canvas_element() const;
 
+    void stroke_internal(Gfx::Path const&);
+    void fill_internal(Gfx::Path&, String const& fill_rule);
+
     // https://html.spec.whatwg.org/multipage/canvas.html#drawing-state
     struct DrawingState {
         Gfx::AffineTransform transform;

+ 5 - 0
Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl

@@ -4,6 +4,7 @@
 #import <HTML/TextMetrics.idl>
 #import <HTML/CanvasGradient.idl>
 #import <HTML/Canvas/CanvasPath.idl>
+#import <HTML/Path2D.idl>
 
 // https://html.spec.whatwg.org/multipage/canvas.html#canvasrenderingcontext2d
 [Exposed=Window]
@@ -18,8 +19,12 @@ interface CanvasRenderingContext2D {
     undefined rotate(double radians);
 
     undefined beginPath();
+    // FIXME: `DOMString` should be `CanvasFillRule`
     undefined fill(optional DOMString fillRule = "nonzero");
+    // FIXME: `DOMString` should be `CanvasFillRule`
+    undefined fill(Path2D path, optional DOMString fillRule = "nonzero");
     undefined stroke();
+    undefined stroke(Path2D path);
 
     undefined fillText(DOMString text, double x, double y, optional double maxWidth);
     undefined strokeText(DOMString text, double x, double y, optional double maxWidth);