Skip to content

Commit

Permalink
Deduplicate codepoints on read and write
Browse files Browse the repository at this point in the history
Closes #263
  • Loading branch information
madig committed Nov 10, 2022
1 parent a9983d9 commit f21fd5f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/glyph/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ impl<'names> GlifParser<'names> {
}

self.glyph.load_object_libs()?;

let mut seen_codepoints = HashSet::new();
let deduplicated_codepoints =
self.glyph.codepoints.iter().filter(|c| seen_codepoints.insert(**c)).cloned().collect();
self.glyph.codepoints = deduplicated_codepoints;

Ok(self.glyph)
}

Expand Down
10 changes: 8 additions & 2 deletions src/glyph/serialize.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Writing out .glif files

use std::io::{Cursor, Write};
use std::{
collections::HashSet,
io::{Cursor, Write},
};

use quick_xml::{
events::{BytesEnd, BytesStart, BytesText, Event},
Expand Down Expand Up @@ -59,8 +62,11 @@ impl Glyph {
start.push_attribute(("format", "2"));
writer.write_event(Event::Start(start)).map_err(GlifWriteError::Xml)?;

let mut seen_codepoints = HashSet::new();
for codepoint in &self.codepoints {
writer.write_event(char_to_event(*codepoint)).map_err(GlifWriteError::Xml)?;
if seen_codepoints.insert(codepoint) {
writer.write_event(char_to_event(*codepoint)).map_err(GlifWriteError::Xml)?;
}
}

// Skip serializing advance if both values are zero, infinite, subnormal, or NaN.
Expand Down
27 changes: 27 additions & 0 deletions src/glyph/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -868,3 +868,30 @@ fn has_component_with_base() {
assert!(glyph.has_component_with_base("dieresis"));
assert!(!glyph.has_component_with_base("Z"));
}

#[test]
fn deduplicate_unicodes() {
let data = r#"
<?xml version="1.0" encoding="UTF-8"?>
<glyph name="period" format="2">
<unicode hex="0065"/>
<unicode hex="0066"/>
<unicode hex="0065"/>
<unicode hex="0067"/>
</glyph>
"#;
let mut glyph = parse_glyph(data.as_bytes()).unwrap();
assert_eq!(glyph.codepoints, vec!['e', 'f', 'g']);

glyph.codepoints = vec!['e', 'f', 'e', 'g'];
let data2 = glyph.encode_xml().unwrap();
let data2 = std::str::from_utf8(&data2).unwrap();
let data2_expected = r#"<?xml version="1.0" encoding="UTF-8"?>
<glyph name="period" format="2">
<unicode hex="0065"/>
<unicode hex="0066"/>
<unicode hex="0067"/>
</glyph>
"#;
assert_eq!(data2, data2_expected);
}

0 comments on commit f21fd5f

Please sign in to comment.