ttf_parser/tables/cff/
charstring.rs

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