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