Prepare for improved font fallback handling in the GL backend

In order to determine the best list of fallback fonts for text
rendering, we need to know what text we're going to render. That's why
this patch passes the text through all the way.
This commit is contained in:
Simon Hausmann 2021-04-13 13:41:16 +02:00
parent ccca2742c3
commit 58fc93d352
2 changed files with 29 additions and 12 deletions

View file

@ -125,7 +125,10 @@ pub(crate) fn load_system_font(canvas: &CanvasRc, request: &FontRequest) -> femt
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub(crate) fn font_fallbacks_for_request(_request: &FontRequest) -> Vec<FontRequest> { pub(crate) fn font_fallbacks_for_request(
_request: &FontRequest,
_reference_text: &str,
) -> Vec<FontRequest> {
_request _request
.family .family
.as_ref() .as_ref()
@ -153,7 +156,10 @@ pub(crate) fn font_fallbacks_for_request(_request: &FontRequest) -> Vec<FontRequ
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
pub(crate) fn font_fallbacks_for_request(_request: &FontRequest) -> Vec<FontRequest> { pub(crate) fn font_fallbacks_for_request(
_request: &FontRequest,
_reference_text: &str,
) -> Vec<FontRequest> {
vec![ vec![
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
FontRequest { FontRequest {

View file

@ -125,12 +125,18 @@ impl FontCache {
.clone() .clone()
} }
fn font(&mut self, canvas: &CanvasRc, mut request: FontRequest, scale_factor: f32) -> GLFont { fn font(
&mut self,
canvas: &CanvasRc,
mut request: FontRequest,
scale_factor: f32,
reference_text: &str,
) -> GLFont {
request.pixel_size = request.pixel_size.or(Some(DEFAULT_FONT_SIZE * scale_factor)); request.pixel_size = request.pixel_size.or(Some(DEFAULT_FONT_SIZE * scale_factor));
request.weight = request.weight.or(Some(DEFAULT_FONT_WEIGHT)); request.weight = request.weight.or(Some(DEFAULT_FONT_WEIGHT));
let primary_font = self.load_single_font(canvas, &request); let primary_font = self.load_single_font(canvas, &request);
let fallbacks = font_fallbacks_for_request(&request); let fallbacks = font_fallbacks_for_request(&request, reference_text);
let fonts = core::iter::once(primary_font) let fonts = core::iter::once(primary_font)
.chain( .chain(
@ -604,6 +610,7 @@ impl ItemRenderer for GLItemRenderer {
&self.shared_data.canvas, &self.shared_data.canvas,
text.unresolved_font_request().merge(&self.default_font_properties.as_ref().get()), text.unresolved_font_request().merge(&self.default_font_properties.as_ref().get()),
self.scale_factor, self.scale_factor,
&text.text(),
); );
let wrap = text.wrap() == TextWrap::word_wrap; let wrap = text.wrap() == TextWrap::word_wrap;
let text_size = font.text_size( let text_size = font.text_size(
@ -695,6 +702,7 @@ impl ItemRenderer for GLItemRenderer {
.unresolved_font_request() .unresolved_font_request()
.merge(&self.default_font_properties.as_ref().get()), .merge(&self.default_font_properties.as_ref().get()),
self.scale_factor, self.scale_factor,
&text_input.text(),
); );
let paint = match self let paint = match self
@ -707,7 +715,7 @@ impl ItemRenderer for GLItemRenderer {
let metrics = self.draw_text_impl( let metrics = self.draw_text_impl(
width, width,
height, height,
&text_input.text(), sixtyfps_corelib::items::TextInput::FIELD_OFFSETS.text.apply_pin(text_input),
text_input text_input
.unresolved_font_request() .unresolved_font_request()
.merge(&self.default_font_properties.as_ref().get()), .merge(&self.default_font_properties.as_ref().get()),
@ -759,7 +767,7 @@ impl ItemRenderer for GLItemRenderer {
self.draw_text_impl( self.draw_text_impl(
text_input.width(), text_input.width(),
text_input.height(), text_input.height(),
&text_input.text(), sixtyfps_corelib::items::TextInput::FIELD_OFFSETS.text.apply_pin(text_input),
text_input text_input
.unresolved_font_request() .unresolved_font_request()
.merge(&self.default_font_properties.as_ref().get()), .merge(&self.default_font_properties.as_ref().get()),
@ -1065,7 +1073,7 @@ impl GLItemRenderer {
&mut self, &mut self,
max_width: f32, max_width: f32,
max_height: f32, max_height: f32,
text: &str, text: Pin<&Property<SharedString>>,
font_request: FontRequest, font_request: FontRequest,
paint: femtovg::Paint, paint: femtovg::Paint,
horizontal_alignment: TextHorizontalAlignment, horizontal_alignment: TextHorizontalAlignment,
@ -1076,13 +1084,14 @@ impl GLItemRenderer {
&self.shared_data.canvas, &self.shared_data.canvas,
font_request, font_request,
self.scale_factor, self.scale_factor,
&text.get(),
); );
let paint = font.init_paint(letter_spacing, paint); let paint = font.init_paint(letter_spacing, paint);
let mut canvas = self.shared_data.canvas.borrow_mut(); let mut canvas = self.shared_data.canvas.borrow_mut();
let (text_width, text_height) = { let (text_width, text_height) = {
let text_metrics = canvas.measure_text(0., 0., &text, paint).unwrap(); let text_metrics = canvas.measure_text(0., 0., &text.as_ref().get(), paint).unwrap();
let font_metrics = canvas.measure_font(paint).unwrap(); let font_metrics = canvas.measure_font(paint).unwrap();
(text_metrics.width(), font_metrics.height()) (text_metrics.width(), font_metrics.height())
}; };
@ -1099,7 +1108,7 @@ impl GLItemRenderer {
TextVerticalAlignment::bottom => max_height - text_height, TextVerticalAlignment::bottom => max_height - text_height,
}; };
canvas.fill_text(translate_x, translate_y, text, paint).unwrap() canvas.fill_text(translate_x, translate_y, text.get(), paint).unwrap()
} }
fn colorize_image( fn colorize_image(
@ -1412,11 +1421,12 @@ struct GLFontMetrics {
impl FontMetrics for GLFontMetrics { impl FontMetrics for GLFontMetrics {
fn text_size(&self, text: &str) -> Size { fn text_size(&self, text: &str) -> Size {
self.font().text_size(self.request.letter_spacing.unwrap_or_default(), text, None) self.font(text).text_size(self.request.letter_spacing.unwrap_or_default(), text, None)
} }
fn text_offset_for_x_position<'a>(&self, text: &'a str, x: f32) -> usize { fn text_offset_for_x_position<'a>(&self, text: &'a str, x: f32) -> usize {
let metrics = self.font().measure(self.request.letter_spacing.unwrap_or_default(), text); let metrics =
self.font(text).measure(self.request.letter_spacing.unwrap_or_default(), text);
let mut current_x = 0.; let mut current_x = 0.;
for glyph in metrics.glyphs { for glyph in metrics.glyphs {
if current_x + glyph.advance_x / 2. >= x { if current_x + glyph.advance_x / 2. >= x {
@ -1429,11 +1439,12 @@ impl FontMetrics for GLFontMetrics {
} }
impl GLFontMetrics { impl GLFontMetrics {
fn font(&self) -> GLFont { fn font(&self, reference_text: &str) -> GLFont {
self.shared_data.loaded_fonts.borrow_mut().font( self.shared_data.loaded_fonts.borrow_mut().font(
&self.shared_data.canvas, &self.shared_data.canvas,
self.request.clone(), self.request.clone(),
self.scale_factor, self.scale_factor,
reference_text,
) )
} }
} }