Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions fontbe/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,11 +663,7 @@ impl Work<Context, AnyWorkId, Error> for FeatureCompilationWork {
// if fea generated tables other than GPOS/GSUB/GDEF, stash them
// so we can merge later on
if result.has_non_layout_tables() {
let extras = ExtraFeaTables::from(result);
// we're currently only handling 'name' and OS/2; if other tables are in
// here we probably need to do something with them too, so let's warn
extras.log_unhandled_extras();
context.extra_fea_tables.set(extras);
context.extra_fea_tables.set(ExtraFeaTables::from(result));
}

// Enables the assumption that if the file exists features were compiled
Expand Down
9 changes: 9 additions & 0 deletions fontbe/src/head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ impl Work<Context, AnyWorkId, Error> for HeadWork {
.variant(FeWorkId::StaticMetadata)
.variant(WorkId::Glyf)
.variant(WorkId::LocaFormat)
.variant(WorkId::ExtraFeaTables)
.build()
}

Expand All @@ -134,6 +135,14 @@ impl Work<Context, AnyWorkId, Error> for HeadWork {
);
apply_created_modified(&mut head, static_metadata.misc.created);
apply_macstyle(&mut head, static_metadata.misc.selection_flags);

// Apply FEA `table head { ... }` override (only FontRevision is settable)
if let Some(extra_tables) = context.extra_fea_tables.try_get()
&& let Some(font_rev) = extra_tables.head.as_ref().map(|h| h.font_revision)
{
head.font_revision = font_rev
}

context.head.set(head);

// Defer x/y Min/Max to metrics and limits job
Expand Down
13 changes: 12 additions & 1 deletion fontbe/src/metrics_and_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ impl Work<Context, AnyWorkId, Error> for MetricAndLimitWork {
.variant(WorkId::ALL_GLYF_FRAGMENTS)
// We need composite bboxes to be calculated:
.variant(WorkId::Glyf)
.variant(WorkId::ExtraFeaTables)
.build()
}

Expand Down Expand Up @@ -350,7 +351,7 @@ impl Work<Context, AnyWorkId, Error> for MetricAndLimitWork {
let metrics = builder.build();

// Build and send horizontal metrics tables out into the world
let hhea = Hhea {
let mut hhea = Hhea {
ascender: FWord::new(default_metrics.hhea_ascender.into_inner().ot_round()),
descender: FWord::new(default_metrics.hhea_descender.into_inner().ot_round()),
line_gap: FWord::new(default_metrics.hhea_line_gap.into_inner().ot_round()),
Expand All @@ -368,6 +369,16 @@ impl Work<Context, AnyWorkId, Error> for MetricAndLimitWork {
}
})?,
};
// Apply FEA `table hhea { ... }` overrides.
// FEA can only set Ascender, Descender, LineGap, CaretOffset.
if let Some(extra_tables) = context.extra_fea_tables.try_get()
&& let Some(fea_hhea) = extra_tables.hhea.as_ref()
{
hhea.ascender = fea_hhea.ascender;
hhea.descender = fea_hhea.descender;
hhea.line_gap = fea_hhea.line_gap;
hhea.caret_offset = fea_hhea.caret_offset;
}
context.hhea.set(hhea);

let hmtx = Hmtx::new(metrics.long_metrics, metrics.first_side_bearings);
Expand Down
16 changes: 0 additions & 16 deletions fontbe/src/orchestration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,22 +266,6 @@ impl From<Compilation> for ExtraFeaTables {
}
}

impl ExtraFeaTables {
pub(crate) fn log_unhandled_extras(&self) {
for (name, unhandled) in [
("head", self.head.is_some()),
("hhea", self.hhea.is_some()),
("vhea", self.vhea.is_some()),
("base", self.base.is_some()),
("stat", self.stat.is_some()),
] {
if unhandled {
log::warn!("FEA generated unused table '{name}'");
}
}
}
}

// we could use serde here but it produces really big outputs; so instead
// we can use fontwrite on each table, and then serialize an array of Option<Vec<u8>>
impl Persistable for ExtraFeaTables {
Expand Down
12 changes: 11 additions & 1 deletion fontbe/src/vertical_metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ impl Work<Context, AnyWorkId, Error> for VerticalMetricsWork {
.variant(WorkId::ALL_GLYF_FRAGMENTS)
// We need composite bboxes to be calculated:
.variant(WorkId::Glyf)
.variant(WorkId::ExtraFeaTables)
.build()
}

Expand Down Expand Up @@ -97,7 +98,7 @@ impl Work<Context, AnyWorkId, Error> for VerticalMetricsWork {
let metrics = builder.build();

// Build and send vertical metrics tables out into the world
let vhea = Vhea {
let mut vhea = Vhea {
ascender: FWord::new(default_metrics.vhea_ascender.into_inner().ot_round()),
descender: FWord::new(default_metrics.vhea_descender.into_inner().ot_round()),
line_gap: FWord::new(default_metrics.vhea_line_gap.into_inner().ot_round()),
Expand All @@ -118,6 +119,15 @@ impl Work<Context, AnyWorkId, Error> for VerticalMetricsWork {
}
})?,
};
// Apply FEA `table vhea { ... }` overrides.
// FEA can only set VertTypoAscender, VertTypoDescender, VertTypoLineGap.
if let Some(extra_tables) = context.extra_fea_tables.try_get()
&& let Some(fea_vhea) = extra_tables.vhea.as_ref()
{
vhea.ascender = fea_vhea.ascender;
vhea.descender = fea_vhea.descender;
vhea.line_gap = fea_vhea.line_gap;
}
context.vhea.set(vhea);

let vmtx = Vmtx::new(metrics.long_metrics, metrics.first_side_bearings);
Expand Down
43 changes: 43 additions & 0 deletions fontc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5537,4 +5537,47 @@ mod tests {
.join("\n")
);
}

// FEA `table` block overrides: verify that explicit values in FEA win over
// fontinfo-derived values for head, hhea, and OS/2 tables.

#[test]
fn fea_table_overrides_head() {
let result = TestCompile::compile_source("FeaTableOverrides.ufo");
let head = result.font().head().unwrap();
// FEA says FontRevision 2.5; fontinfo says versionMajor=1 versionMinor=0
assert_eq!(
write_fonts::types::Fixed::from_f64(2.5),
head.font_revision()
);
}

#[test]
fn fea_table_overrides_hhea() {
let result = TestCompile::compile_source("FeaTableOverrides.ufo");
let hhea = result.font().hhea().unwrap();
// FEA: Ascender 950, Descender -250, LineGap 0, CaretOffset 20
// fontinfo: 800, -200, 0, (default)
assert_eq!(write_fonts::types::FWord::new(950), hhea.ascender());
assert_eq!(write_fonts::types::FWord::new(-250), hhea.descender());
assert_eq!(write_fonts::types::FWord::new(0), hhea.line_gap());
assert_eq!(20, hhea.caret_offset());
}

#[test]
fn fea_table_overrides_os2() {
let result = TestCompile::compile_source("FeaTableOverrides.ufo");
let os2 = result.font().os2().unwrap();
// FEA: FSType 0, TypoAscender 950, TypoDescender -250, TypoLineGap 0,
// winAscent 1100, winDescent 250, WeightClass 700
// fontinfo: FSType 4 (bit 2), TypoAscender 800, TypoDescender -200,
// TypoLineGap 200, winAscent 1000, winDescent 200, WeightClass 400
assert_eq!(0, os2.fs_type());
assert_eq!(950, os2.s_typo_ascender());
assert_eq!(-250, os2.s_typo_descender());
assert_eq!(0, os2.s_typo_line_gap());
assert_eq!(1100, os2.us_win_ascent());
assert_eq!(250, os2.us_win_descent());
assert_eq!(700, os2.us_weight_class());
}
}
22 changes: 22 additions & 0 deletions resources/testdata/FeaTableOverrides.ufo/features.fea
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
languagesystem DFLT dflt;

table head {
FontRevision 2.5;
} head;

table hhea {
Ascender 950;
Descender -250;
LineGap 0;
CaretOffset 20;
} hhea;

table OS/2 {
FSType 0;
TypoAscender 950;
TypoDescender -250;
TypoLineGap 0;
winAscent 1100;
winDescent 250;
WeightClass 700;
} OS/2;
40 changes: 40 additions & 0 deletions resources/testdata/FeaTableOverrides.ufo/fontinfo.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>familyName</key>
<string>FeaTableOverrides</string>
<key>unitsPerEm</key>
<integer>1000</integer>
<key>ascender</key>
<integer>800</integer>
<key>descender</key>
<integer>-200</integer>
<key>openTypeHheaAscender</key>
<integer>800</integer>
<key>openTypeHheaDescender</key>
<integer>-200</integer>
<key>openTypeHheaLineGap</key>
<integer>0</integer>
<key>openTypeOS2TypoAscender</key>
<integer>800</integer>
<key>openTypeOS2TypoDescender</key>
<integer>-200</integer>
<key>openTypeOS2TypoLineGap</key>
<integer>200</integer>
<key>openTypeOS2WinAscent</key>
<integer>1000</integer>
<key>openTypeOS2WinDescent</key>
<integer>200</integer>
<key>openTypeOS2WeightClass</key>
<integer>400</integer>
<key>openTypeOS2Type</key>
<array>
<integer>2</integer>
</array>
<key>versionMajor</key>
<integer>1</integer>
<key>versionMinor</key>
<integer>0</integer>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>space</key>
<string>space.glif</string>
</dict>
</plist>
5 changes: 5 additions & 0 deletions resources/testdata/FeaTableOverrides.ufo/glyphs/space.glif
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<glyph name="space" format="2">
<advance width="250"/>
<unicode hex="0020"/>
</glyph>
10 changes: 10 additions & 0 deletions resources/testdata/FeaTableOverrides.ufo/layercontents.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<array>
<string>public.default</string>
<string>glyphs</string>
</array>
</array>
</plist>
10 changes: 10 additions & 0 deletions resources/testdata/FeaTableOverrides.ufo/lib.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>public.glyphOrder</key>
<array>
<string>space</string>
</array>
</dict>
</plist>
10 changes: 10 additions & 0 deletions resources/testdata/FeaTableOverrides.ufo/metainfo.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>creator</key>
<string>com.github.fonttools.ufoLib</string>
<key>formatVersion</key>
<integer>3</integer>
</dict>
</plist>
Loading