adobe-fonts / source-serif

Typeface for setting text in many sizes, weights, and languages. Designed to complement Source Sans.
https://adobe-fonts.github.io/source-serif
SIL Open Font License 1.1
2.15k stars 161 forks source link

Is the contour direction of `theta` incorrect/reversed? #124

Open tamcy opened 10 months ago

tamcy commented 10 months ago

Two similarily looking glyphs, theta and fita, are created with a different contour order:

This results different contour order when converting the master .ufo to .pfa with the tx command:

Take this command for instance:

tx -t1 ./source-serif-main/Roman/Masters/text/master_0/SourceSerif_0.ufo /tmp/test.pfa

Here's the result (Left: theta, Right: fita): image

If a font is produced with this source, fita will render correctly, but theta could be incorrect at certain size, probably depending on the rendering engine:

image (Same font but in different size; Word 365 on Windows 11)

Note that fonts released here seems fine. The problem arises when a custom build from the masters is needed.

I checked several glyphs that are similar in composition (Oslash, oslash, theta, Fita, fita, Obarcyr, obarcyr, Fita.sc, Obarcyr.sc), with theta's contour direction being the only exception, thus I tend to think this is something to do with the source, not the tx script, so I am reporting it here. Thanks in advance!

frankrolf commented 10 months ago

Thank you for the note! Thank you also for confirming that the released fonts are OK – the contour reversal is something that checkoutlinesufo should take care of (but of course it’s good practice to have the contour order be correct in the source UFOs also).

I was curious if there were any other inadvertently-clockwise glyphs, and came up with the simplest possible script:

f = CurrentFont()

for g in f:
    if g.contours:
        x1, y1, x2, y2 = g.bounds
        ng = g.copy()
        p = ng.getPen()
        p.moveTo((x1, y1))
        p.lineTo((x2, y1))
        p.lineTo((x2, y2))
        p.lineTo((x1, y2))
        p.closePath()
        ng.removeOverlap()
        if len(ng.contours[0].points) > 4:
            print(g.name)

Fortunately, no result (after fixing that theta)