[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [ft-devel] Question about TTF
From: |
Werner LEMBERG |
Subject: |
Re: [ft-devel] Question about TTF |
Date: |
Thu, 24 May 2018 00:17:04 +0200 (CEST) |
> I am a grad student of University of Waterloo. We have a
> project about TTF. We are trying to translate TTF bytecode to
> some kind of 3-addr-code, and optimize the 3-addr-code, then
> convert it back to bytecode.
Nice! I think I've already read about this (or a similar) project a
few years ago.
> We tested our program on arial.ttf, and found that there is a
> CALL instruction in some fpgm, which calls an uncertain fixed
> point value (bytecode attached below).
>
> As you can see, the callee is the result of a series of
> arithmetic operations, (4096 DIV MIN(MAX(0, 64 SUB F26Dot6),
> 192) ADD 44), where 192 not even divides 4096.
You are misinterpreting the code. Rewriting the code with normal
decimal numbers we get
min(max(round(x) - 1.0, 0), 3) + 44
Remarks:
* The `4096 DIV' bytecode converts an F26Dot6 number to a plain
integer (i.e., a division by 64) – it thus disappears in the
decimal formula.
* Value 44 is the function offset; possible function numbers are
obviously 44-47, since the above code uses `min' and `max' to
limit the value accordingly.
> So, I wonder how do you deal with such a call instruction, do
> you just throw an exception?
Why should we do that? The arithmetic code is fully valid! Depending
on the input code (some scaled CVT value, I guess) it either calls
function 44, 45, 46, or 47.
Werner
======================================================================
PUSH[ ]
17
FDEF[ ] /* FunctionDefinition */
DUP[ ] /* DuplicateTopStack */
ROUND[01] /* Round */
PUSHB[ ] /* 1 value pushed */
64
SUB[ ] /* Subtract */
PUSHB[ ] /* 1 value pushed */
0
MAX[ ] /* Maximum */
DUP[ ] /* DuplicateTopStack */
PUSHB[ ] /* 2 values pushed */
44 192
ROLL[ ] /* RollTopThreeStack */
MIN[ ] /* Minimum */
PUSHW[ ] /* 1 value pushed */
4096 /* word */
DIV[ ] /* Divide */
ADD[ ] /* Add */
CALL[ ] /* CallFunction */
GPV[ ] /* GetPVector */
ABS[ ] /* Absolute */
SWAP[ ] /* SwapTopStack */
ABS[ ] /* Absolute */
SUB[ ] /* Subtract */
NOT[ ] /* LogicalNot */
IF[ ] /* If */
PUSHB[ ] /* 1 value pushed */
3
SUB[ ] /* Subtract */
EIF[ ] /* EndIf */
ENDF[ ] /* EndFunctionDefinition */