1use alloc::vec;
35use alloc::vec::Vec;
36
37use rt::fx::{cvtt, cvttd, sqrt};
38
39use crate::outline::{Outline, OLT_CUBIC, OLT_ON};
40use crate::ttf::{Tb, ERR_HDR, ERR_UNSUPPORTED};
41use crate::var;
42
43const FD_MAX: u32 = 256;
44const CS_STACK: usize = 48;
45const CS2_STACK: usize = 513; const CS2_DEFSTACK: i64 = 193; const CS2_REGIONS: usize = 512; const DICT2_STACK: usize = 513; const CS_DEPTH: u32 = 10;
50const CS_BUDGET: i32 = 200_000;
51const OPS_MAX: usize = 48; const F_INV65536: f32 = 0.000_015_258_789_062_5;
53const F_INV8M: f32 = 0.000_000_119_209_29; const F_EPS: f32 = 0.000_001;
55
56#[derive(Clone, Copy, Default)]
58struct Index {
59 count: u32,
60 offsize: u32,
61 offs: u32,
62 data: u32,
63}
64
65pub struct Cff {
66 v2: bool,
68 cid: bool, cs: Index,
70 gs: Index,
71 ls: Index,
72 fdsel: u32, nfd: u32,
74 mat: [f32; 6],
75 hasmat: bool,
76 fdls: Vec<Index>,
77 fdvs: Vec<u16>,
79 vstore: u32,
81 maxstack: u32,
83}
84
85fn c8(t: Tb, off: u32) -> i32 {
88 t.u8(off)
89}
90
91fn c16(t: Tb, off: u32) -> i32 {
92 t.u16(off)
93}
94
95fn c_off(t: Tb, off: u32, size: u32) -> i64 {
97 if off as u64 + size as u64 > t.0.len() as u64 {
98 return -1;
99 }
100 let mut v = 0u32;
101 for i in 0..size {
102 v = (v << 8) | t.0[(off + i) as usize] as u32;
103 }
104 v as i64
105}
106
107fn ix_parse(t: Tb, pos: u32, ix: &mut Index) -> i64 {
111 let count = c16(t, pos);
112 if count < 0 {
113 ix.count = 0;
114 return -1;
115 }
116 ix.count = count as u32;
117 if count == 0 {
118 ix.offsize = 1;
119 ix.offs = pos.wrapping_add(2);
120 ix.data = ix.offs;
121 return ix.offs as i64;
122 }
123 let os = c8(t, pos.wrapping_add(2));
124 if !(1..=4).contains(&os) {
125 ix.count = 0;
126 return -1;
127 }
128 let os = os as u32;
129 ix.offsize = os;
130 ix.offs = pos.wrapping_add(3);
131 ix.data = ix.offs.wrapping_add((count as u32 + 1).wrapping_mul(os));
132 let last = c_off(t, (count as u32).wrapping_mul(os).wrapping_add(ix.offs), os);
134 if last <= 0 {
135 ix.count = 0;
136 return -1;
137 }
138 let end = ix.data as u64 + last as u64 - 1;
139 if end > t.0.len() as u64 {
140 ix.count = 0;
141 return -1;
142 }
143 end as u32 as i64
144}
145
146fn ix_get(t: Tb, ix: &Index, i: u32) -> Option<(u32, u32)> {
148 if i >= ix.count {
149 return None;
150 }
151 let a = c_off(t, i.wrapping_mul(ix.offsize).wrapping_add(ix.offs), ix.offsize);
152 if a <= 0 {
153 return None;
154 }
155 let b = c_off(t, (i + 1).wrapping_mul(ix.offsize).wrapping_add(ix.offs), ix.offsize);
156 if b <= 0 || b < a {
157 return None;
158 }
159 let len = (b - a) as u64;
160 let start = ix.data as u64 + a as u64 - 1;
161 if start + len > t.0.len() as u64 {
162 return None;
163 }
164 if start as u32 as i32 >= 0 { Some((start as u32, len as u32)) } else { None }
165}
166
167fn ix2_parse(t: Tb, pos: u32, ix: &mut Index) -> i64 {
170 ix.count = 0;
171 let count = c_off(t, pos, 4);
172 if count < 0 {
173 return -1;
174 }
175 let base = pos as u64 + 4; if count == 0 {
177 ix.offsize = 1;
178 ix.offs = base as u32;
179 ix.data = base as u32;
180 return base as i64;
181 }
182 let os = c8(t, base as u32);
183 if !(1..=4).contains(&os) {
184 return -1;
185 }
186 let os = os as u64;
187 let offs = base + 1;
188 let data = offs + (count as u64 + 1) * os;
189 if data > t.len() as u64 {
190 return -1;
191 }
192 let last = c_off(t, (offs + count as u64 * os) as u32, os as u32);
193 if last <= 0 {
194 return -1;
195 }
196 let end = data + last as u64 - 1;
197 if end > t.len() as u64 {
198 return -1;
199 }
200 ix.count = count as u32;
201 ix.offsize = os as u32;
202 ix.offs = offs as u32;
203 ix.data = data as u32;
204 end as i64
205}
206
207fn dict2_walk(t: Tb, start: u32, end: u32, regions: &dyn Fn(u32) -> Option<u32>, f: &mut dyn FnMut(u32, &[f64])) -> bool {
214 let mut st: Vec<f64> = Vec::new();
215 let mut vsi = 0u32;
216 let mut p = start;
217 while p < end {
218 let b = c8(t, p);
219 if b < 0 {
220 return false;
221 }
222 let v: f64;
223 if b <= 27 {
224 p += 1;
225 let mut o = b as u32;
226 if o == 12 {
227 let b2 = c8(t, p);
228 if b2 < 0 {
229 return false;
230 }
231 p += 1;
232 o = 1200 + b2 as u32;
233 }
234 if o == 23 {
235 let Some(nv) = st.pop() else { return false };
237 let n = cvttd(nv);
238 let Some(k) = regions(vsi) else { return false };
239 if n < 0 {
240 return false;
241 }
242 let need = n as u64 * (k as u64 + 1);
243 if need > st.len() as u64 {
244 return false;
245 }
246 let keep = st.len() - need as usize + n as usize;
247 st.truncate(keep);
248 continue;
249 }
250 if o == 22 {
251 match st.last().map(|&x| cvttd(x)) {
252 Some(i) if i >= 0 => vsi = i as u32,
253 _ => {}
254 }
255 }
256 f(o, &st);
257 st.clear();
258 continue;
259 } else if b == 28 {
260 let w = c16(t, p.wrapping_add(1));
261 if w < 0 {
262 return false;
263 }
264 v = (w as u16 as i16) as f64;
265 p += 3;
266 } else if b == 29 {
267 let w = c_off(t, p.wrapping_add(1), 4);
268 if w < 0 {
269 return false;
270 }
271 v = (w as u32 as i32) as f64;
272 p += 5;
273 } else if b == 30 {
274 p += 1;
275 v = dict_real(t, &mut p);
276 } else if b == 31 || b == 255 {
277 p += 1; st.clear();
279 continue;
280 } else if b <= 246 {
281 v = (b - 139) as f64;
282 p += 1;
283 } else {
284 let b2 = c8(t, p.wrapping_add(1));
285 if b2 < 0 {
286 return false;
287 }
288 p += 2;
289 v = if b <= 250 { ((b - 247) * 256 + b2 + 108) as f64 } else { (-((b - 251) * 256 + b2 + 108)) as f64 };
290 }
291 if st.len() >= DICT2_STACK {
292 return false;
293 }
294 st.push(v);
295 }
296 true
297}
298
299fn dict2_find(t: Tb, start: u32, end: u32, op: u32, regions: &dyn Fn(u32) -> Option<u32>, ops: &mut [f64; OPS_MAX]) -> i32 {
302 let mut found = -1i32;
303 dict2_walk(t, start, end, regions, &mut |o, a| {
304 if found < 0 && o == op {
305 let a = &a[a.len().saturating_sub(OPS_MAX)..];
306 ops[..a.len()].copy_from_slice(a);
307 found = a.len() as i32;
308 }
309 });
310 found
311}
312
313fn cf2_private(t: Tb, start: u32, end: u32, vstore: u32, ix: &mut Index, ops: &mut [f64; OPS_MAX]) -> u16 {
316 ix.count = 0;
317 let n = dict2_find(t, start, end, 18, &|_| None, ops);
318 if n < 2 {
319 return 0;
320 }
321 let size = cvttd(ops[n as usize - 2]);
322 let off = cvttd(ops[n as usize - 1]);
323 if size <= 0 || off <= 0 || off as u32 >= t.len() {
324 return 0;
325 }
326 let off = off as u32;
327 let e = off.saturating_add(size as u32).min(t.len());
328 let regions = |vsi: u32| if vstore == 0 { None } else { var::ivs_region_count(t, vstore, vsi) };
329 let (mut subrs, mut vsi) = (None, 0u16);
330 dict2_walk(t, off, e, ®ions, &mut |o, a| {
331 let last = a.last().map(|&v| cvttd(v));
332 match (o, last) {
333 (19, Some(s)) if subrs.is_none() => subrs = Some(s),
334 (22, Some(v)) if (0..=0xFFFF).contains(&v) => vsi = v as u16,
335 _ => {}
336 }
337 });
338 if let Some(s) = subrs
339 && s > 0
340 && let Some(pos) = (s as u32).checked_add(off)
341 {
342 ix2_parse(t, pos, ix); }
344 vsi
345}
346
347fn dict_find(t: Tb, start: u32, end: u32, op: u32, ops: &mut [f64; OPS_MAX]) -> i32 {
352 let mut p = start;
353 let mut n = 0usize;
354 while p < end {
355 let b = c8(t, p);
356 if b < 0 {
357 return -1;
358 }
359 let v: f64;
360 if b <= 21 {
361 p += 1;
362 let mut o = b as u32;
363 if o == 12 {
364 let b2 = c8(t, p);
365 if b2 < 0 {
366 return -1;
367 }
368 p += 1;
369 o = 1200 + b2 as u32;
370 }
371 if o == op {
372 return n as i32;
373 }
374 n = 0;
375 continue;
376 } else if b == 28 {
377 let w = c16(t, p.wrapping_add(1));
378 if w < 0 {
379 return -1;
380 }
381 v = (w as u16 as i16) as f64;
382 p = p.wrapping_add(3);
383 } else if b == 29 {
384 let w = c_off(t, p.wrapping_add(1), 4);
385 if w < 0 {
386 return -1;
387 }
388 v = (w as u32 as i32) as f64;
389 p = p.wrapping_add(5);
390 } else if b == 30 {
391 p += 1;
392 v = dict_real(t, &mut p);
393 } else if b < 32 {
394 p += 1;
395 n = 0;
396 continue;
397 } else if b <= 246 {
398 v = (b - 139) as f64;
399 p += 1;
400 } else if b <= 254 {
401 let b2 = c8(t, p.wrapping_add(1));
402 if b2 < 0 {
403 return -1;
404 }
405 p = p.wrapping_add(2);
406 v = if b <= 250 {
407 ((b - 247) * 256 + b2 + 108) as f64
408 } else {
409 (-((b - 251) * 256 + b2 + 108)) as f64
410 };
411 } else {
412 p += 1;
413 n = 0;
414 continue;
415 }
416 if n < OPS_MAX {
417 ops[n] = v;
418 n += 1;
419 }
420 }
421 -1
422}
423
424fn dict_real(t: Tb, p: &mut u32) -> f64 {
426 let mut m = 0u64; let mut digits = 0i32; let mut fl = 0u32; let mut exp = 0i32;
430 'bytes: while (*p as usize) < t.0.len() {
431 let b = t.0[*p as usize] as u32;
432 *p += 1;
433 for nib in [b >> 4, b & 15] {
434 if nib <= 9 {
435 if fl & 4 != 0 {
436 if (exp as u32) < 1000 {
437 exp = exp * 10 + nib as i32;
438 }
439 } else if m >= 100_000_000_000_000_000 {
440 if fl & 2 == 0 {
441 digits -= 1; }
443 } else {
444 m = m * 10 + nib as u64;
445 if fl & 2 != 0 {
446 digits += 1;
447 }
448 }
449 continue;
450 }
451 match nib {
452 0xA => fl |= 2,
453 0xB => fl |= 4,
454 0xC => fl |= 4 | 8,
455 0xE => fl |= 1,
456 0xF => break 'bytes,
457 _ => {}
458 }
459 }
460 }
461 let mut v = m as i64 as f64;
463 if fl & 8 != 0 {
464 exp = exp.wrapping_neg();
465 }
466 let e = exp.wrapping_sub(digits);
467 if e > 0 {
468 if e as u32 > 400 {
469 return 0.0;
470 }
471 for _ in 0..e {
472 v = v * 10.0;
473 }
474 } else if e < 0 {
475 let mut c = e.wrapping_neg() as u32;
476 loop {
477 v = v / 10.0;
478 c -= 1;
479 if c == 0 {
480 break;
481 }
482 if c > 400 {
483 return 0.0;
484 }
485 }
486 }
487 if fl & 1 != 0 {
488 v = 0.0 - v;
489 }
490 v
491}
492
493fn cf_private(t: Tb, start: u32, end: u32, ix: &mut Index, ops: &mut [f64; OPS_MAX]) {
495 ix.count = 0;
496 let n = dict_find(t, start, end, 18, ops);
497 if n < 2 {
498 return;
499 }
500 let size = rt::fx::cvttd(ops[n as usize - 2]);
501 let off = rt::fx::cvttd(ops[n as usize - 1]);
502 if size <= 0 || off <= 0 || off as u32 >= t.len() {
503 return;
504 }
505 let off = off as u32;
506 let e = off.wrapping_add(size as u32).min(t.len());
507 let n = dict_find(t, off, e, 19, ops); if n < 1 {
509 return;
510 }
511 let s = rt::fx::cvttd(ops[n as usize - 1]);
512 if s <= 0 {
513 return;
514 }
515 let (pos, carry) = (s as u32).overflowing_add(off);
516 if carry {
517 return;
518 }
519 ix_parse(t, pos, ix);
520}
521
522impl Cff {
523 fn empty(v2: bool) -> Cff {
524 Cff {
525 v2,
526 cid: false,
527 cs: Index::default(),
528 gs: Index::default(),
529 ls: Index::default(),
530 fdsel: 0,
531 nfd: 0,
532 mat: [0.0; 6],
533 hasmat: false,
534 fdls: Vec::new(),
535 fdvs: Vec::new(),
536 vstore: 0,
537 maxstack: CS2_DEFSTACK as u32,
538 }
539 }
540
541 pub fn is_v2(&self) -> bool {
543 self.v2
544 }
545
546 pub fn varies(&self) -> bool {
548 self.v2 && self.vstore != 0
549 }
550
551 fn set_matrix(&mut self, m: &[f64], upem: u32) {
553 let u = upem as i32 as f64;
554 for (i, &v) in m.iter().take(6).enumerate() {
555 self.mat[i] = (v * u) as f32;
556 }
557 let abs = |v: f32| f32::from_bits(v.to_bits() & 0x7FFF_FFFF);
558 if abs(self.mat[0] - 1.0) > F_EPS || abs(self.mat[3] - 1.0) > F_EPS {
559 self.hasmat = true;
560 } else {
561 for i in [1, 2, 4, 5] {
562 if abs(self.mat[i]) > F_EPS {
563 self.hasmat = true;
564 break;
565 }
566 }
567 }
568 }
569
570 pub fn open(t: Tb, upem: u32) -> Result<Cff, i32> {
572 let mut ops = [0f64; OPS_MAX];
573 let mut c = Cff::empty(false);
574 if c8(t, 0) != 1 {
575 return Err(ERR_UNSUPPORTED);
576 }
577 let hs = c8(t, 2);
578 if hs < 0 {
579 return Err(ERR_HDR);
580 }
581 let mut top = Index::default();
583 let mut strs = Index::default();
584 let p = ix_parse(t, hs as u32, &mut top); if p < 0 {
586 return Err(ERR_HDR);
587 }
588 let p = ix_parse(t, p as u32, &mut top);
589 if p < 0 {
590 return Err(ERR_HDR);
591 }
592 let p = ix_parse(t, p as u32, &mut strs);
593 if p < 0 {
594 return Err(ERR_HDR);
595 }
596 if ix_parse(t, p as u32, &mut c.gs) < 0 {
597 return Err(ERR_HDR);
598 }
599 let Some((ds, dl)) = ix_get(t, &top, 0) else { return Err(ERR_HDR) };
600 let de = ds.wrapping_add(dl);
601 let n = dict_find(t, ds, de, 1206, &mut ops);
603 if n >= 1 && rt::fx::cvttd(ops[0]) != 2 {
604 return Err(ERR_UNSUPPORTED);
605 }
606 let n = dict_find(t, ds, de, 17, &mut ops);
608 if n < 1 {
609 return Err(ERR_HDR);
610 }
611 let o = rt::fx::cvttd(ops[n as usize - 1]);
612 if o <= 0 || ix_parse(t, o as u32, &mut c.cs) < 0 || c.cs.count == 0 {
613 return Err(ERR_HDR);
614 }
615 let n = dict_find(t, ds, de, 1207, &mut ops);
617 if n >= 6 {
618 let m = ops;
619 c.set_matrix(&m[..6], upem);
620 }
621 if dict_find(t, ds, de, 1230, &mut ops) >= 0 {
623 c.cid = true;
624 let n = dict_find(t, ds, de, 1236, &mut ops); if n < 1 {
626 return Err(ERR_HDR);
627 }
628 let o = rt::fx::cvttd(ops[n as usize - 1]);
629 if o <= 0 {
630 return Err(ERR_HDR);
631 }
632 let mut fda = Index::default();
633 if ix_parse(t, o as u32, &mut fda) < 0 {
634 return Err(ERR_HDR);
635 }
636 c.nfd = fda.count.min(FD_MAX);
637 let n = dict_find(t, ds, de, 1237, &mut ops); if n < 1 {
639 return Err(ERR_HDR);
640 }
641 let o = rt::fx::cvttd(ops[n as usize - 1]);
642 if o <= 0 || o as u32 >= t.len() {
643 return Err(ERR_HDR);
644 }
645 c.fdsel = o as u32;
646 c.fdls = vec![Index::default(); c.nfd as usize];
648 for fd in 0..c.nfd {
649 if let Some((s, l)) = ix_get(t, &fda, fd) {
650 cf_private(t, s, s.wrapping_add(l), &mut c.fdls[fd as usize], &mut ops);
651 }
652 }
653 } else {
654 cf_private(t, ds, de, &mut c.ls, &mut ops);
655 }
656 Ok(c)
657 }
658
659 pub fn open2(t: Tb, upem: u32) -> Result<Cff, i32> {
661 let mut ops = [0f64; OPS_MAX];
662 let mut c = Cff::empty(true);
663 if c8(t, 0) != 2 {
664 return Err(ERR_UNSUPPORTED);
665 }
666 let hs = c8(t, 2);
668 let tdl = c16(t, 3);
669 if hs < 5 || tdl < 0 {
670 return Err(ERR_HDR);
671 }
672 let ds = hs as u32;
673 let de = ds + tdl as u32;
674 if de > t.len() {
675 return Err(ERR_HDR);
676 }
677 let (mut cso, mut fda, mut fds, mut vst, mut maxst) = (None, None, None, None, None);
679 let mut mat: Option<[f64; 6]> = None;
680 dict2_walk(t, ds, de, &|_| None, &mut |op, a| {
681 let last = a.last().map(|&v| cvttd(v) as i64);
682 let slot = match op {
683 17 => &mut cso,
684 1236 => &mut fda,
685 1237 => &mut fds,
686 24 => &mut vst,
687 25 => &mut maxst,
688 1207 => {
689 if mat.is_none() && a.len() >= 6 {
690 mat = Some([a[0], a[1], a[2], a[3], a[4], a[5]]);
691 }
692 return;
693 }
694 _ => return,
695 };
696 if slot.is_none() {
697 *slot = last;
698 }
699 });
700 let len = t.len() as i64;
701 let pos = |o: Option<i64>| o.filter(|&o| o > 0 && o < len).map(|o| o as u32);
702 if ix2_parse(t, de, &mut c.gs) < 0 {
704 return Err(ERR_HDR);
705 }
706 match pos(cso) {
707 Some(o) if ix2_parse(t, o, &mut c.cs) >= 0 && c.cs.count != 0 => {}
708 _ => return Err(ERR_HDR),
709 }
710 if let Some(m) = mat {
711 c.set_matrix(&m, upem);
712 }
713 c.maxstack = maxst.unwrap_or(CS2_DEFSTACK).clamp(CS2_DEFSTACK, CS2_STACK as i64) as u32;
714 if let Some(o) = pos(vst)
716 && o as u64 + 2 < t.len() as u64
717 {
718 c.vstore = o + 2;
719 }
720 let mut fdix = Index::default();
722 match pos(fda) {
723 Some(o) if ix2_parse(t, o, &mut fdix) >= 0 && fdix.count != 0 => {}
724 _ => return Err(ERR_HDR),
725 }
726 c.cid = true;
727 c.nfd = fdix.count.min(FD_MAX);
728 c.fdsel = pos(fds).unwrap_or(0);
729 c.fdls = vec![Index::default(); c.nfd as usize];
730 c.fdvs = vec![0; c.nfd as usize];
731 for fd in 0..c.nfd as usize {
732 if let Some((s, l)) = ix_get(t, &fdix, fd as u32) {
733 c.fdvs[fd] = cf2_private(t, s, s.wrapping_add(l), c.vstore, &mut c.fdls[fd], &mut ops);
734 }
735 }
736 Ok(c)
737 }
738
739 fn fdselect(&self, t: Tb, glyph: u32) -> i32 {
741 let fs = self.fdsel;
742 if fs == 0 {
743 return 0; }
745 match c8(t, fs) {
746 0 => c8(t, fs.wrapping_add(glyph).wrapping_add(1)),
747 3 => {
748 let n = c16(t, fs.wrapping_add(1));
749 if n <= 0 {
750 return -1;
751 }
752 let (mut lo, mut hi) = (0u32, n as u32);
755 while lo < hi {
756 let mid = lo + (hi - lo) / 2;
757 let first = c16(t, mid.wrapping_mul(3).wrapping_add(fs).wrapping_add(3));
758 if first < 0 {
759 return -1;
760 }
761 if first as u32 > glyph {
762 hi = mid;
763 } else {
764 lo = mid + 1;
765 }
766 }
767 if lo == 0 {
768 return -1;
769 }
770 c8(t, (lo - 1).wrapping_mul(3).wrapping_add(fs).wrapping_add(5))
771 }
772 4 if self.v2 => {
773 let n = c_off(t, fs.wrapping_add(1), 4);
775 if n <= 0 {
776 return -1;
777 }
778 let first = |k: u64| -> i64 {
779 let at = fs as u64 + 5 + k * 6;
780 if at + 6 > t.len() as u64 { -1 } else { c_off(t, at as u32, 4) }
781 };
782 let (mut lo, mut hi) = (0u64, n as u64);
783 while lo < hi {
784 let mid = lo + (hi - lo) / 2;
785 let f = first(mid);
786 if f < 0 {
787 return -1;
788 }
789 if f as u64 > glyph as u64 {
790 hi = mid;
791 } else {
792 lo = mid + 1;
793 }
794 }
795 if lo == 0 {
796 return -1;
797 }
798 c16(t, (fs as u64 + 5 + (lo - 1) * 6 + 4) as u32)
799 }
800 _ => -1,
801 }
802 }
803
804 pub fn outline(&self, t: Tb, glyph: u32, ol: &mut Outline) -> bool {
806 self.outline_var(t, glyph, &[], ol)
807 }
808
809 pub fn outline_var(&self, t: Tb, glyph: u32, coords: &[i16], ol: &mut Outline) -> bool {
812 if glyph >= self.cs.count {
813 return true;
814 }
815 let (ls, vsi) = if self.cid {
816 let fd = self.fdselect(t, glyph);
817 if fd as u32 >= self.nfd {
818 return false;
819 }
820 (self.fdls[fd as usize], self.fdvs.get(fd as usize).copied().unwrap_or(0))
821 } else {
822 (self.ls, 0)
823 };
824 let Some((s, l)) = ix_get(t, &self.cs, glyph) else { return false };
825 let mut cs = Cs {
826 t,
827 gs: self.gs,
828 ls,
829 st: [0.0; CS2_STACK],
830 sp: 0,
831 maxst: if self.v2 { self.maxstack as usize } else { CS_STACK },
832 x: 0.0,
833 y: 0.0,
834 px: 0.0,
835 py: 0.0,
836 d: [0.0; 6],
837 nstems: 0,
838 wd: self.v2, open: false,
840 budget: CS_BUDGET,
841 trans: [0.0; 32],
842 rand: 0,
843 v2: self.v2,
844 vstore: self.vstore,
845 vsi: vsi as u32,
846 coords,
847 sc: Vec::new(),
848 nreg: None,
849 blended: false,
850 ol,
851 };
852 if cs.run(s, s.wrapping_add(l), 0) < 0 {
853 return false;
854 }
855 let ol = cs.ol;
856 ol.close();
857 if self.hasmat {
858 let m = self.mat;
860 ol.transform(0, m[0], m[1], m[2], m[3]);
861 ol.translate(0, m[4], m[5]);
862 }
863 true
864 }
865}
866
867fn cs_bias(count: u32) -> i32 {
869 if count < 1240 {
870 107
871 } else if count < 33900 {
872 1131
873 } else {
874 32768
875 }
876}
877
878fn fabs(v: f32) -> f32 {
879 f32::from_bits(v.to_bits() & 0x7FFF_FFFF)
880}
881
882fn zf(a: f32, b: f32) -> bool {
884 !(a < b || a > b)
885}
886
887struct Cs<'a, 'o> {
890 t: Tb<'a>,
891 gs: Index,
892 ls: Index,
893 st: [f32; CS2_STACK],
894 sp: usize,
895 maxst: usize, x: f32,
897 y: f32,
898 px: f32,
899 py: f32,
900 d: [f32; 6],
901 nstems: u32,
902 wd: bool,
903 open: bool,
904 budget: i32,
905 trans: [f32; 32], rand: u32,
907 v2: bool,
908 vstore: u32,
909 vsi: u32,
910 coords: &'a [i16],
911 sc: Vec<f32>,
912 nreg: Option<usize>,
913 blended: bool,
914 ol: &'o mut Outline,
915}
916
917enum Flow {
918 Clear,
919 Loop,
920 Err,
921 Ret1,
922}
923
924impl Cs<'_, '_> {
925 fn arg(&self, i: usize) -> f32 {
927 if i < self.sp { self.st[i] } else { 0.0 }
928 }
929
930 fn point(&mut self, tag: u8) {
932 if !self.open {
933 self.open = true;
935 self.ol.point(self.px, self.py, OLT_ON);
936 }
937 self.ol.point(self.x, self.y, tag);
938 }
939
940 fn line(&mut self, dx: f32, dy: f32) {
941 self.px = self.x;
942 self.py = self.y;
943 self.x = dx + self.x;
944 self.y = dy + self.y;
945 self.point(OLT_ON);
946 }
947
948 fn curve(&mut self) {
950 self.px = self.x;
951 self.py = self.y;
952 for i in 0..3 {
953 self.x = self.d[i * 2] + self.x;
954 self.y = self.d[i * 2 + 1] + self.y;
955 self.point(if i == 2 { OLT_ON } else { OLT_CUBIC });
956 }
957 }
958
959 fn d6(&mut self, i: usize) {
960 for k in 0..6 {
961 self.d[k] = self.arg(i + k);
962 }
963 }
964
965 fn curve6(&mut self, i: usize) {
966 self.d6(i);
967 self.curve();
968 }
969
970 fn width(&mut self, expected: usize) -> usize {
972 if self.wd {
973 return 0;
974 }
975 self.wd = true;
976 (self.sp > expected) as usize
977 }
978
979 fn width_even(&mut self) -> u32 {
981 if self.wd {
982 return 0;
983 }
984 self.wd = true;
985 (self.sp & 1) as u32
986 }
987
988 fn moveto_begin(&mut self) {
989 if self.open {
990 self.ol.close();
991 self.open = false;
992 }
993 }
994
995 fn moveto_end(&mut self) {
996 self.open = true;
997 self.ol.point(self.x, self.y, OLT_ON);
998 }
999
1000 fn push(&mut self, v: f32) -> Flow {
1001 if self.sp >= self.maxst {
1002 return Flow::Err;
1003 }
1004 self.st[self.sp] = v;
1005 self.sp += 1;
1006 Flow::Loop
1007 }
1008
1009 fn top(&self) -> Option<f32> {
1010 if self.sp == 0 { None } else { Some(self.st[self.sp - 1]) }
1011 }
1012
1013 fn settop(&mut self, v: f32) -> Flow {
1014 self.st[self.sp - 1] = v;
1015 Flow::Loop
1016 }
1017
1018 fn pop2(&mut self) -> Option<(f32, f32)> {
1020 if self.sp < 2 {
1021 return None;
1022 }
1023 self.sp -= 2;
1024 Some((self.st[self.sp], self.st[self.sp + 1]))
1025 }
1026
1027 fn roll(&mut self, num: i32, j: i32) {
1029 let mut r = j % num;
1030 if r < 0 {
1031 r += num;
1032 }
1033 let first = self.sp - num as usize;
1034 for _ in 0..r {
1035 let top = self.st[self.sp - 1];
1036 let mut k = self.sp - 1;
1037 while k > first {
1038 self.st[k] = self.st[k - 1];
1039 k -= 1;
1040 }
1041 self.st[first] = top;
1042 }
1043 }
1044
1045 fn blend(&mut self) -> bool {
1049 let Some(nv) = self.top() else { return false };
1050 self.sp -= 1;
1051 let n = cvtt(nv);
1052 if n < 0 {
1053 return false;
1054 }
1055 let k = match self.nreg {
1056 Some(k) => k,
1057 None => {
1058 if var::ivs_scalars(self.t, self.vstore, self.vsi, self.coords, CS2_REGIONS, &mut self.sc).is_none() {
1059 return false;
1060 }
1061 self.nreg = Some(self.sc.len());
1062 self.sc.len()
1063 }
1064 };
1065 let n = n as usize;
1066 let Some(need) = n.checked_mul(k + 1) else { return false };
1067 if need > self.sp {
1068 return false;
1069 }
1070 let base = self.sp - need;
1071 for i in 0..n {
1072 let mut v = self.st[base + i];
1073 let d = base + n + i * k;
1074 for (r, &s) in self.sc[..k].iter().enumerate() {
1075 if s != 0.0 {
1076 v = v + self.st[d + r] * s;
1077 }
1078 }
1079 self.st[base + i] = v;
1080 }
1081 self.sp = base + n;
1082 self.blended = true;
1083 true
1084 }
1085
1086 fn run(&mut self, start: u32, end: u32, depth: u32) -> i32 {
1088 if depth > CS_DEPTH {
1089 return -1;
1090 }
1091 let t = self.t;
1092 let mut p = start;
1093 loop {
1094 if p >= end {
1095 return 0;
1096 }
1097 self.budget -= 1;
1098 if self.budget < 0 {
1099 return -1;
1100 }
1101 let b = t.0[p as usize] as u32;
1102 p += 1;
1103 let flow = if b >= 32 || b == 28 {
1104 let v: f32;
1106 if b == 28 {
1107 if p + 2 > end {
1108 return -1;
1109 }
1110 v = (u16::from_be_bytes([t.0[p as usize], t.0[p as usize + 1]]) as i16) as f32;
1111 p += 2;
1112 } else if b <= 246 {
1113 v = (b as i32 - 139) as f32;
1114 } else if b == 255 {
1115 if p + 4 > end {
1116 return -1;
1117 }
1118 let w = u32::from_be_bytes([
1119 t.0[p as usize],
1120 t.0[p as usize + 1],
1121 t.0[p as usize + 2],
1122 t.0[p as usize + 3],
1123 ]) as i32;
1124 p += 4;
1125 v = w as f32 * F_INV65536;
1126 } else {
1127 if p >= end {
1128 return -1;
1129 }
1130 let b2 = t.0[p as usize] as i32;
1131 p += 1;
1132 v = if b <= 250 {
1133 (((b as i32 - 247) << 8) + b2 + 108) as f32
1134 } else {
1135 (-(((b as i32 - 251) << 8) + b2 + 108)) as f32
1136 };
1137 }
1138 self.push(v)
1139 } else {
1140 match b {
1141 1 | 3 | 18 | 23 => {
1142 let n = self.width_even();
1144 self.nstems = self.nstems.wrapping_add((self.sp as u32 - n) >> 1);
1145 Flow::Clear
1146 }
1147 19 | 20 => {
1148 if self.sp != 0 {
1150 let n = self.width_even(); self.nstems = self.nstems.wrapping_add((self.sp as u32 - n) >> 1);
1152 }
1153 self.wd = true;
1154 p = p.wrapping_add(self.nstems.wrapping_add(7) >> 3);
1155 Flow::Clear
1156 }
1157 21 => {
1158 let i = self.width(2);
1160 self.moveto_begin();
1161 self.x = self.arg(i) + self.x;
1162 self.y = self.arg(i + 1) + self.y;
1163 self.moveto_end();
1164 Flow::Clear
1165 }
1166 22 => {
1167 let i = self.width(1);
1169 self.moveto_begin();
1170 self.x = self.arg(i) + self.x;
1171 self.moveto_end();
1172 Flow::Clear
1173 }
1174 4 => {
1175 let i = self.width(1);
1177 self.moveto_begin();
1178 self.y = self.arg(i) + self.y;
1179 self.moveto_end();
1180 Flow::Clear
1181 }
1182 5 => {
1183 let mut i = 0;
1185 while i + 2 <= self.sp {
1186 let (dx, dy) = (self.arg(i), self.arg(i + 1));
1187 self.line(dx, dy);
1188 i += 2;
1189 }
1190 Flow::Clear
1191 }
1192 6 | 7 => {
1193 let mut vert = b == 7;
1195 let mut i = 0;
1196 while i < self.sp {
1197 let v = self.arg(i);
1198 if vert { self.line(0.0, v) } else { self.line(v, 0.0) }
1199 vert = !vert;
1200 i += 1;
1201 }
1202 Flow::Clear
1203 }
1204 8 => {
1205 let mut i = 0;
1207 while i + 6 <= self.sp {
1208 self.curve6(i);
1209 i += 6;
1210 }
1211 Flow::Clear
1212 }
1213 24 => {
1214 let mut i = 0;
1216 while i + 8 <= self.sp {
1217 self.curve6(i);
1218 i += 6;
1219 }
1220 if i + 2 <= self.sp {
1221 let (dx, dy) = (self.arg(i), self.arg(i + 1));
1222 self.line(dx, dy);
1223 }
1224 Flow::Clear
1225 }
1226 25 => {
1227 let mut i = 0;
1229 while i + 8 <= self.sp {
1230 let (dx, dy) = (self.arg(i), self.arg(i + 1));
1231 self.line(dx, dy);
1232 i += 2;
1233 }
1234 if i + 6 <= self.sp {
1235 self.curve6(i);
1236 }
1237 Flow::Clear
1238 }
1239 27 => {
1240 let mut i = 0;
1242 self.d[1] = 0.0;
1243 if self.sp & 1 != 0 {
1244 self.d[1] = self.arg(0);
1245 i = 1;
1246 }
1247 while i + 4 <= self.sp {
1248 self.d[0] = self.arg(i);
1249 self.d[2] = self.arg(i + 1);
1250 self.d[3] = self.arg(i + 2);
1251 self.d[4] = self.arg(i + 3);
1252 self.d[5] = 0.0;
1253 self.curve();
1254 self.d[1] = 0.0;
1255 i += 4;
1256 }
1257 Flow::Clear
1258 }
1259 26 => {
1260 let mut i = 0;
1262 self.d[0] = 0.0;
1263 if self.sp & 1 != 0 {
1264 self.d[0] = self.arg(0);
1265 i = 1;
1266 }
1267 while i + 4 <= self.sp {
1268 self.d[1] = self.arg(i);
1269 self.d[2] = self.arg(i + 1);
1270 self.d[3] = self.arg(i + 2);
1271 self.d[4] = 0.0;
1272 self.d[5] = self.arg(i + 3);
1273 self.curve();
1274 self.d[0] = 0.0;
1275 i += 4;
1276 }
1277 Flow::Clear
1278 }
1279 30 | 31 => {
1280 let mut h = b == 31;
1282 let mut i = 0;
1283 while i + 4 <= self.sp {
1284 let last = (self.sp - i == 5) as usize;
1286 if h {
1287 self.d[0] = self.arg(i);
1288 self.d[1] = 0.0;
1289 self.d[2] = self.arg(i + 1);
1290 self.d[3] = self.arg(i + 2);
1291 self.d[5] = self.arg(i + 3);
1292 self.d[4] = 0.0;
1293 if last != 0 {
1294 self.d[4] = self.arg(i + 4);
1295 }
1296 } else {
1297 self.d[0] = 0.0;
1298 self.d[1] = self.arg(i);
1299 self.d[2] = self.arg(i + 1);
1300 self.d[3] = self.arg(i + 2);
1301 self.d[4] = self.arg(i + 3);
1302 self.d[5] = 0.0;
1303 if last != 0 {
1304 self.d[5] = self.arg(i + 4);
1305 }
1306 }
1307 self.curve();
1308 i += 4 + last;
1309 h = !h;
1310 }
1311 Flow::Clear
1312 }
1313 10 | 29 => {
1314 let ix = if b == 10 { self.ls } else { self.gs };
1316 if self.sp == 0 {
1317 return -1;
1318 }
1319 self.sp -= 1;
1320 let idx = cvtt(self.st[self.sp]);
1321 let i = cs_bias(ix.count).wrapping_add(idx);
1322 if i < 0 {
1323 return -1;
1324 }
1325 let Some((s, l)) = ix_get(t, &ix, i as u32) else { return -1 };
1326 let r = self.run(s, s.wrapping_add(l), depth + 1);
1327 if r < 0 {
1328 return -1;
1329 }
1330 if r != 0 {
1331 return 1; }
1333 Flow::Loop
1334 }
1335 11 => return 0, 15 if self.v2 => {
1337 let Some(v) = self.top() else { return -1 };
1339 let i = cvtt(v);
1340 if self.blended || i < 0 {
1341 return -1;
1342 }
1343 self.vsi = i as u32;
1344 self.nreg = None;
1345 Flow::Clear
1346 }
1347 16 if self.v2 => {
1348 if !self.blend() {
1349 return -1;
1350 }
1351 Flow::Loop }
1353 14 => {
1354 self.wd = true;
1356 self.moveto_begin();
1357 Flow::Ret1
1358 }
1359 12 => {
1360 if p >= end {
1361 return -1;
1362 }
1363 let e = t.0[p as usize] as u32;
1364 p += 1;
1365 self.escape(e)
1366 }
1367 _ => Flow::Clear, }
1369 };
1370 match flow {
1371 Flow::Clear => self.sp = 0,
1372 Flow::Loop => {}
1373 Flow::Err => return -1,
1374 Flow::Ret1 => return 1,
1375 }
1376 }
1377 }
1378
1379 fn escape(&mut self, e: u32) -> Flow {
1381 match e {
1382 35 => {
1383 if self.sp < 12 {
1385 return Flow::Clear;
1386 }
1387 self.d6(0);
1388 self.curve();
1389 self.d6(6);
1390 self.curve();
1391 Flow::Clear
1392 }
1393 34 => {
1394 if self.sp < 7 {
1396 return Flow::Clear;
1397 }
1398 let y0 = self.y;
1399 self.d = [self.arg(0), 0.0, self.arg(1), self.arg(2), self.arg(3), 0.0];
1400 self.curve();
1401 self.d[0] = self.arg(4);
1402 self.d[1] = 0.0;
1403 self.d[2] = self.arg(5);
1404 self.d[3] = y0 - self.y; self.d[4] = self.arg(6);
1406 self.d[5] = 0.0;
1407 self.curve();
1408 Flow::Clear
1409 }
1410 36 => {
1411 if self.sp < 9 {
1413 return Flow::Clear;
1414 }
1415 let y0 = self.y;
1416 self.d = [self.arg(0), self.arg(1), self.arg(2), self.arg(3), self.arg(4), 0.0];
1417 self.curve();
1418 self.d[0] = self.arg(5);
1419 self.d[1] = 0.0;
1420 self.d[2] = self.arg(6);
1421 self.d[3] = self.arg(7);
1422 self.d[4] = self.arg(8);
1423 self.d[5] = (y0 - self.y) - self.d[3]; self.curve();
1425 Flow::Clear
1426 }
1427 37 => {
1428 if self.sp < 11 {
1430 return Flow::Clear;
1431 }
1432 let (x0, y0) = (self.x, self.y);
1433 let (mut sx, mut sy) = (0.0f32, 0.0f32);
1434 for k in 0..5 {
1435 sx = sx + self.st[k * 2];
1436 sy = sy + self.st[k * 2 + 1];
1437 }
1438 let horiz = fabs(sx) > fabs(sy); self.d6(0);
1440 self.curve();
1441 self.d[0] = self.arg(6);
1442 self.d[1] = self.arg(7);
1443 self.d[2] = self.arg(8);
1444 self.d[3] = self.arg(9);
1445 let xx = (self.x + self.d[0]) + self.d[2];
1447 let yy = (self.y + self.d[1]) + self.d[3];
1448 let d6 = self.arg(10);
1449 if horiz {
1450 self.d[4] = d6;
1451 self.d[5] = y0 - yy;
1452 } else {
1453 self.d[5] = d6;
1454 self.d[4] = x0 - xx;
1455 }
1456 self.curve();
1457 Flow::Clear
1458 }
1459 9 => match self.top() {
1460 Some(v) => self.settop(fabs(v)),
1461 None => Flow::Err,
1462 },
1463 14 => match self.top() {
1464 Some(v) => self.settop(f32::from_bits(v.to_bits() ^ 0x8000_0000)),
1465 None => Flow::Err,
1466 },
1467 26 => match self.top() {
1468 Some(v) => self.settop(sqrt(fabs(v))),
1469 None => Flow::Err,
1470 },
1471 5 => match self.top() {
1472 Some(v) => self.settop(if zf(v, 0.0) { 1.0 } else { 0.0 }),
1473 None => Flow::Err,
1474 },
1475 10 | 11 | 24 | 12 | 3 | 4 | 15 => {
1476 let Some((a, b)) = self.pop2() else { return Flow::Err };
1477 let r = match e {
1478 10 => a + b,
1479 11 => a - b,
1480 24 => a * b,
1481 12 => {
1482 if zf(b, 0.0) {
1483 0.0
1484 } else {
1485 a / b
1486 }
1487 }
1488 3 => {
1489 if zf(a, 0.0) || zf(b, 0.0) {
1490 0.0
1491 } else {
1492 1.0
1493 }
1494 }
1495 4 => {
1496 if (a < 0.0 || a > 0.0) || (b < 0.0 || b > 0.0) {
1497 1.0
1498 } else {
1499 0.0
1500 }
1501 }
1502 _ => {
1503 if zf(a, b) {
1504 1.0
1505 } else {
1506 0.0
1507 }
1508 }
1509 };
1510 self.push(r)
1511 }
1512 18 => {
1513 if self.sp == 0 {
1515 return Flow::Err;
1516 }
1517 self.sp -= 1;
1518 Flow::Loop
1519 }
1520 27 => match self.top() {
1521 Some(v) => self.push(v),
1522 None => Flow::Err,
1523 },
1524 28 => {
1525 let Some((a, b)) = self.pop2() else { return Flow::Err };
1527 self.st[self.sp] = b;
1528 self.st[self.sp + 1] = a;
1529 self.sp += 2;
1530 Flow::Loop
1531 }
1532 29 => {
1533 let Some(v) = self.top() else { return Flow::Err };
1535 let mut i = cvtt(v);
1536 if i < 0 {
1537 i = 0;
1538 }
1539 let k = (self.sp as i32).wrapping_sub(2).wrapping_sub(i);
1540 if k < 0 {
1541 return Flow::Err;
1542 }
1543 let v = self.arg(k as usize);
1544 self.settop(v)
1545 }
1546 30 => {
1547 let Some((a, b)) = self.pop2() else { return Flow::Err };
1549 let num = cvtt(a);
1550 let j = cvtt(b);
1551 if num <= 0 {
1552 return Flow::Loop;
1553 }
1554 if num as usize > self.sp {
1555 return Flow::Err;
1556 }
1557 self.roll(num, j);
1558 Flow::Loop
1559 }
1560 20 => {
1561 let Some((a, b)) = self.pop2() else { return Flow::Err };
1563 let i = cvtt(b) as u32;
1564 if i < 32 {
1565 self.trans[i as usize] = a;
1566 }
1567 Flow::Loop
1568 }
1569 21 => {
1570 let Some(v) = self.top() else { return Flow::Err };
1572 let i = cvtt(v) as u32;
1573 if i >= 32 {
1574 return Flow::Err;
1575 }
1576 self.settop(self.trans[i as usize])
1577 }
1578 22 => {
1579 if self.sp < 4 {
1581 return Flow::Err;
1582 }
1583 self.sp -= 4;
1584 let s = self.sp;
1585 let v1 = self.st[s + 2];
1586 let v2 = self.st[s + 3];
1587 let r = if !(v1 > v2) { self.st[s] } else { self.st[s + 1] };
1588 self.push(r)
1589 }
1590 23 => {
1591 let r = self.rand.wrapping_mul(1_103_515_245).wrapping_add(12345);
1593 self.rand = r;
1594 let v = ((r >> 9) | 1) as i32 as f32 * F_INV8M; self.push(v)
1596 }
1597 _ => Flow::Clear, }
1599 }
1600}