diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 7c5f4a94c01..5af9f5be7c6 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -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 { diff --git a/components/style/properties/longhands/font.mako.rs b/components/style/properties/longhands/font.mako.rs index 88369ab9f21..466a4471608 100644 --- a/components/style/properties/longhands/font.mako.rs +++ b/components/style/properties/longhands/font.mako.rs @@ -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 { diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index c78eb9df2e3..8e51072d9a7 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -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); +pub enum FontFamilyList { + /// A strong reference to a Gecko SharedFontList object. + SharedFontList(RefPtr), + /// 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 { 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 { 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 { + 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, + &RefPtr, + >(&structs::SharedFontList_sSingleGenerics[index]) + } + }, + } + } } -#[cfg(feature = "gecko")] /// Iterator of FontFamily +#[cfg(feature = "gecko")] pub struct FontFamilyNameIter<'a> { names: &'a structs::nsTArray, 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 diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index 6c92acbf1b9..baae46aed2f 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -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, }