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

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