mirror of
https://github.com/servo/servo.git
synced 2025-08-24 14:48:21 +01:00
fonts: Have CoreTextFontCache::core_text_font
return a PlatformFont
(#38758)
This will make it easier in a followup to include the normalized font variations in the return value. This also make `PlatformFont::ensure_h_kern_subtable` work on the instance instead of being a struct method. Finally, all `PlatformFont` methods are combined into a single impl block. Testing: This should not change behavior and is thus covered by existing tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
6fdf40dce7
commit
5c885d61ad
2 changed files with 45 additions and 36 deletions
|
@ -17,6 +17,7 @@ use core_text::font_descriptor::kCTFontURLAttribute;
|
|||
use parking_lot::RwLock;
|
||||
|
||||
use crate::FontData;
|
||||
use crate::platform::font::PlatformFont;
|
||||
use crate::system_font_service::FontIdentifier;
|
||||
|
||||
/// A cache of `CTFont` to avoid having to create `CTFont` instances over and over. It is
|
||||
|
@ -36,7 +37,7 @@ impl CoreTextFontCache {
|
|||
font_identifier: FontIdentifier,
|
||||
data: Option<&FontData>,
|
||||
pt_size: f64,
|
||||
) -> Option<CTFont> {
|
||||
) -> Option<PlatformFont> {
|
||||
//// If you pass a zero font size to one of the Core Text APIs, it'll replace it with
|
||||
//// 12.0. We don't want that! (Issue #10492.)
|
||||
let clamped_pt_size = pt_size.max(0.01);
|
||||
|
@ -49,7 +50,7 @@ impl CoreTextFontCache {
|
|||
.get(&font_identifier)
|
||||
.and_then(|identifier_cache| identifier_cache.get(&au_size))
|
||||
{
|
||||
return Some(core_text_font.clone());
|
||||
return Some(PlatformFont::new_with_ctfont(core_text_font.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +61,7 @@ impl CoreTextFontCache {
|
|||
// on the cache has been acquired, the cache was populated with the data that we need. Thus
|
||||
// check again and return the CTFont if it is is already cached.
|
||||
if let Some(core_text_font) = identifier_cache.get(&au_size) {
|
||||
return Some(core_text_font.clone());
|
||||
return Some(PlatformFont::new_with_ctfont(core_text_font.clone()));
|
||||
}
|
||||
|
||||
let core_text_font = match font_identifier {
|
||||
|
@ -98,6 +99,6 @@ impl CoreTextFontCache {
|
|||
};
|
||||
|
||||
identifier_cache.insert(au_size, core_text_font.clone());
|
||||
Some(core_text_font)
|
||||
Some(PlatformFont::new_with_ctfont(core_text_font))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,10 +70,43 @@ unsafe impl Sync for PlatformFont {}
|
|||
unsafe impl Send for PlatformFont {}
|
||||
|
||||
impl PlatformFont {
|
||||
pub(crate) fn new_with_ctfont(ctfont: CTFont) -> Self {
|
||||
Self {
|
||||
ctfont,
|
||||
h_kern_subtable: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn new(
|
||||
font_identifier: FontIdentifier,
|
||||
data: Option<&FontData>,
|
||||
requested_size: Option<Au>,
|
||||
) -> Result<PlatformFont, &'static str> {
|
||||
let size = match requested_size {
|
||||
Some(s) => s.to_f64_px(),
|
||||
None => 0.0,
|
||||
};
|
||||
let Some(mut platform_font) =
|
||||
CoreTextFontCache::core_text_font(font_identifier, data, size)
|
||||
else {
|
||||
return Err("Could not generate CTFont for FontTemplateData");
|
||||
};
|
||||
|
||||
platform_font.load_h_kern_subtable();
|
||||
Ok(platform_font)
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
let font_table = self.table_for_tag(KERN)?;
|
||||
fn load_h_kern_subtable(&mut self) {
|
||||
if self.h_kern_subtable.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(font_table) = self.table_for_tag(KERN) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut result = CachedKernTable {
|
||||
font_table,
|
||||
pair_data_range: 0..0,
|
||||
|
@ -89,7 +122,7 @@ impl PlatformFont {
|
|||
let table = result.font_table.buffer();
|
||||
let version = BigEndian::read_u16(table);
|
||||
if version != 0 {
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
let num_subtables = BigEndian::read_u16(&table[2..]);
|
||||
let mut start = 4;
|
||||
|
@ -102,7 +135,7 @@ impl PlatformFont {
|
|||
// Found a matching subtable.
|
||||
if !result.pair_data_range.is_empty() {
|
||||
debug!("Found multiple horizontal kern tables. Disable fast path.");
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
// Read the subtable header.
|
||||
let subtable_start = start + SUBTABLE_HEADER_LEN;
|
||||
|
@ -112,7 +145,7 @@ impl PlatformFont {
|
|||
result.pair_data_range = pair_data_start..end;
|
||||
if result.pair_data_range.len() != n_pairs * KERN_PAIR_LEN {
|
||||
debug!("Bad data in kern header. Disable fast path.");
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
|
||||
let pt_per_font_unit =
|
||||
|
@ -122,10 +155,9 @@ impl PlatformFont {
|
|||
start = end;
|
||||
}
|
||||
}
|
||||
|
||||
if !result.pair_data_range.is_empty() {
|
||||
Some(result)
|
||||
} else {
|
||||
None
|
||||
self.h_kern_subtable = Some(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,30 +196,6 @@ impl fmt::Debug for CachedKernTable {
|
|||
}
|
||||
}
|
||||
|
||||
impl PlatformFont {
|
||||
fn new(
|
||||
font_identifier: FontIdentifier,
|
||||
data: Option<&FontData>,
|
||||
requested_size: Option<Au>,
|
||||
) -> Result<PlatformFont, &'static str> {
|
||||
let size = match requested_size {
|
||||
Some(s) => s.to_f64_px(),
|
||||
None => 0.0,
|
||||
};
|
||||
let Some(core_text_font) = CoreTextFontCache::core_text_font(font_identifier, data, size)
|
||||
else {
|
||||
return Err("Could not generate CTFont for FontTemplateData");
|
||||
};
|
||||
|
||||
let mut handle = PlatformFont {
|
||||
ctfont: core_text_font.clone_with_font_size(size),
|
||||
h_kern_subtable: None,
|
||||
};
|
||||
handle.h_kern_subtable = handle.find_h_kern_subtable();
|
||||
Ok(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformFontMethods for PlatformFont {
|
||||
fn new_from_data(
|
||||
font_identifier: FontIdentifier,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue