mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #17211 - Manishearth:stylo-single-generic, r=heycam
stylo: Prefill default font when a single generic is set r=heycam https://bugzilla.mozilla.org/show_bug.cgi?id=1370734 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17211) <!-- Reviewable:end -->
This commit is contained in:
commit
eaefcbe551
4 changed files with 113 additions and 35 deletions
|
@ -1346,6 +1346,12 @@ extern "C" {
|
||||||
pres_context:
|
pres_context:
|
||||||
RawGeckoPresContextBorrowed);
|
RawGeckoPresContextBorrowed);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleFont_PrefillDefaultForGeneric(font: *mut nsStyleFont,
|
||||||
|
pres_context:
|
||||||
|
RawGeckoPresContextBorrowed,
|
||||||
|
generic_id: u8);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_nsStyleFont_FixupMinFontSize(font: *mut nsStyleFont,
|
pub fn Gecko_nsStyleFont_FixupMinFontSize(font: *mut nsStyleFont,
|
||||||
pres_context:
|
pres_context:
|
||||||
|
|
|
@ -221,6 +221,9 @@ impl ${style_struct.gecko_struct_name} {
|
||||||
pub fn gecko(&self) -> &${style_struct.gecko_ffi_name} {
|
pub fn gecko(&self) -> &${style_struct.gecko_ffi_name} {
|
||||||
&self.gecko
|
&self.gecko
|
||||||
}
|
}
|
||||||
|
pub fn gecko_mut(&mut self) -> &mut ${style_struct.gecko_ffi_name} {
|
||||||
|
&mut self.gecko
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
@ -1587,7 +1590,6 @@ fn static_assert() {
|
||||||
|
|
||||||
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
|
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
|
||||||
use properties::longhands::font_family::computed_value::FontFamily;
|
use properties::longhands::font_family::computed_value::FontFamily;
|
||||||
use gecko_bindings::structs::FontFamilyType;
|
|
||||||
|
|
||||||
let list = &mut self.gecko.mFont.fontlist;
|
let list = &mut self.gecko.mFont.fontlist;
|
||||||
unsafe { Gecko_FontFamilyList_Clear(list); }
|
unsafe { Gecko_FontFamilyList_Clear(list); }
|
||||||
|
@ -1600,28 +1602,7 @@ fn static_assert() {
|
||||||
unsafe { Gecko_FontFamilyList_AppendNamed(list, f.name.as_ptr(), f.quoted); }
|
unsafe { Gecko_FontFamilyList_AppendNamed(list, f.name.as_ptr(), f.quoted); }
|
||||||
}
|
}
|
||||||
FontFamily::Generic(ref name) => {
|
FontFamily::Generic(ref name) => {
|
||||||
let (family_type, generic) =
|
let (family_type, generic) = FontFamily::generic(name);
|
||||||
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")
|
|
||||||
};
|
|
||||||
if v.0.len() == 1 {
|
if v.0.len() == 1 {
|
||||||
self.gecko.mGenericID = generic;
|
self.gecko.mGenericID = generic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,6 +191,33 @@
|
||||||
quoted: false,
|
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 {
|
impl ToCss for FamilyName {
|
||||||
|
@ -260,6 +287,21 @@
|
||||||
System(SystemFont),
|
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 {
|
impl ToComputedValue for SpecifiedValue {
|
||||||
type ComputedValue = computed_value::T;
|
type ComputedValue = computed_value::T;
|
||||||
fn to_computed_value(&self, _cx: &Context) -> Self::ComputedValue {
|
fn to_computed_value(&self, _cx: &Context) -> Self::ComputedValue {
|
||||||
|
|
|
@ -2732,6 +2732,52 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
|
||||||
let writing_mode = get_writing_mode(context.style.get_inheritedbox());
|
let writing_mode = get_writing_mode(context.style.get_inheritedbox());
|
||||||
context.style.writing_mode = writing_mode;
|
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
|
// It is important that font_size is computed before
|
||||||
// the late properties (for em units), but after font-family
|
// the late properties (for em units), but after font-family
|
||||||
// (for the base-font-size dependence for default and keyword font-sizes)
|
// (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
|
// To avoid an extra iteration, we just pull out the property
|
||||||
// during the early iteration and cascade them in order
|
// during the early iteration and cascade them in order
|
||||||
// after it.
|
// after it.
|
||||||
if let Some(declaration) = font_family {
|
if !_skip_font_family {
|
||||||
let discriminant = LonghandId::FontFamily as usize;
|
if let Some(declaration) = font_family {
|
||||||
(CASCADE_PROPERTY[discriminant])(declaration,
|
|
||||||
inherited_style,
|
let discriminant = LonghandId::FontFamily as usize;
|
||||||
default_style,
|
(CASCADE_PROPERTY[discriminant])(declaration,
|
||||||
&mut context,
|
inherited_style,
|
||||||
&mut cacheable,
|
default_style,
|
||||||
&mut cascade_info,
|
&mut context,
|
||||||
error_reporter);
|
&mut cacheable,
|
||||||
% if product == "gecko":
|
&mut cascade_info,
|
||||||
context.style.mutate_font().fixup_none_generic(context.device);
|
error_reporter);
|
||||||
% endif
|
% if product == "gecko":
|
||||||
|
context.style.mutate_font().fixup_none_generic(context.device);
|
||||||
|
% endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(declaration) = font_size {
|
if let Some(declaration) = font_size {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue