Skip to content

Commit

Permalink
adapt to latest write-fonts' iup_delta_optimize
Browse files Browse the repository at this point in the history
so that fontc can work again with fontations/HEAD following two breaking changes:
googlefonts/fontations#616
googlefonts/fontations#619
  • Loading branch information
anthrotype committed Sep 28, 2023
1 parent 703db33 commit 748a591
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 29 deletions.
5 changes: 4 additions & 1 deletion fontbe/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use fontdrasil::types::GlyphName;
use fontir::{error::VariationModelError, variations::DeltaError};
use read_fonts::ReadError;
use thiserror::Error;
use write_fonts::tables::{glyf::MalformedPath, gvar::GvarInputError, variations::IupError};
use write_fonts::tables::{
glyf::MalformedPath,
gvar::{iup::IupError, GvarInputError},
};

#[derive(Debug, Error)]
pub enum Error {
Expand Down
14 changes: 10 additions & 4 deletions fontbe/src/glyphs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use fontir::{
orchestration::WorkId as FeWorkId,
variations::{VariationModel, VariationRegion},
};
use kurbo::{cubics_to_quadratic_splines, Affine, BezPath, CubicBez, PathEl, Point, Rect, Vec2};
use kurbo::{cubics_to_quadratic_splines, Affine, BezPath, CubicBez, PathEl, Point, Rect};
use log::{log_enabled, trace, warn};

use read_fonts::{
Expand All @@ -31,7 +31,7 @@ use write_fonts::{
Bbox, Component, ComponentFlags, CompositeGlyph, GlyfLocaBuilder, Glyph as RawGlyph,
SimpleGlyph,
},
variations::iup_delta_optimize,
gvar::{iup::iup_delta_optimize, GlyphDelta},
},
OtRound,
};
Expand All @@ -41,7 +41,7 @@ use crate::{
orchestration::{AnyWorkId, BeWork, Context, Glyph, GvarFragment, WorkId},
};

type Deltas = Vec<(VariationRegion, Vec<Option<Vec2>>)>;
type Deltas = Vec<(VariationRegion, Vec<GlyphDelta>)>;

#[derive(Debug)]
struct GlyphWork {
Expand Down Expand Up @@ -275,7 +275,13 @@ fn compute_deltas(
iup_delta_optimize(deltas, coords.clone(), tolerance, contour_ends)
.map(|iup_deltas| (region.clone(), iup_deltas))
} else {
Ok((region, deltas.into_iter().map(Some).collect()))
// IUP only applies to simple glyphs; for composite glyphs we
// just mark the zero deltas as being interpoatable.
Ok((region, deltas.into_iter().map(|delta|
match delta.to_point().ot_round() {
(0, 0) => GlyphDelta::optional(0, 0),
(x, y) => GlyphDelta::required(x, y),
}).collect()))
}
})
.collect::<Result<Vec<_>, _>>()
Expand Down
7 changes: 5 additions & 2 deletions fontbe/src/gvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ impl Work<Context, AnyWorkId, Error> for GvarWork {
mod tests {
use font_types::F2Dot14;
use fontir::ir::GlyphOrder;
use write_fonts::tables::{gvar::GlyphDeltas, variations::Tuple};
use write_fonts::tables::{
gvar::{GlyphDelta, GlyphDeltas},
variations::Tuple,
};

use super::make_variations;

Expand All @@ -103,7 +106,7 @@ mod tests {
// At the maximum extent (normalized pos 1.0) of our axis, add +1, +1
v if v == glyph_with_var => vec![GlyphDeltas::new(
Tuple::new(vec![F2Dot14::from_f32(1.0)]),
vec![Some((1, 1))],
vec![GlyphDelta::new(1, 1, false)],
None,
)],
v => panic!("unexpected {v}"),
Expand Down
51 changes: 29 additions & 22 deletions fontbe/src/orchestration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,33 @@ use fontir::{
},
variations::VariationRegion,
};
use kurbo::Vec2;
use log::trace;
use read_fonts::{FontData, FontRead};
use serde::{Deserialize, Serialize};

use write_fonts::{
dump_table,
tables::{
avar::Avar, cmap::Cmap, fvar::Fvar, gdef::Gdef, glyf::Glyph as RawGlyph, gpos::Gpos,
gsub::Gsub, gvar::GlyphDeltas, head::Head, hhea::Hhea, loca::LocaFormat, maxp::Maxp,
name::Name, os2::Os2, post::Post, stat::Stat, variations::Tuple,
avar::Avar,
cmap::Cmap,
fvar::Fvar,
gdef::Gdef,
glyf::Glyph as RawGlyph,
gpos::Gpos,
gsub::Gsub,
gvar::{GlyphDelta, GlyphDeltas},
head::Head,
hhea::Hhea,
loca::LocaFormat,
maxp::Maxp,
name::Name,
os2::Os2,
post::Post,
stat::Stat,
variations::Tuple,
},
validate::Validate,
FontWrite, OtRound,
FontWrite,
};

use crate::{error::Error, paths::Paths};
Expand Down Expand Up @@ -168,7 +181,7 @@ impl Persistable for Glyph {
pub struct GvarFragment {
pub glyph_name: GlyphName,
/// None entries are safe to omit per IUP
pub deltas: Vec<(VariationRegion, Vec<Option<Vec2>>)>,
pub deltas: Vec<(VariationRegion, Vec<GlyphDelta>)>,
}

impl GvarFragment {
Expand All @@ -181,24 +194,13 @@ impl GvarFragment {
}

// Variation of no point has limited entertainment value
if deltas.is_empty() || deltas.iter().all(|d| d.is_none()) {
if deltas.is_empty() || deltas.iter().all(|d| !d.required) {
return None;
}

let deltas: Vec<_> = deltas
.iter()
.map(|v| {
v.map(|Vec2 { x, y }| {
let x: i16 = x.ot_round();
let y: i16 = y.ot_round();
(x, y)
})
})
.collect();

let tuple_builder = TupleBuilder::new(region, axis_order);
let (min, peak, max) = tuple_builder.build();
Some(GlyphDeltas::new(peak, deltas, Some((min, max))))
Some(GlyphDeltas::new(peak, deltas.clone(), Some((min, max))))
})
.collect()
}
Expand Down Expand Up @@ -526,7 +528,7 @@ mod tests {
variations::{Tent, VariationRegion},
};

use super::GvarFragment;
use super::*;

fn non_default_region() -> VariationRegion {
let mut region = VariationRegion::default();
Expand All @@ -547,7 +549,11 @@ mod tests {
glyph_name: "blah".into(),
deltas: vec![(
non_default_region(),
vec![None, Some((1.0, 0.0).into()), None],
vec![
GlyphDelta::optional(0, 0),
GlyphDelta::required(1, 0),
GlyphDelta::optional(1, 0),
],
)],
}
.to_deltas(&[Tag::new(b"wght")]);
Expand All @@ -556,9 +562,10 @@ mod tests {

#[test]
fn drops_nop_deltas() {
let can_omit = GlyphDelta::optional(0, 0);
let deltas = GvarFragment {
glyph_name: "blah".into(),
deltas: vec![(non_default_region(), vec![None, None, None])],
deltas: vec![(non_default_region(), vec![can_omit; 3])],
}
.to_deltas(&[Tag::new(b"wght")]);
assert!(deltas.is_empty(), "{deltas:?}");
Expand Down

0 comments on commit 748a591

Please sign in to comment.