Skip to content

Commit 736e525

Browse files
committed
Fix text-on-path rendering
1 parent c921696 commit 736e525

3 files changed

Lines changed: 43 additions & 11 deletions

File tree

editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageContext<'_>> for
394394
center,
395395
} => {
396396
let mut options = usvg::Options::default();
397-
options.fontdb_mut().load_font_data(include_bytes!("../../../../font.ttf").to_vec());
397+
options.fontdb_mut().load_font_data(include_bytes!("../overlays/source-sans-pro-regular.ttf").to_vec());
398398
options.font_family = "Source Sans Pro".to_string();
399399

400400
let svg = svg.replace("font-family=\"sans-serif\"", "font-family=\"Source Sans Pro\"");

node-graph/nodes/text/src/font_cache.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use dyn_any::DynAny;
22
use parley::fontique::Blob;
33
use std::collections::HashMap;
4+
use std::hash::Hash;
45
use std::sync::Arc;
56
use serde::Deserialize;
67

@@ -37,6 +38,21 @@ impl Font {
3738
font_style_to_restore: None,
3839
}
3940
}
41+
42+
pub fn named_weight(weight: u32) -> &'static str {
43+
match weight {
44+
100 => "Thin",
45+
200 => "Extra Light",
46+
300 => "Light",
47+
400 => "Regular",
48+
500 => "Medium",
49+
600 => "Semi Bold",
50+
700 => "Bold",
51+
800 => "Extra Bold",
52+
900 => "Black",
53+
_ => "Weight",
54+
}
55+
}
4056
}
4157

4258
impl Default for Font {
@@ -50,21 +66,32 @@ impl Default for Font {
5066
}
5167

5268
/// A cache of fonts
53-
#[derive(Debug, Default, Clone, DynAny)]
69+
#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize, DynAny)]
5470
pub struct FontCache {
5571
/// Mapping of font family name to font style name to font data
5672
pub font_file_data: HashMap<Font, Arc<Vec<u8>>>,
5773
}
5874

75+
impl Hash for FontCache {
76+
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
77+
self.font_file_data.len().hash(state);
78+
}
79+
}
80+
5981
impl FontCache {
6082
/// Get the font data for a font
6183
pub fn get_data(&self, font: &Font) -> Option<Arc<Vec<u8>>> {
6284
self.font_file_data.get(font).cloned()
6385
}
6486

6587
/// Insert font data for a font
66-
pub fn insert(&mut self, font: Font, data: Arc<Vec<u8>>) {
67-
self.font_file_data.insert(font, data);
88+
pub fn insert(&mut self, font: Font, data: impl Into<Arc<Vec<u8>>>) {
89+
self.font_file_data.insert(font, data.into());
90+
}
91+
92+
/// Check if the font data for a font is cached
93+
pub fn loaded_font(&self, font: &Font) -> bool {
94+
self.font_file_data.contains_key(font)
6895
}
6996

7097
/// Check if the font data for a font is cached

node-graph/nodes/text/src/path_builder.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ impl<Upstream: Default + 'static> PathBuilder<Upstream> {
3030
}
3131
}
3232

33+
fn point(&self, x: f32, y: f32) -> Point {
34+
Point::new(x as f64, -y as f64)
35+
}
36+
3337
pub fn draw_glyph(&mut self, glyph: &OutlineGlyph<'_>, size: f32, normalized_coords: &[NormalizedCoord], style_skew: Option<DAffine2>, final_transform: DAffine2, per_glyph_instances: bool) {
3438
self.origin = final_transform.translation;
3539
self.glyph_subpaths.clear();
3640
self.current_segments.clear();
41+
self.current_point = Point::ZERO;
3742

3843
let settings = DrawSettings::unhinted(Size::new(size), normalized_coords);
3944
glyph.draw(settings, self).unwrap();
@@ -101,26 +106,26 @@ impl<Upstream: Default + 'static> OutlinePen for PathBuilder<Upstream> {
101106
self.glyph_subpaths.push(Subpath::from_beziers(&self.current_segments, false));
102107
self.current_segments.clear();
103108
}
104-
self.current_point = Point::new(x as f64, y as f64);
109+
self.current_point = self.point(x, y);
105110
}
106111

107112
fn line_to(&mut self, x: f32, y: f32) {
108-
let p = Point::new(x as f64, y as f64);
113+
let p = self.point(x, y);
109114
self.current_segments.push(PathSeg::Line(kurbo::Line::new(self.current_point, p)));
110115
self.current_point = p;
111116
}
112117

113118
fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) {
114-
let p1 = Point::new(cx0 as f64, cy0 as f64);
115-
let p2 = Point::new(x as f64, y as f64);
119+
let p1 = self.point(cx0, cy0);
120+
let p2 = self.point(x, y);
116121
self.current_segments.push(PathSeg::Quad(kurbo::QuadBez::new(self.current_point, p1, p2)));
117122
self.current_point = p2;
118123
}
119124

120125
fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) {
121-
let p1 = Point::new(cx0 as f64, cy0 as f64);
122-
let p2 = Point::new(cx1 as f64, cy1 as f64);
123-
let p3 = Point::new(x as f64, y as f64);
126+
let p1 = self.point(cx0, cy0);
127+
let p2 = self.point(cx1, cy1);
128+
let p3 = self.point(x, y);
124129
self.current_segments.push(PathSeg::Cubic(kurbo::CubicBez::new(self.current_point, p1, p2, p3)));
125130
self.current_point = p3;
126131
}

0 commit comments

Comments
 (0)