mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Bug 1374233 - Part 9: Add NonNegativeLengthOrPercentageOrNumber for stroke-{width|dasharry}.
Also add SVGWidth which use NonNegativeSVGLengthOrPercentage as the LengthType for stroke-width. MozReview-Commit-ID: 8gD0fVe2eAe
This commit is contained in:
parent
b37f270c65
commit
bd0a098ef1
9 changed files with 64 additions and 46 deletions
|
@ -616,7 +616,7 @@ def set_gecko_property(ffi_name, expr):
|
||||||
};
|
};
|
||||||
match length {
|
match length {
|
||||||
Either::First(number) =>
|
Either::First(number) =>
|
||||||
self.gecko.${gecko_ffi_name}.set_value(CoordDataValue::Factor(number)),
|
self.gecko.${gecko_ffi_name}.set_value(CoordDataValue::Factor(From::from(number))),
|
||||||
Either::Second(lop) => self.gecko.${gecko_ffi_name}.set(lop),
|
Either::Second(lop) => self.gecko.${gecko_ffi_name}.set(lop),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -641,10 +641,10 @@ def set_gecko_property(ffi_name, expr):
|
||||||
return SVGLength::ContextValue;
|
return SVGLength::ContextValue;
|
||||||
}
|
}
|
||||||
let length = match self.gecko.${gecko_ffi_name}.as_value() {
|
let length = match self.gecko.${gecko_ffi_name}.as_value() {
|
||||||
CoordDataValue::Factor(number) => Either::First(number),
|
CoordDataValue::Factor(number) => Either::First(From::from(number)),
|
||||||
CoordDataValue::Coord(coord) => Either::Second(LengthOrPercentage::Length(Au(coord))),
|
CoordDataValue::Coord(coord) => Either::Second(From::from(LengthOrPercentage::Length(Au(coord)))),
|
||||||
CoordDataValue::Percent(p) => Either::Second(LengthOrPercentage::Percentage(Percentage(p))),
|
CoordDataValue::Percent(p) => Either::Second(From::from(LengthOrPercentage::Percentage(Percentage(p)))),
|
||||||
CoordDataValue::Calc(calc) => Either::Second(LengthOrPercentage::Calc(calc.into())),
|
CoordDataValue::Calc(calc) => Either::Second(From::from(LengthOrPercentage::Calc(calc.into()))),
|
||||||
_ => unreachable!("Unexpected coordinate {:?} in ${ident}",
|
_ => unreachable!("Unexpected coordinate {:?} in ${ident}",
|
||||||
self.gecko.${gecko_ffi_name}.as_value()),
|
self.gecko.${gecko_ffi_name}.as_value()),
|
||||||
};
|
};
|
||||||
|
@ -1111,6 +1111,7 @@ impl Clone for ${style_struct.gecko_struct_name} {
|
||||||
"SVGLength": impl_svg_length,
|
"SVGLength": impl_svg_length,
|
||||||
"SVGOpacity": impl_svg_opacity,
|
"SVGOpacity": impl_svg_opacity,
|
||||||
"SVGPaint": impl_svg_paint,
|
"SVGPaint": impl_svg_paint,
|
||||||
|
"SVGWidth": impl_svg_length,
|
||||||
"UrlOrNone": impl_css_url,
|
"UrlOrNone": impl_css_url,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5152,7 +5153,7 @@ clip-path
|
||||||
}
|
}
|
||||||
for (mut gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v) {
|
for (mut gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v) {
|
||||||
match servo {
|
match servo {
|
||||||
Either::First(number) => gecko.set_value(CoordDataValue::Factor(number)),
|
Either::First(number) => gecko.set_value(CoordDataValue::Factor(number.into())),
|
||||||
Either::Second(lop) => gecko.set(lop),
|
Either::Second(lop) => gecko.set(lop),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5192,13 +5193,13 @@ clip-path
|
||||||
let mut vec = vec![];
|
let mut vec = vec![];
|
||||||
for gecko in self.gecko.mStrokeDasharray.iter() {
|
for gecko in self.gecko.mStrokeDasharray.iter() {
|
||||||
match gecko.as_value() {
|
match gecko.as_value() {
|
||||||
CoordDataValue::Factor(number) => vec.push(Either::First(number)),
|
CoordDataValue::Factor(number) => vec.push(Either::First(number.into())),
|
||||||
CoordDataValue::Coord(coord) =>
|
CoordDataValue::Coord(coord) =>
|
||||||
vec.push(Either::Second(LengthOrPercentage::Length(Au(coord)))),
|
vec.push(Either::Second(LengthOrPercentage::Length(Au(coord)).into())),
|
||||||
CoordDataValue::Percent(p) =>
|
CoordDataValue::Percent(p) =>
|
||||||
vec.push(Either::Second(LengthOrPercentage::Percentage(Percentage(p)))),
|
vec.push(Either::Second(LengthOrPercentage::Percentage(Percentage(p)).into())),
|
||||||
CoordDataValue::Calc(calc) =>
|
CoordDataValue::Calc(calc) =>
|
||||||
vec.push(Either::Second(LengthOrPercentage::Calc(calc.into()))),
|
vec.push(Either::Second(LengthOrPercentage::Calc(calc.into()).into())),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -782,6 +782,7 @@ impl ToAnimatedZero for AnimationValue {
|
||||||
|
|
||||||
impl RepeatableListAnimatable for LengthOrPercentage {}
|
impl RepeatableListAnimatable for LengthOrPercentage {}
|
||||||
impl RepeatableListAnimatable for Either<f32, LengthOrPercentage> {}
|
impl RepeatableListAnimatable for Either<f32, LengthOrPercentage> {}
|
||||||
|
impl RepeatableListAnimatable for Either<NonNegativeNumber, NonNegativeLengthOrPercentage> {}
|
||||||
|
|
||||||
macro_rules! repeated_vec_impl {
|
macro_rules! repeated_vec_impl {
|
||||||
($($ty:ty),*) => {
|
($($ty:ty),*) => {
|
||||||
|
|
|
@ -64,12 +64,11 @@ ${helpers.predefined_type(
|
||||||
spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint")}
|
spec="https://www.w3.org/TR/SVG2/painting.html#SpecifyingStrokePaint")}
|
||||||
|
|
||||||
${helpers.predefined_type(
|
${helpers.predefined_type(
|
||||||
"stroke-width", "SVGLength",
|
"stroke-width", "SVGWidth",
|
||||||
"Au::from_px(1).into()",
|
"::values::computed::NonNegativeAu::from_px(1).into()",
|
||||||
"parse_non_negative",
|
|
||||||
products="gecko",
|
products="gecko",
|
||||||
boxed="True",
|
boxed="True",
|
||||||
animation_value_type="ComputedValue",
|
animation_value_type="::values::computed::SVGWidth",
|
||||||
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth")}
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeWidth")}
|
||||||
|
|
||||||
${helpers.single_keyword("stroke-linecap", "butt round square",
|
${helpers.single_keyword("stroke-linecap", "butt round square",
|
||||||
|
@ -95,7 +94,7 @@ ${helpers.predefined_type(
|
||||||
"SVGStrokeDashArray",
|
"SVGStrokeDashArray",
|
||||||
"Default::default()",
|
"Default::default()",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
animation_value_type="ComputedValue",
|
animation_value_type="::values::computed::SVGStrokeDashArray",
|
||||||
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing",
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -569,6 +569,13 @@ impl ToComputedValue for specified::LengthOrPercentageOrNone {
|
||||||
/// A wrapper of LengthOrPercentage, whose value must be >= 0.
|
/// A wrapper of LengthOrPercentage, whose value must be >= 0.
|
||||||
pub type NonNegativeLengthOrPercentage = NonNegative<LengthOrPercentage>;
|
pub type NonNegativeLengthOrPercentage = NonNegative<LengthOrPercentage>;
|
||||||
|
|
||||||
|
impl From<NonNegativeAu> for NonNegativeLengthOrPercentage {
|
||||||
|
#[inline]
|
||||||
|
fn from(length: NonNegativeAu) -> Self {
|
||||||
|
LengthOrPercentage::Length(length.0).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<LengthOrPercentage> for NonNegativeLengthOrPercentage {
|
impl From<LengthOrPercentage> for NonNegativeLengthOrPercentage {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(lop: LengthOrPercentage) -> Self {
|
fn from(lop: LengthOrPercentage) -> Self {
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNum
|
||||||
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength, Percentage};
|
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength, Percentage};
|
||||||
pub use self::length::NonNegativeLengthOrPercentage;
|
pub use self::length::NonNegativeLengthOrPercentage;
|
||||||
pub use self::position::Position;
|
pub use self::position::Position;
|
||||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
|
||||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
||||||
pub use self::transform::{TimingFunction, TransformOrigin};
|
pub use self::transform::{TimingFunction, TransformOrigin};
|
||||||
|
|
||||||
|
@ -528,6 +528,9 @@ pub type PositiveIntegerOrAuto = Either<PositiveInteger, Auto>;
|
||||||
/// <length> | <percentage> | <number>
|
/// <length> | <percentage> | <number>
|
||||||
pub type LengthOrPercentageOrNumber = Either<Number, LengthOrPercentage>;
|
pub type LengthOrPercentageOrNumber = Either<Number, LengthOrPercentage>;
|
||||||
|
|
||||||
|
/// NonNegativeLengthOrPercentage | NonNegativeNumber
|
||||||
|
pub type NonNegativeLengthOrPercentageOrNumber = Either<NonNegativeNumber, NonNegativeLengthOrPercentage>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use values::{Either, RGBA};
|
use values::{Either, RGBA};
|
||||||
use values::computed::{LengthOrPercentageOrNumber, Opacity};
|
use values::computed::{LengthOrPercentageOrNumber, Opacity};
|
||||||
|
use values::computed::{NonNegativeAu, NonNegativeLengthOrPercentageOrNumber};
|
||||||
use values::generics::svg as generic;
|
use values::generics::svg as generic;
|
||||||
|
|
||||||
/// Computed SVG Paint value
|
/// Computed SVG Paint value
|
||||||
|
@ -43,8 +44,17 @@ impl From<Au> for SVGLength {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An non-negative wrapper of SVGLength.
|
||||||
|
pub type SVGWidth = generic::SVGLength<NonNegativeLengthOrPercentageOrNumber>;
|
||||||
|
|
||||||
|
impl From<NonNegativeAu> for SVGWidth {
|
||||||
|
fn from(length: NonNegativeAu) -> Self {
|
||||||
|
generic::SVGLength::Length(Either::Second(length.into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// [ <length> | <percentage> | <number> ]# | context-value
|
/// [ <length> | <percentage> | <number> ]# | context-value
|
||||||
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<LengthOrPercentageOrNumber>;
|
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthOrPercentageOrNumber>;
|
||||||
|
|
||||||
impl Default for SVGStrokeDashArray {
|
impl Default for SVGStrokeDashArray {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|
|
@ -98,7 +98,7 @@ impl<ColorType: Parse> Parse for SVGPaint<ColorType> {
|
||||||
|
|
||||||
/// An SVG length value supports `context-value` in addition to length.
|
/// An SVG length value supports `context-value` in addition to length.
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, HasViewportPercentage, ToComputedValue, ToCss)]
|
#[derive(Clone, Copy, Debug, PartialEq, HasViewportPercentage, ToAnimatedValue, ToComputedValue, ToCss)]
|
||||||
pub enum SVGLength<LengthType> {
|
pub enum SVGLength<LengthType> {
|
||||||
/// `<length> | <percentage> | <number>`
|
/// `<length> | <percentage> | <number>`
|
||||||
Length(LengthType),
|
Length(LengthType),
|
||||||
|
@ -108,7 +108,7 @@ pub enum SVGLength<LengthType> {
|
||||||
|
|
||||||
/// Generic value for stroke-dasharray.
|
/// Generic value for stroke-dasharray.
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
#[derive(Clone, Debug, PartialEq, HasViewportPercentage, ToComputedValue)]
|
#[derive(Clone, Debug, PartialEq, HasViewportPercentage, ToAnimatedValue, ToComputedValue)]
|
||||||
pub enum SVGStrokeDashArray<LengthType> {
|
pub enum SVGStrokeDashArray<LengthType> {
|
||||||
/// `[ <length> | <percentage> | <number> ]#`
|
/// `[ <length> | <percentage> | <number> ]#`
|
||||||
Values(Vec<LengthType>),
|
Values(Vec<LengthType>),
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub use self::length::{NoCalcLength, Percentage, ViewportPercentageLength};
|
||||||
pub use self::length::NonNegativeLengthOrPercentage;
|
pub use self::length::NonNegativeLengthOrPercentage;
|
||||||
pub use self::rect::LengthOrNumberRect;
|
pub use self::rect::LengthOrNumberRect;
|
||||||
pub use self::position::{Position, PositionComponent};
|
pub use self::position::{Position, PositionComponent};
|
||||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray};
|
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
|
||||||
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
pub use self::text::{InitialLetter, LetterSpacing, LineHeight, WordSpacing};
|
||||||
pub use self::transform::{TimingFunction, TransformOrigin};
|
pub use self::transform::{TimingFunction, TransformOrigin};
|
||||||
pub use super::generics::grid::GridLine;
|
pub use super::generics::grid::GridLine;
|
||||||
|
@ -750,19 +750,8 @@ pub type GridTemplateComponent = GenericGridTemplateComponent<LengthOrPercentage
|
||||||
/// <length> | <percentage> | <number>
|
/// <length> | <percentage> | <number>
|
||||||
pub type LengthOrPercentageOrNumber = Either<Number, LengthOrPercentage>;
|
pub type LengthOrPercentageOrNumber = Either<Number, LengthOrPercentage>;
|
||||||
|
|
||||||
impl LengthOrPercentageOrNumber {
|
/// NonNegativeLengthOrPercentage | NonNegativeNumber
|
||||||
/// parse a <length-percentage> | <number> enforcing that the contents aren't negative
|
pub type NonNegativeLengthOrPercentageOrNumber = Either<NonNegativeNumber, NonNegativeLengthOrPercentage>;
|
||||||
pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
|
||||||
-> Result<Self, ParseError<'i>> {
|
|
||||||
// NB: Parse numbers before Lengths so we are consistent about how to
|
|
||||||
// recognize and serialize "0".
|
|
||||||
if let Ok(num) = input.try(|i| Number::parse_non_negative(context, i)) {
|
|
||||||
return Ok(Either::First(num))
|
|
||||||
}
|
|
||||||
|
|
||||||
LengthOrPercentage::parse_non_negative(context, input).map(Either::Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
#[derive(Clone, Debug, HasViewportPercentage, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
|
|
@ -8,7 +8,7 @@ use cssparser::Parser;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseError};
|
use style_traits::{CommaWithSpace, ParseError, Separator, StyleParseError};
|
||||||
use values::generics::svg as generic;
|
use values::generics::svg as generic;
|
||||||
use values::specified::{LengthOrPercentageOrNumber, Opacity};
|
use values::specified::{LengthOrPercentageOrNumber, NonNegativeLengthOrPercentageOrNumber, Opacity};
|
||||||
use values::specified::color::RGBAColor;
|
use values::specified::color::RGBAColor;
|
||||||
|
|
||||||
/// Specified SVG Paint value
|
/// Specified SVG Paint value
|
||||||
|
@ -54,30 +54,38 @@ impl Parse for SVGLength {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SVGLength {
|
|
||||||
/// parse a non-negative SVG length
|
|
||||||
pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
|
||||||
-> Result<Self, ParseError<'i>> {
|
|
||||||
input.try(|i| LengthOrPercentageOrNumber::parse_non_negative(context, i))
|
|
||||||
.map(Into::into)
|
|
||||||
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<LengthOrPercentageOrNumber> for SVGLength {
|
impl From<LengthOrPercentageOrNumber> for SVGLength {
|
||||||
fn from(length: LengthOrPercentageOrNumber) -> Self {
|
fn from(length: LengthOrPercentageOrNumber) -> Self {
|
||||||
generic::SVGLength::Length(length)
|
generic::SVGLength::Length(length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A non-negative version of SVGLength.
|
||||||
|
pub type SVGWidth = generic::SVGLength<NonNegativeLengthOrPercentageOrNumber>;
|
||||||
|
|
||||||
|
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))
|
||||||
|
.map(Into::into)
|
||||||
|
.or_else(|_| parse_context_value(input, generic::SVGLength::ContextValue))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<NonNegativeLengthOrPercentageOrNumber> for SVGWidth {
|
||||||
|
fn from(length: NonNegativeLengthOrPercentageOrNumber) -> Self {
|
||||||
|
generic::SVGLength::Length(length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// [ <length> | <percentage> | <number> ]# | context-value
|
/// [ <length> | <percentage> | <number> ]# | context-value
|
||||||
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<LengthOrPercentageOrNumber>;
|
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthOrPercentageOrNumber>;
|
||||||
|
|
||||||
impl Parse for SVGStrokeDashArray {
|
impl Parse for SVGStrokeDashArray {
|
||||||
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<Self, ParseError<'i>> {
|
-> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(values) = input.try(|i| CommaWithSpace::parse(i, |i| {
|
if let Ok(values) = input.try(|i| CommaWithSpace::parse(i, |i| {
|
||||||
LengthOrPercentageOrNumber::parse_non_negative(context, i)
|
NonNegativeLengthOrPercentageOrNumber::parse(context, i)
|
||||||
})) {
|
})) {
|
||||||
Ok(generic::SVGStrokeDashArray::Values(values))
|
Ok(generic::SVGStrokeDashArray::Values(values))
|
||||||
} else if let Ok(_) = input.try(|i| i.expect_ident_matching("none")) {
|
} else if let Ok(_) = input.try(|i| i.expect_ident_matching("none")) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue