mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Use generics for the line-height property
This commit is contained in:
parent
cf71a0cd96
commit
5c6987a50d
12 changed files with 234 additions and 213 deletions
|
@ -23,11 +23,12 @@ use std::borrow::ToOwned;
|
||||||
use std::collections::LinkedList;
|
use std::collections::LinkedList;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::computed_values::{line_height, text_rendering, text_transform};
|
use style::computed_values::{text_rendering, text_transform};
|
||||||
use style::computed_values::{word_break, white_space};
|
use style::computed_values::{word_break, white_space};
|
||||||
use style::logical_geometry::{LogicalSize, WritingMode};
|
use style::logical_geometry::{LogicalSize, WritingMode};
|
||||||
use style::properties::ServoComputedValues;
|
use style::properties::ServoComputedValues;
|
||||||
use style::properties::style_structs;
|
use style::properties::style_structs;
|
||||||
|
use style::values::generics::text::LineHeight;
|
||||||
use unicode_bidi as bidi;
|
use unicode_bidi as bidi;
|
||||||
use unicode_script::{Script, get_script};
|
use unicode_script::{Script, get_script};
|
||||||
|
|
||||||
|
@ -447,9 +448,9 @@ pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: ::Styl
|
||||||
pub fn line_height_from_style(style: &ServoComputedValues, metrics: &FontMetrics) -> Au {
|
pub fn line_height_from_style(style: &ServoComputedValues, metrics: &FontMetrics) -> Au {
|
||||||
let font_size = style.get_font().font_size;
|
let font_size = style.get_font().font_size;
|
||||||
match style.get_inheritedtext().line_height {
|
match style.get_inheritedtext().line_height {
|
||||||
line_height::T::Normal => metrics.line_gap,
|
LineHeight::Normal => metrics.line_gap,
|
||||||
line_height::T::Number(l) => font_size.scale_by(l),
|
LineHeight::Number(l) => font_size.scale_by(l),
|
||||||
line_height::T::Length(l) => l
|
LineHeight::Length(l) => l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3637,30 +3637,27 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
|
pub fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
|
||||||
use properties::longhands::line_height::computed_value::T;
|
use values::generics::text::LineHeight;
|
||||||
// FIXME: Align binary representations and ditch |match| for cast + static_asserts
|
// FIXME: Align binary representations and ditch |match| for cast + static_asserts
|
||||||
let en = match v {
|
let en = match v {
|
||||||
T::Normal => CoordDataValue::Normal,
|
LineHeight::Normal => CoordDataValue::Normal,
|
||||||
T::Length(val) => CoordDataValue::Coord(val.0),
|
LineHeight::Length(val) => CoordDataValue::Coord(val.0),
|
||||||
T::Number(val) => CoordDataValue::Factor(val),
|
LineHeight::Number(val) => CoordDataValue::Factor(val),
|
||||||
T::MozBlockHeight =>
|
LineHeight::MozBlockHeight =>
|
||||||
CoordDataValue::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
|
CoordDataValue::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
|
||||||
};
|
};
|
||||||
self.gecko.mLineHeight.set_value(en);
|
self.gecko.mLineHeight.set_value(en);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
|
pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
|
||||||
use properties::longhands::line_height::computed_value::T;
|
use values::generics::text::LineHeight;
|
||||||
return match self.gecko.mLineHeight.as_value() {
|
return match self.gecko.mLineHeight.as_value() {
|
||||||
CoordDataValue::Normal => T::Normal,
|
CoordDataValue::Normal => LineHeight::Normal,
|
||||||
CoordDataValue::Coord(coord) => T::Length(Au(coord)),
|
CoordDataValue::Coord(coord) => LineHeight::Length(Au(coord)),
|
||||||
CoordDataValue::Factor(n) => T::Number(n),
|
CoordDataValue::Factor(n) => LineHeight::Number(n),
|
||||||
CoordDataValue::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
|
CoordDataValue::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
|
||||||
T::MozBlockHeight,
|
LineHeight::MozBlockHeight,
|
||||||
_ => {
|
_ => panic!("this should not happen"),
|
||||||
debug_assert!(false);
|
|
||||||
T::MozBlockHeight
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ use properties::longhands;
|
||||||
use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
|
use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
|
||||||
use properties::longhands::font_weight::computed_value::T as FontWeight;
|
use properties::longhands::font_weight::computed_value::T as FontWeight;
|
||||||
use properties::longhands::font_stretch::computed_value::T as FontStretch;
|
use properties::longhands::font_stretch::computed_value::T as FontStretch;
|
||||||
use properties::longhands::line_height::computed_value::T as LineHeight;
|
|
||||||
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
|
use properties::longhands::text_shadow::computed_value::T as TextShadowList;
|
||||||
use properties::longhands::text_shadow::computed_value::TextShadow;
|
use properties::longhands::text_shadow::computed_value::TextShadow;
|
||||||
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
|
use properties::longhands::box_shadow::computed_value::T as BoxShadowList;
|
||||||
|
@ -1300,43 +1299,6 @@ impl Animatable for MaxLength {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-number
|
|
||||||
/// https://drafts.csswg.org/css-transitions/#animtype-length
|
|
||||||
impl Animatable for LineHeight {
|
|
||||||
#[inline]
|
|
||||||
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
|
||||||
match (*self, *other) {
|
|
||||||
(LineHeight::Length(ref this),
|
|
||||||
LineHeight::Length(ref other)) => {
|
|
||||||
this.add_weighted(other, self_portion, other_portion).map(LineHeight::Length)
|
|
||||||
}
|
|
||||||
(LineHeight::Number(ref this),
|
|
||||||
LineHeight::Number(ref other)) => {
|
|
||||||
this.add_weighted(other, self_portion, other_portion).map(LineHeight::Number)
|
|
||||||
}
|
|
||||||
(LineHeight::Normal, LineHeight::Normal) => {
|
|
||||||
Ok(LineHeight::Normal)
|
|
||||||
}
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
|
||||||
match (*self, *other) {
|
|
||||||
(LineHeight::Length(ref this),
|
|
||||||
LineHeight::Length(ref other)) => {
|
|
||||||
this.compute_distance(other)
|
|
||||||
},
|
|
||||||
(LineHeight::Number(ref this),
|
|
||||||
LineHeight::Number(ref other)) => {
|
|
||||||
this.compute_distance(other)
|
|
||||||
},
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// http://dev.w3.org/csswg/css-transitions/#animtype-font-weight
|
/// http://dev.w3.org/csswg/css-transitions/#animtype-font-weight
|
||||||
impl Animatable for FontWeight {
|
impl Animatable for FontWeight {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -6,148 +6,11 @@
|
||||||
<% from data import Keyword %>
|
<% from data import Keyword %>
|
||||||
<% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
|
<% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
|
||||||
|
|
||||||
<%helpers:longhand name="line-height" animation_value_type="ComputedValue"
|
${helpers.predefined_type("line-height",
|
||||||
spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height">
|
"LineHeight",
|
||||||
use std::fmt;
|
"computed::LineHeight::normal()",
|
||||||
use style_traits::ToCss;
|
animation_value_type="ComputedValue",
|
||||||
|
spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height")}
|
||||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub enum SpecifiedValue {
|
|
||||||
Normal,
|
|
||||||
% if product == "gecko":
|
|
||||||
MozBlockHeight,
|
|
||||||
% endif
|
|
||||||
Number(specified::Number),
|
|
||||||
LengthOrPercentage(specified::LengthOrPercentage),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToCss for SpecifiedValue {
|
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
|
||||||
match *self {
|
|
||||||
SpecifiedValue::Normal => dest.write_str("normal"),
|
|
||||||
% if product == "gecko":
|
|
||||||
SpecifiedValue::MozBlockHeight => dest.write_str("-moz-block-height"),
|
|
||||||
% endif
|
|
||||||
SpecifiedValue::LengthOrPercentage(ref value) => value.to_css(dest),
|
|
||||||
SpecifiedValue::Number(number) => number.to_css(dest),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// normal | <number> | <length> | <percentage>
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
|
||||||
use cssparser::Token;
|
|
||||||
use std::ascii::AsciiExt;
|
|
||||||
|
|
||||||
// We try to parse as a Number first because, for 'line-height', we want
|
|
||||||
// "0" to be parsed as a plain Number rather than a Length (0px); this
|
|
||||||
// matches the behaviour of all major browsers
|
|
||||||
if let Ok(number) = input.try(|i| specified::Number::parse_non_negative(context, i)) {
|
|
||||||
return Ok(SpecifiedValue::Number(number))
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(lop) = input.try(|i| specified::LengthOrPercentage::parse_non_negative(context, i)) {
|
|
||||||
return Ok(SpecifiedValue::LengthOrPercentage(lop))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
match try!(input.next()) {
|
|
||||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("normal") => {
|
|
||||||
Ok(SpecifiedValue::Normal)
|
|
||||||
}
|
|
||||||
% if product == "gecko":
|
|
||||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("-moz-block-height") => {
|
|
||||||
Ok(SpecifiedValue::MozBlockHeight)
|
|
||||||
}
|
|
||||||
% endif
|
|
||||||
_ => Err(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub mod computed_value {
|
|
||||||
use app_units::Au;
|
|
||||||
use values::CSSFloat;
|
|
||||||
#[derive(PartialEq, Copy, Clone, Debug)]
|
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
|
||||||
pub enum T {
|
|
||||||
Normal,
|
|
||||||
% if product == "gecko":
|
|
||||||
MozBlockHeight,
|
|
||||||
% endif
|
|
||||||
Length(Au),
|
|
||||||
Number(CSSFloat),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl ToCss for computed_value::T {
|
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
|
||||||
match *self {
|
|
||||||
computed_value::T::Normal => dest.write_str("normal"),
|
|
||||||
% if product == "gecko":
|
|
||||||
computed_value::T::MozBlockHeight => dest.write_str("-moz-block-height"),
|
|
||||||
% endif
|
|
||||||
computed_value::T::Length(length) => length.to_css(dest),
|
|
||||||
computed_value::T::Number(number) => write!(dest, "{}", number),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn get_initial_value() -> computed_value::T { computed_value::T::Normal }
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
|
||||||
SpecifiedValue::Normal
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToComputedValue for SpecifiedValue {
|
|
||||||
type ComputedValue = computed_value::T;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn to_computed_value(&self, context: &Context) -> computed_value::T {
|
|
||||||
match *self {
|
|
||||||
SpecifiedValue::Normal => computed_value::T::Normal,
|
|
||||||
% if product == "gecko":
|
|
||||||
SpecifiedValue::MozBlockHeight => computed_value::T::MozBlockHeight,
|
|
||||||
% endif
|
|
||||||
SpecifiedValue::Number(value) => computed_value::T::Number(value.to_computed_value(context)),
|
|
||||||
SpecifiedValue::LengthOrPercentage(ref value) => {
|
|
||||||
match *value {
|
|
||||||
specified::LengthOrPercentage::Length(ref value) =>
|
|
||||||
computed_value::T::Length(value.to_computed_value(context)),
|
|
||||||
specified::LengthOrPercentage::Percentage(specified::Percentage(value)) => {
|
|
||||||
let fr = specified::Length::NoCalc(specified::NoCalcLength::FontRelative(
|
|
||||||
specified::FontRelativeLength::Em(value)));
|
|
||||||
computed_value::T::Length(fr.to_computed_value(context))
|
|
||||||
},
|
|
||||||
specified::LengthOrPercentage::Calc(ref calc) => {
|
|
||||||
let calc = calc.to_computed_value(context);
|
|
||||||
let fr = specified::FontRelativeLength::Em(calc.percentage());
|
|
||||||
let fr = specified::Length::NoCalc(specified::NoCalcLength::FontRelative(fr));
|
|
||||||
let length = calc.unclamped_length();
|
|
||||||
computed_value::T::Length(calc.clamping_mode.clamp(length + fr.to_computed_value(context)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_computed_value(computed: &computed_value::T) -> Self {
|
|
||||||
match *computed {
|
|
||||||
computed_value::T::Normal => SpecifiedValue::Normal,
|
|
||||||
% if product == "gecko":
|
|
||||||
computed_value::T::MozBlockHeight => SpecifiedValue::MozBlockHeight,
|
|
||||||
% endif
|
|
||||||
computed_value::T::Number(ref value) => {
|
|
||||||
SpecifiedValue::Number(specified::Number::from_computed_value(value))
|
|
||||||
},
|
|
||||||
computed_value::T::Length(au) => {
|
|
||||||
SpecifiedValue::LengthOrPercentage(specified::LengthOrPercentage::Length(
|
|
||||||
ToComputedValue::from_computed_value(&au)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</%helpers:longhand>
|
|
||||||
|
|
||||||
// CSS Text Module Level 3
|
// CSS Text Module Level 3
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,9 @@ use shared_lock::StylesheetGuards;
|
||||||
use style_traits::{HasViewportPercentage, ToCss};
|
use style_traits::{HasViewportPercentage, ToCss};
|
||||||
use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData};
|
use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData};
|
||||||
#[cfg(feature = "servo")] use values::Either;
|
#[cfg(feature = "servo")] use values::Either;
|
||||||
use values::specified::Color;
|
use values::generics::text::LineHeight;
|
||||||
use values::computed;
|
use values::computed;
|
||||||
|
use values::specified::Color;
|
||||||
use cascade_info::CascadeInfo;
|
use cascade_info::CascadeInfo;
|
||||||
use rule_tree::{CascadeLevel, StrongRuleNode};
|
use rule_tree::{CascadeLevel, StrongRuleNode};
|
||||||
use style_adjuster::StyleAdjuster;
|
use style_adjuster::StyleAdjuster;
|
||||||
|
@ -1262,11 +1263,9 @@ impl PropertyDeclaration {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is it the default value of line-height?
|
/// Is it the default value of line-height?
|
||||||
///
|
|
||||||
/// (using match because it generates less code than)
|
|
||||||
pub fn is_default_line_height(&self) -> bool {
|
pub fn is_default_line_height(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
PropertyDeclaration::LineHeight(longhands::line_height::SpecifiedValue::Normal) => true,
|
PropertyDeclaration::LineHeight(LineHeight::Normal) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
${'font-language-override' if product == 'gecko' or data.testing else ''}
|
${'font-language-override' if product == 'gecko' or data.testing else ''}
|
||||||
${'font-feature-settings' if product == 'gecko' or data.testing else ''}"
|
${'font-feature-settings' if product == 'gecko' or data.testing else ''}"
|
||||||
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
|
||||||
|
use parser::Parse;
|
||||||
use properties::longhands::{font_family, font_style, font_weight, font_stretch};
|
use properties::longhands::{font_family, font_style, font_weight, font_stretch};
|
||||||
use properties::longhands::{font_size, line_height, font_variant_caps};
|
use properties::longhands::{font_size, font_variant_caps};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use properties::longhands::system_font::SystemFont;
|
use properties::longhands::system_font::SystemFont;
|
||||||
|
use values::specified::text::LineHeight;
|
||||||
|
|
||||||
<%
|
<%
|
||||||
gecko_sub_properties = "kerning language_override size_adjust \
|
gecko_sub_properties = "kerning language_override size_adjust \
|
||||||
|
@ -50,7 +52,7 @@
|
||||||
${name}: ${name}::SpecifiedValue::system_font(sys),
|
${name}: ${name}::SpecifiedValue::system_font(sys),
|
||||||
% endfor
|
% endfor
|
||||||
// line-height is just reset to initial
|
// line-height is just reset to initial
|
||||||
line_height: line_height::get_initial_specified_value(),
|
line_height: LineHeight::normal(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
@ -98,7 +100,7 @@
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
||||||
Some(try!(line_height::parse(context, input)))
|
Some(try!(LineHeight::parse(context, input)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -107,7 +109,7 @@
|
||||||
% for name in "style weight stretch size variant_caps".split():
|
% for name in "style weight stretch size variant_caps".split():
|
||||||
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
||||||
% endfor
|
% endfor
|
||||||
line_height: unwrap_or_initial!(line_height),
|
line_height: line_height.unwrap_or(LineHeight::normal()),
|
||||||
font_family: family,
|
font_family: family,
|
||||||
% if product == "gecko" or data.testing:
|
% if product == "gecko" or data.testing:
|
||||||
% for name in gecko_sub_properties:
|
% for name in gecko_sub_properties:
|
||||||
|
@ -169,12 +171,9 @@
|
||||||
|
|
||||||
self.font_size.to_css(dest)?;
|
self.font_size.to_css(dest)?;
|
||||||
|
|
||||||
match *self.line_height {
|
if *self.line_height != LineHeight::normal() {
|
||||||
line_height::SpecifiedValue::Normal => {},
|
dest.write_str("/")?;
|
||||||
_ => {
|
self.line_height.to_css(dest)?;
|
||||||
dest.write_str("/")?;
|
|
||||||
self.line_height.to_css(dest)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dest.write_str(" ")?;
|
dest.write_str(" ")?;
|
||||||
|
@ -197,7 +196,7 @@
|
||||||
all = false;
|
all = false;
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
if self.line_height != &line_height::get_initial_specified_value() {
|
if self.line_height != &LineHeight::normal() {
|
||||||
all = false
|
all = false
|
||||||
}
|
}
|
||||||
if all {
|
if all {
|
||||||
|
|
|
@ -38,6 +38,7 @@ pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrP
|
||||||
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
|
||||||
pub use self::length::{MaxLength, MozLength};
|
pub use self::length::{MaxLength, MozLength};
|
||||||
pub use self::position::Position;
|
pub use self::position::Position;
|
||||||
|
pub use self::text::LineHeight;
|
||||||
pub use self::transform::TransformOrigin;
|
pub use self::transform::TransformOrigin;
|
||||||
|
|
||||||
pub mod background;
|
pub mod background;
|
||||||
|
@ -47,6 +48,7 @@ pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod text;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
|
|
||||||
/// A `Context` is all the data a specified value could ever need to compute
|
/// A `Context` is all the data a specified value could ever need to compute
|
||||||
|
|
51
components/style/values/computed/text.rs
Normal file
51
components/style/values/computed/text.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Computed types for text properties.
|
||||||
|
|
||||||
|
use app_units::Au;
|
||||||
|
use properties::animated_properties::Animatable;
|
||||||
|
use values::CSSFloat;
|
||||||
|
use values::generics::text::LineHeight as GenericLineHeight;
|
||||||
|
|
||||||
|
/// A computed value for the `line-height` property.
|
||||||
|
pub type LineHeight = GenericLineHeight<CSSFloat, Au>;
|
||||||
|
|
||||||
|
impl Animatable for LineHeight {
|
||||||
|
#[inline]
|
||||||
|
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
|
||||||
|
match (*self, *other) {
|
||||||
|
(GenericLineHeight::Length(ref this), GenericLineHeight::Length(ref other)) => {
|
||||||
|
this.add_weighted(other, self_portion, other_portion).map(GenericLineHeight::Length)
|
||||||
|
},
|
||||||
|
(GenericLineHeight::Number(ref this), GenericLineHeight::Number(ref other)) => {
|
||||||
|
this.add_weighted(other, self_portion, other_portion).map(GenericLineHeight::Number)
|
||||||
|
},
|
||||||
|
(GenericLineHeight::Normal, GenericLineHeight::Normal) => {
|
||||||
|
Ok(GenericLineHeight::Normal)
|
||||||
|
},
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
(GenericLineHeight::MozBlockHeight, GenericLineHeight::MozBlockHeight) => {
|
||||||
|
Ok(GenericLineHeight::MozBlockHeight)
|
||||||
|
},
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
|
||||||
|
match (*self, *other) {
|
||||||
|
(GenericLineHeight::Length(ref this), GenericLineHeight::Length(ref other)) => {
|
||||||
|
this.compute_distance(other)
|
||||||
|
},
|
||||||
|
(GenericLineHeight::Number(ref this), GenericLineHeight::Number(ref other)) => {
|
||||||
|
this.compute_distance(other)
|
||||||
|
},
|
||||||
|
(GenericLineHeight::Normal, GenericLineHeight::Normal) => Ok(0.),
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
(GenericLineHeight::MozBlockHeight, GenericLineHeight::MozBlockHeight) => Ok(0.),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ pub mod grid;
|
||||||
pub mod image;
|
pub mod image;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod text;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
// https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
|
||||||
|
|
47
components/style/values/generics/text.rs
Normal file
47
components/style/values/generics/text.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Generic types for text properties.
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use style_traits::ToCss;
|
||||||
|
|
||||||
|
/// A generic value for the `line-height` property.
|
||||||
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
|
||||||
|
pub enum LineHeight<Number, LengthOrPercentage> {
|
||||||
|
/// `normal`
|
||||||
|
Normal,
|
||||||
|
/// `-moz-block-height`
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
MozBlockHeight,
|
||||||
|
/// `<number>`
|
||||||
|
Number(Number),
|
||||||
|
/// `<length-or-percentage>`
|
||||||
|
Length(LengthOrPercentage),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, L> LineHeight<N, L> {
|
||||||
|
/// Returns `normal`.
|
||||||
|
#[inline]
|
||||||
|
pub fn normal() -> Self {
|
||||||
|
LineHeight::Normal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, L> ToCss for LineHeight<N, L>
|
||||||
|
where N: ToCss, L: ToCss,
|
||||||
|
{
|
||||||
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
|
||||||
|
where W: fmt::Write,
|
||||||
|
{
|
||||||
|
match *self {
|
||||||
|
LineHeight::Normal => dest.write_str("normal"),
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
LineHeight::MozBlockHeight => dest.write_str("-moz-block-height"),
|
||||||
|
LineHeight::Number(ref number) => number.to_css(dest),
|
||||||
|
LineHeight::Length(ref value) => value.to_css(dest),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercent
|
||||||
pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength};
|
pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength};
|
||||||
pub use self::length::{MaxLength, MozLength};
|
pub use self::length::{MaxLength, MozLength};
|
||||||
pub use self::position::{Position, PositionComponent};
|
pub use self::position::{Position, PositionComponent};
|
||||||
|
pub use self::text::LineHeight;
|
||||||
pub use self::transform::TransformOrigin;
|
pub use self::transform::TransformOrigin;
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -58,6 +59,7 @@ pub mod image;
|
||||||
pub mod length;
|
pub mod length;
|
||||||
pub mod position;
|
pub mod position;
|
||||||
pub mod rect;
|
pub mod rect;
|
||||||
|
pub mod text;
|
||||||
pub mod transform;
|
pub mod transform;
|
||||||
|
|
||||||
/// Common handling for the specified value CSS url() values.
|
/// Common handling for the specified value CSS url() values.
|
||||||
|
|
97
components/style/values/specified/text.rs
Normal file
97
components/style/values/specified/text.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! Specified types for text properties.
|
||||||
|
|
||||||
|
use cssparser::Parser;
|
||||||
|
use parser::{Parse, ParserContext};
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
|
use values::computed::{Context, ToComputedValue};
|
||||||
|
use values::computed::text::LineHeight as ComputedLineHeight;
|
||||||
|
use values::generics::text::LineHeight as GenericLineHeight;
|
||||||
|
use values::specified::Number;
|
||||||
|
use values::specified::length::{FontRelativeLength, Length, LengthOrPercentage, NoCalcLength};
|
||||||
|
|
||||||
|
/// A specified value for the `line-height` property.
|
||||||
|
pub type LineHeight = GenericLineHeight<Number, LengthOrPercentage>;
|
||||||
|
|
||||||
|
impl Parse for LineHeight {
|
||||||
|
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
if let Ok(number) = input.try(|i| Number::parse_non_negative(context, i)) {
|
||||||
|
return Ok(GenericLineHeight::Number(number))
|
||||||
|
}
|
||||||
|
if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) {
|
||||||
|
return Ok(GenericLineHeight::Length(lop))
|
||||||
|
}
|
||||||
|
match &input.expect_ident()? {
|
||||||
|
ident if ident.eq_ignore_ascii_case("normal") => {
|
||||||
|
Ok(GenericLineHeight::Normal)
|
||||||
|
},
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
ident if ident.eq_ignore_ascii_case("-moz-block-height") => {
|
||||||
|
Ok(GenericLineHeight::MozBlockHeight)
|
||||||
|
},
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToComputedValue for LineHeight {
|
||||||
|
type ComputedValue = ComputedLineHeight;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
|
||||||
|
match *self {
|
||||||
|
GenericLineHeight::Normal => {
|
||||||
|
GenericLineHeight::Normal
|
||||||
|
},
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
GenericLineHeight::MozBlockHeight => {
|
||||||
|
GenericLineHeight::MozBlockHeight
|
||||||
|
},
|
||||||
|
GenericLineHeight::Number(number) => {
|
||||||
|
GenericLineHeight::Number(number.to_computed_value(context))
|
||||||
|
},
|
||||||
|
GenericLineHeight::Length(LengthOrPercentage::Length(ref length)) => {
|
||||||
|
GenericLineHeight::Length(length.to_computed_value(context))
|
||||||
|
},
|
||||||
|
GenericLineHeight::Length(LengthOrPercentage::Percentage(p)) => {
|
||||||
|
let font_relative_length =
|
||||||
|
Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(p.0)));
|
||||||
|
GenericLineHeight::Length(font_relative_length.to_computed_value(context))
|
||||||
|
},
|
||||||
|
GenericLineHeight::Length(LengthOrPercentage::Calc(ref calc)) => {
|
||||||
|
let computed_calc = calc.to_computed_value(context);
|
||||||
|
let font_relative_length =
|
||||||
|
Length::NoCalc(NoCalcLength::FontRelative(FontRelativeLength::Em(computed_calc.percentage())));
|
||||||
|
let absolute_length = computed_calc.unclamped_length();
|
||||||
|
let computed_length = computed_calc.clamping_mode.clamp(
|
||||||
|
absolute_length + font_relative_length.to_computed_value(context)
|
||||||
|
);
|
||||||
|
GenericLineHeight::Length(computed_length)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
|
||||||
|
match *computed {
|
||||||
|
GenericLineHeight::Normal => {
|
||||||
|
GenericLineHeight::Normal
|
||||||
|
},
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
GenericLineHeight::MozBlockHeight => {
|
||||||
|
GenericLineHeight::MozBlockHeight
|
||||||
|
},
|
||||||
|
GenericLineHeight::Number(ref number) => {
|
||||||
|
GenericLineHeight::Number(Number::from_computed_value(number))
|
||||||
|
},
|
||||||
|
GenericLineHeight::Length(ref length) => {
|
||||||
|
GenericLineHeight::Length(LengthOrPercentage::Length(
|
||||||
|
NoCalcLength::from_computed_value(length)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue