From e29ed13566ef4d9cc0b097c6837a422e0d069742 Mon Sep 17 00:00:00 2001 From: Chad Brokaw Date: Thu, 9 Jan 2025 16:08:39 -0500 Subject: [PATCH] [skrifa] cleanup phantom deltas Additional code cleanup suggested after merging #1312 --- skrifa/src/outline/glyf/deltas.rs | 12 +++---- skrifa/src/outline/glyf/mod.rs | 60 ++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/skrifa/src/outline/glyf/deltas.rs b/skrifa/src/outline/glyf/deltas.rs index c9d0e9e51..a4d6bd048 100644 --- a/skrifa/src/outline/glyf/deltas.rs +++ b/skrifa/src/outline/glyf/deltas.rs @@ -14,11 +14,11 @@ use super::PHANTOM_POINT_COUNT; #[derive(Copy, Clone, Debug)] pub(super) enum AvailableVarMetrics { /// Full variable metrics with advances and side-bearings. - Present, + All, /// Variable advances but not side-bearings. - MissingSideBearings, + Advances, /// No variable metrics table. - Missing, + None, } /// Compute a set of deltas for the component offsets of a composite glyph. @@ -87,11 +87,11 @@ where // content of the HVAR table. let actual_len = match var_metrics { // Modify LSB and advance - AvailableVarMetrics::Missing => points.len() - 2, + AvailableVarMetrics::None => points.len() - 2, // Modify only LSB - AvailableVarMetrics::MissingSideBearings => points.len() - 3, + AvailableVarMetrics::Advances => points.len() - 3, // Modify nothing - AvailableVarMetrics::Present => points.len() - 4, + AvailableVarMetrics::All => points.len() - PHANTOM_POINT_COUNT, }; let deltas = &mut deltas[..actual_len]; compute_deltas_for_glyph(gvar, glyph_id, coords, deltas, |scalar, tuple, deltas| { diff --git a/skrifa/src/outline/glyf/mod.rs b/skrifa/src/outline/glyf/mod.rs index 9a644bf77..ac2fc7f31 100644 --- a/skrifa/src/outline/glyf/mod.rs +++ b/skrifa/src/outline/glyf/mod.rs @@ -66,12 +66,12 @@ impl<'a> Outlines<'a> { let var_metrics = match glyph_metrics.hvar.as_ref() { Some(hvar) => { if hvar.lsb_mapping().is_some() { - AvailableVarMetrics::Present + AvailableVarMetrics::All } else { - AvailableVarMetrics::MissingSideBearings + AvailableVarMetrics::Advances } } - None => AvailableVarMetrics::Missing, + None => AvailableVarMetrics::None, }; let ( glyph_count, @@ -749,12 +749,19 @@ impl Scaler for FreeTypeScaler<'_> { .ok_or(InsufficientMemory)?; if deltas::composite_glyph(gvar, glyph_id, self.coords, &mut deltas[..]).is_ok() { // Apply selective deltas to phantom points. + self.outlines.var_metrics.phantom_deltas( + &mut self.phantom, + deltas, + |phantom, delta| { + phantom.x += F26Dot6::from_bits(delta.x.to_i32()); + }, + ); match self.outlines.var_metrics { - AvailableVarMetrics::Missing => { + AvailableVarMetrics::None => { self.phantom[0].x += F26Dot6::from_bits(deltas[count - 4].x.to_i32()); self.phantom[1].x += F26Dot6::from_bits(deltas[count - 3].x.to_i32()); } - AvailableVarMetrics::MissingSideBearings => { + AvailableVarMetrics::Advances => { self.phantom[0].x += F26Dot6::from_bits(deltas[count - 4].x.to_i32()); } _ => {} @@ -1172,16 +1179,13 @@ impl Scaler for HarfBuzzScaler<'_> { .ok_or(InsufficientMemory)?; if deltas::composite_glyph(gvar, glyph_id, self.coords, &mut deltas[..]).is_ok() { // Apply selective deltas to phantom points. - match self.outlines.var_metrics { - AvailableVarMetrics::Missing => { - self.phantom[0].x += deltas[count - 4].x; - self.phantom[1].x += deltas[count - 3].x; - } - AvailableVarMetrics::MissingSideBearings => { - self.phantom[0].x += deltas[count - 4].x; - } - _ => {} - } + self.outlines.var_metrics.phantom_deltas( + &mut self.phantom, + deltas, + |phantom, delta| { + phantom.x += delta.x; + }, + ); have_deltas = true; } self.component_delta_count += count; @@ -1295,6 +1299,28 @@ fn map_point(transform: [f32; 6], p: Point) -> Point { } } +impl AvailableVarMetrics { + /// Calls `f` for each combination of phantom point and its associated + /// delta based on the available metrics present in `self`. + fn phantom_deltas( + self, + phantom: &mut [Point

; 4], + deltas: &[Point], + f: impl Fn(&mut Point

, &Point), + ) { + match self { + Self::None => { + f(&mut phantom[0], &deltas[deltas.len() - 4]); + f(&mut phantom[1], &deltas[deltas.len() - 3]); + } + Self::Advances => { + f(&mut phantom[0], &deltas[deltas.len() - 4]); + } + Self::All => {} + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -1348,7 +1374,7 @@ mod tests { let advance_hvar = scaled.adjusted_advance_width(); // Set HVAR to None and mark var metrics as missing so we pull deltas from gvar outlines.glyph_metrics.hvar = None; - outlines.var_metrics = AvailableVarMetrics::Missing; + outlines.var_metrics = AvailableVarMetrics::None; let scaler = FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); let scaled = scaler.scale(&outline.glyph, gid).unwrap(); @@ -1385,7 +1411,7 @@ mod tests { let advance_hvar = scaled.adjusted_advance_width(); // Set HVAR to None and mark var metrics as missing so we pull deltas from gvar outlines.glyph_metrics.hvar = None; - outlines.var_metrics = AvailableVarMetrics::Missing; + outlines.var_metrics = AvailableVarMetrics::None; let scaler = FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); let scaled = scaler.scale(&outline.glyph, gid).unwrap();