Make computed types hold Percentage instead of bare CSSFloat

This commit is contained in:
Anthony Ramine 2017-06-15 15:01:30 +02:00
parent 4b633c8637
commit 608e7f71a2
22 changed files with 140 additions and 110 deletions

View file

@ -322,7 +322,7 @@ impl CandidateBSizeIterator {
let block_size = match (fragment.style.content_block_size(), block_container_block_size) {
(LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => {
MaybeAuto::Specified(block_container_block_size.scale_by(percent))
MaybeAuto::Specified(block_container_block_size.scale_by(percent.0))
}
(LengthOrPercentageOrAuto::Calc(calc), _) => {
MaybeAuto::from_option(calc.to_used_value(block_container_block_size))
@ -333,7 +333,7 @@ impl CandidateBSizeIterator {
};
let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) {
(LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => {
Some(block_container_block_size.scale_by(percent))
Some(block_container_block_size.scale_by(percent.0))
}
(LengthOrPercentageOrNone::Calc(calc), _) => {
calc.to_used_value(block_container_block_size)
@ -344,7 +344,7 @@ impl CandidateBSizeIterator {
};
let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) {
(LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => {
block_container_block_size.scale_by(percent)
block_container_block_size.scale_by(percent.0)
}
(LengthOrPercentage::Calc(calc), _) => {
calc.to_used_value(block_container_block_size).unwrap_or(Au(0))
@ -1178,7 +1178,7 @@ impl BlockFlow {
}
(LengthOrPercentageOrAuto::Length(length), _) => Some(length),
(LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
Some(container_size.scale_by(percent))
Some(container_size.scale_by(percent.0))
}
(LengthOrPercentageOrAuto::Percentage(_), None) |
(LengthOrPercentageOrAuto::Auto, None) => {

View file

@ -65,6 +65,7 @@ use style::values::generics::image::{Circle, Ellipse, EndingShape as GenericEndi
use style::values::generics::image::{GradientItem as GenericGradientItem, GradientKind};
use style::values::generics::image::{Image, ShapeExtent};
use style::values::generics::image::PaintWorklet;
use style::values::specified::length::Percentage;
use style::values::specified::position::{X, Y};
use style_traits::CSSPixel;
use style_traits::cursor::Cursor;
@ -653,14 +654,14 @@ fn convert_gradient_stops(gradient_items: &[GradientItem],
{
let first = stop_items.first_mut().unwrap();
if first.position.is_none() {
first.position = Some(LengthOrPercentage::Percentage(0.0));
first.position = Some(LengthOrPercentage::Percentage(Percentage(0.0)));
}
}
// If the last color stop does not have a position, set its position to 100%.
{
let last = stop_items.last_mut().unwrap();
if last.position.is_none() {
last.position = Some(LengthOrPercentage::Percentage(1.0));
last.position = Some(LengthOrPercentage::Percentage(Percentage(1.0)));
}
}
@ -2871,7 +2872,7 @@ struct StopRun {
fn position_to_offset(position: LengthOrPercentage, total_length: Au) -> f32 {
match position {
LengthOrPercentage::Length(Au(length)) => length as f32 / total_length.0 as f32,
LengthOrPercentage::Percentage(percentage) => percentage as f32,
LengthOrPercentage::Percentage(percentage) => percentage.0 as f32,
LengthOrPercentage::Calc(calc) => {
calc.to_used_value(Some(total_length)).unwrap().0 as f32 / total_length.0 as f32
},

View file

@ -46,7 +46,7 @@ impl AxisSize {
LengthOrPercentageOrAuto::Length(length) => AxisSize::Definite(length),
LengthOrPercentageOrAuto::Percentage(percent) => {
match content_size {
Some(size) => AxisSize::Definite(size.scale_by(percent)),
Some(size) => AxisSize::Definite(size.scale_by(percent.0)),
None => AxisSize::Infinite
}
}
@ -74,7 +74,7 @@ fn from_flex_basis(flex_basis: LengthOrPercentageOrAutoOrContent,
(LengthOrPercentageOrAutoOrContent::Length(length), _) =>
MaybeAuto::Specified(length),
(LengthOrPercentageOrAutoOrContent::Percentage(percent), Some(size)) =>
MaybeAuto::Specified(size.scale_by(percent)),
MaybeAuto::Specified(size.scale_by(percent.0)),
(LengthOrPercentageOrAutoOrContent::Percentage(_), None) =>
MaybeAuto::Auto,
(LengthOrPercentageOrAutoOrContent::Calc(calc), _) =>

View file

@ -505,7 +505,7 @@ impl SpeculatedFloatPlacement {
// might flow around this float.
if let LengthOrPercentageOrAuto::Percentage(percentage) =
flow.as_block().fragment.style.content_inline_size() {
if percentage > 0.0 {
if percentage.0 > 0.0 {
float_inline_size = Au::from_px(1)
}
}

View file

@ -2234,7 +2234,7 @@ impl Fragment {
}
vertical_align::T::LengthOrPercentage(LengthOrPercentage::Percentage(
percentage)) => {
offset -= minimum_line_metrics.space_needed().scale_by(percentage)
offset -= minimum_line_metrics.space_needed().scale_by(percentage.0)
}
vertical_align::T::LengthOrPercentage(LengthOrPercentage::Calc(formula)) => {
offset -= formula.to_used_value(Some(minimum_line_metrics.space_needed())).unwrap()

View file

@ -144,7 +144,7 @@ impl MarginCollapseInfo {
LengthOrPercentageOrAuto::Auto => true,
LengthOrPercentageOrAuto::Length(Au(v)) => v == 0,
LengthOrPercentageOrAuto::Percentage(v) => {
v == 0. || containing_block_size.is_none()
v.0 == 0. || containing_block_size.is_none()
}
LengthOrPercentageOrAuto::Calc(_) => false,
};
@ -154,7 +154,7 @@ impl MarginCollapseInfo {
LengthOrPercentage::Length(Au(0)) => {
FinalMarginState::MarginsCollapseThrough
},
LengthOrPercentage::Percentage(v) if v == 0. => {
LengthOrPercentage::Percentage(v) if v.0 == 0. => {
FinalMarginState::MarginsCollapseThrough
},
_ => {
@ -408,7 +408,7 @@ impl MaybeAuto {
match length {
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
LengthOrPercentageOrAuto::Percentage(percent) => {
MaybeAuto::Specified(containing_length.scale_by(percent))
MaybeAuto::Specified(containing_length.scale_by(percent.0))
}
LengthOrPercentageOrAuto::Calc(calc) => {
MaybeAuto::from_option(calc.to_used_value(Some(containing_length)))

View file

@ -253,7 +253,7 @@ impl Flow for TableFlow {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.0,
},
preferred: Au(0),
constrained: false,

View file

@ -310,7 +310,7 @@ impl Flow for TableRowFlow {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Calc(_) |
LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.0,
},
preferred: child_base.intrinsic_inline_sizes.preferred_inline_size,
constrained: match child_specified_inline_size {

View file

@ -19,13 +19,14 @@ use stylesheets::{Origin, RulesMutateError};
use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use values::generics::image::{CompatMode, Image as GenericImage, GradientItem};
use values::specified::length::Percentage;
impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue {
let has_percentage = other.percentage.is_some();
nsStyleCoord_CalcValue {
mLength: other.unclamped_length().0,
mPercent: other.percentage.unwrap_or(0.0),
mPercent: other.percentage.map_or(0., |p| p.0),
mHasPercent: has_percentage,
}
}
@ -34,7 +35,7 @@ impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue {
impl From<nsStyleCoord_CalcValue> for CalcLengthOrPercentage {
fn from(other: nsStyleCoord_CalcValue) -> CalcLengthOrPercentage {
let percentage = if other.mHasPercent {
Some(other.mPercent)
Some(Percentage(other.mPercent))
} else {
None
};
@ -55,7 +56,7 @@ impl From<LengthOrPercentage> for nsStyleCoord_CalcValue {
LengthOrPercentage::Percentage(pc) => {
nsStyleCoord_CalcValue {
mLength: 0,
mPercent: pc,
mPercent: pc.0,
mHasPercent: true,
}
},
@ -78,7 +79,7 @@ impl LengthOrPercentageOrAuto {
LengthOrPercentageOrAuto::Percentage(pc) => {
Some(nsStyleCoord_CalcValue {
mLength: 0,
mPercent: pc,
mPercent: pc.0,
mHasPercent: true,
})
},
@ -92,7 +93,7 @@ impl From<nsStyleCoord_CalcValue> for LengthOrPercentage {
fn from(other: nsStyleCoord_CalcValue) -> LengthOrPercentage {
match (other.mHasPercent, other.mLength) {
(false, _) => LengthOrPercentage::Length(Au(other.mLength)),
(true, 0) => LengthOrPercentage::Percentage(other.mPercent),
(true, 0) => LengthOrPercentage::Percentage(Percentage(other.mPercent)),
_ => LengthOrPercentage::Calc(other.into()),
}
}

View file

@ -105,7 +105,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentage {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentage::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p),
LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p.0),
LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
coord.set_value(value);
@ -114,7 +114,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentage {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(Percentage(p))),
CoordDataValue::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
_ => None,
}
@ -138,7 +138,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentageOrAuto::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p),
LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p.0),
LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto,
LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
@ -148,7 +148,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(Percentage(p))),
CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto),
CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
_ => None,
@ -160,7 +160,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
LengthOrPercentageOrNone::Length(au) => CoordDataValue::Coord(au.0),
LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p),
LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p.0),
LengthOrPercentageOrNone::None => CoordDataValue::None,
LengthOrPercentageOrNone::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
@ -170,7 +170,7 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
match coord.as_value() {
CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(Percentage(p))),
CoordDataValue::None => Some(LengthOrPercentageOrNone::None),
CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
_ => None,

View file

@ -15,6 +15,7 @@ use std::mem;
use std::ops::{Index, IndexMut};
use std::slice;
use values::computed::{Angle, LengthOrPercentage};
use values::specified::length::Percentage;
use values::specified::url::SpecifiedUrl;
impl nsCSSValue {
@ -79,7 +80,7 @@ impl nsCSSValue {
bindings::Gecko_CSSValue_SetAbsoluteLength(self, au.0)
}
LengthOrPercentage::Percentage(pc) => {
bindings::Gecko_CSSValue_SetPercentage(self, pc)
bindings::Gecko_CSSValue_SetPercentage(self, pc.0)
}
LengthOrPercentage::Calc(calc) => {
bindings::Gecko_CSSValue_SetCalc(self, calc.into())
@ -94,7 +95,7 @@ impl nsCSSValue {
LengthOrPercentage::Length(Au(bindings::Gecko_CSSValue_GetAbsoluteLength(self)))
},
nsCSSUnit::eCSSUnit_Percent => {
LengthOrPercentage::Percentage(bindings::Gecko_CSSValue_GetPercentage(self))
LengthOrPercentage::Percentage(Percentage(bindings::Gecko_CSSValue_GetPercentage(self)))
},
nsCSSUnit::eCSSUnit_Calc => {
LengthOrPercentage::Calc(bindings::Gecko_CSSValue_GetCalc(self).into())

View file

@ -65,6 +65,7 @@ use stylearc::Arc;
use std::cmp;
use values::{Auto, CustomIdent, Either, KeyframesName};
use values::computed::{Shadow, ToComputedValue};
use values::specified::length::Percentage;
use computed_values::border_style;
pub mod style_structs {
@ -4045,7 +4046,7 @@ clip-path
CoordDataValue::Coord(coord) =>
vec.push(Either::Second(LengthOrPercentage::Length(Au(coord)))),
CoordDataValue::Percent(p) =>
vec.push(Either::Second(LengthOrPercentage::Percentage(p))),
vec.push(Either::Second(LengthOrPercentage::Percentage(Percentage(p)))),
CoordDataValue::Calc(calc) =>
vec.push(Either::Second(LengthOrPercentage::Calc(calc.into()))),
_ => unreachable!(),
@ -4068,7 +4069,7 @@ clip-path
match self.gecko.mStrokeDashoffset.as_value() {
CoordDataValue::Factor(number) => Either::First(number),
CoordDataValue::Coord(coord) => Either::Second(LengthOrPercentage::Length(Au(coord))),
CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(p)),
CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(Percentage(p))),
CoordDataValue::Calc(calc) => Either::Second(LengthOrPercentage::Calc(calc.into())),
_ => unreachable!(),
}
@ -4088,7 +4089,7 @@ clip-path
match self.gecko.mStrokeWidth.as_value() {
CoordDataValue::Factor(number) => Either::First(number),
CoordDataValue::Coord(coord) => Either::Second(LengthOrPercentage::Length(Au(coord))),
CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(p)),
CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(Percentage(p))),
CoordDataValue::Calc(calc) => Either::Second(LengthOrPercentage::Calc(calc.into())),
_ => unreachable!(),
}

View file

@ -41,6 +41,7 @@ use values::computed::{LengthOrPercentage, MaxLength, MozLength, Shadow, ToCompu
use values::generics::{SVGPaint, SVGPaintKind};
use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius;
use values::generics::position as generic_position;
use values::specified::length::Percentage;
/// A longhand property whose animation type is not "none".
@ -941,6 +942,22 @@ impl Animatable for Angle {
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-percentage
impl Animatable for Percentage {
#[inline]
fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> {
Ok(Percentage((self.0 as f64 * self_portion + other.0 as f64 * other_portion) as f32))
}
#[inline]
fn get_zero_value(&self) -> Option<Self> { Some(Percentage(0.)) }
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
Ok((self.0 as f64 - other.0 as f64).abs())
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-visibility
impl Animatable for Visibility {
#[inline]
@ -1150,7 +1167,7 @@ impl Animatable for LengthOrPercentage {
},
(LengthOrPercentage::Percentage(ref this),
LengthOrPercentage::Percentage(ref other)) => {
let diff = (this - other) as f64;
let diff = this.0 as f64 - other.0 as f64;
Ok(diff * diff)
},
(this, other) => {
@ -1235,7 +1252,7 @@ impl Animatable for LengthOrPercentageOrAuto {
},
(LengthOrPercentageOrAuto::Percentage(ref this),
LengthOrPercentageOrAuto::Percentage(ref other)) => {
let diff = (this - other) as f64;
let diff = this.0 as f64 - other.0 as f64;
Ok(diff * diff)
},
(this, other) => {

View file

@ -11,7 +11,8 @@ use style_traits::ToCss;
use style_traits::values::specified::AllowedLengthType;
use super::{Number, ToComputedValue, Context};
use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified};
use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength, ViewportPercentageLength};
use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength};
use values::specified::length::{Percentage, ViewportPercentageLength};
pub use super::image::Image;
pub use values::specified::{Angle, BorderStyle, Time, UrlOrNone};
@ -65,20 +66,20 @@ impl ToComputedValue for specified::Length {
pub struct CalcLengthOrPercentage {
pub clamping_mode: AllowedLengthType,
length: Au,
pub percentage: Option<CSSFloat>,
pub percentage: Option<Percentage>,
}
impl CalcLengthOrPercentage {
/// Returns a new `CalcLengthOrPercentage`.
#[inline]
pub fn new(length: Au, percentage: Option<CSSFloat>) -> Self {
pub fn new(length: Au, percentage: Option<Percentage>) -> Self {
Self::with_clamping_mode(length, percentage, AllowedLengthType::All)
}
/// Returns a new `CalcLengthOrPercentage` with a specific clamping mode.
#[inline]
pub fn with_clamping_mode(length: Au,
percentage: Option<CSSFloat>,
percentage: Option<Percentage>,
clamping_mode: AllowedLengthType)
-> Self {
Self {
@ -106,7 +107,7 @@ impl CalcLengthOrPercentage {
#[inline]
#[allow(missing_docs)]
pub fn percentage(&self) -> CSSFloat {
self.percentage.unwrap_or(0.)
self.percentage.map_or(0., |p| p.0)
}
/// If there are special rules for computing percentages in a value (e.g. the height property),
@ -114,7 +115,7 @@ impl CalcLengthOrPercentage {
pub fn to_used_value(&self, container_len: Option<Au>) -> Option<Au> {
match (container_len, self.percentage) {
(Some(len), Some(percent)) => {
Some(self.clamping_mode.clamp(self.length + len.scale_by(percent)))
Some(self.clamping_mode.clamp(self.length + len.scale_by(percent.0)))
},
(_, None) => Some(self.length()),
_ => None,
@ -179,8 +180,8 @@ impl From<LengthOrPercentageOrNone> for Option<CalcLengthOrPercentage> {
impl ToCss for CalcLengthOrPercentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match (self.length, self.percentage) {
(l, Some(p)) if l == Au(0) => write!(dest, "{}%", p * 100.),
(l, Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p * 100.),
(l, Some(p)) if l == Au(0) => p.to_css(dest),
(l, Some(p)) => write!(dest, "calc({}px + {}%)", Au::to_px(l), p.0 * 100.),
(l, None) => write!(dest, "{}px", Au::to_px(l)),
}
}
@ -237,7 +238,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
#[allow(missing_docs)]
pub enum LengthOrPercentage {
Length(Au),
Percentage(CSSFloat),
Percentage(Percentage),
Calc(CalcLengthOrPercentage),
}
@ -269,7 +270,7 @@ impl LengthOrPercentage {
use self::LengthOrPercentage::*;
match *self {
Length(Au(0)) => true,
Percentage(p) => p == 0.0,
Percentage(p) => p.0 == 0.0,
Length(_) | Calc(_) => false
}
}
@ -279,7 +280,7 @@ impl LengthOrPercentage {
use self::LengthOrPercentage::*;
match *self {
Length(l) => (l, NotNaN::new(0.0).unwrap()),
Percentage(p) => (Au(0), NotNaN::new(p).unwrap()),
Percentage(p) => (Au(0), NotNaN::new(p.0).unwrap()),
Calc(c) => (c.unclamped_length(), NotNaN::new(c.percentage()).unwrap()),
}
}
@ -288,7 +289,7 @@ impl LengthOrPercentage {
pub fn to_used_value(&self, containing_length: Au) -> Au {
match *self {
LengthOrPercentage::Length(length) => length,
LengthOrPercentage::Percentage(p) => containing_length.scale_by(p),
LengthOrPercentage::Percentage(p) => containing_length.scale_by(p.0),
LengthOrPercentage::Calc(ref calc) => {
calc.to_used_value(Some(containing_length)).unwrap()
},
@ -300,7 +301,7 @@ impl fmt::Debug for LengthOrPercentage {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LengthOrPercentage::Length(length) => write!(f, "{:?}", length),
LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
LengthOrPercentage::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.),
LengthOrPercentage::Calc(calc) => write!(f, "{:?}", calc),
}
}
@ -315,7 +316,7 @@ impl ToComputedValue for specified::LengthOrPercentage {
LengthOrPercentage::Length(value.to_computed_value(context))
}
specified::LengthOrPercentage::Percentage(value) => {
LengthOrPercentage::Percentage(value.0)
LengthOrPercentage::Percentage(value)
}
specified::LengthOrPercentage::Calc(ref calc) => {
LengthOrPercentage::Calc(calc.to_computed_value(context))
@ -331,7 +332,7 @@ impl ToComputedValue for specified::LengthOrPercentage {
)
}
LengthOrPercentage::Percentage(value) => {
specified::LengthOrPercentage::Percentage(specified::Percentage(value))
specified::LengthOrPercentage::Percentage(value)
}
LengthOrPercentage::Calc(ref calc) => {
specified::LengthOrPercentage::Calc(
@ -346,8 +347,7 @@ impl ToCss for LengthOrPercentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
LengthOrPercentage::Length(length) => length.to_css(dest),
LengthOrPercentage::Percentage(percentage)
=> write!(dest, "{}%", percentage * 100.),
LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest),
LengthOrPercentage::Calc(calc) => calc.to_css(dest),
}
}
@ -358,7 +358,7 @@ impl ToCss for LengthOrPercentage {
#[allow(missing_docs)]
pub enum LengthOrPercentageOrAuto {
Length(Au),
Percentage(CSSFloat),
Percentage(Percentage),
Auto,
Calc(CalcLengthOrPercentage),
}
@ -372,7 +372,7 @@ impl LengthOrPercentageOrAuto {
use self::LengthOrPercentageOrAuto::*;
match *self {
Length(Au(0)) => true,
Percentage(p) => p == 0.0,
Percentage(p) => p.0 == 0.0,
Length(_) | Calc(_) | Auto => false
}
}
@ -382,7 +382,7 @@ impl fmt::Debug for LengthOrPercentageOrAuto {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LengthOrPercentageOrAuto::Length(length) => write!(f, "{:?}", length),
LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
LengthOrPercentageOrAuto::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.),
LengthOrPercentageOrAuto::Auto => write!(f, "auto"),
LengthOrPercentageOrAuto::Calc(calc) => write!(f, "{:?}", calc),
}
@ -399,7 +399,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
}
specified::LengthOrPercentageOrAuto::Percentage(value) => {
LengthOrPercentageOrAuto::Percentage(value.0)
LengthOrPercentageOrAuto::Percentage(value)
}
specified::LengthOrPercentageOrAuto::Auto => {
LengthOrPercentageOrAuto::Auto
@ -420,7 +420,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto {
)
}
LengthOrPercentageOrAuto::Percentage(value) => {
specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(value))
specified::LengthOrPercentageOrAuto::Percentage(value)
}
LengthOrPercentageOrAuto::Calc(calc) => {
specified::LengthOrPercentageOrAuto::Calc(
@ -435,8 +435,7 @@ impl ToCss for LengthOrPercentageOrAuto {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
LengthOrPercentageOrAuto::Length(length) => length.to_css(dest),
LengthOrPercentageOrAuto::Percentage(percentage)
=> write!(dest, "{}%", percentage * 100.),
LengthOrPercentageOrAuto::Percentage(percentage) => percentage.to_css(dest),
LengthOrPercentageOrAuto::Auto => dest.write_str("auto"),
LengthOrPercentageOrAuto::Calc(calc) => calc.to_css(dest),
}
@ -448,7 +447,7 @@ impl ToCss for LengthOrPercentageOrAuto {
#[allow(missing_docs)]
pub enum LengthOrPercentageOrAutoOrContent {
Length(Au),
Percentage(CSSFloat),
Percentage(Percentage),
Calc(CalcLengthOrPercentage),
Auto,
Content
@ -458,7 +457,7 @@ impl fmt::Debug for LengthOrPercentageOrAutoOrContent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LengthOrPercentageOrAutoOrContent::Length(length) => write!(f, "{:?}", length),
LengthOrPercentageOrAutoOrContent::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
LengthOrPercentageOrAutoOrContent::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.),
LengthOrPercentageOrAutoOrContent::Calc(calc) => write!(f, "{:?}", calc),
LengthOrPercentageOrAutoOrContent::Auto => write!(f, "auto"),
LengthOrPercentageOrAutoOrContent::Content => write!(f, "content")
@ -476,7 +475,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context))
},
specified::LengthOrPercentageOrAutoOrContent::Percentage(value) => {
LengthOrPercentageOrAutoOrContent::Percentage(value.0)
LengthOrPercentageOrAutoOrContent::Percentage(value)
},
specified::LengthOrPercentageOrAutoOrContent::Calc(ref calc) => {
LengthOrPercentageOrAutoOrContent::Calc(calc.to_computed_value(context))
@ -506,7 +505,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrAutoOrContent {
)
}
LengthOrPercentageOrAutoOrContent::Percentage(value) => {
specified::LengthOrPercentageOrAutoOrContent::Percentage(specified::Percentage(value))
specified::LengthOrPercentageOrAutoOrContent::Percentage(value)
}
LengthOrPercentageOrAutoOrContent::Calc(calc) => {
specified::LengthOrPercentageOrAutoOrContent::Calc(
@ -521,8 +520,7 @@ impl ToCss for LengthOrPercentageOrAutoOrContent {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
LengthOrPercentageOrAutoOrContent::Length(length) => length.to_css(dest),
LengthOrPercentageOrAutoOrContent::Percentage(percentage)
=> write!(dest, "{}%", percentage * 100.),
LengthOrPercentageOrAutoOrContent::Percentage(percentage) => percentage.to_css(dest),
LengthOrPercentageOrAutoOrContent::Calc(calc) => calc.to_css(dest),
LengthOrPercentageOrAutoOrContent::Auto => dest.write_str("auto"),
LengthOrPercentageOrAutoOrContent::Content => dest.write_str("content")
@ -535,7 +533,7 @@ impl ToCss for LengthOrPercentageOrAutoOrContent {
#[allow(missing_docs)]
pub enum LengthOrPercentageOrNone {
Length(Au),
Percentage(CSSFloat),
Percentage(Percentage),
Calc(CalcLengthOrPercentage),
None,
}
@ -546,7 +544,7 @@ impl LengthOrPercentageOrNone {
match *self {
LengthOrPercentageOrNone::None => None,
LengthOrPercentageOrNone::Length(length) => Some(length),
LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)),
LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent.0)),
LengthOrPercentageOrNone::Calc(ref calc) => calc.to_used_value(Some(containing_length)),
}
}
@ -556,7 +554,7 @@ impl fmt::Debug for LengthOrPercentageOrNone {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LengthOrPercentageOrNone::Length(length) => write!(f, "{:?}", length),
LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage * 100.),
LengthOrPercentageOrNone::Percentage(percentage) => write!(f, "{}%", percentage.0 * 100.),
LengthOrPercentageOrNone::Calc(calc) => write!(f, "{:?}", calc),
LengthOrPercentageOrNone::None => write!(f, "none"),
}
@ -573,7 +571,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
LengthOrPercentageOrNone::Length(value.to_computed_value(context))
}
specified::LengthOrPercentageOrNone::Percentage(value) => {
LengthOrPercentageOrNone::Percentage(value.0)
LengthOrPercentageOrNone::Percentage(value)
}
specified::LengthOrPercentageOrNone::Calc(ref calc) => {
LengthOrPercentageOrNone::Calc(calc.to_computed_value(context))
@ -594,7 +592,7 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
)
}
LengthOrPercentageOrNone::Percentage(value) => {
specified::LengthOrPercentageOrNone::Percentage(specified::Percentage(value))
specified::LengthOrPercentageOrNone::Percentage(value)
}
LengthOrPercentageOrNone::Calc(calc) => {
specified::LengthOrPercentageOrNone::Calc(
@ -609,8 +607,7 @@ impl ToCss for LengthOrPercentageOrNone {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
LengthOrPercentageOrNone::Length(length) => length.to_css(dest),
LengthOrPercentageOrNone::Percentage(percentage) =>
write!(dest, "{}%", percentage * 100.),
LengthOrPercentageOrNone::Percentage(percentage) => percentage.to_css(dest),
LengthOrPercentageOrNone::Calc(calc) => calc.to_css(dest),
LengthOrPercentageOrNone::None => dest.write_str("none"),
}

View file

@ -11,6 +11,7 @@ use std::fmt;
use style_traits::ToCss;
use values::computed::LengthOrPercentage;
use values::generics::position::Position as GenericPosition;
use values::specified::length::Percentage;
/// The computed value of a CSS `<position>`
pub type Position = GenericPosition<HorizontalPosition, VerticalPosition>;
@ -25,7 +26,10 @@ impl Position {
/// `50% 50%`
#[inline]
pub fn center() -> Self {
Self::new(LengthOrPercentage::Percentage(0.5), LengthOrPercentage::Percentage(0.5))
Self::new(
LengthOrPercentage::Percentage(Percentage(0.5)),
LengthOrPercentage::Percentage(Percentage(0.5)),
)
}
/// `0% 0%`

View file

@ -8,6 +8,7 @@ use properties::animated_properties::Animatable;
use values::computed::{Length, LengthOrPercentage, Number};
use values::generics::transform::TimingFunction as GenericTimingFunction;
use values::generics::transform::TransformOrigin as GenericTransformOrigin;
use values::specified::length::Percentage;
/// The computed value of a CSS `<transform-origin>`
pub type TransformOrigin = GenericTransformOrigin<LengthOrPercentage, LengthOrPercentage, Length>;
@ -20,9 +21,9 @@ impl TransformOrigin {
#[inline]
pub fn initial_value() -> Self {
Self::new(
LengthOrPercentage::Percentage(0.5),
LengthOrPercentage::Percentage(0.5),
Length::from_px(0)
LengthOrPercentage::Percentage(Percentage(0.5)),
LengthOrPercentage::Percentage(Percentage(0.5)),
Length::from_px(0),
)
}
}

View file

@ -15,7 +15,8 @@ use style_traits::{HasViewportPercentage, ToCss, ParseError, StyleParseError};
use style_traits::values::specified::AllowedLengthType;
use values::{CSSInteger, CSSFloat};
use values::specified::{Angle, Time};
use values::specified::length::{FontRelativeLength, NoCalcLength, ViewportPercentageLength};
use values::specified::length::{FontRelativeLength, NoCalcLength};
use values::specified::length::{Percentage, ViewportPercentageLength};
/// A node inside a `Calc` expression's AST.
#[derive(Clone, Debug)]
@ -74,7 +75,7 @@ pub struct CalcLengthOrPercentage {
pub ex: Option<CSSFloat>,
pub ch: Option<CSSFloat>,
pub rem: Option<CSSFloat>,
pub percentage: Option<CSSFloat>,
pub percentage: Option<Percentage>,
#[cfg(feature = "gecko")]
pub mozmm: Option<CSSFloat>,
}
@ -128,7 +129,7 @@ impl ToCss for CalcLengthOrPercentage {
if let Some(val) = self.percentage {
first_value_check!();
try!(write!(dest, "{}%", val * 100.));
val.to_css(dest)?;
}
write!(dest, ")")
@ -298,7 +299,9 @@ impl CalcNode {
{
match *self {
CalcNode::Percentage(pct) => {
ret.percentage = Some(ret.percentage.unwrap_or(0.) + pct * factor)
ret.percentage = Some(Percentage(
ret.percentage.map_or(0., |p| p.0) + pct * factor,
));
}
CalcNode::Length(ref l) => {
match *l {

View file

@ -701,7 +701,7 @@ impl<T: Parse> Either<Length, T> {
/// As of today, only `-moz-image-rect` supports percentages without length.
/// This is not a regression, and that's a non-standard extension anyway, so I'm
/// not implementing it for now.
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq)]
#[derive(Clone, Copy, Debug, Default, HasViewportPercentage, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Percentage(pub CSSFloat);

View file

@ -224,22 +224,22 @@ impl<S: Side> ToComputedValue for PositionComponent<S> {
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
PositionComponent::Center => {
ComputedLengthOrPercentage::Percentage(0.5)
ComputedLengthOrPercentage::Percentage(Percentage(0.5))
},
PositionComponent::Side(ref keyword, None) => {
let p = if keyword.is_start() { 0. } else { 1. };
let p = Percentage(if keyword.is_start() { 0. } else { 1. });
ComputedLengthOrPercentage::Percentage(p)
},
PositionComponent::Side(ref keyword, Some(ref length)) if !keyword.is_start() => {
match length.to_computed_value(context) {
ComputedLengthOrPercentage::Length(length) => {
ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(-length, Some(1.0)))
ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(-length, Some(Percentage(1.0))))
},
ComputedLengthOrPercentage::Percentage(p) => {
ComputedLengthOrPercentage::Percentage(1.0 - p)
ComputedLengthOrPercentage::Percentage(Percentage(1.0 - p.0))
},
ComputedLengthOrPercentage::Calc(calc) => {
let p = 1. - calc.percentage.unwrap_or(0.);
let p = Percentage(1. - calc.percentage.map_or(0., |p| p.0));
ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(-calc.unclamped_length(), Some(p)))
},
}

View file

@ -14,7 +14,7 @@ use values::computed::transform::TimingFunction as ComputedTimingFunction;
use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction};
use values::generics::transform::{TimingKeyword, TransformOrigin as GenericTransformOrigin};
use values::specified::{Integer, Number};
use values::specified::length::{Length, LengthOrPercentage};
use values::specified::length::{Length, LengthOrPercentage, Percentage};
use values::specified::position::{Side, X, Y};
/// The specified value of a CSS `<transform-origin>`
@ -107,13 +107,13 @@ impl<S> ToComputedValue for OriginComponent<S>
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
OriginComponent::Center => {
ComputedLengthOrPercentage::Percentage(0.5)
ComputedLengthOrPercentage::Percentage(Percentage(0.5))
},
OriginComponent::Length(ref length) => {
length.to_computed_value(context)
},
OriginComponent::Side(ref keyword) => {
let p = if keyword.is_start() { 0. } else { 1. };
let p = Percentage(if keyword.is_start() { 0. } else { 1. });
ComputedLengthOrPercentage::Percentage(p)
},
}

View file

@ -7,6 +7,7 @@ use cssparser::RGBA;
use style::properties::animated_properties::{Animatable, IntermediateRGBA};
use style::properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
use style::properties::longhands::transform::computed_value::T as TransformList;
use style::values::specified::length::Percentage;
fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA {
let from: IntermediateRGBA = from.into();
@ -78,25 +79,25 @@ fn test_transform_interpolation_on_translate() {
LengthOrPercentage::Length(Au(50)),
Au(50))])));
let from = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Percentage(0.5),
LengthOrPercentage::Percentage(1.0),
Au(25))]));
let from = TransformList(Some(vec![TransformOperation::Translate(
LengthOrPercentage::Percentage(Percentage(0.5)),
LengthOrPercentage::Percentage(Percentage(1.0)),
Au(25),
)]));
let to = TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Length(Au(100)),
LengthOrPercentage::Length(Au(50)),
Au(75))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![
TransformOperation::Translate(LengthOrPercentage::Calc(
// calc(50px + 25%)
CalcLengthOrPercentage::new(Au(50),
Some(0.25))),
LengthOrPercentage::Calc(
// calc(25px + 50%)
CalcLengthOrPercentage::new(Au(25),
Some(0.5))),
Au(50))])));
assert_eq!(
from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::Translate(
// calc(50px + 25%)
LengthOrPercentage::Calc(CalcLengthOrPercentage::new(Au(50), Some(Percentage(0.25)))),
// calc(25px + 50%)
LengthOrPercentage::Calc(CalcLengthOrPercentage::new(Au(25), Some(Percentage(0.5)))),
Au(50),
)]))
);
}
#[test]
@ -143,10 +144,12 @@ fn test_transform_interpolation_on_mismatched_lists() {
TransformOperation::Translate(LengthOrPercentage::Length(Au(100)),
LengthOrPercentage::Length(Au(0)),
Au(0))]));
assert_eq!(from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::InterpolateMatrix {
from_list: from.clone(),
to_list: to.clone(),
progress: Percentage(0.5)
}])));
assert_eq!(
from.interpolate(&to, 0.5).unwrap(),
TransformList(Some(vec![TransformOperation::InterpolateMatrix {
from_list: from.clone(),
to_list: to.clone(),
progress: Percentage(0.5),
}]))
);
}

View file

@ -5,10 +5,11 @@
use app_units::Au;
use style::attr::{AttrValue, LengthOrPercentageOrAuto, parse_length};
use style::values::computed::CalcLengthOrPercentage;
use style::values::specified::length::Percentage;
#[test]
fn test_length_calc() {
let calc = CalcLengthOrPercentage::new(Au(10), Some(0.2));
let calc = CalcLengthOrPercentage::new(Au(10), Some(Percentage(0.2)));
assert_eq!(calc.to_used_value(Some(Au(10))), Some(Au(12)));
assert_eq!(calc.to_used_value(Some(Au(0))), Some(Au(10)));
assert_eq!(calc.to_used_value(None), None);