mirror of
https://github.com/servo/servo.git
synced 2025-08-26 23:58:20 +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 parking_lot::RwLock;
|
||||||
|
|
||||||
use crate::FontData;
|
use crate::FontData;
|
||||||
|
use crate::platform::font::PlatformFont;
|
||||||
use crate::system_font_service::FontIdentifier;
|
use crate::system_font_service::FontIdentifier;
|
||||||
|
|
||||||
/// A cache of `CTFont` to avoid having to create `CTFont` instances over and over. It is
|
/// 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,
|
font_identifier: FontIdentifier,
|
||||||
data: Option<&FontData>,
|
data: Option<&FontData>,
|
||||||
pt_size: f64,
|
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
|
//// 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.)
|
//// 12.0. We don't want that! (Issue #10492.)
|
||||||
let clamped_pt_size = pt_size.max(0.01);
|
let clamped_pt_size = pt_size.max(0.01);
|
||||||
|
@ -49,7 +50,7 @@ impl CoreTextFontCache {
|
||||||
.get(&font_identifier)
|
.get(&font_identifier)
|
||||||
.and_then(|identifier_cache| identifier_cache.get(&au_size))
|
.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
|
// 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.
|
// check again and return the CTFont if it is is already cached.
|
||||||
if let Some(core_text_font) = identifier_cache.get(&au_size) {
|
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 {
|
let core_text_font = match font_identifier {
|
||||||
|
@ -98,6 +99,6 @@ impl CoreTextFontCache {
|
||||||
};
|
};
|
||||||
|
|
||||||
identifier_cache.insert(au_size, core_text_font.clone());
|
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 {}
|
unsafe impl Send for PlatformFont {}
|
||||||
|
|
||||||
impl 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
|
/// 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.
|
/// 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> {
|
fn load_h_kern_subtable(&mut self) {
|
||||||
let font_table = self.table_for_tag(KERN)?;
|
if self.h_kern_subtable.is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Some(font_table) = self.table_for_tag(KERN) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
let mut result = CachedKernTable {
|
let mut result = CachedKernTable {
|
||||||
font_table,
|
font_table,
|
||||||
pair_data_range: 0..0,
|
pair_data_range: 0..0,
|
||||||
|
@ -89,7 +122,7 @@ impl PlatformFont {
|
||||||
let table = result.font_table.buffer();
|
let table = result.font_table.buffer();
|
||||||
let version = BigEndian::read_u16(table);
|
let version = BigEndian::read_u16(table);
|
||||||
if version != 0 {
|
if version != 0 {
|
||||||
return None;
|
return;
|
||||||
}
|
}
|
||||||
let num_subtables = BigEndian::read_u16(&table[2..]);
|
let num_subtables = BigEndian::read_u16(&table[2..]);
|
||||||
let mut start = 4;
|
let mut start = 4;
|
||||||
|
@ -102,7 +135,7 @@ impl PlatformFont {
|
||||||
// Found a matching subtable.
|
// Found a matching subtable.
|
||||||
if !result.pair_data_range.is_empty() {
|
if !result.pair_data_range.is_empty() {
|
||||||
debug!("Found multiple horizontal kern tables. Disable fast path.");
|
debug!("Found multiple horizontal kern tables. Disable fast path.");
|
||||||
return None;
|
return;
|
||||||
}
|
}
|
||||||
// Read the subtable header.
|
// Read the subtable header.
|
||||||
let subtable_start = start + SUBTABLE_HEADER_LEN;
|
let subtable_start = start + SUBTABLE_HEADER_LEN;
|
||||||
|
@ -112,7 +145,7 @@ impl PlatformFont {
|
||||||
result.pair_data_range = pair_data_start..end;
|
result.pair_data_range = pair_data_start..end;
|
||||||
if result.pair_data_range.len() != n_pairs * KERN_PAIR_LEN {
|
if result.pair_data_range.len() != n_pairs * KERN_PAIR_LEN {
|
||||||
debug!("Bad data in kern header. Disable fast path.");
|
debug!("Bad data in kern header. Disable fast path.");
|
||||||
return None;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pt_per_font_unit =
|
let pt_per_font_unit =
|
||||||
|
@ -122,10 +155,9 @@ impl PlatformFont {
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !result.pair_data_range.is_empty() {
|
if !result.pair_data_range.is_empty() {
|
||||||
Some(result)
|
self.h_kern_subtable = Some(result);
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
impl PlatformFontMethods for PlatformFont {
|
||||||
fn new_from_data(
|
fn new_from_data(
|
||||||
font_identifier: FontIdentifier,
|
font_identifier: FontIdentifier,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue