Hi, my font has consistent values for underlines and strikethrough accross the masters, generating the OTF static font does it correctly, but when generating the Variable font it changes the thickness of the line ignoring the ‘underlineThickness’ and ‘strikeoutSize’ values.
Here some pics:
I wonder if there’s any other parameter affecting it that I overlooked.
Thanks!
It is probably just that the app is ignoring the values from the font and inferred something.
Thanks for your answer, the app is Indesign, and other Variable fonts react correctly, so it seems to be a font issue.
When opening the generated font in Glyphs I can see something wrong in the values, the ‘underlineThickness’ is gone and instead it shows some buggie code:
This is the code inside ‘prep Table Assembly’
SVTCA[0] /* SetFreedomAndProjectionVectorToAxis */
PUSHB[ ] /* 3 values pushed */
0 3 13
WS[ ] /* WriteStore */
CALL[ ] /* CallFunction */
PUSHB[ ] /* 1 value pushed */
1
CALL[ ] /* CallFunction */
PUSHB[ ] /* 7 values pushed */
57 64 2 1 13 2 1
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
EQ[ ] /* Equal */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 2 values pushed */
46 1
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
15
LT[ ] /* LessThan */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 4 values pushed */
7 3 3 1
RS[ ] /* ReadStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
93
LT[ ] /* LessThan */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 3 values pushed */
10 3 64
WS[ ] /* WriteStore */
JMPR[ ] /* Jump */
PUSHB[ ] /* 2 values pushed */
3 3
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
6
SUB[ ] /* Subtract */
ROUND[01] /* Round */
WS[ ] /* WriteStore */
PUSHW[ ] /* 1 value pushed */
-52
PUSHB[ ] /* 4 values pushed */
1 1 1 1
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
3
RS[ ] /* ReadStore */
WCVTP[ ] /* WriteCVTInPixels */
RS[ ] /* ReadStore */
ADD[ ] /* Add */
WS[ ] /* WriteStore */
JMPR[ ] /* Jump */
PUSHB[ ] /* 1 value pushed */
44
JMPR[ ] /* Jump */
PUSHB[ ] /* 2 values pushed */
36 1
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
15
LT[ ] /* LessThan */
JROF[ ] /* JumpRelativeOnFalse */
PUSHW[ ] /* 1 value pushed */
-42
PUSHB[ ] /* 8 values pushed */
1 1 1 1 4 4 4 1
RS[ ] /* ReadStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
2
RS[ ] /* ReadStore */
MUL[ ] /* Multiply */
ROUND[01] /* Round */
PUSHB[ ] /* 1 value pushed */
2
RS[ ] /* ReadStore */
DIV[ ] /* Divide */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
4
RS[ ] /* ReadStore */
WCVTP[ ] /* WriteCVTInPixels */
RS[ ] /* ReadStore */
ADD[ ] /* Add */
WS[ ] /* WriteStore */
JMPR[ ] /* Jump */
PUSHB[ ] /* 4 values pushed */
6 40 2 3
CALL[ ] /* CallFunction */
PUSHB[ ] /* 4 values pushed */
6 40 4 3
CALL[ ] /* CallFunction */
PUSHB[ ] /* 4 values pushed */
12 40 6 3
CALL[ ] /* CallFunction */
PUSHB[ ] /* 4 values pushed */
0 40 8 3
CALL[ ] /* CallFunction */
PUSHB[ ] /* 4 values pushed */
0 40 10 3
CALL[ ] /* CallFunction */
MPPEM[ ] /* MeasurePixelPerEm */
PUSHW[ ] /* 1 value pushed */
4096
MUL[ ] /* Multiply */
NEG[ ] /* Negate */
PUSHW[ ] /* 1 value pushed */
15000
ADD[ ] /* Add */
PUSHW[ ] /* 1 value pushed */
6400
DIV[ ] /* Divide */
PUSHB[ ] /* 1 value pushed */
10
SWAP[ ] /* SwapTopStack */
WS[ ] /* WriteStore */
PUSHB[ ] /* 2 values pushed */
0 10
RS[ ] /* ReadStore */
GT[ ] /* GreaterThan */
IF[ ] /* If */
PUSHB[ ] /* 1 value pushed */
0
ELSE[ ] /* Else */
PUSHB[ ] /* 1 value pushed */
10
RS[ ] /* ReadStore */
EIF[ ] /* EndIf */
SCVTCI[ ] /* SetCVTCutIn */
PUSHB[ ] /* 1 value pushed */
13
SMD[ ] /* SetMinimumDistance */
This is the code inside ‘fpgm Table Assembly’
PUSHB[ ] /* 1 value pushed */
0
FDEF[ ] /* FunctionDefinition */
PUSHB[ ] /* 2 values pushed */
0 2
WS[ ] /* WriteStore */
PUSHB[ ] /* 1 value pushed */
0
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
3
RS[ ] /* ReadStore */
LT[ ] /* LessThan */
IF[ ] /* If */
PUSHB[ ] /* 2 values pushed */
20 0
RS[ ] /* ReadStore */
ADD[ ] /* Add */
PUSHB[ ] /* 1 value pushed */
0
RS[ ] /* ReadStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
PUSHB[ ] /* 3 values pushed */
0 1 0
RS[ ] /* ReadStore */
ADD[ ] /* Add */
WS[ ] /* WriteStore */
PUSHW[ ] /* 1 value pushed */
-28
JMPR[ ] /* Jump */
EIF[ ] /* EndIf */
ENDF[ ] /* EndFunctionDefinition */
PUSHB[ ] /* 1 value pushed */
1
FDEF[ ] /* FunctionDefinition */
PUSHB[ ] /* 4 values pushed */
7 0 0 1
GETINFO[ ] /* GetInfo */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
38
LT[ ] /* LessThan */
PUSHB[ ] /* 2 values pushed */
37 0
RS[ ] /* ReadStore */
EQ[ ] /* Equal */
PUSHB[ ] /* 2 values pushed */
0 64
GETINFO[ ] /* GetInfo */
EQ[ ] /* Equal */
AND[ ] /* LogicalAnd */
NOT[ ] /* LogicalNot */
AND[ ] /* LogicalAnd */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 3 values pushed */
7 1 64
WCVTP[ ] /* WriteCVTInPixels */
JMPR[ ] /* Jump */
PUSHB[ ] /* 1 value pushed */
1
PUSHW[ ] /* 1 value pushed */
256
WCVTP[ ] /* WriteCVTInPixels */
ENDF[ ] /* EndFunctionDefinition */
PUSHB[ ] /* 1 value pushed */
2
FDEF[ ] /* FunctionDefinition */
PUSHB[ ] /* 1 value pushed */
2
SWAP[ ] /* SwapTopStack */
WS[ ] /* WriteStore */
PUSHB[ ] /* 1 value pushed */
3
SWAP[ ] /* SwapTopStack */
WS[ ] /* WriteStore */
PUSHB[ ] /* 6 values pushed */
2 0 3 1 20 3
RS[ ] /* ReadStore */
ADD[ ] /* Add */
RS[ ] /* ReadStore */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
2
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
1
SZP2[ ] /* SetZonePointer2 */
GC[0] /* GetCoordOnPVector */
PUSHB[ ] /* 1 value pushed */
0
RS[ ] /* ReadStore */
ADD[ ] /* Add */
PUSHB[ ] /* 1 value pushed */
1
RS[ ] /* ReadStore */
SUB[ ] /* Subtract */
SCFS[ ] /* SetCoordFromStackFP */
PUSHB[ ] /* 1 value pushed */
2
RS[ ] /* ReadStore */
MDAP[0] /* MoveDirectAbsPt */
ENDF[ ] /* EndFunctionDefinition */
PUSHB[ ] /* 1 value pushed */
3
FDEF[ ] /* FunctionDefinition */
PUSHB[ ] /* 1 value pushed */
5
SWAP[ ] /* SwapTopStack */
WS[ ] /* WriteStore */
PUSHB[ ] /* 1 value pushed */
11
SWAP[ ] /* SwapTopStack */
WS[ ] /* WriteStore */
PUSHB[ ] /* 1 value pushed */
10
SWAP[ ] /* SwapTopStack */
WS[ ] /* WriteStore */
PUSHB[ ] /* 5 values pushed */
10 9 9 4 5
RS[ ] /* ReadStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
MPPEM[ ] /* MeasurePixelPerEm */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
16
LT[ ] /* LessThan */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 2 values pushed */
4 4
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
10
RS[ ] /* ReadStore */
ADD[ ] /* Add */
WS[ ] /* WriteStore */
NPUSHB[ ] /* 12 values pushed */
9 8 8 1 3 5 5 1 5 5 7 4
RS[ ] /* ReadStore */
ROUND[01] /* Round */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
7
RS[ ] /* ReadStore */
WCVTP[ ] /* WriteCVTInPixels */
RS[ ] /* ReadStore */
ADD[ ] /* Add */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
RCVT[ ] /* ReadCVT */
WS[ ] /* WriteStore */
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
64
GT[ ] /* GreaterThan */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 2 values pushed */
11 11
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
11
SUB[ ] /* Subtract */
WS[ ] /* WriteStore */
PUSHB[ ] /* 2 values pushed */
25 9
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
11
RS[ ] /* ReadStore */
GT[ ] /* GreaterThan */
JROF[ ] /* JumpRelativeOnFalse */
PUSHB[ ] /* 3 values pushed */
6 6 7
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
3
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
4
RS[ ] /* ReadStore */
SUB[ ] /* Subtract */
PUSHB[ ] /* 1 value pushed */
8
RS[ ] /* ReadStore */
MUL[ ] /* Multiply */
ROUND[01] /* Round */
PUSHB[ ] /* 1 value pushed */
8
RS[ ] /* ReadStore */
DIV[ ] /* Divide */
ADD[ ] /* Add */
WS[ ] /* WriteStore */
JMPR[ ] /* Jump */
PUSHB[ ] /* 2 values pushed */
6 7
RS[ ] /* ReadStore */
WS[ ] /* WriteStore */
PUSHB[ ] /* 1 value pushed */
5
RS[ ] /* ReadStore */
PUSHB[ ] /* 1 value pushed */
6
RS[ ] /* ReadStore */
WCVTP[ ] /* WriteCVTInPixels */
ENDF[ ] /* EndFunctionDefinition */
This is the code inside ‘CVT Table’
(
0,
0,
750,
765,
730,
745,
496,
511,
0,
"-15",
"-200",
"-215",
0,
85,
90,
0
)
Any idea on how to fix this?
Thanks!
Those things have nothing to do with the underline.
The other font might have a MVAR table. That is not supported in Glyphs, yet.
I see, is it in scope to add the table?
mekkablue
(Rainer Erich Scheichelbauer)
July 5, 2024, 12:12pm
6
Albert Creus:
Hi, my font has consistent values for underlines and strikethrough accross the masters, generating the OTF static font does it correctly, but when generating the Variable font it changes the thickness of the line ignoring the ‘underlineThickness’ and ‘strikeoutSize’ values.
This is an Adobe bug. They are reluctant to fix it because it jeopardizes backwards compatibility.
I see, thanks for clarifying. Little hopes on Adobe solving it, higher hopes on you guys implementing MVAR ; )
TimAhrens
(Tim Ahrens)
February 25, 2025, 2:11pm
9
Just trying to get underline position and thickness to work in a browser (Firefox for now). Seems like it always applies the values of the origin master, and the other ones are not stored in the font at all? Is there a way to fix this?
Is this a variable font? Or are you testing different instances?
I think that would be done with a MVAR table. And Glyphs doesn’t write it, yet. I’ll have a look.
TimAhrens
(Tim Ahrens)
February 25, 2025, 2:19pm
12
Yes, I was trying it with a VF. Thanks for looking into it, Georg!