From 652543f9aa0c69cb3568841a7432a8a22dcecda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 15 Dec 2022 05:06:47 +0100 Subject: [PATCH] Implement method to obtain glyph outlines This is useful for drawing text with non-bitmap based renderers (e.g. vectorial, tessellators, etc.). --- src/swash.rs | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/swash.rs b/src/swash.rs index 7a654de..28dfe27 100644 --- a/src/swash.rs +++ b/src/swash.rs @@ -10,6 +10,7 @@ use swash::zeno::{Format, Vector}; use crate::{CacheKey, Color, FontSystem}; +pub use swash::zeno::Command; pub use swash::scale::image::{Content as SwashContent, Image as SwashImage}; fn swash_image(font_system: &FontSystem, context: &mut ScaleContext, cache_key: CacheKey) -> Option { @@ -33,6 +34,7 @@ fn swash_image(font_system: &FontSystem, context: &mut ScaleContext, cache_key: let offset = Vector::new(cache_key.x_bin.as_float(), cache_key.y_bin.as_float()); + // Select our source order Render::new(&[ // Color outline with the first palette @@ -50,11 +52,40 @@ fn swash_image(font_system: &FontSystem, context: &mut ScaleContext, cache_key: .render(&mut scaler, cache_key.glyph_id) } +fn swash_outline_commands(font_system: &FontSystem, context: &mut ScaleContext, cache_key: CacheKey) -> Option> { + use swash::zeno::PathData as _; + + let font = match font_system.get_font(cache_key.font_id) { + Some(some) => some, + None => { + log::warn!("did not find font {:?}", cache_key.font_id); + return None; + }, + }; + + + // Build the scaler + let mut scaler = context + .builder(font.as_swash()) + .size(cache_key.font_size as f32) + .build(); + + // Scale the outline + let outline = scaler.scale_outline(cache_key.glyph_id).or_else(|| scaler.scale_color_outline(cache_key.glyph_id))?; + + // Get the path information of the outline + let path = outline.path(); + + // Return the commands + Some(path.commands().collect()) +} + /// Cache for rasterizing with the swash scaler pub struct SwashCache<'a> { font_system: &'a FontSystem, context: ScaleContext, pub image_cache: Map>, + pub outline_command_cache: Map>>, } impl<'a> SwashCache<'a> { @@ -63,7 +94,8 @@ impl<'a> SwashCache<'a> { Self { font_system, context: ScaleContext::new(), - image_cache: Map::new() + image_cache: Map::new(), + outline_command_cache: Map::new() } } @@ -79,6 +111,12 @@ impl<'a> SwashCache<'a> { }) } + pub fn get_outline_commands(&mut self, cache_key: CacheKey) -> Option<&[swash::zeno::Command]> { + self.outline_command_cache.entry(cache_key).or_insert_with(|| { + swash_outline_commands(self.font_system, &mut self.context, cache_key) + }).as_deref() + } + /// Enumerate pixels in an Image, use `with_image` for better performance pub fn with_pixels( &mut self,