Skip to content
Permalink
Browse files

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
  • Loading branch information...
heycam authored and emilio committed Mar 30, 2019
1 parent 91586ee commit b6b5ddda71b475e4edb474982ad3b2d5df380fe4
@@ -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,
}

0 comments on commit b6b5ddd

Please sign in to comment.
You can’t perform that action at this time.