Fix Text node glyph duplication and wrong tilt calculation with per-glyph instances (#2907)

* fix: text node subpaths duplication

* fix: text node tilt calculation for per-glyph instaces
This commit is contained in:
Salman Abuhaimed
2025-07-18 11:00:24 -07:00
committed by GitHub
parent 4427e97f73
commit 7ef9e5a3e8
+22 -16
View File
@@ -50,16 +50,14 @@ impl PathBuilder {
} }
if per_glyph_instances { if per_glyph_instances {
if !self.glyph_subpaths.is_empty() { self.vector_table.push(Instance {
self.vector_table.push(Instance { instance: VectorData::from_subpaths(core::mem::take(&mut self.glyph_subpaths), false),
instance: VectorData::from_subpaths(core::mem::take(&mut self.glyph_subpaths), false), transform: DAffine2::from_translation(glyph_offset),
transform: DAffine2::from_translation(glyph_offset), ..Default::default()
..Default::default() });
}) } else {
} for subpath in self.glyph_subpaths.drain(..) {
} else if !self.glyph_subpaths.is_empty() { // Unwrapping here is ok because `self.vector_table` is initialized with a single `VectorData`
for subpath in self.glyph_subpaths.iter() {
// Unwrapping here is ok, since the check above guarantees there is at least one `VectorData`
self.vector_table.get_mut(0).unwrap().instance.append_subpath(subpath, false); self.vector_table.get_mut(0).unwrap().instance.append_subpath(subpath, false);
} }
} }
@@ -128,18 +126,26 @@ fn render_glyph_run(glyph_run: &GlyphRun<'_, ()>, path_builder: &mut PathBuilder
// User-requested tilt applied around baseline to avoid vertical displacement // User-requested tilt applied around baseline to avoid vertical displacement
// Translation ensures rotation point is at the baseline, not origin // Translation ensures rotation point is at the baseline, not origin
let skew = DAffine2::from_translation(DVec2::new(0., run_y as f64)) let skew = if per_glyph_instances {
* DAffine2::from_cols_array(&[1., 0., -tilt.to_radians().tan(), 1., 0., 0.]) DAffine2::from_cols_array(&[1., 0., -tilt.to_radians().tan(), 1., 0., 0.])
* DAffine2::from_translation(DVec2::new(0., -run_y as f64)); } else {
DAffine2::from_translation(DVec2::new(0., run_y as f64))
* DAffine2::from_cols_array(&[1., 0., -tilt.to_radians().tan(), 1., 0., 0.])
* DAffine2::from_translation(DVec2::new(0., -run_y as f64))
};
let synthesis = run.synthesis(); let synthesis = run.synthesis();
// Font synthesis (e.g., synthetic italic) applied separately from user transforms // Font synthesis (e.g., synthetic italic) applied separately from user transforms
// This preserves the distinction between font styling and user transformations // This preserves the distinction between font styling and user transformations
let style_skew = synthesis.skew().map(|angle| { let style_skew = synthesis.skew().map(|angle| {
DAffine2::from_translation(DVec2::new(0., run_y as f64)) if per_glyph_instances {
* DAffine2::from_cols_array(&[1., 0., -angle.to_radians().tan() as f64, 1., 0., 0.]) DAffine2::from_cols_array(&[1., 0., -angle.to_radians().tan() as f64, 1., 0., 0.])
* DAffine2::from_translation(DVec2::new(0., -run_y as f64)) } else {
DAffine2::from_translation(DVec2::new(0., run_y as f64))
* DAffine2::from_cols_array(&[1., 0., -angle.to_radians().tan() as f64, 1., 0., 0.])
* DAffine2::from_translation(DVec2::new(0., -run_y as f64))
}
}); });
let font = run.font(); let font = run.font();