diff --git a/wgui/src/widget/label.rs b/wgui/src/widget/label.rs index b9821785..9b0d68b9 100644 --- a/wgui/src/widget/label.rs +++ b/wgui/src/widget/label.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, rc::Rc}; -use cosmic_text::{Attrs, AttrsList, Buffer, Metrics, Shaping, Wrap}; +use cosmic_text::{Attrs, AttrsList, BorrowedWithFontSystem, Buffer, Metrics, Shaping, Wrap}; use slotmap::Key; use taffy::AvailableSpace; @@ -68,6 +68,16 @@ impl WidgetLabel { ) } + fn with_buffer(buffer: &Rc>, globals: &Globals, func: F) -> R + where + F: FnOnce(BorrowedWithFontSystem<'_, Buffer>) -> R, + { + let mut font_system = globals.font_system.system.lock(); + let mut buffer = buffer.borrow_mut(); + let buffer = buffer.borrow_with(&mut font_system); + func(buffer) + } + // set text without layout/re-render update. // Not recommended unless the widget wasn't rendered yet (first init). pub fn set_text_simple(&mut self, globals: &mut Globals, translation: Translation) -> bool { @@ -78,14 +88,16 @@ impl WidgetLabel { self.params.content = translation; let attrs = Attrs::from(&self.params.style); - let mut buffer = self.buffer.borrow_mut(); - buffer.set_rich_text( - [(self.params.content.generate(&mut globals.i18n_builtin).as_ref(), attrs)], - &Attrs::new(), - Shaping::Advanced, - self.params.style.align.map(Into::into), - ); + let text = self.params.content.generate(&mut globals.i18n_builtin); + WidgetLabel::with_buffer(&self.buffer, globals, |mut buffer| { + buffer.set_rich_text( + [(text.as_ref(), attrs)], + &Attrs::new(), + Shaping::Advanced, + self.params.style.align.map(Into::into), + ); + }); true } @@ -118,8 +130,9 @@ impl WidgetObj for WidgetLabel { fn draw(&mut self, state: &mut super::DrawState, _params: &super::DrawParams) { let boundary = drawing::Boundary::construct_relative(state.transform_stack); - let mut buffer = self.buffer.borrow_mut(); - buffer.set_size(Some(boundary.size.x), Some(boundary.size.y)); + WidgetLabel::with_buffer(&self.buffer, state.globals, |mut buffer| { + buffer.set_size(Some(boundary.size.x), Some(boundary.size.y)); + }); state.primitives.push(drawing::RenderPrimitive::Text( PrimitiveExtent { @@ -133,7 +146,7 @@ impl WidgetObj for WidgetLabel { fn measure( &mut self, - _globals: &Globals, + globals: &Globals, known_dimensions: taffy::Size>, available_space: taffy::Size, ) -> taffy::Size { @@ -144,19 +157,18 @@ impl WidgetObj for WidgetLabel { AvailableSpace::Definite(width) => Some(width), }); - let mut buffer = self.buffer.borrow_mut(); - buffer.set_size(width_constraint, None); - - // Determine measured size of text - let (width, total_lines) = buffer.layout_runs().fold((0.0, 0usize), |(width, total_lines), run| { - (run.line_w.max(width), total_lines + 1) - }); - let height = total_lines as f32 * buffer.metrics().line_height; - - taffy::Size { - width: width + 1.0, /* f32 aliasing fix */ - height, - } + WidgetLabel::with_buffer(&self.buffer, globals, |mut buffer| { + buffer.set_size(width_constraint, None); + // Determine measured size of text + let (width, total_lines) = buffer.layout_runs().fold((0.0, 0usize), |(width, total_lines), run| { + (run.line_w.max(width), total_lines + 1) + }); + let height = total_lines as f32 * buffer.metrics().line_height; + taffy::Size { + width: width + 1.0, /* f32 aliasing fix */ + height, + } + }) } fn get_id(&self) -> WidgetID {