mirror of
https://github.com/servo/servo.git
synced 2025-08-14 01:45:33 +01:00
fonts: Use IpcSharedMemory
to send font data (#33530)
This changes modifes the way that font data is sent over IPC channels. Instead of serializing the data or sending it via IPC byte senders, font data is copied into shared memory and a copy of the handle is sent over the channel. There is also the idea of sending the file handle of the on disk data of system fonts. This could be implemented as a further followup once there is an abstraction in `ipc-channel` over file handles. To accomplish this, a `FontData` abstraction is added, which also allows caching an in-memory shared `Arc<Vec<u8>>` version of the data (neeeded by some APIs). This could also be a place for caching font tables in the future. Finally, the `FontCacheThread` is renamed to the `SystemFontService` while the proxy for this is now named `SystemFontServiceProxy`. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
parent
2c6d9a190f
commit
ade902207f
26 changed files with 601 additions and 544 deletions
|
@ -15,12 +15,11 @@ use style::computed_values::font_style::T as FontStyle;
|
|||
use style::stylesheets::DocumentStyleSheet;
|
||||
use style::values::computed::font::FontWeight;
|
||||
|
||||
use crate::font::{FontDescriptor, PlatformFontMethods};
|
||||
use crate::font_cache_thread::{
|
||||
use crate::font::FontDescriptor;
|
||||
use crate::platform::font_list::LocalFontIdentifier;
|
||||
use crate::system_font_service::{
|
||||
CSSFontFaceDescriptors, ComputedFontStyleDescriptor, FontIdentifier,
|
||||
};
|
||||
use crate::platform::font::PlatformFont;
|
||||
use crate::platform::font_list::LocalFontIdentifier;
|
||||
|
||||
/// A reference to a [`FontTemplate`] with shared ownership and mutability.
|
||||
pub type FontTemplateRef = Arc<AtomicRefCell<FontTemplate>>;
|
||||
|
@ -109,7 +108,7 @@ impl FontTemplateDescriptor {
|
|||
self.stretch.1 >= descriptor_to_match.stretch
|
||||
}
|
||||
|
||||
fn override_values_with_css_font_template_descriptors(
|
||||
pub(crate) fn override_values_with_css_font_template_descriptors(
|
||||
&mut self,
|
||||
css_font_template_descriptors: &CSSFontFaceDescriptors,
|
||||
) {
|
||||
|
@ -137,27 +136,20 @@ impl FontTemplateDescriptor {
|
|||
/// This describes all the information needed to create
|
||||
/// font instance handles. It contains a unique
|
||||
/// FontTemplateData structure that is platform specific.
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||
pub struct FontTemplate {
|
||||
pub identifier: FontIdentifier,
|
||||
pub descriptor: FontTemplateDescriptor,
|
||||
/// The data to use for this [`FontTemplate`]. For web fonts, this is always filled, but
|
||||
/// for local fonts, this is loaded only lazily in layout.
|
||||
pub data: Option<Arc<Vec<u8>>>,
|
||||
/// If this font is a web font, this is a reference to the stylesheet that
|
||||
/// created it. This will be used to remove this font from caches, when the
|
||||
/// stylesheet is removed.
|
||||
///
|
||||
/// This is not serialized, as it's only useful in the [`super::FontContext`]
|
||||
/// that it is created in.
|
||||
#[serde(skip)]
|
||||
pub stylesheet: Option<DocumentStyleSheet>,
|
||||
}
|
||||
|
||||
impl malloc_size_of::MallocSizeOf for FontTemplate {
|
||||
fn size_of(&self, ops: &mut malloc_size_of::MallocSizeOfOps) -> usize {
|
||||
self.identifier.size_of(ops) +
|
||||
self.descriptor.size_of(ops) +
|
||||
self.data.as_ref().map_or(0, |data| (*data).size_of(ops))
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FontTemplate {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
self.identifier.fmt(f)
|
||||
|
@ -176,7 +168,6 @@ impl FontTemplate {
|
|||
FontTemplate {
|
||||
identifier: FontIdentifier::Local(identifier),
|
||||
descriptor,
|
||||
data: None,
|
||||
stylesheet: None,
|
||||
}
|
||||
}
|
||||
|
@ -184,22 +175,12 @@ impl FontTemplate {
|
|||
/// Create a new [`FontTemplate`] for a `@font-family` with a `url(...)` `src` font.
|
||||
pub fn new_for_remote_web_font(
|
||||
url: ServoUrl,
|
||||
data: Arc<Vec<u8>>,
|
||||
css_font_template_descriptors: &CSSFontFaceDescriptors,
|
||||
descriptor: FontTemplateDescriptor,
|
||||
stylesheet: Option<DocumentStyleSheet>,
|
||||
) -> Result<FontTemplate, &'static str> {
|
||||
let identifier = FontIdentifier::Web(url.clone());
|
||||
let Ok(handle) = PlatformFont::new_from_data(identifier, data.clone(), 0, None) else {
|
||||
return Err("Could not initialize platform font data for: {url:?}");
|
||||
};
|
||||
|
||||
let mut descriptor = handle.descriptor();
|
||||
descriptor
|
||||
.override_values_with_css_font_template_descriptors(css_font_template_descriptors);
|
||||
Ok(FontTemplate {
|
||||
identifier: FontIdentifier::Web(url),
|
||||
descriptor,
|
||||
data: Some(data),
|
||||
stylesheet,
|
||||
})
|
||||
}
|
||||
|
@ -223,19 +204,9 @@ impl FontTemplate {
|
|||
pub fn identifier(&self) -> &FontIdentifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
/// Returns a reference to the bytes in this font if they are in memory.
|
||||
/// This function never performs disk I/O.
|
||||
pub fn data_if_in_memory(&self) -> Option<Arc<Vec<u8>>> {
|
||||
self.data.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FontTemplateRefMethods {
|
||||
/// Returns a reference to the data in this font. This may be a hugely expensive
|
||||
/// operation (depending on the platform) which performs synchronous disk I/O
|
||||
/// and should never be done lightly.
|
||||
fn data(&self) -> Arc<Vec<u8>>;
|
||||
/// Get the descriptor.
|
||||
fn descriptor(&self) -> FontTemplateDescriptor;
|
||||
/// Get the [`FontIdentifier`] for this template.
|
||||
|
@ -267,24 +238,6 @@ impl FontTemplateRefMethods for FontTemplateRef {
|
|||
self.descriptor().distance_from(descriptor_to_match)
|
||||
}
|
||||
|
||||
fn data(&self) -> Arc<Vec<u8>> {
|
||||
if let Some(data) = self.borrow().data.clone() {
|
||||
return data;
|
||||
}
|
||||
|
||||
let mut template = self.borrow_mut();
|
||||
let identifier = template.identifier.clone();
|
||||
template
|
||||
.data
|
||||
.get_or_insert_with(|| match identifier {
|
||||
FontIdentifier::Local(local_identifier) => {
|
||||
Arc::new(local_identifier.read_data_from_file())
|
||||
},
|
||||
FontIdentifier::Web(_) => unreachable!("Web fonts should always have data."),
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
|
||||
fn char_in_unicode_range(&self, character: char) -> bool {
|
||||
let character = character as u32;
|
||||
self.borrow()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue