gfx: Remove FontTemplateData (#32034)

Now that `FontTemplateData` is more or less the same on all platforms,
it can be removed. This is a preparatory change for a full refactor of
the font system on Servo. The major changes here are:

 - Remove `FontTemplateData` and move its members into `FontTemplate`
 - Make `FontTemplate` have full interior mutability instead of only
   the `FontTemplateData` member. This is preparation for having these
   data types `Send` and `Sync` with locking.
 - Remove the strong/weak reference concept for font data. In practice,
   all font data references were strong, so this was never fully
   complete. Instead of using this approach, the new font system will
   use a central font data cache with references associated to layouts.
 - The `CTFont` cache is now a global cache, so `CTFont`s can be shared
   between threads. The cache is cleared when clearing font caches.

A benefit of this change (apart from `CTFont` sharing) is that font data
loading is platform-independent now.
This commit is contained in:
Martin Robinson 2024-04-16 19:50:50 +02:00 committed by GitHub
parent 689c144714
commit 6b2fa91357
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 394 additions and 600 deletions

View file

@ -4,7 +4,6 @@
use std::cmp::Ordering;
use std::ops::Range;
use std::sync::Arc;
use std::{fmt, ptr};
/// Implementation of Quartz (CoreGraphics) fonts.
@ -21,12 +20,12 @@ use core_text::font_descriptor::{
use log::debug;
use style::values::computed::font::{FontStretch, FontStyle, FontWeight};
use super::font_template::CoreTextFontTemplateMethods;
use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, GPOS, GSUB,
KERN,
};
use crate::font_cache_thread::FontIdentifier;
use crate::platform::font_template::FontTemplateData;
use crate::font_template::FontTemplateRef;
use crate::text::glyph::GlyphId;
const KERN_PAIR_LEN: usize = 6;
@ -54,7 +53,7 @@ impl FontTableMethods for FontTable {
#[derive(Debug)]
pub struct FontHandle {
font_data: Arc<FontTemplateData>,
font_template: FontTemplateRef,
ctfont: CTFont,
h_kern_subtable: Option<CachedKernTable>,
can_do_fast_shaping: bool,
@ -157,34 +156,33 @@ impl fmt::Debug for CachedKernTable {
impl FontHandleMethods for FontHandle {
fn new_from_template(
template: Arc<FontTemplateData>,
font_template: FontTemplateRef,
pt_size: Option<Au>,
) -> Result<FontHandle, &'static str> {
let size = match pt_size {
Some(s) => s.to_f64_px(),
None => 0.0,
};
match template.ctfont(size) {
Some(ref ctfont) => {
let mut handle = FontHandle {
font_data: template.clone(),
ctfont: ctfont.clone_with_font_size(size),
h_kern_subtable: None,
can_do_fast_shaping: false,
};
handle.h_kern_subtable = handle.find_h_kern_subtable();
// TODO (#11310): Implement basic support for GPOS and GSUB.
handle.can_do_fast_shaping = handle.h_kern_subtable.is_some() &&
handle.table_for_tag(GPOS).is_none() &&
handle.table_for_tag(GSUB).is_none();
Ok(handle)
},
None => Err("Could not generate CTFont for FontTemplateData"),
}
let Some(core_text_font) = font_template.core_text_font(size) else {
return Err("Could not generate CTFont for FontTemplateData");
};
let mut handle = FontHandle {
font_template,
ctfont: core_text_font.clone_with_font_size(size),
h_kern_subtable: None,
can_do_fast_shaping: false,
};
handle.h_kern_subtable = handle.find_h_kern_subtable();
// TODO (#11310): Implement basic support for GPOS and GSUB.
handle.can_do_fast_shaping = handle.h_kern_subtable.is_some() &&
handle.table_for_tag(GPOS).is_none() &&
handle.table_for_tag(GSUB).is_none();
Ok(handle)
}
fn template(&self) -> Arc<FontTemplateData> {
self.font_data.clone()
fn template(&self) -> FontTemplateRef {
self.font_template.clone()
}
fn family_name(&self) -> Option<String> {
@ -317,8 +315,4 @@ impl FontHandleMethods for FontHandle {
let result: Option<CFData> = self.ctfont.get_font_table(tag);
result.map(FontTable::wrap)
}
fn identifier(&self) -> &FontIdentifier {
&self.font_data.identifier
}
}