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