cn_font_split/pre_subset/
name_table.rs1use 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 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
39pub 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(), NameID::FontFamilyName => "FontFamilyName".to_string(), NameID::FontSubfamilyName => "FontSubfamilyName".to_string(), NameID::UniqueFontID => "UniqueFontID".to_string(), NameID::FullFontName => "FullFontName".to_string(), NameID::VersionString => "VersionString".to_string(), NameID::PostScriptFontName => "PostScriptFontName".to_string(), NameID::Trademark => "Trademark".to_string(), NameID::ManufacturerName => "ManufacturerName".to_string(), NameID::DesignerName => "DesignerName".to_string(), NameID::Description => "Description".to_string(), NameID::VendorURL => "VendorURL".to_string(), NameID::DesignerURL => "DesignerURL".to_string(), NameID::LicenseDescription => "LicenseDescription".to_string(), NameID::LicenseURL => "LicenseURL".to_string(), NameID::TypographicFamilyName => "TypographicFamilyName".to_string(), NameID::TypographicSubfamilyName => {
94 "TypographicSubfamilyName".to_string()
95 } NameID::CompatibleFullFontName => "CompatibleFullFontName".to_string(), NameID::SampleText => "SampleText".to_string(), NameID::PostScriptCIDFindFontName => {
99 "PostScriptCIDFindFontName".to_string()
100 } NameID::WWSFamilyName => "WWSFamilyName".to_string(), NameID::WWSSubfamilyName => "WWSSubfamilyName".to_string(), NameID::LightBackgroundPalette => "LightBackgroundPalette".to_string(), NameID::DarkBackgroundPalette => "DarkBackgroundPalette".to_string(), NameID::PostScriptVariationNamePrefix => {
106 "PostScriptVariationNamePrefix".to_string()
107 } _ => "Other".to_string(), }
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 assert_eq!(
126 data.get_name("FontFamilyName", None, None)[0].value,
127 "Smiley Sans Oblique"
128 )
129}