diff options
author | 2019-11-13 03:54:36 +0100 | |
---|---|---|
committer | 2019-11-13 03:54:36 +0100 | |
commit | f0b1e65ba4f8df173f8201585a1d81245e93ab94 (patch) | |
tree | 1e03a138846adc20ba072079e15f3454106ad2ec /wgpu/src/text.rs | |
parent | 73f3c900071f950ea914652ca3f0002c1e173f61 (diff) | |
download | iced-f0b1e65ba4f8df173f8201585a1d81245e93ab94.tar.gz iced-f0b1e65ba4f8df173f8201585a1d81245e93ab94.tar.bz2 iced-f0b1e65ba4f8df173f8201585a1d81245e93ab94.zip |
Move text logic in `iced_wgpu` to a `text` module
Diffstat (limited to 'wgpu/src/text.rs')
-rw-r--r-- | wgpu/src/text.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs new file mode 100644 index 00000000..d6565195 --- /dev/null +++ b/wgpu/src/text.rs @@ -0,0 +1,106 @@ +mod font; + +use crate::Transformation; +use std::cell::RefCell; + +pub struct Pipeline { + draw_brush: wgpu_glyph::GlyphBrush<'static, ()>, + measure_brush: RefCell<glyph_brush::GlyphBrush<'static, ()>>, +} + +impl Pipeline { + pub fn new(device: &mut wgpu::Device) -> Self { + // TODO: Font customization + let font_source = font::Source::new(); + + let default_font = font_source + .load(&[font::Family::SansSerif, font::Family::Serif]) + .expect("Find sans-serif or serif font"); + + let mono_font = font_source + .load(&[font::Family::Monospace]) + .expect("Find monospace font"); + + let draw_brush = + wgpu_glyph::GlyphBrushBuilder::using_fonts_bytes(vec![ + default_font.clone(), + mono_font, + ]) + .initial_cache_size((2048, 2048)) + .build(device, wgpu::TextureFormat::Bgra8UnormSrgb); + + let measure_brush = + glyph_brush::GlyphBrushBuilder::using_font_bytes(default_font) + .build(); + + Pipeline { + draw_brush, + measure_brush: RefCell::new(measure_brush), + } + } + + pub fn overlay_font(&self) -> wgpu_glyph::FontId { + wgpu_glyph::FontId(1) + } + + pub fn queue(&mut self, section: wgpu_glyph::Section) { + self.draw_brush.queue(section); + } + + pub fn draw_queued( + &mut self, + device: &mut wgpu::Device, + encoder: &mut wgpu::CommandEncoder, + target: &wgpu::TextureView, + transformation: Transformation, + region: wgpu_glyph::Region, + ) { + self.draw_brush + .draw_queued_with_transform_and_scissoring( + device, + encoder, + target, + transformation.into(), + region, + ) + .expect("Draw text"); + } + + pub fn measure(&self, section: &wgpu_glyph::Section<'_>) -> (f32, f32) { + use wgpu_glyph::GlyphCruncher; + + if let Some(bounds) = + self.measure_brush.borrow_mut().glyph_bounds(section) + { + (bounds.width().ceil(), bounds.height().ceil()) + } else { + (0.0, 0.0) + } + } + + pub fn space_width(&self, size: f32) -> f32 { + use wgpu_glyph::GlyphCruncher; + + let glyph_brush = self.measure_brush.borrow(); + + // TODO: Select appropriate font + let font = &glyph_brush.fonts()[0]; + + font.glyph(' ') + .scaled(wgpu_glyph::Scale { x: size, y: size }) + .h_metrics() + .advance_width + } + + pub fn clear_measurement_cache(&mut self) { + // Trim measurements cache + // TODO: We should probably use a `GlyphCalculator` for this. However, + // it uses a lifetimed `GlyphCalculatorGuard` with side-effects on drop. + // This makes stuff quite inconvenient. A manual method for trimming the + // cache would make our lives easier. + self.measure_brush + .borrow_mut() + .process_queued(|_, _| {}, |_| {}) + .expect("Trim text measurements"); + } +} |