read_fonts/tables/glyf/bytecode/
opcode.rs

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)]
9pub 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    INS8F = 0x8F,
154    INS90 = 0x90,
155    GETVARIATION = 0x91,
156    GETDATA = 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
268impl Opcode {
269    /// Creates an opcode from the given byte.
270    ///
271    /// There is a 1:1 mapping between bytes and opcodes.
272    #[inline]
273    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 => INS8F,
420            0x90 => INS90,
421            0x91 => GETVARIATION,
422            0x92 => GETDATA,
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.
536    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]
543    pub fn is_push(self) -> bool {
544        (self >= Self::PUSHB000 && self <= Self::PUSHW111)
545            || self == Self::NPUSHB
546            || self == Self::NPUSHW
547    }
548
549    pub(super) fn is_push_words(self) -> bool {
550        (self >= Self::PUSHW000 && self <= Self::PUSHW111) || self == Self::NPUSHW
551    }
552
553    pub(super) fn len(self) -> i32 {
554        OPCODE_LENGTHS[self as usize] as i32
555    }
556}
557
558impl std::fmt::Display for Opcode {
559    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>
569const 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>
835const 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];