Make FontSystem global and simplify Paragraph API

This commit is contained in:
Héctor Ramón Jiménez 2023-09-11 02:47:24 +02:00
parent 9245423c5d
commit 346af3f8b0
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
15 changed files with 165 additions and 328 deletions

View file

@ -58,16 +58,6 @@ impl text::Renderer for Null {
fn load_font(&mut self, _font: Cow<'static, [u8]>) {} fn load_font(&mut self, _font: Cow<'static, [u8]>) {}
fn create_paragraph(&self, _text: Text<'_, Self::Font>) -> Self::Paragraph {
}
fn resize_paragraph(
&self,
_paragraph: &mut Self::Paragraph,
_new_bounds: Size,
) {
}
fn fill_paragraph( fn fill_paragraph(
&mut self, &mut self,
_paragraph: &Self::Paragraph, _paragraph: &Self::Paragraph,
@ -88,24 +78,12 @@ impl text::Renderer for Null {
impl text::Paragraph for () { impl text::Paragraph for () {
type Font = Font; type Font = Font;
fn content(&self) -> &str { fn with_text(_text: Text<'_, Self::Font>) -> Self {}
""
}
fn text_size(&self) -> Pixels { fn resize(&mut self, _new_bounds: Size) {}
Pixels(16.0)
}
fn font(&self) -> Self::Font { fn compare(&self, _text: Text<'_, Self::Font>) -> text::Difference {
Font::default() text::Difference::None
}
fn line_height(&self) -> text::LineHeight {
text::LineHeight::default()
}
fn shaping(&self) -> text::Shaping {
text::Shaping::default()
} }
fn horizontal_alignment(&self) -> alignment::Horizontal { fn horizontal_alignment(&self) -> alignment::Horizontal {
@ -120,10 +98,6 @@ impl text::Paragraph for () {
None None
} }
fn bounds(&self) -> Size {
Size::ZERO
}
fn min_bounds(&self) -> Size { fn min_bounds(&self) -> Size {
Size::ZERO Size::ZERO
} }

View file

@ -156,33 +156,6 @@ pub trait Renderer: crate::Renderer {
/// Loads a [`Self::Font`] from its bytes. /// Loads a [`Self::Font`] from its bytes.
fn load_font(&mut self, font: Cow<'static, [u8]>); fn load_font(&mut self, font: Cow<'static, [u8]>);
/// Creates a new [`Paragraph`] laid out with the given [`Text`].
fn create_paragraph(&self, text: Text<'_, Self::Font>) -> Self::Paragraph;
/// Lays out the given [`Paragraph`] with some new boundaries.
fn resize_paragraph(
&self,
paragraph: &mut Self::Paragraph,
new_bounds: Size,
);
/// Updates a [`Paragraph`] to match the given [`Text`], if needed.
fn update_paragraph(
&self,
paragraph: &mut Self::Paragraph,
text: Text<'_, Self::Font>,
) {
match compare(paragraph, text) {
Difference::None => {}
Difference::Bounds => {
self.resize_paragraph(paragraph, text.bounds);
}
Difference::Shape => {
*paragraph = self.create_paragraph(text);
}
}
}
/// Draws the given [`Paragraph`] at the given position and with the given /// Draws the given [`Paragraph`] at the given position and with the given
/// [`Color`]. /// [`Color`].
fn fill_paragraph( fn fill_paragraph(
@ -201,25 +174,21 @@ pub trait Renderer: crate::Renderer {
color: Color, color: Color,
); );
} }
/// A text paragraph. /// A text paragraph.
pub trait Paragraph: Default { pub trait Paragraph: Sized + Default {
/// The font of this [`Paragraph`]. /// The font of this [`Paragraph`].
type Font; type Font: Copy + PartialEq;
/// Returns the content of the [`Paragraph`]. /// Creates a new [`Paragraph`] laid out with the given [`Text`].
fn content(&self) -> &str; fn with_text(text: Text<'_, Self::Font>) -> Self;
/// Returns the text size of the [`Paragraph`]. /// Lays out the [`Paragraph`] with some new boundaries.
fn text_size(&self) -> Pixels; fn resize(&mut self, new_bounds: Size);
/// Returns the [`LineHeight`] of the [`Paragraph`]. /// Compares the [`Paragraph`] with some desired [`Text`] and returns the
fn line_height(&self) -> LineHeight; /// [`Difference`].
fn compare(&self, text: Text<'_, Self::Font>) -> Difference;
/// Returns the [`Self::Font`] of the [`Paragraph`].
fn font(&self) -> Self::Font;
/// Returns the [`Shaping`] strategy of the [`Paragraph`].
fn shaping(&self) -> Shaping;
/// Returns the horizontal alignment of the [`Paragraph`]. /// Returns the horizontal alignment of the [`Paragraph`].
fn horizontal_alignment(&self) -> alignment::Horizontal; fn horizontal_alignment(&self) -> alignment::Horizontal;
@ -227,9 +196,6 @@ pub trait Paragraph: Default {
/// Returns the vertical alignment of the [`Paragraph`]. /// Returns the vertical alignment of the [`Paragraph`].
fn vertical_alignment(&self) -> alignment::Vertical; fn vertical_alignment(&self) -> alignment::Vertical;
/// Returns the boundaries of the [`Paragraph`].
fn bounds(&self) -> Size;
/// Returns the minimum boundaries that can fit the contents of the /// Returns the minimum boundaries that can fit the contents of the
/// [`Paragraph`]. /// [`Paragraph`].
fn min_bounds(&self) -> Size; fn min_bounds(&self) -> Size;
@ -241,6 +207,19 @@ pub trait Paragraph: Default {
/// Returns the distance to the given grapheme index in the [`Paragraph`]. /// Returns the distance to the given grapheme index in the [`Paragraph`].
fn grapheme_position(&self, line: usize, index: usize) -> Option<Point>; fn grapheme_position(&self, line: usize, index: usize) -> Option<Point>;
/// Updates the [`Paragraph`] to match the given [`Text`], if needed.
fn update(&mut self, text: Text<'_, Self::Font>) {
match self.compare(text) {
Difference::None => {}
Difference::Bounds => {
self.resize(text.bounds);
}
Difference::Shape => {
*self = Self::with_text(text);
}
}
}
/// Returns the minimum width that can fit the contents of the [`Paragraph`]. /// Returns the minimum width that can fit the contents of the [`Paragraph`].
fn min_width(&self) -> f32 { fn min_width(&self) -> f32 {
self.min_bounds().width self.min_bounds().width
@ -276,26 +255,3 @@ pub enum Difference {
/// the text is necessary. /// the text is necessary.
Shape, Shape,
} }
/// Compares a [`Paragraph`] with some desired [`Text`] and returns the
/// [`Difference`].
pub fn compare<Font: PartialEq>(
paragraph: &impl Paragraph<Font = Font>,
text: Text<'_, Font>,
) -> Difference {
if paragraph.content() != text.content
|| paragraph.text_size() != text.size
|| paragraph.line_height().to_absolute(text.size)
!= text.line_height.to_absolute(text.size)
|| paragraph.font() != text.font
|| paragraph.shaping() != text.shaping
|| paragraph.horizontal_alignment() != text.horizontal_alignment
|| paragraph.vertical_alignment() != text.vertical_alignment
{
Difference::Shape
} else if paragraph.bounds() != text.bounds {
Difference::Bounds
} else {
Difference::None
}
}

View file

@ -212,19 +212,16 @@ where
let State(ref mut paragraph) = state; let State(ref mut paragraph) = state;
renderer.update_paragraph( paragraph.update(text::Text {
paragraph, content,
text::Text { bounds,
content, size,
bounds, line_height,
size, font,
line_height, shaping,
font, horizontal_alignment,
shaping, vertical_alignment,
horizontal_alignment, });
vertical_alignment,
},
);
let size = limits.resolve(paragraph.min_bounds()); let size = limits.resolve(paragraph.min_bounds());

View file

@ -25,16 +25,15 @@ iced_core.workspace = true
bitflags.workspace = true bitflags.workspace = true
bytemuck.workspace = true bytemuck.workspace = true
cosmic-text.workspace = true
glam.workspace = true glam.workspace = true
half.workspace = true half.workspace = true
log.workspace = true log.workspace = true
once_cell.workspace = true
raw-window-handle.workspace = true raw-window-handle.workspace = true
thiserror.workspace = true
cosmic-text.workspace = true
rustc-hash.workspace = true rustc-hash.workspace = true
thiserror.workspace = true
lyon_path.workspace = true twox-hash.workspace = true
lyon_path.optional = true
image.workspace = true image.workspace = true
image.optional = true image.optional = true
@ -42,7 +41,8 @@ image.optional = true
kamadak-exif.workspace = true kamadak-exif.workspace = true
kamadak-exif.optional = true kamadak-exif.optional = true
twox-hash.workspace = true lyon_path.workspace = true
lyon_path.optional = true
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
twox-hash.workspace = true twox-hash.workspace = true

View file

@ -2,7 +2,6 @@
use crate::core::image; use crate::core::image;
use crate::core::svg; use crate::core::svg;
use crate::core::Size; use crate::core::Size;
use crate::text;
use std::borrow::Cow; use std::borrow::Cow;
@ -18,9 +17,6 @@ pub trait Backend {
pub trait Text { pub trait Text {
/// Loads a font from its bytes. /// Loads a font from its bytes.
fn load_font(&mut self, font: Cow<'static, [u8]>); fn load_font(&mut self, font: Cow<'static, [u8]>);
/// Returns the [`cosmic_text::FontSystem`] of the [`Backend`].
fn font_system(&self) -> &text::FontSystem;
} }
/// A graphics backend that supports image rendering. /// A graphics backend that supports image rendering.

View file

@ -158,41 +158,6 @@ where
self.backend.load_font(bytes); self.backend.load_font(bytes);
} }
fn create_paragraph(&self, text: Text<'_, Self::Font>) -> text::Paragraph {
text::Paragraph::with_text(text, self.backend.font_system())
}
fn update_paragraph(
&self,
paragraph: &mut Self::Paragraph,
text: Text<'_, Self::Font>,
) {
let font_system = self.backend.font_system();
if paragraph.version() != font_system.version() {
// The font system has changed, paragraph fonts may be outdated
*paragraph = self.create_paragraph(text);
} else {
match core::text::compare(paragraph, text) {
core::text::Difference::None => {}
core::text::Difference::Bounds => {
self.resize_paragraph(paragraph, text.bounds);
}
core::text::Difference::Shape => {
*paragraph = self.create_paragraph(text);
}
}
}
}
fn resize_paragraph(
&self,
paragraph: &mut Self::Paragraph,
new_bounds: Size,
) {
paragraph.resize(new_bounds, self.backend.font_system());
}
fn fill_paragraph( fn fill_paragraph(
&mut self, &mut self,
paragraph: &Self::Paragraph, paragraph: &Self::Paragraph,

View file

@ -10,40 +10,39 @@ use crate::core::font::{self, Font};
use crate::core::text::Shaping; use crate::core::text::Shaping;
use crate::core::Size; use crate::core::Size;
use once_cell::sync::OnceCell;
use std::borrow::Cow; use std::borrow::Cow;
use std::sync::{self, Arc, RwLock}; use std::sync::{Arc, RwLock};
#[allow(missing_debug_implementations)] pub fn font_system() -> &'static RwLock<FontSystem> {
pub struct FontSystem { static FONT_SYSTEM: OnceCell<RwLock<FontSystem>> = OnceCell::new();
raw: RwLock<cosmic_text::FontSystem>,
version: Version,
}
impl FontSystem { FONT_SYSTEM.get_or_init(|| {
pub fn new() -> Self { RwLock::new(FontSystem {
FontSystem { raw: cosmic_text::FontSystem::new_with_fonts(
raw: RwLock::new(cosmic_text::FontSystem::new_with_fonts(
[cosmic_text::fontdb::Source::Binary(Arc::new( [cosmic_text::fontdb::Source::Binary(Arc::new(
include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), include_bytes!("../fonts/Iced-Icons.ttf").as_slice(),
))] ))]
.into_iter(), .into_iter(),
)), ),
version: Version::default(), version: Version::default(),
} })
} })
}
pub fn get_mut(&mut self) -> &mut cosmic_text::FontSystem { #[allow(missing_debug_implementations)]
self.raw.get_mut().expect("Lock font system") pub struct FontSystem {
} raw: cosmic_text::FontSystem,
version: Version,
}
pub fn write( impl FontSystem {
&self, pub fn raw(&mut self) -> &mut cosmic_text::FontSystem {
) -> (sync::RwLockWriteGuard<'_, cosmic_text::FontSystem>, Version) { &mut self.raw
(self.raw.write().expect("Write font system"), self.version)
} }
pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) {
let _ = self.get_mut().db_mut().load_font_source( let _ = self.raw.db_mut().load_font_source(
cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())),
); );
@ -58,12 +57,6 @@ impl FontSystem {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct Version(u32); pub struct Version(u32);
impl Default for FontSystem {
fn default() -> Self {
Self::new()
}
}
pub fn measure(buffer: &cosmic_text::Buffer) -> Size { pub fn measure(buffer: &cosmic_text::Buffer) -> Size {
let (width, total_lines) = buffer let (width, total_lines) = buffer
.layout_runs() .layout_runs()

View file

@ -2,7 +2,7 @@ use crate::core;
use crate::core::alignment; use crate::core::alignment;
use crate::core::text::{Hit, LineHeight, Shaping, Text}; use crate::core::text::{Hit, LineHeight, Shaping, Text};
use crate::core::{Font, Pixels, Point, Size}; use crate::core::{Font, Pixels, Point, Size};
use crate::text::{self, FontSystem}; use crate::text;
use std::fmt; use std::fmt;
use std::sync::{self, Arc}; use std::sync::{self, Arc};
@ -27,13 +27,39 @@ impl Paragraph {
Self::default() Self::default()
} }
pub fn with_text(text: Text<'_, Font>, font_system: &FontSystem) -> Self { pub fn buffer(&self) -> &cosmic_text::Buffer {
&self.internal().buffer
}
pub fn downgrade(&self) -> Weak {
let paragraph = self.internal();
Weak {
raw: Arc::downgrade(paragraph),
min_bounds: paragraph.min_bounds,
horizontal_alignment: paragraph.horizontal_alignment,
vertical_alignment: paragraph.vertical_alignment,
}
}
fn internal(&self) -> &Arc<Internal> {
self.0
.as_ref()
.expect("paragraph should always be initialized")
}
}
impl core::text::Paragraph for Paragraph {
type Font = Font;
fn with_text(text: Text<'_, Font>) -> Self {
log::trace!("Allocating paragraph: {}", text.content); log::trace!("Allocating paragraph: {}", text.content);
let (mut font_system, version) = font_system.write(); let mut font_system =
text::font_system().write().expect("Write font system");
let mut buffer = cosmic_text::Buffer::new( let mut buffer = cosmic_text::Buffer::new(
&mut font_system, font_system.raw(),
cosmic_text::Metrics::new( cosmic_text::Metrics::new(
text.size.into(), text.size.into(),
text.line_height.to_absolute(text.size).into(), text.line_height.to_absolute(text.size).into(),
@ -41,13 +67,13 @@ impl Paragraph {
); );
buffer.set_size( buffer.set_size(
&mut font_system, font_system.raw(),
text.bounds.width, text.bounds.width,
text.bounds.height, text.bounds.height,
); );
buffer.set_text( buffer.set_text(
&mut font_system, font_system.raw(),
text.content, text.content,
text::to_attributes(text.font), text::to_attributes(text.font),
text::to_shaping(text.shaping), text::to_shaping(text.shaping),
@ -64,30 +90,11 @@ impl Paragraph {
shaping: text.shaping, shaping: text.shaping,
bounds: text.bounds, bounds: text.bounds,
min_bounds, min_bounds,
version, version: font_system.version(),
}))) })))
} }
pub fn buffer(&self) -> &cosmic_text::Buffer { fn resize(&mut self, new_bounds: Size) {
&self.internal().buffer
}
pub fn version(&self) -> text::Version {
self.internal().version
}
pub fn downgrade(&self) -> Weak {
let paragraph = self.internal();
Weak {
raw: Arc::downgrade(paragraph),
min_bounds: paragraph.min_bounds,
horizontal_alignment: paragraph.horizontal_alignment,
vertical_alignment: paragraph.vertical_alignment,
}
}
pub fn resize(&mut self, new_bounds: Size, font_system: &FontSystem) {
let paragraph = self let paragraph = self
.0 .0
.take() .take()
@ -95,10 +102,11 @@ impl Paragraph {
match Arc::try_unwrap(paragraph) { match Arc::try_unwrap(paragraph) {
Ok(mut internal) => { Ok(mut internal) => {
let (mut font_system, _) = font_system.write(); let mut font_system =
text::font_system().write().expect("Write font system");
internal.buffer.set_size( internal.buffer.set_size(
&mut font_system, font_system.raw(),
new_bounds.width, new_bounds.width,
new_bounds.height, new_bounds.height,
); );
@ -113,55 +121,42 @@ impl Paragraph {
// If there is a strong reference somewhere, we recompute the // If there is a strong reference somewhere, we recompute the
// buffer from scratch // buffer from scratch
*self = Self::with_text( *self = Self::with_text(Text {
Text { content: &internal.content,
content: &internal.content, bounds: internal.bounds,
bounds: internal.bounds, size: Pixels(metrics.font_size),
size: Pixels(metrics.font_size), line_height: LineHeight::Absolute(Pixels(
line_height: LineHeight::Absolute(Pixels( metrics.line_height,
metrics.line_height, )),
)), font: internal.font,
font: internal.font, horizontal_alignment: internal.horizontal_alignment,
horizontal_alignment: internal.horizontal_alignment, vertical_alignment: internal.vertical_alignment,
vertical_alignment: internal.vertical_alignment, shaping: internal.shaping,
shaping: internal.shaping, });
},
font_system,
);
} }
} }
} }
fn internal(&self) -> &Arc<Internal> { fn compare(&self, text: Text<'_, Font>) -> core::text::Difference {
self.0 let font_system = text::font_system().read().expect("Read font system");
.as_ref() let paragraph = self.internal();
.expect("paragraph should always be initialized") let metrics = paragraph.buffer.metrics();
}
}
impl core::text::Paragraph for Paragraph { if paragraph.version != font_system.version
type Font = Font; || paragraph.content != text.content
|| metrics.font_size != text.size.0
fn content(&self) -> &str { || metrics.line_height != text.line_height.to_absolute(text.size).0
&self.internal().content || paragraph.font != text.font
} || paragraph.shaping != text.shaping
|| paragraph.horizontal_alignment != text.horizontal_alignment
fn text_size(&self) -> Pixels { || paragraph.vertical_alignment != text.vertical_alignment
Pixels(self.internal().buffer.metrics().font_size) {
} core::text::Difference::Shape
} else if paragraph.bounds != text.bounds {
fn line_height(&self) -> LineHeight { core::text::Difference::Bounds
LineHeight::Absolute(Pixels( } else {
self.internal().buffer.metrics().line_height, core::text::Difference::None
)) }
}
fn font(&self) -> Font {
self.internal().font
}
fn shaping(&self) -> Shaping {
self.internal().shaping
} }
fn horizontal_alignment(&self) -> alignment::Horizontal { fn horizontal_alignment(&self) -> alignment::Horizontal {
@ -172,10 +167,6 @@ impl core::text::Paragraph for Paragraph {
self.internal().vertical_alignment self.internal().vertical_alignment
} }
fn bounds(&self) -> Size {
self.internal().bounds
}
fn min_bounds(&self) -> Size { fn min_bounds(&self) -> Size {
self.internal().min_bounds self.internal().min_bounds
} }

View file

@ -173,22 +173,6 @@ impl<T> text::Renderer for Renderer<T> {
delegate!(self, renderer, renderer.default_size()) delegate!(self, renderer, renderer.default_size())
} }
fn create_paragraph(&self, text: Text<'_, Self::Font>) -> Self::Paragraph {
delegate!(self, renderer, renderer.create_paragraph(text))
}
fn resize_paragraph(
&self,
paragraph: &mut Self::Paragraph,
new_bounds: Size,
) {
delegate!(
self,
renderer,
renderer.resize_paragraph(paragraph, new_bounds)
);
}
fn load_font(&mut self, bytes: Cow<'static, [u8]>) { fn load_font(&mut self, bytes: Cow<'static, [u8]>) {
delegate!(self, renderer, renderer.load_font(bytes)); delegate!(self, renderer, renderer.load_font(bytes));
} }

View file

@ -1,6 +1,5 @@
use crate::core::{Background, Color, Gradient, Rectangle, Vector}; use crate::core::{Background, Color, Gradient, Rectangle, Vector};
use crate::graphics::backend; use crate::graphics::backend;
use crate::graphics::text;
use crate::graphics::{Damage, Viewport}; use crate::graphics::{Damage, Viewport};
use crate::primitive::{self, Primitive}; use crate::primitive::{self, Primitive};
@ -805,10 +804,6 @@ impl iced_graphics::Backend for Backend {
} }
impl backend::Text for Backend { impl backend::Text for Backend {
fn font_system(&self) -> &text::FontSystem {
self.text_pipeline.font_system()
}
fn load_font(&mut self, font: Cow<'static, [u8]>) { fn load_font(&mut self, font: Cow<'static, [u8]>) {
self.text_pipeline.load_font(font); self.text_pipeline.load_font(font);
} }

View file

@ -2,8 +2,8 @@ use crate::core::alignment;
use crate::core::text::{LineHeight, Shaping}; use crate::core::text::{LineHeight, Shaping};
use crate::core::{Color, Font, Pixels, Point, Rectangle}; use crate::core::{Color, Font, Pixels, Point, Rectangle};
use crate::graphics::text::cache::{self, Cache}; use crate::graphics::text::cache::{self, Cache};
use crate::graphics::text::font_system;
use crate::graphics::text::paragraph; use crate::graphics::text::paragraph;
use crate::graphics::text::FontSystem;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use std::borrow::Cow; use std::borrow::Cow;
@ -12,7 +12,6 @@ use std::collections::hash_map;
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct Pipeline { pub struct Pipeline {
font_system: FontSystem,
glyph_cache: GlyphCache, glyph_cache: GlyphCache,
cache: RefCell<Cache>, cache: RefCell<Cache>,
} }
@ -20,18 +19,16 @@ pub struct Pipeline {
impl Pipeline { impl Pipeline {
pub fn new() -> Self { pub fn new() -> Self {
Pipeline { Pipeline {
font_system: FontSystem::new(),
glyph_cache: GlyphCache::new(), glyph_cache: GlyphCache::new(),
cache: RefCell::new(Cache::new()), cache: RefCell::new(Cache::new()),
} }
} }
pub fn font_system(&self) -> &FontSystem {
&self.font_system
}
pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) {
self.font_system.load_font(bytes); font_system()
.write()
.expect("Write font system")
.load_font(bytes);
self.cache = RefCell::new(Cache::new()); self.cache = RefCell::new(Cache::new());
} }
@ -51,8 +48,10 @@ impl Pipeline {
return; return;
}; };
let mut font_system = font_system().write().expect("Write font system");
draw( draw(
self.font_system.get_mut(), font_system.raw(),
&mut self.glyph_cache, &mut self.glyph_cache,
paragraph.buffer(), paragraph.buffer(),
Rectangle::new(position, paragraph.min_bounds()), Rectangle::new(position, paragraph.min_bounds()),
@ -82,7 +81,9 @@ impl Pipeline {
) { ) {
let line_height = f32::from(line_height.to_absolute(size)); let line_height = f32::from(line_height.to_absolute(size));
let font_system = self.font_system.get_mut(); let mut font_system = font_system().write().expect("Write font system");
let font_system = font_system.raw();
let key = cache::Key { let key = cache::Key {
bounds: bounds.size(), bounds: bounds.size(),
content, content,

View file

@ -1,5 +1,4 @@
use crate::core::{Color, Size}; use crate::core::{Color, Size};
use crate::graphics;
use crate::graphics::backend; use crate::graphics::backend;
use crate::graphics::color; use crate::graphics::color;
use crate::graphics::{Transformation, Viewport}; use crate::graphics::{Transformation, Viewport};
@ -310,10 +309,6 @@ impl crate::graphics::Backend for Backend {
} }
impl backend::Text for Backend { impl backend::Text for Backend {
fn font_system(&self) -> &graphics::text::FontSystem {
self.text_pipeline.font_system()
}
fn load_font(&mut self, font: Cow<'static, [u8]>) { fn load_font(&mut self, font: Cow<'static, [u8]>) {
self.text_pipeline.load_font(font); self.text_pipeline.load_font(font);
} }

View file

@ -2,7 +2,7 @@ use crate::core::alignment;
use crate::core::{Rectangle, Size}; use crate::core::{Rectangle, Size};
use crate::graphics::color; use crate::graphics::color;
use crate::graphics::text::cache::{self, Cache}; use crate::graphics::text::cache::{self, Cache};
use crate::graphics::text::{FontSystem, Paragraph}; use crate::graphics::text::{font_system, Paragraph};
use crate::layer::Text; use crate::layer::Text;
use std::borrow::Cow; use std::borrow::Cow;
@ -10,7 +10,6 @@ use std::cell::RefCell;
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
pub struct Pipeline { pub struct Pipeline {
font_system: FontSystem,
renderers: Vec<glyphon::TextRenderer>, renderers: Vec<glyphon::TextRenderer>,
atlas: glyphon::TextAtlas, atlas: glyphon::TextAtlas,
prepare_layer: usize, prepare_layer: usize,
@ -24,7 +23,6 @@ impl Pipeline {
format: wgpu::TextureFormat, format: wgpu::TextureFormat,
) -> Self { ) -> Self {
Pipeline { Pipeline {
font_system: FontSystem::new(),
renderers: Vec::new(), renderers: Vec::new(),
atlas: glyphon::TextAtlas::with_color_mode( atlas: glyphon::TextAtlas::with_color_mode(
device, device,
@ -41,12 +39,11 @@ impl Pipeline {
} }
} }
pub fn font_system(&self) -> &FontSystem {
&self.font_system
}
pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) {
self.font_system.load_font(bytes); font_system()
.write()
.expect("Write font system")
.load_font(bytes);
self.cache = RefCell::new(Cache::new()); self.cache = RefCell::new(Cache::new());
} }
@ -69,7 +66,9 @@ impl Pipeline {
)); ));
} }
let font_system = self.font_system.get_mut(); let mut font_system = font_system().write().expect("Write font system");
let font_system = font_system.raw();
let renderer = &mut self.renderers[self.prepare_layer]; let renderer = &mut self.renderers[self.prepare_layer];
let cache = self.cache.get_mut(); let cache = self.cache.get_mut();

View file

@ -415,23 +415,17 @@ where
for (option, paragraph) in options.iter().zip(state.options.iter_mut()) { for (option, paragraph) in options.iter().zip(state.options.iter_mut()) {
let label = option.to_string(); let label = option.to_string();
renderer.update_paragraph( paragraph.update(Text {
paragraph, content: &label,
Text { ..option_text
content: &label, });
..option_text
},
);
} }
if let Some(placeholder) = placeholder { if let Some(placeholder) = placeholder {
renderer.update_paragraph( state.placeholder.update(Text {
&mut state.placeholder, content: placeholder,
Text { ..option_text
content: placeholder, });
..option_text
},
);
} }
let max_width = match width { let max_width = match width {

View file

@ -523,18 +523,15 @@ where
shaping: text::Shaping::Advanced, shaping: text::Shaping::Advanced,
}; };
renderer.update_paragraph(&mut state.placeholder, placeholder_text); state.placeholder.update(placeholder_text);
let secure_value = is_secure.then(|| value.secure()); let secure_value = is_secure.then(|| value.secure());
let value = secure_value.as_ref().unwrap_or(value); let value = secure_value.as_ref().unwrap_or(value);
renderer.update_paragraph( state.value.update(Text {
&mut state.value, content: &value.to_string(),
Text { ..placeholder_text
content: &value.to_string(), });
..placeholder_text
},
);
if let Some(icon) = icon { if let Some(icon) = icon {
let icon_text = Text { let icon_text = Text {
@ -548,7 +545,7 @@ where
shaping: text::Shaping::Advanced, shaping: text::Shaping::Advanced,
}; };
renderer.update_paragraph(&mut state.icon, icon_text); state.icon.update(icon_text);
let icon_width = state.icon.min_width(); let icon_width = state.icon.min_width();
@ -1461,7 +1458,7 @@ fn replace_paragraph<Renderer>(
let mut children_layout = layout.children(); let mut children_layout = layout.children();
let text_bounds = children_layout.next().unwrap().bounds(); let text_bounds = children_layout.next().unwrap().bounds();
state.value = renderer.create_paragraph(Text { state.value = Renderer::Paragraph::with_text(Text {
font, font,
line_height, line_height,
content: &value.to_string(), content: &value.to_string(),