mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
style: Allow references to static, single-generic C++ SharedFontList objects from Rust FontFamilyList.
UA style sheets only ever specify a single generic font family in font-family properties, so we pre-create a unique, static SharedFontList for each generic and change the representation of FontFamilyList to be able to refer to them by their generic ID. This avoids having to share refcounted SharedFontList objects across processes. Differential Revision: https://phabricator.services.mozilla.com/D17183
This commit is contained in:
parent
91586eea0e
commit
b6b5ddda71
4 changed files with 59 additions and 23 deletions
|
@ -1993,7 +1993,9 @@ fn static_assert() {
|
|||
} else {
|
||||
v.families.single_generic().unwrap_or(structs::kGenericFont_NONE)
|
||||
};
|
||||
self.gecko.mFont.fontlist.mFontlist.mBasePtr.set_move(v.families.0.clone());
|
||||
self.gecko.mFont.fontlist.mFontlist.mBasePtr.set_move(
|
||||
v.families.shared_font_list().clone()
|
||||
);
|
||||
// Fixed-up if needed in Cascade::fixup_font_stuff.
|
||||
self.gecko.mFont.fontlist.mDefaultFontType = FontFamilyType::eFamily_none;
|
||||
}
|
||||
|
@ -2038,7 +2040,7 @@ fn static_assert() {
|
|||
};
|
||||
FontFamilyList::new(Box::new([default]))
|
||||
} else {
|
||||
FontFamilyList(shared_fontlist)
|
||||
FontFamilyList::SharedFontList(shared_fontlist)
|
||||
};
|
||||
|
||||
FontFamily {
|
||||
|
|
|
@ -406,9 +406,9 @@ ${helpers.predefined_type(
|
|||
let font_style = FontStyle::from_gecko(system.style);
|
||||
let ret = ComputedSystemFont {
|
||||
font_family: FontFamily {
|
||||
families: FontFamilyList(unsafe {
|
||||
system.fontlist.mFontlist.mBasePtr.to_safe()
|
||||
}),
|
||||
families: FontFamilyList::SharedFontList(
|
||||
unsafe { system.fontlist.mFontlist.mBasePtr.to_safe() }
|
||||
),
|
||||
is_system_font: true,
|
||||
},
|
||||
font_size: FontSize {
|
||||
|
|
|
@ -24,6 +24,8 @@ use cssparser::{serialize_identifier, CssStringWriter, Parser};
|
|||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
use std::fmt::{self, Write};
|
||||
use std::hash::{Hash, Hasher};
|
||||
#[cfg(feature = "gecko")]
|
||||
use std::mem;
|
||||
#[cfg(feature = "servo")]
|
||||
use std::slice;
|
||||
use style_traits::{CssWriter, ParseError, ToCss};
|
||||
|
@ -202,9 +204,8 @@ impl MallocSizeOf for FontFamily {
|
|||
// SharedFontList objects are generally shared from the pointer
|
||||
// stored in the specified value. So only count this if the
|
||||
// SharedFontList is unshared.
|
||||
unsafe {
|
||||
bindings::Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(self.families.0.get())
|
||||
}
|
||||
let shared_font_list = self.families.shared_font_list().get();
|
||||
unsafe { bindings::Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(shared_font_list) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,7 +501,12 @@ pub struct FontFamilyList(Box<[SingleFontFamily]>);
|
|||
#[cfg(feature = "gecko")]
|
||||
#[derive(Clone, Debug)]
|
||||
/// A list of SingleFontFamily
|
||||
pub struct FontFamilyList(pub RefPtr<structs::SharedFontList>);
|
||||
pub enum FontFamilyList {
|
||||
/// A strong reference to a Gecko SharedFontList object.
|
||||
SharedFontList(RefPtr<structs::SharedFontList>),
|
||||
/// A font-family generic ID.
|
||||
Generic(structs::FontFamilyType),
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl Hash for FontFamilyList {
|
||||
|
@ -510,7 +516,7 @@ impl Hash for FontFamilyList {
|
|||
{
|
||||
use crate::string_cache::WeakAtom;
|
||||
|
||||
for name in self.0.mNames.iter() {
|
||||
for name in self.shared_font_list().mNames.iter() {
|
||||
name.mType.hash(state);
|
||||
if !name.mName.mRawPtr.is_null() {
|
||||
unsafe {
|
||||
|
@ -524,10 +530,13 @@ impl Hash for FontFamilyList {
|
|||
#[cfg(feature = "gecko")]
|
||||
impl PartialEq for FontFamilyList {
|
||||
fn eq(&self, other: &FontFamilyList) -> bool {
|
||||
if self.0.mNames.len() != other.0.mNames.len() {
|
||||
let self_list = self.shared_font_list();
|
||||
let other_list = other.shared_font_list();
|
||||
|
||||
if self_list.mNames.len() != other_list.mNames.len() {
|
||||
return false;
|
||||
}
|
||||
for (a, b) in self.0.mNames.iter().zip(other.0.mNames.iter()) {
|
||||
for (a, b) in self_list.mNames.iter().zip(other_list.mNames.iter()) {
|
||||
if a.mType != b.mType || a.mName.mRawPtr != b.mName.mRawPtr {
|
||||
return false;
|
||||
}
|
||||
|
@ -540,14 +549,14 @@ impl PartialEq for FontFamilyList {
|
|||
impl Eq for FontFamilyList {}
|
||||
|
||||
impl FontFamilyList {
|
||||
#[cfg(feature = "servo")]
|
||||
/// Return FontFamilyList with a vector of SingleFontFamily
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn new(families: Box<[SingleFontFamily]>) -> FontFamilyList {
|
||||
FontFamilyList(families)
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
/// Return FontFamilyList with a vector of SingleFontFamily
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn new(families: Box<[SingleFontFamily]>) -> FontFamilyList {
|
||||
let fontlist;
|
||||
let names;
|
||||
|
@ -578,26 +587,26 @@ impl FontFamilyList {
|
|||
}
|
||||
}
|
||||
|
||||
FontFamilyList(unsafe { RefPtr::from_addrefed(fontlist) })
|
||||
FontFamilyList::SharedFontList(unsafe { RefPtr::from_addrefed(fontlist) })
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
/// Return iterator of SingleFontFamily
|
||||
#[cfg(feature = "servo")]
|
||||
pub fn iter(&self) -> slice::Iter<SingleFontFamily> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
/// Return iterator of SingleFontFamily
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn iter(&self) -> FontFamilyNameIter {
|
||||
FontFamilyNameIter {
|
||||
names: &self.0.mNames,
|
||||
names: &self.shared_font_list().mNames,
|
||||
cur: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
/// Return the generic ID if it is a single generic font
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn single_generic(&self) -> Option<u8> {
|
||||
let mut iter = self.iter();
|
||||
if let Some(SingleFontFamily::Generic(ref name)) = iter.next() {
|
||||
|
@ -607,10 +616,29 @@ impl FontFamilyList {
|
|||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Return a reference to the Gecko SharedFontList.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn shared_font_list(&self) -> &RefPtr<structs::SharedFontList> {
|
||||
match self {
|
||||
FontFamilyList::SharedFontList(r) => r,
|
||||
FontFamilyList::Generic(t) => {
|
||||
unsafe {
|
||||
// TODO(heycam): Should really add StaticRefPtr sugar.
|
||||
let index =
|
||||
(*t as usize) - (structs::FontFamilyType::eFamily_generic_first as usize);
|
||||
mem::transmute::<
|
||||
&structs::StaticRefPtr<structs::SharedFontList>,
|
||||
&RefPtr<structs::SharedFontList>,
|
||||
>(&structs::SharedFontList_sSingleGenerics[index])
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
/// Iterator of FontFamily
|
||||
#[cfg(feature = "gecko")]
|
||||
pub struct FontFamilyNameIter<'a> {
|
||||
names: &'a structs::nsTArray<structs::FontFamilyName>,
|
||||
cur: usize,
|
||||
|
@ -631,8 +659,8 @@ impl<'a> Iterator for FontFamilyNameIter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
/// Preserve the readability of text when font fallback occurs
|
||||
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
|
||||
pub enum FontSizeAdjust {
|
||||
#[animation(error)]
|
||||
/// None variant
|
||||
|
|
|
@ -567,8 +567,14 @@ impl MallocSizeOf for FontFamily {
|
|||
match *self {
|
||||
FontFamily::Values(ref v) => {
|
||||
// Although a SharedFontList object is refcounted, we always
|
||||
// attribute its size to the specified value.
|
||||
unsafe { bindings::Gecko_SharedFontList_SizeOfIncludingThis(v.0.get()) }
|
||||
// attribute its size to the specified value, as long as it's
|
||||
// not a value in SharedFontList::sSingleGenerics.
|
||||
if matches!(v, FontFamilyList::SharedFontList(_)) {
|
||||
let ptr = v.shared_font_list().get();
|
||||
unsafe { bindings::Gecko_SharedFontList_SizeOfIncludingThis(ptr) }
|
||||
} else {
|
||||
0
|
||||
}
|
||||
},
|
||||
FontFamily::System(_) => 0,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue