diff options
Diffstat (limited to 'wgpu/src/text.rs')
| -rw-r--r-- | wgpu/src/text.rs | 87 | 
1 files changed, 44 insertions, 43 deletions
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 714e0400..c9188bd1 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -2,6 +2,7 @@ use crate::core::alignment;  use crate::core::font::{self, Font};  use crate::core::text::{Hit, LineHeight, Shaping};  use crate::core::{Pixels, Point, Rectangle, Size}; +use crate::graphics::color;  use crate::layer::Text;  use rustc_hash::{FxHashMap, FxHashSet}; @@ -17,8 +18,7 @@ pub struct Pipeline {      renderers: Vec<glyphon::TextRenderer>,      atlas: glyphon::TextAtlas,      prepare_layer: usize, -    measurement_cache: RefCell<Cache>, -    render_cache: Cache, +    cache: RefCell<Cache>,  }  impl Pipeline { @@ -35,17 +35,27 @@ impl Pipeline {                  .into_iter(),              )),              renderers: Vec::new(), -            atlas: glyphon::TextAtlas::new(device, queue, format), +            atlas: glyphon::TextAtlas::new( +                device, +                queue, +                format, +                if color::GAMMA_CORRECTION { +                    glyphon::ColorMode::Accurate +                } else { +                    glyphon::ColorMode::Web +                }, +            ),              prepare_layer: 0, -            measurement_cache: RefCell::new(Cache::new()), -            render_cache: Cache::new(), +            cache: RefCell::new(Cache::new()),          }      }      pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { -        self.font_system.get_mut().db_mut().load_font_source( +        let _ = self.font_system.get_mut().db_mut().load_font_source(              glyphon::fontdb::Source::Binary(Arc::new(bytes.into_owned())),          ); + +        self.cache = RefCell::new(Cache::new());      }      pub fn prepare( @@ -68,25 +78,25 @@ impl Pipeline {          let font_system = self.font_system.get_mut();          let renderer = &mut self.renderers[self.prepare_layer]; +        let cache = self.cache.get_mut();          let keys: Vec<_> = sections              .iter()              .map(|section| { -                let (key, _) = self.render_cache.allocate( +                let (key, _) = cache.allocate(                      font_system,                      Key {                          content: section.content, -                        size: section.size * scale_factor, +                        size: section.size,                          line_height: f32::from(                              section                                  .line_height                                  .to_absolute(Pixels(section.size)), -                        ) * scale_factor, +                        ),                          font: section.font,                          bounds: Size { -                            width: (section.bounds.width * scale_factor).ceil(), -                            height: (section.bounds.height * scale_factor) -                                .ceil(), +                            width: section.bounds.width, +                            height: section.bounds.height,                          },                          shaping: section.shaping,                      }, @@ -103,22 +113,16 @@ impl Pipeline {                  .iter()                  .zip(keys.iter())                  .filter_map(|(section, key)| { -                    let buffer = -                        self.render_cache.get(key).expect("Get cached buffer"); - -                    let (total_lines, max_width) = buffer -                        .layout_runs() -                        .enumerate() -                        .fold((0, 0.0), |(_, max), (i, buffer)| { -                            (i + 1, buffer.line_w.max(max)) -                        }); - -                    let total_height = -                        total_lines as f32 * buffer.metrics().line_height; +                    let buffer = cache.get(key).expect("Get cached buffer");                      let x = section.bounds.x * scale_factor;                      let y = section.bounds.y * scale_factor; +                    let (max_width, total_height) = measure(buffer); + +                    let max_width = max_width * scale_factor; +                    let total_height = total_height * scale_factor; +                      let left = match section.horizontal_alignment {                          alignment::Horizontal::Left => x,                          alignment::Horizontal::Center => x - max_width / 2.0, @@ -140,14 +144,11 @@ impl Pipeline {                      let clip_bounds = bounds.intersection(§ion_bounds)?; -                    // TODO: Subpixel glyph positioning -                    let left = left.round() as i32; -                    let top = top.round() as i32; -                      Some(glyphon::TextArea {                          buffer,                          left,                          top, +                        scale: scale_factor,                          bounds: glyphon::TextBounds {                              left: clip_bounds.x as i32,                              top: clip_bounds.y as i32, @@ -155,7 +156,8 @@ impl Pipeline {                              bottom: (clip_bounds.y + clip_bounds.height) as i32,                          },                          default_color: { -                            let [r, g, b, a] = section.color.into_linear(); +                            let [r, g, b, a] = +                                color::pack(section.color).components();                              glyphon::Color::rgba(                                  (r * 255.0) as u8, @@ -224,7 +226,7 @@ impl Pipeline {      pub fn end_frame(&mut self) {          self.atlas.trim(); -        self.render_cache.trim(); +        self.cache.get_mut().trim();          self.prepare_layer = 0;      } @@ -238,7 +240,7 @@ impl Pipeline {          bounds: Size,          shaping: Shaping,      ) -> (f32, f32) { -        let mut measurement_cache = self.measurement_cache.borrow_mut(); +        let mut measurement_cache = self.cache.borrow_mut();          let line_height = f32::from(line_height.to_absolute(Pixels(size))); @@ -254,14 +256,7 @@ impl Pipeline {              },          ); -        let (total_lines, max_width) = paragraph -            .layout_runs() -            .enumerate() -            .fold((0, 0.0), |(_, max), (i, buffer)| { -                (i + 1, buffer.line_w.max(max)) -            }); - -        (max_width, line_height * total_lines as f32) +        measure(paragraph)      }      pub fn hit_test( @@ -275,7 +270,7 @@ impl Pipeline {          point: Point,          _nearest_only: bool,      ) -> Option<Hit> { -        let mut measurement_cache = self.measurement_cache.borrow_mut(); +        let mut measurement_cache = self.cache.borrow_mut();          let line_height = f32::from(line_height.to_absolute(Pixels(size))); @@ -295,10 +290,16 @@ impl Pipeline {          Some(Hit::CharOffset(cursor.index))      } +} -    pub fn trim_measurement_cache(&mut self) { -        self.measurement_cache.borrow_mut().trim(); -    } +fn measure(buffer: &glyphon::Buffer) -> (f32, f32) { +    let (width, total_lines) = buffer +        .layout_runs() +        .fold((0.0, 0usize), |(width, total_lines), run| { +            (run.line_w.max(width), total_lines + 1) +        }); + +    (width, total_lines as f32 * buffer.metrics().line_height)  }  fn to_family(family: font::Family) -> glyphon::Family<'static> {  | 
