diffenator3_lib/render/
encodedglyphs.rs1use std::fmt::Display;
3
4use super::{DEFAULT_GLYPHS_FONT_SIZE, DEFAULT_GLYPHS_THRESHOLD};
5pub use crate::structs::{CmapDiff, EncodedGlyph};
6use crate::{
7 dfont::DFont,
8 render::{diff_many_words, GlyphDiff},
9};
10pub use harfrust::Direction;
11use static_lang_word_lists::WordList;
12
13impl From<char> for EncodedGlyph {
14 fn from(c: char) -> Self {
15 EncodedGlyph {
16 string: c.to_string(),
17 name: unicode_names2::name(c).map(|s| s.to_string()),
18 }
19 }
20}
21
22impl From<u32> for EncodedGlyph {
23 fn from(c: u32) -> Self {
24 char::from_u32(c).unwrap().into()
25 }
26}
27
28impl Display for EncodedGlyph {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 write!(
31 f,
32 "{} (U+{:04X})",
33 self.string,
34 self.string.chars().next().unwrap() as u32
35 )?;
36 if let Some(name) = &self.name {
37 write!(f, " {}", name)
38 } else {
39 Ok(())
40 }
41 }
42}
43
44impl CmapDiff {
45 pub fn is_some(&self) -> bool {
46 !self.missing.is_empty() || !self.new.is_empty()
47 }
48
49 pub fn new(font_a: &DFont, font_b: &DFont) -> Self {
51 let cmap_a = &font_a.codepoints;
52 let cmap_b = &font_b.codepoints;
53 Self {
54 missing: cmap_a.difference(cmap_b).map(|&x| x.into()).collect(),
55 new: cmap_b.difference(cmap_a).map(|&x| x.into()).collect(),
56 }
57 }
58}
59
60pub fn modified_encoded_glyphs(font_a: &DFont, font_b: &DFont) -> Vec<GlyphDiff> {
62 let cmap_a = &font_a.codepoints;
63 let cmap_b = &font_b.codepoints;
64 let same_glyphs = cmap_a.intersection(cmap_b);
65 let word_list: Vec<String> = same_glyphs
66 .filter_map(|i| char::from_u32(*i))
67 .map(|c| c.to_string())
68 .collect();
69 let wl = WordList::define("Encoded glyphs", word_list);
70 let mut result: Vec<GlyphDiff> = diff_many_words(
71 font_a,
72 font_b,
73 DEFAULT_GLYPHS_FONT_SIZE,
74 &wl,
75 None,
76 DEFAULT_GLYPHS_THRESHOLD,
77 )
78 .into_iter()
79 .map(|x| x.into())
80 .collect();
81 result.sort_by_key(|x| -(x.differing_pixels as i32));
82 result
83}