Implement Path primitives

RESOLVED FIXED in mozilla31

Status

()

Core
Canvas: 2D
--
enhancement
RESOLVED FIXED
4 years ago
2 years ago

People

(Reporter: tobytailor, Assigned: Rik Cabanier)

Tracking

(Blocks: 4 bugs, {dev-doc-complete})

unspecified
mozilla31
dev-doc-complete
Points:
---
Dependency tree / graph
Bug Flags:
in-testsuite +

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [Shumway:p1])

Attachments

(2 attachments, 20 obsolete attachments)

6.35 KB, patch
roc
: review+
Details | Diff | Splinter Review
16.79 KB, patch
roc
: review+
Details | Diff | Splinter Review
(Reporter)

Description

4 years ago
Canvas v5 introduces a bunch of useful API additions. We are working on Shumway, a SWF runtime written in JavaScript, that uses Canvas for rendering. One of the new features we (and other apps like Pdf.js and Games in general) would profit a lot from is support for Path primitives (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path-objects). At the moment we use a shim for exactly that API and implementing it native definitely makes sense for us.
(Reporter)

Comment 1

4 years ago
Created attachment 702330 [details] [diff] [review]
Initial implementation of Path primitives.
(Assignee)

Comment 2

4 years ago
Do you have any comments on: http://lists.w3.org/Archives/Public/public-canvas-api/2013JanMar/0002.html
Basically, your implementation would be the pathSink (naming is TBD)

Comment 3

4 years ago
Can we not share more code with our SVG SVGPathData::ConstructPath implementation rather than writing yet another path constructor?
(Reporter)

Comment 4

4 years ago
Created attachment 705958 [details] [diff] [review]
Initial implementation of Path primitives. v2
Attachment #702330 - Attachment is obsolete: true
(Assignee)

Comment 5

4 years ago
We are also working on adding the path object to WebKit: https://bugs.webkit.org/show_bug.cgi?id=97333
This will live behind an experimental flag for now. Please note that it will be different from the current WhatWG proposal. It would be good if we can coordinate this.
(In reply to Rik Cabanier from comment #5)
> We are also working on adding the path object to WebKit:
> https://bugs.webkit.org/show_bug.cgi?id=97333
> This will live behind an experimental flag for now. Please note that it will
> be different from the current WhatWG proposal. It would be good if we can
> coordinate this.

Did you send use cases to the list? If not, I suggest we implement the spec and you fix your implementation.
(Assignee)

Comment 7

4 years ago
I did. There was no substantial feedback so we're trying to fix it in the implementation. Ian indicated in the bug that he would update the spec.

The current path syntax is broken. Simply aggregating path segments is the wrong way to do path logic and will give bad results.
(Reporter)

Comment 8

4 years ago
We already use a shim for the Path API in Shumway (Flash VM in JavaScript) and we haven't encountered any major problems with the current spec so far. Not exactly sure what your concerns are.
(Assignee)

Comment 9

4 years ago
That's because flash's edge lists already separate the paths into non-intersecting regions. In addition, Flash Authoring (which is the biggest producer of SWFs) will remove shared lines which also fixes even-odd weirdness for you.
This is not something that an author could do.

I would be very surprised if you can use this to implement stroking reliably.
(Reporter)

Comment 10

4 years ago
Any real world examples that proof your point?
(Reporter)

Comment 11

4 years ago
s/proof/prove/
(Assignee)

Comment 12

4 years ago
(In reply to Tobias Schneider from comment #10)
> Any real world examples that proof your point?

I have a blog post that shows the problem. I'm waiting for my team to sign off on it.
(Reporter)

Comment 13

4 years ago
> I have a blog post that shows the problem. I'm waiting for my team to sign
> off on it.

Cool.

For now I've implemented just as much of the API as WebKit does (plus the ability to parse an optional given SVG path data string). That's what you named PathSink. I'm not going to implement any of the Path interface methods (addPath, addPathByStrokingPath...) in this step. So no conflicts to API's that might change.
(Reporter)

Updated

4 years ago
Attachment #705958 - Flags: review?(jmuizelaar)
Comment on attachment 705958 [details] [diff] [review]
Initial implementation of Path primitives. v2

Review of attachment 705958 [details] [diff] [review]:
-----------------------------------------------------------------

This should be building an Azure Path object directly instead of building a temporary Canvas path object and building a Path from that during Stroke/Fill etc.
Attachment #705958 - Flags: review?(jmuizelaar) → review-
Keywords: dev-doc-needed
Whiteboard: [Shumway:p1]
Blocks: 885526
Blocks: 802882
(Reporter)

Updated

4 years ago
Blocks: 927828
(Reporter)

Updated

4 years ago
No longer blocks: 927828
(Reporter)

Updated

4 years ago
Blocks: 927828
(Assignee)

Comment 15

4 years ago
Let's make this happen!
(Assignee)

Comment 16

4 years ago
(In reply to Jeff Muizelaar [:jrmuizel] on PTO till October 21 from comment #14)
> Comment on attachment 705958 [details] [diff] [review]
> Initial implementation of Path primitives. v2
> 
> Review of attachment 705958 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> This should be building an Azure Path object directly instead of building a
> temporary Canvas path object and building a Path from that during
> Stroke/Fill etc.

I think this was done because the Path object doesn't know what type of backend the canvas object will have.
I've revived this patch and will try to land it.

Should I update it to create an azure path?
(Assignee)

Updated

4 years ago
Depends on: 929723
(Assignee)

Updated

4 years ago
Assignee: nobody → cabanier
(Assignee)

Comment 17

4 years ago
Created attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment
Attachment #705958 - Attachment is obsolete: true
(Assignee)

Updated

4 years ago
Attachment #822115 - Attachment description: canvaspath.patch → Refreshed patch that incorporates jeff's comment
(Assignee)

Comment 18

4 years ago
Comment on attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment

Try build: https://tbpl.mozilla.org/?tree=Try&rev=0879372fd3ec

Need to patch the test that finds the new global class. maybe add more tests?
Attachment #822115 - Flags: feedback?(roc)
(Assignee)

Updated

4 years ago
Blocks: 931587
(Assignee)

Updated

4 years ago
Attachment #822115 - Flags: feedback?(roc) → review?(roc)
Comment on attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment

Review of attachment 822115 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +1838,5 @@
>  
> +already_AddRefed<CanvasPath>
> +CanvasRenderingContext2D::CurrentPath()
> +{
> +  RefPtr<PathBuilder> CopyPathBuilder;

copyPathBuilder

@@ +1851,5 @@
> +    mDSPathBuilder = mTempPath->CopyToBuilder(CurrentState().fillRule);
> +  }
> +
> +  nsRefPtr<CanvasPath> NewPathObject(new CanvasPath(this, CopyPathBuilder));
> +  return NewPathObject.forget();

newPathObject

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +24,5 @@
>  #include "gfx2DGlue.h"
>  #include "imgIEncoder.h"
>  
> +#define NS_CANVASPATHAZURE_PRIVATE_IID \
> +    {0xaf712aac, 0xfd0b, 0x4cea, {0x9f, 0xa4, 0x83, 0x02, 0x87, 0x4f, 0x7a, 0x18}}

We shouldn't need this.

@@ +45,5 @@
>  
>  template<typename T> class Optional;
>  
> +class CanvasPath :
> +  public nsIDOMPath,

We shouldn't need to inherit from nsIDOMPath here. We shouldn't need nsIDOMPath at all.

@@ +52,5 @@
> +public:
> +  NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATHAZURE_PRIVATE_IID)
> +
> +  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
> +  NS_DECL_CYCLE_COLLECTION_CLASS(CanvasPath)

You don't need to implement nsISupports. Follow CanvasPattern and use   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPattern).

@@ +76,5 @@
> +             mozilla::ErrorResult& error);
> +  void Rect(double x, double y, double w, double h);
> +  void Arc(double x, double y, double radius,
> +           double startAngle, double endAngle, bool anticlockwise,
> +           mozilla::ErrorResult& error);

You should already be in the mozilla namespace so don't use the mozilla prefix here.

@@ +83,5 @@
> +  void BezierTo(const mozilla::gfx::Point& aCP1,
> +                const mozilla::gfx::Point& aCP2,
> +                const mozilla::gfx::Point& aCP3);
> +
> +  CanvasPath(nsISupports* aParent, mozilla::RefPtr<mozilla::gfx::PathBuilder> mPathBuilder);

Use typedefs in the class to avoid using prefixes here. E.g.
  typedef mozilla::gfx::PathBuilder PathBuilder;
  typedef mozilla::gfx::Float Float;
You don't need the mozilla prefix in any case.

@@ +376,5 @@
>    void Rect(double x, double y, double w, double h);
>    void Arc(double x, double y, double radius, double startAngle,
>             double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
>  
> +  already_AddRefed<CanvasPath > CurrentPath();

Remove space before >

::: dom/base/nsDOMClassInfo.cpp
@@ +87,5 @@
>  // Event related includes
>  #include "nsIDOMEventTarget.h"
>  
> +// Canvas
> +#include "nsIDOMCanvasRenderingContext2D.h"

No changes to nsDOMClassInfo should be needed. nsDOMClassInfo is obsolete.

::: dom/base/nsDOMClassInfoClasses.h
@@ +25,5 @@
>  
>  // Range classes
>  DOMCI_CLASS(Selection)
>  
> +DOMCI_CLASS(CanvasPath)

This shouldn't be needed. nsDOMClassInfoClasses is obsolete.

::: dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
@@ +32,5 @@
>    const unsigned long DRAWWINDOW_ASYNC_DECODE_IMAGES = 0x10;
>  };
> +
> +[scriptable, uuid(1146b8a4-45b4-4c96-8817-d55647f31e15)]
> +interface nsIDOMPath : nsISupports

I don't think we want to add this. nsIDOMCanvasRenderingContext2D.idl is obsolete.

::: dom/webidl/CanvasRenderingContext2D.webidl
@@ +123,5 @@
>    [Throws]
>    void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
>  
> +  // current path 
> +  attribute Path currentPath;

Is this specced somewhere? Because I don't see it in http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html.

::: js/xpconnect/src/dom_quickstubs.qsconf
@@ +52,5 @@
>      # dom/interfaces/core
>      'nsIDOMDOMStringList.*',
>  
> +    #
> +    'nsIDOMPath.*',

You shouldn't be adding anything to dom_quickstubs.qsconf. This is all obseleted by .webidl.
(Assignee)

Comment 20

4 years ago
Thanks for the review.
Most of that code came from the old patch. I will update per your comments.
(Assignee)

Comment 21

4 years ago
Created attachment 824467 [details] [diff] [review]
New patch for path objects
Attachment #822115 - Attachment is obsolete: true
Attachment #822115 - Flags: review?(roc)
(Assignee)

Comment 22

4 years ago
Comment on attachment 822115 [details] [diff] [review]
Refreshed patch that incorporates jeff's comment

Review of attachment 822115 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +1838,5 @@
>  
> +already_AddRefed<CanvasPath>
> +CanvasRenderingContext2D::CurrentPath()
> +{
> +  RefPtr<PathBuilder> CopyPathBuilder;

Fixed.

@@ +1851,5 @@
> +    mDSPathBuilder = mTempPath->CopyToBuilder(CurrentState().fillRule);
> +  }
> +
> +  nsRefPtr<CanvasPath> NewPathObject(new CanvasPath(this, CopyPathBuilder));
> +  return NewPathObject.forget();

Fixed

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +24,5 @@
>  #include "gfx2DGlue.h"
>  #include "imgIEncoder.h"
>  
> +#define NS_CANVASPATHAZURE_PRIVATE_IID \
> +    {0xaf712aac, 0xfd0b, 0x4cea, {0x9f, 0xa4, 0x83, 0x02, 0x87, 0x4f, 0x7a, 0x18}}

You were right.
Removed this + all other obsolete code

@@ +76,5 @@
> +             mozilla::ErrorResult& error);
> +  void Rect(double x, double y, double w, double h);
> +  void Arc(double x, double y, double radius,
> +           double startAngle, double endAngle, bool anticlockwise,
> +           mozilla::ErrorResult& error);

removed the prefix everywhere in the file.

@@ +376,5 @@
>    void Rect(double x, double y, double w, double h);
>    void Arc(double x, double y, double radius, double startAngle,
>             double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
>  
> +  already_AddRefed<CanvasPath > CurrentPath();

done
(Assignee)

Updated

4 years ago
Attachment #824467 - Flags: review?(roc)
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

Review of attachment 824467 [details] [diff] [review]:
-----------------------------------------------------------------

I still don't see a spec for currentPath anywhere!

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +42,5 @@
>  
>  template<typename T> class Optional;
>  
> +class BaseCanvasPath
> +{

I don't understand why you've separated things into this base class. Can't we just merge this into CanvasPath?

::: dom/bindings/Bindings.conf
@@ +1876,5 @@
>  addExternalIface('CameraReleaseCallback', nativeType='nsICameraReleaseCallback', headerFile='nsIDOMCameraManager.h')
>  addExternalIface('CameraStartRecordingCallback', nativeType='nsICameraStartRecordingCallback', headerFile='nsIDOMCameraManager.h')
>  addExternalIface('CameraPreviewStateChange', nativeType='nsICameraPreviewStateChange', headerFile='nsIDOMCameraManager.h')
>  addExternalIface('CameraPreviewStreamCallback', nativeType='nsICameraPreviewStreamCallback', headerFile='nsIDOMCameraManager.h')
> +addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')

There should be no change here.

::: dom/tests/mochitest/general/test_interfaces.html
@@ +104,5 @@
>      "CameraCapabilities",
>      "CameraControl",
>      "CameraManager",
>      "CanvasGradient",
> +    "CanvasPath",

This should not be here.
(Assignee)

Comment 24

4 years ago
(In reply to Robert O'Callahan (:roc) (Mozilla Corporation) from comment #23)
> Comment on attachment 824467 [details] [diff] [review]
> New patch for path objects
> 
> Review of attachment 824467 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> I still don't see a spec for currentPath anywhere!

True. Blink and WebKit implemented it but it's not in the spec yet.
I'll follow up.

> 
> ::: content/canvas/src/CanvasRenderingContext2D.h
> @@ +42,5 @@
> >  
> >  template<typename T> class Optional;
> >  
> > +class BaseCanvasPath
> > +{
> 
> I don't understand why you've separated things into this base class. Can't
> we just merge this into CanvasPath?

I did that because the cleanup patch uses the same base functionality but not the JS exposed logic.
If that one doesn't go anywhere, I can put it back together.

> 
> ::: dom/bindings/Bindings.conf
> @@ +1876,5 @@
> >  addExternalIface('CameraReleaseCallback', nativeType='nsICameraReleaseCallback', headerFile='nsIDOMCameraManager.h')
> >  addExternalIface('CameraStartRecordingCallback', nativeType='nsICameraStartRecordingCallback', headerFile='nsIDOMCameraManager.h')
> >  addExternalIface('CameraPreviewStateChange', nativeType='nsICameraPreviewStateChange', headerFile='nsIDOMCameraManager.h')
> >  addExternalIface('CameraPreviewStreamCallback', nativeType='nsICameraPreviewStreamCallback', headerFile='nsIDOMCameraManager.h')
> > +addExternalIface('CameraRecorderStateChange', nativeType='nsICameraRecorderStateChange', headerFile='nsIDOMCameraManager.h')
> 
> There should be no change here.
> 
> ::: dom/tests/mochitest/general/test_interfaces.html
> @@ +104,5 @@
> >      "CameraCapabilities",
> >      "CameraControl",
> >      "CameraManager",
> >      "CanvasGradient",
> > +    "CanvasPath",
> 
> This should not be here.
Will do
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

Review of attachment 824467 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4034,5 @@
> +  return PathBinding::Wrap(cx, scope, this);
> +}
> +
> +already_AddRefed<CanvasPath>
> +CanvasPath::Constructor(const GlobalObject& aGlobal, ErrorResult& rv)

aRv, also elsewhere

@@ +4084,5 @@
> +}
> +
> +void
> +BaseCanvasPath::BezierCurveTo(double cp1x, double cp1y,
> +                          double cp2x, double cp2y,

Indentation

@@ +4088,5 @@
> +                          double cp2x, double cp2y,
> +                          double x, double y)
> +{
> +  BezierTo(mozilla::gfx::Point(ToFloat(cp1x), ToFloat(cp1y)),
> +             mozilla::gfx::Point(ToFloat(cp2x), ToFloat(cp2y)),

Indentation

@@ +4202,5 @@
> +
> +  return mTempPath->CopyToBuilder();
> +}
> +
> +}

} // namespace foo

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +73,5 @@
> +
> +  RefPtr<gfx::PathBuilder> mPathBuilder;
> +};
> +
> +class CanvasPath :

Why is this not called mozilla::dom::Path?

@@ +83,5 @@
> +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
> +
> +  nsISupports* GetParentObject() { return mParent; }
> +
> +  JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> scope);

* goes to the left, argument names start with a

@@ +91,5 @@
> +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
> +                                                  CanvasPath& aCanvasPath,
> +                                                  ErrorResult& rv);
> +
> +  CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);

Passing refptrs as arguments isn't done.

@@ +97,5 @@
> +  CanvasPath(nsISupports* aParent);
> +
> +  virtual ~CanvasPath() {}
> +
> +  nsISupports* mParent;

What keeps this alive?

@@ +629,5 @@
>    /**
>      * Returns the surface format this canvas should be allocated using. Takes
>      * into account mOpaque, platform requirements, etc.
>      */
> +  gfx::SurfaceFormat GetSurfaceFormat() const;

Put all those changes in a separate patch, please.

::: content/canvas/test/test_canvas.html
@@ +24990,5 @@
>    throw e;
>    ok(false, "unexpected exception thrown in: test_linedash");
>   }
>   try {
> +  test_path

You're not running the test. As I asked you before, though, please put this in a separate file.

::: dom/bindings/Bindings.conf
@@ +877,5 @@
>  },
>  
> +'Path': {
> +    'nativeType': 'mozilla::dom::CanvasPath',
> +    'headerFile': 'nsIDOMCanvasRenderingContext2D.h'

That's not true.
(Assignee)

Comment 26

4 years ago
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

Review of attachment 824467 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +73,5 @@
> +
> +  RefPtr<gfx::PathBuilder> mPathBuilder;
> +};
> +
> +class CanvasPath :

To avoid clashes with Path

@@ +83,5 @@
> +  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(CanvasPath)
> +
> +  nsISupports* GetParentObject() { return mParent; }
> +
> +  JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> scope);

fixed

@@ +91,5 @@
> +  static already_AddRefed<CanvasPath> Constructor(const GlobalObject& aGlobal,
> +                                                  CanvasPath& aCanvasPath,
> +                                                  ErrorResult& rv);
> +
> +  CanvasPath(nsISupports* aParent, RefPtr<gfx::PathBuilder> mPathBuilder);

fixed

@@ +97,5 @@
> +  CanvasPath(nsISupports* aParent);
> +
> +  virtual ~CanvasPath() {}
> +
> +  nsISupports* mParent;

fixed by wrapping

@@ +629,5 @@
>    /**
>      * Returns the surface format this canvas should be allocated using. Takes
>      * into account mOpaque, platform requirements, etc.
>      */
> +  gfx::SurfaceFormat GetSurfaceFormat() const;

made these changes because roc said to do so. I can remove if needed.
(Assignee)

Comment 27

4 years ago
Comment on attachment 824467 [details] [diff] [review]
New patch for path objects

Review of attachment 824467 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +42,5 @@
>  
>  template<typename T> class Optional;
>  
> +class BaseCanvasPath
> +{

I collapsed them again
(In reply to Rik Cabanier from comment #26)
> @@ +629,5 @@
> >    /**
> >      * Returns the surface format this canvas should be allocated using. Takes
> >      * into account mOpaque, platform requirements, etc.
> >      */
> > +  gfx::SurfaceFormat GetSurfaceFormat() const;
> 
> made these changes because roc said to do so. I can remove if needed.

Don't revert them, but create two patches: one that just removes the prefixes, and another on top of that that contains the functional changes.
(Assignee)

Comment 29

4 years ago
Created attachment 826170 [details] [diff] [review]
New patch for path objects
Attachment #824467 - Attachment is obsolete: true
Attachment #824467 - Flags: review?(roc)
(Assignee)

Updated

4 years ago
Attachment #826170 - Flags: review?(roc)
(Assignee)

Comment 30

4 years ago
(In reply to :Ms2ger from comment #28)
> (In reply to Rik Cabanier from comment #26)
> > @@ +629,5 @@
> > >    /**
> > >      * Returns the surface format this canvas should be allocated using. Takes
> > >      * into account mOpaque, platform requirements, etc.
> > >      */
> > > +  gfx::SurfaceFormat GetSurfaceFormat() const;
> > 
> > made these changes because roc said to do so. I can remove if needed.
> 
> Don't revert them, but create two patches: one that just removes the
> prefixes, and another on top of that that contains the functional changes.

OK. Latest patch doesn't have the changes. Will add another patch with them when I get r+ on this one.
Comment on attachment 826170 [details] [diff] [review]
New patch for path objects

Review of attachment 826170 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/test/test_canvas.html
@@ +24909,5 @@
>    ok(false, "unexpected exception thrown in: test_linedash");
>   }
>   try {
> +  test_path();
> +  } catch(e) {

Fix indent.

::: dom/webidl/CanvasRenderingContext2D.webidl
@@ +122,5 @@
>    [Throws]
>    void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
>  
> +  // current path
> +  attribute Path currentPath;

I thought you were going to take this out?
Attachment #826170 - Flags: review?(roc) → review-
(Assignee)

Comment 32

4 years ago
Comment on attachment 826170 [details] [diff] [review]
New patch for path objects

Review of attachment 826170 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/test/test_canvas.html
@@ +24909,5 @@
>    ok(false, "unexpected exception thrown in: test_linedash");
>   }
>   try {
> +  test_path();
> +  } catch(e) {

will do.

::: dom/webidl/CanvasRenderingContext2D.webidl
@@ +122,5 @@
>    [Throws]
>    void putImageData(ImageData imagedata, double dx, double dy, double dirtyX, double dirtyY, double dirtyWidth, double dirtyHeight);
>  
> +  // current path
> +  attribute Path currentPath;

The tests won't work without it. Basically, the path object is useless without a connection to canvas.

I will see if the mailing list converges this week.
If not, I will take it out and just test if the path APIs work.
It it does, I will put the new API behind a runtime flag.
FWIW, for other work I'm implementing code that allows streaming the contents of a Path object to an arbitrary PathSink.
(Assignee)

Comment 34

4 years ago
(In reply to Bas Schouten (:bas.schouten) from comment #33)
> FWIW, for other work I'm implementing code that allows streaming the
> contents of a Path object to an arbitrary PathSink.

Like this: https://bugzilla.mozilla.org/show_bug.cgi?id=929723
Comment on attachment 826170 [details] [diff] [review]
New patch for path objects

Review of attachment 826170 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4020,5 @@
> +{
> +  SetIsDOMBinding();
> +
> +  BackendType aBackend = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
> +  RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);

I believe we don't have need for creating a draw target to create a path builder anymore. That should be fixed as we don't want to create a DrawTarget for every path.

Also, does the code handle the cases where DrawTarget backends don't match?(i.e. Direct2D vs software when the canvas is too large) I didn't see any tests for that.
Attachment #826170 - Flags: review-
(Assignee)

Comment 36

4 years ago
(In reply to Jeff Muizelaar [:jrmuizel] from comment #35)
> Comment on attachment 826170 [details] [diff] [review]
> New patch for path objects
> 
> Review of attachment 826170 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: content/canvas/src/CanvasRenderingContext2D.cpp
> @@ +4020,5 @@
> > +{
> > +  SetIsDOMBinding();
> > +
> > +  BackendType aBackend = gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
> > +  RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> 
> I believe we don't have need for creating a draw target to create a path
> builder anymore. That should be fixed as we don't want to create a
> DrawTarget for every path.

Can you point me to the API that allows this?

> 
> Also, does the code handle the cases where DrawTarget backends don't
> match?(i.e. Direct2D vs software when the canvas is too large) I didn't see
> any tests for that.

Did Bas land that code? If so, can you point me to it?
Flags: needinfo?(jmuizelaar)
(Assignee)

Comment 37

4 years ago
I'm in the process of:
- renaming path to path2d
- changing currentPath to set/getCurrentPath

Looking at the architecture of mozilla's canvas implementation, I think it would really benefit from having the Shape class (http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/) since it allows caching of the mPathBuilder object.
What should I do to implement this? It could be behind a runtime flag for now.
(In reply to Rik Cabanier from comment #36)
> (In reply to Jeff Muizelaar [:jrmuizel] from comment #35)
> > 
> > I believe we don't have need for creating a draw target to create a path
> > builder anymore. That should be fixed as we don't want to create a
> > DrawTarget for every path.
> 
> Can you point me to the API that allows this?

There's no current API for this. It would need to be created but should be relatively easy now.

> > 
> > Also, does the code handle the cases where DrawTarget backends don't
> > match?(i.e. Direct2D vs software when the canvas is too large) I didn't see
> > any tests for that.
> 
> Did Bas land that code? If so, can you point me to it?

http://dxr.mozilla.org/mozilla-central/source/gfx/thebes/gfxPlatform.cpp?from=CreateOffscreenCanvasDrawTarget#1004
Flags: needinfo?(jmuizelaar)
(Assignee)

Comment 39

3 years ago
(In reply to Jeff Muizelaar [:jrmuizel] from comment #38)
> (In reply to Rik Cabanier from comment #36)
> > (In reply to Jeff Muizelaar [:jrmuizel] from comment #35)
> > > 
> > > I believe we don't have need for creating a draw target to create a path
> > > builder anymore. That should be fixed as we don't want to create a
> > > DrawTarget for every path.
> > 
> > Can you point me to the API that allows this?
> 
> There's no current API for this. It would need to be created but should be
> relatively easy now.

Could you tell me how I could create such an API?
 
> > > 
> > > Also, does the code handle the cases where DrawTarget backends don't
> > > match?(i.e. Direct2D vs software when the canvas is too large) I didn't see
> > > any tests for that.
> > 
> > Did Bas land that code? If so, can you point me to it?
> 
> http://dxr.mozilla.org/mozilla-central/source/gfx/thebes/gfxPlatform.
> cpp?from=CreateOffscreenCanvasDrawTarget#1004

I saw other code for streaming to any pathsink. (StreamToSink)
Were you pointing to the code that creates a reusable backend?
(Assignee)

Updated

3 years ago
Flags: needinfo?(jmuizelaar)
(Assignee)

Comment 40

3 years ago
Created attachment 8368633 [details] [diff] [review]
1. update IDL +  implementation of path primitives
Attachment #826170 - Attachment is obsolete: true
(Assignee)

Updated

3 years ago
Attachment #8368633 - Attachment description: canvaspath.patch → 1. update IDL + implementation of path primitives
(Assignee)

Comment 41

3 years ago
Created attachment 8383190 [details] [diff] [review]
2. Recreate path object if backends don't match
(Assignee)

Comment 42

3 years ago
Created attachment 8383387 [details] [diff] [review]
2. Recreate path object if backends don't match + add runtime flag + remove creation of drawtarget from path constructor
Attachment #8383190 - Attachment is obsolete: true
(Assignee)

Comment 43

3 years ago
Created attachment 8383416 [details] [diff] [review]
3. Add tests for path objects
(Assignee)

Updated

3 years ago
Attachment #8368633 - Flags: review?(jmuizelaar)
(Assignee)

Updated

3 years ago
Attachment #8383387 - Flags: review?(jmuizelaar)
(Assignee)

Updated

3 years ago
Flags: needinfo?(jmuizelaar)
(Assignee)

Comment 44

3 years ago
Created attachment 8383462 [details] [diff] [review]
1. update IDL + implementation of path primitives
Attachment #8368633 - Attachment is obsolete: true
Attachment #8368633 - Flags: review?(jmuizelaar)
Attachment #8383462 - Flags: review?(jmuizelaar)
(Assignee)

Comment 45

3 years ago
Created attachment 8383499 [details] [diff] [review]
1. update IDL + implementation of path primitives
Attachment #8383462 - Attachment is obsolete: true
Attachment #8383462 - Flags: review?(jmuizelaar)
Attachment #8383499 - Flags: review?(jmuizelaar)
(Assignee)

Comment 46

3 years ago
Created attachment 8383500 [details] [diff] [review]
1. update IDL + implementation of path primitives
Attachment #8383499 - Attachment is obsolete: true
Attachment #8383499 - Flags: review?(jmuizelaar)
Attachment #8383500 - Flags: review?(jmuizelaar)
(Assignee)

Comment 47

3 years ago
Created attachment 8383501 [details] [diff] [review]
1. update IDL + implementation of path primitives

Sorry about the noise. Was updating the wrong patch.

try run: https://tbpl.mozilla.org/?tree=Try&rev=18fb9ed6533f
Attachment #8383500 - Attachment is obsolete: true
Attachment #8383500 - Flags: review?(jmuizelaar)
Attachment #8383501 - Flags: review?(jmuizelaar)
(Assignee)

Comment 48

3 years ago
Created attachment 8383514 [details] [diff] [review]
1. update IDL + implementation of path primitives

fixed issue with test file
Attachment #8383501 - Attachment is obsolete: true
Attachment #8383501 - Flags: review?(jmuizelaar)
Attachment #8383514 - Flags: review?(jmuizelaar)
(Assignee)

Comment 49

3 years ago
Created attachment 8383982 [details] [diff] [review]
1. update IDL + implementation of path primitives
Attachment #8383514 - Attachment is obsolete: true
Attachment #8383514 - Flags: review?(jmuizelaar)
Attachment #8383982 - Flags: review?(jmuizelaar)
(Assignee)

Updated

3 years ago
Attachment #8383982 - Flags: review?(jmuizelaar)
(Assignee)

Comment 50

3 years ago
Created attachment 8384034 [details] [diff] [review]
1. update IDL + implementation of path primitives
Attachment #8383982 - Attachment is obsolete: true
Attachment #8384034 - Flags: review?(jmuizelaar)
Comment on attachment 8384034 [details] [diff] [review]
1. update IDL + implementation of path primitives

Review of attachment 8384034 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4298,5 @@
> +  SetIsDOMBinding();
> +
> +  RefPtr<DrawTarget> aDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(IntSize(8, 8), gfx::SurfaceFormat::B8G8R8X8);
> +  //RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> +  mPathBuilder = aDrawTarget->CreatePathBuilder();

There's currently no reason that we need mTarget for CreatePathBuilder anymore. Afaict it can just live off of the Factory. Can you fix this first before this patch? It should make creating this draw target unnecessary.

@@ +4363,5 @@
> +}
> +
> +void
> +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> +                  ErrorResult& error)

This seems to duplicate CanvasRenderingContext2D::ArcTo. Is that necessary?
Attachment #8384034 - Flags: review?(jmuizelaar) → review-
(Assignee)

Comment 52

3 years ago
(In reply to Jeff Muizelaar [:jrmuizel] from comment #51)
> Comment on attachment 8384034 [details] [diff] [review]
> 1. update IDL + implementation of path primitives
> 
> Review of attachment 8384034 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: content/canvas/src/CanvasRenderingContext2D.cpp
> @@ +4298,5 @@
> > +  SetIsDOMBinding();
> > +
> > +  RefPtr<DrawTarget> aDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(IntSize(8, 8), gfx::SurfaceFormat::B8G8R8X8);
> > +  //RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> > +  mPathBuilder = aDrawTarget->CreatePathBuilder();
> 
> There's currently no reason that we need mTarget for CreatePathBuilder
> anymore. Afaict it can just live off of the Factory. Can you fix this first
> before this patch? It should make creating this draw target unnecessary.

sorry, I addressed that in the second patch: 
   RefPtr<DrawTarget> aDrawTarget = gfxPlatform::ScreenReferenceDrawTarget()->CreatePathBuilder();

> @@ +4363,5 @@
> > +}
> > +
> > +void
> > +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> > +                  ErrorResult& error)
> 
> This seems to duplicate CanvasRenderingContext2D::ArcTo. Is that necessary?

I didn't see an easy way to simplify this.
I have a proposed patch to simplify the path handling for canvas which will address that problem. See https://bugzilla.mozilla.org/show_bug.cgi?id=931587
(Assignee)

Updated

3 years ago
Flags: needinfo?(jmuizelaar)
(In reply to Rik Cabanier from comment #52)
> (In reply to Jeff Muizelaar [:jrmuizel] from comment #51)
> > Comment on attachment 8384034 [details] [diff] [review]
> > 1. update IDL + implementation of path primitives
> > 
> > Review of attachment 8384034 [details] [diff] [review]:
> > -----------------------------------------------------------------
> > 
> > ::: content/canvas/src/CanvasRenderingContext2D.cpp
> > @@ +4298,5 @@
> > > +  SetIsDOMBinding();
> > > +
> > > +  RefPtr<DrawTarget> aDrawTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(IntSize(8, 8), gfx::SurfaceFormat::B8G8R8X8);
> > > +  //RefPtr<DrawTarget> aDrawTarget = Factory::CreateDrawTarget(aBackend, IntSize(8, 8), FORMAT_B8G8R8X8);
> > > +  mPathBuilder = aDrawTarget->CreatePathBuilder();
> > 
> > There's currently no reason that we need mTarget for CreatePathBuilder
> > anymore. Afaict it can just live off of the Factory. Can you fix this first
> > before this patch? It should make creating this draw target unnecessary.
> 
> sorry, I addressed that in the second patch: 
>    RefPtr<DrawTarget> aDrawTarget =
> gfxPlatform::ScreenReferenceDrawTarget()->CreatePathBuilder();

This is still using a DrawTarget to create the path builder. There should be no reason for that.
Flags: needinfo?(jmuizelaar)
(Assignee)

Updated

3 years ago
Depends on: 978980
(Assignee)

Comment 54

3 years ago
Created attachment 8389441 [details] [diff] [review]
1. update IDL + implementation of path primitives (
Attachment #8384034 - Attachment is obsolete: true
(Assignee)

Comment 55

3 years ago
Created attachment 8389444 [details] [diff] [review]
2. Recreate path object if backends don't match + add runtime flag + remove creation of drawtarget from path constructor
Attachment #8383387 - Attachment is obsolete: true
Attachment #8383387 - Flags: review?(jmuizelaar)
(Assignee)

Comment 56

3 years ago
Created attachment 8389445 [details] [diff] [review]
2. Add tests for path objects
Attachment #8383416 - Attachment is obsolete: true
(Assignee)

Comment 57

3 years ago
Created attachment 8389450 [details] [diff] [review]
2. Recreate path object if backends don't match + add runtime flag + remove creation of drawtarget from path constructor
Attachment #8389444 - Attachment is obsolete: true
(Assignee)

Updated

3 years ago
Attachment #8389441 - Flags: review?(bas)
(Assignee)

Updated

3 years ago
Attachment #8389445 - Flags: review?(bas)
(Assignee)

Updated

3 years ago
Attachment #8389450 - Flags: review?(bas)
(Assignee)

Comment 58

3 years ago
try run: https://tbpl.mozilla.org/?tree=Try&rev=378a61b62519
(Assignee)

Updated

3 years ago
Attachment #8389441 - Flags: review?(bas) → review?(roc)
(Assignee)

Updated

3 years ago
Attachment #8389445 - Flags: review?(bas) → review?(roc)
(Assignee)

Updated

3 years ago
Attachment #8389450 - Flags: review?(bas) → review?(roc)
Comment on attachment 8389441 [details] [diff] [review]
1. update IDL + implementation of path primitives (

Review of attachment 8389441 [details] [diff] [review]:
-----------------------------------------------------------------

How does this deal with a mismatch between the canvas DrawTarget backend and the backend used to construct the CanvasPath?

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4332,5 @@
> +void
> +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> +                  ErrorResult& error)
> +{
> +  if (radius < 0) {

Any way to share the code copied into this function?

@@ +4436,5 @@
> +  RefPtr<Path> mTempPath = mPathBuilder->Finish();
> +
> +  FillRule fillRule = FillRule::FILL_WINDING;
> +  if(winding == CanvasWindingRule::Evenodd)
> +    fillRule = FillRule::FILL_EVEN_ODD;

space before (, and {} around body

::: content/canvas/src/CanvasRenderingContext2D.h
@@ +87,5 @@
> +  CanvasPath(nsCOMPtr<nsISupports> aParent, RefPtr<gfx::PathBuilder> mPathBuilder);
> +  virtual ~CanvasPath() {}
> +
> +private:
> +  

delete this line
Attachment #8389441 - Flags: review?(roc) → review-
Attachment #8389445 - Flags: review?(roc) → review+
Comment on attachment 8389450 [details] [diff] [review]
2. Recreate path object if backends don't match + add runtime flag + remove creation of drawtarget from path constructor

Review of attachment 8389450 [details] [diff] [review]:
-----------------------------------------------------------------

Fold this into part 1!
Attachment #8389450 - Flags: review?(roc) → review-
(Assignee)

Comment 61

3 years ago
Comment on attachment 8389441 [details] [diff] [review]
1. update IDL + implementation of path primitives (

Review of attachment 8389441 [details] [diff] [review]:
-----------------------------------------------------------------

::: content/canvas/src/CanvasRenderingContext2D.cpp
@@ +4332,5 @@
> +void
> +CanvasPath::ArcTo(double x1, double y1, double x2, double y2, double radius,
> +                  ErrorResult& error)
> +{
> +  if (radius < 0) {

Yes,
I opened a "cleanup" bug that will collapse the logic: https://bugzilla.mozilla.org/show_bug.cgi?id=931587
I will tackle that after this goes in. (If you remember, we talked about not keeping 2 paths in the convas context)
(Assignee)

Comment 62

3 years ago
Created attachment 8392595 [details] [diff] [review]
1. Add implementation + idl of path primitives
Attachment #8389441 - Attachment is obsolete: true
Attachment #8389450 - Attachment is obsolete: true
(Assignee)

Comment 63

3 years ago
Created attachment 8392615 [details] [diff] [review]
1. Add implementation + idl of path primitives
Attachment #8392595 - Attachment is obsolete: true
(Assignee)

Updated

3 years ago
Attachment #8389445 - Attachment description: 3. Add tests for path objects → 2. Add tests for path objects
(Assignee)

Updated

3 years ago
Attachment #8392615 - Flags: review?(roc)
Attachment #8392615 - Flags: review?(roc) → review+
(Assignee)

Updated

3 years ago
Keywords: checkin-needed
(Assignee)

Comment 64

3 years ago
successful try run: https://tbpl.mozilla.org/?tree=Try&rev=1c1d11d3d9eb
https://hg.mozilla.org/integration/mozilla-inbound/rev/5375b5018e53
https://hg.mozilla.org/integration/mozilla-inbound/rev/28ab518279e3
Flags: in-testsuite+
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/5375b5018e53
https://hg.mozilla.org/mozilla-central/rev/28ab518279e3
Status: NEW → RESOLVED
Last Resolved: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla31
(Assignee)

Updated

3 years ago
Blocks: 985178
(Assignee)

Updated

3 years ago
Blocks: 985257
(Assignee)

Updated

3 years ago
Blocks: 985801
Depends on: 1009685
Interface https://developer.mozilla.org/en-US/docs/Web/API/Path2D
Constructor https://developer.mozilla.org/en-US/docs/Web/API/Path2D.Path2D

Updated these methods to say that they can take paths now:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.isPointInPath
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.isPointInStroke
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.clip
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.fill
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.stroke

Mentioned on Firefox 31 for developers
https://developer.mozilla.org/en-US/Firefox/Releases/31#Interfaces.2FAPIs.2FDOM

All marked as enabled by default as per bug 988409.

A chapter in the MDN canvas tutorial will follow.
Keywords: dev-doc-needed → dev-doc-complete
Blocks: 1119470

Updated

2 years ago
Depends on: 1135244
You need to log in before you can comment on or make changes to this bug.