Simplify font resolution in the GL backend

The font resolution function querying fontdb is fast now, so we can
always call it when rendering text. That way we don't need all the
indirection in the text_size(), etc. functions, we don't need an entry
in the item graphics cache for the font and we can avoid a lot of
property dependencies.
This commit is contained in:
Simon Hausmann 2021-09-20 18:05:04 +02:00
parent 2f1db396e8
commit ac0cc85d33
7 changed files with 62 additions and 140 deletions

View file

@ -20,8 +20,6 @@ use sixtyfps_corelib::{SharedString, SharedVector};
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use crate::ItemGraphicsCache;
pub const DEFAULT_FONT_SIZE: f32 = 12.;
pub const DEFAULT_FONT_WEIGHT: i32 = 400; // CSS normal
@ -122,30 +120,15 @@ impl Font {
}
pub(crate) fn text_size(
graphics_cache: &RefCell<ItemGraphicsCache>,
item_graphics_cache: &sixtyfps_corelib::item_rendering::CachedRenderingData,
font_request_fn: impl Fn() -> sixtyfps_corelib::graphics::FontRequest,
scale_factor: std::pin::Pin<&sixtyfps_corelib::Property<f32>>,
text_getter: &dyn Fn() -> SharedString,
font_request: &sixtyfps_corelib::graphics::FontRequest,
scale_factor: f32,
text: &str,
max_width: Option<f32>,
) -> Size {
let cached_font = item_graphics_cache
.get_or_update(graphics_cache, || {
Some(super::ItemGraphicsCacheEntry::Font(FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
font_request_fn(),
scale_factor.get(),
// FIXME: there is no dependency to the text property
&text_getter(),
)
})))
})
.unwrap();
let font = cached_font.as_font();
let letter_spacing = font_request_fn().letter_spacing.unwrap_or_default();
let scale_factor = scale_factor.get();
font.text_size(letter_spacing, &text_getter(), max_width.map(|x| x * scale_factor))
/ scale_factor
let font =
FONT_CACHE.with(|cache| cache.borrow_mut().font(font_request.clone(), scale_factor, text));
let letter_spacing = font_request.letter_spacing.unwrap_or_default();
font.text_size(letter_spacing, text, max_width.map(|x| x * scale_factor)) / scale_factor
}
#[derive(Copy, Clone)]

View file

@ -25,12 +25,10 @@ use corelib::layout::Orientation;
use corelib::slice::Slice;
use corelib::window::{PlatformWindow, PopupWindow, PopupWindowLocation};
use corelib::Property;
use corelib::SharedString;
use sixtyfps_corelib as corelib;
use winit::dpi::LogicalSize;
use crate::CanvasRc;
use crate::ItemGraphicsCacheEntry;
/// GraphicsWindow is an implementation of the [PlatformWindow][`crate::eventloop::PlatformWindow`] trait. This is
/// typically instantiated by entry factory functions of the different graphics back ends.
@ -506,20 +504,16 @@ impl PlatformWindow for GraphicsWindow {
fn text_size(
&self,
item_graphics_cache: &corelib::item_rendering::CachedRenderingData,
unresolved_font_request_getter: &dyn Fn() -> corelib::graphics::FontRequest,
text_getter: &dyn Fn() -> SharedString,
font_request: corelib::graphics::FontRequest,
text: &str,
max_width: Option<f32>,
) -> Size {
let font_request_fn =
|| unresolved_font_request_getter().merge(&self.default_font_properties());
let font_request = font_request.merge(&self.default_font_properties());
crate::fonts::text_size(
&self.graphics_cache,
item_graphics_cache,
font_request_fn,
self.self_weak.upgrade().unwrap().scale_factor_property(),
text_getter,
&font_request,
self.self_weak.upgrade().unwrap().scale_factor(),
text,
max_width,
)
}
@ -541,20 +535,13 @@ impl PlatformWindow for GraphicsWindow {
return 0;
}
let font = text_input
.cached_rendering_data
.get_or_update(&self.graphics_cache, || {
Some(ItemGraphicsCacheEntry::Font(crate::fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text_input.unresolved_font_request().merge(&self.default_font_properties()),
scale_factor,
&text_input.text(),
)
})))
})
.unwrap()
.as_font()
.clone();
let font = crate::fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text_input.unresolved_font_request().merge(&self.default_font_properties()),
scale_factor,
&text_input.text(),
)
});
let paint = font.init_paint(text_input.letter_spacing() * scale_factor, Default::default());
let text_context =
@ -603,20 +590,13 @@ impl PlatformWindow for GraphicsWindow {
return result;
}
let font = text_input
.cached_rendering_data
.get_or_update(&self.graphics_cache, || {
Some(ItemGraphicsCacheEntry::Font(crate::fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text_input.unresolved_font_request().merge(&self.default_font_properties()),
scale_factor,
&text_input.text(),
)
})))
})
.unwrap()
.as_font()
.clone();
let font = crate::fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text_input.unresolved_font_request().merge(&self.default_font_properties()),
scale_factor,
&text_input.text(),
)
});
let paint = font.init_paint(text_input.letter_spacing() * scale_factor, Default::default());
crate::fonts::layout_text_lines(

View file

@ -53,8 +53,6 @@ enum ItemGraphicsCacheEntry {
_original_image: Rc<CachedImage>,
colorized_image: Rc<CachedImage>,
},
// The font selection is expensive because it is also based on the concrete rendered text, so this is cached here to speed up re-paints
Font(fonts::Font),
}
impl ItemGraphicsCacheEntry {
@ -62,18 +60,11 @@ impl ItemGraphicsCacheEntry {
match self {
ItemGraphicsCacheEntry::Image(image) => image,
ItemGraphicsCacheEntry::ColorizedImage { colorized_image, .. } => colorized_image,
_ => panic!("internal error. image requested for non-image gpu data"),
}
}
fn is_colorized_image(&self) -> bool {
matches!(self, ItemGraphicsCacheEntry::ColorizedImage { .. })
}
fn as_font(&self) -> &fonts::Font {
match self {
ItemGraphicsCacheEntry::Font(font) => font,
_ => panic!("internal error. font requested for non-font gpu data"),
}
}
}
type ItemGraphicsCache = RenderingCache<Option<ItemGraphicsCacheEntry>>;
@ -453,21 +444,14 @@ impl ItemRenderer for GLItemRenderer {
let string = text.text();
let string = string.as_str();
let font = text
.cached_rendering_data
.get_or_update(&self.graphics_window.graphics_cache, || {
Some(ItemGraphicsCacheEntry::Font(fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text.unresolved_font_request()
.merge(&self.graphics_window.default_font_properties()),
self.scale_factor,
&text.text(),
)
})))
})
.unwrap()
.as_font()
.clone();
let font = fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text.unresolved_font_request()
.merge(&self.graphics_window.default_font_properties()),
self.scale_factor,
&text.text(),
)
});
let paint = match self
.brush_to_paint(text.color(), &mut rect_to_path(item_rect(text, self.scale_factor)))
@ -499,22 +483,15 @@ impl ItemRenderer for GLItemRenderer {
return;
}
let font = text_input
.cached_rendering_data
.get_or_update(&self.graphics_window.graphics_cache, || {
Some(ItemGraphicsCacheEntry::Font(fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text_input
.unresolved_font_request()
.merge(&self.graphics_window.default_font_properties()),
self.scale_factor,
&text_input.text(),
)
})))
})
.unwrap()
.as_font()
.clone();
let font = fonts::FONT_CACHE.with(|cache| {
cache.borrow_mut().font(
text_input
.unresolved_font_request()
.merge(&self.graphics_window.default_font_properties()),
self.scale_factor,
&text_input.text(),
)
});
let paint = match self.brush_to_paint(
text_input.color(),
@ -987,7 +964,6 @@ impl ItemRenderer for GLItemRenderer {
let image_id = match cache_entry {
Some(ItemGraphicsCacheEntry::Image(image)) => image.ensure_uploaded_to_gpu(self, None),
Some(ItemGraphicsCacheEntry::ColorizedImage { .. }) => unreachable!(),
Some(ItemGraphicsCacheEntry::Font(_)) => unreachable!(),
None => return,
};
let mut canvas = self.canvas.borrow_mut();