my outlines have too many points due to how I generate the glyphs (via Phython/mathematical functions). Therefore I have to do some “cleaning” before interpolation.

In FontLab7 I found the comment “

However, I can't find anything in RF doing something similar. Any help appreciated!

Thanks in advance,

Petra

Screenshot before:

Screenshot after:

my outlines have too many points due to how I generate the glyphs (via Phython/mathematical functions). Therefore I have to do some “cleaning” before interpolation.

In FontLab7 I found the comment “

However, I can't find anything in RF doing something similar. Any help appreciated!

Thanks in advance,

Petra

Screenshot before:

Screenshot after:

RoboFont does recurve as much as possible when deleting a point.

So that means all the building blocks are there to make a clean up tool.

**the plan:**

- make a copy of the glyph
- delete one point in the copy
- check if curve is almost the same as the original, maybe with an controlled error value
- continue doing this until you can not delete points anymore or when all points are required to draw the shape

good luck!!!

]]>The thing is that we're talking about a few hundred glyphs – which get generated on one click. So deleting all the points in each glyph cannot be done over and over again. (My font file is basically a Pyhthon script which gets generated on need.)

Worst case I have to import the file in FontLab, but I was hoping to be able to avoid that. ]]>

Just wrote it down in pseudo code how to solve this. I dont have much time left. Not my intention to scare you, more to trigger you or someone else to write this little script :)

]]>Cheers,

P ]]>

- Copy the contour and then paste it to a background layer. Make sure this layer is visible, via the Inspector.
- Select a point that isn’t needed, and hit
`delete`

. Adjust the path as needed to match the background contour as much as you want, while considering whether you can improve upon that. - Repeat!

If you had a bunch of glyphs to clean up, this would obviously be a hassle. But, often, it is probably better to have precise control over exactly how you are simplifying paths. It will result in cleaner curves, and helps you be careful to consider interpolation compatibility as you go (if needed).

]]>Your described process is how I was approaching the issue until now – I have tried a few glyphs manually, to test. But now I am in the phase of my project where I have to switch to “mass production”, otherwise my whole approach wouldn't make sense. (It's a student project where I rebuild type which was defined by a mathematical system from a writing master of the 18th century.) ]]>

It works in my case because the the non-extrema points are usually extraneous, so the RoboFont point-deletion recurve algorithm "solves" the deletion correctly.

No error checking or anything like that, as Frederik suggested, but hopefully it might still help you.

```
for glyph in CurrentFont():
glyph.deselect()
for contour in glyph.contours:
for bp in contour.bPoints:
ix, iy = bp.bcpIn
ox, oy = bp.bcpOut
if bp.type == "corner":
continue
if abs(ox-ix) > 5 and abs(oy-iy) > 5:
bp.selected = True
if True:
glyph.removeSelection(
removePoints=True,
removeComponents=False,
removeAnchors=False,
removeImages=False)
```

]]>I will post the final code here:

```
import math
def calc_vector(point1, point2):
x1, y1 = point1
x2, y2 = point2
dx = x2 - x1
dy = y2 - y1
return dx, dy
def calc_angle(point1, point2):
dx, dy = calc_vector(point1, point2)
return math.degrees(math.atan2(dy, dx))
def bp_angles(bp):
ax, ay = bp.anchor
ix, iy = bp.bcpIn
ox, oy = bp.bcpOut
in_angle = calc_angle((ix+ax, iy+ay), bp.anchor)
out_angle = calc_angle(bp.anchor, (ox+ax, oy+ay))
diff = abs(in_angle - out_angle)
return in_angle, out_angle, diff
def select_extra_points(glyph, remove=False):
if False: # flip to True if you want to select a point and see it’s angles printed, useful for debugging
for bp in glyph.selectedBPoints:
in_angle, out_angle, diff = bp_angles(bp)
print("----------", in_angle, out_angle, diff)
else:
glyph.deselect()
for contour in glyph.contours:
for bp in contour.bPoints:
in_angle, out_angle, diff = bp_angles(bp)
if diff < 10:
if abs(abs(in_angle / 90) - round(abs(in_angle / 90))) > 0.1:
bp.selected = True
if remove:
glyph.removeSelection(
removePoints=True,
removeComponents=False,
removeAnchors=False,
removeImages=False)
glyph = CurrentGlyph()
#glyph.removeOverlap(round=1)
select_extra_points(glyph, remove=False)
# To run on the entire font
#for glyph in CurrentFont():
# select_extra_points(glyph, remove=True)
```

]]>