Skip to content

Commit

Permalink
[fontc] Work with the new fea-rs API
Browse files Browse the repository at this point in the history
This does the minimum to get us compiling again; there's a larger patch
to write that skips the intermediate step and just creates these types
directly.
  • Loading branch information
cmyr committed Nov 28, 2023
1 parent 3d1de1a commit b24324b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 112 deletions.
20 changes: 1 addition & 19 deletions fea-rs/src/compile/feature_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@
use std::collections::{BTreeMap, HashMap};

use write_fonts::{
tables::{
layout::{LookupFlag, PendingVariationIndex},
variations::VariationRegion,
},
types::Tag,
};
use write_fonts::{tables::layout::LookupFlag, types::Tag};

use crate::GlyphSet;

Expand Down Expand Up @@ -92,18 +86,6 @@ impl<'a> FeatureBuilder<'a> {
next_id
}

/// Add a set of deltas to the `ItemVariationStore`.
///
/// Returns a `PendingVariationIndex` which should be stored whereever a
/// `VariationIndex` table would be expected (it will be remapped during
/// compilation).
pub fn add_deltas<T: Into<i32>>(
&mut self,
deltas: Vec<(VariationRegion, T)>,
) -> PendingVariationIndex {
todo!("remove me!")
}

/// Add lookups to every default language system.
///
/// Convenience method for recurring pattern.
Expand Down
12 changes: 4 additions & 8 deletions fontbe/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,8 @@ impl<'a> FeatureWriter<'a> {
}
let mut ppos_subtables = PairPosBuilder::default();

let mut var_indices = HashMap::new();
for (idx, deltas) in self.kerning.deltas().enumerate() {
var_indices.insert(idx, builder.add_deltas(deltas.clone()));
}
for kern in self.kerning.kerns() {
kern.insert_into(&var_indices, &mut ppos_subtables);
kern.insert_into(&mut ppos_subtables);
}

// now we have a builder for the pairpos subtables, so we can make
Expand Down Expand Up @@ -252,7 +248,7 @@ impl<'a> FeatureWriter<'a> {
.insert_mark(
mark.gid,
mark_base.class.clone(),
mark.create_anchor_table(builder)?,
mark.create_anchor_table(),
)
.map_err(Error::PreviouslyAssignedClass)?;
}
Expand All @@ -261,7 +257,7 @@ impl<'a> FeatureWriter<'a> {
mark_base_builder.insert_base(
base.gid,
&mark_base.class,
base.create_anchor_table(builder)?,
base.create_anchor_table(),
)
}

Expand All @@ -282,7 +278,7 @@ impl<'a> FeatureWriter<'a> {
.insert_mark1(
mark.gid,
mark_mark.class.clone(),
mark.create_anchor_table(builder)?,
mark.create_anchor_table(),
)
.map_err(Error::PreviouslyAssignedClass)?;
}
Expand Down
32 changes: 11 additions & 21 deletions fontbe/src/kern.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
//! Generates a [Kerning] datastructure to be fed to fea-rs
use std::collections::{BTreeMap, HashMap, HashSet};
use std::collections::{BTreeMap, HashSet};

use fea_rs::GlyphSet;
use fea_rs::{compile::ValueRecord as ValueRecordBuilder, GlyphSet};
use fontdrasil::orchestration::{Access, Work};
use write_fonts::{tables::gpos::ValueRecord, types::GlyphId};
use fontir::{ir::KernParticipant, orchestration::WorkId as FeWorkId};
use write_fonts::types::GlyphId;

use crate::{
error::Error,
features::resolve_variable_metric,
orchestration::{AnyWorkId, BeWork, Context, Kerning, WorkId},
};
use fontir::{ir::KernParticipant, orchestration::WorkId as FeWorkId};

#[derive(Debug)]
struct KerningWork {}
Expand Down Expand Up @@ -62,25 +62,15 @@ impl Work<Context, AnyWorkId, Error> for KerningWork {
let mut kerning = Kerning::default();

// now for each kerning entry, directly add a rule to the builder:
let mut delta_indices = HashMap::new();
for ((left, right), values) in &ir_kerning.kerns {
let (default_value, deltas) = resolve_variable_metric(&static_metadata, values)?;
let delta_idx = if !deltas.is_empty() {
let mut current = delta_indices.get(&deltas).cloned();
if current.is_none() {
let idx = kerning.add_deltas(deltas.clone());
delta_indices.insert(deltas, idx);
current = Some(idx);
}
current
} else {
None
};
let x_adv_record = ValueRecord::new().with_x_advance(default_value);
let x_adv_record = ValueRecordBuilder::new()
.with_x_advance(default_value)
.with_x_advance_device(deltas);

match (left, right) {
(KernParticipant::Glyph(left), KernParticipant::Glyph(right)) => {
kerning.add_pair(gid(left)?, x_adv_record.clone(), gid(right)?, delta_idx);
kerning.add_pair(gid(left)?, x_adv_record.clone(), gid(right)?);
}
(KernParticipant::Group(left), KernParticipant::Group(right)) => {
let left = glyph_classes
Expand All @@ -91,7 +81,7 @@ impl Work<Context, AnyWorkId, Error> for KerningWork {
.get(right)
.ok_or_else(|| Error::MissingGlyphId(right.clone()))?
.clone();
kerning.add_class(left, x_adv_record.clone(), right, delta_idx);
kerning.add_class(left, x_adv_record.clone(), right);
}
// if groups are mixed with glyphs then we enumerate the group
(KernParticipant::Glyph(left), KernParticipant::Group(right)) => {
Expand All @@ -105,7 +95,7 @@ impl Work<Context, AnyWorkId, Error> for KerningWork {
.get(&right)
.ok_or_else(|| Error::MissingGlyphId(right.clone()))?;
for gid1 in right.iter() {
kerning.add_pair(gid0, x_adv_record.clone(), gid1, delta_idx);
kerning.add_pair(gid0, x_adv_record.clone(), gid1);
}
}
(KernParticipant::Group(left), KernParticipant::Glyph(right)) => {
Expand All @@ -114,7 +104,7 @@ impl Work<Context, AnyWorkId, Error> for KerningWork {
.ok_or_else(|| Error::MissingGlyphId(left.clone()))?;
let gid1 = gid(right)?;
for gid0 in left.iter() {
kerning.add_pair(gid0, x_adv_record.clone(), gid1, delta_idx);
kerning.add_pair(gid0, x_adv_record.clone(), gid1);
}
}
}
Expand Down
79 changes: 15 additions & 64 deletions fontbe/src/orchestration.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//! Helps coordinate the graph execution for BE
use std::{
collections::HashMap,
fs::File,
io::{self, BufReader, BufWriter, Read, Write},
path::{Path, PathBuf},
sync::Arc,
};

use fea_rs::{
compile::{FeatureBuilder, PairPosBuilder},
compile::{PairPosBuilder, ValueRecord as ValueRecordBuilder},
GlyphMap, GlyphSet,
};
use fontdrasil::{
Expand Down Expand Up @@ -38,13 +37,12 @@ use write_fonts::{
fvar::Fvar,
gdef::Gdef,
glyf::Glyph as RawGlyph,
gpos::{AnchorTable, Gpos, ValueRecord},
gpos::Gpos,
gsub::Gsub,
gvar::{GlyphDelta, GlyphDeltas},
head::Head,
hhea::Hhea,
hvar::Hvar,
layout::PendingVariationIndex,
loca::LocaFormat,
maxp::Maxp,
name::Name,
Expand Down Expand Up @@ -275,56 +273,32 @@ pub enum Kern {
Pair {
glyph0: GlyphId,
glyph1: GlyphId,
x_advance: ValueRecord,
delta_idx: Option<usize>,
x_advance: ValueRecordBuilder,
},
Class {
glyphs0: GlyphSet,
glyphs1: GlyphSet,
x_advance: ValueRecord,
delta_idx: Option<usize>,
x_advance: ValueRecordBuilder,
},
}

impl Kern {
pub fn insert_into(
&self,
var_indices: &HashMap<usize, PendingVariationIndex>,
ppos_subtables: &mut PairPosBuilder,
) {
let with_deltas = |x_advance: &ValueRecord, delta_idx: Option<usize>| {
if let Some(delta_idx) = delta_idx {
x_advance.clone().with_x_advance_device(
var_indices
.get(&delta_idx)
.unwrap_or_else(|| panic!("No entry for {delta_idx} in {var_indices:?}"))
.clone(),
)
} else {
x_advance.clone()
}
};

pub fn insert_into(&self, ppos_subtables: &mut PairPosBuilder) {
match self {
Kern::Pair {
glyph0,
glyph1,
x_advance,
delta_idx,
} => ppos_subtables.insert_pair(
*glyph0,
with_deltas(x_advance, *delta_idx),
*glyph1,
Default::default(),
),
} => {
ppos_subtables.insert_pair(*glyph0, x_advance.clone(), *glyph1, Default::default())
}
Kern::Class {
glyphs0,
glyphs1,
x_advance,
delta_idx,
} => ppos_subtables.insert_classes(
glyphs0.clone(),
with_deltas(x_advance, *delta_idx),
x_advance.clone(),
glyphs1.clone(),
Default::default(),
),
Expand Down Expand Up @@ -381,24 +355,10 @@ impl MarkEntry {
})
}

pub(crate) fn create_anchor_table(
&self,
builder: &mut FeatureBuilder,
) -> Result<AnchorTable, Error> {
let x_var_idx =
(!self.x_deltas.is_empty()).then(|| builder.add_deltas(self.x_deltas.clone()));
let y_var_idx =
(!self.y_deltas.is_empty()).then(|| builder.add_deltas(self.y_deltas.clone()));
if x_var_idx.is_some() || y_var_idx.is_some() {
Ok(AnchorTable::format_3(
self.x_default,
self.y_default,
x_var_idx.map(Into::into),
y_var_idx.map(Into::into),
))
} else {
Ok(AnchorTable::format_1(self.x_default, self.y_default))
}
pub(crate) fn create_anchor_table(&self) -> fea_rs::compile::Anchor {
fea_rs::compile::Anchor::new(self.x_default, self.y_default)
.with_x_device(self.x_deltas.clone())
.with_y_device(self.y_deltas.clone())
}
}

Expand Down Expand Up @@ -500,33 +460,24 @@ impl Kerning {
self.deltas.len() - 1
}

pub fn add_pair(
&mut self,
glyph0: GlyphId,
x_advance: ValueRecord,
glyph1: GlyphId,
delta_idx: Option<usize>,
) {
pub fn add_pair(&mut self, glyph0: GlyphId, x_advance: ValueRecordBuilder, glyph1: GlyphId) {
self.kerns.push(Kern::Pair {
glyph0,
glyph1,
x_advance,
delta_idx,
})
}

pub fn add_class(
&mut self,
glyphs0: GlyphSet,
x_advance: ValueRecord,
x_advance: ValueRecordBuilder,
glyphs1: GlyphSet,
delta_idx: Option<usize>,
) {
self.kerns.push(Kern::Class {
glyphs0,
glyphs1,
x_advance,
delta_idx,
})
}
}
Expand Down

0 comments on commit b24324b

Please sign in to comment.