1mod parser;
2mod index;
3pub mod charset;
4mod charstring;
5mod dict;
6mod argstack;
7mod std_names;
8mod encoding;
9mod cff;
10
11pub use cff::{Table, string_by_id};
12use parser::{FromData, Stream, TryNumFrom};
13pub use encoding::{Encoding, EncodingKind, Format1Range, STANDARD_ENCODING};
14
15#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
17pub struct StringId(u16);
18
19impl FromData for StringId {
20 const SIZE: usize = 2;
21
22 #[inline]
23 fn parse(data: &[u8]) -> Option<Self> {
24 u16::parse(data).map(StringId)
25 }
26}
27
28trait IsEven {
29 fn is_odd(&self) -> bool;
30}
31impl IsEven for usize {
32 fn is_odd(&self) -> bool {
33 self & 1 == 1
34 }
35}
36
37#[derive(Clone, Copy, PartialEq, Debug)]
39pub enum CFFError {
40 NoGlyph,
41 ReadOutOfBounds,
42 ZeroBBox,
43 InvalidOperator,
44 UnsupportedOperator,
45 MissingEndChar,
46 DataAfterEndChar,
47 NestingLimitReached,
48 ArgumentsStackLimitReached,
49 InvalidArgumentsStackLength,
50 BboxOverflow,
51 MissingMoveTo,
52 InvalidSubroutineIndex,
53 NoLocalSubroutines,
54 InvalidSeacCode,
55}
56
57
58#[inline]
59pub fn f32_abs(n: f32) -> f32 {
60 n.abs()
61}
62
63
64#[inline]
65pub fn conv_subroutine_index(index: f32, bias: u16) -> Result<u32, CFFError> {
66 conv_subroutine_index_impl(index, bias).ok_or(CFFError::InvalidSubroutineIndex)
67}
68
69#[inline]
70fn conv_subroutine_index_impl(index: f32, bias: u16) -> Option<u32> {
71 let index = i32::try_num_from(index)?;
72 let bias = i32::from(bias);
73
74 let index = index.checked_add(bias)?;
75 u32::try_from(index).ok()
76}
77
78#[inline]
80pub fn calc_subroutine_bias(len: u32) -> u16 {
81 if len < 1240 {
82 107
83 } else if len < 33900 {
84 1131
85 } else {
86 32768
87 }
88}
89
90pub trait OutlineBuilder {
92 fn move_to(&mut self, x: f32, y: f32);
96
97 fn line_to(&mut self, x: f32, y: f32);
99
100 fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32);
102
103 fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32);
105
106 fn close(&mut self);
110}
111
112
113struct DummyOutline;
114impl OutlineBuilder for DummyOutline {
115 fn move_to(&mut self, _: f32, _: f32) {}
116 fn line_to(&mut self, _: f32, _: f32) {}
117 fn quad_to(&mut self, _: f32, _: f32, _: f32, _: f32) {}
118 fn curve_to(&mut self, _: f32, _: f32, _: f32, _: f32, _: f32, _: f32) {}
119 fn close(&mut self) {}
120}
121
122
123pub(crate) struct Builder<'a> {
124 builder: &'a mut dyn OutlineBuilder,
125 bbox: RectF,
126}
127
128impl<'a> Builder<'a> {
129 #[inline]
130 fn move_to(&mut self, x: f32, y: f32) {
131 self.bbox.extend_by(x, y);
132 self.builder.move_to(x, y);
133 }
134
135 #[inline]
136 fn line_to(&mut self, x: f32, y: f32) {
137 self.bbox.extend_by(x, y);
138 self.builder.line_to(x, y);
139 }
140
141 #[inline]
142 fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
143 self.bbox.extend_by(x1, y1);
144 self.bbox.extend_by(x2, y2);
145 self.bbox.extend_by(x, y);
146 self.builder.curve_to(x1, y1, x2, y2, x, y);
147 }
148
149 #[inline]
150 fn close(&mut self) {
151 self.builder.close();
152 }
153}
154#[repr(C)]
158#[allow(missing_docs)]
159#[derive(Clone, Copy, PartialEq, Eq, Debug)]
160pub struct Rect {
161 pub x_min: i16,
162 pub y_min: i16,
163 pub x_max: i16,
164 pub y_max: i16,
165}
166
167impl Rect {
168 #[inline]
169 fn zero() -> Self {
170 Self {
171 x_min: 0,
172 y_min: 0,
173 x_max: 0,
174 y_max: 0,
175 }
176 }
177
178 #[inline]
180 pub fn width(&self) -> i16 {
181 self.x_max - self.x_min
182 }
183
184 #[inline]
186 pub fn height(&self) -> i16 {
187 self.y_max - self.y_min
188 }
189}
190
191#[derive(Clone, Copy, Debug, PartialEq)]
193pub struct RectF {
194 pub x_min: f32,
196 pub y_min: f32,
198 pub x_max: f32,
200 pub y_max: f32,
202}
203
204impl RectF {
205 #[inline]
206 fn new() -> Self {
207 RectF {
208 x_min: f32::MAX,
209 y_min: f32::MAX,
210 x_max: f32::MIN,
211 y_max: f32::MIN,
212 }
213 }
214
215 #[inline]
216 fn is_default(&self) -> bool {
217 self.x_min == f32::MAX
218 && self.y_min == f32::MAX
219 && self.x_max == f32::MIN
220 && self.y_max == f32::MIN
221 }
222
223 #[inline]
224 fn extend_by(&mut self, x: f32, y: f32) {
225 self.x_min = self.x_min.min(x);
226 self.y_min = self.y_min.min(y);
227 self.x_max = self.x_max.max(x);
228 self.y_max = self.y_max.max(y);
229 }
230
231 #[inline]
232 fn to_rect(self) -> Option<Rect> {
233 Some(Rect {
234 x_min: i16::try_num_from(self.x_min)?,
235 y_min: i16::try_num_from(self.y_min)?,
236 x_max: i16::try_num_from(self.x_max)?,
237 y_max: i16::try_num_from(self.y_max)?,
238 })
239 }
240}
241
242
243
244#[repr(transparent)]
246#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Default, Debug)]
247pub struct GlyphId(pub u16);
248
249impl FromData for GlyphId {
250 const SIZE: usize = 2;
251
252 #[inline]
253 fn parse(data: &[u8]) -> Option<Self> {
254 u16::parse(data).map(GlyphId)
255 }
256}
257
258