Trim text measurements only before layout
This commit is contained in:
parent
cdce03cf7f
commit
d666e739cd
4 changed files with 30 additions and 28 deletions
|
|
@ -12,6 +12,13 @@ use std::borrow::Cow;
|
||||||
pub trait Backend {
|
pub trait Backend {
|
||||||
/// The custom kind of primitives this [`Backend`] supports.
|
/// The custom kind of primitives this [`Backend`] supports.
|
||||||
type Primitive;
|
type Primitive;
|
||||||
|
|
||||||
|
/// Trims the measurements cache.
|
||||||
|
///
|
||||||
|
/// This method is currently necessary to properly trim the text cache in
|
||||||
|
/// `iced_wgpu` and `iced_glow` because of limitations in the text rendering
|
||||||
|
/// pipeline. It will be removed in the future.
|
||||||
|
fn trim_measurements(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A graphics backend that supports text rendering.
|
/// A graphics backend that supports text rendering.
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,8 @@ impl<B: Backend, T> iced_core::Renderer for Renderer<B, T> {
|
||||||
element: &Element<'_, Message, Self>,
|
element: &Element<'_, Message, Self>,
|
||||||
limits: &layout::Limits,
|
limits: &layout::Limits,
|
||||||
) -> layout::Node {
|
) -> layout::Node {
|
||||||
|
self.backend.trim_measurements();
|
||||||
|
|
||||||
element.as_widget().layout(self, limits)
|
element.as_widget().layout(self, limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -337,6 +337,10 @@ impl Backend {
|
||||||
|
|
||||||
impl crate::graphics::Backend for Backend {
|
impl crate::graphics::Backend for Backend {
|
||||||
type Primitive = primitive::Custom;
|
type Primitive = primitive::Custom;
|
||||||
|
|
||||||
|
fn trim_measurements(&mut self) {
|
||||||
|
self.text_pipeline.trim_measurements();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl backend::Text for Backend {
|
impl backend::Text for Backend {
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,7 @@ impl Pipeline {
|
||||||
let cache = self.cache.get_mut();
|
let cache = self.cache.get_mut();
|
||||||
|
|
||||||
if self.prepare_layer == 0 {
|
if self.prepare_layer == 0 {
|
||||||
let _ = cache.switch(Mode::Drawing);
|
cache.trim(Purpose::Drawing);
|
||||||
cache.trim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let keys: Vec<_> = sections
|
let keys: Vec<_> = sections
|
||||||
|
|
@ -105,6 +104,7 @@ impl Pipeline {
|
||||||
},
|
},
|
||||||
shaping: section.shaping,
|
shaping: section.shaping,
|
||||||
},
|
},
|
||||||
|
Purpose::Drawing,
|
||||||
);
|
);
|
||||||
|
|
||||||
key
|
key
|
||||||
|
|
@ -233,6 +233,10 @@ impl Pipeline {
|
||||||
self.prepare_layer = 0;
|
self.prepare_layer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn trim_measurements(&mut self) {
|
||||||
|
self.cache.get_mut().trim(Purpose::Measuring);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn measure(
|
pub fn measure(
|
||||||
&self,
|
&self,
|
||||||
content: &str,
|
content: &str,
|
||||||
|
|
@ -246,10 +250,6 @@ impl Pipeline {
|
||||||
|
|
||||||
let line_height = f32::from(line_height.to_absolute(Pixels(size)));
|
let line_height = f32::from(line_height.to_absolute(Pixels(size)));
|
||||||
|
|
||||||
if cache.switch(Mode::Measuring) {
|
|
||||||
cache.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_, entry) = cache.allocate(
|
let (_, entry) = cache.allocate(
|
||||||
&mut self.font_system.borrow_mut(),
|
&mut self.font_system.borrow_mut(),
|
||||||
Key {
|
Key {
|
||||||
|
|
@ -260,6 +260,7 @@ impl Pipeline {
|
||||||
bounds,
|
bounds,
|
||||||
shaping,
|
shaping,
|
||||||
},
|
},
|
||||||
|
Purpose::Measuring,
|
||||||
);
|
);
|
||||||
|
|
||||||
entry.bounds
|
entry.bounds
|
||||||
|
|
@ -280,10 +281,6 @@ impl Pipeline {
|
||||||
|
|
||||||
let line_height = f32::from(line_height.to_absolute(Pixels(size)));
|
let line_height = f32::from(line_height.to_absolute(Pixels(size)));
|
||||||
|
|
||||||
if cache.switch(Mode::Measuring) {
|
|
||||||
cache.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_, entry) = cache.allocate(
|
let (_, entry) = cache.allocate(
|
||||||
&mut self.font_system.borrow_mut(),
|
&mut self.font_system.borrow_mut(),
|
||||||
Key {
|
Key {
|
||||||
|
|
@ -294,6 +291,7 @@ impl Pipeline {
|
||||||
bounds,
|
bounds,
|
||||||
shaping,
|
shaping,
|
||||||
},
|
},
|
||||||
|
Purpose::Measuring,
|
||||||
);
|
);
|
||||||
|
|
||||||
let cursor = entry.buffer.hit(point.x, point.y)?;
|
let cursor = entry.buffer.hit(point.x, point.y)?;
|
||||||
|
|
@ -364,7 +362,6 @@ struct Cache {
|
||||||
recently_measured: FxHashSet<KeyHash>,
|
recently_measured: FxHashSet<KeyHash>,
|
||||||
recently_drawn: FxHashSet<KeyHash>,
|
recently_drawn: FxHashSet<KeyHash>,
|
||||||
hasher: HashBuilder,
|
hasher: HashBuilder,
|
||||||
mode: Mode,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
|
|
@ -373,7 +370,7 @@ struct Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum Mode {
|
enum Purpose {
|
||||||
Measuring,
|
Measuring,
|
||||||
Drawing,
|
Drawing,
|
||||||
}
|
}
|
||||||
|
|
@ -392,7 +389,6 @@ impl Cache {
|
||||||
recently_measured: FxHashSet::default(),
|
recently_measured: FxHashSet::default(),
|
||||||
recently_drawn: FxHashSet::default(),
|
recently_drawn: FxHashSet::default(),
|
||||||
hasher: HashBuilder::default(),
|
hasher: HashBuilder::default(),
|
||||||
mode: Mode::Measuring,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,24 +396,17 @@ impl Cache {
|
||||||
self.entries.get(key)
|
self.entries.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch(&mut self, mode: Mode) -> bool {
|
|
||||||
let has_changed = self.mode != mode;
|
|
||||||
|
|
||||||
self.mode = mode;
|
|
||||||
|
|
||||||
has_changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allocate(
|
fn allocate(
|
||||||
&mut self,
|
&mut self,
|
||||||
font_system: &mut glyphon::FontSystem,
|
font_system: &mut glyphon::FontSystem,
|
||||||
key: Key<'_>,
|
key: Key<'_>,
|
||||||
|
purpose: Purpose,
|
||||||
) -> (KeyHash, &mut Entry) {
|
) -> (KeyHash, &mut Entry) {
|
||||||
let hash = key.hash(self.hasher.build_hasher());
|
let hash = key.hash(self.hasher.build_hasher());
|
||||||
|
|
||||||
let recently_used = match self.mode {
|
let recently_used = match purpose {
|
||||||
Mode::Measuring => &mut self.recently_measured,
|
Purpose::Measuring => &mut self.recently_measured,
|
||||||
Mode::Drawing => &mut self.recently_drawn,
|
Purpose::Drawing => &mut self.recently_drawn,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(hash) = self.aliases.get(&hash) {
|
if let Some(hash) = self.aliases.get(&hash) {
|
||||||
|
|
@ -469,7 +458,7 @@ impl Cache {
|
||||||
(hash, self.entries.get_mut(&hash).unwrap())
|
(hash, self.entries.get_mut(&hash).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trim(&mut self) {
|
fn trim(&mut self, purpose: Purpose) {
|
||||||
self.entries.retain(|key, _| {
|
self.entries.retain(|key, _| {
|
||||||
self.recently_measured.contains(key)
|
self.recently_measured.contains(key)
|
||||||
|| self.recently_drawn.contains(key)
|
|| self.recently_drawn.contains(key)
|
||||||
|
|
@ -479,11 +468,11 @@ impl Cache {
|
||||||
|| self.recently_drawn.contains(value)
|
|| self.recently_drawn.contains(value)
|
||||||
});
|
});
|
||||||
|
|
||||||
match self.mode {
|
match purpose {
|
||||||
Mode::Measuring => {
|
Purpose::Measuring => {
|
||||||
self.recently_measured.clear();
|
self.recently_measured.clear();
|
||||||
}
|
}
|
||||||
Mode::Drawing => {
|
Purpose::Drawing => {
|
||||||
self.recently_drawn.clear();
|
self.recently_drawn.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue