diff --git a/node-graph/gcore/src/logic.rs b/node-graph/gcore/src/logic.rs index 8ccd9c506..9be5e7c60 100644 --- a/node-graph/gcore/src/logic.rs +++ b/node-graph/gcore/src/logic.rs @@ -33,8 +33,8 @@ fn string_slice(_: impl Ctx, #[implementations(String)] string: String, start: f } #[node_macro::node(category("Text"))] -fn string_length(_: impl Ctx, #[implementations(String)] string: String) -> usize { - string.len() +fn string_length(_: impl Ctx, #[implementations(String)] string: String) -> u32 { + string.chars().count() as u32 } #[node_macro::node(category("Math: Logic"))] diff --git a/node-graph/gcore/src/text/to_path.rs b/node-graph/gcore/src/text/to_path.rs index bfe60da86..0a6175506 100644 --- a/node-graph/gcore/src/text/to_path.rs +++ b/node-graph/gcore/src/text/to_path.rs @@ -1,4 +1,4 @@ -use crate::vector::PointId; +use crate::vector::{PointId, VectorData}; use bezier_rs::{ManipulatorGroup, Subpath}; use core::cell::RefCell; use glam::{DAffine2, DVec2}; @@ -21,23 +21,17 @@ thread_local! { struct PathBuilder { current_subpath: Subpath, glyph_subpaths: Vec>, - other_subpaths: Vec>, - origin: DVec2, + other_subpaths: Vec>, scale: f64, id: PointId, } impl PathBuilder { fn point(&self, x: f32, y: f32) -> DVec2 { - // Y-axis inversion converts from font coordinate system (Y-up) to graphics coordinate system (Y-down) - DVec2::new(self.origin.x + x as f64, self.origin.y - y as f64) * self.scale + DVec2::new(x as f64, -y as f64) * self.scale } - fn set_origin(&mut self, x: f64, y: f64) { - self.origin = DVec2::new(x, y); - } - - fn draw_glyph(&mut self, glyph: &OutlineGlyph<'_>, size: f32, normalized_coords: &[NormalizedCoord], style_skew: Option, skew: DAffine2) { + fn draw_glyph(&mut self, glyph: &OutlineGlyph<'_>, size: f32, normalized_coords: &[NormalizedCoord], glyph_offset: DVec2, style_skew: Option, skew: DAffine2) { let location_ref = LocationRef::new(normalized_coords); let settings = DrawSettings::unhinted(Size::new(size), location_ref); glyph.draw(settings, self).unwrap(); @@ -53,7 +47,11 @@ impl PathBuilder { } if !self.glyph_subpaths.is_empty() { - self.other_subpaths.extend(core::mem::take(&mut self.glyph_subpaths)); + self.other_subpaths.push(crate::instances::Instance { + instance: VectorData::from_subpaths(core::mem::take(&mut self.glyph_subpaths), false), + transform: DAffine2::from_translation(glyph_offset), + ..Default::default() + }) } } } @@ -145,14 +143,12 @@ fn render_glyph_run(glyph_run: &GlyphRun<'_, ()>, path_builder: &mut PathBuilder let outlines = font_ref.outline_glyphs(); for glyph in glyph_run.glyphs() { - let glyph_x = run_x + glyph.x; - let glyph_y = run_y - glyph.y; + let glyph_offset = DVec2::new((run_x + glyph.x) as f64, (run_y - glyph.y) as f64); run_x += glyph.advance; let glyph_id = GlyphId::from(glyph.id); if let Some(glyph_outline) = outlines.get(glyph_id) { - path_builder.set_origin(glyph_x as f64, glyph_y as f64); - path_builder.draw_glyph(&glyph_outline, font_size, &normalized_coords, style_skew, skew); + path_builder.draw_glyph(&glyph_outline, font_size, &normalized_coords, glyph_offset, style_skew, skew); } } } @@ -187,14 +183,13 @@ fn layout_text(str: &str, font_data: Option>, typesetting: TypesettingC Some(layout) } -pub fn to_path(str: &str, font_data: Option>, typesetting: TypesettingConfig) -> Vec> { +pub fn to_path(str: &str, font_data: Option>, typesetting: TypesettingConfig) -> Vec> { let Some(layout) = layout_text(str, font_data, typesetting) else { return Vec::new() }; let mut path_builder = PathBuilder { current_subpath: Subpath::new(Vec::new(), false), glyph_subpaths: Vec::new(), other_subpaths: Vec::new(), - origin: DVec2::ZERO, scale: layout.scale() as f64, id: PointId::ZERO, }; diff --git a/node-graph/gcore/src/vector/vector_nodes.rs b/node-graph/gcore/src/vector/vector_nodes.rs index 118c2fbfb..7f55f8e9e 100644 --- a/node-graph/gcore/src/vector/vector_nodes.rs +++ b/node-graph/gcore/src/vector/vector_nodes.rs @@ -1875,7 +1875,7 @@ fn point_inside(_: impl Ctx, source: VectorDataTable, point: DVec2) -> bool { #[node_macro::node(category("General"), path(graphene_core::vector))] async fn count_elements(_: impl Ctx, #[implementations(GraphicGroupTable, VectorDataTable, RasterDataTable, RasterDataTable)] source: Instances) -> u64 { - source.instance_iter().count() as u64 + source.len() as u64 } #[node_macro::node(category("Vector: Measure"), path(graphene_core::vector))] diff --git a/node-graph/gstd/src/text.rs b/node-graph/gstd/src/text.rs index 71eea96fb..eb0b67f22 100644 --- a/node-graph/gstd/src/text.rs +++ b/node-graph/gstd/src/text.rs @@ -39,7 +39,17 @@ fn text<'i: 'n>( let font_data = editor.font_cache.get(&font_name).map(|f| load_font(f)); - let result = VectorData::from_subpaths(to_path(&text, font_data, typesetting), false); + let glyph_vectors = to_path(&text, font_data, typesetting); - VectorDataTable::new(result) + let mut glyph_table = if glyph_vectors.is_empty() { + VectorDataTable::new(VectorData::default()) + } else { + VectorDataTable::default() + }; + + for glyph in glyph_vectors { + glyph_table.push(glyph); + } + + glyph_table }