Skip to content

Commit 7ef9e5a

Browse files
authored
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
1 parent 4427e97 commit 7ef9e5a

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

node-graph/gcore/src/text/to_path.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,14 @@ impl PathBuilder {
5050
}
5151

5252
if per_glyph_instances {
53-
if !self.glyph_subpaths.is_empty() {
54-
self.vector_table.push(Instance {
55-
instance: VectorData::from_subpaths(core::mem::take(&mut self.glyph_subpaths), false),
56-
transform: DAffine2::from_translation(glyph_offset),
57-
..Default::default()
58-
})
59-
}
60-
} else if !self.glyph_subpaths.is_empty() {
61-
for subpath in self.glyph_subpaths.iter() {
62-
// Unwrapping here is ok, since the check above guarantees there is at least one `VectorData`
53+
self.vector_table.push(Instance {
54+
instance: VectorData::from_subpaths(core::mem::take(&mut self.glyph_subpaths), false),
55+
transform: DAffine2::from_translation(glyph_offset),
56+
..Default::default()
57+
});
58+
} else {
59+
for subpath in self.glyph_subpaths.drain(..) {
60+
// Unwrapping here is ok because `self.vector_table` is initialized with a single `VectorData`
6361
self.vector_table.get_mut(0).unwrap().instance.append_subpath(subpath, false);
6462
}
6563
}
@@ -128,18 +126,26 @@ fn render_glyph_run(glyph_run: &GlyphRun<'_, ()>, path_builder: &mut PathBuilder
128126

129127
// User-requested tilt applied around baseline to avoid vertical displacement
130128
// Translation ensures rotation point is at the baseline, not origin
131-
let skew = DAffine2::from_translation(DVec2::new(0., run_y as f64))
132-
* DAffine2::from_cols_array(&[1., 0., -tilt.to_radians().tan(), 1., 0., 0.])
133-
* DAffine2::from_translation(DVec2::new(0., -run_y as f64));
129+
let skew = if per_glyph_instances {
130+
DAffine2::from_cols_array(&[1., 0., -tilt.to_radians().tan(), 1., 0., 0.])
131+
} else {
132+
DAffine2::from_translation(DVec2::new(0., run_y as f64))
133+
* DAffine2::from_cols_array(&[1., 0., -tilt.to_radians().tan(), 1., 0., 0.])
134+
* DAffine2::from_translation(DVec2::new(0., -run_y as f64))
135+
};
134136

135137
let synthesis = run.synthesis();
136138

137139
// Font synthesis (e.g., synthetic italic) applied separately from user transforms
138140
// This preserves the distinction between font styling and user transformations
139141
let style_skew = synthesis.skew().map(|angle| {
140-
DAffine2::from_translation(DVec2::new(0., run_y as f64))
141-
* DAffine2::from_cols_array(&[1., 0., -angle.to_radians().tan() as f64, 1., 0., 0.])
142-
* DAffine2::from_translation(DVec2::new(0., -run_y as f64))
142+
if per_glyph_instances {
143+
DAffine2::from_cols_array(&[1., 0., -angle.to_radians().tan() as f64, 1., 0., 0.])
144+
} else {
145+
DAffine2::from_translation(DVec2::new(0., run_y as f64))
146+
* DAffine2::from_cols_array(&[1., 0., -angle.to_radians().tan() as f64, 1., 0., 0.])
147+
* DAffine2::from_translation(DVec2::new(0., -run_y as f64))
148+
}
143149
});
144150

145151
let font = run.font();

0 commit comments

Comments
 (0)