Closed typesupply closed 2 years ago
@letterror and @typemytype, do you have any ideas?
It looks like you are basically doing the same as an autohinter ;)
I have a script which does something similar, finding points that constitute stems to use for autohinting or for determining postscriptStemSnapH/postscriptStemSnapV.
The analysing of outlines is done in a pen: StemPen.py.zip
At a quick glance, what I do that you don't is that the direction of outlines is taken into account.
For finding related points, the script checks if the directions are "paired", i.e. the outline direction is up in the first point and down in the second point, or, for vertical relations, if the outline directions are left to right and right to left through the respective point candidates.
That should avoid points on the same side of a "stem" being recognized as related.
@jenskutilek Thanks! I do something similar in Glyph Nanny. Hm, I'll give it a try for this.
I added an experiment script that runs in the DrawBot extension in RoboFont. I has the point to point code isolated and it generates a visual report after testing manyManyManyManyManyManyManyManyManyMany locations to see what the nearest points are.
The latest optimization seems to have broken some situations. Hovering in the middle of this glyph does not snap to the top/bottom points for some reason.
<?xml version='1.0' encoding='UTF-8'?>
<glyph name="zero.num" format="2">
<advance width="242"/>
<outline>
<contour>
<point x="121" y="706" type="curve"/>
<point x="68" y="706"/>
<point x="28" y="659"/>
<point x="28" y="573" type="curve" smooth="yes"/>
<point x="28" y="476" type="line" smooth="yes"/>
<point x="28" y="389"/>
<point x="68" y="343"/>
<point x="121" y="343" type="curve"/>
<point x="174" y="343"/>
<point x="214" y="389"/>
<point x="214" y="476" type="curve" smooth="yes"/>
<point x="214" y="573" type="line" smooth="yes"/>
<point x="214" y="659"/>
<point x="174" y="706"/>
</contour>
<contour>
<point x="121" y="689" type="curve"/>
<point x="164" y="689"/>
<point x="195" y="650"/>
<point x="195" y="573" type="curve" smooth="yes"/>
<point x="195" y="476" type="line" smooth="yes"/>
<point x="195" y="399"/>
<point x="164" y="360"/>
<point x="121" y="360" type="curve"/>
<point x="78" y="360"/>
<point x="47" y="399"/>
<point x="47" y="476" type="curve" smooth="yes"/>
<point x="47" y="573" type="line" smooth="yes"/>
<point x="47" y="650"/>
<point x="78" y="689"/>
</contour>
</outline>
</glyph>
Narrow shapes are problematic in the point-to-point algorithm. The algorithm is in the
NearestPointsPointPen.find
method. The algorithm is trying to find if the user has is using the current mouse location,location
, (in glyph units) to see the distance between two on curve points.The algorithm works by gathering all on curve points and then trying all combinations of
point1
andpoint2
. There are some optimizations at the start to eliminate obviously incorrect combinations, but after that the algorithm is basically this:(point1, location, point2)
roughly collinear?point1
andpoint2
close to a right angle?point1
andpoint2
intersect the glyph in more locations than justpoint1
andpoint2
?In narrow shapes, step 1 and step 2 create a situation in which the "middle" between points diagonally opposite each other is so large that it's counter-intuitive for the user. For example:
I haven't found a solution to eliminate this yet.
I think the same steps are causing nonsensical combinations to be considered correct. For example:
GLIF for testing: