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}
614