1 //! TrueType hinting opcodes.
2 
3 /// Operation code for a TrueType instruction.
4 ///
5 /// See [the TrueType instruction set](https://learn.microsoft.com/en-us/typography/opentype/spec/tt_instructions)
6 /// from the OpenType specification for more detail.
7 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
8 #[repr(u8)]
9 pub enum Opcode {
10     SVTCA0 = 0x00,
11     SVTCA1 = 0x01,
12     SPVTCA0 = 0x02,
13     SPVTCA1 = 0x03,
14     SFVTCA0 = 0x04,
15     SFVTCA1 = 0x05,
16     SPVTL0 = 0x06,
17     SPVTL1 = 0x07,
18     SFVTL0 = 0x08,
19     SFVTL1 = 0x09,
20     SPVFS = 0x0A,
21     SFVFS = 0x0B,
22     GPV = 0x0C,
23     GFV = 0x0D,
24     SFVTPV = 0x0E,
25     ISECT = 0x0F,
26     SRP0 = 0x10,
27     SRP1 = 0x11,
28     SRP2 = 0x12,
29     SZP0 = 0x13,
30     SZP1 = 0x14,
31     SZP2 = 0x15,
32     SZPS = 0x16,
33     SLOOP = 0x17,
34     RTG = 0x18,
35     RTHG = 0x19,
36     SMD = 0x1A,
37     ELSE = 0x1B,
38     JMPR = 0x1C,
39     SCVTCI = 0x1D,
40     SSWCI = 0x1E,
41     SSW = 0x1F,
42     DUP = 0x20,
43     POP = 0x21,
44     CLEAR = 0x22,
45     SWAP = 0x23,
46     DEPTH = 0x24,
47     CINDEX = 0x25,
48     MINDEX = 0x26,
49     ALIGNPTS = 0x27,
50     INS28 = 0x28,
51     UTP = 0x29,
52     LOOPCALL = 0x2A,
53     CALL = 0x2B,
54     FDEF = 0x2C,
55     ENDF = 0x2D,
56     MDAP0 = 0x2E,
57     MDAP1 = 0x2F,
58     IUP0 = 0x30,
59     IUP1 = 0x31,
60     SHP0 = 0x32,
61     SHP1 = 0x33,
62     SHC0 = 0x34,
63     SHC1 = 0x35,
64     SHZ0 = 0x36,
65     SHZ1 = 0x37,
66     SHPIX = 0x38,
67     IP = 0x39,
68     MSIRP0 = 0x3A,
69     MSIRP1 = 0x3B,
70     ALIGNRP = 0x3C,
71     RTDG = 0x3D,
72     MIAP0 = 0x3E,
73     MIAP1 = 0x3F,
74     NPUSHB = 0x40,
75     NPUSHW = 0x41,
76     WS = 0x42,
77     RS = 0x43,
78     WCVTP = 0x44,
79     RCVT = 0x45,
80     GC0 = 0x46,
81     GC1 = 0x47,
82     SCFS = 0x48,
83     MD0 = 0x49,
84     MD1 = 0x4A,
85     MPPEM = 0x4B,
86     MPS = 0x4C,
87     FLIPON = 0x4D,
88     FLIPOFF = 0x4E,
89     DEBUG = 0x4F,
90     LT = 0x50,
91     LTEQ = 0x51,
92     GT = 0x52,
93     GTEQ = 0x53,
94     EQ = 0x54,
95     NEQ = 0x55,
96     ODD = 0x56,
97     EVEN = 0x57,
98     IF = 0x58,
99     EIF = 0x59,
100     AND = 0x5A,
101     OR = 0x5B,
102     NOT = 0x5C,
103     DELTAP1 = 0x5D,
104     SDB = 0x5E,
105     SDS = 0x5F,
106     ADD = 0x60,
107     SUB = 0x61,
108     DIV = 0x62,
109     MUL = 0x63,
110     ABS = 0x64,
111     NEG = 0x65,
112     FLOOR = 0x66,
113     CEILING = 0x67,
114     ROUND00 = 0x68,
115     ROUND01 = 0x69,
116     ROUND10 = 0x6A,
117     ROUND11 = 0x6B,
118     NROUND00 = 0x6C,
119     NROUND01 = 0x6D,
120     NROUND10 = 0x6E,
121     NROUND11 = 0x6F,
122     WCVTF = 0x70,
123     DELTAP2 = 0x71,
124     DELTAP3 = 0x72,
125     DELTAC1 = 0x73,
126     DELTAC2 = 0x74,
127     DELTAC3 = 0x75,
128     SROUND = 0x76,
129     S45ROUND = 0x77,
130     JROT = 0x78,
131     JROF = 0x79,
132     ROFF = 0x7A,
133     INS7B = 0x7B,
134     RUTG = 0x7C,
135     RDTG = 0x7D,
136     SANGW = 0x7E,
137     AA = 0x7F,
138     FLIPPT = 0x80,
139     FLIPRGON = 0x81,
140     FLIPRGOFF = 0x82,
141     INS83 = 0x83,
142     INS84 = 0x84,
143     SCANCTRL = 0x85,
144     SDPVTL0 = 0x86,
145     SDPVTL1 = 0x87,
146     GETINFO = 0x88,
147     IDEF = 0x89,
148     ROLL = 0x8A,
149     MAX = 0x8B,
150     MIN = 0x8C,
151     SCANTYPE = 0x8D,
152     INSTCTRL = 0x8E,
153     GETVARIATION = 0x8F,
154     GETDATA = 0x90,
155     INS91 = 0x91,
156     INS92 = 0x92,
157     INS93 = 0x93,
158     INS94 = 0x94,
159     INS95 = 0x95,
160     INS96 = 0x96,
161     INS97 = 0x97,
162     INS98 = 0x98,
163     INS99 = 0x99,
164     INS9A = 0x9A,
165     INS9B = 0x9B,
166     INS9C = 0x9C,
167     INS9D = 0x9D,
168     INS9E = 0x9E,
169     INS9F = 0x9F,
170     INSA0 = 0xA0,
171     INSA1 = 0xA1,
172     INSA2 = 0xA2,
173     INSA3 = 0xA3,
174     INSA4 = 0xA4,
175     INSA5 = 0xA5,
176     INSA6 = 0xA6,
177     INSA7 = 0xA7,
178     INSA8 = 0xA8,
179     INSA9 = 0xA9,
180     INSAA = 0xAA,
181     INSAB = 0xAB,
182     INSAC = 0xAC,
183     INSAD = 0xAD,
184     INSAE = 0xAE,
185     INSAF = 0xAF,
186     PUSHB000 = 0xB0,
187     PUSHB001 = 0xB1,
188     PUSHB010 = 0xB2,
189     PUSHB011 = 0xB3,
190     PUSHB100 = 0xB4,
191     PUSHB101 = 0xB5,
192     PUSHB110 = 0xB6,
193     PUSHB111 = 0xB7,
194     PUSHW000 = 0xB8,
195     PUSHW001 = 0xB9,
196     PUSHW010 = 0xBA,
197     PUSHW011 = 0xBB,
198     PUSHW100 = 0xBC,
199     PUSHW101 = 0xBD,
200     PUSHW110 = 0xBE,
201     PUSHW111 = 0xBF,
202     MDRP00000 = 0xC0,
203     MDRP00001 = 0xC1,
204     MDRP00010 = 0xC2,
205     MDRP00011 = 0xC3,
206     MDRP00100 = 0xC4,
207     MDRP00101 = 0xC5,
208     MDRP00110 = 0xC6,
209     MDRP00111 = 0xC7,
210     MDRP01000 = 0xC8,
211     MDRP01001 = 0xC9,
212     MDRP01010 = 0xCA,
213     MDRP01011 = 0xCB,
214     MDRP01100 = 0xCC,
215     MDRP01101 = 0xCD,
216     MDRP01110 = 0xCE,
217     MDRP01111 = 0xCF,
218     MDRP10000 = 0xD0,
219     MDRP10001 = 0xD1,
220     MDRP10010 = 0xD2,
221     MDRP10011 = 0xD3,
222     MDRP10100 = 0xD4,
223     MDRP10101 = 0xD5,
224     MDRP10110 = 0xD6,
225     MDRP10111 = 0xD7,
226     MDRP11000 = 0xD8,
227     MDRP11001 = 0xD9,
228     MDRP11010 = 0xDA,
229     MDRP11011 = 0xDB,
230     MDRP11100 = 0xDC,
231     MDRP11101 = 0xDD,
232     MDRP11110 = 0xDE,
233     MDRP11111 = 0xDF,
234     MIRP00000 = 0xE0,
235     MIRP00001 = 0xE1,
236     MIRP00010 = 0xE2,
237     MIRP00011 = 0xE3,
238     MIRP00100 = 0xE4,
239     MIRP00101 = 0xE5,
240     MIRP00110 = 0xE6,
241     MIRP00111 = 0xE7,
242     MIRP01000 = 0xE8,
243     MIRP01001 = 0xE9,
244     MIRP01010 = 0xEA,
245     MIRP01011 = 0xEB,
246     MIRP01100 = 0xEC,
247     MIRP01101 = 0xED,
248     MIRP01110 = 0xEE,
249     MIRP01111 = 0xEF,
250     MIRP10000 = 0xF0,
251     MIRP10001 = 0xF1,
252     MIRP10010 = 0xF2,
253     MIRP10011 = 0xF3,
254     MIRP10100 = 0xF4,
255     MIRP10101 = 0xF5,
256     MIRP10110 = 0xF6,
257     MIRP10111 = 0xF7,
258     MIRP11000 = 0xF8,
259     MIRP11001 = 0xF9,
260     MIRP11010 = 0xFA,
261     MIRP11011 = 0xFB,
262     MIRP11100 = 0xFC,
263     MIRP11101 = 0xFD,
264     MIRP11110 = 0xFE,
265     MIRP11111 = 0xFF,
266 }
267 
268 impl Opcode {
269     /// Creates an opcode from the given byte.
270     ///
271     /// There is a 1:1 mapping between bytes and opcodes.
272     #[inline]
from_byte(byte: u8) -> Self273     pub fn from_byte(byte: u8) -> Self {
274         use Opcode::*;
275         match byte {
276             0x00 => SVTCA0,
277             0x01 => SVTCA1,
278             0x02 => SPVTCA0,
279             0x03 => SPVTCA1,
280             0x04 => SFVTCA0,
281             0x05 => SFVTCA1,
282             0x06 => SPVTL0,
283             0x07 => SPVTL1,
284             0x08 => SFVTL0,
285             0x09 => SFVTL1,
286             0x0A => SPVFS,
287             0x0B => SFVFS,
288             0x0C => GPV,
289             0x0D => GFV,
290             0x0E => SFVTPV,
291             0x0F => ISECT,
292             0x10 => SRP0,
293             0x11 => SRP1,
294             0x12 => SRP2,
295             0x13 => SZP0,
296             0x14 => SZP1,
297             0x15 => SZP2,
298             0x16 => SZPS,
299             0x17 => SLOOP,
300             0x18 => RTG,
301             0x19 => RTHG,
302             0x1A => SMD,
303             0x1B => ELSE,
304             0x1C => JMPR,
305             0x1D => SCVTCI,
306             0x1E => SSWCI,
307             0x1F => SSW,
308             0x20 => DUP,
309             0x21 => POP,
310             0x22 => CLEAR,
311             0x23 => SWAP,
312             0x24 => DEPTH,
313             0x25 => CINDEX,
314             0x26 => MINDEX,
315             0x27 => ALIGNPTS,
316             0x28 => INS28,
317             0x29 => UTP,
318             0x2A => LOOPCALL,
319             0x2B => CALL,
320             0x2C => FDEF,
321             0x2D => ENDF,
322             0x2E => MDAP0,
323             0x2F => MDAP1,
324             0x30 => IUP0,
325             0x31 => IUP1,
326             0x32 => SHP0,
327             0x33 => SHP1,
328             0x34 => SHC0,
329             0x35 => SHC1,
330             0x36 => SHZ0,
331             0x37 => SHZ1,
332             0x38 => SHPIX,
333             0x39 => IP,
334             0x3A => MSIRP0,
335             0x3B => MSIRP1,
336             0x3C => ALIGNRP,
337             0x3D => RTDG,
338             0x3E => MIAP0,
339             0x3F => MIAP1,
340             0x40 => NPUSHB,
341             0x41 => NPUSHW,
342             0x42 => WS,
343             0x43 => RS,
344             0x44 => WCVTP,
345             0x45 => RCVT,
346             0x46 => GC0,
347             0x47 => GC1,
348             0x48 => SCFS,
349             0x49 => MD0,
350             0x4A => MD1,
351             0x4B => MPPEM,
352             0x4C => MPS,
353             0x4D => FLIPON,
354             0x4E => FLIPOFF,
355             0x4F => DEBUG,
356             0x50 => LT,
357             0x51 => LTEQ,
358             0x52 => GT,
359             0x53 => GTEQ,
360             0x54 => EQ,
361             0x55 => NEQ,
362             0x56 => ODD,
363             0x57 => EVEN,
364             0x58 => IF,
365             0x59 => EIF,
366             0x5A => AND,
367             0x5B => OR,
368             0x5C => NOT,
369             0x5D => DELTAP1,
370             0x5E => SDB,
371             0x5F => SDS,
372             0x60 => ADD,
373             0x61 => SUB,
374             0x62 => DIV,
375             0x63 => MUL,
376             0x64 => ABS,
377             0x65 => NEG,
378             0x66 => FLOOR,
379             0x67 => CEILING,
380             0x68 => ROUND00,
381             0x69 => ROUND01,
382             0x6A => ROUND10,
383             0x6B => ROUND11,
384             0x6C => NROUND00,
385             0x6D => NROUND01,
386             0x6E => NROUND10,
387             0x6F => NROUND11,
388             0x70 => WCVTF,
389             0x71 => DELTAP2,
390             0x72 => DELTAP3,
391             0x73 => DELTAC1,
392             0x74 => DELTAC2,
393             0x75 => DELTAC3,
394             0x76 => SROUND,
395             0x77 => S45ROUND,
396             0x78 => JROT,
397             0x79 => JROF,
398             0x7A => ROFF,
399             0x7B => INS7B,
400             0x7C => RUTG,
401             0x7D => RDTG,
402             0x7E => SANGW,
403             0x7F => AA,
404             0x80 => FLIPPT,
405             0x81 => FLIPRGON,
406             0x82 => FLIPRGOFF,
407             0x83 => INS83,
408             0x84 => INS84,
409             0x85 => SCANCTRL,
410             0x86 => SDPVTL0,
411             0x87 => SDPVTL1,
412             0x88 => GETINFO,
413             0x89 => IDEF,
414             0x8A => ROLL,
415             0x8B => MAX,
416             0x8C => MIN,
417             0x8D => SCANTYPE,
418             0x8E => INSTCTRL,
419             0x8F => GETVARIATION,
420             0x90 => GETDATA,
421             0x91 => INS91,
422             0x92 => INS92,
423             0x93 => INS93,
424             0x94 => INS94,
425             0x95 => INS95,
426             0x96 => INS96,
427             0x97 => INS97,
428             0x98 => INS98,
429             0x99 => INS99,
430             0x9A => INS9A,
431             0x9B => INS9B,
432             0x9C => INS9C,
433             0x9D => INS9D,
434             0x9E => INS9E,
435             0x9F => INS9F,
436             0xA0 => INSA0,
437             0xA1 => INSA1,
438             0xA2 => INSA2,
439             0xA3 => INSA3,
440             0xA4 => INSA4,
441             0xA5 => INSA5,
442             0xA6 => INSA6,
443             0xA7 => INSA7,
444             0xA8 => INSA8,
445             0xA9 => INSA9,
446             0xAA => INSAA,
447             0xAB => INSAB,
448             0xAC => INSAC,
449             0xAD => INSAD,
450             0xAE => INSAE,
451             0xAF => INSAF,
452             0xB0 => PUSHB000,
453             0xB1 => PUSHB001,
454             0xB2 => PUSHB010,
455             0xB3 => PUSHB011,
456             0xB4 => PUSHB100,
457             0xB5 => PUSHB101,
458             0xB6 => PUSHB110,
459             0xB7 => PUSHB111,
460             0xB8 => PUSHW000,
461             0xB9 => PUSHW001,
462             0xBA => PUSHW010,
463             0xBB => PUSHW011,
464             0xBC => PUSHW100,
465             0xBD => PUSHW101,
466             0xBE => PUSHW110,
467             0xBF => PUSHW111,
468             0xC0 => MDRP00000,
469             0xC1 => MDRP00001,
470             0xC2 => MDRP00010,
471             0xC3 => MDRP00011,
472             0xC4 => MDRP00100,
473             0xC5 => MDRP00101,
474             0xC6 => MDRP00110,
475             0xC7 => MDRP00111,
476             0xC8 => MDRP01000,
477             0xC9 => MDRP01001,
478             0xCA => MDRP01010,
479             0xCB => MDRP01011,
480             0xCC => MDRP01100,
481             0xCD => MDRP01101,
482             0xCE => MDRP01110,
483             0xCF => MDRP01111,
484             0xD0 => MDRP10000,
485             0xD1 => MDRP10001,
486             0xD2 => MDRP10010,
487             0xD3 => MDRP10011,
488             0xD4 => MDRP10100,
489             0xD5 => MDRP10101,
490             0xD6 => MDRP10110,
491             0xD7 => MDRP10111,
492             0xD8 => MDRP11000,
493             0xD9 => MDRP11001,
494             0xDA => MDRP11010,
495             0xDB => MDRP11011,
496             0xDC => MDRP11100,
497             0xDD => MDRP11101,
498             0xDE => MDRP11110,
499             0xDF => MDRP11111,
500             0xE0 => MIRP00000,
501             0xE1 => MIRP00001,
502             0xE2 => MIRP00010,
503             0xE3 => MIRP00011,
504             0xE4 => MIRP00100,
505             0xE5 => MIRP00101,
506             0xE6 => MIRP00110,
507             0xE7 => MIRP00111,
508             0xE8 => MIRP01000,
509             0xE9 => MIRP01001,
510             0xEA => MIRP01010,
511             0xEB => MIRP01011,
512             0xEC => MIRP01100,
513             0xED => MIRP01101,
514             0xEE => MIRP01110,
515             0xEF => MIRP01111,
516             0xF0 => MIRP10000,
517             0xF1 => MIRP10001,
518             0xF2 => MIRP10010,
519             0xF3 => MIRP10011,
520             0xF4 => MIRP10100,
521             0xF5 => MIRP10101,
522             0xF6 => MIRP10110,
523             0xF7 => MIRP10111,
524             0xF8 => MIRP11000,
525             0xF9 => MIRP11001,
526             0xFA => MIRP11010,
527             0xFB => MIRP11011,
528             0xFC => MIRP11100,
529             0xFD => MIRP11101,
530             0xFE => MIRP11110,
531             0xFF => MIRP11111,
532         }
533     }
534 
535     /// Returns a more descriptive name for the opcode.
name(self) -> &'static str536     pub fn name(self) -> &'static str {
537         OPCODE_NAMES[self as usize]
538     }
539 
540     /// Returns true if this is an instruction that pushes values onto the
541     /// stack.
542     #[inline]
is_push(self) -> bool543     pub fn is_push(self) -> bool {
544         (self >= Self::PUSHB000 && self <= Self::PUSHW111)
545             || self == Self::NPUSHB
546             || self == Self::NPUSHW
547     }
548 
is_push_words(self) -> bool549     pub(super) fn is_push_words(self) -> bool {
550         (self >= Self::PUSHW000 && self <= Self::PUSHW111) || self == Self::NPUSHW
551     }
552 
len(self) -> i32553     pub(super) fn len(self) -> i32 {
554         OPCODE_LENGTHS[self as usize] as i32
555     }
556 }
557 
558 impl std::fmt::Display for Opcode {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result559     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
560         write!(f, "{}", self.name())
561     }
562 }
563 
564 /// There doesn't seem to be any prevailing set of mnemonics for these
565 /// instructions. These are pulled from FreeType with the justification
566 /// that diffing FreeType hinting traces with our own is the most
567 /// efficient way to track down discrepancies.
568 /// <https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.c#L837>
569 const OPCODE_NAMES: [&str; 256] = [
570     "SVTCA[y]",
571     "SVTCA[x]",
572     "SPVTCA[y]",
573     "SPVTCA[x]",
574     "SFVTCA[y]",
575     "SFVTCA[x]",
576     "SPVTL[||]",
577     "SPVTL[+]",
578     "SFVTL[||]",
579     "SFVTL[+]",
580     "SPVFS",
581     "SFVFS",
582     "GPV",
583     "GFV",
584     "SFVTPV",
585     "ISECT",
586     "SRP0",
587     "SRP1",
588     "SRP2",
589     "SZP0",
590     "SZP1",
591     "SZP2",
592     "SZPS",
593     "SLOOP",
594     "RTG",
595     "RTHG",
596     "SMD",
597     "ELSE",
598     "JMPR",
599     "SCVTCI",
600     "SSWCI",
601     "SSW",
602     "DUP",
603     "POP",
604     "CLEAR",
605     "SWAP",
606     "DEPTH",
607     "CINDEX",
608     "MINDEX",
609     "ALIGNPTS",
610     "INS_$28",
611     "UTP",
612     "LOOPCALL",
613     "CALL",
614     "FDEF",
615     "ENDF",
616     "MDAP[]",
617     "MDAP[rnd]",
618     "IUP[y]",
619     "IUP[x]",
620     "SHP[rp2]",
621     "SHP[rp1]",
622     "SHC[rp2]",
623     "SHC[rp1]",
624     "SHZ[rp2]",
625     "SHZ[rp1]",
626     "SHPIX",
627     "IP",
628     "MSIRP[]",
629     "MSIRP[rp0]",
630     "ALIGNRP",
631     "RTDG",
632     "MIAP[]",
633     "MIAP[rnd]",
634     "NPUSHB",
635     "NPUSHW",
636     "WS",
637     "RS",
638     "WCVTP",
639     "RCVT",
640     "GC[curr]",
641     "GC[orig]",
642     "SCFS",
643     "MD[curr]",
644     "MD[orig]",
645     "MPPEM",
646     "MPS",
647     "FLIPON",
648     "FLIPOFF",
649     "DEBUG",
650     "LT",
651     "LTEQ",
652     "GT",
653     "GTEQ",
654     "EQ",
655     "NEQ",
656     "ODD",
657     "EVEN",
658     "IF",
659     "EIF",
660     "AND",
661     "OR",
662     "NOT",
663     "DELTAP1",
664     "SDB",
665     "SDS",
666     "ADD",
667     "SUB",
668     "DIV",
669     "MUL",
670     "ABS",
671     "NEG",
672     "FLOOR",
673     "CEILING",
674     "ROUND[G]",
675     "ROUND[B]",
676     "ROUND[W]",
677     "ROUND[]",
678     "NROUND[G]",
679     "NROUND[B]",
680     "NROUND[W]",
681     "NROUND[]",
682     "WCVTF",
683     "DELTAP2",
684     "DELTAP3",
685     "DELTAC1",
686     "DELTAC2",
687     "DELTAC3",
688     "SROUND",
689     "S45ROUND",
690     "JROT",
691     "JROF",
692     "ROFF",
693     "INS_$7B",
694     "RUTG",
695     "RDTG",
696     "SANGW",
697     "AA",
698     "FLIPPT",
699     "FLIPRGON",
700     "FLIPRGOFF",
701     "INS_$83",
702     "INS_$84",
703     "SCANCTRL",
704     "SDPVTL[||]",
705     "SDPVTL[+]",
706     "GETINFO",
707     "IDEF",
708     "ROLL",
709     "MAX",
710     "MIN",
711     "SCANTYPE",
712     "INSTCTRL",
713     "INS_$8F",
714     "INS_$90",
715     "GETVARIATION",
716     "GETDATA",
717     "INS_$93",
718     "INS_$94",
719     "INS_$95",
720     "INS_$96",
721     "INS_$97",
722     "INS_$98",
723     "INS_$99",
724     "INS_$9A",
725     "INS_$9B",
726     "INS_$9C",
727     "INS_$9D",
728     "INS_$9E",
729     "INS_$9F",
730     "INS_$A0",
731     "INS_$A1",
732     "INS_$A2",
733     "INS_$A3",
734     "INS_$A4",
735     "INS_$A5",
736     "INS_$A6",
737     "INS_$A7",
738     "INS_$A8",
739     "INS_$A9",
740     "INS_$AA",
741     "INS_$AB",
742     "INS_$AC",
743     "INS_$AD",
744     "INS_$AE",
745     "INS_$AF",
746     "PUSHB[0]",
747     "PUSHB[1]",
748     "PUSHB[2]",
749     "PUSHB[3]",
750     "PUSHB[4]",
751     "PUSHB[5]",
752     "PUSHB[6]",
753     "PUSHB[7]",
754     "PUSHW[0]",
755     "PUSHW[1]",
756     "PUSHW[2]",
757     "PUSHW[3]",
758     "PUSHW[4]",
759     "PUSHW[5]",
760     "PUSHW[6]",
761     "PUSHW[7]",
762     "MDRP[G]",
763     "MDRP[B]",
764     "MDRP[W]",
765     "MDRP[]",
766     "MDRP[rG]",
767     "MDRP[rB]",
768     "MDRP[rW]",
769     "MDRP[r]",
770     "MDRP[mG]",
771     "MDRP[mB]",
772     "MDRP[mW]",
773     "MDRP[m]",
774     "MDRP[mrG]",
775     "MDRP[mrB]",
776     "MDRP[mrW]",
777     "MDRP[mr]",
778     "MDRP[pG]",
779     "MDRP[pB]",
780     "MDRP[pW]",
781     "MDRP[p]",
782     "MDRP[prG]",
783     "MDRP[prB]",
784     "MDRP[prW]",
785     "MDRP[pr]",
786     "MDRP[pmG]",
787     "MDRP[pmB]",
788     "MDRP[pmW]",
789     "MDRP[pm]",
790     "MDRP[pmrG]",
791     "MDRP[pmrB]",
792     "MDRP[pmrW]",
793     "MDRP[pmr]",
794     "MIRP[G]",
795     "MIRP[B]",
796     "MIRP[W]",
797     "MIRP[]",
798     "MIRP[rG]",
799     "MIRP[rB]",
800     "MIRP[rW]",
801     "MIRP[r]",
802     "MIRP[mG]",
803     "MIRP[mB]",
804     "MIRP[mW]",
805     "MIRP[m]",
806     "MIRP[mrG]",
807     "MIRP[mrB]",
808     "MIRP[mrW]",
809     "MIRP[mr]",
810     "MIRP[pG]",
811     "MIRP[pB]",
812     "MIRP[pW]",
813     "MIRP[p]",
814     "MIRP[prG]",
815     "MIRP[prB]",
816     "MIRP[prW]",
817     "MIRP[pr]",
818     "MIRP[pmG]",
819     "MIRP[pmB]",
820     "MIRP[pmW]",
821     "MIRP[pm]",
822     "MIRP[pmrG]",
823     "MIRP[pmrB]",
824     "MIRP[pmrW]",
825     "MIRP[pmr]",
826 ];
827 
828 /// Size in bytes of an instruction.
829 ///
830 /// The negative values represent variable length instructions where the
831 /// next byte in the stream is the count of following operands and the
832 /// absolute value of the length in this table is the size in bytes of
833 /// each operand. These are just the NPUSHB and NPUSHW instructions.
834 /// <https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.c#L1137>
835 const OPCODE_LENGTHS: [i8; 256] = [
836     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
837     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
838     -1, -2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
839     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
840     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
841     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 3, 5, 7, 9, 11, 13,
842     15, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
843     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844     1, 1, 1,
845 ];
846