From 3a85a98855d9f2b7181c12c648ed28a24bbc3769 Mon Sep 17 00:00:00 2001 From: Rik Cabanier Date: Wed, 16 Jan 2013 21:55:43 -0500 Subject: [PATCH] Bug 827053 - Add support for winding in fill + clip + isPointInPath + tests the feature. r=bas --- .../canvas/src/CanvasRenderingContext2D.cpp | 18 ++++--- content/canvas/src/CanvasRenderingContext2D.h | 9 ++-- content/canvas/test/Makefile.in | 3 ++ content/canvas/test/test_2d.clip.winding.html | 53 +++++++++++++++++++ content/canvas/test/test_2d.fill.winding.html | 51 ++++++++++++++++++ .../test/test_2d.isPointInPath.winding.html | 29 ++++++++++ dom/webidl/CanvasRenderingContext2D.webidl | 8 +-- 7 files changed, 157 insertions(+), 14 deletions(-) create mode 100644 content/canvas/test/test_2d.clip.winding.html create mode 100644 content/canvas/test/test_2d.fill.winding.html create mode 100644 content/canvas/test/test_2d.isPointInPath.winding.html diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index 2e593a682570..4fb760d1f1bc 100644 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -1636,9 +1636,9 @@ CanvasRenderingContext2D::BeginPath() } void -CanvasRenderingContext2D::Fill() +CanvasRenderingContext2D::Fill(const CanvasWindingRule& winding) { - EnsureUserSpacePath(); + EnsureUserSpacePath(winding); if (!mPath) { return; @@ -1687,9 +1687,9 @@ CanvasRenderingContext2D::Stroke() } void -CanvasRenderingContext2D::Clip() +CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding) { - EnsureUserSpacePath(); + EnsureUserSpacePath(winding); if (!mPath) { return; @@ -1848,9 +1848,11 @@ CanvasRenderingContext2D::EnsureWritablePath() } void -CanvasRenderingContext2D::EnsureUserSpacePath() +CanvasRenderingContext2D::EnsureUserSpacePath(const CanvasWindingRule& winding) { FillRule fillRule = CurrentState().fillRule; + if(winding == CanvasWindingRuleValues::Evenodd) + fillRule = FILL_EVEN_ODD; if (!mPath && !mPathBuilder && !mDSPathBuilder) { EnsureTarget(); @@ -2836,19 +2838,21 @@ CanvasRenderingContext2D::SetMozDashOffset(double mozDashOffset) } bool -CanvasRenderingContext2D::IsPointInPath(double x, double y) +CanvasRenderingContext2D::IsPointInPath(double x, double y, const CanvasWindingRule& winding) { if (!FloatValidate(x,y)) { return false; } - EnsureUserSpacePath(); + EnsureUserSpacePath(winding); if (!mPath) { return false; } + if (mPathTransformWillUpdate) { return mPath->ContainsPoint(Point(x, y), mPathToDS); } + return mPath->ContainsPoint(Point(x, y), mTarget->GetTransform()); } diff --git a/content/canvas/src/CanvasRenderingContext2D.h b/content/canvas/src/CanvasRenderingContext2D.h index cd4d1740590f..378ee5d0e910 100644 --- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -17,6 +17,7 @@ #include "mozilla/ErrorResult.h" #include "mozilla/dom/ImageData.h" #include "mozilla/dom/UnionTypes.h" +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" #define NS_CANVASGRADIENTAZURE_PRIVATE_IID \ {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}} @@ -238,10 +239,10 @@ public: void FillRect(double x, double y, double w, double h); void StrokeRect(double x, double y, double w, double h); void BeginPath(); - void Fill(); + void Fill(const CanvasWindingRule& winding); void Stroke(); - void Clip(); - bool IsPointInPath(double x, double y); + void Clip(const CanvasWindingRule& winding); + bool IsPointInPath(double x, double y, const CanvasWindingRule& winding); bool IsPointInStroke(double x, double y); void FillText(const nsAString& text, double x, double y, const mozilla::dom::Optional& maxWidth, @@ -587,7 +588,7 @@ protected: void EnsureWritablePath(); // Ensures a path in UserSpace is available. - void EnsureUserSpacePath(); + void EnsureUserSpacePath(const CanvasWindingRule& winding = CanvasWindingRuleValues::Nonzero); /** * Needs to be called before updating the transform. This makes a call to diff --git a/content/canvas/test/Makefile.in b/content/canvas/test/Makefile.in index 05c3faef8af5..77c79f44829f 100644 --- a/content/canvas/test/Makefile.in +++ b/content/canvas/test/Makefile.in @@ -36,6 +36,7 @@ MOCHITEST_FILES = \ test_drawImageIncomplete.html \ test_canvas_font_setter.html \ test_2d.clearRect.image.offscreen.html \ + test_2d.clip.winding.html \ test_2d.composite.canvas.destination-atop.html \ test_2d.composite.canvas.destination-in.html \ test_2d.composite.canvas.source-in.html \ @@ -93,6 +94,8 @@ MOCHITEST_FILES = \ test_2d.composite.uncovered.fill.color.html \ test_2d.composite.uncovered.fill.luminosity.html \ test_2d.drawImage.zerocanvas.html \ + test_2d.fill.winding.html \ + test_2d.isPointInPath.winding.html \ test_2d.strokeRect.zero.5.html \ test_toBlob.html \ test_toDataURL_alpha.html \ diff --git a/content/canvas/test/test_2d.clip.winding.html b/content/canvas/test/test_2d.clip.winding.html new file mode 100644 index 000000000000..1dca69d28077 --- /dev/null +++ b/content/canvas/test/test_2d.clip.winding.html @@ -0,0 +1,53 @@ + +Canvas test: 2d.clip.winding + + + + +

FAIL (fallback content)

+ + diff --git a/content/canvas/test/test_2d.fill.winding.html b/content/canvas/test/test_2d.fill.winding.html new file mode 100644 index 000000000000..d8fa6f548c7d --- /dev/null +++ b/content/canvas/test/test_2d.fill.winding.html @@ -0,0 +1,51 @@ + +Canvas test: 2d.fill.winding + + + + +

FAIL (fallback content)

+ + diff --git a/content/canvas/test/test_2d.isPointInPath.winding.html b/content/canvas/test/test_2d.isPointInPath.winding.html new file mode 100644 index 000000000000..9cd549c858ff --- /dev/null +++ b/content/canvas/test/test_2d.isPointInPath.winding.html @@ -0,0 +1,29 @@ + +Canvas test: 2d.isPointInPath.winding + + + + +

FAIL (fallback content)

+ + diff --git a/dom/webidl/CanvasRenderingContext2D.webidl b/dom/webidl/CanvasRenderingContext2D.webidl index 8471cf8212ed..046952ceb545 100644 --- a/dom/webidl/CanvasRenderingContext2D.webidl +++ b/dom/webidl/CanvasRenderingContext2D.webidl @@ -20,6 +20,8 @@ interface TextMetrics; interface Window; interface XULElement; +enum CanvasWindingRule { "nonzero", "evenodd" }; + interface CanvasRenderingContext2D { // back-reference to the canvas. Might be null if we're not @@ -80,7 +82,7 @@ interface CanvasRenderingContext2D { // path API (see also CanvasPathMethods) void beginPath(); - void fill(); + void fill(optional CanvasWindingRule winding = "nonzero"); // NOT IMPLEMENTED void fill(Path path); void stroke(); // NOT IMPLEMENTED void stroke(Path path); @@ -90,10 +92,10 @@ interface CanvasRenderingContext2D { // NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element); // NOT IMPLEMENTED void scrollPathIntoView(); // NOT IMPLEMENTED void scrollPathIntoView(Path path); - void clip(); + void clip(optional CanvasWindingRule winding = "nonzero"); // NOT IMPLEMENTED void clip(Path path); // NOT IMPLEMENTED void resetClip(); - boolean isPointInPath(unrestricted double x, unrestricted double y); + boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero"); // NOT IMPLEMENTED boolean isPointInPath(Path path, unrestricted double x, unrestricted double y); boolean isPointInStroke(double x, double y);