Skip to content

Commit

Permalink
stylo: Calculate font-size keywords based on base size
Browse files Browse the repository at this point in the history
MozReview-Commit-ID: Ff6kt8RLChI
  • Loading branch information
Manishearth committed Mar 24, 2017
1 parent 0aceddd commit fddddc9
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 27 deletions.
1 change: 1 addition & 0 deletions components/style/build_gecko.rs
Expand Up @@ -293,6 +293,7 @@ mod bindings {
"BORDER_STYLE_.*",
"mozilla::SERVO_PREF_.*",
"kNameSpaceID_.*",
"kGenericFont_.*",
];
let whitelist = [
"RawGecko.*",
Expand Down
6 changes: 6 additions & 0 deletions components/style/gecko_bindings/bindings.rs
Expand Up @@ -1012,6 +1012,12 @@ extern "C" {
pub fn Gecko_nsStyleFont_CopyLangFrom(aFont: *mut nsStyleFont,
aSource: *const nsStyleFont);
}
extern "C" {
pub fn Gecko_nsStyleFont_GetBaseSize(font: *const nsStyleFont,
pres_context:
RawGeckoPresContextBorrowed)
-> nscoord;
}
extern "C" {
pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature;
}
Expand Down
8 changes: 8 additions & 0 deletions components/style/gecko_bindings/structs_debug.rs
Expand Up @@ -19097,6 +19097,14 @@ pub mod root {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
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)]
#[derive(Debug)]
pub struct nsFont {
Expand Down
8 changes: 8 additions & 0 deletions components/style/gecko_bindings/structs_release.rs
Expand Up @@ -18546,6 +18546,14 @@ pub mod root {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
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)]
#[derive(Debug)]
pub struct nsFont {
Expand Down
38 changes: 30 additions & 8 deletions components/style/properties/gecko.mako.rs
Expand Up @@ -194,6 +194,11 @@ impl ComputedValues {
pub struct ${style_struct.gecko_struct_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 name="impl_simple_setter(ident, gecko_ffi_name)">
Expand Down Expand Up @@ -1191,14 +1196,31 @@ fn static_assert() {
unsafe { Gecko_FontFamilyList_AppendNamed(list, name.0.as_ptr()); }
}
FontFamily::Generic(ref name) => {
let family_type =
if name == &atom!("serif") { FontFamilyType::eFamily_serif }
else if name == &atom!("sans-serif") { FontFamilyType::eFamily_sans_serif }
else if name == &atom!("cursive") { FontFamilyType::eFamily_cursive }
else if name == &atom!("fantasy") { FontFamilyType::eFamily_fantasy }
else if name == &atom!("monospace") { FontFamilyType::eFamily_monospace }
else if name == &atom!("-moz-fixed") { FontFamilyType::eFamily_moz_fixed }
else { panic!("Unknown generic font family") };
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")
};
if v.0.len() == 1 {
self.gecko.mGenericID = generic;
}
unsafe { Gecko_FontFamilyList_AppendGeneric(list, family_type); }
}
}
Expand Down
88 changes: 69 additions & 19 deletions components/style/properties/longhand/font.mako.rs
Expand Up @@ -482,29 +482,79 @@ ${helpers.single_keyword("font-variant-caps",
}
}

impl ToComputedValue for KeywordSize {
type ComputedValue = Au;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
use values::FONT_MEDIUM_PX;
match *self {
XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5,
XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4,
Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9,
Medium => Au::from_px(FONT_MEDIUM_PX),
Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5,
XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2,
XXLarge => Au::from_px(FONT_MEDIUM_PX) * 2,
XXXLarge => Au::from_px(FONT_MEDIUM_PX) * 3,
% if product == "servo":
impl ToComputedValue for KeywordSize {
type ComputedValue = Au;
#[inline]
fn to_computed_value(&self, _: &Context) -> computed_value::T {
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
use values::FONT_MEDIUM_PX;
match *self {
XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5,
XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4,
Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9,
Medium => Au::from_px(FONT_MEDIUM_PX),
Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5,
XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2,
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]
];

static FONT_SIZE_FACTORS: [i32; 8] = [60, 75, 89, 100, 120, 150, 200, 300];

// 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!()
#[inline]
fn from_computed_value(_: &computed_value::T) -> Self {
unreachable!()
}
}
}
% endif

impl SpecifiedValue {
/// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size
Expand Down
8 changes: 8 additions & 0 deletions components/style/values/specified/length.rs
Expand Up @@ -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_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)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
/// A font relative length.
Expand Down

0 comments on commit fddddc9

Please sign in to comment.