Skip to content

Commit

Permalink
Try to make field matching in fontra match better. Don't reinvent chu…
Browse files Browse the repository at this point in the history
…nks.
  • Loading branch information
rsheeter committed Feb 6, 2024
1 parent 01937df commit 707df96
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
54 changes: 39 additions & 15 deletions fontra2fontir/src/fontra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use std::{
collections::{BTreeMap, HashMap},
fmt::Display,
fs,
path::{Path, PathBuf},
};
Expand All @@ -13,6 +14,24 @@ use fontir::error::Error;
use serde::Deserialize;
use write_fonts::types::Tag;

#[derive(Debug, Clone, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct AxisName(pub(crate) String);

impl Display for AxisName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.0.as_str())
}
}

#[derive(Debug, Clone, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct LayerName(pub(crate) String);

impl Display for LayerName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.0.as_str())
}
}

const SEPARATOR_CHAR: char = '^';

fn is_reserved_char(c: char) -> bool {
Expand Down Expand Up @@ -63,13 +82,12 @@ const BASE_32_CHARS: [char; 32] = [
/// Matches <https://github.com/googlefonts/fontra/blob/15bc0b8401054390484cfb86d509d633d29657a1/src/fontra/backends/filenames.py#L40-L64>
fn string_to_filename(string: &str, suffix: &str) -> String {
let string_bytes = string.as_bytes();
let mut code_digits: Vec<_> = (0..string_bytes.len())
.step_by(5)
.map(|i| {
let mut code_digits: Vec<_> = string_bytes
.chunks(5)
.map(|chunk| {
let mut digit = 0;
let mut bit = 1;
let string = string.as_bytes();
for byte in string[i..(i + 5).min(string.len())].iter() {
for byte in chunk {
if byte.is_ascii_uppercase() {
digit |= bit
}
Expand Down Expand Up @@ -140,7 +158,7 @@ impl FontraFontData {

#[derive(Debug, Clone, Deserialize)]
pub(crate) struct FontraAxis {
pub(crate) name: String,
pub(crate) name: AxisName,
pub(crate) tag: Tag,
#[serde(default)]
pub(crate) hidden: bool,
Expand All @@ -165,7 +183,7 @@ pub(crate) struct FontraGlyph {
#[serde(default)]
pub(crate) axes: Vec<FontraGlyphAxis>,
pub(crate) sources: Vec<FontraSource>,
pub(crate) layers: BTreeMap<String, FontraLayer>,
pub(crate) layers: BTreeMap<LayerName, FontraLayer>,
}

/// An axis specific to a glyph meant to be used as a variable component
Expand All @@ -189,9 +207,9 @@ pub(crate) struct FontraGlyphAxis {
pub(crate) struct FontraSource {
pub(crate) name: String,
#[serde(rename = "layerName")]
pub(crate) layer_name: String,
pub(crate) layer_name: LayerName,
#[serde(default)]
pub(crate) location: HashMap<String, f64>,
pub(crate) location: HashMap<AxisName, f64>,
// TODO: locationBase
#[serde(default)]
pub(crate) inactive: bool,
Expand Down Expand Up @@ -351,7 +369,7 @@ mod tests {
.iter()
.map(|a| {
(
a.name.as_str(),
a.name.0.as_str(),
a.tag,
a.min_value,
a.default_value,
Expand Down Expand Up @@ -418,7 +436,10 @@ mod tests {
let glyph = read_test_glyph("minimal.fontra", ".notdef");
assert_eq!(GlyphName::new(".notdef"), glyph.name, "{glyph:#?}");
assert_eq!(
1000.0, glyph.layers["foreground"].glyph.x_advance,
1000.0,
glyph.layers[&LayerName("foreground".into())]
.glyph
.x_advance,
"{glyph:#?}"
);
}
Expand All @@ -443,9 +464,12 @@ mod tests {
fn read_simple_contours() {
let glyph = read_test_glyph("2glyphs.fontra", "u20089");
assert_eq!(GlyphName::new("u20089"), glyph.name, "{glyph:#?}");
let mut layer_names: Vec<_> = glyph.layers.keys().map(|n| n.as_str()).collect();
let mut layer_names: Vec<_> = glyph.layers.keys().cloned().collect();
layer_names.sort();
assert_eq!(vec!["foreground", "wght=1"], layer_names);
assert_eq!(
vec![LayerName("foreground".into()), LayerName("wght=1".into())],
layer_names
);
assert_eq!(
HashSet::from([10, 11]),
glyph
Expand All @@ -455,7 +479,7 @@ mod tests {
.collect::<HashSet<_>>(),
"{glyph:#?}"
);
let contour = glyph.layers["foreground"]
let contour = glyph.layers[&LayerName("foreground".into())]
.glyph
.path
.contours
Expand Down Expand Up @@ -484,7 +508,7 @@ mod tests {
.glyph
.components
.iter()
.map(|c| (n.clone(), c.name.clone())))
.map(|c| (n.to_string(), c.name.clone())))
.collect::<Vec<_>>(),
);
}
Expand Down
18 changes: 9 additions & 9 deletions fontra2fontir/src/toir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use kurbo::BezPath;
use log::trace;
use write_fonts::types::Tag;

use crate::fontra::{FontraContour, FontraFontData, FontraGlyph, FontraPoint, PointType};
use crate::fontra::{AxisName, FontraContour, FontraFontData, FontraGlyph, FontraPoint, PointType};

pub(crate) fn to_ir_static_metadata(
font_data: &FontraFontData,
Expand Down Expand Up @@ -61,7 +61,7 @@ pub(crate) fn to_ir_static_metadata(

Ok(Axis {
tag: a.tag,
name: a.name.clone(),
name: a.name.to_string(),
hidden: a.hidden,
min,
default,
Expand All @@ -86,7 +86,7 @@ pub(crate) fn to_ir_static_metadata(
///
#[allow(dead_code)] // TEMPORARY
fn to_ir_glyph(
global_axes: HashMap<&str, Tag>,
global_axes: HashMap<AxisName, Tag>,
codepoints: HashSet<u32>,
fontra_glyph: &FontraGlyph,
) -> Result<Glyph, WorkError> {
Expand All @@ -99,7 +99,7 @@ fn to_ir_glyph(
let layer_locations: HashMap<_, _> = fontra_glyph
.sources
.iter()
.map(|s| (s.layer_name.as_str(), &s.location))
.map(|s| (&s.layer_name, &s.location))
.collect();

let mut instances = HashMap::new();
Expand All @@ -109,15 +109,15 @@ fn to_ir_glyph(
todo!("Support local axes");
}

let Some(location) = layer_locations.get(layer_name.as_str()) else {
return Err(WorkError::NoSourceForName(layer_name.clone()));
let Some(location) = layer_locations.get(layer_name) else {
return Err(WorkError::NoSourceForName(layer_name.to_string()));
};
let global_location: NormalizedLocation = global_axes
.iter()
.map(|(name, tag)| {
(
*tag,
NormalizedCoord::new(location.get(*name).copied().unwrap_or_default() as f32),
NormalizedCoord::new(location.get(name).copied().unwrap_or_default() as f32),
)
})
.collect();
Expand Down Expand Up @@ -230,7 +230,7 @@ mod tests {
use write_fonts::types::Tag;

use crate::{
fontra::{FontraFontData, FontraGlyph},
fontra::{AxisName, FontraFontData, FontraGlyph},
test::testdata_dir,
toir::to_ir_static_metadata,
};
Expand Down Expand Up @@ -300,7 +300,7 @@ mod tests {
let glyph_file = testdata_dir().join("2glyphs.fontra/glyphs/u20089.json");
let fontra_glyph = FontraGlyph::from_file(&glyph_file).unwrap();
let glyph = to_ir_glyph(
HashMap::from([("Weight", Tag::new(b"wght"))]),
HashMap::from([(AxisName("Weight".into()), Tag::new(b"wght"))]),
Default::default(),
&fontra_glyph,
)
Expand Down

0 comments on commit 707df96

Please sign in to comment.