add pens module containing Cu2QuPen, Cu2QuPointPen, etc. #20
Conversation
… and ReverseContourPointPen I copied the ReverseContourPointPen from the robofab.pens. I think it's useful for the Cu2QuPen to have a `reverse_direction` argument which inverts the contours' winding direction. I didn't want to add a dependency on robofab, since things are in transitions... We will add it to the future "penBox" package (or whatever it'll be called) once that is set up.
PS: All pens work on a single-glyph basis. I still haven't figured out how to properly handle collections of glyphs as in |
we were alrady doing that in curveTo, so we might well do it here too
please do not merge this just yet as I'm still working on the tests. Thanks |
also, add test *.glif files to package_data, so users can run test modules against the installed cu2qu by doing e.g.: ``` python -m cu2qu.test.pens_test ```
Sorry I got sidetracked with other stuff. I've finally pushed the promised unit tests for the Cu2Qu pens. I'll send another PR for setting up the continuous integration. In the next days I'll look into ways of integrating the pen protocol with the GlyphCollection class (i.e. to keep interpolation compatibility across multiple fonts). Please let me know if you have any comments. Thanks |
Ah, about the *.glif test files that are in the
The corresponding *.glif files in |
I feel like collection classes are less useful with this pen approach. It might be easier to do the error checking outside of init or the pen, instead in some new fonts_to_quadratic which uses pens to draw quadratic curves with a fixed # of points and then checks errors and bumps up # points itself. Though this may be slower and seems to require that the pen take in an optional fixed num points argument. |
Never mind, of course that won't work because you have different # points for different segments in a single glyph. Hmm. |
OK, one idea for using collections with pens. It's kind of messy and involves many passes over a glyph (i.e. "drawing" the glyph many times).
This still doesn't really require any collection objects. You can just do it by zipping the UFOs and extracting lists of glyphs. |
else: | ||
# on-curves of sub-segments are always "smooth" | ||
new_segment.append((sub_points[-1], True, None, {})) | ||
sub_segments.append(new_segment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's a super Bézier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a curve segment with implicit inflexion point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any tool out there that produces these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that I know of. Maybe @justvanrossum may now, as he is the original author of the basePen module.
Anyway, since they are part of the Pen Protocol, I implemented them here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're implicitly supported in UFO, too, through BasePen, so we need to be cautious. @typesupply, any thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They were in UFO 1 and 2, but as of UFO 3 curve is limited to one or two offcurves. See here:
http://unifiedfontobject.org/versions/ufo3/glif.html#point
I love super beziers (and desperately need them on something I'm drawing right now) but there wasn't must interest in them when I was updating the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love super beziers (and desperately need them on something I'm drawing right now)
How are they useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They allow you to draw a sequence of perfectly smoothly connected cubics with only a few points, so you'll get more flexibility at a low cost. (The number of resulting cubic segments is the number of offcurve points minus one.) Compare that to the need to add three more points (one oncurve, two offcurve points) in your "regular" bezier world, when a single cubic bezier segment simply doesn't cut it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like Robofont supports these curves. I don't know if there's a tool to manipulate them from the GUI, but I could draw one from Python code. Then the control points can be moved inside glyph view. They appear without the handles. Interesting.
g = CurrentGlyph()
pen = g.getPen()
pen.moveTo((10, 10))
pen.curveTo((-1, 28), (-5, 60), (10, 84), (31, 94), (55, 95), (78, 87), (97, 72), (103, 61))
pen.closePath()
I think this PR can be merged, as it's already useful as is: if, say, one wants to use cu2qu in environments with different glyph APIs than defcon or robofab.objectsRF, and does not need to keep interpolatability. I would still like to add support in the top-level I see that in PR #23, James added a file called |
Interesting. I definitely want to reduce duplicate functionality throughout cu2qu, but maybe the ufo module can be adjusted to use a model like this. |
Thanks James! About googlefonts/ufo2ft#35, now that #20 is merged and we have a |
definitely. I just need to find the time to finish it. Unless you fix it first ;) |
@anthrotype Let's also review this together in Berlin. I haven't had time to do that. |
As described in #20 (comment)
I will add docstrings and tests tomorrow, but this is a start.
The
Cu2QuPen
follows the fonttools (segment) pen protocol, whereas theCu2QuPointPen
follows the robofab point pen protocol. They both take another segment or point pen in the constructor, and call that with the result of the cubic-to-quadratic conversion.I believe it's useful to have a
reverse_direction
argument to invert the contours' winding direction. Now, theReverseContourPointPen
from therobofab.pens
does the job. However, I didn't want to add a dependency on robofab, since things are in transition, so I simply copied it here...We can add it to the future "penBox" package (or whatever it'll be called) once that is set up, no?
Please excuse the mixing of underscores and camelCase: cu2qu uses the former, the pens traditionally use the latter. I tried to to be consistent as much as possible.
Let me know if you have any comments.
Thanks