diff --git a/fontc/src/lib.rs b/fontc/src/lib.rs index a57c60025..24cac5db6 100644 --- a/fontc/src/lib.rs +++ b/fontc/src/lib.rs @@ -326,7 +326,7 @@ mod tests { use fontbe::orchestration::{ AnyWorkId, Context as BeContext, Glyph, LocaFormatWrapper, WorkId as BeWorkIdentifier, }; - use fontdrasil::types::GlyphName; + use fontdrasil::{paths::glyph_file, types::GlyphName}; use fontir::{ ir::{self, KernParticipant}, orchestration::{Context as FeContext, Persistable, WorkId as FeWorkIdentifier}, @@ -818,12 +818,12 @@ mod tests { } fn read_ir_glyph(build_dir: &Path, name: &str) -> ir::Glyph { - let raw_glyph = read_file(&build_dir.join(format!("glyph_ir/{name}.yml"))); + let raw_glyph = read_file(&build_dir.join("glyph_ir").join(glyph_file(name, ".yml"))); ir::Glyph::read(&mut raw_glyph.as_slice()) } fn read_be_glyph(build_dir: &Path, name: &str) -> RawGlyph { - let raw_glyph = read_file(&build_dir.join(format!("glyphs/{name}.glyf"))); + let raw_glyph = read_file(&build_dir.join("glyphs").join(glyph_file(name, ".glyf"))); let read: &mut dyn Read = &mut raw_glyph.as_slice(); Glyph::read(read).data } diff --git a/fontdrasil/src/paths.rs b/fontdrasil/src/paths.rs index 3ea2edc88..83a3a833e 100644 --- a/fontdrasil/src/paths.rs +++ b/fontdrasil/src/paths.rs @@ -1,5 +1,45 @@ pub fn glyph_file(glyph_name: &str, suffix: &str) -> String { // TODO handle names that are invalid for the filesystem // Ref https://github.com/unified-font-object/ufo-spec/issues/164 - glyph_name.to_owned() + suffix + let mut filename = Vec::new(); + for ch in glyph_name.chars() { + filename.push(ch); + if ch == '_' || ch.is_uppercase() { + filename.push('_'); + } + } + filename.extend(suffix.chars()); + filename.into_iter().collect() +} + +#[cfg(test)] +mod tests { + use std::collections::HashSet; + + use super::glyph_file; + + /// + fn assert_unique_for_caseinsensitive_fs(names: &[&str]) { + let filenames: HashSet<_> = names + .iter() + .map(|n| glyph_file(n, "")) + .map(|n| n.to_lowercase()) + .collect(); + assert_eq!( + names.len(), + filenames.len(), + "{names:?} became {filenames:?}" + ); + } + + #[test] + fn lower_and_upper_a() { + assert_unique_for_caseinsensitive_fs(&["a", "A"]); + } + + #[test] + fn adding_underscore_avoids_collisions() { + // if we don't add _ to _ the resulting names are identical + assert_unique_for_caseinsensitive_fs(&["Aa", "a_a"]); + } }