afdko icon indicating copy to clipboard operation
afdko copied to clipboard

psstemhist -z does not find flat descenders

Open frankrolf opened this issue 5 years ago • 1 comments

I cannot find p or q-descenders running psstemhist -z -g A-Z,a-z font.ufo on the attached UFO file.

font.ufo.zip

frankrolf avatar Mar 06 '20 18:03 frankrolf

There are at least two causes of this. One is a bad pruning calculation that wasn't using abs() as it should have, that's easily fixed.

The other is trickier, and in this code that goes back (in one form or another) as long as we have records:

           if ((top == t && CloseSegs(sg2, vLst->vSeg2, vert) &&
                 (vert || (!InBlueBand(t, gLenTopBands, gTopBands) &&
                           !InBlueBand(bot, gLenBotBands, gBotBands) &&
                           !InBlueBand(b, gLenBotBands, gBotBands)))) ||
                (bot == b && CloseSegs(sg1, vLst->vSeg1, vert) &&
                 (vert || (!InBlueBand(b, gLenBotBands, gBotBands) &&
                           !InBlueBand(t, gLenTopBands, gTopBands) &&
                           !InBlueBand(top, gLenTopBands, gTopBands)))) ||
                (abs(top - t) <= gMaxMerge && abs(bot - b) <= gMaxMerge &&
                 (vert ||
                  (t == top || !InBlueBand(top, gLenTopBands, gTopBands))) &&
                 (vert ||
                  (b == bot || !InBlueBand(bot, gLenBotBands, gBotBands))))) {
                if (s == spc && val == v && !vert) {
                    if (InBlueBand(t, gLenTopBands, gTopBands)) {
                        if (t < top)
                            goto replace;
                    } else if (InBlueBand(b, gLenBotBands, gBotBands)) {
                        if (b > bot)
                            goto replace;
                    }
                } else
                    goto replace;

sg2 and vLst->vSeg2 are associated with top, and so forth. So what this is doing is if two stems have the same location on one side and neither side falls in a blueValue, the lower-weighted one gets replaced with the higher-weighted one, which will generally be the one that is less wide.

I'm not going to do anything about this for the moment, but one easy solution would be to have InBlueBand (or its Python equivalent) always return true when gathering zone information, so that every location is privileged and therefore no location is. @frankrolf and I can play around with values sometime to see what works best.

skef avatar Apr 01 '22 12:04 skef