1fn strip_subset_prefix(base_font: &str) -> &str {
14 let bytes = base_font.as_bytes();
15 if bytes.len() > 7 && bytes[6] == b'+' && bytes[..6].iter().all(u8::is_ascii_uppercase) {
20 &base_font[7..]
21 } else {
22 base_font
23 }
24}
25
26#[derive(Clone, Copy, PartialEq, Eq, Debug)]
28enum Family {
29 Helvetica,
30 Times,
31 Courier,
32}
33
34const FAMILY_STEMS: &[(&str, Family)] = &[
42 ("timesnewromanps", Family::Times),
43 ("timesnewroman", Family::Times),
44 ("couriernew", Family::Courier),
45 ("helvetica", Family::Helvetica),
46 ("courier", Family::Courier),
47 ("arial", Family::Helvetica),
48 ("times", Family::Times),
49];
50
51const STYLE_TOKENS: &[&str] = &[
59 "oblique", "regular", "italic", "roman", "bold", "book", "psmt", "ps", "mt",
60];
61
62fn strip_style_tokens(mut rest: &str) -> Option<(bool, bool)> {
67 let mut bold = false;
68 let mut italic = false;
69 while !rest.is_empty() {
70 let tok = *STYLE_TOKENS.iter().find(|&&t| rest.starts_with(t))?;
71 match tok {
72 "bold" => bold = true,
73 "italic" | "oblique" => italic = true,
74 _ => {}
75 }
76 rest = &rest[tok.len()..];
77 }
78 Some((bold, italic))
79}
80
81fn classify(base_font: &str) -> Option<(Family, bool, bool)> {
101 let stripped = strip_subset_prefix(base_font);
102 let lower = stripped.to_lowercase();
103 let compact: String = lower
104 .chars()
105 .filter(|c| !matches!(c, '-' | ',' | ' '))
106 .collect();
107 let (family, rest) = FAMILY_STEMS
108 .iter()
109 .find_map(|&(stem, family)| compact.strip_prefix(stem).map(|rest| (family, rest)))?;
110 let (bold, italic) = strip_style_tokens(rest)?;
111 Some((family, bold, italic))
112}
113
114fn lookup(table: &[(&str, u16)], glyph_name: &str) -> Option<f32> {
116 table
117 .binary_search_by_key(&glyph_name, |&(name, _)| name)
118 .ok()
119 .map(|i| table[i].1 as f32)
120}
121
122pub fn standard_14_width(base_font: &str, glyph_name: &str) -> Option<f32> {
133 let (family, bold, italic) = classify(base_font)?;
134 match family {
135 Family::Courier => Some(600.0),
136 Family::Helvetica => {
137 let table = if bold { HELVETICA_BOLD } else { HELVETICA };
138 lookup(table, glyph_name)
139 }
140 Family::Times => {
141 let table = match (bold, italic) {
142 (true, true) => TIMES_BOLD_ITALIC,
143 (true, false) => TIMES_BOLD,
144 (false, true) => TIMES_ITALIC,
145 (false, false) => TIMES_ROMAN,
146 };
147 lookup(table, glyph_name)
148 }
149 }
150}
151
152pub fn is_standard_14(base_font: &str) -> bool {
155 classify(base_font).is_some()
156}
157
158#[rustfmt::skip]
161const HELVETICA: &[(&str, u16)] = &[
162 ("A", 667),
163 ("AE", 1000),
164 ("Aacute", 667),
165 ("Acircumflex", 667),
166 ("Adieresis", 667),
167 ("Agrave", 667),
168 ("Aring", 667),
169 ("Atilde", 667),
170 ("B", 667),
171 ("C", 722),
172 ("Ccedilla", 722),
173 ("D", 722),
174 ("E", 667),
175 ("Eacute", 667),
176 ("Ecircumflex", 667),
177 ("Edieresis", 667),
178 ("Egrave", 667),
179 ("Eth", 722),
180 ("F", 611),
181 ("G", 778),
182 ("H", 722),
183 ("I", 278),
184 ("Iacute", 278),
185 ("Icircumflex", 278),
186 ("Idieresis", 278),
187 ("Igrave", 278),
188 ("J", 500),
189 ("K", 667),
190 ("L", 556),
191 ("Lslash", 556),
192 ("M", 833),
193 ("N", 722),
194 ("Ntilde", 722),
195 ("O", 778),
196 ("OE", 1000),
197 ("Oacute", 778),
198 ("Ocircumflex", 778),
199 ("Odieresis", 778),
200 ("Ograve", 778),
201 ("Oslash", 778),
202 ("Otilde", 778),
203 ("P", 667),
204 ("Q", 778),
205 ("R", 722),
206 ("S", 667),
207 ("Scaron", 667),
208 ("T", 611),
209 ("Thorn", 667),
210 ("U", 722),
211 ("Uacute", 722),
212 ("Ucircumflex", 722),
213 ("Udieresis", 722),
214 ("Ugrave", 722),
215 ("V", 667),
216 ("W", 944),
217 ("X", 667),
218 ("Y", 667),
219 ("Yacute", 667),
220 ("Ydieresis", 667),
221 ("Z", 611),
222 ("Zcaron", 611),
223 ("a", 556),
224 ("aacute", 556),
225 ("acircumflex", 556),
226 ("acute", 333),
227 ("adieresis", 556),
228 ("ae", 889),
229 ("agrave", 556),
230 ("ampersand", 667),
231 ("aring", 556),
232 ("asciicircum", 469),
233 ("asciitilde", 584),
234 ("asterisk", 389),
235 ("at", 1015),
236 ("atilde", 556),
237 ("b", 556),
238 ("backslash", 278),
239 ("bar", 260),
240 ("braceleft", 334),
241 ("braceright", 334),
242 ("bracketleft", 278),
243 ("bracketright", 278),
244 ("breve", 333),
245 ("brokenbar", 260),
246 ("bullet", 350),
247 ("c", 500),
248 ("caron", 333),
249 ("ccedilla", 500),
250 ("cedilla", 333),
251 ("cent", 556),
252 ("circumflex", 333),
253 ("colon", 278),
254 ("comma", 278),
255 ("copyright", 737),
256 ("currency", 556),
257 ("d", 556),
258 ("dagger", 556),
259 ("daggerdbl", 556),
260 ("degree", 400),
261 ("dieresis", 333),
262 ("divide", 584),
263 ("dollar", 556),
264 ("dotaccent", 333),
265 ("dotlessi", 278),
266 ("e", 556),
267 ("eacute", 556),
268 ("ecircumflex", 556),
269 ("edieresis", 556),
270 ("egrave", 556),
271 ("eight", 556),
272 ("ellipsis", 1000),
273 ("emdash", 1000),
274 ("endash", 556),
275 ("equal", 584),
276 ("eth", 556),
277 ("exclam", 278),
278 ("exclamdown", 333),
279 ("f", 278),
280 ("fi", 500),
281 ("five", 556),
282 ("fl", 500),
283 ("florin", 556),
284 ("four", 556),
285 ("fraction", 167),
286 ("g", 556),
287 ("germandbls", 611),
288 ("grave", 333),
289 ("greater", 584),
290 ("guillemotleft", 556),
291 ("guillemotright", 556),
292 ("guilsinglleft", 333),
293 ("guilsinglright", 333),
294 ("h", 556),
295 ("hungarumlaut", 333),
296 ("hyphen", 333),
297 ("i", 222),
298 ("iacute", 278),
299 ("icircumflex", 278),
300 ("idieresis", 278),
301 ("igrave", 278),
302 ("j", 222),
303 ("k", 500),
304 ("l", 222),
305 ("less", 584),
306 ("logicalnot", 584),
307 ("lslash", 222),
308 ("m", 833),
309 ("macron", 333),
310 ("minus", 584),
311 ("mu", 556),
312 ("multiply", 584),
313 ("n", 556),
314 ("nine", 556),
315 ("ntilde", 556),
316 ("numbersign", 556),
317 ("o", 556),
318 ("oacute", 556),
319 ("ocircumflex", 556),
320 ("odieresis", 556),
321 ("oe", 944),
322 ("ogonek", 333),
323 ("ograve", 556),
324 ("one", 556),
325 ("onehalf", 834),
326 ("onequarter", 834),
327 ("onesuperior", 333),
328 ("ordfeminine", 370),
329 ("ordmasculine", 365),
330 ("oslash", 611),
331 ("otilde", 556),
332 ("p", 556),
333 ("paragraph", 537),
334 ("parenleft", 333),
335 ("parenright", 333),
336 ("percent", 889),
337 ("period", 278),
338 ("periodcentered", 278),
339 ("perthousand", 1000),
340 ("plus", 584),
341 ("plusminus", 584),
342 ("q", 556),
343 ("question", 556),
344 ("questiondown", 611),
345 ("quotedbl", 355),
346 ("quotedblbase", 333),
347 ("quotedblleft", 333),
348 ("quotedblright", 333),
349 ("quoteleft", 222),
350 ("quoteright", 222),
351 ("quotesinglbase", 222),
352 ("quotesingle", 191),
353 ("r", 333),
354 ("registered", 737),
355 ("ring", 333),
356 ("s", 500),
357 ("scaron", 500),
358 ("section", 556),
359 ("semicolon", 278),
360 ("seven", 556),
361 ("six", 556),
362 ("slash", 278),
363 ("space", 278),
364 ("sterling", 556),
365 ("t", 278),
366 ("thorn", 556),
367 ("three", 556),
368 ("threequarters", 834),
369 ("threesuperior", 333),
370 ("tilde", 333),
371 ("trademark", 1000),
372 ("two", 556),
373 ("twosuperior", 333),
374 ("u", 556),
375 ("uacute", 556),
376 ("ucircumflex", 556),
377 ("udieresis", 556),
378 ("ugrave", 556),
379 ("underscore", 556),
380 ("v", 500),
381 ("w", 722),
382 ("x", 500),
383 ("y", 500),
384 ("yacute", 500),
385 ("ydieresis", 500),
386 ("yen", 556),
387 ("z", 500),
388 ("zcaron", 500),
389 ("zero", 556),
390];
391
392#[rustfmt::skip]
395const HELVETICA_BOLD: &[(&str, u16)] = &[
396 ("A", 722),
397 ("AE", 1000),
398 ("Aacute", 722),
399 ("Acircumflex", 722),
400 ("Adieresis", 722),
401 ("Agrave", 722),
402 ("Aring", 722),
403 ("Atilde", 722),
404 ("B", 722),
405 ("C", 722),
406 ("Ccedilla", 722),
407 ("D", 722),
408 ("E", 667),
409 ("Eacute", 667),
410 ("Ecircumflex", 667),
411 ("Edieresis", 667),
412 ("Egrave", 667),
413 ("Eth", 722),
414 ("F", 611),
415 ("G", 778),
416 ("H", 722),
417 ("I", 278),
418 ("Iacute", 278),
419 ("Icircumflex", 278),
420 ("Idieresis", 278),
421 ("Igrave", 278),
422 ("J", 556),
423 ("K", 722),
424 ("L", 611),
425 ("Lslash", 611),
426 ("M", 833),
427 ("N", 722),
428 ("Ntilde", 722),
429 ("O", 778),
430 ("OE", 1000),
431 ("Oacute", 778),
432 ("Ocircumflex", 778),
433 ("Odieresis", 778),
434 ("Ograve", 778),
435 ("Oslash", 778),
436 ("Otilde", 778),
437 ("P", 667),
438 ("Q", 778),
439 ("R", 722),
440 ("S", 667),
441 ("Scaron", 667),
442 ("T", 611),
443 ("Thorn", 667),
444 ("U", 722),
445 ("Uacute", 722),
446 ("Ucircumflex", 722),
447 ("Udieresis", 722),
448 ("Ugrave", 722),
449 ("V", 667),
450 ("W", 944),
451 ("X", 667),
452 ("Y", 667),
453 ("Yacute", 667),
454 ("Ydieresis", 667),
455 ("Z", 611),
456 ("Zcaron", 611),
457 ("a", 556),
458 ("aacute", 556),
459 ("acircumflex", 556),
460 ("acute", 333),
461 ("adieresis", 556),
462 ("ae", 889),
463 ("agrave", 556),
464 ("ampersand", 722),
465 ("aring", 556),
466 ("asciicircum", 584),
467 ("asciitilde", 584),
468 ("asterisk", 389),
469 ("at", 975),
470 ("atilde", 556),
471 ("b", 611),
472 ("backslash", 278),
473 ("bar", 280),
474 ("braceleft", 389),
475 ("braceright", 389),
476 ("bracketleft", 333),
477 ("bracketright", 333),
478 ("breve", 333),
479 ("brokenbar", 280),
480 ("bullet", 350),
481 ("c", 556),
482 ("caron", 333),
483 ("ccedilla", 556),
484 ("cedilla", 333),
485 ("cent", 556),
486 ("circumflex", 333),
487 ("colon", 333),
488 ("comma", 278),
489 ("copyright", 737),
490 ("currency", 556),
491 ("d", 611),
492 ("dagger", 556),
493 ("daggerdbl", 556),
494 ("degree", 400),
495 ("dieresis", 333),
496 ("divide", 584),
497 ("dollar", 556),
498 ("dotaccent", 333),
499 ("dotlessi", 278),
500 ("e", 556),
501 ("eacute", 556),
502 ("ecircumflex", 556),
503 ("edieresis", 556),
504 ("egrave", 556),
505 ("eight", 556),
506 ("ellipsis", 1000),
507 ("emdash", 1000),
508 ("endash", 556),
509 ("equal", 584),
510 ("eth", 611),
511 ("exclam", 333),
512 ("exclamdown", 333),
513 ("f", 333),
514 ("fi", 611),
515 ("five", 556),
516 ("fl", 611),
517 ("florin", 556),
518 ("four", 556),
519 ("fraction", 167),
520 ("g", 611),
521 ("germandbls", 611),
522 ("grave", 333),
523 ("greater", 584),
524 ("guillemotleft", 556),
525 ("guillemotright", 556),
526 ("guilsinglleft", 333),
527 ("guilsinglright", 333),
528 ("h", 611),
529 ("hungarumlaut", 333),
530 ("hyphen", 333),
531 ("i", 278),
532 ("iacute", 278),
533 ("icircumflex", 278),
534 ("idieresis", 278),
535 ("igrave", 278),
536 ("j", 278),
537 ("k", 556),
538 ("l", 278),
539 ("less", 584),
540 ("logicalnot", 584),
541 ("lslash", 278),
542 ("m", 889),
543 ("macron", 333),
544 ("minus", 584),
545 ("mu", 611),
546 ("multiply", 584),
547 ("n", 611),
548 ("nine", 556),
549 ("ntilde", 611),
550 ("numbersign", 556),
551 ("o", 611),
552 ("oacute", 611),
553 ("ocircumflex", 611),
554 ("odieresis", 611),
555 ("oe", 944),
556 ("ogonek", 333),
557 ("ograve", 611),
558 ("one", 556),
559 ("onehalf", 834),
560 ("onequarter", 834),
561 ("onesuperior", 333),
562 ("ordfeminine", 370),
563 ("ordmasculine", 365),
564 ("oslash", 611),
565 ("otilde", 611),
566 ("p", 611),
567 ("paragraph", 556),
568 ("parenleft", 333),
569 ("parenright", 333),
570 ("percent", 889),
571 ("period", 278),
572 ("periodcentered", 278),
573 ("perthousand", 1000),
574 ("plus", 584),
575 ("plusminus", 584),
576 ("q", 611),
577 ("question", 611),
578 ("questiondown", 611),
579 ("quotedbl", 474),
580 ("quotedblbase", 500),
581 ("quotedblleft", 500),
582 ("quotedblright", 500),
583 ("quoteleft", 278),
584 ("quoteright", 278),
585 ("quotesinglbase", 278),
586 ("quotesingle", 238),
587 ("r", 389),
588 ("registered", 737),
589 ("ring", 333),
590 ("s", 556),
591 ("scaron", 556),
592 ("section", 556),
593 ("semicolon", 333),
594 ("seven", 556),
595 ("six", 556),
596 ("slash", 278),
597 ("space", 278),
598 ("sterling", 556),
599 ("t", 333),
600 ("thorn", 611),
601 ("three", 556),
602 ("threequarters", 834),
603 ("threesuperior", 333),
604 ("tilde", 333),
605 ("trademark", 1000),
606 ("two", 556),
607 ("twosuperior", 333),
608 ("u", 611),
609 ("uacute", 611),
610 ("ucircumflex", 611),
611 ("udieresis", 611),
612 ("ugrave", 611),
613 ("underscore", 556),
614 ("v", 556),
615 ("w", 778),
616 ("x", 556),
617 ("y", 556),
618 ("yacute", 556),
619 ("ydieresis", 556),
620 ("yen", 556),
621 ("z", 500),
622 ("zcaron", 500),
623 ("zero", 556),
624];
625
626#[rustfmt::skip]
629const TIMES_ROMAN: &[(&str, u16)] = &[
630 ("A", 722),
631 ("AE", 889),
632 ("Aacute", 722),
633 ("Acircumflex", 722),
634 ("Adieresis", 722),
635 ("Agrave", 722),
636 ("Aring", 722),
637 ("Atilde", 722),
638 ("B", 667),
639 ("C", 667),
640 ("Ccedilla", 667),
641 ("D", 722),
642 ("E", 611),
643 ("Eacute", 611),
644 ("Ecircumflex", 611),
645 ("Edieresis", 611),
646 ("Egrave", 611),
647 ("Eth", 722),
648 ("F", 556),
649 ("G", 722),
650 ("H", 722),
651 ("I", 333),
652 ("Iacute", 333),
653 ("Icircumflex", 333),
654 ("Idieresis", 333),
655 ("Igrave", 333),
656 ("J", 389),
657 ("K", 722),
658 ("L", 611),
659 ("Lslash", 611),
660 ("M", 889),
661 ("N", 722),
662 ("Ntilde", 722),
663 ("O", 722),
664 ("OE", 889),
665 ("Oacute", 722),
666 ("Ocircumflex", 722),
667 ("Odieresis", 722),
668 ("Ograve", 722),
669 ("Oslash", 722),
670 ("Otilde", 722),
671 ("P", 556),
672 ("Q", 722),
673 ("R", 667),
674 ("S", 556),
675 ("Scaron", 556),
676 ("T", 611),
677 ("Thorn", 556),
678 ("U", 722),
679 ("Uacute", 722),
680 ("Ucircumflex", 722),
681 ("Udieresis", 722),
682 ("Ugrave", 722),
683 ("V", 722),
684 ("W", 944),
685 ("X", 722),
686 ("Y", 722),
687 ("Yacute", 722),
688 ("Ydieresis", 722),
689 ("Z", 611),
690 ("Zcaron", 611),
691 ("a", 444),
692 ("aacute", 444),
693 ("acircumflex", 444),
694 ("acute", 333),
695 ("adieresis", 444),
696 ("ae", 667),
697 ("agrave", 444),
698 ("ampersand", 778),
699 ("aring", 444),
700 ("asciicircum", 469),
701 ("asciitilde", 541),
702 ("asterisk", 500),
703 ("at", 921),
704 ("atilde", 444),
705 ("b", 500),
706 ("backslash", 278),
707 ("bar", 200),
708 ("braceleft", 480),
709 ("braceright", 480),
710 ("bracketleft", 333),
711 ("bracketright", 333),
712 ("breve", 333),
713 ("brokenbar", 200),
714 ("bullet", 350),
715 ("c", 444),
716 ("caron", 333),
717 ("ccedilla", 444),
718 ("cedilla", 333),
719 ("cent", 500),
720 ("circumflex", 333),
721 ("colon", 278),
722 ("comma", 250),
723 ("copyright", 760),
724 ("currency", 500),
725 ("d", 500),
726 ("dagger", 500),
727 ("daggerdbl", 500),
728 ("degree", 400),
729 ("dieresis", 333),
730 ("divide", 564),
731 ("dollar", 500),
732 ("dotaccent", 333),
733 ("dotlessi", 278),
734 ("e", 444),
735 ("eacute", 444),
736 ("ecircumflex", 444),
737 ("edieresis", 444),
738 ("egrave", 444),
739 ("eight", 500),
740 ("ellipsis", 1000),
741 ("emdash", 1000),
742 ("endash", 500),
743 ("equal", 564),
744 ("eth", 500),
745 ("exclam", 333),
746 ("exclamdown", 333),
747 ("f", 333),
748 ("fi", 556),
749 ("five", 500),
750 ("fl", 556),
751 ("florin", 500),
752 ("four", 500),
753 ("fraction", 167),
754 ("g", 500),
755 ("germandbls", 500),
756 ("grave", 333),
757 ("greater", 564),
758 ("guillemotleft", 500),
759 ("guillemotright", 500),
760 ("guilsinglleft", 333),
761 ("guilsinglright", 333),
762 ("h", 500),
763 ("hungarumlaut", 333),
764 ("hyphen", 333),
765 ("i", 278),
766 ("iacute", 278),
767 ("icircumflex", 278),
768 ("idieresis", 278),
769 ("igrave", 278),
770 ("j", 278),
771 ("k", 500),
772 ("l", 278),
773 ("less", 564),
774 ("logicalnot", 564),
775 ("lslash", 278),
776 ("m", 778),
777 ("macron", 333),
778 ("minus", 564),
779 ("mu", 500),
780 ("multiply", 564),
781 ("n", 500),
782 ("nine", 500),
783 ("ntilde", 500),
784 ("numbersign", 500),
785 ("o", 500),
786 ("oacute", 500),
787 ("ocircumflex", 500),
788 ("odieresis", 500),
789 ("oe", 722),
790 ("ogonek", 333),
791 ("ograve", 500),
792 ("one", 500),
793 ("onehalf", 750),
794 ("onequarter", 750),
795 ("onesuperior", 300),
796 ("ordfeminine", 276),
797 ("ordmasculine", 310),
798 ("oslash", 500),
799 ("otilde", 500),
800 ("p", 500),
801 ("paragraph", 453),
802 ("parenleft", 333),
803 ("parenright", 333),
804 ("percent", 833),
805 ("period", 250),
806 ("periodcentered", 250),
807 ("perthousand", 1000),
808 ("plus", 564),
809 ("plusminus", 564),
810 ("q", 500),
811 ("question", 444),
812 ("questiondown", 444),
813 ("quotedbl", 408),
814 ("quotedblbase", 444),
815 ("quotedblleft", 444),
816 ("quotedblright", 444),
817 ("quoteleft", 333),
818 ("quoteright", 333),
819 ("quotesinglbase", 333),
820 ("quotesingle", 180),
821 ("r", 333),
822 ("registered", 760),
823 ("ring", 333),
824 ("s", 389),
825 ("scaron", 389),
826 ("section", 500),
827 ("semicolon", 278),
828 ("seven", 500),
829 ("six", 500),
830 ("slash", 278),
831 ("space", 250),
832 ("sterling", 500),
833 ("t", 278),
834 ("thorn", 500),
835 ("three", 500),
836 ("threequarters", 750),
837 ("threesuperior", 300),
838 ("tilde", 333),
839 ("trademark", 980),
840 ("two", 500),
841 ("twosuperior", 300),
842 ("u", 500),
843 ("uacute", 500),
844 ("ucircumflex", 500),
845 ("udieresis", 500),
846 ("ugrave", 500),
847 ("underscore", 500),
848 ("v", 500),
849 ("w", 722),
850 ("x", 500),
851 ("y", 500),
852 ("yacute", 500),
853 ("ydieresis", 500),
854 ("yen", 500),
855 ("z", 444),
856 ("zcaron", 444),
857 ("zero", 500),
858];
859
860#[rustfmt::skip]
863const TIMES_BOLD: &[(&str, u16)] = &[
864 ("A", 722),
865 ("AE", 1000),
866 ("Aacute", 722),
867 ("Acircumflex", 722),
868 ("Adieresis", 722),
869 ("Agrave", 722),
870 ("Aring", 722),
871 ("Atilde", 722),
872 ("B", 667),
873 ("C", 722),
874 ("Ccedilla", 722),
875 ("D", 722),
876 ("E", 667),
877 ("Eacute", 667),
878 ("Ecircumflex", 667),
879 ("Edieresis", 667),
880 ("Egrave", 667),
881 ("Eth", 722),
882 ("F", 611),
883 ("G", 778),
884 ("H", 778),
885 ("I", 389),
886 ("Iacute", 389),
887 ("Icircumflex", 389),
888 ("Idieresis", 389),
889 ("Igrave", 389),
890 ("J", 500),
891 ("K", 778),
892 ("L", 667),
893 ("Lslash", 667),
894 ("M", 944),
895 ("N", 722),
896 ("Ntilde", 722),
897 ("O", 778),
898 ("OE", 1000),
899 ("Oacute", 778),
900 ("Ocircumflex", 778),
901 ("Odieresis", 778),
902 ("Ograve", 778),
903 ("Oslash", 778),
904 ("Otilde", 778),
905 ("P", 611),
906 ("Q", 778),
907 ("R", 722),
908 ("S", 556),
909 ("Scaron", 556),
910 ("T", 667),
911 ("Thorn", 611),
912 ("U", 722),
913 ("Uacute", 722),
914 ("Ucircumflex", 722),
915 ("Udieresis", 722),
916 ("Ugrave", 722),
917 ("V", 722),
918 ("W", 1000),
919 ("X", 722),
920 ("Y", 722),
921 ("Yacute", 722),
922 ("Ydieresis", 722),
923 ("Z", 667),
924 ("Zcaron", 667),
925 ("a", 500),
926 ("aacute", 500),
927 ("acircumflex", 500),
928 ("acute", 333),
929 ("adieresis", 500),
930 ("ae", 722),
931 ("agrave", 500),
932 ("ampersand", 833),
933 ("aring", 500),
934 ("asciicircum", 581),
935 ("asciitilde", 520),
936 ("asterisk", 500),
937 ("at", 930),
938 ("atilde", 500),
939 ("b", 556),
940 ("backslash", 278),
941 ("bar", 220),
942 ("braceleft", 394),
943 ("braceright", 394),
944 ("bracketleft", 333),
945 ("bracketright", 333),
946 ("breve", 333),
947 ("brokenbar", 220),
948 ("bullet", 350),
949 ("c", 444),
950 ("caron", 333),
951 ("ccedilla", 444),
952 ("cedilla", 333),
953 ("cent", 500),
954 ("circumflex", 333),
955 ("colon", 333),
956 ("comma", 250),
957 ("copyright", 747),
958 ("currency", 500),
959 ("d", 556),
960 ("dagger", 500),
961 ("daggerdbl", 500),
962 ("degree", 400),
963 ("dieresis", 333),
964 ("divide", 570),
965 ("dollar", 500),
966 ("dotaccent", 333),
967 ("dotlessi", 278),
968 ("e", 444),
969 ("eacute", 444),
970 ("ecircumflex", 444),
971 ("edieresis", 444),
972 ("egrave", 444),
973 ("eight", 500),
974 ("ellipsis", 1000),
975 ("emdash", 1000),
976 ("endash", 500),
977 ("equal", 570),
978 ("eth", 500),
979 ("exclam", 333),
980 ("exclamdown", 333),
981 ("f", 333),
982 ("fi", 556),
983 ("five", 500),
984 ("fl", 556),
985 ("florin", 500),
986 ("four", 500),
987 ("fraction", 167),
988 ("g", 500),
989 ("germandbls", 556),
990 ("grave", 333),
991 ("greater", 570),
992 ("guillemotleft", 500),
993 ("guillemotright", 500),
994 ("guilsinglleft", 333),
995 ("guilsinglright", 333),
996 ("h", 556),
997 ("hungarumlaut", 333),
998 ("hyphen", 333),
999 ("i", 278),
1000 ("iacute", 278),
1001 ("icircumflex", 278),
1002 ("idieresis", 278),
1003 ("igrave", 278),
1004 ("j", 333),
1005 ("k", 556),
1006 ("l", 278),
1007 ("less", 570),
1008 ("logicalnot", 570),
1009 ("lslash", 278),
1010 ("m", 833),
1011 ("macron", 333),
1012 ("minus", 570),
1013 ("mu", 556),
1014 ("multiply", 570),
1015 ("n", 556),
1016 ("nine", 500),
1017 ("ntilde", 556),
1018 ("numbersign", 500),
1019 ("o", 500),
1020 ("oacute", 500),
1021 ("ocircumflex", 500),
1022 ("odieresis", 500),
1023 ("oe", 722),
1024 ("ogonek", 333),
1025 ("ograve", 500),
1026 ("one", 500),
1027 ("onehalf", 750),
1028 ("onequarter", 750),
1029 ("onesuperior", 300),
1030 ("ordfeminine", 300),
1031 ("ordmasculine", 330),
1032 ("oslash", 500),
1033 ("otilde", 500),
1034 ("p", 556),
1035 ("paragraph", 540),
1036 ("parenleft", 333),
1037 ("parenright", 333),
1038 ("percent", 1000),
1039 ("period", 250),
1040 ("periodcentered", 250),
1041 ("perthousand", 1000),
1042 ("plus", 570),
1043 ("plusminus", 570),
1044 ("q", 556),
1045 ("question", 500),
1046 ("questiondown", 500),
1047 ("quotedbl", 555),
1048 ("quotedblbase", 500),
1049 ("quotedblleft", 500),
1050 ("quotedblright", 500),
1051 ("quoteleft", 333),
1052 ("quoteright", 333),
1053 ("quotesinglbase", 333),
1054 ("quotesingle", 278),
1055 ("r", 444),
1056 ("registered", 747),
1057 ("ring", 333),
1058 ("s", 389),
1059 ("scaron", 389),
1060 ("section", 500),
1061 ("semicolon", 333),
1062 ("seven", 500),
1063 ("six", 500),
1064 ("slash", 278),
1065 ("space", 250),
1066 ("sterling", 500),
1067 ("t", 333),
1068 ("thorn", 556),
1069 ("three", 500),
1070 ("threequarters", 750),
1071 ("threesuperior", 300),
1072 ("tilde", 333),
1073 ("trademark", 1000),
1074 ("two", 500),
1075 ("twosuperior", 300),
1076 ("u", 556),
1077 ("uacute", 556),
1078 ("ucircumflex", 556),
1079 ("udieresis", 556),
1080 ("ugrave", 556),
1081 ("underscore", 500),
1082 ("v", 500),
1083 ("w", 722),
1084 ("x", 500),
1085 ("y", 500),
1086 ("yacute", 500),
1087 ("ydieresis", 500),
1088 ("yen", 500),
1089 ("z", 444),
1090 ("zcaron", 444),
1091 ("zero", 500),
1092];
1093
1094#[rustfmt::skip]
1097const TIMES_ITALIC: &[(&str, u16)] = &[
1098 ("A", 611),
1099 ("AE", 889),
1100 ("Aacute", 611),
1101 ("Acircumflex", 611),
1102 ("Adieresis", 611),
1103 ("Agrave", 611),
1104 ("Aring", 611),
1105 ("Atilde", 611),
1106 ("B", 611),
1107 ("C", 667),
1108 ("Ccedilla", 667),
1109 ("D", 722),
1110 ("E", 611),
1111 ("Eacute", 611),
1112 ("Ecircumflex", 611),
1113 ("Edieresis", 611),
1114 ("Egrave", 611),
1115 ("Eth", 722),
1116 ("F", 611),
1117 ("G", 722),
1118 ("H", 722),
1119 ("I", 333),
1120 ("Iacute", 333),
1121 ("Icircumflex", 333),
1122 ("Idieresis", 333),
1123 ("Igrave", 333),
1124 ("J", 444),
1125 ("K", 667),
1126 ("L", 556),
1127 ("Lslash", 556),
1128 ("M", 833),
1129 ("N", 667),
1130 ("Ntilde", 667),
1131 ("O", 722),
1132 ("OE", 944),
1133 ("Oacute", 722),
1134 ("Ocircumflex", 722),
1135 ("Odieresis", 722),
1136 ("Ograve", 722),
1137 ("Oslash", 722),
1138 ("Otilde", 722),
1139 ("P", 611),
1140 ("Q", 722),
1141 ("R", 611),
1142 ("S", 500),
1143 ("Scaron", 500),
1144 ("T", 556),
1145 ("Thorn", 611),
1146 ("U", 722),
1147 ("Uacute", 722),
1148 ("Ucircumflex", 722),
1149 ("Udieresis", 722),
1150 ("Ugrave", 722),
1151 ("V", 611),
1152 ("W", 833),
1153 ("X", 611),
1154 ("Y", 556),
1155 ("Yacute", 556),
1156 ("Ydieresis", 556),
1157 ("Z", 556),
1158 ("Zcaron", 556),
1159 ("a", 500),
1160 ("aacute", 500),
1161 ("acircumflex", 500),
1162 ("acute", 333),
1163 ("adieresis", 500),
1164 ("ae", 667),
1165 ("agrave", 500),
1166 ("ampersand", 778),
1167 ("aring", 500),
1168 ("asciicircum", 422),
1169 ("asciitilde", 541),
1170 ("asterisk", 500),
1171 ("at", 920),
1172 ("atilde", 500),
1173 ("b", 500),
1174 ("backslash", 278),
1175 ("bar", 275),
1176 ("braceleft", 400),
1177 ("braceright", 400),
1178 ("bracketleft", 389),
1179 ("bracketright", 389),
1180 ("breve", 333),
1181 ("brokenbar", 275),
1182 ("bullet", 350),
1183 ("c", 444),
1184 ("caron", 333),
1185 ("ccedilla", 444),
1186 ("cedilla", 333),
1187 ("cent", 500),
1188 ("circumflex", 333),
1189 ("colon", 333),
1190 ("comma", 250),
1191 ("copyright", 760),
1192 ("currency", 500),
1193 ("d", 500),
1194 ("dagger", 500),
1195 ("daggerdbl", 500),
1196 ("degree", 400),
1197 ("dieresis", 333),
1198 ("divide", 675),
1199 ("dollar", 500),
1200 ("dotaccent", 333),
1201 ("dotlessi", 278),
1202 ("e", 444),
1203 ("eacute", 444),
1204 ("ecircumflex", 444),
1205 ("edieresis", 444),
1206 ("egrave", 444),
1207 ("eight", 500),
1208 ("ellipsis", 889),
1209 ("emdash", 889),
1210 ("endash", 500),
1211 ("equal", 675),
1212 ("eth", 500),
1213 ("exclam", 333),
1214 ("exclamdown", 389),
1215 ("f", 278),
1216 ("fi", 500),
1217 ("five", 500),
1218 ("fl", 500),
1219 ("florin", 500),
1220 ("four", 500),
1221 ("fraction", 167),
1222 ("g", 500),
1223 ("germandbls", 500),
1224 ("grave", 333),
1225 ("greater", 675),
1226 ("guillemotleft", 500),
1227 ("guillemotright", 500),
1228 ("guilsinglleft", 333),
1229 ("guilsinglright", 333),
1230 ("h", 500),
1231 ("hungarumlaut", 333),
1232 ("hyphen", 333),
1233 ("i", 278),
1234 ("iacute", 278),
1235 ("icircumflex", 278),
1236 ("idieresis", 278),
1237 ("igrave", 278),
1238 ("j", 278),
1239 ("k", 444),
1240 ("l", 278),
1241 ("less", 675),
1242 ("logicalnot", 675),
1243 ("lslash", 278),
1244 ("m", 722),
1245 ("macron", 333),
1246 ("minus", 675),
1247 ("mu", 500),
1248 ("multiply", 675),
1249 ("n", 500),
1250 ("nine", 500),
1251 ("ntilde", 500),
1252 ("numbersign", 500),
1253 ("o", 500),
1254 ("oacute", 500),
1255 ("ocircumflex", 500),
1256 ("odieresis", 500),
1257 ("oe", 667),
1258 ("ogonek", 333),
1259 ("ograve", 500),
1260 ("one", 500),
1261 ("onehalf", 750),
1262 ("onequarter", 750),
1263 ("onesuperior", 300),
1264 ("ordfeminine", 276),
1265 ("ordmasculine", 310),
1266 ("oslash", 500),
1267 ("otilde", 500),
1268 ("p", 500),
1269 ("paragraph", 523),
1270 ("parenleft", 333),
1271 ("parenright", 333),
1272 ("percent", 833),
1273 ("period", 250),
1274 ("periodcentered", 250),
1275 ("perthousand", 1000),
1276 ("plus", 675),
1277 ("plusminus", 675),
1278 ("q", 500),
1279 ("question", 500),
1280 ("questiondown", 500),
1281 ("quotedbl", 420),
1282 ("quotedblbase", 556),
1283 ("quotedblleft", 556),
1284 ("quotedblright", 556),
1285 ("quoteleft", 333),
1286 ("quoteright", 333),
1287 ("quotesinglbase", 333),
1288 ("quotesingle", 214),
1289 ("r", 389),
1290 ("registered", 760),
1291 ("ring", 333),
1292 ("s", 389),
1293 ("scaron", 389),
1294 ("section", 500),
1295 ("semicolon", 333),
1296 ("seven", 500),
1297 ("six", 500),
1298 ("slash", 278),
1299 ("space", 250),
1300 ("sterling", 500),
1301 ("t", 278),
1302 ("thorn", 500),
1303 ("three", 500),
1304 ("threequarters", 750),
1305 ("threesuperior", 300),
1306 ("tilde", 333),
1307 ("trademark", 980),
1308 ("two", 500),
1309 ("twosuperior", 300),
1310 ("u", 500),
1311 ("uacute", 500),
1312 ("ucircumflex", 500),
1313 ("udieresis", 500),
1314 ("ugrave", 500),
1315 ("underscore", 500),
1316 ("v", 444),
1317 ("w", 667),
1318 ("x", 444),
1319 ("y", 444),
1320 ("yacute", 444),
1321 ("ydieresis", 444),
1322 ("yen", 500),
1323 ("z", 389),
1324 ("zcaron", 389),
1325 ("zero", 500),
1326];
1327
1328#[rustfmt::skip]
1331const TIMES_BOLD_ITALIC: &[(&str, u16)] = &[
1332 ("A", 667),
1333 ("AE", 944),
1334 ("Aacute", 667),
1335 ("Acircumflex", 667),
1336 ("Adieresis", 667),
1337 ("Agrave", 667),
1338 ("Aring", 667),
1339 ("Atilde", 667),
1340 ("B", 667),
1341 ("C", 667),
1342 ("Ccedilla", 667),
1343 ("D", 722),
1344 ("E", 667),
1345 ("Eacute", 667),
1346 ("Ecircumflex", 667),
1347 ("Edieresis", 667),
1348 ("Egrave", 667),
1349 ("Eth", 722),
1350 ("F", 667),
1351 ("G", 722),
1352 ("H", 778),
1353 ("I", 389),
1354 ("Iacute", 389),
1355 ("Icircumflex", 389),
1356 ("Idieresis", 389),
1357 ("Igrave", 389),
1358 ("J", 500),
1359 ("K", 667),
1360 ("L", 611),
1361 ("Lslash", 611),
1362 ("M", 889),
1363 ("N", 722),
1364 ("Ntilde", 722),
1365 ("O", 722),
1366 ("OE", 944),
1367 ("Oacute", 722),
1368 ("Ocircumflex", 722),
1369 ("Odieresis", 722),
1370 ("Ograve", 722),
1371 ("Oslash", 722),
1372 ("Otilde", 722),
1373 ("P", 611),
1374 ("Q", 722),
1375 ("R", 667),
1376 ("S", 556),
1377 ("Scaron", 556),
1378 ("T", 611),
1379 ("Thorn", 611),
1380 ("U", 722),
1381 ("Uacute", 722),
1382 ("Ucircumflex", 722),
1383 ("Udieresis", 722),
1384 ("Ugrave", 722),
1385 ("V", 667),
1386 ("W", 889),
1387 ("X", 667),
1388 ("Y", 611),
1389 ("Yacute", 611),
1390 ("Ydieresis", 611),
1391 ("Z", 611),
1392 ("Zcaron", 611),
1393 ("a", 500),
1394 ("aacute", 500),
1395 ("acircumflex", 500),
1396 ("acute", 333),
1397 ("adieresis", 500),
1398 ("ae", 722),
1399 ("agrave", 500),
1400 ("ampersand", 778),
1401 ("aring", 500),
1402 ("asciicircum", 570),
1403 ("asciitilde", 570),
1404 ("asterisk", 500),
1405 ("at", 832),
1406 ("atilde", 500),
1407 ("b", 500),
1408 ("backslash", 278),
1409 ("bar", 220),
1410 ("braceleft", 348),
1411 ("braceright", 348),
1412 ("bracketleft", 333),
1413 ("bracketright", 333),
1414 ("breve", 333),
1415 ("brokenbar", 220),
1416 ("bullet", 350),
1417 ("c", 444),
1418 ("caron", 333),
1419 ("ccedilla", 444),
1420 ("cedilla", 333),
1421 ("cent", 500),
1422 ("circumflex", 333),
1423 ("colon", 333),
1424 ("comma", 250),
1425 ("copyright", 747),
1426 ("currency", 500),
1427 ("d", 500),
1428 ("dagger", 500),
1429 ("daggerdbl", 500),
1430 ("degree", 400),
1431 ("dieresis", 333),
1432 ("divide", 570),
1433 ("dollar", 500),
1434 ("dotaccent", 333),
1435 ("dotlessi", 278),
1436 ("e", 444),
1437 ("eacute", 444),
1438 ("ecircumflex", 444),
1439 ("edieresis", 444),
1440 ("egrave", 444),
1441 ("eight", 500),
1442 ("ellipsis", 1000),
1443 ("emdash", 1000),
1444 ("endash", 500),
1445 ("equal", 570),
1446 ("eth", 500),
1447 ("exclam", 389),
1448 ("exclamdown", 389),
1449 ("f", 333),
1450 ("fi", 556),
1451 ("five", 500),
1452 ("fl", 556),
1453 ("florin", 500),
1454 ("four", 500),
1455 ("fraction", 167),
1456 ("g", 500),
1457 ("germandbls", 500),
1458 ("grave", 333),
1459 ("greater", 570),
1460 ("guillemotleft", 500),
1461 ("guillemotright", 500),
1462 ("guilsinglleft", 333),
1463 ("guilsinglright", 333),
1464 ("h", 556),
1465 ("hungarumlaut", 333),
1466 ("hyphen", 333),
1467 ("i", 278),
1468 ("iacute", 278),
1469 ("icircumflex", 278),
1470 ("idieresis", 278),
1471 ("igrave", 278),
1472 ("j", 278),
1473 ("k", 500),
1474 ("l", 278),
1475 ("less", 570),
1476 ("logicalnot", 606),
1477 ("lslash", 278),
1478 ("m", 778),
1479 ("macron", 333),
1480 ("minus", 606),
1481 ("mu", 576),
1482 ("multiply", 570),
1483 ("n", 556),
1484 ("nine", 500),
1485 ("ntilde", 556),
1486 ("numbersign", 500),
1487 ("o", 500),
1488 ("oacute", 500),
1489 ("ocircumflex", 500),
1490 ("odieresis", 500),
1491 ("oe", 722),
1492 ("ogonek", 333),
1493 ("ograve", 500),
1494 ("one", 500),
1495 ("onehalf", 750),
1496 ("onequarter", 750),
1497 ("onesuperior", 300),
1498 ("ordfeminine", 266),
1499 ("ordmasculine", 300),
1500 ("oslash", 500),
1501 ("otilde", 500),
1502 ("p", 500),
1503 ("paragraph", 500),
1504 ("parenleft", 333),
1505 ("parenright", 333),
1506 ("percent", 833),
1507 ("period", 250),
1508 ("periodcentered", 250),
1509 ("perthousand", 1000),
1510 ("plus", 570),
1511 ("plusminus", 570),
1512 ("q", 500),
1513 ("question", 500),
1514 ("questiondown", 500),
1515 ("quotedbl", 555),
1516 ("quotedblbase", 500),
1517 ("quotedblleft", 500),
1518 ("quotedblright", 500),
1519 ("quoteleft", 333),
1520 ("quoteright", 333),
1521 ("quotesinglbase", 333),
1522 ("quotesingle", 278),
1523 ("r", 389),
1524 ("registered", 747),
1525 ("ring", 333),
1526 ("s", 389),
1527 ("scaron", 389),
1528 ("section", 500),
1529 ("semicolon", 333),
1530 ("seven", 500),
1531 ("six", 500),
1532 ("slash", 278),
1533 ("space", 250),
1534 ("sterling", 500),
1535 ("t", 278),
1536 ("thorn", 500),
1537 ("three", 500),
1538 ("threequarters", 750),
1539 ("threesuperior", 300),
1540 ("tilde", 333),
1541 ("trademark", 1000),
1542 ("two", 500),
1543 ("twosuperior", 300),
1544 ("u", 556),
1545 ("uacute", 556),
1546 ("ucircumflex", 556),
1547 ("udieresis", 556),
1548 ("ugrave", 556),
1549 ("underscore", 500),
1550 ("v", 444),
1551 ("w", 667),
1552 ("x", 500),
1553 ("y", 444),
1554 ("yacute", 444),
1555 ("ydieresis", 444),
1556 ("yen", 500),
1557 ("z", 389),
1558 ("zcaron", 389),
1559 ("zero", 500),
1560];
1561
1562#[cfg(test)]
1563mod tests {
1564 use super::*;
1565
1566 #[test]
1567 fn standard_14_known_widths() {
1568 assert_eq!(standard_14_width("Helvetica", "space"), Some(278.0));
1569 assert_eq!(standard_14_width("Helvetica", "A"), Some(667.0));
1570 assert_eq!(standard_14_width("Helvetica-Bold", "A"), Some(722.0));
1571 assert_eq!(standard_14_width("Times-Roman", "A"), Some(722.0));
1572 assert_eq!(standard_14_width("Times-Italic", "a"), Some(500.0));
1573 assert_eq!(standard_14_width("Courier", "A"), Some(600.0));
1575 assert_eq!(standard_14_width("Courier-BoldOblique", "m"), Some(600.0));
1576 assert_eq!(
1578 standard_14_width("Helvetica-Oblique", "A"),
1579 standard_14_width("Helvetica", "A")
1580 );
1581 assert_eq!(
1582 standard_14_width("Helvetica-BoldOblique", "A"),
1583 standard_14_width("Helvetica-Bold", "A")
1584 );
1585 }
1586
1587 #[test]
1588 fn standard_14_aliases_and_non_members() {
1589 assert_eq!(standard_14_width("Arial", "space"), Some(278.0)); assert_eq!(standard_14_width("ABCDEF+Times-Bold", "A"), Some(722.0)); assert_eq!(standard_14_width("TimesNewRomanPSMT", "A"), Some(722.0)); assert_eq!(standard_14_width("CourierNewPS-BoldMT", "A"), Some(600.0)); assert!(standard_14_width("Symbol", "alpha").is_none()); assert!(standard_14_width("SomeEmbeddedFont", "A").is_none());
1595 assert!(is_standard_14("Courier-Bold") && !is_standard_14("Comic Sans"));
1596 assert!(is_standard_14("Arial-BoldMT"));
1597 assert!(!is_standard_14("ZapfDingbats"));
1598 }
1599
1600 #[test]
1605 fn standard_14_review_fix_positive() {
1606 assert_eq!(standard_14_width("Helvetica-Bold", "A"), Some(722.0));
1607 assert_eq!(standard_14_width("Arial-BoldMT", "space"), Some(278.0));
1608 assert!(standard_14_width("TimesNewRomanPS-BoldItalicMT", "A").is_some());
1609 assert_eq!(standard_14_width("CourierNew-Bold", "x"), Some(600.0));
1610 assert!(standard_14_width("TimesNewRoman", "A").is_some());
1612 assert!(standard_14_width("Times New Roman", "A").is_some());
1613 }
1614
1615 #[test]
1616 fn standard_14_rejects_metrically_distinct_siblings() {
1617 assert!(standard_14_width("Helvetica-Narrow", "A").is_none());
1618 assert!(standard_14_width("HelveticaNeue-Bold", "A").is_none());
1619 assert!(standard_14_width("Helvetica Neue", "A").is_none());
1620 assert!(standard_14_width("TimesTen-Bold", "A").is_none());
1621 assert!(standard_14_width("Helvetica-Light", "A").is_none());
1622 assert!(standard_14_width("Times New Roman Condensed", "A").is_none());
1623 }
1624
1625 #[test]
1626 fn standard_14_classify_case_folds() {
1627 assert_eq!(standard_14_width("arial-bold", "A"), Some(722.0));
1630 }
1631}