Add SVGLengthOrPercentageOrNumber for stroke-*.

We need to use enum instead of Either since we can't interpolate stroke-* between
unitless length and unit length(e.g. '5' -> '10px').

This coomit make following:

 * Introduce SVGLengthOrPercentageOrNumber on computed and specified values.
 * Make SVGLengthOrPercentageOrNumber animatable.
 * Make stroke-dasharray not-accumulate.
This commit is contained in:
Mantaroh Yoshinaga 2017-07-12 13:37:53 +09:00
parent 6988c7424d
commit 1c574cf93b
6 changed files with 286 additions and 45 deletions

View file

@ -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)]