1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use core::num::NonZeroU16;
use crate::{Tag, NormalizedCoord};
use crate::parser::{Stream, FromData, Fixed, Offset16, Offset, LazyArray16, LazyArrayIter16, f32_bound};
#[allow(missing_docs)]
#[repr(C)]
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct VariationAxis {
pub tag: Tag,
pub min_value: f32,
pub def_value: f32,
pub max_value: f32,
pub name_id: u16,
pub hidden: bool,
}
impl VariationAxis {
pub(crate) fn normalized_value(&self, mut v: f32) -> NormalizedCoord {
v = f32_bound(self.min_value, v, self.max_value);
if v == self.def_value {
v = 0.0;
} else if v < self.def_value {
v = (v - self.def_value) / (self.def_value - self.min_value);
} else {
v = (v - self.def_value) / (self.max_value - self.def_value);
}
NormalizedCoord::from(v)
}
}
#[derive(Clone, Copy)]
pub(crate) struct Table<'a> {
axes: LazyArray16<'a, VariationAxisRecord>,
}
impl<'a> Table<'a> {
pub fn parse(data: &'a [u8]) -> Option<Self> {
let mut s = Stream::new(data);
let version: u32 = s.read()?;
if version != 0x00010000 {
return None;
}
let axes_array_offset: Offset16 = s.read()?;
s.skip::<u16>();
let axis_count: u16 = s.read()?;
let axis_count = NonZeroU16::new(axis_count)?;
let mut s = Stream::new_at(data, axes_array_offset.to_usize())?;
let axes = s.read_array16(axis_count.get())?;
Some(Table { axes })
}
pub fn axes(&self) -> VariationAxes<'a> {
VariationAxes { iter: self.axes.into_iter() }
}
}
#[allow(missing_debug_implementations)]
#[derive(Clone, Copy, Default)]
pub struct VariationAxes<'a> {
iter: LazyArrayIter16<'a, VariationAxisRecord>,
}
impl<'a> Iterator for VariationAxes<'a> {
type Item = VariationAxis;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let record = self.iter.next()?;
let def_value = record.def_value;
let min_value = def_value.min(record.min_value);
let max_value = def_value.max(record.max_value);
Some(VariationAxis {
tag: record.axis_tag,
min_value,
def_value,
max_value,
name_id: record.axis_name_id,
hidden: (record.flags >> 3) & 1 == 1,
})
}
#[inline]
fn count(self) -> usize {
self.iter.count()
}
}
#[derive(Clone, Copy)]
struct VariationAxisRecord {
axis_tag: Tag,
min_value: f32,
def_value: f32,
max_value: f32,
flags: u16,
axis_name_id: u16,
}
impl FromData for VariationAxisRecord {
const SIZE: usize = 20;
#[inline]
fn parse(data: &[u8]) -> Option<Self> {
let mut s = Stream::new(data);
Some(VariationAxisRecord {
axis_tag: s.read()?,
min_value: s.read::<Fixed>()?.0,
def_value: s.read::<Fixed>()?.0,
max_value: s.read::<Fixed>()?.0,
flags: s.read()?,
axis_name_id: s.read()?,
})
}
}