1use super::{super::error::Error, blend::BlendState};
4use types::Fixed;
5
6const MAX_STACK: usize = 513;
13
14pub struct Stack {
26 values: [i32; MAX_STACK],
27 value_is_fixed: [bool; MAX_STACK],
28 top: usize,
29}
30
31impl Stack {
32 pub fn new() -> Self {
33 Self {
34 values: [0; MAX_STACK],
35 value_is_fixed: [false; MAX_STACK],
36 top: 0,
37 }
38 }
39
40 pub fn is_empty(&self) -> bool {
41 self.top == 0
42 }
43
44 pub fn len(&self) -> usize {
45 self.top
46 }
47
48 pub fn verify_exact_len(&self, len: usize) -> Result<(), Error> {
49 if self.top != len {
50 Err(Error::StackUnderflow)
51 } else {
52 Ok(())
53 }
54 }
55
56 pub fn verify_at_least_len(&self, len: usize) -> Result<(), Error> {
57 if self.top < len {
58 Err(Error::StackUnderflow)
59 } else {
60 Ok(())
61 }
62 }
63
64 pub fn len_is_odd(&self) -> bool {
70 self.top & 1 != 0
71 }
72
73 pub fn clear(&mut self) {
74 self.top = 0;
75 }
76
77 pub fn reverse(&mut self) {
82 self.values[..self.top].reverse();
83 self.value_is_fixed[..self.top].reverse();
84 }
85
86 pub(crate) fn exch(&mut self) -> Result<(), Error> {
88 if self.top < 2 {
89 return Err(Error::StackUnderflow);
90 }
91 let a = self.top - 1;
92 let b = a - 1;
93 self.values.swap(a, b);
94 self.value_is_fixed.swap(a, b);
95 Ok(())
96 }
97
98 pub fn push(&mut self, number: impl Into<Number>) -> Result<(), Error> {
99 match number.into() {
100 Number::I32(value) => self.push_impl(value, false),
101 Number::Fixed(value) => self.push_impl(value.to_bits(), true),
102 }
103 }
104
105 pub fn set(&mut self, index: usize, number: impl Into<Number>) -> Result<(), Error> {
107 if index >= self.top {
108 return Err(Error::StackOverflow);
109 }
110 match number.into() {
111 Number::I32(value) => {
112 self.value_is_fixed[index] = false;
113 self.values[index] = value;
114 }
115 Number::Fixed(value) => {
116 self.value_is_fixed[index] = true;
117 self.values[index] = value.to_bits();
118 }
119 }
120 Ok(())
121 }
122
123 pub fn drop(&mut self, n: usize) {
128 self.top = self.top.saturating_sub(n);
129 }
130
131 pub fn get_i32(&self, index: usize) -> Result<i32, Error> {
136 let Some(value) = self.values.get(index).copied() else {
139 return Ok(0);
140 };
141 if self.value_is_fixed[index] {
142 Err(Error::ExpectedI32StackEntry(index))
145 } else {
146 Ok(value)
147 }
148 }
149
150 pub fn get_fixed(&self, index: usize) -> Result<Fixed, Error> {
155 let Some(value) = self.values.get(index).copied() else {
158 return Ok(Fixed::ZERO);
159 };
160 Ok(if self.value_is_fixed[index] {
161 Fixed::from_bits(value)
162 } else {
163 Fixed::from_i32(value)
164 })
165 }
166
167 pub fn pop_i32(&mut self) -> Result<i32, Error> {
172 let i = self.pop()?;
173 self.get_i32(i)
174 }
175
176 pub fn pop_fixed(&mut self) -> Result<Fixed, Error> {
181 let i = self.pop()?;
182 self.get_fixed(i)
183 }
184
185 pub fn fixed_values(&self) -> impl Iterator<Item = Fixed> + '_ {
191 self.values[..self.top]
192 .iter()
193 .zip(&self.value_is_fixed)
194 .map(|(value, is_real)| {
195 if *is_real {
196 Fixed::from_bits(*value)
197 } else {
198 Fixed::from_i32(*value)
199 }
200 })
201 }
202
203 pub fn fixed_array<const N: usize>(&self, first_index: usize) -> Result<[Fixed; N], Error> {
206 let mut result = [Fixed::ZERO; N];
207 let end = first_index + N;
208 let range = first_index.min(self.top)..end.min(self.top);
212 for ((src, is_fixed), dest) in self.values[range.clone()]
213 .iter()
214 .zip(&self.value_is_fixed[range])
215 .zip(&mut result)
216 {
217 let value = if *is_fixed {
218 Fixed::from_bits(*src)
219 } else {
220 Fixed::from_i32(*src)
221 };
222 *dest = value;
223 }
224 Ok(result)
225 }
226
227 pub fn number_values(&self) -> impl Iterator<Item = Number> + '_ {
232 self.values[..self.top]
233 .iter()
234 .zip(&self.value_is_fixed)
235 .map(|(value, is_fixed)| Number::from_stack(*value, *is_fixed))
236 }
237
238 pub fn apply_delta_prefix_sum(&mut self) {
248 if self.top > 1 {
249 let mut sum = Fixed::ZERO;
250 for (value, is_fixed) in self.values[..self.top]
251 .iter_mut()
252 .zip(&mut self.value_is_fixed)
253 {
254 let fixed_value = if *is_fixed {
255 Fixed::from_bits(*value)
256 } else {
257 Fixed::from_i32(*value)
258 };
259 sum = sum.wrapping_add(fixed_value);
265 *value = sum.to_bits();
266 *is_fixed = true;
267 }
268 }
269 }
270
271 #[inline(never)]
275 pub fn apply_blend(&mut self, blend_state: &BlendState) -> Result<(), Error> {
276 let target_value_count = self.pop_i32()? as usize;
292 if target_value_count > self.top {
293 return Err(Error::StackUnderflow);
294 }
295 let region_count = blend_state.region_count()?;
296 let operand_count = target_value_count * (region_count + 1);
299 if self.len() < operand_count {
300 return Err(Error::StackUnderflow);
301 }
302 let start = self.len() - operand_count;
305 let end = start + operand_count;
306 for (value, is_fixed) in self.values[start..end]
308 .iter_mut()
309 .zip(&mut self.value_is_fixed[start..])
310 {
311 if !*is_fixed {
312 *value = Fixed::from_i32(*value).to_bits();
313 *is_fixed = true;
314 }
315 }
316 let (values, deltas) = self.values[start..].split_at_mut(target_value_count);
317 for (region_ix, maybe_scalar) in blend_state.scalars()?.enumerate() {
321 let scalar = maybe_scalar?;
322 if scalar == Fixed::ZERO {
326 continue;
327 }
328 for (value_ix, value) in values.iter_mut().enumerate() {
329 let delta_ix = (region_count * value_ix) + region_ix;
330 let delta = Fixed::from_bits(deltas[delta_ix]);
331 *value = (Fixed::from_bits(*value).wrapping_add(delta * scalar)).to_bits();
332 }
333 }
334 self.top = start + target_value_count;
335 Ok(())
336 }
337
338 pub(crate) fn div(&mut self, is_type1: bool) -> Result<(), Error> {
343 let b_idx = self.pop()?;
344 let a_idx = self.pop()?;
345 let (a, b) = if self.value_is_fixed[a_idx] {
346 (self.get_fixed(a_idx)?, self.get_fixed(b_idx)?)
347 } else {
348 let a = self.get_i32(a_idx)?;
352 if is_type1 && !(-32000..=32000).contains(&a) {
353 (Fixed::from_bits(a), Fixed::from_bits(self.get_i32(b_idx)?))
354 } else {
355 (self.get_fixed(a_idx)?, self.get_fixed(b_idx)?)
356 }
357 };
358 self.push(a / b)
359 }
360
361 fn push_impl(&mut self, value: i32, is_fixed: bool) -> Result<(), Error> {
362 if self.top == MAX_STACK {
363 return Err(Error::StackOverflow);
364 }
365 self.values[self.top] = value;
366 self.value_is_fixed[self.top] = is_fixed;
367 self.top += 1;
368 Ok(())
369 }
370
371 fn pop(&mut self) -> Result<usize, Error> {
372 if self.top > 0 {
373 self.top -= 1;
374 Ok(self.top)
375 } else {
376 Ok(0)
377 }
378 }
379}
380
381impl Default for Stack {
382 fn default() -> Self {
383 Self::new()
384 }
385}
386
387#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
392pub enum Number {
393 I32(i32),
394 Fixed(Fixed),
395}
396
397impl Number {
398 fn from_stack(raw: i32, is_fixed: bool) -> Self {
399 if is_fixed {
400 Self::Fixed(Fixed::from_bits(raw))
401 } else {
402 Self::I32(raw)
403 }
404 }
405}
406
407impl From<i32> for Number {
408 fn from(value: i32) -> Self {
409 Self::I32(value)
410 }
411}
412
413impl From<Fixed> for Number {
414 fn from(value: Fixed) -> Self {
415 Self::Fixed(value)
416 }
417}
418
419impl std::fmt::Display for Number {
420 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
421 match self {
422 Self::I32(value) => value.fmt(f),
423 Self::Fixed(value) => value.fmt(f),
424 }
425 }
426}
427
428#[cfg(test)]
429mod tests {
430 use super::*;
431 use crate::{tables::variations::ItemVariationStore, FontData, FontRead};
432 use types::{F2Dot14, Fixed};
433
434 #[test]
435 fn push_pop() {
436 let mut stack = Stack::new();
437 stack.push(20).unwrap();
438 stack.push(Fixed::from_f64(42.42)).unwrap();
439 assert!(!stack.len_is_odd());
440 stack.verify_exact_len(2).unwrap();
441 stack.verify_at_least_len(2).unwrap();
442 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_f64(42.42));
443 assert_eq!(stack.pop_i32().unwrap(), 20);
444 }
445
446 #[test]
447 fn push_fixed_pop_i32() {
448 let mut stack = Stack::new();
449 stack.push(Fixed::from_f64(42.42)).unwrap();
450 assert!(stack.pop_i32().is_err());
451 }
452
453 #[test]
454 fn push_i32_pop_fixed() {
455 let mut stack = Stack::new();
456 stack.push(123).unwrap();
457 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_f64(123.0));
458 }
459
460 #[test]
461 fn reverse() {
462 let mut stack = Stack::new();
463 stack.push(Fixed::from_f64(1.5)).unwrap();
464 stack.push(42).unwrap();
465 stack.push(Fixed::from_f64(4.2)).unwrap();
466 stack.reverse();
467 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_f64(1.5));
468 assert_eq!(stack.pop_i32().unwrap(), 42);
469 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_f64(4.2));
470 }
471
472 #[test]
473 fn delta_prefix_sum() {
474 let mut stack = Stack::new();
475 stack.push(Fixed::from_f64(1.5)).unwrap();
476 stack.push(42).unwrap();
477 stack.push(Fixed::from_f64(4.2)).unwrap();
478 stack.apply_delta_prefix_sum();
479 assert!(stack.len_is_odd());
480 let values: Vec<_> = stack.fixed_values().collect();
481 let expected = &[
482 Fixed::from_f64(1.5),
483 Fixed::from_f64(43.5),
484 Fixed::from_f64(47.69999694824219),
485 ];
486 assert_eq!(&values, expected);
487 }
488
489 #[test]
490 fn blend() {
491 let ivs_data = &font_test_data::cff2::EXAMPLE[18..];
492 let ivs = ItemVariationStore::read(FontData::new(ivs_data)).unwrap();
493 let coords = &[F2Dot14::from_f32(-0.75)];
495 let blend_state = BlendState::new(ivs, coords, 0).unwrap();
496 let mut stack = Stack::new();
497 stack.push(10).unwrap();
499 stack.push(20).unwrap();
500 stack.push(4).unwrap();
502 stack.push(-8).unwrap();
503 stack.push(-60).unwrap();
505 stack.push(2).unwrap();
506 stack.push(2).unwrap();
508 stack.apply_blend(&blend_state).unwrap();
509 let result: Vec<_> = stack.fixed_values().collect();
510 let expected = &[Fixed::from_f64(8.0), Fixed::from_f64(-9.0)];
514 assert_eq!(&result, expected);
515 }
516
517 #[test]
518 fn invalid_access_yields_zero() {
519 let mut stack = Stack::new();
520 assert_eq!(stack.pop_i32().unwrap(), 0);
521 assert_eq!(stack.pop_fixed().unwrap(), Fixed::ZERO);
522 assert_eq!(stack.get_i32(10).unwrap(), 0);
523 assert_eq!(stack.get_fixed(10).unwrap(), Fixed::ZERO);
524 stack.push(5).unwrap();
527 assert_eq!(
528 stack.fixed_array::<3>(0).unwrap(),
529 [Fixed::from_i32(5), Fixed::ZERO, Fixed::ZERO]
530 );
531 }
532
533 #[test]
534 fn exch() {
535 let mut stack = Stack::new();
536 stack.push(4).unwrap();
537 stack.push(Fixed::from_f64(2.5)).unwrap();
538 stack.exch().unwrap();
539 assert_eq!(stack.pop_i32().unwrap(), 4);
540 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_f64(2.5));
541 stack.clear();
543 stack.push(1).unwrap();
544 assert!(stack.exch().is_err());
545 }
546
547 #[test]
548 fn div() {
549 let mut stack = Stack::new();
550 stack.push(200).unwrap();
552 stack.push(50).unwrap();
553 stack.div(false).unwrap();
554 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_i32(4));
555 stack.push(Fixed::from_f64(151.0)).unwrap();
556 stack.push(2).unwrap();
557 stack.div(false).unwrap();
558 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_f64(75.5));
559 stack.push(40000).unwrap();
561 stack.push(20).unwrap();
562 stack.div(true).unwrap();
563 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_i32(2000));
564 stack.push(-40000).unwrap();
565 stack.push(20).unwrap();
566 stack.div(true).unwrap();
567 assert_eq!(stack.pop_fixed().unwrap(), Fixed::from_i32(-2000));
568 }
569
570 #[test]
571 fn set() {
572 let mut stack = Stack::new();
573 stack.push(0).unwrap();
574 stack.push(0).unwrap();
575 stack.push(0).unwrap();
576 stack.set(0, Fixed::from_f64(-4.2)).unwrap();
577 stack.set(2, 25).unwrap();
578 assert_eq!(
579 stack.fixed_array(0).unwrap(),
580 [Fixed::from_f64(-4.2), Fixed::ZERO, Fixed::from_f64(25.0)]
581 );
582 }
583
584 #[test]
585 fn drop() {
586 let mut stack = Stack::new();
587 for _ in 0..20 {
588 stack.push(0).unwrap();
589 }
590 assert_eq!(stack.len(), 20);
591 stack.drop(4);
592 assert_eq!(stack.len(), 16);
593 stack.drop(10);
594 assert_eq!(stack.len(), 6);
595 stack.drop(7);
598 assert_eq!(stack.len(), 0);
599 }
600}