[librsvg: 1/6] Implement paint-order property definition
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/6] Implement paint-order property definition
- Date: Wed, 2 Sep 2020 00:49:38 +0000 (UTC)
commit 9d2f6aec5adcc8949db065996f6fe62d56632b27
Author: John Ledbetter <john ledbetter gmail com>
Date: Tue Aug 25 12:26:01 2020 -0400
Implement paint-order property definition
rsvg_internals/src/properties.rs | 2 +
rsvg_internals/src/property_defs.rs | 85 +++++++++++++++++++++++++++++++++++++
2 files changed, 87 insertions(+)
---
diff --git a/rsvg_internals/src/properties.rs b/rsvg_internals/src/properties.rs
index d6552e47..1a02b206 100644
--- a/rsvg_internals/src/properties.rs
+++ b/rsvg_internals/src/properties.rs
@@ -416,6 +416,7 @@ make_properties! {
longhands_not_supported_by_markup5ever: {
"line-height" => line_height : LineHeight,
"mix-blend-mode" => mix_blend_mode : MixBlendMode,
+ "paint-order" => paint_order : PaintOrder,
}
// These are not properties, but presentation attributes. However,
@@ -594,6 +595,7 @@ impl SpecifiedValues {
compute!(MixBlendMode, mix_blend_mode);
compute!(Opacity, opacity);
compute!(Overflow, overflow);
+ compute!(PaintOrder, paint_order);
compute!(ShapeRendering, shape_rendering);
compute!(StopColor, stop_color);
compute!(StopOpacity, stop_opacity);
diff --git a/rsvg_internals/src/property_defs.rs b/rsvg_internals/src/property_defs.rs
index e19462b5..5ca37dcc 100644
--- a/rsvg_internals/src/property_defs.rs
+++ b/rsvg_internals/src/property_defs.rs
@@ -41,6 +41,7 @@
//! [`Parse`]: ../trait.Parse.html
//! [`Property`]: ../property_macros/trait.Property.html
//! [`UnitInterval`]: ../unit_interval/struct.UnitInterval.html
+use std::convert::TryInto;
use cssparser::{Parser, Token};
@@ -498,6 +499,90 @@ make_property!(
"auto" => Auto,
);
+#[repr(u8)]
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
+pub enum PaintTarget {
+ Fill,
+ Stroke,
+ Markers,
+}
+
+// https://www.w3.org/TR/SVG2/painting.html#PaintOrder
+make_property!(
+ ComputedValues,
+ PaintOrder,
+ inherits_automatically: true,
+ fields: {
+ targets: [PaintTarget; 3], default: [PaintTarget::Fill, PaintTarget::Stroke, PaintTarget::Markers],
+ }
+
+ parse_impl: {
+ impl Parse for PaintOrder {
+ fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<PaintOrder, ParseError<'i>> {
+ let allowed_targets = 3;
+ let mut targets = Vec::with_capacity(allowed_targets);
+
+ if parser.try_parse(|p| p.expect_ident_matching("normal")).is_ok() {
+ return Ok(PaintOrder::default());
+ }
+
+ while !parser.is_exhausted() {
+ let loc = parser.current_source_location();
+ let token = parser.next()?;
+
+ let value = match token {
+ Token::Ident(ref cow) if cow.eq_ignore_ascii_case("fill") &&
!targets.contains(&PaintTarget::Fill) => PaintTarget::Fill,
+ Token::Ident(ref cow) if cow.eq_ignore_ascii_case("stroke") &&
!targets.contains(&PaintTarget::Stroke) => PaintTarget::Stroke,
+ Token::Ident(ref cow) if cow.eq_ignore_ascii_case("markers") &&
!targets.contains(&PaintTarget::Markers) => PaintTarget::Markers,
+ _ => return Err(loc.new_basic_unexpected_token_error(token.clone()).into()),
+ };
+
+ targets.push(value);
+ };
+
+ // any values which were not specfied should be painted in default order
+ // (fill, stroke, markers) following the values which were explicitly specified.
+ for &target in &[PaintTarget::Fill, PaintTarget::Stroke, PaintTarget::Markers] {
+ if !targets.contains(&target) {
+ targets.push(target);
+ }
+ }
+ Ok(PaintOrder {
+ targets: targets[..].try_into().expect("Incorrect number of targets in paint-order")
+ })
+ }
+ }
+ }
+);
+
+#[cfg(test)]
+#[test]
+fn parses_paint_order() {
+ assert_eq!(
+ PaintOrder::parse_str("normal").unwrap(),
+ PaintOrder {
+ targets: [PaintTarget::Fill, PaintTarget::Stroke, PaintTarget::Markers]
+ }
+ );
+
+ assert_eq!(
+ PaintOrder::parse_str("markers fill").unwrap(),
+ PaintOrder {
+ targets: [PaintTarget::Markers, PaintTarget::Fill, PaintTarget::Stroke]
+ }
+ );
+
+ assert_eq!(
+ PaintOrder::parse_str("stroke").unwrap(),
+ PaintOrder {
+ targets: [PaintTarget::Stroke, PaintTarget::Fill, PaintTarget::Markers]
+ }
+ );
+
+ assert!(PaintOrder::parse_str("stroke stroke").is_err());
+ assert!(PaintOrder::parse_str("markers stroke fill hello").is_err());
+}
+
// https://www.w3.org/TR/SVG/painting.html#ShapeRenderingProperty
make_property!(
ComputedValues,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]