cn_font_split/pre_subset/
name_table.rs

1use opentype::truetype::tables::names::{NameID, PlatformID};
2use opentype::truetype::tables::Names;
3use opentype::Font;
4use std::io::Cursor;
5
6use cn_font_proto::api_interface::output_report::NameTable;
7
8#[derive(Debug)]
9pub struct NameTableSets {
10    pub table: Vec<NameTable>,
11}
12impl NameTableSets {
13    fn get_language(&self, str: &str) -> Vec<&NameTable> {
14        self.table.iter().filter(|x| x.language == str).collect()
15    }
16    /// 默认获取 Windows 下面的 en 的标签,这个是用于机器看的
17    pub fn get_name(
18        &self,
19        str: &str,
20        platform: Option<&str>,
21        language: Option<&str>,
22    ) -> Vec<&NameTable> {
23        let platform = platform.unwrap_or("Windows");
24        let table = self.get_language(language.unwrap_or(&"en"));
25        table
26            .iter()
27            .filter(|x| x.name == str && x.platform == platform)
28            .map(|x| *x)
29            .collect()
30    }
31    pub fn get_name_first(&self, str: &str) -> Option<String> {
32        match self.get_name(str, None, None).get(0) {
33            Some(val) => Option::from(val.value.clone()),
34            _ => None,
35        }
36    }
37}
38
39/// 解析 name table 可以得知关于整个字体的头部信息
40pub fn analyze_name_table(
41    font: &Font,
42    font_file: &mut Cursor<&[u8]>,
43) -> NameTableSets {
44    let data: Names = font.take(font_file).unwrap().unwrap();
45    let mut table = NameTableSets { table: vec![] };
46    data.iter().for_each(|((platform, _, language, name), value)| {
47        let key = name_id_to_string(name);
48        let void_language_tag_decode: [Option<&str>; 1] = [None];
49        match value {
50            Some(value) => {
51                table.table.push(NameTable {
52                    language: language
53                        .tag(&void_language_tag_decode)
54                        .unwrap_or("en")
55                        .to_string(),
56                    platform: platform_to_string(platform),
57                    name: key,
58                    value,
59                });
60            }
61            None => {}
62        };
63    });
64    table
65}
66
67pub fn platform_to_string(platform_id: PlatformID) -> String {
68    match platform_id {
69        PlatformID::Unicode => "Unicode".to_string(),
70        PlatformID::Macintosh => "Macintosh".to_string(),
71        PlatformID::Windows => "Windows".to_string(),
72    }
73}
74
75pub fn name_id_to_string(name_id: NameID) -> String {
76    match name_id {
77        NameID::CopyrightNotice => "CopyrightNotice".to_string(), // 版权声明
78        NameID::FontFamilyName => "FontFamilyName".to_string(), // 字体家族名称
79        NameID::FontSubfamilyName => "FontSubfamilyName".to_string(), // 字体子家族名称
80        NameID::UniqueFontID => "UniqueFontID".to_string(), // 唯一字体标识
81        NameID::FullFontName => "FullFontName".to_string(), // 完整字体名称
82        NameID::VersionString => "VersionString".to_string(), // 版本字符串
83        NameID::PostScriptFontName => "PostScriptFontName".to_string(), // PostScript 字体名称
84        NameID::Trademark => "Trademark".to_string(),                   // 商标
85        NameID::ManufacturerName => "ManufacturerName".to_string(), // 制造商名称
86        NameID::DesignerName => "DesignerName".to_string(), // 设计师名称
87        NameID::Description => "Description".to_string(),   // 描述
88        NameID::VendorURL => "VendorURL".to_string(),       // 供应商 URL
89        NameID::DesignerURL => "DesignerURL".to_string(),   // 设计师 URL
90        NameID::LicenseDescription => "LicenseDescription".to_string(), // 许可证描述
91        NameID::LicenseURL => "LicenseURL".to_string(), // 许可证 URL
92        NameID::TypographicFamilyName => "TypographicFamilyName".to_string(), // 排版家族名称
93        NameID::TypographicSubfamilyName => {
94            "TypographicSubfamilyName".to_string()
95        } // 排版子家族名称
96        NameID::CompatibleFullFontName => "CompatibleFullFontName".to_string(), // 兼容的完整字体名称
97        NameID::SampleText => "SampleText".to_string(), // 示例文本
98        NameID::PostScriptCIDFindFontName => {
99            "PostScriptCIDFindFontName".to_string()
100        } // PostScript CID 查找字体名称
101        NameID::WWSFamilyName => "WWSFamilyName".to_string(), // WWS 家族名称
102        NameID::WWSSubfamilyName => "WWSSubfamilyName".to_string(), // WWS 子家族名称
103        NameID::LightBackgroundPalette => "LightBackgroundPalette".to_string(), // 浅色背景调色板
104        NameID::DarkBackgroundPalette => "DarkBackgroundPalette".to_string(), // 深色背景调色板
105        NameID::PostScriptVariationNamePrefix => {
106            "PostScriptVariationNamePrefix".to_string()
107        } // PostScript 变体名称前缀
108        _ => "Other".to_string(), // 其他
109    }
110}
111
112#[test]
113fn test_name_table() {
114    use cn_font_utils::read_binary_file;
115    let path = "./packages/demo/public/SmileySans-Oblique.ttf";
116    let file_binary = read_binary_file(&path).expect("Failed to read file");
117    let mut font_file = Cursor::new(&*file_binary);
118    let font = Font::read(&mut font_file).expect("TODO: panic message");
119    let data = analyze_name_table(&font, &mut font_file);
120
121    // data.table.iter().for_each(|x| {
122    //     println!("{:?}", x);
123    // });
124
125    assert_eq!(
126        data.get_name("FontFamilyName", None, None)[0].value,
127        "Smiley Sans Oblique"
128    )
129}