Skip to content

Commit

Permalink
Implement viewport percentage length units ('vw', 'vh', 'vmin', 'vmax')
Browse files Browse the repository at this point in the history
  • Loading branch information
luniv committed Mar 5, 2015
1 parent 16a8047 commit bc1c44b
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions components/style/media_queries.rs
Expand Up @@ -34,6 +34,8 @@ impl Range<specified::Length> {
let initial_font_size = longhands::font_size::get_initial_value();
value.to_computed_value(initial_font_size, initial_font_size)
}
&specified::Length::ViewportPercentage(value) =>
value.to_computed_value(viewport_size),
_ => unreachable!()
}
};
Expand Down
2 changes: 2 additions & 0 deletions components/style/properties.mako.rs
Expand Up @@ -19,6 +19,7 @@ use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser,
DeclarationListParser, parse_important, ToCss};
use geom::num::Zero;
use geom::SideOffsets2D;
use geom::size::Size2D;

use values::specified::BorderStyle;
use values::computed::{self, ToComputedValue};
Expand Down Expand Up @@ -3732,6 +3733,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
let inherited_font_style = inherited_style.get_font();
computed::Context {
is_root_element: is_root_element,
viewport_size: viewport_size,
inherited_font_weight: inherited_font_style.font_weight,
inherited_font_size: inherited_font_style.font_size,
inherited_height: inherited_style.get_box().height,
Expand Down
60 changes: 60 additions & 0 deletions components/style/values.rs
Expand Up @@ -52,11 +52,14 @@ pub type CSSFloat = f64;

pub mod specified {
use std::ascii::AsciiExt;
use std::cmp;
use std::f64::consts::PI;
use std::fmt;
use std::fmt::{Formatter, Debug};
use std::num::{NumCast, ToPrimitive};
use url::Url;
use cssparser::{self, Token, Parser, ToCss, CssStringWriter};
use geom::size::Size2D;
use parser::ParserContext;
use text_writer::{self, TextWriter};
use util::geometry::Au;
Expand Down Expand Up @@ -154,6 +157,51 @@ pub mod specified {
}
}

#[derive(Clone, PartialEq, Copy)]
pub enum ViewportPercentageLength {
Vw(CSSFloat),
Vh(CSSFloat),
Vmin(CSSFloat),
Vmax(CSSFloat)
}

impl fmt::Debug for ViewportPercentageLength {
#[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_to_css(f) }
}

impl ToCss for ViewportPercentageLength {
fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
match self {
&ViewportPercentageLength::Vw(length) => write!(dest, "{}vw", length),
&ViewportPercentageLength::Vh(length) => write!(dest, "{}vh", length),
&ViewportPercentageLength::Vmin(length) => write!(dest, "{}vmin", length),
&ViewportPercentageLength::Vmax(length) => write!(dest, "{}vmax", length)
}
}
}

impl ViewportPercentageLength {
pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> Au {
macro_rules! to_unit {
($viewport_dimension:expr) => {
$viewport_dimension.to_f64().unwrap() / 100.0
}
}

let value = match self {
&ViewportPercentageLength::Vw(length) =>
length * to_unit!(viewport_size.width),
&ViewportPercentageLength::Vh(length) =>
length * to_unit!(viewport_size.height),
&ViewportPercentageLength::Vmin(length) =>
length * to_unit!(cmp::min(viewport_size.width, viewport_size.height)),
&ViewportPercentageLength::Vmax(length) =>
length * to_unit!(cmp::max(viewport_size.width, viewport_size.height)),
};
NumCast::from(value).unwrap()
}
}

#[derive(Clone, PartialEq, Copy)]
pub struct CharacterWidth(pub i32);

Expand All @@ -173,6 +221,8 @@ pub mod specified {
pub enum Length {
Absolute(Au), // application units
FontRelative(FontRelativeLength),
ViewportPercentage(ViewportPercentageLength),

/// HTML5 "character width", as defined in HTML5 § 14.5.4.
///
/// This cannot be specified by the user directly and is only generated by
Expand All @@ -189,6 +239,7 @@ pub mod specified {
match self {
&Length::Absolute(length) => write!(dest, "{}px", length.to_subpx()),
&Length::FontRelative(length) => length.to_css(dest),
&Length::ViewportPercentage(length) => length.to_css(dest),
&Length::ServoCharacterWidth(_)
=> panic!("internal CSS values should never be serialized"),
}
Expand Down Expand Up @@ -232,6 +283,11 @@ pub mod specified {
"ex" => Ok(Length::FontRelative(FontRelativeLength::Ex(value))),
"ch" => Err(()),
"rem" => Ok(Length::FontRelative(FontRelativeLength::Rem(value))),
// viewport percentages
"vw" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vw(value))),
"vh" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vh(value))),
"vmin" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmin(value))),
"vmax" => Ok(Length::ViewportPercentage(ViewportPercentageLength::Vmax(value)))
_ => Err(())
}
}
Expand Down Expand Up @@ -701,6 +757,7 @@ pub mod computed {
use super::specified::{AngleOrCorner};
use super::{specified, CSSFloat};
pub use cssparser::Color as CSSColor;
use geom::size::Size2D;
use properties::longhands;
use std::fmt;
use url::Url;
Expand All @@ -727,6 +784,7 @@ pub mod computed {
pub border_bottom_present: bool,
pub border_left_present: bool,
pub is_root_element: bool,
pub viewport_size: Size2D<Au>
// TODO, as needed: viewport size, etc.
}

Expand Down Expand Up @@ -768,6 +826,8 @@ pub mod computed {
&specified::Length::Absolute(length) => length,
&specified::Length::FontRelative(length) =>
length.to_computed_value(context.font_size, context.root_font_size),
&specified::Length::ViewportPercentage(length) =>
length.to_computed_value(context.viewport_size),
&specified::Length::ServoCharacterWidth(length) =>
length.to_computed_value(context.font_size)
}
Expand Down

0 comments on commit bc1c44b

Please sign in to comment.