style: Cleanup and fix interpolation of SVG lengths.

Instead of storing them as LengthPercentage | Number, always store as
LengthPercentage, and use the unitless length quirk to parse numbers instead.

Further cleanups to use the rust representation can happen as a followup, which
will also get rid of the boolean argument (since we can poke at the rust length
itself). That's why I didn't bother to convert it to an enum class yet.

Differential Revision: https://phabricator.services.mozilla.com/D21804
This commit is contained in:
Emilio Cobos Álvarez 2019-03-01 23:17:12 +01:00
parent 9e0d38a64f
commit f1b5d5c06a
7 changed files with 94 additions and 280 deletions

View file

@ -782,16 +782,22 @@ impl ClipRectOrAuto {
/// Whether quirks are allowed in this context.
#[derive(Clone, Copy, PartialEq)]
pub enum AllowQuirks {
/// Quirks are allowed.
Yes,
/// Quirks are not allowed.
No,
/// Quirks are allowed, in quirks mode.
Yes,
/// Quirks are always allowed, used for SVG lengths.
Always,
}
impl AllowQuirks {
/// Returns `true` if quirks are allowed in this context.
pub fn allowed(self, quirks_mode: QuirksMode) -> bool {
self == AllowQuirks::Yes && quirks_mode == QuirksMode::Quirks
match self {
AllowQuirks::Always => true,
AllowQuirks::No => false,
AllowQuirks::Yes => quirks_mode == QuirksMode::Quirks,
}
}
}

View file

@ -6,11 +6,11 @@
use crate::parser::{Parse, ParserContext};
use crate::values::generics::svg as generic;
use crate::values::specified::AllowQuirks;
use crate::values::specified::color::Color;
use crate::values::specified::url::SpecifiedUrl;
use crate::values::specified::LengthPercentage;
use crate::values::specified::{NonNegativeLengthPercentage, NonNegativeNumber};
use crate::values::specified::{Number, Opacity};
use crate::values::specified::{NonNegativeLengthPercentage, Opacity};
use crate::values::CustomIdent;
use cssparser::Parser;
use std::fmt::{self, Write};
@ -23,36 +23,53 @@ pub type SVGPaint = generic::SVGPaint<Color, SpecifiedUrl>;
/// Specified SVG Paint Kind value
pub type SVGPaintKind = generic::SVGPaintKind<Color, SpecifiedUrl>;
/// A value of <length> | <percentage> | <number> for stroke-dashoffset.
/// <https://www.w3.org/TR/SVG11/painting.html#StrokeProperties>
pub type SvgLengthPercentageOrNumber =
generic::SvgLengthPercentageOrNumber<LengthPercentage, Number>;
/// <length> | <percentage> | <number> | context-value
pub type SVGLength = generic::SVGLength<SvgLengthPercentageOrNumber>;
impl From<SvgLengthPercentageOrNumber> for SVGLength {
fn from(length: SvgLengthPercentageOrNumber) -> 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 NonNegativeSvgLengthPercentageOrNumber =
generic::SvgLengthPercentageOrNumber<NonNegativeLengthPercentage, NonNegativeNumber>;
pub type SVGLength = generic::SVGLength<LengthPercentage>;
/// A non-negative version of SVGLength.
pub type SVGWidth = generic::SVGLength<NonNegativeSvgLengthPercentageOrNumber>;
pub type SVGWidth = generic::SVGLength<NonNegativeLengthPercentage>;
impl From<NonNegativeSvgLengthPercentageOrNumber> for SVGWidth {
fn from(length: NonNegativeSvgLengthPercentageOrNumber) -> Self {
generic::SVGLength::Length(length)
/// [ <length> | <percentage> | <number> ]# | context-value
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeLengthPercentage>;
/// Whether the `context-value` value is enabled.
#[cfg(feature = "gecko")]
pub fn is_context_value_enabled() -> bool {
use crate::gecko_bindings::structs::mozilla;
unsafe { mozilla::StaticPrefs_sVarCache_gfx_font_rendering_opentype_svg_enabled }
}
/// Whether the `context-value` value is enabled.
#[cfg(not(feature = "gecko"))]
pub fn is_context_value_enabled() -> bool {
false
}
macro_rules! parse_svg_length {
($ty:ty, $lp:ty) => {
impl Parse for $ty {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
if let Ok(lp) = input.try(|i| {
<$lp>::parse_quirky(context, i, AllowQuirks::Always)
}) {
return Ok(generic::SVGLength::LengthPercentage(lp))
}
try_match_ident_ignore_ascii_case! { input,
"context-value" if is_context_value_enabled() => {
Ok(generic::SVGLength::ContextValue)
},
}
}
}
}
}
/// [ <length> | <percentage> | <number> ]# | context-value
pub type SVGStrokeDashArray = generic::SVGStrokeDashArray<NonNegativeSvgLengthPercentageOrNumber>;
parse_svg_length!(SVGLength, LengthPercentage);
parse_svg_length!(SVGWidth, NonNegativeLengthPercentage);
impl Parse for SVGStrokeDashArray {
fn parse<'i, 't>(
@ -61,14 +78,18 @@ impl Parse for SVGStrokeDashArray {
) -> Result<Self, ParseError<'i>> {
if let Ok(values) = input.try(|i| {
CommaWithSpace::parse(i, |i| {
NonNegativeSvgLengthPercentageOrNumber::parse(context, i)
NonNegativeLengthPercentage::parse_quirky(
context,
i,
AllowQuirks::Always,
)
})
}) {
return Ok(generic::SVGStrokeDashArray::Values(values));
}
try_match_ident_ignore_ascii_case! { input,
"context-value" if generic::is_context_value_enabled(context) => {
"context-value" if is_context_value_enabled() => {
Ok(generic::SVGStrokeDashArray::ContextValue)
},
"none" => Ok(generic::SVGStrokeDashArray::Values(vec![])),