mirror of
https://github.com/servo/servo.git
synced 2025-09-29 16:19:14 +01:00
Fix loading raw data from .ttc
files on macos (#38753)
# Objective Ensure that functionality which uses the raw font data (such as rendering text to canvas) works correctly on macOS when the specified font is a system font that lives in an OpenType Collection (`.ttc`) file. ## Changes made - The `read_data_from_file` in each backend now returns a `index: u32` in addition to `data: Vec<u8>` - The `data` field on the `Font` type has been renamed to `raw` and the `data` method on the `Font` type has been renamed to `raw_font`. This allows the index to be cached as computing is moderately expensive on macOS (on the order of 100 microseconds). - Both of the above now store/return a `struct RawFont` instead of a `FontData` where `RawFont` is defined as `struct RawFont { data: FontData, index: u32 }`. - The users of the `data` method have been updated to use the cached index from `data` rather than calling `.index()` each time. --------- Signed-off-by: Nico Burns <nico@nicoburns.com>
This commit is contained in:
parent
3225d19907
commit
39629560c8
13 changed files with 164 additions and 76 deletions
|
@ -33,8 +33,8 @@ use crate::platform::font::{FontTable, PlatformFont};
|
|||
pub use crate::platform::font_list::fallback_font_families;
|
||||
use crate::{
|
||||
ByteIndex, EmojiPresentationPreference, FallbackFontSelectionOptions, FontContext, FontData,
|
||||
FontIdentifier, FontTemplateDescriptor, FontTemplateRef, FontTemplateRefMethods, GlyphData,
|
||||
GlyphId, GlyphStore, LocalFontIdentifier, Shaper,
|
||||
FontDataAndIndex, FontDataError, FontIdentifier, FontTemplateDescriptor, FontTemplateRef,
|
||||
FontTemplateRefMethods, GlyphData, GlyphId, GlyphStore, LocalFontIdentifier, Shaper,
|
||||
};
|
||||
|
||||
#[macro_export]
|
||||
|
@ -254,8 +254,9 @@ pub struct Font {
|
|||
pub metrics: FontMetrics,
|
||||
pub descriptor: FontDescriptor,
|
||||
|
||||
/// The data for this font. This might be uninitialized for system fonts.
|
||||
data: OnceLock<FontData>,
|
||||
/// The data for this font. And the index of the font within the data (in case it's a TTC)
|
||||
/// This might be uninitialized for system fonts.
|
||||
data_and_index: OnceLock<FontDataAndIndex>,
|
||||
|
||||
shaper: OnceLock<Shaper>,
|
||||
cached_shape_data: RwLock<CachedShapeData>,
|
||||
|
@ -313,7 +314,9 @@ impl Font {
|
|||
template,
|
||||
metrics,
|
||||
descriptor,
|
||||
data: data.map(OnceLock::from).unwrap_or_default(),
|
||||
data_and_index: data
|
||||
.map(|data| OnceLock::from(FontDataAndIndex { data, index: 0 }))
|
||||
.unwrap_or_default(),
|
||||
shaper: OnceLock::new(),
|
||||
cached_shape_data: Default::default(),
|
||||
font_instance_key: Default::default(),
|
||||
|
@ -348,17 +351,20 @@ impl Font {
|
|||
|
||||
/// Return the data for this `Font`. Note that this is currently highly inefficient for system
|
||||
/// fonts and should not be used except in legacy canvas code.
|
||||
pub fn data(&self) -> &FontData {
|
||||
self.data.get_or_init(|| {
|
||||
let FontIdentifier::Local(local_font_identifier) = self.identifier() else {
|
||||
unreachable!("All web fonts should already have initialized data");
|
||||
};
|
||||
FontData::from_bytes(
|
||||
&local_font_identifier
|
||||
.read_data_from_file()
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
})
|
||||
pub fn font_data_and_index(&self) -> Result<&FontDataAndIndex, FontDataError> {
|
||||
if let Some(data_and_index) = self.data_and_index.get() {
|
||||
return Ok(data_and_index);
|
||||
}
|
||||
|
||||
let FontIdentifier::Local(local_font_identifier) = self.identifier() else {
|
||||
unreachable!("All web fonts should already have initialized data");
|
||||
};
|
||||
let Some(data_and_index) = local_font_identifier.font_data_and_index() else {
|
||||
return Err(FontDataError::FailedToLoad);
|
||||
};
|
||||
|
||||
let data_and_index = self.data_and_index.get_or_init(move || data_and_index);
|
||||
Ok(data_and_index)
|
||||
}
|
||||
|
||||
pub fn variations(&self) -> &[FontVariation] {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue