diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-08-17 23:39:00 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-17 23:39:00 -0500 |
commit | d17f27640be455c91daaf8733289dca90eb505c5 (patch) | |
tree | e5e111187cbc1c85a09e52ae97e6b5d5efaa8525 | |
parent | 489b25004bdc1ccd9348f659e6a608656c55c13b (diff) | |
parent | 1c574cf93b1aaab41efe56ceedfd8e0c1c63b931 (diff) | |
download | servo-d17f27640be455c91daaf8733289dca90eb505c5.tar.gz servo-d17f27640be455c91daaf8733289dca90eb505c5.zip |
Auto merge of #17704 - mantaroh:interpolate-stroke, r=nox
Add animation value related with stroke-dasharray / stroke-dashoffset / stroke-width.
<!-- Please describe your changes on the following line: -->
This is a PR for https://bugzilla.mozilla.org/show_bug.cgi?id=1369614
This patch will:
* Add animation value conversion of LengthOrPercentage in order to interpolate length and number.
* Add animation value of Vec<LengthOrPercentage> in order to interpolate the stroke-dasharray.
Spec is as follow:
https://svgwg.org/svg2-draft/painting.html#StrokeDashing
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
<!-- Either: -->
There are tests for these changes, a test case will be landed in wpt in https://bugzilla.mozilla.org/show_bug.cgi?id=1369614.
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17288)
<!-- Reviewable:end -->
-rw-r--r-- | components/style/properties/gecko.mako.rs | 50 | ||||
-rw-r--r-- | components/style/properties/helpers/animated_properties.mako.rs | 149 | ||||
-rw-r--r-- | components/style/values/computed/length.rs | 7 | ||||
-rw-r--r-- | components/style/values/computed/svg.rs | 43 | ||||
-rw-r--r-- | components/style/values/generics/svg.rs | 49 | ||||
-rw-r--r-- | components/style/values/specified/svg.rs | 33 |
6 files changed, 286 insertions, 45 deletions
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 682e2cfb39a..6f1b0d2a74f 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -588,7 +588,7 @@ def set_gecko_property(ffi_name, expr): // set on mContextFlags, and the length field is set to the initial value. pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { - use values::generics::svg::SVGLength; + use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber}; use gecko_bindings::structs::nsStyleSVG_${ident.upper()}_CONTEXT as CONTEXT_VALUE; let length = match v { SVGLength::Length(length) => { @@ -604,9 +604,10 @@ def set_gecko_property(ffi_name, expr): } }; match length { - Either::First(number) => - self.gecko.${gecko_ffi_name}.set_value(CoordDataValue::Factor(From::from(number))), - Either::Second(lop) => self.gecko.${gecko_ffi_name}.set(lop), + SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => + self.gecko.${gecko_ffi_name}.set(lop), + SvgLengthOrPercentageOrNumber::Number(num) => + self.gecko.${gecko_ffi_name}.set_value(CoordDataValue::Factor(num.into())), } } @@ -623,21 +624,28 @@ def set_gecko_property(ffi_name, expr): } pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { - use values::generics::svg::SVGLength; + use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber}; use values::computed::LengthOrPercentage; use gecko_bindings::structs::nsStyleSVG_${ident.upper()}_CONTEXT as CONTEXT_VALUE; if (self.gecko.mContextFlags & CONTEXT_VALUE) != 0 { return SVGLength::ContextValue; } let length = match self.gecko.${gecko_ffi_name}.as_value() { - CoordDataValue::Factor(number) => Either::First(From::from(number)), - CoordDataValue::Coord(coord) => Either::Second(From::from(LengthOrPercentage::Length(Au(coord)))), - CoordDataValue::Percent(p) => Either::Second(From::from(LengthOrPercentage::Percentage(Percentage(p)))), - CoordDataValue::Calc(calc) => Either::Second(From::from(LengthOrPercentage::Calc(calc.into()))), + CoordDataValue::Factor(number) => + SvgLengthOrPercentageOrNumber::Number(number), + CoordDataValue::Coord(coord) => + SvgLengthOrPercentageOrNumber::LengthOrPercentage( + LengthOrPercentage::Length(Au(coord))), + CoordDataValue::Percent(p) => + SvgLengthOrPercentageOrNumber::LengthOrPercentage( + LengthOrPercentage::Percentage(Percentage(p))), + CoordDataValue::Calc(calc) => + SvgLengthOrPercentageOrNumber::LengthOrPercentage( + LengthOrPercentage::Calc(calc.into())), _ => unreachable!("Unexpected coordinate {:?} in ${ident}", self.gecko.${gecko_ffi_name}.as_value()), }; - SVGLength::Length(length) + SVGLength::Length(length.into()) } </%def> @@ -5141,7 +5149,7 @@ clip-path pub fn set_stroke_dasharray(&mut self, v: longhands::stroke_dasharray::computed_value::T) { use gecko_bindings::structs::nsStyleSVG_STROKE_DASHARRAY_CONTEXT as CONTEXT_VALUE; - use values::generics::svg::SVGStrokeDashArray; + use values::generics::svg::{SVGStrokeDashArray, SvgLengthOrPercentageOrNumber}; match v { SVGStrokeDashArray::Values(v) => { @@ -5152,8 +5160,10 @@ clip-path } for (gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v) { match servo { - Either::First(number) => gecko.set_value(CoordDataValue::Factor(number.into())), - Either::Second(lop) => gecko.set(lop), + SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => + gecko.set(lop), + SvgLengthOrPercentageOrNumber::Number(num) => + gecko.set_value(CoordDataValue::Factor(num.into())), } } } @@ -5183,7 +5193,7 @@ clip-path pub fn clone_stroke_dasharray(&self) -> longhands::stroke_dasharray::computed_value::T { use gecko_bindings::structs::nsStyleSVG_STROKE_DASHARRAY_CONTEXT as CONTEXT_VALUE; use values::computed::LengthOrPercentage; - use values::generics::svg::SVGStrokeDashArray; + use values::generics::svg::{SVGStrokeDashArray, SvgLengthOrPercentageOrNumber}; if self.gecko.mContextFlags & CONTEXT_VALUE != 0 { debug_assert_eq!(self.gecko.mStrokeDasharray.len(), 0); @@ -5192,13 +5202,17 @@ clip-path let mut vec = vec![]; for gecko in self.gecko.mStrokeDasharray.iter() { match gecko.as_value() { - CoordDataValue::Factor(number) => vec.push(Either::First(number.into())), + CoordDataValue::Factor(number) => + vec.push(SvgLengthOrPercentageOrNumber::Number(number.into())), CoordDataValue::Coord(coord) => - vec.push(Either::Second(LengthOrPercentage::Length(Au(coord)).into())), + vec.push(SvgLengthOrPercentageOrNumber::LengthOrPercentage( + LengthOrPercentage::Length(Au(coord)).into())), CoordDataValue::Percent(p) => - vec.push(Either::Second(LengthOrPercentage::Percentage(Percentage(p)).into())), + vec.push(SvgLengthOrPercentageOrNumber::LengthOrPercentage( + LengthOrPercentage::Percentage(Percentage(p)).into())), CoordDataValue::Calc(calc) => - vec.push(Either::Second(LengthOrPercentage::Calc(calc.into()).into())), + vec.push(SvgLengthOrPercentageOrNumber::LengthOrPercentage( + LengthOrPercentage::Calc(calc.into()).into())), _ => unreachable!(), } } diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 38ac83a941d..1e3558482ec 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -43,18 +43,20 @@ use values::animated::effects::BoxShadowList as AnimatedBoxShadowList; use values::animated::effects::Filter as AnimatedFilter; use values::animated::effects::FilterList as AnimatedFilterList; use values::animated::effects::TextShadowList as AnimatedTextShadowList; -use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; -use values::computed::{BorderCornerRadius, ClipRect}; -use values::computed::{CalcLengthOrPercentage, Context, ComputedValueAsSpecified, ComputedUrl}; -use values::computed::{LengthOrPercentage, MaxLength, MozLength, Percentage, ToComputedValue}; -use values::computed::{NonNegativeAu, NonNegativeNumber, PositiveIntegerOrAuto}; +use values::computed::{Angle, BorderCornerRadius, CalcLengthOrPercentage}; +use values::computed::{ClipRect, Context, ComputedUrl, ComputedValueAsSpecified}; +use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; +use values::computed::{LengthOrPercentageOrNone, MaxLength, MozLength, NonNegativeAu}; +use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage}; +use values::computed::{PositiveIntegerOrAuto, ToComputedValue}; use values::computed::length::{NonNegativeLengthOrAuto, NonNegativeLengthOrNormal}; use values::computed::length::NonNegativeLengthOrPercentage; use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::generics::{GreaterThanOrEqualToOne, NonNegative}; use values::generics::effects::Filter; use values::generics::position as generic_position; -use values::generics::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray}; +use values::generics::svg::{SVGLength, SvgLengthOrPercentageOrNumber, SVGPaint}; +use values::generics::svg::{SVGPaintKind, SVGStrokeDashArray, SVGOpacity}; /// A trait used to implement various procedures used during animation. pub trait Animatable: Sized { @@ -781,6 +783,7 @@ impl ToAnimatedZero for AnimationValue { impl RepeatableListAnimatable for LengthOrPercentage {} impl RepeatableListAnimatable for Either<f32, LengthOrPercentage> {} impl RepeatableListAnimatable for Either<NonNegativeNumber, NonNegativeLengthOrPercentage> {} +impl RepeatableListAnimatable for SvgLengthOrPercentageOrNumber<NonNegativeLengthOrPercentage, NonNegativeNumber> {} macro_rules! repeated_vec_impl { ($($ty:ty),*) => { @@ -1016,7 +1019,12 @@ impl Animatable for LengthOrPercentage { impl ToAnimatedZero for LengthOrPercentage { #[inline] fn to_animated_zero(&self) -> Result<Self, ()> { - Ok(LengthOrPercentage::zero()) + match self { + &LengthOrPercentage::Length(_) | &LengthOrPercentage::Calc(_) => + Ok(LengthOrPercentage::zero()), + &LengthOrPercentage::Percentage(_) => + Ok(LengthOrPercentage::Percentage(Percentage::zero())), + } } } @@ -2496,6 +2504,120 @@ impl ToAnimatedZero for IntermediateSVGPaintKind { } } +impl From<NonNegativeLengthOrPercentage> for NumberOrPercentage { + fn from(lop: NonNegativeLengthOrPercentage) -> NumberOrPercentage { + lop.0.into() + } +} + +impl From<NonNegativeNumber> for NumberOrPercentage { + fn from(num: NonNegativeNumber) -> NumberOrPercentage { + num.0.into() + } +} + +impl From<LengthOrPercentage> for NumberOrPercentage { + fn from(lop: LengthOrPercentage) -> NumberOrPercentage { + match lop { + LengthOrPercentage::Length(len) => NumberOrPercentage::Number(len.to_f32_px()), + LengthOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p), + LengthOrPercentage::Calc(_) => { + panic!("We dont't expected calc interpolation for SvgLengthOrPercentageOrNumber"); + }, + } + } +} + +impl From<Number> for NumberOrPercentage { + fn from(num: Number) -> NumberOrPercentage { + NumberOrPercentage::Number(num) + } +} + +fn convert_to_number_or_percentage<LengthOrPercentageType, NumberType>( + from: SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType>) + -> NumberOrPercentage + where LengthOrPercentageType: Into<NumberOrPercentage>, + NumberType: Into<NumberOrPercentage> +{ + match from { + SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => { + lop.into() + } + SvgLengthOrPercentageOrNumber::Number(num) => { + num.into() + } + } +} + +fn convert_from_number_or_percentage<LengthOrPercentageType, NumberType>( + from: NumberOrPercentage) + -> SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> + where LengthOrPercentageType: From<LengthOrPercentage>, + NumberType: From<Number> +{ + match from { + NumberOrPercentage::Number(num) => + SvgLengthOrPercentageOrNumber::Number(num.into()), + NumberOrPercentage::Percentage(p) => + SvgLengthOrPercentageOrNumber::LengthOrPercentage( + (LengthOrPercentage::Percentage(p)).into()) + } +} + +impl <LengthOrPercentageType, NumberType> Animatable for + SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> + where LengthOrPercentageType: Animatable + Into<NumberOrPercentage> + From<LengthOrPercentage> + Copy, + NumberType: Animatable + Into<NumberOrPercentage> + From<Number>, + SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType>: Copy, + LengthOrPercentage: From<LengthOrPercentageType> +{ + #[inline] + fn add_weighted(&self, other: &Self, self_portion: f64, other_portion: f64) -> Result<Self, ()> { + if self.has_calc() || other.has_calc() { + // TODO: We need to treat calc value. + // https://bugzilla.mozilla.org/show_bug.cgi?id=1386967 + return Err(()); + } + + let from_value = convert_to_number_or_percentage(*self); + let to_value = convert_to_number_or_percentage(*other); + + match (from_value, to_value) { + (NumberOrPercentage::Number(from), + NumberOrPercentage::Number(to)) => { + from.add_weighted(&to, self_portion, other_portion) + .map(|num| NumberOrPercentage::Number(num)) + .map(|nop| convert_from_number_or_percentage(nop)) + }, + (NumberOrPercentage::Percentage(from), + NumberOrPercentage::Percentage(to)) => { + from.add_weighted(&to, self_portion, other_portion) + .map(|p| NumberOrPercentage::Percentage(p)) + .map(|nop| convert_from_number_or_percentage(nop)) + }, + _ => Err(()), + } + } +} + +impl <LengthOrPercentageType, NumberType> ToAnimatedZero for + SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> + where LengthOrPercentageType: ToAnimatedZero, NumberType: ToAnimatedZero +{ + #[inline] + fn to_animated_zero(&self) -> Result<Self, ()> { + match self { + &SvgLengthOrPercentageOrNumber::LengthOrPercentage(ref lop) => + lop.to_animated_zero() + .map(SvgLengthOrPercentageOrNumber::LengthOrPercentage), + &SvgLengthOrPercentageOrNumber::Number(ref num) => + num.to_animated_zero() + .map(SvgLengthOrPercentageOrNumber::Number), + } + } +} + impl<LengthType> Animatable for SVGLength<LengthType> where LengthType: Animatable + Clone { @@ -2522,6 +2644,7 @@ impl<LengthType> ToAnimatedZero for SVGLength<LengthType> where LengthType : ToA } } +/// https://www.w3.org/TR/SVG11/painting.html#StrokeDasharrayProperty impl<LengthType> Animatable for SVGStrokeDashArray<LengthType> where LengthType : RepeatableListAnimatable + Clone { @@ -2537,6 +2660,18 @@ impl<LengthType> Animatable for SVGStrokeDashArray<LengthType> } } } + + /// stroke-dasharray is non-additive + #[inline] + fn add(&self, _other: &Self) -> Result<Self, ()> { + Err(()) + } + + /// stroke-dasharray is non-additive + #[inline] + fn accumulate(&self, _other: &Self, _count: u64) -> Result<Self, ()> { + Err(()) + } } impl<LengthType> ToAnimatedZero for SVGStrokeDashArray<LengthType> diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index fbe3b56e724..a8287fa9991 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -606,6 +606,13 @@ impl From<LengthOrPercentage> for NonNegativeLengthOrPercentage { } } +impl From<NonNegativeLengthOrPercentage> for LengthOrPercentage { + #[inline] + fn from(lop: NonNegativeLengthOrPercentage) -> LengthOrPercentage { + lop.0 + } +} + impl NonNegativeLengthOrPercentage { /// Get zero value. #[inline] diff --git a/components/style/values/computed/svg.rs b/components/style/values/computed/svg.rs index 88cdbd5009e..b4d66b3cec5 100644 --- a/components/style/values/computed/svg.rs +++ b/components/style/values/computed/svg.rs @@ -5,10 +5,10 @@ //! Computed types for SVG properties. use app_units::Au; -use values::{Either, RGBA}; -use values::computed::{LengthOrPercentageOrNumber, Opacity}; -use values::computed::{NonNegativeAu, NonNegativeLengthOrPercentageOrNumber}; -use values::computed::ComputedUrl; +use values::RGBA; +use values::computed::{ComputedUrl, LengthOrPercentage, NonNegativeAu}; +use values::computed::{NonNegativeNumber, NonNegativeLengthOrPercentage, Number}; +use values::computed::Opacity; use values::generics::svg as generic; /// Computed SVG Paint value @@ -36,26 +36,51 @@ impl SVGPaint { } } +/// A value of <length> | <percentage> | <number> for stroke-dashoffset. +/// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties +pub type SvgLengthOrPercentageOrNumber = + generic::SvgLengthOrPercentageOrNumber<LengthOrPercentage, Number>; + /// <length> | <percentage> | <number> | context-value -pub type SVGLength = generic::SVGLength<LengthOrPercentageOrNumber>; +pub type SVGLength = generic::SVGLength<SvgLengthOrPercentageOrNumber>; impl From<Au> for SVGLength { fn from(length: Au) -> Self { - generic::SVGLength::Length(Either::Second(length.into())) + generic::SVGLength::Length( + generic::SvgLengthOrPercentageOrNumber::LengthOrPercentage(length.into())) + } +} + +/// A value of <length> | <percentage> | <number> for stroke-width/stroke-dasharray. +/// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties +pub type NonNegativeSvgLengthOrPercentageOrNumber = + generic::SvgLengthOrPercentageOrNumber<NonNegativeLengthOrPercentage, NonNegativeNumber>; + +impl Into<NonNegativeSvgLengthOrPercentageOrNumber> for SvgLengthOrPercentageOrNumber { + fn into(self) -> NonNegativeSvgLengthOrPercentageOrNumber { + match self { + generic::SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) =>{ + generic::SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop.into()) + }, + generic::SvgLengthOrPercentageOrNumber::Number(num) => { + generic::SvgLengthOrPercentageOrNumber::Number(num.into()) + }, + } } } /// An non-negative wrapper of SVGLength. -pub type SVGWidth = generic::SVGLength<NonNegativeLengthOrPercentageOrNumber>; +pub type SVGWidth = generic::SVGLength<NonNegativeSvgLengthOrPercentageOrNumber>; impl From<NonNegativeAu> for SVGWidth { fn from(length: NonNegativeAu) -> Self { - generic::SVGLength::Length(Either::Second(length.into())) + generic::SVGLength::Length( + generic::SvgLengthOrPercentageOrNumber::LengthOrPercentage(length.into())) } } /// [ <length> | <percentage> | <number> ]# | context-value -pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthOrPercentageOrNumber>; +pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeSvgLengthOrPercentageOrNumber>; impl Default for SVGStrokeDashArray { fn default() -> Self { diff --git a/components/style/values/generics/svg.rs b/components/style/values/generics/svg.rs index 60f76950aee..631e6374e2d 100644 --- a/components/style/values/generics/svg.rs +++ b/components/style/values/generics/svg.rs @@ -8,6 +8,8 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; use style_traits::{ParseError, StyleParseError, ToCss}; +use values::computed::length::LengthOrPercentage; + /// An SVG paint value /// @@ -95,6 +97,53 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP } } +/// A value of <length> | <percentage> | <number> for svg which allow unitless length. +/// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, PartialEq, ToCss, HasViewportPercentage)] +#[derive(ToComputedValue, ToAnimatedValue, ComputeSquaredDistance)] +pub enum SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> { + /// <length> | <percentage> + LengthOrPercentage(LengthOrPercentageType), + /// <number> + Number(NumberType), +} + +impl<LengthOrPercentageType, NumberType> SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> + where LengthOrPercentage: From<LengthOrPercentageType>, + LengthOrPercentageType: Copy +{ + /// return true if this struct has calc value. + pub fn has_calc(&self) -> bool { + match self { + &SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => { + match LengthOrPercentage::from(lop) { + LengthOrPercentage::Calc(_) => true, + _ => false, + } + }, + _ => false, + } + } +} + +/// Parsing the SvgLengthOrPercentageOrNumber. At first, we need to parse number +/// since prevent converting to the length. +impl <LengthOrPercentageType: Parse, NumberType: Parse> Parse for + SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> { + fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) + -> Result<Self, ParseError<'i>> { + if let Ok(num) = input.try(|i| NumberType::parse(context, i)) { + return Ok(SvgLengthOrPercentageOrNumber::Number(num)); + } + + if let Ok(lop) = input.try(|i| LengthOrPercentageType::parse(context, i)) { + return Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop)); + } + Err(StyleParseError::UnspecifiedError.into()) + } +} + /// An SVG length value supports `context-value` in addition to length. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq)] diff --git a/components/style/values/specified/svg.rs b/components/style/values/specified/svg.rs index 980162ccd2d..178b6892793 100644 --- a/components/style/values/specified/svg.rs +++ b/components/style/values/specified/svg.rs @@ -8,7 +8,8 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseError}; use values::generics::svg as generic; -use values::specified::{LengthOrPercentageOrNumber, NonNegativeLengthOrPercentageOrNumber, Opacity, SpecifiedUrl}; +use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber}; +use values::specified::{Number, Opacity, SpecifiedUrl}; use values::specified::color::RGBAColor; /// Specified SVG Paint value @@ -42,50 +43,60 @@ fn parse_context_value<'i, 't, T>(input: &mut Parser<'i, 't>, value: T) Err(StyleParseError::UnspecifiedError.into()) } +/// A value of <length> | <percentage> | <number> for stroke-dashoffset. +/// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties +pub type SvgLengthOrPercentageOrNumber = + generic::SvgLengthOrPercentageOrNumber<LengthOrPercentage, Number>; + /// <length> | <percentage> | <number> | context-value -pub type SVGLength = generic::SVGLength<LengthOrPercentageOrNumber>; +pub type SVGLength = generic::SVGLength<SvgLengthOrPercentageOrNumber>; impl Parse for SVGLength { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { - input.try(|i| LengthOrPercentageOrNumber::parse(context, i)) + input.try(|i| SvgLengthOrPercentageOrNumber::parse(context, i)) .map(Into::into) .or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue)) } } -impl From<LengthOrPercentageOrNumber> for SVGLength { - fn from(length: LengthOrPercentageOrNumber) -> Self { +impl From<SvgLengthOrPercentageOrNumber> for SVGLength { + fn from(length: SvgLengthOrPercentageOrNumber) -> Self { generic::SVGLength::Length(length) } } +/// A value of <length> | <percentage> | <number> for stroke-width/stroke-dasharray. +/// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties +pub type NonNegativeSvgLengthOrPercentageOrNumber = + generic::SvgLengthOrPercentageOrNumber<NonNegativeLengthOrPercentage, NonNegativeNumber>; + /// A non-negative version of SVGLength. -pub type SVGWidth = generic::SVGLength<NonNegativeLengthOrPercentageOrNumber>; +pub type SVGWidth = generic::SVGLength<NonNegativeSvgLengthOrPercentageOrNumber>; impl Parse for SVGWidth { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { - input.try(|i| NonNegativeLengthOrPercentageOrNumber::parse(context, i)) + input.try(|i| NonNegativeSvgLengthOrPercentageOrNumber::parse(context, i)) .map(Into::into) .or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue)) } } -impl From<NonNegativeLengthOrPercentageOrNumber> for SVGWidth { - fn from(length: NonNegativeLengthOrPercentageOrNumber) -> Self { +impl From<NonNegativeSvgLengthOrPercentageOrNumber> for SVGWidth { + fn from(length: NonNegativeSvgLengthOrPercentageOrNumber) -> Self { generic::SVGLength::Length(length) } } /// [ <length> | <percentage> | <number> ]# | context-value -pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthOrPercentageOrNumber>; +pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeSvgLengthOrPercentageOrNumber>; impl Parse for SVGStrokeDashArray { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> { if let Ok(values) = input.try(|i| CommaWithSpace::parse(i, |i| { - NonNegativeLengthOrPercentageOrNumber::parse(context, i) + NonNegativeSvgLengthOrPercentageOrNumber::parse(context, i) })) { Ok(generic::SVGStrokeDashArray::Values(values)) } else if let Ok(_) = input.try(|i| i.expect_ident_matching("none")) { |