1use super::StandardFont;
11
12pub fn unicode_to_winansi(ch: char) -> Option<u8> {
18 let cp = ch as u32;
19 if (0x20..=0x7E).contains(&cp) || (0xA0..=0xFF).contains(&cp) {
21 return Some(cp as u8);
22 }
23 match cp {
25 0x20AC => Some(0x80), 0x201A => Some(0x82), 0x0192 => Some(0x83), 0x201E => Some(0x84), 0x2026 => Some(0x85), 0x2020 => Some(0x86), 0x2021 => Some(0x87), 0x02C6 => Some(0x88), 0x2030 => Some(0x89), 0x0160 => Some(0x8A), 0x2039 => Some(0x8B), 0x0152 => Some(0x8C), 0x017D => Some(0x8E), 0x2018 => Some(0x91), 0x2019 => Some(0x92), 0x201C => Some(0x93), 0x201D => Some(0x94), 0x2022 => Some(0x95), 0x2013 => Some(0x96), 0x2014 => Some(0x97), 0x02DC => Some(0x98), 0x2122 => Some(0x99), 0x0161 => Some(0x9A), 0x203A => Some(0x9B), 0x0153 => Some(0x9C), 0x017E => Some(0x9E), 0x0178 => Some(0x9F), _ => None,
53 }
54}
55
56pub struct StandardFontMetrics {
60 pub widths: &'static [u16; 224],
61 pub default_width: u16,
62}
63
64impl StandardFontMetrics {
65 pub fn char_width(&self, ch: char, font_size: f64) -> f64 {
67 let code = ch as u32;
68 let w = if (32..=255).contains(&code) {
69 let idx = (code - 32) as usize;
70 let w = self.widths[idx];
71 if w > 0 {
72 w
73 } else {
74 self.default_width
75 }
76 } else if let Some(winansi) = unicode_to_winansi(ch) {
77 if winansi >= 32 {
78 let idx = (winansi as u32 - 32) as usize;
79 let w = self.widths[idx];
80 if w > 0 {
81 w
82 } else {
83 self.default_width
84 }
85 } else {
86 self.default_width
87 }
88 } else {
89 self.default_width
90 };
91 (w as f64 / 1000.0) * font_size
92 }
93
94 pub fn measure_string(&self, text: &str, font_size: f64, letter_spacing: f64) -> f64 {
96 let mut width = 0.0;
97 for ch in text.chars() {
98 width += self.char_width(ch, font_size) + letter_spacing;
99 }
100 width
101 }
102}
103
104impl StandardFont {
105 pub fn metrics(&self) -> StandardFontMetrics {
107 match self {
108 Self::Helvetica => StandardFontMetrics {
109 widths: &HELVETICA_WIDTHS,
110 default_width: 278,
111 },
112 Self::HelveticaBold => StandardFontMetrics {
113 widths: &HELVETICA_BOLD_WIDTHS,
114 default_width: 278,
115 },
116 Self::HelveticaOblique => StandardFontMetrics {
117 widths: &HELVETICA_OBLIQUE_WIDTHS,
118 default_width: 278,
119 },
120 Self::HelveticaBoldOblique => StandardFontMetrics {
121 widths: &HELVETICA_BOLD_OBLIQUE_WIDTHS,
122 default_width: 278,
123 },
124 Self::TimesRoman => StandardFontMetrics {
125 widths: &TIMES_ROMAN_WIDTHS,
126 default_width: 250,
127 },
128 Self::TimesBold => StandardFontMetrics {
129 widths: &TIMES_BOLD_WIDTHS,
130 default_width: 250,
131 },
132 Self::TimesItalic => StandardFontMetrics {
133 widths: &TIMES_ITALIC_WIDTHS,
134 default_width: 250,
135 },
136 Self::TimesBoldItalic => StandardFontMetrics {
137 widths: &TIMES_BOLD_ITALIC_WIDTHS,
138 default_width: 250,
139 },
140 Self::Courier => StandardFontMetrics {
141 widths: &COURIER_WIDTHS,
142 default_width: 600,
143 },
144 Self::CourierBold => StandardFontMetrics {
145 widths: &COURIER_BOLD_WIDTHS,
146 default_width: 600,
147 },
148 Self::CourierOblique => StandardFontMetrics {
149 widths: &COURIER_OBLIQUE_WIDTHS,
150 default_width: 600,
151 },
152 Self::CourierBoldOblique => StandardFontMetrics {
153 widths: &COURIER_BOLD_OBLIQUE_WIDTHS,
154 default_width: 600,
155 },
156 Self::Symbol => StandardFontMetrics {
157 widths: &SYMBOL_WIDTHS,
158 default_width: 250,
159 },
160 Self::ZapfDingbats => StandardFontMetrics {
161 widths: &ZAPF_DINGBATS_WIDTHS,
162 default_width: 278,
163 },
164 }
165 }
166}
167
168static HELVETICA_WIDTHS: [u16; 224] = [
169 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556,
170 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667,
171 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667,
172 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500,
173 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584,
174 0, 556, 0, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 0, 611, 0, 0, 222, 222,
175 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 0, 500, 667, 278, 333, 556, 556, 167, 556,
176 556, 556, 556, 191, 333, 556, 333, 333, 500, 500, 400, 556, 556, 556, 278, 556, 537, 350, 222,
177 333, 333, 556, 1000, 1000, 834, 611, 667, 333, 333, 333, 333, 333, 333, 333, 333, 667, 333,
178 333, 278, 333, 333, 333, 1000, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667,
179 667, 611, 556, 1000, 556, 370, 556, 556, 889, 500, 556, 778, 1000, 365, 278, 278, 278, 278,
180 556, 889, 556, 556, 556, 278, 556, 584, 222, 611, 944, 611, 556, 500, 556, 500,
181];
182
183static HELVETICA_BOLD_WIDTHS: [u16; 224] = [
184 278, 333, 474, 556, 556, 889, 722, 278, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556,
185 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667,
186 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667,
187 667, 611, 333, 278, 333, 584, 556, 278, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556,
188 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584,
189 0, 556, 0, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 0, 611, 0, 0, 278, 278,
190 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 0, 500, 667, 278, 333, 556, 556, 167, 556,
191 556, 556, 556, 238, 500, 556, 333, 333, 611, 611, 400, 556, 556, 556, 278, 611, 556, 350, 278,
192 500, 500, 556, 1000, 1000, 834, 611, 722, 333, 333, 333, 333, 333, 333, 333, 333, 667, 333,
193 333, 278, 333, 333, 333, 1000, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667,
194 667, 611, 556, 1000, 556, 370, 556, 556, 889, 556, 611, 778, 1000, 365, 278, 278, 278, 278,
195 611, 889, 611, 611, 611, 278, 611, 584, 278, 611, 944, 611, 611, 556, 611, 556,
196];
197
198static HELVETICA_OBLIQUE_WIDTHS: [u16; 224] = [
199 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556,
200 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667,
201 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667,
202 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500,
203 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584,
204 0, 556, 0, 222, 556, 333, 1000, 556, 556, 333, 1000, 667, 333, 1000, 0, 611, 0, 0, 222, 222,
205 333, 333, 350, 556, 1000, 333, 1000, 500, 333, 944, 0, 500, 667, 278, 333, 556, 556, 167, 556,
206 556, 556, 556, 191, 333, 556, 333, 333, 500, 500, 400, 556, 556, 556, 278, 556, 537, 350, 222,
207 333, 333, 556, 1000, 1000, 834, 611, 667, 333, 333, 333, 333, 333, 333, 333, 333, 667, 333,
208 333, 278, 333, 333, 333, 1000, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667,
209 667, 611, 556, 1000, 556, 370, 556, 556, 889, 500, 556, 778, 1000, 365, 278, 278, 278, 278,
210 556, 889, 556, 556, 556, 278, 556, 584, 222, 611, 944, 611, 556, 500, 556, 500,
211];
212
213static HELVETICA_BOLD_OBLIQUE_WIDTHS: [u16; 224] = [
214 278, 333, 474, 556, 556, 889, 722, 278, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556,
215 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667,
216 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667,
217 667, 611, 333, 278, 333, 584, 556, 278, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556,
218 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584,
219 0, 556, 0, 278, 556, 500, 1000, 556, 556, 333, 1000, 667, 333, 1000, 0, 611, 0, 0, 278, 278,
220 500, 500, 350, 556, 1000, 333, 1000, 556, 333, 944, 0, 500, 667, 278, 333, 556, 556, 167, 556,
221 556, 556, 556, 238, 500, 556, 333, 333, 611, 611, 400, 556, 556, 556, 278, 611, 556, 350, 278,
222 500, 500, 556, 1000, 1000, 834, 611, 722, 333, 333, 333, 333, 333, 333, 333, 333, 667, 333,
223 333, 278, 333, 333, 333, 1000, 722, 778, 778, 778, 778, 778, 584, 778, 722, 722, 722, 722, 667,
224 667, 611, 556, 1000, 556, 370, 556, 556, 889, 556, 611, 778, 1000, 365, 278, 278, 278, 278,
225 611, 889, 611, 611, 611, 278, 611, 584, 278, 611, 944, 611, 611, 556, 611, 556,
226];
227
228static TIMES_ROMAN_WIDTHS: [u16; 224] = [
229 250, 333, 408, 500, 500, 833, 778, 333, 333, 333, 500, 564, 250, 333, 250, 278, 500, 500, 500,
230 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444, 921, 722, 667, 667, 722, 611,
231 556, 722, 722, 333, 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944, 722,
232 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500,
233 278, 778, 500, 500, 500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541,
234 0, 500, 0, 333, 500, 444, 1000, 500, 500, 333, 1000, 556, 333, 889, 0, 611, 0, 0, 333, 333,
235 444, 444, 350, 500, 1000, 333, 980, 389, 333, 722, 0, 444, 722, 250, 333, 500, 500, 167, 500,
236 500, 500, 500, 180, 444, 500, 333, 333, 556, 556, 400, 500, 500, 500, 250, 500, 453, 350, 333,
237 444, 444, 500, 1000, 1000, 750, 444, 722, 333, 333, 333, 333, 333, 333, 333, 333, 611, 333,
238 333, 333, 333, 333, 333, 1000, 722, 722, 722, 722, 722, 722, 564, 722, 722, 722, 722, 722, 722,
239 556, 500, 444, 889, 444, 276, 444, 444, 667, 444, 611, 722, 889, 310, 278, 278, 278, 278, 500,
240 667, 500, 500, 500, 278, 500, 564, 278, 500, 722, 500, 500, 500, 500, 500,
241];
242
243static TIMES_BOLD_WIDTHS: [u16; 224] = [
244 250, 333, 555, 500, 500, 1000, 833, 333, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500,
245 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 930, 722, 667, 722, 722, 667,
246 611, 778, 778, 389, 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000, 722,
247 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556,
248 278, 833, 556, 500, 556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520,
249 0, 500, 0, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 1000, 0, 667, 0, 0, 333, 333,
250 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 0, 444, 722, 250, 333, 500, 500, 167, 500,
251 500, 500, 500, 278, 500, 500, 333, 333, 556, 556, 400, 500, 500, 500, 250, 556, 540, 350, 333,
252 500, 500, 500, 1000, 1000, 750, 500, 722, 333, 333, 333, 333, 333, 333, 333, 333, 667, 333,
253 333, 389, 333, 333, 333, 1000, 722, 778, 778, 778, 778, 778, 570, 778, 722, 722, 722, 722, 722,
254 611, 556, 500, 1000, 500, 300, 500, 500, 722, 444, 667, 778, 1000, 330, 278, 278, 278, 278,
255 500, 722, 500, 500, 500, 278, 500, 570, 278, 500, 722, 556, 556, 500, 556, 500,
256];
257
258static TIMES_ITALIC_WIDTHS: [u16; 224] = [
259 250, 333, 420, 500, 500, 833, 778, 333, 333, 333, 500, 675, 250, 333, 250, 278, 500, 500, 500,
260 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500, 920, 611, 611, 667, 722, 611,
261 611, 722, 722, 333, 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833, 611,
262 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444,
263 278, 722, 500, 500, 500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541,
264 0, 500, 0, 333, 500, 556, 889, 500, 500, 333, 1000, 500, 333, 944, 0, 556, 0, 0, 333, 333, 556,
265 556, 350, 500, 889, 333, 980, 389, 333, 667, 0, 389, 556, 250, 389, 500, 500, 167, 500, 500,
266 500, 500, 214, 556, 500, 333, 333, 500, 500, 400, 500, 500, 500, 250, 500, 523, 350, 333, 556,
267 556, 500, 889, 1000, 750, 500, 611, 333, 333, 333, 333, 333, 333, 333, 333, 611, 333, 333, 333,
268 333, 333, 333, 889, 667, 722, 722, 722, 722, 722, 675, 722, 722, 722, 722, 722, 556, 611, 500,
269 500, 889, 500, 276, 500, 500, 667, 444, 556, 722, 944, 310, 278, 278, 278, 278, 500, 667, 500,
270 500, 500, 278, 500, 675, 278, 500, 667, 500, 500, 444, 500, 444,
271];
272
273static TIMES_BOLD_ITALIC_WIDTHS: [u16; 224] = [
274 250, 389, 555, 500, 500, 833, 778, 333, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500,
275 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 832, 667, 667, 667, 722, 667,
276 667, 722, 778, 389, 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889, 667,
277 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500,
278 278, 778, 556, 500, 500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570,
279 0, 500, 0, 333, 500, 500, 1000, 500, 500, 333, 1000, 556, 333, 944, 0, 611, 0, 0, 333, 333,
280 500, 500, 350, 500, 1000, 333, 1000, 389, 333, 722, 0, 389, 611, 250, 389, 500, 500, 167, 500,
281 500, 500, 500, 278, 500, 500, 333, 333, 556, 556, 400, 500, 500, 500, 250, 576, 500, 350, 333,
282 500, 500, 500, 1000, 1000, 750, 500, 667, 333, 333, 333, 333, 333, 333, 333, 333, 667, 333,
283 333, 389, 333, 333, 333, 1000, 722, 722, 722, 722, 722, 722, 570, 722, 722, 722, 722, 722, 611,
284 611, 500, 500, 944, 500, 266, 500, 500, 722, 444, 611, 722, 944, 300, 278, 278, 278, 278, 500,
285 722, 500, 500, 500, 278, 500, 570, 278, 500, 722, 500, 556, 444, 500, 444,
286];
287
288static COURIER_WIDTHS: [u16; 224] = [
289 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
290 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
291 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
292 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
293 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
294 0, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 0, 0, 600, 600, 600,
295 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600,
296 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
297 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
298 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
299 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
300 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
301];
302
303static COURIER_BOLD_WIDTHS: [u16; 224] = [
304 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
305 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
306 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
307 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
308 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
309 0, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 0, 0, 600, 600, 600,
310 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600,
311 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
312 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
313 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
314 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
315 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
316];
317
318static COURIER_OBLIQUE_WIDTHS: [u16; 224] = [
319 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
320 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
321 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
322 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
323 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
324 0, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 0, 0, 600, 600, 600,
325 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600,
326 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
327 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
328 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
329 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
330 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
331];
332
333static COURIER_BOLD_OBLIQUE_WIDTHS: [u16; 224] = [
334 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
335 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
336 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
337 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
338 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
339 0, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 0, 0, 600, 600, 600,
340 600, 600, 600, 600, 600, 600, 600, 600, 600, 0, 600, 600, 600, 600, 600, 600, 600, 600, 600,
341 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
342 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
343 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
344 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
345 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
346];
347
348static SYMBOL_WIDTHS: [u16; 224] = [
349 250, 333, 713, 500, 549, 833, 778, 439, 333, 333, 500, 549, 250, 549, 250, 278, 500, 500, 500,
350 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444, 549, 722, 667, 722, 612, 611,
351 763, 603, 722, 333, 631, 722, 686, 889, 722, 722, 768, 741, 556, 592, 611, 690, 439, 768, 645,
352 795, 611, 333, 863, 333, 658, 500, 500, 631, 549, 549, 494, 439, 521, 411, 603, 329, 603, 549,
353 549, 576, 521, 549, 549, 521, 549, 603, 439, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549,
354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 750, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603, 400, 549,
356 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658, 823, 686, 795, 987,
357 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713, 768, 713, 790, 790, 890, 823, 549,
358 250, 713, 603, 603, 1042, 987, 603, 987, 603, 494, 329, 790, 790, 786, 713, 384, 384, 384, 384,
359 384, 384, 494, 494, 494, 494, 0, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494,
360 494, 494, 0,
361];
362
363static ZAPF_DINGBATS_WIDTHS: [u16; 224] = [
364 278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933, 911, 945, 974,
365 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537, 577, 692, 786, 788, 788, 790,
366 793, 794, 816, 823, 789, 841, 823, 833, 816, 831, 923, 744, 723, 749, 790, 792, 695, 776, 768,
367 792, 759, 707, 708, 682, 701, 826, 815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785,
368 791, 873, 761, 762, 762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668,
369 0, 390, 390, 317, 317, 276, 276, 509, 509, 410, 410, 234, 234, 334, 334, 0, 0, 0, 0, 0, 0, 0,
370 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788,
371 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788,
372 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788,
373 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834, 873, 828, 924, 924, 917, 930,
374 931, 463, 883, 836, 836, 867, 867, 696, 696, 874, 0, 874, 760, 946, 771, 865, 771, 888, 967,
375 888, 831, 873, 927, 970, 918, 0,
376];
377
378#[cfg(test)]
379mod tests {
380 use super::*;
381
382 #[test]
383 fn test_helvetica_known_widths() {
384 let m = StandardFont::Helvetica.metrics();
385 assert_eq!(m.widths[0], 278); assert_eq!(m.widths[33], 667); assert_eq!(m.widths[77], 833); }
390
391 #[test]
392 fn test_helvetica_bold_wider() {
393 let regular = StandardFont::Helvetica.metrics();
394 let bold = StandardFont::HelveticaBold.metrics();
395 assert_eq!(bold.widths[33], 722);
397 assert!(bold.widths[33] > regular.widths[33]);
398 }
399
400 #[test]
401 fn test_courier_monospaced() {
402 let m = StandardFont::Courier.metrics();
403 for &w in m.widths.iter() {
405 if w > 0 {
406 assert_eq!(w, 600, "Courier should be monospaced");
407 }
408 }
409 }
410
411 #[test]
412 fn test_char_width_calculation() {
413 let m = StandardFont::Helvetica.metrics();
414 let w = m.char_width(' ', 12.0);
416 assert!((w - 3.336).abs() < 0.001);
417 }
418
419 #[test]
420 fn test_measure_string() {
421 let m = StandardFont::Helvetica.metrics();
422 let w = m.measure_string("A", 12.0, 0.0);
423 assert!((w - 8.004).abs() < 0.001); }
425
426 #[test]
427 fn test_char_width_em_dash_uses_winansi() {
428 let m = StandardFont::Helvetica.metrics();
429 let w = m.char_width('\u{2014}', 10.0);
432 assert!(
433 (w - 10.0).abs() < 0.001,
434 "em dash should be 1000/1000 * 10 = 10.0, got {}",
435 w
436 );
437 }
438
439 #[test]
440 fn test_char_width_en_dash_uses_winansi() {
441 let m = StandardFont::Helvetica.metrics();
442 let w = m.char_width('\u{2013}', 10.0);
445 assert!(
446 (w - 5.56).abs() < 0.001,
447 "en dash should be 556/1000 * 10 = 5.56, got {}",
448 w
449 );
450 }
451
452 #[test]
453 fn test_unicode_to_winansi_mappings() {
454 assert_eq!(unicode_to_winansi('\u{2014}'), Some(0x97)); assert_eq!(unicode_to_winansi('\u{2013}'), Some(0x96)); assert_eq!(unicode_to_winansi('\u{201C}'), Some(0x93)); assert_eq!(unicode_to_winansi('\u{2026}'), Some(0x85)); assert_eq!(unicode_to_winansi('A'), Some(0x41)); assert_eq!(unicode_to_winansi('\u{4E00}'), None); }
461}