-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open Corners allowed in Glyphs source? #288
Comments
Overlaps in general are removed by default unless fontmake is called with --keep-overlaps. What kind of “open corner” are you talking about? |
No, they are not supported. We will need to figure out how these "open corners" are stored in the .glyphs source and derive the closed path from them by finding the intersection. |
sorry, maybe I'm confusing this with something else I saw at some fontlab VI presentation.. |
I'm talking about in Glyphs you can select points and contextual menu Open Corner. It's a nice feature in some situations. |
Open corners can be inner or outer shapes. Like @anthrotype says, fontmake currently doesn’t support outer open corners. But inner open corners are just regular overlaps. |
indeed, removing the overlaps means making a union of all the contours in the glyph; if you open a corner and it falls outside, then it's not merged. I can't see another way to handle them. |
@punchcutter These don’t translate to open corners that need to be removed in UFO. Glyphs.app just removes the outer open corners when removing overlaps but only when they are in the right direction and their size is below a threshold relative to the neighbouring outline segments. |
Hm, I don't know, I'll have to play with it to understand what it does. |
Looks like we need something like GSPathPen as shown here: https://forum.glyphsapp.com/t/how-to-detect-an-outside-open-corner/4117/11 For now I can just run a script in Glyphs to remove all the corners, but it would be nice to not alter the source files. |
I think this way of clipping is at odds with the conventional non-zero or even-odd winding rules, and is too Glyphs.app specific. /cc @marekjez86 |
Georg has explained the rule here: googlefonts/glyphsLib#255 (comment) |
@anthrotype : OK. we'll change the sources. Thanks for the feedback |
Would it make me sense for glyphsLib to either remove these outer overlaps or add a filter that does before generating an OTF? |
Apparently I’m incapable of figuring out how to detect these outer open corners. Anyone has a code snippet that can be used in e.g. a ufo2ft filter to remove these? |
Georg posted something like this a long time ago and I've used it to remove the open corners before running fontmake.
|
Thanks. IIUC, this has to be run inside Glyphs app and depends on a Glyphs feature, but I’m looking for something that can be run by fontmake at build time to keep the sources unchanged. |
I am also running into this issue of outside open corners remaining as triangles which is making testing difficult. Outside corners can be just as important as inside corners for maintaining the flexibility of individual line segments. L: Glyphs R: FontGoggles |
I think what we need here is a filter pen that iterates over triplets (prev, curr, next) of segments in each contour, computes intersection between previous and next segment, and if intersection falls after the mid-point of the previous segment and before the mid-point of the next segment, then the filter pen should draw with the wrapped pen only the portions of previous and next segments that we want, thus excluding the current segment and surrounding sub-segments that make up the corner shape. Then we use this filterPen in a ufo2ft preProcessor filter that we run only when building from .glyphs sources (where it is expected). For UFO workflows one could enable the filter manually by setting the relevant filter lib key. |
although I am not sure whether this open corner trimming should do that unconditionally or only for those corners that lie outside of a contour (as opposed to regular, inner overlaps), nor I know how to detect the latter situation in a reliable efficient way. |
If I'm allowed to use from beziers.path.representations.fontparts import FontParts
from beziers.path.representations.Segment import SegmentRepresentation
class EraseOpenCornersFilter(BaseFilter):
def filter(self, glyph):
if not len(glyph):
return False
paths = FontParts.fromFontpartsGlyph(glyph)
altered = False
for p in paths:
p.closed = True
segs = p.asSegments()
newsegs = []
for ix, seg in enumerate(segs):
prevseg = segs[ix - 1]
nextIx = (ix + 1) % len(segs)
intersection = segs[ix - 1].intersections(segs[nextIx])
if intersection and (
intersection[0].t1 > 0.5 and intersection[0].t2 < 0.5
):
(segs[ix - 1], _) = segs[ix - 1].splitAtTime(intersection[0].t1)
if newsegs:
newsegs[-1] = segs[ix - 1]
(_, segs[nextIx]) = segs[nextIx].splitAtTime(intersection[0].t2)
altered = True
continue
newsegs.append(seg)
p.activeRepresentation = SegmentRepresentation(p, newsegs)
if altered:
glyph.clearContours()
for p in paths:
FontParts.drawToFontpartsGlyph(glyph, p)
return altered (Yes, it says I have no idea how I would do all the intersection testing and curve splitting without a beziers library. |
nice! By the way, you should already be able to load that custom filter without needing to modify the core ufo2ft library. We designed the filters API to allow dynamically loading such custom filter classes from external modules. Yeah, documentation.. |
Ok, will look at bezierTools tomorrow! |
line-line intersection is trivial; curve-to-line fonttools can do it (it's a matter of translating/rotating the curve and line such that the line is reduced to the x or the y axes then solve the bezier polynomial to get the ts for the intersections); curve-to-curve maybe we don't have it in fonttools but we can add something |
I'm trying to work out where to plumb this into the toolchain. If we want this filter to fire on all UFOs generated from Glyphs sources, it should probably be added to the lib on output in If we don't want that, and we want In fact, I should have picked this up when I added flattenComponents. Rather than Yet Another Kwarg on
it would be a whole lot cleaner just to pass a list of filters around. Then we can add new filters as a command line arg to fontmake. |
I don't think we want a new command-line argument for fontmake, since this is the default behaviour for glyphs-generated sources and nobody wants to build a font with those open corners anyway. |
maybe I misunderstood. are you suggesting we add a generic --filters option to fontmake CLI, similar to --feature-writers with which one can load custom writers from the CLI in addition to from the UFO lib? I guess that could be handy.. but in general one should be able to achieve the same result by injecting a filter definition in the UFO libs.
maybe fontmake is best placed to inject the open courner filter, as the filter is only useful when compiling to a binary font, whereas one may use glyphsLib for source-to-source translation. |
Right, exactly. And if we can pass
But if you are doing
Bah, you just said to define it inside glyphsLib since it is Glyphs-specific. (I agree!) The code does need to import ufo2ft but the filter only gets run by ufo2ft, so it doesn't matter. I added a |
that's what I was trying to avoid.. having glyphsLib depend on ufo2ft |
Only for dev and only for running test. Not a big deal, is it? |
there are precedents for ufo2ft.filters that are only defined but not enabled by default, e.g. the Transformations filter (which is also very glyphs-like in the naming of the various parameters, as it was designed to implement the Glyphs.app's Transformations custom parameter). |
I see what you mean.. yeah, it's fine then. As long as we don't add a runtime dep on ufo2ft in glyphsLib |
Having a |
alright |
I think the main reason is that there is no tool to add or edit ufo2ft libkeys. |
This is all done, now, right? |
I was pretty sure I didn't have problems with open corners before, but right now I have some Glyphs sources with open corners in the outlines and the fonts generated with fontmake don't take care of the corners properly. I'm not sure if I broke something somewhere or is it just that open corners aren't supported at all?
The text was updated successfully, but these errors were encountered: