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}
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;
373 if self.stack.len() == 1 {
374 self.x += self.stack.pop();
375 }
376 self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
377 if self.stack.is_empty() {
378 break;
379 }
380
381 if self.stack.len() < 4 {
382 return Err(CFFError::InvalidArgumentsStackLength);
383 }
384
385 let x1 = self.x;
386 let y1 = self.y + self.stack.pop();
387 let x2 = x1 + self.stack.pop();
388 let y2 = y1 + self.stack.pop();
389 self.x = x2 + self.stack.pop();
390 self.y = y2;
391 if self.stack.len() == 1 {
392 self.y += self.stack.pop()
393 }
394 self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
395 }
396
397 debug_assert!(self.stack.is_empty());
398 Ok(())
399 }
400
401 #[inline]
402 pub fn parse_vh_curve_to(&mut self) -> Result<(), CFFError> {
403 // dy1 dx2 dy2 dx3 {dxa dxb dyb dyc dyd dxe dye dxf}* dyf?
404 // {dya dxb dyb dxc dxd dxe dye dyf}+ dxf?
405
406 if !self.has_move_to {
407 return Err(CFFError::MissingMoveTo);
408 }
409
410 if self.stack.len() < 4 {
411 return Err(CFFError::InvalidArgumentsStackLength);
412 }
413
414 self.stack.reverse();
415 while !self.stack.is_empty() {
416 if self.stack.len() < 4 {
417 return Err(CFFError::InvalidArgumentsStackLength);
418 }
419
420 let x1 = self.x;
421 let y1 = self.y + self.stack.pop();
422 let x2 = x1 + self.stack.pop();
423 let y2 = y1 + self.stack.pop();
424 self.x = x2 + self.stack.pop();
425 self.y = y2;
426 if self.stack.len() == 1 {
427 self.y += self.stack.pop();
428 }
429 self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
430 if self.stack.is_empty() {
431 break;
432 }
433
434 if self.stack.len() < 4 {
435 return Err(CFFError::InvalidArgumentsStackLength);
436 }
437
438 let x1 = self.x + self.stack.pop();
439 let y1 = self.y;
440 let x2 = x1 + self.stack.pop();
441 let y2 = y1 + self.stack.pop();
442 self.y = y2 + self.stack.pop();
443 self.x = x2;
444 if self.stack.len() == 1 {
445 self.x += self.stack.pop();
446 }
447 self.builder.curve_to(x1, y1, x2, y2, self.x, self.y);
448 }
449
450 debug_assert!(self.stack.is_empty());
451 Ok(())
452 }
453
454 #[inline]
455 pub fn parse_flex(&mut self) -> Result<(), CFFError> {
456 // dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd
457
458 if !self.has_move_to {
459 return Err(CFFError::MissingMoveTo);
460 }
461
462 if self.stack.len() != 13 {
463 return Err(CFFError::InvalidArgumentsStackLength);
464 }
465
466 let dx1 = self.x + self.stack.at(0);
467 let dy1 = self.y + self.stack.at(1);
468 let dx2 = dx1 + self.stack.at(2);
469 let dy2 = dy1 + self.stack.at(3);
470 let dx3 = dx2 + self.stack.at(4);
471 let dy3 = dy2 + self.stack.at(5);
472 let dx4 = dx3 + self.stack.at(6);
473 let dy4 = dy3 + self.stack.at(7);
474 let dx5 = dx4 + self.stack.at(8);
475 let dy5 = dy4 + self.stack.at(9);
476 self.x = dx5 + self.stack.at(10);
477 self.y = dy5 + self.stack.at(11);
478 self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
479 self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
480
481 self.stack.clear();
482 Ok(())
483 }
484
485 #[inline]
486 pub fn parse_flex1(&mut self) -> Result<(), CFFError> {
487 // dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6
488
489 if !self.has_move_to {
490 return Err(CFFError::MissingMoveTo);
491 }
492
493 if self.stack.len() != 11 {
494 return Err(CFFError::InvalidArgumentsStackLength);
495 }
496
497 let dx1 = self.x + self.stack.at(0);
498 let dy1 = self.y + self.stack.at(1);
499 let dx2 = dx1 + self.stack.at(2);
500 let dy2 = dy1 + self.stack.at(3);
501 let dx3 = dx2 + self.stack.at(4);
502 let dy3 = dy2 + self.stack.at(5);
503 let dx4 = dx3 + self.stack.at(6);
504 let dy4 = dy3 + self.stack.at(7);
505 let dx5 = dx4 + self.stack.at(8);
506 let dy5 = dy4 + self.stack.at(9);
507
508 if f32_abs(dx5 - self.x) > f32_abs(dy5 - self.y) {
509 self.x = dx5 + self.stack.at(10);
510 } else {
511 self.y = dy5 + self.stack.at(10);
512 }
513
514 self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
515 self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
516
517 self.stack.clear();
518 Ok(())
519 }
520
521 #[inline]
522 pub fn parse_hflex(&mut self) -> Result<(), CFFError> {
523 // dx1 dx2 dy2 dx3 dx4 dx5 dx6
524
525 if !self.has_move_to {
526 return Err(CFFError::MissingMoveTo);
527 }
528
529 if self.stack.len() != 7 {
530 return Err(CFFError::InvalidArgumentsStackLength);
531 }
532
533 let dx1 = self.x + self.stack.at(0);
534 let dy1 = self.y;
535 let dx2 = dx1 + self.stack.at(1);
536 let dy2 = dy1 + self.stack.at(2);
537 let dx3 = dx2 + self.stack.at(3);
538 let dy3 = dy2;
539 let dx4 = dx3 + self.stack.at(4);
540 let dy4 = dy2;
541 let dx5 = dx4 + self.stack.at(5);
542 let dy5 = self.y;
543 self.x = dx5 + self.stack.at(6);
544 self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
545 self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
546
547 self.stack.clear();
548 Ok(())
549 }
550
551 #[inline]
552 pub fn parse_hflex1(&mut self) -> Result<(), CFFError> {
553 // dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6
554
555 if !self.has_move_to {
556 return Err(CFFError::MissingMoveTo);
557 }
558
559 if self.stack.len() != 9 {
560 return Err(CFFError::InvalidArgumentsStackLength);
561 }
562
563 let dx1 = self.x + self.stack.at(0);
564 let dy1 = self.y + self.stack.at(1);
565 let dx2 = dx1 + self.stack.at(2);
566 let dy2 = dy1 + self.stack.at(3);
567 let dx3 = dx2 + self.stack.at(4);
568 let dy3 = dy2;
569 let dx4 = dx3 + self.stack.at(5);
570 let dy4 = dy2;
571 let dx5 = dx4 + self.stack.at(6);
572 let dy5 = dy4 + self.stack.at(7);
573 self.x = dx5 + self.stack.at(8);
574 self.builder.curve_to(dx1, dy1, dx2, dy2, dx3, dy3);
575 self.builder.curve_to(dx4, dy4, dx5, dy5, self.x, self.y);
576
577 self.stack.clear();
578 Ok(())
579 }
580
581 #[inline]
582 pub fn parse_int1(&mut self, op: u8) -> Result<(), CFFError> {
583 let n = i16::from(op) - 139;
584 self.stack.push(f32::from(n))?;
585 Ok(())
586 }
587
588 #[inline]
589 pub fn parse_int2(&mut self, op: u8, s: &mut Stream) -> Result<(), CFFError> {
590 let b1 = s.read::<u8>().ok_or(CFFError::ReadOutOfBounds)?;
591 let n = (i16::from(op) - 247) * 256 + i16::from(b1) + 108;
592 debug_assert!((108..=1131).contains(&n));
593 self.stack.push(f32::from(n))?;
594 Ok(())
595 }
596
597 #[inline]
598 pub fn parse_int3(&mut self, op: u8, s: &mut Stream) -> Result<(), CFFError> {
599 let b1 = s.read::<u8>().ok_or(CFFError::ReadOutOfBounds)?;
600 let n = -(i16::from(op) - 251) * 256 - i16::from(b1) - 108;
601 debug_assert!((-1131..=-108).contains(&n));
602 self.stack.push(f32::from(n))?;
603 Ok(())
604 }
605
606 #[inline]
607 pub fn parse_fixed(&mut self, s: &mut Stream) -> Result<(), CFFError> {
608 let n = s.read::<Fixed>().ok_or(CFFError::ReadOutOfBounds)?;
609 self.stack.push(n.0)?;
610 Ok(())
611 }
612}
613