diff options
Diffstat (limited to 'wgpu')
-rw-r--r-- | wgpu/Cargo.toml | 4 | ||||
-rw-r--r-- | wgpu/src/backend.rs | 86 | ||||
-rw-r--r-- | wgpu/src/text.rs | 264 |
3 files changed, 25 insertions, 329 deletions
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index f1e22cf6..5badeae6 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -23,14 +23,11 @@ dds = ["iced_graphics/dds"] farbfeld = ["iced_graphics/farbfeld"] canvas = ["iced_graphics/canvas"] qr_code = ["iced_graphics/qr_code"] -default_system_font = ["iced_graphics/font-source"] spirv = ["wgpu/spirv"] webgl = ["wgpu/webgl"] [dependencies] wgpu = "0.14" -wgpu_glyph = "0.18" -glyph_brush = "0.7" raw-window-handle = "0.5" log = "0.4" guillotiere = "0.6" @@ -48,7 +45,6 @@ path = "../native" [dependencies.iced_graphics] version = "0.7" path = "../graphics" -features = ["font-fallback", "font-icons"] [dependencies.tracing] version = "0.1.6" diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 6a299425..e9e23e80 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -4,10 +4,8 @@ use crate::triangle; use crate::{Settings, Transformation}; use iced_graphics::backend; -use iced_graphics::font; use iced_graphics::layer::Layer; use iced_graphics::{Primitive, Viewport}; -use iced_native::alignment; use iced_native::{Font, Size}; #[cfg(feature = "tracing")] @@ -173,83 +171,11 @@ impl Backend { } if !layer.text.is_empty() { - for text in layer.text.iter() { - // Target physical coordinates directly to avoid blurry text - let text = wgpu_glyph::Section { - // TODO: We `round` here to avoid rerasterizing text when - // its position changes slightly. This can make text feel a - // bit "jumpy". We may be able to do better once we improve - // our text rendering/caching pipeline. - screen_position: ( - (text.bounds.x * scale_factor).round(), - (text.bounds.y * scale_factor).round(), - ), - // TODO: Fix precision issues with some scale factors. - // - // The `ceil` here can cause some words to render on the - // same line when they should not. - // - // Ideally, `wgpu_glyph` should be able to compute layout - // using logical positions, and then apply the proper - // scaling when rendering. This would ensure that both - // measuring and rendering follow the same layout rules. - bounds: ( - (text.bounds.width * scale_factor).ceil(), - (text.bounds.height * scale_factor).ceil(), - ), - text: vec![wgpu_glyph::Text { - text: text.content, - scale: wgpu_glyph::ab_glyph::PxScale { - x: text.size * scale_factor, - y: text.size * scale_factor, - }, - font_id: self.text_pipeline.find_font(text.font), - extra: wgpu_glyph::Extra { - color: text.color, - z: 0.0, - }, - }], - layout: wgpu_glyph::Layout::default() - .h_align(match text.horizontal_alignment { - alignment::Horizontal::Left => { - wgpu_glyph::HorizontalAlign::Left - } - alignment::Horizontal::Center => { - wgpu_glyph::HorizontalAlign::Center - } - alignment::Horizontal::Right => { - wgpu_glyph::HorizontalAlign::Right - } - }) - .v_align(match text.vertical_alignment { - alignment::Vertical::Top => { - wgpu_glyph::VerticalAlign::Top - } - alignment::Vertical::Center => { - wgpu_glyph::VerticalAlign::Center - } - alignment::Vertical::Bottom => { - wgpu_glyph::VerticalAlign::Bottom - } - }), - }; - - self.text_pipeline.queue(text); + for _text in layer.text.iter() { + // TODO: Queue text sections } - self.text_pipeline.draw_queued( - device, - staging_belt, - encoder, - target, - transformation, - wgpu_glyph::Region { - x: bounds.x, - y: bounds.y, - width: bounds.width, - height: bounds.height, - }, - ); + // TODO: Draw queued } } } @@ -261,9 +187,9 @@ impl iced_graphics::Backend for Backend { } impl backend::Text for Backend { - const ICON_FONT: Font = font::ICONS; - const CHECKMARK_ICON: char = font::CHECKMARK_ICON; - const ARROW_DOWN_ICON: char = font::ARROW_DOWN_ICON; + const ICON_FONT: Font = Font::Default; // TODO + const CHECKMARK_ICON: char = '✓'; + const ARROW_DOWN_ICON: char = '▼'; fn default_size(&self) -> f32 { self.default_text_size diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index e17b84c1..125e6be0 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -1,265 +1,39 @@ -use crate::Transformation; - -use iced_graphics::font; - -use std::{cell::RefCell, collections::HashMap}; -use wgpu_glyph::ab_glyph; - pub use iced_native::text::Hit; #[derive(Debug)] -pub struct Pipeline { - draw_brush: RefCell<wgpu_glyph::GlyphBrush<()>>, - draw_font_map: RefCell<HashMap<String, wgpu_glyph::FontId>>, - measure_brush: RefCell<glyph_brush::GlyphBrush<()>>, -} +pub struct Pipeline; impl Pipeline { pub fn new( - device: &wgpu::Device, - format: wgpu::TextureFormat, - default_font: Option<&[u8]>, - multithreading: bool, + _device: &wgpu::Device, + _format: wgpu::TextureFormat, + _default_font: Option<&[u8]>, + _multithreading: bool, ) -> Self { - let default_font = default_font.map(|slice| slice.to_vec()); - - // TODO: Font customization - #[cfg(not(target_os = "ios"))] - #[cfg(feature = "default_system_font")] - let default_font = { - default_font.or_else(|| { - font::Source::new() - .load(&[font::Family::SansSerif, font::Family::Serif]) - .ok() - }) - }; - - let default_font = - default_font.unwrap_or_else(|| font::FALLBACK.to_vec()); - - let font = ab_glyph::FontArc::try_from_vec(default_font) - .unwrap_or_else(|_| { - log::warn!( - "System font failed to load. Falling back to \ - embedded font..." - ); - - ab_glyph::FontArc::try_from_slice(font::FALLBACK) - .expect("Load fallback font") - }); - - let draw_brush_builder = - wgpu_glyph::GlyphBrushBuilder::using_font(font.clone()) - .initial_cache_size((2048, 2048)) - .draw_cache_multithread(multithreading); - - #[cfg(target_arch = "wasm32")] - let draw_brush_builder = draw_brush_builder.draw_cache_align_4x4(true); - - let draw_brush = draw_brush_builder.build(device, format); - - let measure_brush = - glyph_brush::GlyphBrushBuilder::using_font(font).build(); - - Pipeline { - draw_brush: RefCell::new(draw_brush), - draw_font_map: RefCell::new(HashMap::new()), - measure_brush: RefCell::new(measure_brush), - } - } - - pub fn queue(&mut self, section: wgpu_glyph::Section<'_>) { - self.draw_brush.borrow_mut().queue(section); - } - - pub fn draw_queued( - &mut self, - device: &wgpu::Device, - staging_belt: &mut wgpu::util::StagingBelt, - encoder: &mut wgpu::CommandEncoder, - target: &wgpu::TextureView, - transformation: Transformation, - region: wgpu_glyph::Region, - ) { - self.draw_brush - .borrow_mut() - .draw_queued_with_transform_and_scissoring( - device, - staging_belt, - encoder, - target, - transformation.into(), - region, - ) - .expect("Draw text"); + Pipeline } pub fn measure( &self, - content: &str, - size: f32, - font: iced_native::Font, - bounds: iced_native::Size, + _content: &str, + _size: f32, + _font: iced_native::Font, + _bounds: iced_native::Size, ) -> (f32, f32) { - use wgpu_glyph::GlyphCruncher; - - let wgpu_glyph::FontId(font_id) = self.find_font(font); - - let section = wgpu_glyph::Section { - bounds: (bounds.width, bounds.height), - text: vec![wgpu_glyph::Text { - text: content, - scale: size.into(), - font_id: wgpu_glyph::FontId(font_id), - extra: wgpu_glyph::Extra::default(), - }], - ..Default::default() - }; - - if let Some(bounds) = - self.measure_brush.borrow_mut().glyph_bounds(section) - { - (bounds.width().ceil(), bounds.height().ceil()) - } else { - (0.0, 0.0) - } + (0.0, 0.0) } pub fn hit_test( &self, - content: &str, - size: f32, - font: iced_native::Font, - bounds: iced_native::Size, - point: iced_native::Point, - nearest_only: bool, + _content: &str, + _size: f32, + _font: iced_native::Font, + _bounds: iced_native::Size, + _point: iced_native::Point, + _nearest_only: bool, ) -> Option<Hit> { - use wgpu_glyph::GlyphCruncher; - - let wgpu_glyph::FontId(font_id) = self.find_font(font); - - let section = wgpu_glyph::Section { - bounds: (bounds.width, bounds.height), - text: vec![wgpu_glyph::Text { - text: content, - scale: size.into(), - font_id: wgpu_glyph::FontId(font_id), - extra: wgpu_glyph::Extra::default(), - }], - ..Default::default() - }; - - let mut mb = self.measure_brush.borrow_mut(); - - // The underlying type is FontArc, so clones are cheap. - use wgpu_glyph::ab_glyph::{Font, ScaleFont}; - let font = mb.fonts()[font_id].clone().into_scaled(size); - - // Implements an iterator over the glyph bounding boxes. - let bounds = mb.glyphs(section).map( - |wgpu_glyph::SectionGlyph { - byte_index, glyph, .. - }| { - ( - *byte_index, - iced_native::Rectangle::new( - iced_native::Point::new( - glyph.position.x - font.h_side_bearing(glyph.id), - glyph.position.y - font.ascent(), - ), - iced_native::Size::new( - font.h_advance(glyph.id), - font.ascent() - font.descent(), - ), - ), - ) - }, - ); - - // Implements computation of the character index based on the byte index - // within the input string. - let char_index = |byte_index| { - let mut b_count = 0; - for (i, utf8_len) in - content.chars().map(|c| c.len_utf8()).enumerate() - { - if byte_index < (b_count + utf8_len) { - return i; - } - b_count += utf8_len; - } - - byte_index - }; - - if !nearest_only { - for (idx, bounds) in bounds.clone() { - if bounds.contains(point) { - return Some(Hit::CharOffset(char_index(idx))); - } - } - } - - let nearest = bounds - .map(|(index, bounds)| (index, bounds.center())) - .min_by(|(_, center_a), (_, center_b)| { - center_a - .distance(point) - .partial_cmp(¢er_b.distance(point)) - .unwrap_or(std::cmp::Ordering::Greater) - }); - - nearest.map(|(idx, center)| { - Hit::NearestCharOffset(char_index(idx), point - center) - }) + None } - pub fn trim_measurement_cache(&mut self) { - // 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. - loop { - let action = self - .measure_brush - .borrow_mut() - .process_queued(|_, _| {}, |_| {}); - - match action { - Ok(_) => break, - Err(glyph_brush::BrushError::TextureTooSmall { suggested }) => { - let (width, height) = suggested; - - self.measure_brush - .borrow_mut() - .resize_texture(width, height); - } - } - } - } - - pub fn find_font(&self, font: iced_native::Font) -> wgpu_glyph::FontId { - match font { - iced_native::Font::Default => wgpu_glyph::FontId(0), - iced_native::Font::External { name, bytes } => { - if let Some(font_id) = self.draw_font_map.borrow().get(name) { - return *font_id; - } - - let font = ab_glyph::FontArc::try_from_slice(bytes) - .expect("Load font"); - - let _ = self.measure_brush.borrow_mut().add_font(font.clone()); - - let font_id = self.draw_brush.borrow_mut().add_font(font); - - let _ = self - .draw_font_map - .borrow_mut() - .insert(String::from(name), font_id); - - font_id - } - } - } + pub fn trim_measurement_cache(&mut self) {} } |