Coverage Report

Created: 2026-04-01 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/read-fonts/src/tables/glyf/bytecode/opcode.rs
Line
Count
Source
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
    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
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]
273
0
    pub fn from_byte(byte: u8) -> Self {
274
        use Opcode::*;
275
0
        match byte {
276
0
            0x00 => SVTCA0,
277
0
            0x01 => SVTCA1,
278
0
            0x02 => SPVTCA0,
279
0
            0x03 => SPVTCA1,
280
0
            0x04 => SFVTCA0,
281
0
            0x05 => SFVTCA1,
282
0
            0x06 => SPVTL0,
283
0
            0x07 => SPVTL1,
284
0
            0x08 => SFVTL0,
285
0
            0x09 => SFVTL1,
286
0
            0x0A => SPVFS,
287
0
            0x0B => SFVFS,
288
0
            0x0C => GPV,
289
0
            0x0D => GFV,
290
0
            0x0E => SFVTPV,
291
0
            0x0F => ISECT,
292
0
            0x10 => SRP0,
293
0
            0x11 => SRP1,
294
0
            0x12 => SRP2,
295
0
            0x13 => SZP0,
296
0
            0x14 => SZP1,
297
0
            0x15 => SZP2,
298
0
            0x16 => SZPS,
299
0
            0x17 => SLOOP,
300
0
            0x18 => RTG,
301
0
            0x19 => RTHG,
302
0
            0x1A => SMD,
303
0
            0x1B => ELSE,
304
0
            0x1C => JMPR,
305
0
            0x1D => SCVTCI,
306
0
            0x1E => SSWCI,
307
0
            0x1F => SSW,
308
0
            0x20 => DUP,
309
0
            0x21 => POP,
310
0
            0x22 => CLEAR,
311
0
            0x23 => SWAP,
312
0
            0x24 => DEPTH,
313
0
            0x25 => CINDEX,
314
0
            0x26 => MINDEX,
315
0
            0x27 => ALIGNPTS,
316
0
            0x28 => INS28,
317
0
            0x29 => UTP,
318
0
            0x2A => LOOPCALL,
319
0
            0x2B => CALL,
320
0
            0x2C => FDEF,
321
0
            0x2D => ENDF,
322
0
            0x2E => MDAP0,
323
0
            0x2F => MDAP1,
324
0
            0x30 => IUP0,
325
0
            0x31 => IUP1,
326
0
            0x32 => SHP0,
327
0
            0x33 => SHP1,
328
0
            0x34 => SHC0,
329
0
            0x35 => SHC1,
330
0
            0x36 => SHZ0,
331
0
            0x37 => SHZ1,
332
0
            0x38 => SHPIX,
333
0
            0x39 => IP,
334
0
            0x3A => MSIRP0,
335
0
            0x3B => MSIRP1,
336
0
            0x3C => ALIGNRP,
337
0
            0x3D => RTDG,
338
0
            0x3E => MIAP0,
339
0
            0x3F => MIAP1,
340
0
            0x40 => NPUSHB,
341
0
            0x41 => NPUSHW,
342
0
            0x42 => WS,
343
0
            0x43 => RS,
344
0
            0x44 => WCVTP,
345
0
            0x45 => RCVT,
346
0
            0x46 => GC0,
347
0
            0x47 => GC1,
348
0
            0x48 => SCFS,
349
0
            0x49 => MD0,
350
0
            0x4A => MD1,
351
0
            0x4B => MPPEM,
352
0
            0x4C => MPS,
353
0
            0x4D => FLIPON,
354
0
            0x4E => FLIPOFF,
355
0
            0x4F => DEBUG,
356
0
            0x50 => LT,
357
0
            0x51 => LTEQ,
358
0
            0x52 => GT,
359
0
            0x53 => GTEQ,
360
0
            0x54 => EQ,
361
0
            0x55 => NEQ,
362
0
            0x56 => ODD,
363
0
            0x57 => EVEN,
364
0
            0x58 => IF,
365
0
            0x59 => EIF,
366
0
            0x5A => AND,
367
0
            0x5B => OR,
368
0
            0x5C => NOT,
369
0
            0x5D => DELTAP1,
370
0
            0x5E => SDB,
371
0
            0x5F => SDS,
372
0
            0x60 => ADD,
373
0
            0x61 => SUB,
374
0
            0x62 => DIV,
375
0
            0x63 => MUL,
376
0
            0x64 => ABS,
377
0
            0x65 => NEG,
378
0
            0x66 => FLOOR,
379
0
            0x67 => CEILING,
380
0
            0x68 => ROUND00,
381
0
            0x69 => ROUND01,
382
0
            0x6A => ROUND10,
383
0
            0x6B => ROUND11,
384
0
            0x6C => NROUND00,
385
0
            0x6D => NROUND01,
386
0
            0x6E => NROUND10,
387
0
            0x6F => NROUND11,
388
0
            0x70 => WCVTF,
389
0
            0x71 => DELTAP2,
390
0
            0x72 => DELTAP3,
391
0
            0x73 => DELTAC1,
392
0
            0x74 => DELTAC2,
393
0
            0x75 => DELTAC3,
394
0
            0x76 => SROUND,
395
0
            0x77 => S45ROUND,
396
0
            0x78 => JROT,
397
0
            0x79 => JROF,
398
0
            0x7A => ROFF,
399
0
            0x7B => INS7B,
400
0
            0x7C => RUTG,
401
0
            0x7D => RDTG,
402
0
            0x7E => SANGW,
403
0
            0x7F => AA,
404
0
            0x80 => FLIPPT,
405
0
            0x81 => FLIPRGON,
406
0
            0x82 => FLIPRGOFF,
407
0
            0x83 => INS83,
408
0
            0x84 => INS84,
409
0
            0x85 => SCANCTRL,
410
0
            0x86 => SDPVTL0,
411
0
            0x87 => SDPVTL1,
412
0
            0x88 => GETINFO,
413
0
            0x89 => IDEF,
414
0
            0x8A => ROLL,
415
0
            0x8B => MAX,
416
0
            0x8C => MIN,
417
0
            0x8D => SCANTYPE,
418
0
            0x8E => INSTCTRL,
419
0
            0x8F => INS8F,
420
0
            0x90 => INS90,
421
0
            0x91 => GETVARIATION,
422
0
            0x92 => GETDATA,
423
0
            0x93 => INS93,
424
0
            0x94 => INS94,
425
0
            0x95 => INS95,
426
0
            0x96 => INS96,
427
0
            0x97 => INS97,
428
0
            0x98 => INS98,
429
0
            0x99 => INS99,
430
0
            0x9A => INS9A,
431
0
            0x9B => INS9B,
432
0
            0x9C => INS9C,
433
0
            0x9D => INS9D,
434
0
            0x9E => INS9E,
435
0
            0x9F => INS9F,
436
0
            0xA0 => INSA0,
437
0
            0xA1 => INSA1,
438
0
            0xA2 => INSA2,
439
0
            0xA3 => INSA3,
440
0
            0xA4 => INSA4,
441
0
            0xA5 => INSA5,
442
0
            0xA6 => INSA6,
443
0
            0xA7 => INSA7,
444
0
            0xA8 => INSA8,
445
0
            0xA9 => INSA9,
446
0
            0xAA => INSAA,
447
0
            0xAB => INSAB,
448
0
            0xAC => INSAC,
449
0
            0xAD => INSAD,
450
0
            0xAE => INSAE,
451
0
            0xAF => INSAF,
452
0
            0xB0 => PUSHB000,
453
0
            0xB1 => PUSHB001,
454
0
            0xB2 => PUSHB010,
455
0
            0xB3 => PUSHB011,
456
0
            0xB4 => PUSHB100,
457
0
            0xB5 => PUSHB101,
458
0
            0xB6 => PUSHB110,
459
0
            0xB7 => PUSHB111,
460
0
            0xB8 => PUSHW000,
461
0
            0xB9 => PUSHW001,
462
0
            0xBA => PUSHW010,
463
0
            0xBB => PUSHW011,
464
0
            0xBC => PUSHW100,
465
0
            0xBD => PUSHW101,
466
0
            0xBE => PUSHW110,
467
0
            0xBF => PUSHW111,
468
0
            0xC0 => MDRP00000,
469
0
            0xC1 => MDRP00001,
470
0
            0xC2 => MDRP00010,
471
0
            0xC3 => MDRP00011,
472
0
            0xC4 => MDRP00100,
473
0
            0xC5 => MDRP00101,
474
0
            0xC6 => MDRP00110,
475
0
            0xC7 => MDRP00111,
476
0
            0xC8 => MDRP01000,
477
0
            0xC9 => MDRP01001,
478
0
            0xCA => MDRP01010,
479
0
            0xCB => MDRP01011,
480
0
            0xCC => MDRP01100,
481
0
            0xCD => MDRP01101,
482
0
            0xCE => MDRP01110,
483
0
            0xCF => MDRP01111,
484
0
            0xD0 => MDRP10000,
485
0
            0xD1 => MDRP10001,
486
0
            0xD2 => MDRP10010,
487
0
            0xD3 => MDRP10011,
488
0
            0xD4 => MDRP10100,
489
0
            0xD5 => MDRP10101,
490
0
            0xD6 => MDRP10110,
491
0
            0xD7 => MDRP10111,
492
0
            0xD8 => MDRP11000,
493
0
            0xD9 => MDRP11001,
494
0
            0xDA => MDRP11010,
495
0
            0xDB => MDRP11011,
496
0
            0xDC => MDRP11100,
497
0
            0xDD => MDRP11101,
498
0
            0xDE => MDRP11110,
499
0
            0xDF => MDRP11111,
500
0
            0xE0 => MIRP00000,
501
0
            0xE1 => MIRP00001,
502
0
            0xE2 => MIRP00010,
503
0
            0xE3 => MIRP00011,
504
0
            0xE4 => MIRP00100,
505
0
            0xE5 => MIRP00101,
506
0
            0xE6 => MIRP00110,
507
0
            0xE7 => MIRP00111,
508
0
            0xE8 => MIRP01000,
509
0
            0xE9 => MIRP01001,
510
0
            0xEA => MIRP01010,
511
0
            0xEB => MIRP01011,
512
0
            0xEC => MIRP01100,
513
0
            0xED => MIRP01101,
514
0
            0xEE => MIRP01110,
515
0
            0xEF => MIRP01111,
516
0
            0xF0 => MIRP10000,
517
0
            0xF1 => MIRP10001,
518
0
            0xF2 => MIRP10010,
519
0
            0xF3 => MIRP10011,
520
0
            0xF4 => MIRP10100,
521
0
            0xF5 => MIRP10101,
522
0
            0xF6 => MIRP10110,
523
0
            0xF7 => MIRP10111,
524
0
            0xF8 => MIRP11000,
525
0
            0xF9 => MIRP11001,
526
0
            0xFA => MIRP11010,
527
0
            0xFB => MIRP11011,
528
0
            0xFC => MIRP11100,
529
0
            0xFD => MIRP11101,
530
0
            0xFE => MIRP11110,
531
0
            0xFF => MIRP11111,
532
        }
533
0
    }
Unexecuted instantiation: <read_fonts::tables::glyf::bytecode::opcode::Opcode>::from_byte
Unexecuted instantiation: <read_fonts::tables::glyf::bytecode::opcode::Opcode>::from_byte
534
535
    /// Returns a more descriptive name for the opcode.
536
0
    pub fn name(self) -> &'static str {
537
0
        OPCODE_NAMES[self as usize]
538
0
    }
539
540
    /// Returns true if this is an instruction that pushes values onto the
541
    /// stack.
542
    #[inline]
543
0
    pub fn is_push(self) -> bool {
544
0
        (self >= Self::PUSHB000 && self <= Self::PUSHW111)
545
0
            || self == Self::NPUSHB
546
0
            || self == Self::NPUSHW
547
0
    }
548
549
0
    pub(super) fn is_push_words(self) -> bool {
550
0
        (self >= Self::PUSHW000 && self <= Self::PUSHW111) || self == Self::NPUSHW
551
0
    }
552
553
0
    pub(super) fn len(self) -> i32 {
554
0
        OPCODE_LENGTHS[self as usize] as i32
555
0
    }
556
}
557
558
impl std::fmt::Display for Opcode {
559
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
560
0
        write!(f, "{}", self.name())
561
0
    }
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
];