stylo: Calculate font-size keywords based on base size

MozReview-Commit-ID: Ff6kt8RLChI
This commit is contained in:
Manish Goregaokar 2017-03-17 19:48:20 -07:00 committed by Manish Goregaokar
parent 0aceddd47b
commit fddddc9711
7 changed files with 130 additions and 27 deletions

View file

@ -293,6 +293,7 @@ mod bindings {
"BORDER_STYLE_.*", "BORDER_STYLE_.*",
"mozilla::SERVO_PREF_.*", "mozilla::SERVO_PREF_.*",
"kNameSpaceID_.*", "kNameSpaceID_.*",
"kGenericFont_.*",
]; ];
let whitelist = [ let whitelist = [
"RawGecko.*", "RawGecko.*",

View file

@ -1012,6 +1012,12 @@ extern "C" {
pub fn Gecko_nsStyleFont_CopyLangFrom(aFont: *mut nsStyleFont, pub fn Gecko_nsStyleFont_CopyLangFrom(aFont: *mut nsStyleFont,
aSource: *const nsStyleFont); aSource: *const nsStyleFont);
} }
extern "C" {
pub fn Gecko_nsStyleFont_GetBaseSize(font: *const nsStyleFont,
pres_context:
RawGeckoPresContextBorrowed)
-> nscoord;
}
extern "C" { extern "C" {
pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature; pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature;
} }

View file

@ -19097,6 +19097,14 @@ pub mod root {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct gfxFontStyle([u8; 0]); pub struct gfxFontStyle([u8; 0]);
pub const kGenericFont_NONE: u8 = 0;
pub const kGenericFont_moz_variable: u8 = 0;
pub const kGenericFont_moz_fixed: u8 = 1;
pub const kGenericFont_serif: u8 = 2;
pub const kGenericFont_sans_serif: u8 = 4;
pub const kGenericFont_monospace: u8 = 8;
pub const kGenericFont_cursive: u8 = 16;
pub const kGenericFont_fantasy: u8 = 32;
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct nsFont { pub struct nsFont {

View file

@ -18546,6 +18546,14 @@ pub mod root {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct gfxFontStyle([u8; 0]); pub struct gfxFontStyle([u8; 0]);
pub const kGenericFont_NONE: u8 = 0;
pub const kGenericFont_moz_variable: u8 = 0;
pub const kGenericFont_moz_fixed: u8 = 1;
pub const kGenericFont_serif: u8 = 2;
pub const kGenericFont_sans_serif: u8 = 4;
pub const kGenericFont_monospace: u8 = 8;
pub const kGenericFont_cursive: u8 = 16;
pub const kGenericFont_fantasy: u8 = 32;
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct nsFont { pub struct nsFont {

View file

@ -194,6 +194,11 @@ impl ComputedValues {
pub struct ${style_struct.gecko_struct_name} { pub struct ${style_struct.gecko_struct_name} {
gecko: ${style_struct.gecko_ffi_name}, gecko: ${style_struct.gecko_ffi_name},
} }
impl ${style_struct.gecko_struct_name} {
pub fn gecko(&self) -> &${style_struct.gecko_ffi_name} {
&self.gecko
}
}
</%def> </%def>
<%def name="impl_simple_setter(ident, gecko_ffi_name)"> <%def name="impl_simple_setter(ident, gecko_ffi_name)">
@ -1191,14 +1196,31 @@ fn static_assert() {
unsafe { Gecko_FontFamilyList_AppendNamed(list, name.0.as_ptr()); } unsafe { Gecko_FontFamilyList_AppendNamed(list, name.0.as_ptr()); }
} }
FontFamily::Generic(ref name) => { FontFamily::Generic(ref name) => {
let family_type = let (family_type, generic) =
if name == &atom!("serif") { FontFamilyType::eFamily_serif } if name == &atom!("serif") {
else if name == &atom!("sans-serif") { FontFamilyType::eFamily_sans_serif } (FontFamilyType::eFamily_serif,
else if name == &atom!("cursive") { FontFamilyType::eFamily_cursive } structs::kGenericFont_serif)
else if name == &atom!("fantasy") { FontFamilyType::eFamily_fantasy } } else if name == &atom!("sans-serif") {
else if name == &atom!("monospace") { FontFamilyType::eFamily_monospace } (FontFamilyType::eFamily_sans_serif,
else if name == &atom!("-moz-fixed") { FontFamilyType::eFamily_moz_fixed } structs::kGenericFont_sans_serif)
else { panic!("Unknown generic font family") }; } 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 {
self.gecko.mGenericID = generic;
}
unsafe { Gecko_FontFamilyList_AppendGeneric(list, family_type); } unsafe { Gecko_FontFamilyList_AppendGeneric(list, family_type); }
} }
} }

View file

@ -482,29 +482,79 @@ ${helpers.single_keyword("font-variant-caps",
} }
} }
impl ToComputedValue for KeywordSize { % if product == "servo":
type ComputedValue = Au; impl ToComputedValue for KeywordSize {
#[inline] type ComputedValue = Au;
fn to_computed_value(&self, _: &Context) -> computed_value::T { #[inline]
// https://drafts.csswg.org/css-fonts-3/#font-size-prop fn to_computed_value(&self, _: &Context) -> computed_value::T {
use values::FONT_MEDIUM_PX; // https://drafts.csswg.org/css-fonts-3/#font-size-prop
match *self { use values::FONT_MEDIUM_PX;
XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5, match *self {
XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4, XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5,
Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9, XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4,
Medium => Au::from_px(FONT_MEDIUM_PX), Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9,
Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5, Medium => Au::from_px(FONT_MEDIUM_PX),
XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2, Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5,
XXLarge => Au::from_px(FONT_MEDIUM_PX) * 2, XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2,
XXXLarge => Au::from_px(FONT_MEDIUM_PX) * 3, XXLarge => Au::from_px(FONT_MEDIUM_PX) * 2,
XXXLarge => Au::from_px(FONT_MEDIUM_PX) * 3,
}
}
#[inline]
fn from_computed_value(_: &computed_value::T) -> Self {
unreachable!()
} }
} }
% else:
impl ToComputedValue for KeywordSize {
type ComputedValue = Au;
#[inline]
fn to_computed_value(&self, cx: &Context) -> computed_value::T {
use gecko_bindings::bindings::Gecko_nsStyleFont_GetBaseSize;
use values::specified::length::au_to_int_px;
// Data from nsRuleNode.cpp in Gecko
// Mapping from base size and HTML size to pixels
// The first index is (base_size - 9), the second is the
// HTML size. "0" is CSS keyword xx-small, not HTML size 0,
// since HTML size 0 is the same as 1.
//
// xxs xs s m l xl xxl -
// - 0/1 2 3 4 5 6 7
static FONT_SIZE_MAPPING: [[i32; 8]; 8] = [
[9, 9, 9, 9, 11, 14, 18, 27],
[9, 9, 9, 10, 12, 15, 20, 30],
[9, 9, 10, 11, 13, 17, 22, 33],
[9, 9, 10, 12, 14, 18, 24, 36],
[9, 10, 12, 13, 16, 20, 26, 39],
[9, 10, 12, 14, 17, 21, 28, 42],
[9, 10, 13, 15, 18, 23, 30, 45],
[9, 10, 13, 16, 18, 24, 32, 48]
];
#[inline] static FONT_SIZE_FACTORS: [i32; 8] = [60, 75, 89, 100, 120, 150, 200, 300];
fn from_computed_value(_: &computed_value::T) -> Self {
unreachable!() // XXXManishearth handle quirks mode
let base_size = unsafe {
Gecko_nsStyleFont_GetBaseSize(cx.style().get_font().gecko(),
&*cx.device.pres_context)
};
let base_size_px = au_to_int_px(base_size as f32);
let html_size = *self as usize;
if base_size_px >= 9 && base_size_px <= 16 {
Au::from_px(FONT_SIZE_MAPPING[(base_size_px - 9) as usize][html_size])
} else {
Au(FONT_SIZE_FACTORS[html_size] * base_size / 100)
}
}
#[inline]
fn from_computed_value(_: &computed_value::T) -> Self {
unreachable!()
}
} }
} % endif
impl SpecifiedValue { impl SpecifiedValue {
/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size /// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size

View file

@ -33,6 +33,14 @@ const AU_PER_Q: CSSFloat = AU_PER_MM / 4.;
const AU_PER_PT: CSSFloat = AU_PER_IN / 72.; const AU_PER_PT: CSSFloat = AU_PER_IN / 72.;
const AU_PER_PC: CSSFloat = AU_PER_PT * 12.; const AU_PER_PC: CSSFloat = AU_PER_PT * 12.;
/// Same as Gecko's AppUnitsToIntCSSPixels
///
/// Converts app units to integer pixel values,
/// rounding during the conversion
pub fn au_to_int_px(au: f32) -> i32 {
(au / AU_PER_PX).round() as i32
}
#[derive(Clone, PartialEq, Copy, Debug)] #[derive(Clone, PartialEq, Copy, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// A font relative length. /// A font relative length.