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

View file

@ -10,13 +10,16 @@ LICENSE END */
#![warn(missing_docs)] #![warn(missing_docs)]
//! Exposed Window API //! Exposed Window API
use crate::component::{ComponentRc, ComponentWeak};
use crate::graphics::Point; use crate::graphics::Point;
use crate::input::{KeyEvent, MouseEventType, MouseInputState, TextCursorBlinker}; use crate::input::{KeyEvent, MouseEventType, MouseInputState, TextCursorBlinker};
use crate::items::{ItemRc, ItemRef, ItemWeak}; use crate::items::{ItemRc, ItemRef, ItemWeak};
use crate::properties::PropertyTracker; use crate::properties::PropertyTracker;
use crate::slice::Slice; use crate::slice::Slice;
use crate::ImageReference; use crate::ImageReference;
use crate::{
component::{ComponentRc, ComponentWeak},
SharedString,
};
use core::cell::Cell; use core::cell::Cell;
use core::pin::Pin; use core::pin::Pin;
use std::cell::RefCell; use std::cell::RefCell;
@ -59,7 +62,9 @@ pub trait PlatformWindow {
/// With some backends this may return none unless the window is mapped. /// With some backends this may return none unless the window is mapped.
fn font_metrics( fn font_metrics(
&self, &self,
item_graphics_cache: &crate::item_rendering::CachedRenderingData,
unresolved_font_request_getter: &dyn Fn() -> crate::graphics::FontRequest, unresolved_font_request_getter: &dyn Fn() -> crate::graphics::FontRequest,
reference_text: Pin<&crate::properties::Property<SharedString>>,
) -> Option<Box<dyn crate::graphics::FontMetrics>>; ) -> Option<Box<dyn crate::graphics::FontMetrics>>;
/// Return the size of the image referenced by the specified resource, multiplied by the window /// 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::slice::Slice;
use corelib::window::{ComponentWindow, PlatformWindow}; use corelib::window::{ComponentWindow, PlatformWindow};
use corelib::Property; use corelib::Property;
use corelib::SharedString;
use sixtyfps_corelib as corelib; use sixtyfps_corelib as corelib;
/// FIXME! this is some remains from a time where the GLRenderer was called the backend /// 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( fn font_metrics(
&self, &self,
item_graphics_cache: &corelib::item_rendering::CachedRenderingData,
unresolved_font_request_getter: &dyn Fn() -> corelib::graphics::FontRequest, unresolved_font_request_getter: &dyn Fn() -> corelib::graphics::FontRequest,
reference_text: Pin<&Property<SharedString>>,
) -> Option<Box<dyn corelib::graphics::FontMetrics>> { ) -> Option<Box<dyn corelib::graphics::FontMetrics>> {
match &*self.map_state.borrow() { match &*self.map_state.borrow() {
GraphicsWindowBackendState::Unmapped => None, GraphicsWindowBackendState::Unmapped => None,
GraphicsWindowBackendState::Mapped(window) => { GraphicsWindowBackendState::Mapped(window) => Some(
Some(window.backend.borrow_mut().font_metrics( window.backend.borrow_mut().font_metrics(
unresolved_font_request_getter, item_graphics_cache,
&|| self.default_font_properties().as_ref().get(), &|| {
self.scale_factor(), 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. /// closely as possible.
fn font_metrics( fn font_metrics(
&mut self, &mut self,
unresolved_request_fn: &dyn Fn() -> FontRequest, _item_graphics_cache: &sixtyfps_corelib::item_rendering::CachedRenderingData,
default_font_props_fn: &dyn Fn() -> FontRequest, font_request_fn: &dyn Fn() -> FontRequest,
scale_factor: f32, scale_factor: Pin<&Property<f32>>,
_reference_text: Pin<&Property<SharedString>>,
) -> Box<dyn FontMetrics> { ) -> Box<dyn FontMetrics> {
Box::new(GLFontMetrics { Box::new(GLFontMetrics {
request: unresolved_request_fn().merge(&default_font_props_fn()), request: font_request_fn(),
scale_factor, scale_factor: scale_factor.get(),
shared_data: self.shared_data.clone(), shared_data: self.shared_data.clone(),
}) })
} }

View file

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