Trouble merging TT instructions into variable font

72 views
Skip to first unread message

Peter Baker

unread,
Jul 2, 2020, 2:45:41 PM7/2/20
to fonttools
I'm trying to write a script that merges TT instructions into a variable font. My understanding (so far) is that the basics of instructing a variable font are the same as for any other TT font (except for the optional cvar table). But in the output font, any instructed glyphs show up as red frowny faces in OT Master Light, while in other apps the instructions seem to be getting dropped, though the glyph displays. Thinking my assembly code was faulty, I tried producing a script that would do almost nothing (just pushing and popping values) but the result was the same. Odd thing is, the very same script works fine on a static font: it displays well, and if the instructions are real instructions, they work correctly. So what am I doing wrong? Or what do I have to do differently for a variable font?

BTW I can verify that the cvt, fpgm, prep and glyph code look correct when examined via ttx or OT Master.

Below is the script. Sorry for my ugly code and for making the post so long. But I'd appreciate any help anyone can give.

from fontTools import ttLib
from fontTools.ttLib import ttFont, tables
import array

currentFont
= ttLib.TTFont("Elstob[GRAD,opsz,wght].ttf")
for g_name in currentFont['glyf'].glyphs:
    glyph
= currentFont['glyf'][g_name]
   
if hasattr(glyph, 'program'):
        glyph
.program.fromAssembly("")

def install_glyph_program(nm, fo, asm):
    g
= fo['glyf'][nm]
    g
.program = tables.ttProgram.Program()
    g
.program.fromAssembly(asm)

currentFont
['cvt '] = ttFont.newTable('cvt ')
setattr
(currentFont['cvt '],'values',array.array('h', [891, 914, 74, 1487, 85, 39, 0, -23]))

currentFont
['fpgm'] = ttFont.newTable('fpgm')
currentFont
['fpgm'].program = tables.ttProgram.Program()
currentFont
['fpgm'].program.fromAssembly('PUSHB[ ]\n\
0\n\
FDEF[ ]\n\
PUSHB[ ]\n\
0\n\
POP[ ]\n\
ENDF[ ]'
)

currentFont
['prep'] = ttFont.newTable('prep')
currentFont
['prep'].program = tables.ttProgram.Program()
currentFont
['prep'].program.fromAssembly('\n\
PUSHB[ ]\n\
1\n\
POP[ ]'
)

install_glyph_program
("a", currentFont, "SVTCA[0]\n\
PUSHB[ ]\n\
34\n\
1\n\
MIAP[1]"
)

currentFont
['maxp'].maxTwilightPoints = 25
currentFont
['maxp'].maxStorage = 70
currentFont
['maxp'].maxStackElements = 256
currentFont
['maxp'].maxFunctionDefs = 4

currentFont
.save("Elstob[GRAD,opsz,wght]-hinted.ttf", 1)




Peter Baker

unread,
Jul 3, 2020, 10:32:15 AM7/3/20
to fonttools
I'll answer my own query, since I figured it out this morning after some two days of struggle. Got the answer by trying the font out in Axis-Praxis with the console open, so saw the report from OTSanitiser that maxSizeOfInstructions in maxp was too small. In fact, I wasn't setting MaxSizeOfInstructions at all, so whatever value was already stored in the font was being retained. The difference between a variable font and a static one was simply that fontmake was running ttfautohint on the static font but not on the variable one, so MaxSizeOfInstructions in the static font was quite large, while in the variable font it was zero.

One can track the size of the instructions with len(glyph.program.getBytecode())
Reply all
Reply to author
Forward
0 new messages