mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
stylo: Support stroke-dasharray and stroke-dashoffset
MozReview-Commit-ID: 4QKKzJ1DVYP
This commit is contained in:
parent
4d33761596
commit
ff08de8ad1
7 changed files with 89 additions and 4 deletions
|
@ -726,6 +726,14 @@ extern "C" {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_nsStyleSVGPaint_Reset(paint: *mut nsStyleSVGPaint);
|
pub fn Gecko_nsStyleSVGPaint_Reset(paint: *mut nsStyleSVGPaint);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVG_SetDashArrayLength(svg: *mut nsStyleSVG,
|
||||||
|
len: u32);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_nsStyleSVG_CopyDashArray(dst: *mut nsStyleSVG,
|
||||||
|
src: *const nsStyleSVG);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_NewURLValue(uri: ServoBundledURI) -> *mut URLValue;
|
pub fn Gecko_NewURLValue(uri: ServoBundledURI) -> *mut URLValue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,22 @@ impl<T> Parse for Vec<T> where T: Parse + OneOrMoreCommaSeparated {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a non-empty space-separated or comma-separated list of objects parsed by parse_one
|
||||||
|
pub fn parse_space_or_comma_separated<F, T>(input: &mut Parser, mut parse_one: F)
|
||||||
|
-> Result<Vec<T>, ()>
|
||||||
|
where F: FnMut(&mut Parser) -> Result<T, ()> {
|
||||||
|
let first = parse_one(input)?;
|
||||||
|
let mut vec = vec![first];
|
||||||
|
loop {
|
||||||
|
let _ = input.try(|i| i.expect_comma());
|
||||||
|
if let Ok(val) = input.try(|i| parse_one(i)) {
|
||||||
|
vec.push(val)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(vec)
|
||||||
|
}
|
||||||
impl Parse for UnicodeRange {
|
impl Parse for UnicodeRange {
|
||||||
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
fn parse(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
UnicodeRange::parse(input)
|
UnicodeRange::parse(input)
|
||||||
|
|
|
@ -2800,7 +2800,7 @@ clip-path
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="InheritedSVG"
|
<%self:impl_trait style_struct_name="InheritedSVG"
|
||||||
skip_longhands="paint-order"
|
skip_longhands="paint-order stroke-dasharray"
|
||||||
skip_additionals="*">
|
skip_additionals="*">
|
||||||
pub fn set_paint_order(&mut self, v: longhands::paint_order::computed_value::T) {
|
pub fn set_paint_order(&mut self, v: longhands::paint_order::computed_value::T) {
|
||||||
use self::longhands::paint_order;
|
use self::longhands::paint_order;
|
||||||
|
@ -2825,6 +2825,25 @@ clip-path
|
||||||
}
|
}
|
||||||
|
|
||||||
${impl_simple_copy('paint_order', 'mPaintOrder')}
|
${impl_simple_copy('paint_order', 'mPaintOrder')}
|
||||||
|
|
||||||
|
pub fn set_stroke_dasharray(&mut self, v: longhands::stroke_dasharray::computed_value::T) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVG_SetDashArrayLength(&mut self.gecko, v.0.len() as u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (mut gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v.0.into_iter()) {
|
||||||
|
match servo {
|
||||||
|
Either::First(lop) => gecko.set(lop),
|
||||||
|
Either::Second(number) => gecko.set_value(CoordDataValue::Factor(number)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_stroke_dasharray_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_nsStyleSVG_CopyDashArray(&mut self.gecko, &other.gecko);
|
||||||
|
}
|
||||||
|
}
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Color"
|
<%self:impl_trait style_struct_name="Color"
|
||||||
|
|
|
@ -66,7 +66,8 @@
|
||||||
We assume that the default/initial value is an empty vector for these.
|
We assume that the default/initial value is an empty vector for these.
|
||||||
`initial_value` need not be defined for these.
|
`initial_value` need not be defined for these.
|
||||||
</%doc>
|
</%doc>
|
||||||
<%def name="vector_longhand(name, gecko_only=False, allow_empty=False, delegate_animate=False, **kwargs)">
|
<%def name="vector_longhand(name, gecko_only=False, allow_empty=False,
|
||||||
|
delegate_animate=False, space_separated_allowed=False, **kwargs)">
|
||||||
<%call expr="longhand(name, **kwargs)">
|
<%call expr="longhand(name, **kwargs)">
|
||||||
% if not gecko_only:
|
% if not gecko_only:
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -86,6 +87,7 @@
|
||||||
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
|
use properties::{CSSWideKeyword, DeclaredValue, ShorthandId};
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
use values::{computed, specified};
|
use values::{computed, specified};
|
||||||
|
use values::{Auto, Either, None_, Normal};
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,16 +168,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||||
|
use parser::parse_space_or_comma_separated;
|
||||||
|
|
||||||
|
<%
|
||||||
|
parse_func = "Parser::parse_comma_separated"
|
||||||
|
if space_separated_allowed:
|
||||||
|
parse_func = "parse_space_or_comma_separated"
|
||||||
|
%>
|
||||||
% if allow_empty:
|
% if allow_empty:
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
Ok(SpecifiedValue(Vec::new()))
|
Ok(SpecifiedValue(Vec::new()))
|
||||||
} else {
|
} else {
|
||||||
input.parse_comma_separated(|parser| {
|
${parse_func}(input, |parser| {
|
||||||
single_value::parse(context, parser)
|
single_value::parse(context, parser)
|
||||||
}).map(SpecifiedValue)
|
}).map(SpecifiedValue)
|
||||||
}
|
}
|
||||||
% else:
|
% else:
|
||||||
input.parse_comma_separated(|parser| {
|
${parse_func}(input, |parser| {
|
||||||
single_value::parse(context, parser)
|
single_value::parse(context, parser)
|
||||||
}).map(SpecifiedValue)
|
}).map(SpecifiedValue)
|
||||||
% endif
|
% endif
|
||||||
|
|
|
@ -93,6 +93,22 @@ ${helpers.predefined_type("stroke-opacity", "Opacity", "1.0",
|
||||||
products="gecko", animatable=False,
|
products="gecko", animatable=False,
|
||||||
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}
|
spec="https://www.w3.org/TR/SVG11/painting.html#StrokeOpacityProperty")}
|
||||||
|
|
||||||
|
${helpers.predefined_type("stroke-dasharray", "LoPOrNumber", "Either::Second(0.0)",
|
||||||
|
"parse_non_negative",
|
||||||
|
vector="True",
|
||||||
|
products="gecko",
|
||||||
|
animatable="False",
|
||||||
|
space_separated_allowed="True",
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}
|
||||||
|
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"stroke-dashoffset", "LengthOrPercentage",
|
||||||
|
"computed::LengthOrPercentage::zero()",
|
||||||
|
products="gecko",
|
||||||
|
animatable=True,
|
||||||
|
boxed=True,
|
||||||
|
spec="https://www.w3.org/TR/SVG2/painting.html#StrokeDashing")}
|
||||||
|
|
||||||
// Section 14 - Clipping, Masking and Compositing
|
// Section 14 - Clipping, Masking and Compositing
|
||||||
${helpers.single_keyword("clip-rule", "nonzero evenodd",
|
${helpers.single_keyword("clip-rule", "nonzero evenodd",
|
||||||
products="gecko",
|
products="gecko",
|
||||||
|
|
|
@ -259,6 +259,8 @@ impl ToCss for SVGPaint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <length> | <percentage> | <number>
|
||||||
|
pub type LoPOrNumber = Either<LengthOrPercentage, Number>;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
|
|
@ -824,6 +824,21 @@ impl ToComputedValue for SVGPaintKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <length> | <percentage> | <number>
|
||||||
|
pub type LoPOrNumber = Either<LengthOrPercentage, Number>;
|
||||||
|
|
||||||
|
impl LoPOrNumber {
|
||||||
|
/// parse a <length-percentage> | <number> enforcing that the contents aren't negative
|
||||||
|
pub fn parse_non_negative(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||||
|
if let Ok(lop) = input.try(LengthOrPercentage::parse_non_negative) {
|
||||||
|
Ok(Either::First(lop))
|
||||||
|
} else if let Ok(num) = input.try(Number::parse_non_negative) {
|
||||||
|
Ok(Either::Second(num))
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl HasViewportPercentage for ClipRect {
|
impl HasViewportPercentage for ClipRect {
|
||||||
fn has_viewport_percentage(&self) -> bool {
|
fn has_viewport_percentage(&self) -> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue