rust_pdf_box/font/
type1.rs1use crate::cos::object::{COSDictionary, COSName};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum PDType1Font {
6 Helvetica,
7 HelveticaBold,
8 HelveticaOblique,
9 HelveticaBoldOblique,
10 TimesRoman,
11 TimesBold,
12 TimesItalic,
13 TimesBoldItalic,
14 Courier,
15 CourierBold,
16 CourierOblique,
17 CourierBoldOblique,
18 Symbol,
19 ZapfDingbats,
20}
21
22impl PDType1Font {
23 pub fn base_font_name(&self) -> &'static str {
24 match self {
25 Self::Helvetica => "Helvetica",
26 Self::HelveticaBold => "Helvetica-Bold",
27 Self::HelveticaOblique => "Helvetica-Oblique",
28 Self::HelveticaBoldOblique => "Helvetica-BoldOblique",
29 Self::TimesRoman => "Times-Roman",
30 Self::TimesBold => "Times-Bold",
31 Self::TimesItalic => "Times-Italic",
32 Self::TimesBoldItalic => "Times-BoldItalic",
33 Self::Courier => "Courier",
34 Self::CourierBold => "Courier-Bold",
35 Self::CourierOblique => "Courier-Oblique",
36 Self::CourierBoldOblique => "Courier-BoldOblique",
37 Self::Symbol => "Symbol",
38 Self::ZapfDingbats => "ZapfDingbats",
39 }
40 }
41
42 pub fn to_dict(&self) -> COSDictionary {
44 let mut dict = COSDictionary::new();
45 dict.set("Type", COSName::new("Font"));
46 dict.set("Subtype", COSName::new("Type1"));
47 dict.set("BaseFont", COSName::new(self.base_font_name()));
48 if !matches!(self, Self::Symbol | Self::ZapfDingbats) {
49 dict.set("Encoding", COSName::new("WinAnsiEncoding"));
50 }
51 dict
52 }
53
54 pub fn get_char_width(&self, c: char) -> f64 {
56 match self {
57 Self::Courier | Self::CourierBold | Self::CourierOblique | Self::CourierBoldOblique => {
58 600.0
60 }
61 Self::TimesRoman | Self::TimesBold | Self::TimesItalic | Self::TimesBoldItalic => {
62 match c {
63 ' ' => 250.0,
64 'i' | 'j' | 'l' | '!' | '.' | ':' | ';' | '\'' => 278.0,
65 'f' | 't' | 'I' => 333.0,
66 'r' => 389.0,
67 's' => 444.0,
68 'a' | 'b' | 'c' | 'd' | 'e' | 'g' | 'h' | 'k' | 'n' | 'o' | 'p' | 'q' | 'u'
69 | 'v' | 'x' | 'y' | 'z' => 500.0,
70 'w' => 722.0,
71 'm' => 778.0,
72 'M' | 'W' => 889.0,
73 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'J' | 'K' | 'N' | 'O' | 'P'
74 | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'X' | 'Y' | 'Z' => 667.0,
75 _ => 500.0,
76 }
77 }
78 _ => {
79 match c {
81 ' ' => 278.0,
82 'i' | 'l' | '!' | '.' | ':' | ';' | '\'' | '|' => 222.0,
83 'j' | 'r' | 't' | 'I' => 278.0,
84 'f' => 278.0,
85 'c' | 's' | 'z' => 500.0,
86 'a' | 'b' | 'd' | 'e' | 'g' | 'h' | 'k' | 'n' | 'o' | 'p' | 'q' | 'u' | 'v'
87 | 'x' | 'y' => 556.0,
88 'w' => 722.0,
89 'm' => 833.0,
90 'W' | 'M' => 833.0,
91 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'J' | 'K' | 'L' | 'N' | 'O'
92 | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'X' | 'Y' | 'Z' => 667.0,
93 _ => 556.0,
94 }
95 }
96 }
97 }
98
99 pub fn get_string_width(&self, text: &str, font_size: f64) -> f64 {
101 let total_units: f64 = text.chars().map(|c| self.get_char_width(c)).sum();
102 (total_units / 1000.0) * font_size
103 }
104}