printed icon indicating copy to clipboard operation
printed copied to clipboard

Added circle and ellipse shapes

Open a-ludi opened this issue 3 years ago • 4 comments

I added circle and ellipse methods to the renderer interface. These are not part of the Canvas 2D context API but I feel they are useful features for many users/use cases.

As far as I can tell, the Canvas 2D context API only specifies arc to draw circles and ellipses which seems to be much complicated to handle in both SVG and PDF. At the same time, it is more powerful because it can create arcs (i.e. partial ellipses) and ellipses with non-perpendicular axes.

I am happy to discuss different options of including these type of objects into the interface.

a-ludi avatar Jul 13 '21 14:07 a-ludi

Hello,

This is going to be a bit painful.

fillRect is special and add points to a separate path than the one in beginPath/closePath.

From spec: https://www.w3.org/TR/2dcontext/#dom-context-2d-fillrect "Shapes are painted without affecting the current default path"

For example, consider this interleaved scenario, well defined in HTML5: https://www.w3schools.com/code/tryit.asp?filename=GSFPBJJQ2EFY

If one replace fillRect by a fillCircle that starts a new path in the above example, will destroy the start of the path. If I merge your PR, then fillRect preserve the current path, but fillCircle will destroy it, which is surprising. (not for SVG, but possibly for PDF)

  • Any fillCircle or strokeEllipse function (that destroys the current path) should be imo implemented as an UFCS extension function outside of the IRenderingContext2D
  • You can put them in package.d or in an "extra" file.
  • Such drawing functions should not know about PDF or SVG internals.

This is a tricky part of HTMLCanvas that I did wrong in dplug:canvas.

EDIT: if it's inside IRenderingContext2D then it needs to preserve current path. Else it's an extension function that doesn't have to follow the spec spirit

p0nce avatar Jul 13 '21 14:07 p0nce

This is going to be a bit painful.

Certainly. The canvas spec leves room for improvement IMHO.

fillRect is special and add points to a separate path than the one in beginPath/closePath.

I read that, too. SVG elements <circle> and <ellipse> do this as well – no surprises here. As for PDF, we just need to store the current path instead of outputting it immediately. Then it will match the specified behavior.

* Any `fillCircle` or `strokeEllipse` function (that destroys the current path) should be imo implemented as an UFCS extension function outside of the `IRenderingContext2D`

I will implement the proposed fix and keep it in the interface.

* Such drawing functions should not know about PDF or SVG internals.

I think such functions should not belong to this package at all but may be bundled in a separated package as a kind of "standard library":

It is intended to provide a barebones API […].

This standard library could also include a part for easier text layout [#19].

a-ludi avatar Jul 17 '21 12:07 a-ludi

Hello,

I think it's OK if the functions are just next in the same file, just after the IRenderingContext2D definition. You can also create another sub-package if you prefer and see it as better for printed. I have no real preference myself. Such a stdlib could build upon IRenderingContext2D for easier drawing indeed, with a more free design of your choosing.

Will be merged as is in one of these two cases.

If the new primitives break PDF path preserve just open a new Issue for the future, because to be fair I don't know if we already follow the spec wrt fillRect and preserving path. You can ignore this since it's a bit of an edge case in actual use.

(excuse me for swings as I've been confused lately)

p0nce avatar Jul 18 '21 10:07 p0nce

Regurlarly have "stroke-like" needs in DPlug plugins, with fillLine, fillVerticalLine, fillHorizontalLine being, fillSquare being the most common.

p0nce avatar Mar 03 '22 14:03 p0nce