Simplify FontHandle and rename it to PlatformFont (#32101)

* Simplify `FontHandle` and rename it to `PlatformFont`

Rename it to `PlatformFont` and move the `FontTemplate` member to
`Font`, because it's shared by all platforms.

* Update components/gfx/platform/freetype/font.rs

Co-authored-by: Mukilan Thiyagarajan <mukilanthiagarajan@gmail.com>

* Fix build for MacOS and Windows

---------

Co-authored-by: Mukilan Thiyagarajan <mukilanthiagarajan@gmail.com>
This commit is contained in:
Martin Robinson 2024-04-17 19:44:34 +02:00 committed by GitHub
parent e9e46f4c0b
commit 5393d30a8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 71 additions and 80 deletions

View file

@ -4,6 +4,7 @@
use std::ffi::CString;
use std::os::raw::{c_char, c_long};
use std::sync::Arc;
use std::{mem, ptr};
use app_units::Au;
@ -23,7 +24,7 @@ use style::values::computed::font::FontStyle;
use super::c_str_to_string;
use super::library_handle::FreeTypeLibraryHandle;
use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, GPOS, GSUB,
FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, PlatformFontMethods, GPOS, GSUB,
KERN,
};
use crate::font_cache_thread::FontIdentifier;
@ -70,15 +71,18 @@ struct OS2Table {
#[derive(Debug)]
#[allow(unused)]
pub struct FontHandle {
// The template contains the font data, which must stay valid for the
// lifetime of the platform [`FT_Face`], if it's created via [`FT_Memory_Face`].
font_template: FontTemplateRef,
pub struct PlatformFont {
/// The font data itself, which must stay valid for the lifetime of the
/// platform [`FT_Face`], if it's created via [`FT_New_Memory_Face`]. A reference
/// to this data is also stored in the [`crate::font::Font`] that holds
/// this [`PlatformFont`], but if it's ever separated from it's font,
/// this ensures the data stays alive.
font_data: Option<Arc<Vec<u8>>>,
face: FT_Face,
can_do_fast_shaping: bool,
}
impl Drop for FontHandle {
impl Drop for PlatformFont {
fn drop(&mut self) {
assert!(!self.face.is_null());
unsafe {
@ -134,22 +138,22 @@ fn create_face(template: &FontTemplateRef, pt_size: Option<Au>) -> Result<FT_Fac
}
if let Some(s) = pt_size {
FontHandle::set_char_size(face, s)?
PlatformFont::set_char_size(face, s)?
}
Ok(face)
}
}
impl FontHandleMethods for FontHandle {
impl PlatformFontMethods for PlatformFont {
fn new_from_template(
template: FontTemplateRef,
pt_size: Option<Au>,
) -> Result<FontHandle, &'static str> {
) -> Result<PlatformFont, &'static str> {
let face = create_face(&template, pt_size)?;
let mut handle = FontHandle {
let mut handle = PlatformFont {
face,
font_template: template.clone(),
font_data: template.borrow().data_if_in_memory(),
can_do_fast_shaping: false,
};
// TODO (#11310): Implement basic support for GPOS and GSUB.
@ -158,10 +162,6 @@ impl FontHandleMethods for FontHandle {
Ok(handle)
}
fn template(&self) -> FontTemplateRef {
self.font_template.clone()
}
fn family_name(&self) -> Option<String> {
unsafe {
let family_name = (*self.face).family_name;
@ -362,7 +362,7 @@ impl FontHandleMethods for FontHandle {
}
}
impl<'a> FontHandle {
impl<'a> PlatformFont {
fn set_char_size(face: FT_Face, pt_size: Au) -> Result<(), &'static str> {
let char_size = pt_size.to_f64_px() * 64.0 + 0.5;

View file

@ -4,6 +4,7 @@
use std::cmp::Ordering;
use std::ops::Range;
use std::sync::Arc;
use std::{fmt, ptr};
/// Implementation of Quartz (CoreGraphics) fonts.
@ -22,7 +23,7 @@ use style::values::computed::font::{FontStretch, FontStyle, FontWeight};
use super::font_template::CoreTextFontTemplateMethods;
use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, GPOS, GSUB,
FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, PlatformFontMethods, GPOS, GSUB,
KERN,
};
use crate::font_template::FontTemplateRef;
@ -52,14 +53,16 @@ impl FontTableMethods for FontTable {
}
#[derive(Debug)]
pub struct FontHandle {
font_template: FontTemplateRef,
pub struct PlatformFont {
ctfont: CTFont,
/// A reference to this data used to create this [`PlatformFont`], ensuring the
/// data stays alive of the lifetime of this struct.
_data: Option<Arc<Vec<u8>>>,
h_kern_subtable: Option<CachedKernTable>,
can_do_fast_shaping: bool,
}
impl FontHandle {
impl PlatformFont {
/// Cache all the data needed for basic horizontal kerning. This is used only as a fallback or
/// fast path (when the GPOS table is missing or unnecessary) so it needn't handle every case.
fn find_h_kern_subtable(&self) -> Option<CachedKernTable> {
@ -154,11 +157,11 @@ impl fmt::Debug for CachedKernTable {
}
}
impl FontHandleMethods for FontHandle {
impl PlatformFontMethods for PlatformFont {
fn new_from_template(
font_template: FontTemplateRef,
pt_size: Option<Au>,
) -> Result<FontHandle, &'static str> {
) -> Result<PlatformFont, &'static str> {
let size = match pt_size {
Some(s) => s.to_f64_px(),
None => 0.0,
@ -167,8 +170,8 @@ impl FontHandleMethods for FontHandle {
return Err("Could not generate CTFont for FontTemplateData");
};
let mut handle = FontHandle {
font_template,
let mut handle = PlatformFont {
_data: font_template.borrow().data_if_in_memory(),
ctfont: core_text_font.clone_with_font_size(size),
h_kern_subtable: None,
can_do_fast_shaping: false,
@ -181,10 +184,6 @@ impl FontHandleMethods for FontHandle {
Ok(handle)
}
fn template(&self) -> FontTemplateRef {
self.font_template.clone()
}
fn family_name(&self) -> Option<String> {
Some(self.ctfont.family_name())
}

View file

@ -8,6 +8,7 @@
use std::fmt;
use std::ops::Deref;
use std::sync::Arc;
use app_units::Au;
use dwrote::{Font, FontFace, FontFile, FontStretch, FontStyle};
@ -18,7 +19,7 @@ use style::values::computed::font::FontStyle as StyleFontStyle;
use style::values::specified::font::FontStretchKeyword;
use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel,
FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, PlatformFontMethods,
};
use crate::font_cache_thread::FontIdentifier;
use crate::font_template::{FontTemplateRef, FontTemplateRefMethods};
@ -198,9 +199,11 @@ impl FontInfo {
}
#[derive(Debug)]
pub struct FontHandle {
font_template: FontTemplateRef,
pub struct PlatformFont {
face: Nondebug<FontFace>,
/// A reference to this data used to create this [`PlatformFont`], ensuring the
/// data stays alive of the lifetime of this struct.
data: Option<Arc<Vec<u8>>>,
info: FontInfo,
em_size: f32,
du_to_px: f32,
@ -222,9 +225,7 @@ impl<T> Deref for Nondebug<T> {
}
}
impl FontHandle {}
impl FontHandleMethods for FontHandle {
impl PlatformFontMethods for PlatformFont {
fn new_from_template(
font_template: FontTemplateRef,
pt_size: Option<Au>,
@ -234,8 +235,12 @@ impl FontHandleMethods for FontHandle {
FontIdentifier::Web(_) => None,
};
let (face, info) = match direct_write_font {
Some(font) => (font.create_font_face(), FontInfo::new_from_font(&font)?),
let (face, info, data) = match direct_write_font {
Some(font) => (
font.create_font_face(),
FontInfo::new_from_font(&font)?,
None,
),
None => {
let bytes = font_template.data();
let font_file =
@ -244,7 +249,7 @@ impl FontHandleMethods for FontHandle {
.create_face(0, dwrote::DWRITE_FONT_SIMULATIONS_NONE)
.map_err(|_| "Could not create FontFace")?;
let info = FontInfo::new_from_face(&face)?;
(face, info)
(face, info, font_template.borrow().data_if_in_memory())
},
};
@ -257,9 +262,9 @@ impl FontHandleMethods for FontHandle {
let design_units_to_pixels = 1. / design_units_per_pixel;
let scaled_design_units_to_pixels = em_size / design_units_per_pixel;
Ok(FontHandle {
font_template,
Ok(PlatformFont {
face: Nondebug(face),
data,
info,
em_size,
du_to_px: design_units_to_pixels,
@ -267,10 +272,6 @@ impl FontHandleMethods for FontHandle {
})
}
fn template(&self) -> FontTemplateRef {
self.font_template.clone()
}
fn family_name(&self) -> Option<String> {
Some(self.info.family_name.clone())
}