aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko/generated/bindings.rs6
-rw-r--r--components/style/properties/gecko.mako.rs27
-rw-r--r--components/style/properties/longhand/font.mako.rs42
-rw-r--r--components/style/properties/properties.mako.rs73
4 files changed, 113 insertions, 35 deletions
diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs
index 3eed899e538..f12de6938cf 100644
--- a/components/style/gecko/generated/bindings.rs
+++ b/components/style/gecko/generated/bindings.rs
@@ -1347,6 +1347,12 @@ extern "C" {
RawGeckoPresContextBorrowed);
}
extern "C" {
+ pub fn Gecko_nsStyleFont_PrefillDefaultForGeneric(font: *mut nsStyleFont,
+ pres_context:
+ RawGeckoPresContextBorrowed,
+ generic_id: u8);
+}
+extern "C" {
pub fn Gecko_nsStyleFont_FixupMinFontSize(font: *mut nsStyleFont,
pres_context:
RawGeckoPresContextBorrowed);
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index efefebcfe16..3c0b57c9fe0 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -221,6 +221,9 @@ impl ${style_struct.gecko_struct_name} {
pub fn gecko(&self) -> &${style_struct.gecko_ffi_name} {
&self.gecko
}
+ pub fn gecko_mut(&mut self) -> &mut ${style_struct.gecko_ffi_name} {
+ &mut self.gecko
+ }
}
</%def>
@@ -1587,7 +1590,6 @@ fn static_assert() {
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
use properties::longhands::font_family::computed_value::FontFamily;
- use gecko_bindings::structs::FontFamilyType;
let list = &mut self.gecko.mFont.fontlist;
unsafe { Gecko_FontFamilyList_Clear(list); }
@@ -1600,28 +1602,7 @@ fn static_assert() {
unsafe { Gecko_FontFamilyList_AppendNamed(list, f.name.as_ptr(), f.quoted); }
}
FontFamily::Generic(ref name) => {
- let (family_type, generic) =
- if name == &atom!("serif") {
- (FontFamilyType::eFamily_serif,
- structs::kGenericFont_serif)
- } else if name == &atom!("sans-serif") {
- (FontFamilyType::eFamily_sans_serif,
- structs::kGenericFont_sans_serif)
- } else if name == &atom!("cursive") {
- (FontFamilyType::eFamily_cursive,
- structs::kGenericFont_cursive)
- } else if name == &atom!("fantasy") {
- (FontFamilyType::eFamily_fantasy,
- structs::kGenericFont_fantasy)
- } else if name == &atom!("monospace") {
- (FontFamilyType::eFamily_monospace,
- structs::kGenericFont_monospace)
- } else if name == &atom!("-moz-fixed") {
- (FontFamilyType::eFamily_moz_fixed,
- structs::kGenericFont_moz_fixed)
- } else {
- panic!("Unknown generic font family")
- };
+ let (family_type, generic) = FontFamily::generic(name);
if v.0.len() == 1 {
self.gecko.mGenericID = generic;
}
diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs
index 51963a7dbb0..825577b1e60 100644
--- a/components/style/properties/longhand/font.mako.rs
+++ b/components/style/properties/longhand/font.mako.rs
@@ -191,6 +191,33 @@
quoted: false,
}))
}
+
+ #[cfg(feature = "gecko")]
+ /// Return the generic ID for a given generic font name
+ pub fn generic(name: &Atom) -> (::gecko_bindings::structs::FontFamilyType, u8) {
+ use gecko_bindings::structs::{self, FontFamilyType};
+ if *name == atom!("serif") {
+ (FontFamilyType::eFamily_serif,
+ structs::kGenericFont_serif)
+ } else if *name == atom!("sans-serif") {
+ (FontFamilyType::eFamily_sans_serif,
+ structs::kGenericFont_sans_serif)
+ } else if *name == atom!("cursive") {
+ (FontFamilyType::eFamily_cursive,
+ structs::kGenericFont_cursive)
+ } else if *name == atom!("fantasy") {
+ (FontFamilyType::eFamily_fantasy,
+ structs::kGenericFont_fantasy)
+ } else if *name == atom!("monospace") {
+ (FontFamilyType::eFamily_monospace,
+ structs::kGenericFont_monospace)
+ } else if *name == atom!("-moz-fixed") {
+ (FontFamilyType::eFamily_moz_fixed,
+ structs::kGenericFont_moz_fixed)
+ } else {
+ panic!("Unknown generic {}", name);
+ }
+ }
}
impl ToCss for FamilyName {
@@ -260,6 +287,21 @@
System(SystemFont),
}
+ #[cfg(feature = "gecko")]
+ impl SpecifiedValue {
+ /// Return the generic ID if it is a single generic font
+ pub fn single_generic(&self) -> Option<u8> {
+ if let SpecifiedValue::Values(ref values) = *self {
+ if values.len() == 1 {
+ if let FontFamily::Generic(ref name) = values[0] {
+ return Some(FontFamily::generic(name).1);
+ }
+ }
+ }
+ None
+ }
+ }
+
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
fn to_computed_value(&self, _cx: &Context) -> Self::ComputedValue {
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index 1a4af56d9cc..a0264d41e8c 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -2732,6 +2732,52 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
let writing_mode = get_writing_mode(context.style.get_inheritedbox());
context.style.writing_mode = writing_mode;
+ let mut _skip_font_family = false;
+
+ % if product == "gecko":
+ // Whenever a single generic value is specified, gecko will do a bunch of
+ // recalculation walking up the rule tree, including handling the font-size stuff.
+ // It basically repopulates the font struct with the default font for a given
+ // generic and language. We handle the font-size stuff separately, so this boils
+ // down to just copying over the font-family lists (no other aspect of the default
+ // font can be configured).
+
+ if seen.contains(LonghandId::XLang) || font_family.is_some() {
+ // if just the language changed, the inherited generic is all we need
+ let mut generic = inherited_style.get_font().gecko().mGenericID;
+ if let Some(declaration) = font_family {
+ if let PropertyDeclaration::FontFamily(ref fam) = *declaration {
+ if let Some(id) = fam.single_generic() {
+ generic = id;
+ // In case of a specified font family with a single generic, we will
+ // end up setting font family below, but its value would get
+ // overwritten later in the pipeline when cascading.
+ //
+ // We instead skip cascading font-family in that case.
+ //
+ // In case of the language changing, we wish for a specified font-
+ // family to override this, so we do not skip cascading then.
+ _skip_font_family = true;
+ }
+ }
+ }
+
+ // In case of just the language changing, the parent could have had no generic,
+ // which Gecko just does regular cascading with. Do the same.
+ // This can only happen in the case where the language changed but the family did not
+ if generic != structs::kGenericFont_NONE {
+ let pres_context = context.device.pres_context;
+ let gecko_font = context.mutate_style().mutate_font().gecko_mut();
+ gecko_font.mGenericID = generic;
+ unsafe {
+ bindings::Gecko_nsStyleFont_PrefillDefaultForGeneric(gecko_font,
+ &*pres_context,
+ generic);
+ }
+ }
+ }
+ % endif
+
// It is important that font_size is computed before
// the late properties (for em units), but after font-family
// (for the base-font-size dependence for default and keyword font-sizes)
@@ -2743,18 +2789,21 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
// To avoid an extra iteration, we just pull out the property
// during the early iteration and cascade them in order
// after it.
- if let Some(declaration) = font_family {
- let discriminant = LonghandId::FontFamily as usize;
- (CASCADE_PROPERTY[discriminant])(declaration,
- inherited_style,
- default_style,
- &mut context,
- &mut cacheable,
- &mut cascade_info,
- error_reporter);
- % if product == "gecko":
- context.style.mutate_font().fixup_none_generic(context.device);
- % endif
+ if !_skip_font_family {
+ if let Some(declaration) = font_family {
+
+ let discriminant = LonghandId::FontFamily as usize;
+ (CASCADE_PROPERTY[discriminant])(declaration,
+ inherited_style,
+ default_style,
+ &mut context,
+ &mut cacheable,
+ &mut cascade_info,
+ error_reporter);
+ % if product == "gecko":
+ context.style.mutate_font().fixup_none_generic(context.device);
+ % endif
+ }
}
if let Some(declaration) = font_size {