Decouple caching from Paragraph API
This commit is contained in:
parent
616689ca54
commit
ffb520fb37
7 changed files with 128 additions and 95 deletions
|
|
@ -1,8 +1,8 @@
|
|||
//! Draw paragraphs.
|
||||
use crate::core;
|
||||
use crate::core::alignment;
|
||||
use crate::core::text::{Hit, LineHeight, Shaping, Text};
|
||||
use crate::core::{Font, Pixels, Point, Size};
|
||||
use crate::core::text::{Hit, Shaping, Text};
|
||||
use crate::core::{Font, Point, Size};
|
||||
use crate::text;
|
||||
|
||||
use std::fmt;
|
||||
|
|
@ -10,11 +10,11 @@ use std::sync::{self, Arc};
|
|||
|
||||
/// A bunch of text.
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Paragraph(Option<Arc<Internal>>);
|
||||
pub struct Paragraph(Arc<Internal>);
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Internal {
|
||||
buffer: cosmic_text::Buffer,
|
||||
content: String, // TODO: Reuse from `buffer` (?)
|
||||
font: Font,
|
||||
shaping: Shaping,
|
||||
horizontal_alignment: alignment::Horizontal,
|
||||
|
|
@ -52,9 +52,7 @@ impl Paragraph {
|
|||
}
|
||||
|
||||
fn internal(&self) -> &Arc<Internal> {
|
||||
self.0
|
||||
.as_ref()
|
||||
.expect("paragraph should always be initialized")
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,9 +88,8 @@ impl core::text::Paragraph for Paragraph {
|
|||
|
||||
let min_bounds = text::measure(&buffer);
|
||||
|
||||
Self(Some(Arc::new(Internal {
|
||||
Self(Arc::new(Internal {
|
||||
buffer,
|
||||
content: text.content.to_owned(),
|
||||
font: text.font,
|
||||
horizontal_alignment: text.horizontal_alignment,
|
||||
vertical_alignment: text.vertical_alignment,
|
||||
|
|
@ -100,59 +97,31 @@ impl core::text::Paragraph for Paragraph {
|
|||
bounds: text.bounds,
|
||||
min_bounds,
|
||||
version: font_system.version(),
|
||||
})))
|
||||
}))
|
||||
}
|
||||
|
||||
fn resize(&mut self, new_bounds: Size) {
|
||||
let paragraph = self
|
||||
.0
|
||||
.take()
|
||||
.expect("paragraph should always be initialized");
|
||||
let paragraph = Arc::make_mut(&mut self.0);
|
||||
|
||||
match Arc::try_unwrap(paragraph) {
|
||||
Ok(mut internal) => {
|
||||
let mut font_system =
|
||||
text::font_system().write().expect("Write font system");
|
||||
let mut font_system =
|
||||
text::font_system().write().expect("Write font system");
|
||||
|
||||
internal.buffer.set_size(
|
||||
font_system.raw(),
|
||||
Some(new_bounds.width),
|
||||
Some(new_bounds.height),
|
||||
);
|
||||
paragraph.buffer.set_size(
|
||||
font_system.raw(),
|
||||
Some(new_bounds.width),
|
||||
Some(new_bounds.height),
|
||||
);
|
||||
|
||||
internal.bounds = new_bounds;
|
||||
internal.min_bounds = text::measure(&internal.buffer);
|
||||
|
||||
self.0 = Some(Arc::new(internal));
|
||||
}
|
||||
Err(internal) => {
|
||||
let metrics = internal.buffer.metrics();
|
||||
|
||||
// If there is a strong reference somewhere, we recompute the
|
||||
// buffer from scratch
|
||||
*self = Self::with_text(Text {
|
||||
content: &internal.content,
|
||||
bounds: internal.bounds,
|
||||
size: Pixels(metrics.font_size),
|
||||
line_height: LineHeight::Absolute(Pixels(
|
||||
metrics.line_height,
|
||||
)),
|
||||
font: internal.font,
|
||||
horizontal_alignment: internal.horizontal_alignment,
|
||||
vertical_alignment: internal.vertical_alignment,
|
||||
shaping: internal.shaping,
|
||||
});
|
||||
}
|
||||
}
|
||||
paragraph.bounds = new_bounds;
|
||||
paragraph.min_bounds = text::measure(¶graph.buffer);
|
||||
}
|
||||
|
||||
fn compare(&self, text: Text<&str>) -> core::text::Difference {
|
||||
fn compare(&self, text: Text<()>) -> core::text::Difference {
|
||||
let font_system = text::font_system().read().expect("Read font system");
|
||||
let paragraph = self.internal();
|
||||
let metrics = paragraph.buffer.metrics();
|
||||
|
||||
if paragraph.version != font_system.version
|
||||
|| paragraph.content != text.content
|
||||
|| metrics.font_size != text.size.0
|
||||
|| metrics.line_height != text.line_height.to_absolute(text.size).0
|
||||
|| paragraph.font != text.font
|
||||
|
|
@ -231,7 +200,7 @@ impl core::text::Paragraph for Paragraph {
|
|||
|
||||
impl Default for Paragraph {
|
||||
fn default() -> Self {
|
||||
Self(Some(Arc::new(Internal::default())))
|
||||
Self(Arc::new(Internal::default()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +209,6 @@ impl fmt::Debug for Paragraph {
|
|||
let paragraph = self.internal();
|
||||
|
||||
f.debug_struct("Paragraph")
|
||||
.field("content", ¶graph.content)
|
||||
.field("font", ¶graph.font)
|
||||
.field("shaping", ¶graph.shaping)
|
||||
.field("horizontal_alignment", ¶graph.horizontal_alignment)
|
||||
|
|
@ -253,8 +221,7 @@ impl fmt::Debug for Paragraph {
|
|||
|
||||
impl PartialEq for Internal {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.content == other.content
|
||||
&& self.font == other.font
|
||||
self.font == other.font
|
||||
&& self.shaping == other.shaping
|
||||
&& self.horizontal_alignment == other.horizontal_alignment
|
||||
&& self.vertical_alignment == other.vertical_alignment
|
||||
|
|
@ -271,7 +238,6 @@ impl Default for Internal {
|
|||
font_size: 1.0,
|
||||
line_height: 1.0,
|
||||
}),
|
||||
content: String::new(),
|
||||
font: Font::default(),
|
||||
shaping: Shaping::default(),
|
||||
horizontal_alignment: alignment::Horizontal::Left,
|
||||
|
|
@ -298,7 +264,7 @@ pub struct Weak {
|
|||
impl Weak {
|
||||
/// Tries to update the reference into a [`Paragraph`].
|
||||
pub fn upgrade(&self) -> Option<Paragraph> {
|
||||
self.raw.upgrade().map(Some).map(Paragraph)
|
||||
self.raw.upgrade().map(Paragraph)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue