Skip to content

Commit

Permalink
Use IndexSet instead of Vec for codepoints
Browse files Browse the repository at this point in the history
This ensures that codepoints are unique, but also respects the original
order in which they appear in the file.
  • Loading branch information
cmyr committed Dec 5, 2022
1 parent 417e4ac commit b67c9f4
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ quick-xml = { version = "0.26.0", features = ["serialize"] }
rayon = { version = "1.3.0", optional = true }
kurbo = { version = "0.9.0", optional = true }
thiserror = "1.0"
indexmap = {version = "1.9.2", features = ["serde"] }

[dependencies.druid]
default-features = false
Expand Down
5 changes: 3 additions & 2 deletions src/glyph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::error::ConvertContourError;

#[cfg(feature = "druid")]
use druid::{Data, Lens};
use indexmap::IndexSet;

use crate::error::{ErrorKind, GlifLoadError, GlifWriteError, StoreError};
use crate::name::Name;
Expand All @@ -38,7 +39,7 @@ pub struct Glyph {
/// A collection of glyph Unicode code points.
///
/// The first entry defines the primary Unicode value for this glyph.
pub codepoints: Vec<char>,
pub codepoints: IndexSet<char>,
/// Arbitrary glyph note.
pub note: Option<String>,
/// A collection of glyph guidelines.
Expand Down Expand Up @@ -115,7 +116,7 @@ impl Glyph {
name,
height: 0.0,
width: 0.0,
codepoints: Vec::new(),
codepoints: Default::default(),
note: None,
guidelines: Vec::new(),
anchors: Vec::new(),
Expand Down
2 changes: 1 addition & 1 deletion src/glyph/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ impl<'names> GlifParser<'names> {
.map_err(|_| value.to_string())
.and_then(|n| char::try_from(n).map_err(|_| value.to_string()))
.map_err(|_| ErrorKind::BadHexValue)?;
self.glyph.codepoints.push(chr);
self.glyph.codepoints.insert(chr);
}
_other => return Err(ErrorKind::UnexpectedAttribute.into()),
}
Expand Down
29 changes: 29 additions & 0 deletions src/glyph/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use indexmap::indexset;

use super::parse::parse_glyph;
use super::*;
use crate::write::QuoteChar;
Expand Down Expand Up @@ -868,3 +870,30 @@ fn has_component_with_base() {
assert!(glyph.has_component_with_base("dieresis"));
assert!(!glyph.has_component_with_base("Z"));
}

#[test]
fn deduplicate_unicodes2() {
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, indexset!['e', 'f', 'g'].into());

glyph.codepoints = indexset!['e', 'f', 'e', 'g'].into();
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);
}
4 changes: 3 additions & 1 deletion src/layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ impl Default for Layer {

#[cfg(test)]
mod tests {
use indexmap::indexset;

use crate::DataRequest;

use super::*;
Expand All @@ -613,7 +615,7 @@ mod tests {
let glyph = layer.get_glyph("A").expect("failed to load glyph 'A'");
assert_eq!(glyph.height, 0.);
assert_eq!(glyph.width, 1190.);
assert_eq!(glyph.codepoints, vec!['A']);
assert_eq!(glyph.codepoints, indexset!['A']);
}

#[test]
Expand Down
5 changes: 3 additions & 2 deletions tests/save.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Testing saving files.

use indexmap::indexset;
use norad::{Font, FormatVersion, Glyph, Identifier, Plist};
use plist::Value;

Expand All @@ -24,7 +25,7 @@ fn save_default() {
fn save_new_file() {
let mut my_ufo = Font::new();
let mut my_glyph = Glyph::new("A");
my_glyph.codepoints = vec!['A'];
my_glyph.codepoints = indexset!['A'];
my_glyph.note = Some("I did a glyph!".into());
let mut plist = Plist::new();
plist.insert("my-cool-key".into(), plist::Value::Integer(420_u32.into()));
Expand All @@ -42,7 +43,7 @@ fn save_new_file() {
let loaded = Font::load(dir).unwrap();
assert!(loaded.default_layer().get_glyph("A").is_some());
let glyph = loaded.default_layer().get_glyph("A").unwrap();
assert_eq!(glyph.codepoints, vec!['A']);
assert_eq!(glyph.codepoints, indexset!['A']);
let lib_val = glyph.lib.get("my-cool-key").and_then(|val| val.as_unsigned_integer());
assert_eq!(lib_val, Some(420));
}
Expand Down

0 comments on commit b67c9f4

Please sign in to comment.