mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +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::mem;
|
||||
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::logical_geometry::{LogicalSize, WritingMode};
|
||||
use style::properties::ServoComputedValues;
|
||||
use style::properties::style_structs;
|
||||
use style::values::generics::text::LineHeight;
|
||||
use unicode_bidi as bidi;
|
||||
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 {
|
||||
let font_size = style.get_font().font_size;
|
||||
match style.get_inheritedtext().line_height {
|
||||
line_height::T::Normal => metrics.line_gap,
|
||||
line_height::T::Number(l) => font_size.scale_by(l),
|
||||
line_height::T::Length(l) => l
|
||||
LineHeight::Normal => metrics.line_gap,
|
||||
LineHeight::Number(l) => font_size.scale_by(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) {
|
||||
use properties::longhands::line_height::computed_value::T;
|
||||
use values::generics::text::LineHeight;
|
||||
// FIXME: Align binary representations and ditch |match| for cast + static_asserts
|
||||
let en = match v {
|
||||
T::Normal => CoordDataValue::Normal,
|
||||
T::Length(val) => CoordDataValue::Coord(val.0),
|
||||
T::Number(val) => CoordDataValue::Factor(val),
|
||||
T::MozBlockHeight =>
|
||||
LineHeight::Normal => CoordDataValue::Normal,
|
||||
LineHeight::Length(val) => CoordDataValue::Coord(val.0),
|
||||
LineHeight::Number(val) => CoordDataValue::Factor(val),
|
||||
LineHeight::MozBlockHeight =>
|
||||
CoordDataValue::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
|
||||
};
|
||||
self.gecko.mLineHeight.set_value(en);
|
||||
}
|
||||
|
||||
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() {
|
||||
CoordDataValue::Normal => T::Normal,
|
||||
CoordDataValue::Coord(coord) => T::Length(Au(coord)),
|
||||
CoordDataValue::Factor(n) => T::Number(n),
|
||||
CoordDataValue::Normal => LineHeight::Normal,
|
||||
CoordDataValue::Coord(coord) => LineHeight::Length(Au(coord)),
|
||||
CoordDataValue::Factor(n) => LineHeight::Number(n),
|
||||
CoordDataValue::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
|
||||
T::MozBlockHeight,
|
||||
_ => {
|
||||
debug_assert!(false);
|
||||
T::MozBlockHeight
|
||||
}
|
||||
LineHeight::MozBlockHeight,
|
||||
_ => panic!("this should not happen"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ use properties::longhands;
|
|||
use properties::longhands::background_size::computed_value::T as BackgroundSizeList;
|
||||
use properties::longhands::font_weight::computed_value::T as FontWeight;
|
||||
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::TextShadow;
|
||||
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
|
||||
impl Animatable for FontWeight {
|
||||
#[inline]
|
||||
|
|
|
@ -6,148 +6,11 @@
|
|||
<% from data import Keyword %>
|
||||
<% data.new_style_struct("InheritedText", inherited=True, gecko_name="Text") %>
|
||||
|
||||
<%helpers:longhand name="line-height" animation_value_type="ComputedValue"
|
||||
spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
|
||||
#[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>
|
||||
${helpers.predefined_type("line-height",
|
||||
"LineHeight",
|
||||
"computed::LineHeight::normal()",
|
||||
animation_value_type="ComputedValue",
|
||||
spec="https://drafts.csswg.org/css2/visudet.html#propdef-line-height")}
|
||||
|
||||
// CSS Text Module Level 3
|
||||
|
||||
|
|
|
@ -38,8 +38,9 @@ use shared_lock::StylesheetGuards;
|
|||
use style_traits::{HasViewportPercentage, ToCss};
|
||||
use stylesheets::{CssRuleType, MallocSizeOf, MallocSizeOfFn, Origin, UrlExtraData};
|
||||
#[cfg(feature = "servo")] use values::Either;
|
||||
use values::specified::Color;
|
||||
use values::generics::text::LineHeight;
|
||||
use values::computed;
|
||||
use values::specified::Color;
|
||||
use cascade_info::CascadeInfo;
|
||||
use rule_tree::{CascadeLevel, StrongRuleNode};
|
||||
use style_adjuster::StyleAdjuster;
|
||||
|
@ -1262,11 +1263,9 @@ impl PropertyDeclaration {
|
|||
}
|
||||
|
||||
/// Is it the default value of line-height?
|
||||
///
|
||||
/// (using match because it generates less code than)
|
||||
pub fn is_default_line_height(&self) -> bool {
|
||||
match *self {
|
||||
PropertyDeclaration::LineHeight(longhands::line_height::SpecifiedValue::Normal) => true,
|
||||
PropertyDeclaration::LineHeight(LineHeight::Normal) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,12 @@
|
|||
${'font-language-override' 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">
|
||||
use parser::Parse;
|
||||
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")]
|
||||
use properties::longhands::system_font::SystemFont;
|
||||
use values::specified::text::LineHeight;
|
||||
|
||||
<%
|
||||
gecko_sub_properties = "kerning language_override size_adjust \
|
||||
|
@ -50,7 +52,7 @@
|
|||
${name}: ${name}::SpecifiedValue::system_font(sys),
|
||||
% endfor
|
||||
// line-height is just reset to initial
|
||||
line_height: line_height::get_initial_specified_value(),
|
||||
line_height: LineHeight::normal(),
|
||||
})
|
||||
}
|
||||
% endif
|
||||
|
@ -98,7 +100,7 @@
|
|||
return Err(())
|
||||
}
|
||||
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 {
|
||||
None
|
||||
};
|
||||
|
@ -107,7 +109,7 @@
|
|||
% for name in "style weight stretch size variant_caps".split():
|
||||
font_${name}: unwrap_or_initial!(font_${name}, ${name}),
|
||||
% endfor
|
||||
line_height: unwrap_or_initial!(line_height),
|
||||
line_height: line_height.unwrap_or(LineHeight::normal()),
|
||||
font_family: family,
|
||||
% if product == "gecko" or data.testing:
|
||||
% for name in gecko_sub_properties:
|
||||
|
@ -169,12 +171,9 @@
|
|||
|
||||
self.font_size.to_css(dest)?;
|
||||
|
||||
match *self.line_height {
|
||||
line_height::SpecifiedValue::Normal => {},
|
||||
_ => {
|
||||
dest.write_str("/")?;
|
||||
self.line_height.to_css(dest)?;
|
||||
}
|
||||
if *self.line_height != LineHeight::normal() {
|
||||
dest.write_str("/")?;
|
||||
self.line_height.to_css(dest)?;
|
||||
}
|
||||
|
||||
dest.write_str(" ")?;
|
||||
|
@ -197,7 +196,7 @@
|
|||
all = false;
|
||||
}
|
||||
% endfor
|
||||
if self.line_height != &line_height::get_initial_specified_value() {
|
||||
if self.line_height != &LineHeight::normal() {
|
||||
all = false
|
||||
}
|
||||
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::{MaxLength, MozLength};
|
||||
pub use self::position::Position;
|
||||
pub use self::text::LineHeight;
|
||||
pub use self::transform::TransformOrigin;
|
||||
|
||||
pub mod background;
|
||||
|
@ -47,6 +48,7 @@ pub mod image;
|
|||
pub mod length;
|
||||
pub mod position;
|
||||
pub mod rect;
|
||||
pub mod text;
|
||||
pub mod transform;
|
||||
|
||||
/// 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 position;
|
||||
pub mod rect;
|
||||
pub mod text;
|
||||
pub mod transform;
|
||||
|
||||
// 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::{MaxLength, MozLength};
|
||||
pub use self::position::{Position, PositionComponent};
|
||||
pub use self::text::LineHeight;
|
||||
pub use self::transform::TransformOrigin;
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -58,6 +59,7 @@ pub mod image;
|
|||
pub mod length;
|
||||
pub mod position;
|
||||
pub mod rect;
|
||||
pub mod text;
|
||||
pub mod transform;
|
||||
|
||||
/// 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