ttf_parser/tables/cff/
charstring.rs

1use super::argstack::ArgumentsStack;
2use super::{f32_abs, Builder, CFFError, IsEven};
3use crate::parser::{Fixed, Stream};
4
5pub(crate) struct CharStringParser<'a> {
6    pub stack: ArgumentsStack<'a>,
7    pub builder: &'a mut Builder<'a>,
8    pub x: f32,
9    pub y: f32,
10    pub has_move_to: bool,
11    pub is_first_move_to: bool,
12    pub width_only: bool, // Exit right after the glyph width is parsed.
13}
14
15impl CharStringParser<'_> {
16    #[inline]
17    pub fn parse_move_to(&mut self, offset: usize) -> Result<(), CFFError> {
18        // dx1 dy1
19
20        if self.stack.len() != offset + 2 {
21            return Err(CFFError::InvalidArgumentsStackLength);
22        }
23
24        if self.is_first_move_to {
25            self.is_first_move_to = false;
26        } else {
27            self.builder.close();
28        }
29
30        self.has_move_to = true;
31
32        self.x += self.stack.at(offset + 0);
33        self.y += self.stack.at(offset + 1);
34        self.builder.move_to(self.x, self.y);
35
36        self.stack.clear();
37        Ok(())
38    }
39
40    #[inline]
41    pub fn parse_horizontal_move_to(&mut self, offset: usize) -> Result<(), CFFError> {
42        // dx1
43
44        if self.stack.len() != offset + 1 {
45            return Err(CFFError::InvalidArgumentsStackLength);
46        }
47
48        if self.is_first_move_to {
49            self.is_first_move_to = false;
50        } else {
51            self.builder.close();
52        }
53
54        self.has_move_to = true;
55
56        self.x += self.stack.at(offset);
57        self.builder.move_to(self.x, self.y);
58
59        self.stack.clear();
60        Ok(())
61    }
62
63    #[inline]
64    pub fn parse_vertical_move_to(&mut self, offset: usize) -> Result<(), CFFError> {
65        // dy1
66
67        if self.stack.len() != offset + 1 {
68            return Err(CFFError::InvalidArgumentsStackLength);
69        }
70
71        if self.is_first_move_to {
72            self.is_first_move_to = false;
73        } else {
74            self.builder.close();
75        }
76
77        self.has_move_to = true;
78
79        self.y += self.stack.at(offset);
80        self.builder.move_to(self.x, self.y);
81
82        self.stack.clear();
83        Ok(())
84    }
85
86    #[inline]
87    pub fn parse_line_to(&mut self) -> Result<(), CFFError> {
88        // {dxa dya}+
89
90        if !self.has_move_to {
91            return Err(CFFError::MissingMoveTo);
92        }
93
94        if self.stack.len().is_odd() {
95            return Err(CFFError::InvalidArgumentsStackLength);
96        }
97
98        let mut i = 0;
99        while i < self.stack.len() {
100            self.x += self.stack.at(i + 0);
101            self.y += self.stack.at(i + 1);
102            self.builder.line_to(self.x, self.y);
103            i += 2;
104        }
105
106        self.stack.clear();
107        Ok(())
108    }
109
110    #[inline]
111    pub fn parse_horizontal_line_to(&mut self) -> Result<(), CFFError> {
112        // dx1 {dya dxb}*
113        //     {dxa dyb}+
114
115        if !self.has_move_to {
116            return Err(CFFError::MissingMoveTo);
117        }
118
119        if self.stack.is_empty() {
120            return Err(CFFError::InvalidArgumentsStackLength);
121        }
122
123        let mut i = 0;
124        while i < self.stack.len() {
125            self.x += self.stack.at(i);
126            i += 1;
127            self.builder.line_to(self.x, self.y);
128
129            if i == self.stack.len() {
130                break;
131            }
132
133            self.y += self.stack.at(i);
134            i += 1;
135            self.builder.line_to(self.x, self.y);
136        }
137
138        self.stack.clear();
139        Ok(())
140    }
141
142    #[inline]
143    pub fn parse_vertical_line_to(&mut self) -> Result<(), CFFError> {
144        // dy1 {dxa dyb}*
145        //     {dya dxb}+
146
147        if !self.has_move_to {
148            return Err(CFFError::MissingMoveTo);
149        }
150
151        if self.stack.is_empty() {
152            return Err(CFFError::InvalidArgumentsStackLength);
153        }
154
155        let mut i = 0;
156        while i < self.stack.len() {
157            self.y += self.stack.at(i);
158            i += 1;
159            self.builder.line_to(self.x, self.y);
160
161            if i == self.stack.len() {
162                break;
163            }
164
165            self.x += self.stack.at(i);
166            i += 1;
167            self.builder.line_to(self.x, self.y);
168        }
169
170        self.stack.clear();
171        Ok(())
172    }
173
174    #[inline]
175    pub fn parse_curve_to(&mut self) -> Result<(), CFFError> {
176        // {dxa dya dxb dyb dxc dyc}+
177
178        if !self.has_move_to {
179            return Err(CFFError::MissingMoveTo);
180        }
181
182        if self.stack.len() % 6 != 0 {
183            return Err(CFFError::InvalidArgumentsStackLength);
184        }
185
186        let mut i = 0;
187        while i < self.stack.len() {
188            let x1 = self.x + self.stack.at(i + 0);
189            let y1 = self.y + self.stack.at(i + 1);
190            let x2 = x1 + self.stack.at(i + 2);
191            let y2 = y1 + self.stack.at(i + 3);
192            self.x = x2 + self.stack.at(i + 4);
193            self.y = y2 + self.stack.at(i + 5);
194
195            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
196            i += 6;
197        }
198
199        self.stack.clear();
200        Ok(())
201    }
202
203    #[inline]
204    pub fn parse_curve_line(&mut self) -> Result<(), CFFError> {
205        // {dxa dya dxb dyb dxc dyc}+ dxd dyd
206
207        if !self.has_move_to {
208            return Err(CFFError::MissingMoveTo);
209        }
210
211        if self.stack.len() < 8 {
212            return Err(CFFError::InvalidArgumentsStackLength);
213        }
214
215        if (self.stack.len() - 2) % 6 != 0 {
216            return Err(CFFError::InvalidArgumentsStackLength);
217        }
218
219        let mut i = 0;
220        while i < self.stack.len() - 2 {
221            let x1 = self.x + self.stack.at(i + 0);
222            let y1 = self.y + self.stack.at(i + 1);
223            let x2 = x1 + self.stack.at(i + 2);
224            let y2 = y1 + self.stack.at(i + 3);
225            self.x = x2 + self.stack.at(i + 4);
226            self.y = y2 + self.stack.at(i + 5);
227
228            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
229            i += 6;
230        }
231
232        self.x += self.stack.at(i + 0);
233        self.y += self.stack.at(i + 1);
234        self.builder.line_to(self.x, self.y);
235
236        self.stack.clear();
237        Ok(())
238    }
239
240    #[inline]
241    pub fn parse_line_curve(&mut self) -> Result<(), CFFError> {
242        // {dxa dya}+ dxb dyb dxc dyc dxd dyd
243
244        if !self.has_move_to {
245            return Err(CFFError::MissingMoveTo);
246        }
247
248        if self.stack.len() < 8 {
249            return Err(CFFError::InvalidArgumentsStackLength);
250        }
251
252        if (self.stack.len() - 6).is_odd() {
253            return Err(CFFError::InvalidArgumentsStackLength);
254        }
255
256        let mut i = 0;
257        while i < self.stack.len() - 6 {
258            self.x += self.stack.at(i + 0);
259            self.y += self.stack.at(i + 1);
260
261            self.builder.line_to(self.x, self.y);
262            i += 2;
263        }
264
265        let x1 = self.x + self.stack.at(i + 0);
266        let y1 = self.y + self.stack.at(i + 1);
267        let x2 = x1 + self.stack.at(i + 2);
268        let y2 = y1 + self.stack.at(i + 3);
269        self.x = x2 + self.stack.at(i + 4);
270        self.y = y2 + self.stack.at(i + 5);
271        self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
272
273        self.stack.clear();
274        Ok(())
275    }
276
277    #[inline]
278    pub fn parse_hh_curve_to(&mut self) -> Result<(), CFFError> {
279        // dy1? {dxa dxb dyb dxc}+
280
281        if !self.has_move_to {
282            return Err(CFFError::MissingMoveTo);
283        }
284
285        let mut i = 0;
286
287        // The odd argument count indicates an Y position.
288        if self.stack.len().is_odd() {
289            self.y += self.stack.at(0);
290            i += 1;
291        }
292
293        if (self.stack.len() - i) % 4 != 0 {
294            return Err(CFFError::InvalidArgumentsStackLength);
295        }
296
297        while i < self.stack.len() {
298            let x1 = self.x + self.stack.at(i + 0);
299            let y1 = self.y;
300            let x2 = x1 + self.stack.at(i + 1);
301            let y2 = y1 + self.stack.at(i + 2);
302            self.x = x2 + self.stack.at(i + 3);
303            self.y = y2;
304
305            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
306            i += 4;
307        }
308
309        self.stack.clear();
310        Ok(())
311    }
312
313    #[inline]
314    pub fn parse_vv_curve_to(&mut self) -> Result<(), CFFError> {
315        // dx1? {dya dxb dyb dyc}+
316
317        if !self.has_move_to {
318            return Err(CFFError::MissingMoveTo);
319        }
320
321        let mut i = 0;
322
323        // The odd argument count indicates an X position.
324        if self.stack.len().is_odd() {
325            self.x += self.stack.at(0);
326            i += 1;
327        }
328
329        if (self.stack.len() - i) % 4 != 0 {
330            return Err(CFFError::InvalidArgumentsStackLength);
331        }
332
333        while i < self.stack.len() {
334            let x1 = self.x;
335            let y1 = self.y + self.stack.at(i + 0);
336            let x2 = x1 + self.stack.at(i + 1);
337            let y2 = y1 + self.stack.at(i + 2);
338            self.x = x2;
339            self.y = y2 + self.stack.at(i + 3);
340
341            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
342            i += 4;
343        }
344
345        self.stack.clear();
346        Ok(())
347    }
348
349    #[inline]
350    pub fn parse_hv_curve_to(&mut self) -> Result<(), CFFError> {
351        // dx1 dx2 dy2 dy3 {dya dxb dyb dxc dxd dxe dye dyf}* dxf?
352        //                 {dxa dxb dyb dyc dyd dxe dye dxf}+ dyf?
353
354        if !self.has_move_to {
355            return Err(CFFError::MissingMoveTo);
356        }
357
358        if self.stack.len() < 4 {
359            return Err(CFFError::InvalidArgumentsStackLength);
360        }
361
362        self.stack.reverse();
363        while !self.stack.is_empty() {
364            if self.stack.len() < 4 {
365                return Err(CFFError::InvalidArgumentsStackLength);
366            }
367
368            let x1 = self.x + self.stack.pop();
369            let y1 = self.y;
370            let x2 = x1 + self.stack.pop();
371            let y2 = y1 + self.stack.pop();
372            self.y = y2 + self.stack.pop();
373            self.x = x2;
374            if self.stack.len() == 1 {
375                self.x += self.stack.pop();
376            }
377            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
378            if self.stack.is_empty() {
379                break;
380            }
381
382            if self.stack.len() < 4 {
383                return Err(CFFError::InvalidArgumentsStackLength);
384            }
385
386            let x1 = self.x;
387            let y1 = self.y + self.stack.pop();
388            let x2 = x1 + self.stack.pop();
389            let y2 = y1 + self.stack.pop();
390            self.x = x2 + self.stack.pop();
391            self.y = y2;
392            if self.stack.len() == 1 {
393                self.y += self.stack.pop()
394            }
395            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
396        }
397
398        debug_assert!(self.stack.is_empty());
399        Ok(())
400    }
401
402    #[inline]
403    pub fn parse_vh_curve_to(&mut self) -> Result<(), CFFError> {
404        // dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf?
405        //                 {dya dxb dyb dxc dxd dxe dye dyf}+ dxf?
406
407        if !self.has_move_to {
408            return Err(CFFError::MissingMoveTo);
409        }
410
411        if self.stack.len() < 4 {
412            return Err(CFFError::InvalidArgumentsStackLength);
413        }
414
415        self.stack.reverse();
416        while !self.stack.is_empty() {
417            if self.stack.len() < 4 {
418                return Err(CFFError::InvalidArgumentsStackLength);
419            }
420
421            let x1 = self.x;
422            let y1 = self.y + self.stack.pop();
423            let x2 = x1 + self.stack.pop();
424            let y2 = y1 + self.stack.pop();
425            self.x = x2 + self.stack.pop();
426            self.y = y2;
427            if self.stack.len() == 1 {
428                self.y += self.stack.pop();
429            }
430            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
431            if self.stack.is_empty() {
432                break;
433            }
434
435            if self.stack.len() < 4 {
436                return Err(CFFError::InvalidArgumentsStackLength);
437            }
438
439            let x1 = self.x + self.stack.pop();
440            let y1 = self.y;
441            let x2 = x1 + self.stack.pop();
442            let y2 = y1 + self.stack.pop();
443            self.y = y2 + self.stack.pop();
444            self.x = x2;
445            if self.stack.len() == 1 {
446                self.x += self.stack.pop();
447            }
448            self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
449        }
450
451        debug_assert!(self.stack.is_empty());
452        Ok(())
453    }
454
455    #[inline]
456    pub fn parse_flex(&mut self) -> Result<(), CFFError> {
457        // dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd
458
459        if !self.has_move_to {
460            return Err(CFFError::MissingMoveTo);
461        }
462
463        if self.stack.len() != 13 {
464            return Err(CFFError::InvalidArgumentsStackLength);
465        }
466
467        let dx1 = self.x + self.stack.at(0);
468        let dy1 = self.y + self.stack.at(1);
469        let dx2 = dx1 + self.stack.at(2);
470        let dy2 = dy1 + self.stack.at(3);
471        let dx3 = dx2 + self.stack.at(4);
472        let dy3 = dy2 + self.stack.at(5);
473        let dx4 = dx3 + self.stack.at(6);
474        let dy4 = dy3 + self.stack.at(7);
475        let dx5 = dx4 + self.stack.at(8);
476        let dy5 = dy4 + self.stack.at(9);
477        self.x = dx5 + self.stack.at(10);
478        self.y = dy5 + self.stack.at(11);
479        self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
480        self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
481
482        self.stack.clear();
483        Ok(())
484    }
485
486    #[inline]
487    pub fn parse_flex1(&mut self) -> Result<(), CFFError> {
488        // dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6
489
490        if !self.has_move_to {
491            return Err(CFFError::MissingMoveTo);
492        }
493
494        if self.stack.len() != 11 {
495            return Err(CFFError::InvalidArgumentsStackLength);
496        }
497
498        let dx1 = self.x + self.stack.at(0);
499        let dy1 = self.y + self.stack.at(1);
500        let dx2 = dx1 + self.stack.at(2);
501        let dy2 = dy1 + self.stack.at(3);
502        let dx3 = dx2 + self.stack.at(4);
503        let dy3 = dy2 + self.stack.at(5);
504        let dx4 = dx3 + self.stack.at(6);
505        let dy4 = dy3 + self.stack.at(7);
506        let dx5 = dx4 + self.stack.at(8);
507        let dy5 = dy4 + self.stack.at(9);
508
509        if f32_abs(dx5 - self.x) > f32_abs(dy5 - self.y) {
510            self.x = dx5 + self.stack.at(10);
511        } else {
512            self.y = dy5 + self.stack.at(10);
513        }
514
515        self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
516        self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
517
518        self.stack.clear();
519        Ok(())
520    }
521
522    #[inline]
523    pub fn parse_hflex(&mut self) -> Result<(), CFFError> {
524        // dx1 dx2 dy2 dx3 dx4 dx5 dx6
525
526        if !self.has_move_to {
527            return Err(CFFError::MissingMoveTo);
528        }
529
530        if self.stack.len() != 7 {
531            return Err(CFFError::InvalidArgumentsStackLength);
532        }
533
534        let dx1 = self.x + self.stack.at(0);
535        let dy1 = self.y;
536        let dx2 = dx1 + self.stack.at(1);
537        let dy2 = dy1 + self.stack.at(2);
538        let dx3 = dx2 + self.stack.at(3);
539        let dy3 = dy2;
540        let dx4 = dx3 + self.stack.at(4);
541        let dy4 = dy2;
542        let dx5 = dx4 + self.stack.at(5);
543        let dy5 = self.y;
544        self.x = dx5 + self.stack.at(6);
545        self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
546        self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
547
548        self.stack.clear();
549        Ok(())
550    }
551
552    #[inline]
553    pub fn parse_hflex1(&mut self) -> Result<(), CFFError> {
554        // dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6
555
556        if !self.has_move_to {
557            return Err(CFFError::MissingMoveTo);
558        }
559
560        if self.stack.len() != 9 {
561            return Err(CFFError::InvalidArgumentsStackLength);
562        }
563
564        let dx1 = self.x + self.stack.at(0);
565        let dy1 = self.y + self.stack.at(1);
566        let dx2 = dx1 + self.stack.at(2);
567        let dy2 = dy1 + self.stack.at(3);
568        let dx3 = dx2 + self.stack.at(4);
569        let dy3 = dy2;
570        let dx4 = dx3 + self.stack.at(5);
571        let dy4 = dy2;
572        let dx5 = dx4 + self.stack.at(6);
573        let dy5 = dy4 + self.stack.at(7);
574        self.x = dx5 + self.stack.at(8);
575        self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
576        self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
577
578        self.stack.clear();
579        Ok(())
580    }
581
582    #[inline]
583    pub fn parse_int1(&mut self, op: u8) -> Result<(), CFFError> {
584        let n = i16::from(op) - 139;
585        self.stack.push(f32::from(n))?;
586        Ok(())
587    }
588
589    #[inline]
590    pub fn parse_int2(&mut self, op: u8, s: &mut Stream) -> Result<(), CFFError> {
591        let b1 = s.read::<u8>().ok_or(CFFError::ReadOutOfBounds)?;
592        let n = (i16::from(op) - 247) * 256 + i16::from(b1) + 108;
593        debug_assert!((108..=1131).contains(&n));
594        self.stack.push(f32::from(n))?;
595        Ok(())
596    }
597
598    #[inline]
599    pub fn parse_int3(&mut self, op: u8, s: &mut Stream) -> Result<(), CFFError> {
600        let b1 = s.read::<u8>().ok_or(CFFError::ReadOutOfBounds)?;
601        let n = -(i16::from(op) - 251) * 256 - i16::from(b1) - 108;
602        debug_assert!((-1131..=-108).contains(&n));
603        self.stack.push(f32::from(n))?;
604        Ok(())
605    }
606
607    #[inline]
608    pub fn parse_fixed(&mut self, s: &mut Stream) -> Result<(), CFFError> {
609        let n = s.read::<Fixed>().ok_or(CFFError::ReadOutOfBounds)?;
610        self.stack.push(n.0)?;
611        Ok(())
612    }
613}