cetz-package / cetz

CeTZ: ein Typst Zeichenpaket - A library for drawing stuff with Typst.
https://cetz-package.github.io
GNU Lesser General Public License v3.0
809 stars 35 forks source link

Support multiple closed paths in `merge-path` #553

Open liuguangxi opened 4 months ago

liuguangxi commented 4 months ago

Currently at most one closed path could be created by function merge-path, with optional stroke and fill. However in SVG, you can create a "single" path with multiple closed subpaths in the <path> element.

Consider the following SVG files:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
    <path
        d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"
        fill="#e31919"
    />
</svg>

And here is the shape of it: multipath

You can see that there are 3 closed subpaths in it and the filling is done as a whole.

So I don't know how difficult it is to implement this feature, or it's limited by the underlying drawing functionality of Typst.

liuguangxi commented 4 months ago

Also, the fill rule can't apply to multiple paths concurrently, so the "drill holes" drawing in Graphic Parameters: Interior Rules of TikZ still can't be implemented in CeTZ easily.

Whether this feature can be enhanced in CeTZ?

fenjalien commented 4 months ago

We can't currently draw holes at all as we are using typst's path function to draw the paths. It might be possible by splitting up the shape and handling it in a special case.

liuguangxi commented 4 months ago

I feel the drawing function of path in Typst is indeed limited. I also requested adding parameter of "evenodd" fill-rule to path function, as in #3789. The core drawing functionality of Typst may need to be upgraded in the future, so the various features of SVG can be better reproduced in Typst.

For example, we modify the SVG file above a bit:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 460 540">
    <defs>
        <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop
            offset="0%"
            style="stop-color: rgb(230, 230, 70); stop-opacity: 1"
          />
          <stop
            offset="100%"
            style="stop-color: rgb(20, 180, 180); stop-opacity: 1"
          />
        </linearGradient>
    </defs>
    <path
        d="M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v25.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm0 96c61.9 0 112 50.1 112 112v25.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V208c0-61.9 50.1-112 112-112zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z"
        fill="url(#grad1)"
        stroke-width="5" stroke="silver"
    />
</svg>

multipath

It's very difficult to draw this shape effect at the moment with Typst/CeTZ.

Enivex commented 4 months ago

It would be a good idea to mention more use-cases in https://github.com/typst/typst/issues/3789 to demonstrate that it's an important feature. The current example isn't good enough, because it can be achieved without the feature (with some more effort). As opposed to multiply connected regions like here.

liuguangxi commented 4 months ago

Maybe the underlying drawing primitives in Typst need to be reviewed and improved, not only the issues mentioned here. The existing drawing syntax is not very convenient to use, and it is counterintuitive in some places. I feel that Asymptote library is worth learning from. I'm looking forward to having perfect drawing functions in the future.