diff --git a/Cargo.toml b/Cargo.toml index 30912a8..db05694 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ license = "MIT OR Apache-2.0 OR Zlib" [dependencies] wgpu = "0.14.0" etagere = "0.2.6" -cosmic-text = { git = "https://github.com/pop-os/cosmic-text", rev = "5fc5d2b", features = ["std", "swash"] } +cosmic-text = { git = "https://github.com/pop-os/cosmic-text", rev = "e788c17", features = ["std", "swash"] } lru = "0.9" [dev-dependencies] diff --git a/examples/hello-world.rs b/examples/hello-world.rs index 5eb569c..b414644 100644 --- a/examples/hello-world.rs +++ b/examples/hello-world.rs @@ -19,8 +19,6 @@ fn main() { pollster::block_on(run()); } -static mut FONT_SYSTEM: Option = None; - async fn run() { // Set up window let (width, height) = (800, 600); @@ -64,24 +62,19 @@ async fn run() { surface.configure(&device, &config); // Set up text renderer - unsafe { - FONT_SYSTEM = Some(FontSystem::new()); - } - let mut cache = SwashCache::new(unsafe { FONT_SYSTEM.as_ref().unwrap() }); + let mut font_system = FontSystem::new(); + let mut cache = SwashCache::new(); let mut atlas = TextAtlas::new(&device, &queue, swapchain_format); let mut text_renderer = TextRenderer::new(&mut atlas, &device, MultisampleState::default(), None); - let mut buffer = Buffer::new( - unsafe { FONT_SYSTEM.as_ref().unwrap() }, - Metrics::new(30, 42), - ); + let mut buffer = Buffer::new(&mut font_system, Metrics::new(30.0, 42.0)); - let physical_width = (width as f64 * scale_factor) as i32; - let physical_height = (height as f64 * scale_factor) as i32; + let physical_width = (width as f64 * scale_factor) as f32; + let physical_height = (height as f64 * scale_factor) as f32; - buffer.set_size(physical_width, physical_height); - buffer.set_text("Hello world! 👋\nThis is rendered with 🦅 glyphon 🦁\nThe text below should be partially clipped.\na b c d e f g h i j k l m n o p q r s t u v w x y z", Attrs::new().family(Family::SansSerif)); - buffer.shape_until_scroll(); + buffer.set_size(&mut font_system, physical_width, physical_height); + buffer.set_text(&mut font_system, "Hello world! 👋\nThis is rendered with 🦅 glyphon 🦁\nThe text below should be partially clipped.\na b c d e f g h i j k l m n o p q r s t u v w x y z", Attrs::new().family(Family::SansSerif)); + buffer.shape_until_scroll(&mut font_system); event_loop.run(move |event, _, control_flow| { let _ = (&instance, &adapter); @@ -102,6 +95,7 @@ async fn run() { .prepare( &device, &queue, + &mut font_system, &mut atlas, Resolution { width: config.width, diff --git a/src/lib.rs b/src/lib.rs index 1e235da..83dd6e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,10 +10,9 @@ pub use text_render::TextRenderer; // Re-export all top-level types from `cosmic-text` for convenience. pub use cosmic_text::{ self, fontdb, Action, Affinity, Attrs, AttrsList, AttrsOwned, Buffer, BufferLine, CacheKey, - Color, Command, Cursor, Edit, Editor, Family, FamilyOwned, Font, FontMatches, FontSystem, - LayoutCursor, LayoutGlyph, LayoutLine, LayoutRun, LayoutRunIter, Metrics, ShapeGlyph, - ShapeLine, ShapeSpan, ShapeWord, Stretch, Style, SubpixelBin, SwashCache, SwashContent, - SwashImage, Weight, Wrap, + Color, Command, Cursor, Edit, Editor, Family, FamilyOwned, Font, FontSystem, LayoutCursor, + LayoutGlyph, LayoutLine, LayoutRun, LayoutRunIter, Metrics, ShapeGlyph, ShapeLine, ShapeSpan, + ShapeWord, Stretch, Style, SubpixelBin, SwashCache, SwashContent, SwashImage, Weight, Wrap, }; use etagere::AllocId; @@ -90,9 +89,9 @@ impl Default for TextBounds { } /// A text area containing text to be rendered along with its overflow behavior. -pub struct TextArea<'a, 'b: 'a> { +pub struct TextArea<'a> { /// The buffer containing the text to be rendered. - pub buffer: &'a Buffer<'b>, + pub buffer: &'a Buffer, /// The left edge of the buffer. pub left: i32, /// The top edge of the buffer. diff --git a/src/text_render.rs b/src/text_render.rs index b87abb5..781b807 100644 --- a/src/text_render.rs +++ b/src/text_render.rs @@ -1,6 +1,6 @@ use crate::{ - CacheKey, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError, RenderError, - Resolution, SwashCache, SwashContent, TextArea, TextAtlas, + CacheKey, FontSystem, GlyphDetails, GlyphToRender, GpuCacheStatus, Params, PrepareError, + RenderError, Resolution, SwashCache, SwashContent, TextArea, TextAtlas, }; use std::{collections::HashSet, iter, mem::size_of, num::NonZeroU32, slice, sync::Arc}; use wgpu::{ @@ -63,13 +63,14 @@ impl TextRenderer { } /// Prepares all of the provided text areas for rendering. - pub fn prepare_with_depth<'a, 'b: 'a>( + pub fn prepare_with_depth( &mut self, device: &Device, queue: &Queue, + font_system: &mut FontSystem, atlas: &mut TextAtlas, screen_resolution: Resolution, - text_areas: &[TextArea<'a, 'b>], + text_areas: &[TextArea<'_>], cache: &mut SwashCache, mut metadata_to_depth: impl FnMut(usize) -> f32, ) -> Result<(), PrepareError> { @@ -104,7 +105,9 @@ impl TextRenderer { continue; } - let image = cache.get_image_uncached(glyph.cache_key).unwrap(); + let image = cache + .get_image_uncached(font_system, glyph.cache_key) + .unwrap(); let content_type = match image.content { SwashContent::Color => ContentType::Color, @@ -201,7 +204,7 @@ impl TextRenderer { let details = atlas.glyph(&glyph.cache_key).unwrap(); let mut x = glyph.x_int + details.left as i32 + text_area.left; - let mut y = line_y + glyph.y_int - details.top as i32 + text_area.top; + let mut y = line_y as i32 + glyph.y_int - details.top as i32 + text_area.top; let (mut atlas_x, mut atlas_y, content_type) = match details.gpu_cache { GpuCacheStatus::InAtlas { x, y, content_type } => (x, y, content_type), @@ -349,18 +352,20 @@ impl TextRenderer { Ok(()) } - pub fn prepare<'a, 'b: 'a>( + pub fn prepare( &mut self, device: &Device, queue: &Queue, + font_system: &mut FontSystem, atlas: &mut TextAtlas, screen_resolution: Resolution, - text_areas: &[TextArea<'a, 'b>], + text_areas: &[TextArea<'_>], cache: &mut SwashCache, ) -> Result<(), PrepareError> { self.prepare_with_depth( device, queue, + font_system, atlas, screen_resolution, text_areas,