1#![forbid(unsafe_code)]
15#![deny(missing_docs)]
16
17use crate::util::TryNumFrom;
18
19pub mod cff;
20pub mod type1;
21
22mod argstack;
23mod util;
24
25#[repr(transparent)]
27#[derive(Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Default, Debug, Hash)]
28pub struct GlyphId(pub u16);
29
30pub trait OutlineBuilder {
32 fn move_to(&mut self, x: f32, y: f32);
36
37 fn line_to(&mut self, x: f32, y: f32);
39
40 fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32);
42
43 fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32);
45
46 fn close(&mut self);
50}
51
52struct DummyOutline;
53impl OutlineBuilder for DummyOutline {
54 fn move_to(&mut self, _: f32, _: f32) {}
55 fn line_to(&mut self, _: f32, _: f32) {}
56 fn quad_to(&mut self, _: f32, _: f32, _: f32, _: f32) {}
57 fn curve_to(&mut self, _: f32, _: f32, _: f32, _: f32, _: f32, _: f32) {}
58 fn close(&mut self) {}
59}
60
61#[repr(C)]
65#[allow(missing_docs)]
66#[derive(Clone, Copy, PartialEq, Eq, Debug)]
67pub struct Rect {
68 pub x_min: i16,
69 pub y_min: i16,
70 pub x_max: i16,
71 pub y_max: i16,
72}
73
74impl Rect {
75 #[inline]
76 fn zero() -> Self {
77 Self {
78 x_min: 0,
79 y_min: 0,
80 x_max: 0,
81 y_max: 0,
82 }
83 }
84
85 #[inline]
87 pub fn width(&self) -> i16 {
88 self.x_max - self.x_min
89 }
90
91 #[inline]
93 pub fn height(&self) -> i16 {
94 self.y_max - self.y_min
95 }
96}
97
98#[derive(Clone, Copy, Debug, PartialEq)]
100pub struct RectF {
101 pub x_min: f32,
103 pub y_min: f32,
105 pub x_max: f32,
107 pub y_max: f32,
109}
110
111impl RectF {
112 #[inline]
113 fn new() -> Self {
114 Self {
115 x_min: f32::MAX,
116 y_min: f32::MAX,
117 x_max: f32::MIN,
118 y_max: f32::MIN,
119 }
120 }
121
122 #[inline]
123 fn is_default(&self) -> bool {
124 self.x_min == f32::MAX
125 && self.y_min == f32::MAX
126 && self.x_max == f32::MIN
127 && self.y_max == f32::MIN
128 }
129
130 #[inline]
131 fn extend_by(&mut self, x: f32, y: f32) {
132 self.x_min = self.x_min.min(x);
133 self.y_min = self.y_min.min(y);
134 self.x_max = self.x_max.max(x);
135 self.y_max = self.y_max.max(y);
136 }
137
138 #[inline]
139 fn to_rect(self) -> Option<Rect> {
140 Some(Rect {
141 x_min: i16::try_num_from(self.x_min)?,
142 y_min: i16::try_num_from(self.y_min)?,
143 x_max: i16::try_num_from(self.x_max)?,
144 y_max: i16::try_num_from(self.y_max)?,
145 })
146 }
147}
148
149pub(crate) struct Builder<'a> {
150 pub(crate) builder: &'a mut dyn OutlineBuilder,
151 pub(crate) bbox: RectF,
152}
153
154impl<'a> Builder<'a> {
155 #[inline]
156 fn move_to(&mut self, x: f32, y: f32) {
157 self.bbox.extend_by(x, y);
158 self.builder.move_to(x, y);
159 }
160
161 #[inline]
162 fn line_to(&mut self, x: f32, y: f32) {
163 self.bbox.extend_by(x, y);
164 self.builder.line_to(x, y);
165 }
166
167 #[inline]
168 fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
169 self.bbox.extend_by(x1, y1);
170 self.bbox.extend_by(x2, y2);
171 self.bbox.extend_by(x, y);
172 self.builder.curve_to(x1, y1, x2, y2, x, y);
173 }
174
175 #[inline]
176 fn close(&mut self) {
177 self.builder.close();
178 }
179}
180
181#[allow(missing_docs)]
183#[derive(Clone, Copy, Debug)]
184pub struct Matrix {
185 pub sx: f32,
186 pub ky: f32,
187 pub kx: f32,
188 pub sy: f32,
189 pub tx: f32,
190 pub ty: f32,
191}
192
193impl Default for Matrix {
194 fn default() -> Self {
195 Self {
196 sx: 0.001,
197 ky: 0.0,
198 kx: 0.0,
199 sy: 0.001,
200 tx: 0.0,
201 ty: 0.0,
202 }
203 }
204}
205
206#[allow(missing_docs)]
208#[derive(Clone, Copy, PartialEq, Eq, Debug)]
209pub enum OutlineError {
210 NoGlyph,
211 ReadOutOfBounds,
212 ZeroBBox,
213 InvalidOperator,
214 UnsupportedOperator,
215 MissingEndChar,
216 DataAfterEndChar,
217 NestingLimitReached,
218 ArgumentsStackLimitReached,
219 InvalidArgumentsStackLength,
220 BboxOverflow,
221 MissingMoveTo,
222 InvalidSubroutineIndex,
223 NoLocalSubroutines,
224 InvalidSeacCode,
225}