--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -347,17 +347,16 @@ opaque-types = [
"mozilla::dom::.*Callback", # Pulls in ErrorResult and other things that
# don't align properly on Linux 32-bit
]
mapped-generic-types = [
{ generic = true, gecko = "mozilla::ServoUnsafeCell", servo = "::std::cell::UnsafeCell" },
{ generic = true, gecko = "mozilla::ServoCell", servo = "::std::cell::Cell" },
{ generic = false, gecko = "ServoNodeData", servo = "AtomicRefCell<ElementData>" },
{ generic = false, gecko = "mozilla::ServoWritingMode", servo = "::logical_geometry::WritingMode" },
- { generic = false, gecko = "mozilla::ServoFontComputationData", servo = "::properties::FontComputationData" },
{ generic = false, gecko = "mozilla::ServoCustomPropertiesMap", servo = "Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>" },
{ generic = false, gecko = "mozilla::ServoRuleNode", servo = "Option<::rule_tree::StrongRuleNode>" },
{ generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>" },
{ generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
{ generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::servo_arc::RawOffsetArc" },
{ generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>" },
]
fixups = [
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -130,44 +130,16 @@ enum class InheritTarget {
// We're requesting a style for a placeholder frame.
PlaceholderFrame,
};
struct ServoWritingMode {
uint8_t mBits;
};
-// Don't attempt to read from this
-// (see comment on ServoFontComputationData
-enum ServoKeywordSize {
- Empty, // when the Option is None
- XXSmall,
- XSmall,
- Small,
- Medium,
- Large,
- XLarge,
- XXLarge,
- XXXLarge,
-};
-
-// Don't attempt to read from this. We can't
-// always guarantee that the interior representation
-// of this is correct (the mKeyword field may have a different padding),
-// but the entire struct should
-// have the same size and alignment as the Rust version.
-// Ensure layout tests get run if touching either side.
-struct ServoFontComputationData {
- ServoKeywordSize mKeyword;
- float/*32_t*/ mRatio;
- int32_t mAbsolute;
-
- static_assert(sizeof(float) == 4, "float should be 32 bit");
-};
-
struct ServoCustomPropertiesMap {
uintptr_t mPtr;
};
struct ServoRuleNode {
uintptr_t mPtr;
};
@@ -265,24 +237,16 @@ private:
/// node. Can be None for default values and text nodes. This is
/// essentially an optimization to avoid referencing the root rule node.
mozilla::ServoRuleNode rules;
/// The element's computed values if visited, only computed if there's a
/// relevant link for this element. A element's "relevant link" is the
/// element being matched if it is a link or the nearest ancestor link.
mozilla::ServoVisitedStyle visited_style;
- // this is the last member because most of the other members
- // are pointer sized. This makes it easier to deal with the
- // alignment of the fields when replacing things via bindgen
- //
- // This is opaque, please don't read from it from C++
- // (see comment on ServoFontComputationData)
- mozilla::ServoFontComputationData font_computation_data;
-
// C++ just sees this struct as a bucket of bits, and will
// do the wrong thing if we let it use the default copy ctor/assignment
// operator. Remove them so that there is no footgun.
//
// We remove the move ctor/assignment operator as well, because
// moves in C++ don't prevent destructors from being called,
// which will lead to double frees.
ServoComputedData& operator=(const ServoComputedData&) = delete;
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -5,17 +5,16 @@ pub use self::root::mozilla::*;
pub use self::root::mozilla::css::*;
pub use self::root::mozilla::dom::*;
use atomic_refcell::AtomicRefCell;
use data::ElementData;
pub type ServoUnsafeCell<T> = ::std::cell::UnsafeCell<T>;
pub type ServoCell<T> = ::std::cell::Cell<T>;
pub type ServoNodeData = AtomicRefCell<ElementData>;
pub type ServoWritingMode = ::logical_geometry::WritingMode;
-pub type ServoFontComputationData = ::properties::FontComputationData;
pub type ServoCustomPropertiesMap = Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>;
pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
pub type ServoVisitedStyle = Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>;
pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
pub type ServoRawOffsetArc<T> = ::servo_arc::RawOffsetArc<T>;
pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>;
#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
@@ -4458,41 +4457,28 @@ pub mod root {
pub type ParsingMode = u8;
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum InheritTarget {
Text = 0,
FirstLetterContinuation = 1,
PlaceholderFrame = 2,
}
- #[repr(u32)]
- #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
- pub enum ServoKeywordSize {
- Empty = 0,
- XXSmall = 1,
- XSmall = 2,
- Small = 3,
- Medium = 4,
- Large = 5,
- XLarge = 6,
- XXLarge = 7,
- XXXLarge = 8,
- }
#[repr(C)]
#[derive(Debug)]
pub struct ServoStyleContext {
pub _base: root::nsStyleContext,
pub mPresContext: *mut root::nsPresContext,
pub mSource: root::ServoComputedData,
pub mNextInheritingAnonBoxStyle: root::RefPtr<root::mozilla::ServoStyleContext>,
pub mNextLazyPseudoStyle: root::RefPtr<root::mozilla::ServoStyleContext>,
}
#[test]
fn bindgen_test_layout_ServoStyleContext() {
- assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 280usize ,
+ assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 264usize ,
concat ! (
"Size of: " , stringify ! ( ServoStyleContext ) ));
assert_eq! (::std::mem::align_of::<ServoStyleContext>() , 8usize ,
concat ! (
"Alignment of " , stringify ! ( ServoStyleContext )
));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleContext ) ) .
@@ -4505,24 +4491,24 @@ pub mod root {
& ( * ( 0 as * const ServoStyleContext ) ) . mSource
as * const _ as usize } , 32usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleContext ) , "::" , stringify ! ( mSource )
));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleContext ) ) .
mNextInheritingAnonBoxStyle as * const _ as usize } ,
- 264usize , concat ! (
+ 248usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleContext ) , "::" , stringify ! (
mNextInheritingAnonBoxStyle ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleContext ) ) .
mNextLazyPseudoStyle as * const _ as usize } ,
- 272usize , concat ! (
+ 256usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleContext ) , "::" , stringify ! (
mNextLazyPseudoStyle ) ));
}
#[repr(C)]
#[derive(Debug)]
pub struct GeckoFont {
pub gecko: root::nsStyleFont,
@@ -14823,21 +14809,20 @@ pub mod root {
/// The rule node representing the ordered list of rules matched for this
/// /// node. Can be None for default values and text nodes. This is
/// /// essentially an optimization to avoid referencing the root rule node.
pub rules: ::gecko_bindings::structs::ServoRuleNode,
/// The element's computed values if visited, only computed if there's a
/// /// relevant link for this element. A element's "relevant link" is the
/// /// element being matched if it is a link or the nearest ancestor link.
pub visited_style: ::gecko_bindings::structs::ServoVisitedStyle,
- pub font_computation_data: ::gecko_bindings::structs::ServoFontComputationData,
}
#[test]
fn bindgen_test_layout_ServoComputedData() {
- assert_eq!(::std::mem::size_of::<ServoComputedData>() , 232usize ,
+ assert_eq!(::std::mem::size_of::<ServoComputedData>() , 216usize ,
concat ! ( "Size of: " , stringify ! ( ServoComputedData )
));
assert_eq! (::std::mem::align_of::<ServoComputedData>() , 8usize ,
concat ! (
"Alignment of " , stringify ! ( ServoComputedData ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoComputedData ) ) . Font as *
const _ as usize } , 0usize , concat ! (
@@ -14974,22 +14959,16 @@ pub mod root {
const _ as usize } , 200usize , concat ! (
"Alignment of field: " , stringify ! ( ServoComputedData )
, "::" , stringify ! ( rules ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoComputedData ) ) . visited_style
as * const _ as usize } , 208usize , concat ! (
"Alignment of field: " , stringify ! ( ServoComputedData )
, "::" , stringify ! ( visited_style ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ServoComputedData ) ) .
- font_computation_data as * const _ as usize } , 216usize ,
- concat ! (
- "Alignment of field: " , stringify ! ( ServoComputedData )
- , "::" , stringify ! ( font_computation_data ) ));
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum JSValueTag {
JSVAL_TAG_MAX_DOUBLE = 131056,
JSVAL_TAG_INT32 = 131057,
JSVAL_TAG_UNDEFINED = 131058,
JSVAL_TAG_NULL = 131059,
--- a/servo/components/style/gecko/generated/structs_release.rs
+++ b/servo/components/style/gecko/generated/structs_release.rs
@@ -5,17 +5,16 @@ pub use self::root::mozilla::*;
pub use self::root::mozilla::css::*;
pub use self::root::mozilla::dom::*;
use atomic_refcell::AtomicRefCell;
use data::ElementData;
pub type ServoUnsafeCell<T> = ::std::cell::UnsafeCell<T>;
pub type ServoCell<T> = ::std::cell::Cell<T>;
pub type ServoNodeData = AtomicRefCell<ElementData>;
pub type ServoWritingMode = ::logical_geometry::WritingMode;
-pub type ServoFontComputationData = ::properties::FontComputationData;
pub type ServoCustomPropertiesMap = Option<::servo_arc::Arc<::custom_properties::CustomPropertiesMap>>;
pub type ServoRuleNode = Option<::rule_tree::StrongRuleNode>;
pub type ServoVisitedStyle = Option<::servo_arc::RawOffsetArc<::properties::ComputedValues>>;
pub type ServoComputedValueFlags = ::properties::computed_value_flags::ComputedValueFlags;
pub type ServoRawOffsetArc<T> = ::servo_arc::RawOffsetArc<T>;
pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<::properties::ComputedValues>;
#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
@@ -4378,41 +4377,28 @@ pub mod root {
pub type ParsingMode = u8;
#[repr(i32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum InheritTarget {
Text = 0,
FirstLetterContinuation = 1,
PlaceholderFrame = 2,
}
- #[repr(u32)]
- #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
- pub enum ServoKeywordSize {
- Empty = 0,
- XXSmall = 1,
- XSmall = 2,
- Small = 3,
- Medium = 4,
- Large = 5,
- XLarge = 6,
- XXLarge = 7,
- XXXLarge = 8,
- }
#[repr(C)]
#[derive(Debug)]
pub struct ServoStyleContext {
pub _base: root::nsStyleContext,
pub mPresContext: *mut root::nsPresContext,
pub mSource: root::ServoComputedData,
pub mNextInheritingAnonBoxStyle: root::RefPtr<root::mozilla::ServoStyleContext>,
pub mNextLazyPseudoStyle: root::RefPtr<root::mozilla::ServoStyleContext>,
}
#[test]
fn bindgen_test_layout_ServoStyleContext() {
- assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 272usize ,
+ assert_eq!(::std::mem::size_of::<ServoStyleContext>() , 256usize ,
concat ! (
"Size of: " , stringify ! ( ServoStyleContext ) ));
assert_eq! (::std::mem::align_of::<ServoStyleContext>() , 8usize ,
concat ! (
"Alignment of " , stringify ! ( ServoStyleContext )
));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleContext ) ) .
@@ -4425,24 +4411,24 @@ pub mod root {
& ( * ( 0 as * const ServoStyleContext ) ) . mSource
as * const _ as usize } , 24usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleContext ) , "::" , stringify ! ( mSource )
));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleContext ) ) .
mNextInheritingAnonBoxStyle as * const _ as usize } ,
- 256usize , concat ! (
+ 240usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleContext ) , "::" , stringify ! (
mNextInheritingAnonBoxStyle ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoStyleContext ) ) .
mNextLazyPseudoStyle as * const _ as usize } ,
- 264usize , concat ! (
+ 248usize , concat ! (
"Alignment of field: " , stringify ! (
ServoStyleContext ) , "::" , stringify ! (
mNextLazyPseudoStyle ) ));
}
#[repr(C)]
#[derive(Debug)]
pub struct GeckoFont {
pub gecko: root::nsStyleFont,
@@ -14670,21 +14656,20 @@ pub mod root {
/// The rule node representing the ordered list of rules matched for this
/// /// node. Can be None for default values and text nodes. This is
/// /// essentially an optimization to avoid referencing the root rule node.
pub rules: ::gecko_bindings::structs::ServoRuleNode,
/// The element's computed values if visited, only computed if there's a
/// /// relevant link for this element. A element's "relevant link" is the
/// /// element being matched if it is a link or the nearest ancestor link.
pub visited_style: ::gecko_bindings::structs::ServoVisitedStyle,
- pub font_computation_data: ::gecko_bindings::structs::ServoFontComputationData,
}
#[test]
fn bindgen_test_layout_ServoComputedData() {
- assert_eq!(::std::mem::size_of::<ServoComputedData>() , 232usize ,
+ assert_eq!(::std::mem::size_of::<ServoComputedData>() , 216usize ,
concat ! ( "Size of: " , stringify ! ( ServoComputedData )
));
assert_eq! (::std::mem::align_of::<ServoComputedData>() , 8usize ,
concat ! (
"Alignment of " , stringify ! ( ServoComputedData ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoComputedData ) ) . Font as *
const _ as usize } , 0usize , concat ! (
@@ -14821,22 +14806,16 @@ pub mod root {
const _ as usize } , 200usize , concat ! (
"Alignment of field: " , stringify ! ( ServoComputedData )
, "::" , stringify ! ( rules ) ));
assert_eq! (unsafe {
& ( * ( 0 as * const ServoComputedData ) ) . visited_style
as * const _ as usize } , 208usize , concat ! (
"Alignment of field: " , stringify ! ( ServoComputedData )
, "::" , stringify ! ( visited_style ) ));
- assert_eq! (unsafe {
- & ( * ( 0 as * const ServoComputedData ) ) .
- font_computation_data as * const _ as usize } , 216usize ,
- concat ! (
- "Alignment of field: " , stringify ! ( ServoComputedData )
- , "::" , stringify ! ( font_computation_data ) ));
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum JSValueTag {
JSVAL_TAG_MAX_DOUBLE = 131056,
JSVAL_TAG_INT32 = 131057,
JSVAL_TAG_UNDEFINED = 131058,
JSVAL_TAG_NULL = 131059,
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -48,17 +48,17 @@ use gecko_bindings::sugar::ns_style_coor
use gecko::values::convert_nscolor_to_rgba;
use gecko::values::convert_rgba_to_nscolor;
use gecko::values::GeckoStyleCoordConvertible;
use gecko::values::round_border_to_device_pixels;
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::animated_properties::TransitionProperty;
use properties::computed_value_flags::*;
-use properties::{default_font_size_keyword, longhands, FontComputationData, Importance, LonghandId};
+use properties::{longhands, Importance, LonghandId};
use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId};
use rule_tree::StrongRuleNode;
use selector_parser::PseudoElement;
use servo_arc::{Arc, RawOffsetArc};
use std::mem::{forget, uninitialized, transmute, zeroed};
use std::{cmp, ops, ptr};
use values::{self, Auto, CustomIdent, Either, KeyframesName, None_};
use values::computed::{NonNegativeLength, ToComputedValue, Percentage};
@@ -80,28 +80,26 @@ pub struct ComputedValues(::gecko_bindin
impl ComputedValues {
pub fn new(
device: &Device,
parent: Option<<&ComputedValues>,
pseudo: Option<<&PseudoElement>,
custom_properties: Option<Arc<CustomPropertiesMap>>,
writing_mode: WritingMode,
- font_size_keyword: FontComputationData,
flags: ComputedValueFlags,
rules: Option<StrongRuleNode>,
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.style_structs:
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Arc<Self> {
ComputedValuesInner::new(
custom_properties,
writing_mode,
- font_size_keyword,
flags,
rules,
visited_style,
% for style_struct in data.style_structs:
${style_struct.ident},
% endfor
).to_outer(
device.pres_context(),
@@ -109,17 +107,16 @@ impl ComputedValues {
pseudo.map(|p| p.pseudo_info())
)
}
pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
ComputedValuesInner::new(
/* custom_properties = */ None,
/* writing_mode = */ WritingMode::empty(), // FIXME(bz): This seems dubious
- default_font_size_keyword(),
ComputedValueFlags::empty(),
/* rules = */ None,
/* visited_style = */ None,
% for style_struct in data.style_structs:
style_structs::${style_struct.name}::default(pres_context),
% endfor
).to_outer(pres_context, None, None)
}
@@ -169,42 +166,39 @@ impl Clone for ComputedValues {
impl Clone for ComputedValuesInner {
fn clone(&self) -> Self {
ComputedValuesInner {
% for style_struct in data.style_structs:
${style_struct.gecko_name}: self.${style_struct.gecko_name}.clone(),
% endfor
custom_properties: self.custom_properties.clone(),
writing_mode: self.writing_mode.clone(),
- font_computation_data: self.font_computation_data.clone(),
flags: self.flags.clone(),
rules: self.rules.clone(),
visited_style: self.visited_style.clone(),
}
}
}
type PseudoInfo = (*mut structs::nsIAtom, structs::CSSPseudoElementType);
type ParentStyleContextInfo<'a> = Option< &'a ComputedValues>;
impl ComputedValuesInner {
pub fn new(custom_properties: Option<Arc<CustomPropertiesMap>>,
writing_mode: WritingMode,
- font_size_keyword: FontComputationData,
flags: ComputedValueFlags,
rules: Option<StrongRuleNode>,
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.style_structs:
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Self {
ComputedValuesInner {
custom_properties: custom_properties,
writing_mode: writing_mode,
- font_computation_data: font_size_keyword,
rules: rules,
visited_style: visited_style.map(|x| Arc::into_raw_offset(x)),
flags: flags,
% for style_struct in data.style_structs:
${style_struct.gecko_name}: Arc::into_raw_offset(${style_struct.ident}),
% endfor
}
}
@@ -2317,21 +2311,19 @@ fn static_assert() {
(cmp::min(new_size, cmp::max(new_unconstrained_size, min)),
new_unconstrained_size)
}
}
/// This function will also handle scriptminsize and scriptlevel
/// so should not be called when you just want the font sizes to be copied.
/// Hence the different name.
- ///
- /// Returns true if the inherited keyword size was actually used
pub fn inherit_font_size_from(&mut self, parent: &Self,
kw_inherited_size: Option<NonNegativeLength>,
- device: &Device) -> bool {
+ device: &Device) {
let (adjusted_size, adjusted_unconstrained_size)
= self.calculate_script_level_size(parent, device);
if adjusted_size.0 != parent.gecko.mSize ||
adjusted_unconstrained_size.0 != parent.gecko.mScriptUnconstrainedSize {
// This is incorrect. When there is both a keyword size being inherited
// and a scriptlevel change, we must handle the keyword size the same
// way we handle em units. This complicates things because we now have
// to keep track of the adjusted and unadjusted ratios in the kw font size.
@@ -2350,41 +2342,36 @@ fn static_assert() {
// Technically the MathML constrained size may also be keyword-derived
// but we ignore this since it would be too complicated
// to correctly track and it's mostly unnecessary.
self.gecko.mFontSizeKeyword = structs::NS_STYLE_FONT_SIZE_NO_KEYWORD as u8;
self.gecko.mFontSizeFactor = 1.;
self.gecko.mFontSizeOffset = 0;
self.gecko.mScriptUnconstrainedSize = adjusted_unconstrained_size.0;
- self.fixup_font_min_size(device);
- false
} else if let Some(size) = kw_inherited_size {
// Parent element was a keyword-derived size.
self.gecko.mSize = size.0.to_i32_au();
// Copy keyword info over.
self.gecko.mFontSizeFactor = parent.gecko.mFontSizeFactor;
self.gecko.mFontSizeOffset = parent.gecko.mFontSizeOffset;
self.gecko.mFontSizeKeyword = parent.gecko.mFontSizeKeyword;
// MathML constraints didn't apply here, so we can ignore this.
self.gecko.mScriptUnconstrainedSize = size.0.to_i32_au();
- self.fixup_font_min_size(device);
- true
} else {
// MathML isn't affecting us, and our parent element does not
// have a keyword-derived size. Set things normally.
self.gecko.mSize = parent.gecko.mSize;
// copy keyword info over
self.gecko.mFontSizeKeyword = structs::NS_STYLE_FONT_SIZE_NO_KEYWORD as u8;
self.gecko.mFontSizeFactor = 1.;
self.gecko.mFontSizeOffset = 0;
self.gecko.mScriptUnconstrainedSize = parent.gecko.mScriptUnconstrainedSize;
- self.fixup_font_min_size(device);
- false
- }
+ }
+ self.fixup_font_min_size(device);
}
pub fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
use self::longhands::font_size::KeywordSize;
let size = Au(self.gecko.mSize).into();
let kw = match self.gecko.mFontSizeKeyword as u32 {
structs::NS_STYLE_FONT_SIZE_XXSMALL => KeywordSize::XXSmall,
structs::NS_STYLE_FONT_SIZE_XSMALL => KeywordSize::XSmall,
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -600,17 +600,17 @@ macro_rules! impl_gecko_keyword_conversi
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER"
allow_quirks="True" spec="https://drafts.csswg.org/css-fonts/#propdef-font-size">
use app_units::Au;
use properties::longhands::system_font::SystemFont;
use std::fmt;
use style_traits::ToCss;
use values::FONT_MEDIUM_PX;
use values::computed::NonNegativeLength;
- use values::specified::{AllowQuirks, FontRelativeLength, LengthOrPercentage, NoCalcLength};
+ use values::specified::{AllowQuirks, LengthOrPercentage, NoCalcLength};
use values::specified::length::FontBaseSize;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
SpecifiedValue::Length(ref lop) => lop.to_css(dest),
SpecifiedValue::Keyword(kw, _, _) => kw.to_css(dest),
SpecifiedValue::Smaller => dest.write_str("smaller"),
@@ -856,72 +856,36 @@ macro_rules! impl_gecko_keyword_conversi
4 => Large,
5 => XLarge,
6 => XXLarge,
// If value is greater than 7, let it be 7.
_ => XXXLarge,
}, 1., Au(0).into())
}
- /// If this value is specified as a ratio of the parent font (em units
- /// or percent) return the ratio
- pub fn as_font_ratio(&self, context: &Context) -> Option<(f32, NonNegativeLength)> {
- match *self {
- SpecifiedValue::Length(ref lop) => {
- match *lop {
- LengthOrPercentage::Percentage(pc) => {
- Some((pc.0, NonNegativeLength::zero()))
- }
- LengthOrPercentage::Length(ref nocalc) => {
- match *nocalc {
- NoCalcLength::FontRelative(FontRelativeLength::Em(em)) => {
- Some((em, NonNegativeLength::zero()))
- }
- _ => None,
- }
- }
- LengthOrPercentage::Calc(ref calc) => {
- if calc.em.is_none() && calc.percentage.is_none() {
- return None;
- }
- let ratio = calc.em.unwrap_or(0.) + calc.percentage.map_or(0., |pc| pc.0);
- // Compute it, but shave off the font-relative part (em, %)
- // This will mean that other font-relative units like ex and ch will be computed against
- // the old font even when the font changes. There's no particular "right answer" for what
- // to do here -- Gecko recascades as if the font had changed, we instead track the changes
- // and reapply, which means that we carry over old computed ex/ch values whilst Gecko
- // recomputes new ones. This is enough of an edge case to not really matter.
- let abs = calc.to_computed_value_zoomed(context, FontBaseSize::Custom(Au(0)))
- .length_component().into();
- Some((ratio, abs))
- }
- }
- }
- SpecifiedValue::Larger => Some((LARGER_FONT_SIZE_RATIO, Au(0).into())),
- SpecifiedValue::Smaller => Some((1. / LARGER_FONT_SIZE_RATIO, Au(0).into())),
- _ => None,
- }
- }
-
/// Compute it against a given base font size
pub fn to_computed_value_against(
&self,
context: &Context,
base_size: FontBaseSize,
) -> computed_value::T {
use values::specified::length::FontRelativeLength;
+ let compose_keyword = |factor| {
+ context.style().get_parent_font()
+ .clone_font_size().info
+ .map(|i| i.compose(factor, Au(0).into()))
+ };
let mut info = None;
let size = match *self {
SpecifiedValue::Length(LengthOrPercentage::Length(
NoCalcLength::FontRelative(value))) => {
if let FontRelativeLength::Em(em) = value {
// If the parent font was keyword-derived, this is too.
// Tack the em unit onto the factor
- info = context.style().get_parent_font()
- .clone_font_size().info.map(|i| i.compose(em, Au(0).into()));
+ info = compose_keyword(em);
}
value.to_computed_value(context, base_size).into()
}
SpecifiedValue::Length(LengthOrPercentage::Length(
NoCalcLength::ServoCharacterWidth(value))) => {
value.to_computed_value(base_size.resolve(context)).into()
}
SpecifiedValue::Length(LengthOrPercentage::Length(
@@ -929,17 +893,17 @@ macro_rules! impl_gecko_keyword_conversi
context.maybe_zoom_text(l.to_computed_value(context).into())
}
SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => {
l.to_computed_value(context).into()
}
SpecifiedValue::Length(LengthOrPercentage::Percentage(pc)) => {
// If the parent font was keyword-derived, this is too.
// Tack the % onto the factor
- info = context.style().get_parent_font().clone_font_size().info.map(|i| i.compose(pc.0, Au(0).into()));
+ info = compose_keyword(pc.0);
base_size.resolve(context).scale_by(pc.0).into()
}
SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => {
let parent = context.style().get_parent_font().clone_font_size();
// if we contain em/% units and the parent was keyword derived, this is too
// Extract the ratio/offset and compose it
if (calc.em.is_some() || calc.percentage.is_some()) && parent.info.is_some() {
let ratio = calc.em.unwrap_or(0.) + calc.percentage.map_or(0., |pc| pc.0);
@@ -962,20 +926,22 @@ macro_rules! impl_gecko_keyword_conversi
kw: key,
factor: fraction,
offset: offset,
});
let key_len = key.to_computed_value(context).scale_by(fraction) + offset;
context.maybe_zoom_text(key_len).into()
}
SpecifiedValue::Smaller => {
+ info = compose_keyword(1. / LARGER_FONT_SIZE_RATIO);
FontRelativeLength::Em(1. / LARGER_FONT_SIZE_RATIO)
.to_computed_value(context, base_size).into()
}
SpecifiedValue::Larger => {
+ info = compose_keyword(LARGER_FONT_SIZE_RATIO);
FontRelativeLength::Em(LARGER_FONT_SIZE_RATIO)
.to_computed_value(context, base_size).into()
}
SpecifiedValue::System(_) => {
<%self:nongecko_unreachable>
context.cached_system_font.as_ref().unwrap().font_size.size
</%self:nongecko_unreachable>
@@ -1058,55 +1024,29 @@ macro_rules! impl_gecko_keyword_conversi
}
}
}
#[allow(unused_mut)]
pub fn cascade_specified_font_size(context: &mut Context,
specified_value: &SpecifiedValue,
mut computed: computed_value::T) {
- if let SpecifiedValue::Keyword(kw, fraction, offset) = *specified_value {
- context.builder.font_size_keyword = Some((kw, fraction, offset));
- } else if let Some((ratio, abs)) = specified_value.as_font_ratio(context) {
- // In case a font-size-relative value was applied to a keyword
- // value, we must preserve this fact in case the generic font family
- // changes. relative values (em and %) applied to keywords must be
- // recomputed from the base size for the keyword and the relative size.
- //
- // See bug 1355707
- if let Some((kw, fraction, old_abs)) = *context.builder.inherited_font_computation_data() {
- context.builder.font_size_keyword =
- Some((kw, fraction * ratio, abs + old_abs.scale_by(ratio)));
- } else {
- context.builder.font_size_keyword = None;
- }
- } else {
- context.builder.font_size_keyword = None;
- }
-
// we could use clone_language and clone_font_family() here but that's
// expensive. Do it only in gecko mode for now.
% if product == "gecko":
use gecko_bindings::structs::nsIAtom;
// if the language or generic changed, we need to recalculate
// the font size from the stored font-size origin information.
if context.builder.get_font().gecko().mLanguage.raw::<nsIAtom>() !=
context.builder.get_parent_font().gecko().mLanguage.raw::<nsIAtom>() ||
context.builder.get_font().gecko().mGenericID !=
context.builder.get_parent_font().gecko().mGenericID {
- if let Some((kw, ratio, offset)) = context.builder.font_size_keyword {
- let len = context.maybe_zoom_text(kw.to_computed_value(context).scale_by(ratio) + offset);
- computed = computed_value::T {
- size: len,
- info: Some(computed_value::KeywordInfo {
- kw: kw,
- factor: ratio,
- offset: offset
- }),
- }
+ if let Some(info) = computed.info {
+ computed.size = context.maybe_zoom_text(info.kw.to_computed_value(context)
+ .scale_by(info.factor) + info.offset)
}
}
% endif
let device = context.builder.device;
let mut font = context.builder.take_font();
let parent_unconstrained = {
let parent_font = context.builder.get_parent_font();
@@ -1125,31 +1065,27 @@ macro_rules! impl_gecko_keyword_conversi
}
/// FIXME(emilio): This is very complex. Also, it should move to
/// StyleBuilder.
pub fn cascade_inherit_font_size(context: &mut Context) {
// If inheriting, we must recompute font-size in case of language
// changes using the font_size_keyword. We also need to do this to
// handle mathml scriptlevel changes
- let kw_inherited_size = context.builder.font_size_keyword.map(|(kw, ratio, offset)| {
- context.maybe_zoom_text(SpecifiedValue::Keyword(kw, ratio, offset).to_computed_value(context).size)
+ let kw_inherited_size = context.builder.get_parent_font()
+ .clone_font_size()
+ .info.map(|info| {
+ context.maybe_zoom_text(SpecifiedValue::Keyword(info.kw, info.factor, info.offset)
+ .to_computed_value(context).size)
});
- let parent_kw;
- let device = context.builder.device;
let mut font = context.builder.take_font();
- let used_kw = {
- let parent_font = context.builder.get_parent_font();
- parent_kw = *context.builder.inherited_font_computation_data();
-
- font.inherit_font_size_from(parent_font, kw_inherited_size, device)
- };
+ font.inherit_font_size_from(context.builder.get_parent_font(),
+ kw_inherited_size,
+ context.builder.device);
context.builder.put_font(font);
- context.builder.font_size_keyword =
- if used_kw { parent_kw } else { None };
}
/// Cascade the initial value for the `font-size` property.
///
/// FIXME(emilio): This is the only function that is outside of the
/// `StyleBuilder`, and should really move inside!
///
/// Can we move the font stuff there?
@@ -1159,17 +1095,16 @@ macro_rules! impl_gecko_keyword_conversi
let mut computed = longhands::font_size::get_initial_specified_value()
.to_computed_value(context);
computed.size = context.maybe_zoom_text(computed.size);
context.builder.mutate_font().set_font_size(computed);
% if product == "gecko":
let device = context.builder.device;
context.builder.mutate_font().fixup_font_min_size(device);
% endif
- context.builder.font_size_keyword = Some((Default::default(), 1., Au(0).into()));
}
</%helpers:longhand>
<%helpers:longhand products="gecko" name="font-size-adjust"
animation_value_type="longhands::font_size_adjust::computed_value::T"
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER"
spec="https://drafts.csswg.org/css-fonts/#propdef-font-size-adjust">
use properties::longhands::system_font::SystemFont;
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -5,16 +5,17 @@
// This file is a Mako template: http://www.makotemplates.org/
// Please note that valid Rust syntax may be mangled by the Mako parser.
// For example, Vec<&Foo> will be mangled as Vec&Foo>. To work around these issues, the code
// can be escaped. In the above example, Vec<<&Foo> or Vec< &Foo> achieves the desired result of Vec<&Foo>.
<%namespace name="helpers" file="/helpers.mako.rs" />
+#[cfg(feature = "servo")]
use app_units::Au;
use servo_arc::{Arc, UniqueArc};
use smallbitvec::SmallBitVec;
use std::borrow::Cow;
use hash::HashSet;
use std::{fmt, mem, ops};
use std::cell::RefCell;
#[cfg(feature = "gecko")] use std::ptr;
@@ -87,42 +88,16 @@ pub mod computed_value_flags;
pub mod declaration_block;
/// Conversion with fewer impls than From/Into
pub trait MaybeBoxed<Out> {
/// Convert
fn maybe_boxed(self) -> Out;
}
-
-/// This is where we store extra font data while
-/// while computing font sizes.
-///
-/// font-size keyword values (and font-size-relative values applied
-/// to keyword values) need to preserve their identity as originating
-/// from keywords and relative font sizes. We store this information
-/// out of band in the ComputedValues. When None, the font size on the
-/// current struct was computed from a value that was not a keyword
-/// or a chain of font-size-relative values applying to successive parents
-/// terminated by a keyword. When Some, this means the font-size was derived
-/// from a keyword value or a keyword value on some ancestor with only
-/// font-size-relative keywords and regular inheritance in between. The
-/// integer stores the final ratio of the chain of font size relative values.
-/// and is 1 when there was just a keyword and no relative values.
-///
-/// When this is Some, we compute font sizes by computing the keyword against
-/// the generic font, and then multiplying it by the ratio (as well as adding any
-/// absolute offset from calcs)
-pub type FontComputationData = Option<(longhands::font_size::KeywordSize, f32, NonNegativeLength)>;
-
-/// Default value for FontComputationData
-pub fn default_font_size_keyword() -> FontComputationData {
- Some((Default::default(), 1., Au(0).into()))
-}
-
impl<T> MaybeBoxed<T> for T {
#[inline]
fn maybe_boxed(self) -> T { self }
}
impl<T> MaybeBoxed<Box<T>> for T {
#[inline]
fn maybe_boxed(self) -> Box<T> { Box::new(self) }
@@ -1840,19 +1815,18 @@ pub mod style_structs {
self.font_stretch.hash(&mut hasher);
self.font_family.hash(&mut hasher);
self.hash = hasher.finish()
}
/// (Servo does not handle MathML, so this just calls copy_font_size_from)
pub fn inherit_font_size_from(&mut self, parent: &Self,
_: Option<NonNegativeLength>,
- _: &Device) -> bool {
+ _: &Device) {
self.copy_font_size_from(parent);
- false
}
/// (Servo does not handle MathML, so this just calls set_font_size)
pub fn apply_font_size(&mut self,
v: longhands::font_size::computed_value::T,
_: &Self,
_: &Device) -> Option<NonNegativeLength> {
self.set_font_size(v);
None
@@ -1980,19 +1954,16 @@ pub use gecko_properties::{ComputedValue
pub struct ComputedValuesInner {
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
/// The writing mode of this computed values struct.
pub writing_mode: WritingMode,
- /// The keyword behind the current font-size property, if any
- pub font_computation_data: FontComputationData,
-
/// A set of flags we use to store misc information regarding this style.
pub flags: ComputedValueFlags,
/// The rule node representing the ordered list of rules matched for this
/// node. Can be None for default values and text nodes. This is
/// essentially an optimization to avoid referencing the root rule node.
pub rules: Option<StrongRuleNode>,
@@ -2038,29 +2009,27 @@ impl ComputedValues {
impl ComputedValues {
/// Create a new refcounted `ComputedValues`
pub fn new(
_: &Device,
_: Option<<&ComputedValues>,
_: Option<<&PseudoElement>,
custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
writing_mode: WritingMode,
- font_size_keyword: FontComputationData,
flags: ComputedValueFlags,
rules: Option<StrongRuleNode>,
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Arc<Self> {
Arc::new(Self {
inner: ComputedValuesInner::new(
custom_properties,
writing_mode,
- font_size_keyword,
flags,
rules,
visited_style,
% for style_struct in data.active_style_structs():
${style_struct.ident},
% endfor
)
})
@@ -2071,28 +2040,26 @@ impl ComputedValues {
}
#[cfg(feature = "servo")]
impl ComputedValuesInner {
/// Construct a `ComputedValuesInner` instance.
pub fn new(
custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
writing_mode: WritingMode,
- font_size_keyword: FontComputationData,
flags: ComputedValueFlags,
rules: Option<StrongRuleNode>,
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Self {
ComputedValuesInner {
custom_properties: custom_properties,
writing_mode: writing_mode,
- font_computation_data: font_size_keyword,
rules: rules,
visited_style: visited_style,
flags: flags,
% for style_struct in data.active_style_structs():
${style_struct.ident}: ${style_struct.ident},
% endfor
}
}
@@ -2604,18 +2571,16 @@ pub struct StyleBuilder<'a> {
/// `clear_modified_reset` was called. This is used to tell whether the
/// `StyleAdjuster` did any work.
modified_reset: bool,
/// The writing mode flags.
///
/// TODO(emilio): Make private.
pub writing_mode: WritingMode,
- /// The keyword behind the current font-size property, if any.
- pub font_size_keyword: FontComputationData,
/// Flags for the computed value.
pub flags: ComputedValueFlags,
/// The element's style if visited, only computed if there's a relevant link
/// for this element. A element's "relevant link" is the element being
/// matched if it is a link or the nearest ancestor link.
visited_style: Option<Arc<ComputedValues>>,
% for style_struct in data.active_style_structs():
${style_struct.ident}: StyleStructRef<'a, style_structs::${style_struct.name}>,
@@ -2628,17 +2593,16 @@ impl<'a> StyleBuilder<'a> {
device: &'a Device,
parent_style: Option<<&'a ComputedValues>,
parent_style_ignoring_first_line: Option<<&'a ComputedValues>,
pseudo: Option<<&'a PseudoElement>,
cascade_flags: CascadeFlags,
rules: Option<StrongRuleNode>,
custom_properties: Option<Arc<::custom_properties::CustomPropertiesMap>>,
writing_mode: WritingMode,
- font_size_keyword: FontComputationData,
mut flags: ComputedValueFlags,
visited_style: Option<Arc<ComputedValues>>,
) -> Self {
debug_assert_eq!(parent_style.is_some(), parent_style_ignoring_first_line.is_some());
#[cfg(feature = "gecko")]
debug_assert!(parent_style.is_none() ||
ptr::eq(parent_style.unwrap(),
parent_style_ignoring_first_line.unwrap()) ||
@@ -2666,17 +2630,16 @@ impl<'a> StyleBuilder<'a> {
inherited_style,
inherited_style_ignoring_first_line,
reset_style,
pseudo,
rules,
modified_reset: false,
custom_properties,
writing_mode,
- font_size_keyword,
flags,
visited_style,
% for style_struct in data.active_style_structs():
% if style_struct.inherited:
${style_struct.ident}: StyleStructRef::Borrowed(inherited_style.${style_struct.name_lower}_arc()),
% else:
${style_struct.ident}: StyleStructRef::Borrowed(reset_style.${style_struct.name_lower}_arc()),
% endif
@@ -2709,17 +2672,16 @@ impl<'a> StyleBuilder<'a> {
// None of our callers pass in ::first-line parent styles.
inherited_style_ignoring_first_line: inherited_style,
reset_style,
pseudo,
modified_reset: false,
rules: None, // FIXME(emilio): Dubious...
custom_properties: style_to_derive_from.custom_properties(),
writing_mode: style_to_derive_from.writing_mode,
- font_size_keyword: style_to_derive_from.font_computation_data,
flags: style_to_derive_from.flags,
visited_style: style_to_derive_from.clone_visited_style(),
% for style_struct in data.active_style_structs():
${style_struct.ident}: StyleStructRef::Borrowed(
style_to_derive_from.${style_struct.name_lower}_arc()
),
% endfor
}
@@ -2829,17 +2791,16 @@ impl<'a> StyleBuilder<'a> {
device,
Some(parent),
Some(parent),
pseudo,
CascadeFlags::empty(),
/* rules = */ None,
parent.custom_properties(),
parent.writing_mode,
- parent.font_computation_data,
parent.flags,
parent.clone_visited_style()
)
}
/// Returns whether we have a visited style.
pub fn has_visited_style(&self) -> bool {
self.visited_style.is_some()
@@ -2936,17 +2897,16 @@ impl<'a> StyleBuilder<'a> {
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
pub fn build(self) -> Arc<ComputedValues> {
ComputedValues::new(
self.device,
self.parent_style,
self.pseudo,
self.custom_properties,
self.writing_mode,
- self.font_size_keyword,
self.flags,
self.rules,
self.visited_style,
% for style_struct in data.active_style_structs():
self.${style_struct.ident}.build(),
% endfor
)
}
@@ -2959,21 +2919,16 @@ impl<'a> StyleBuilder<'a> {
self.custom_properties.clone()
}
/// Access to various information about our inherited styles. We don't
/// expose an inherited ComputedValues directly, because in the
/// ::first-line case some of the inherited information needs to come from
/// one ComputedValues instance and some from a different one.
- /// Inherited font bits.
- pub fn inherited_font_computation_data(&self) -> &FontComputationData {
- &self.inherited_style.font_computation_data
- }
-
/// Inherited writing-mode.
pub fn inherited_writing_mode(&self) -> &WritingMode {
&self.inherited_style.writing_mode
}
/// Inherited style flags.
pub fn inherited_flags(&self) -> &ComputedValueFlags {
&self.inherited_style.flags
@@ -3001,17 +2956,16 @@ pub use self::lazy_static_module::INITIA
// Use a module to work around #[cfg] on lazy_static! not being applied to every generated item.
#[cfg(feature = "servo")]
#[allow(missing_docs)]
mod lazy_static_module {
use logical_geometry::WritingMode;
use servo_arc::Arc;
use super::{ComputedValues, ComputedValuesInner, longhands, style_structs};
- use super::default_font_size_keyword;
use super::computed_value_flags::ComputedValueFlags;
/// The initial values for all style structs as defined by the specification.
lazy_static! {
pub static ref INITIAL_SERVO_VALUES: ComputedValues = ComputedValues {
inner: ComputedValuesInner {
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
@@ -3020,17 +2974,16 @@ mod lazy_static_module {
% endfor
% if style_struct.name == "Font":
hash: 0,
% endif
}),
% endfor
custom_properties: None,
writing_mode: WritingMode::empty(),
- font_computation_data: default_font_size_keyword(),
rules: None,
visited_style: None,
flags: ComputedValueFlags::empty(),
}
};
}
}
@@ -3247,17 +3200,16 @@ where
device,
parent_style,
parent_style_ignoring_first_line,
pseudo,
flags,
Some(rules.clone()),
custom_properties,
WritingMode::empty(),
- inherited_style.font_computation_data,
ComputedValueFlags::empty(),
visited_style,
),
cached_system_font: None,
in_media_query: false,
for_smil_animation: false,
for_non_inherited_property: None,
font_metrics_provider,