googlefonts / picosvg

Helps simplify SVG files. Intended for use as part of a font build.
Apache License 2.0
141 stars 12 forks source link

fix TypeError when converting pathops.Path to svg #305

Closed anthrotype closed 1 year ago

anthrotype commented 1 year ago

Fixes #304 Fixes https://github.com/googlefonts/nanoemoji/issues/455 Fixes https://github.com/googlefonts/noto-emoji/issues/429

since skia-pathops v0.8.0, the Path.segments (aka SegmentPenIterator) may yield segments where the on-curve point is set to None, which happens when a closed contour is only comprised of quadratic beziers and all the on-curve points can be implied as in-between consecutive off-curve points (i.e. special TrueType quadratic spline). This was to match FontTools pen protocol, which the SegmentPenIterator is supposed to work with, allowing to round-trip these oncurve-less contours through pathops.

Picosvg happens to be using this Path.segments interface when converting from pathops.Path to SVG path.d strings, and an uncaught TypeError was being raised when that happened. However, it turns out that picosvg can avoid using the SegmentPenIterator altogether when converting from pathops.Path to SVG, because the Path's RawPathIterator (i.e. used for iterating over the Path itself, as opposed to its Path.segments) already yields (verb, points) for individual curve segments that match what SVG expects: in this particular case, an explicit move, a list of quadratic bezier segments each with one off-curve point, and a close command, and no fonttools-style None-implied points. This way we can translate between SVG<=>pathops.Path in a more straightforward way, since they are closer to one another than to fonttools pen protocol, more geared towards font format specifics.