Further preparation for more aggressive font caching

Pass everything needed for delayed evaluation for
`PlatformWindow::font_metrics()` to permit caching the font matching
result in the Text/TextInput's rendering cache.
This commit is contained in:
Simon Hausmann 2021-04-13 15:18:17 +02:00
parent a48b81022b
commit 47a255eea5
5 changed files with 55 additions and 19 deletions

View file

@ -128,8 +128,11 @@ impl Item for Text {
if self.wrap() == TextWrap::word_wrap {
// FIXME: one should limit to the size of the smaler word
LayoutInfo::default()
} else if let Some(font_metrics) = window.0.font_metrics(&|| self.unresolved_font_request())
{
} else if let Some(font_metrics) = window.0.font_metrics(
&self.cached_rendering_data,
&|| self.unresolved_font_request(),
Self::FIELD_OFFSETS.text.apply_pin(self),
) {
let mut min_size = font_metrics.text_size(&self.text());
match self.overflow() {
TextOverflow::elide => {
@ -153,7 +156,11 @@ impl Item for Text {
fn implicit_size(self: Pin<&Self>, window: &ComponentWindow) -> Size {
window
.0
.font_metrics(&|| self.unresolved_font_request())
.font_metrics(
&self.cached_rendering_data,
&|| self.unresolved_font_request(),
Self::FIELD_OFFSETS.text.apply_pin(self),
)
.map(|metrics| metrics.text_size(&self.text()))
.unwrap_or_default()
}
@ -264,7 +271,11 @@ impl Item for TextInput {
}
fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo {
if let Some(font_metrics) = window.0.font_metrics(&|| self.unresolved_font_request()) {
if let Some(font_metrics) = window.0.font_metrics(
&self.cached_rendering_data,
&|| self.unresolved_font_request(),
Self::FIELD_OFFSETS.text.apply_pin(self),
) {
let size = font_metrics.text_size("********************");
LayoutInfo {
@ -281,7 +292,11 @@ impl Item for TextInput {
fn implicit_size(self: Pin<&Self>, window: &ComponentWindow) -> Size {
window
.0
.font_metrics(&|| self.unresolved_font_request())
.font_metrics(
&self.cached_rendering_data,
&|| self.unresolved_font_request(),
Self::FIELD_OFFSETS.text.apply_pin(self),
)
.map(|metrics| metrics.text_size(&self.text()))
.unwrap_or_default()
}
@ -306,7 +321,11 @@ impl Item for TextInput {
}
let text = self.text();
let font_metrics = match window.0.font_metrics(&|| self.unresolved_font_request()) {
let font_metrics = match window.0.font_metrics(
&self.cached_rendering_data,
&|| self.unresolved_font_request(),
Self::FIELD_OFFSETS.text.apply_pin(self),
) {
Some(font) => font,
None => return InputEventResult::EventIgnored,
};

View file

@ -10,13 +10,16 @@ LICENSE END */
#![warn(missing_docs)]
//! Exposed Window API
use crate::component::{ComponentRc, ComponentWeak};
use crate::graphics::Point;
use crate::input::{KeyEvent, MouseEventType, MouseInputState, TextCursorBlinker};
use crate::items::{ItemRc, ItemRef, ItemWeak};
use crate::properties::PropertyTracker;
use crate::slice::Slice;
use crate::ImageReference;
use crate::{
component::{ComponentRc, ComponentWeak},
SharedString,
};
use core::cell::Cell;
use core::pin::Pin;
use std::cell::RefCell;
@ -59,7 +62,9 @@ pub trait PlatformWindow {
/// With some backends this may return none unless the window is mapped.
fn font_metrics(
&self,
item_graphics_cache: &crate::item_rendering::CachedRenderingData,
unresolved_font_request_getter: &dyn Fn() -> crate::graphics::FontRequest,
reference_text: Pin<&crate::properties::Property<SharedString>>,
) -> Option<Box<dyn crate::graphics::FontMetrics>>;
/// Return the size of the image referenced by the specified resource, multiplied by the window

View file

@ -21,6 +21,7 @@ use corelib::items::ItemRef;
use corelib::slice::Slice;
use corelib::window::{ComponentWindow, PlatformWindow};
use corelib::Property;
use corelib::SharedString;
use sixtyfps_corelib as corelib;
/// FIXME! this is some remains from a time where the GLRenderer was called the backend
@ -466,17 +467,25 @@ impl PlatformWindow for GraphicsWindow {
fn font_metrics(
&self,
item_graphics_cache: &corelib::item_rendering::CachedRenderingData,
unresolved_font_request_getter: &dyn Fn() -> corelib::graphics::FontRequest,
reference_text: Pin<&Property<SharedString>>,
) -> Option<Box<dyn corelib::graphics::FontMetrics>> {
match &*self.map_state.borrow() {
GraphicsWindowBackendState::Unmapped => None,
GraphicsWindowBackendState::Mapped(window) => {
Some(window.backend.borrow_mut().font_metrics(
unresolved_font_request_getter,
&|| self.default_font_properties().as_ref().get(),
self.scale_factor(),
))
}
GraphicsWindowBackendState::Mapped(window) => Some(
window.backend.borrow_mut().font_metrics(
item_graphics_cache,
&|| {
unresolved_font_request_getter()
.merge(&self.default_font_properties().as_ref().get())
},
WindowProperties::FIELD_OFFSETS
.scale_factor
.apply_pin(self.properties.as_ref()),
reference_text,
),
),
}
}

View file

@ -467,13 +467,14 @@ impl GLRenderer {
/// closely as possible.
fn font_metrics(
&mut self,
unresolved_request_fn: &dyn Fn() -> FontRequest,
default_font_props_fn: &dyn Fn() -> FontRequest,
scale_factor: f32,
_item_graphics_cache: &sixtyfps_corelib::item_rendering::CachedRenderingData,
font_request_fn: &dyn Fn() -> FontRequest,
scale_factor: Pin<&Property<f32>>,
_reference_text: Pin<&Property<SharedString>>,
) -> Box<dyn FontMetrics> {
Box::new(GLFontMetrics {
request: unresolved_request_fn().merge(&default_font_props_fn()),
scale_factor,
request: font_request_fn(),
scale_factor: scale_factor.get(),
shared_data: self.shared_data.clone(),
})
}

View file

@ -1009,7 +1009,9 @@ impl PlatformWindow for QtWindow {
fn font_metrics(
&self,
_item_graphics_cache: &sixtyfps_corelib::item_rendering::CachedRenderingData,
unresolved_font_request_getter: &dyn Fn() -> sixtyfps_corelib::graphics::FontRequest,
_reference_text: Pin<&Property<SharedString>>,
) -> Option<Box<dyn sixtyfps_corelib::graphics::FontMetrics>> {
Some(Box::new(get_font(
unresolved_font_request_getter().merge(&self.default_font_properties()),