[librsvg: 1/21] WIP: (#487) Begin implementing transform as property This change adds TransformProperty, Function, a
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/21] WIP: (#487) Begin implementing transform as property This change adds TransformProperty, Function, a
- Date: Tue, 31 Aug 2021 18:37:37 +0000 (UTC)
commit a03f188905902351060ab54c143419f6eea0d0fb
Author: Madds H <madds hollandart io>
Date: Wed Aug 4 00:01:27 2021 -0500
WIP: (#487) Begin implementing transform as property
This change adds TransformProperty, Function, and parser to transform.rs
It also adds the TransformProperty to properties macros
Current Errors: Macro in Properties requires #derive(Clone, Debug)
but 'type' cannot implement them, not sure how to fix aside from
changing `TransformProperty::List(TransformList)` to
`::List(Vec<TransformList>)`, which doesn't look pretty
Not quite done implementing the parser, and the names of the functions
there need changed to be consistent.
Part-of: <https://gitlab.gnome.org/GNOME/librsvg/-/merge_requests/576>
src/properties.rs | 3 ++
src/property_defs.rs | 11 ++++
src/transform.rs | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 155 insertions(+), 1 deletion(-)
---
diff --git a/src/properties.rs b/src/properties.rs
index 510efd7c..9d9e1096 100644
--- a/src/properties.rs
+++ b/src/properties.rs
@@ -27,6 +27,7 @@ use crate::error::*;
use crate::parsers::{Parse, ParseValue};
use crate::property_macros::Property;
use crate::transform::Transform;
+use crate::transform::TransformProperty;
use crate::xml::Attributes;
// Re-export the actual properties so they are easy to find from a single place `properties::*`.
@@ -424,6 +425,7 @@ make_properties! {
"text-anchor" => text_anchor : TextAnchor,
"text-decoration" => text_decoration : TextDecoration,
"text-rendering" => text_rendering : TextRendering,
+ "transform" => transform_property : TransformProperty,
"unicode-bidi" => unicode_bidi : UnicodeBidi,
"visibility" => visibility : Visibility,
"writing-mode" => writing_mode : WritingMode,
@@ -636,6 +638,7 @@ impl SpecifiedValues {
compute!(TextAnchor, text_anchor);
compute!(TextDecoration, text_decoration);
compute!(TextRendering, text_rendering);
+ compute!(TransformProperty, transform_property);
compute!(UnicodeBidi, unicode_bidi);
compute!(Visibility, visibility);
compute!(WritingMode, writing_mode);
diff --git a/src/property_defs.rs b/src/property_defs.rs
index 05b667a5..c12653be 100644
--- a/src/property_defs.rs
+++ b/src/property_defs.rs
@@ -49,6 +49,7 @@ use crate::parsers::Parse;
use crate::properties::ComputedValues;
use crate::property_macros::Property;
use crate::rect::Rect;
+use crate::transform::TransformProperty;
use crate::unit_interval::UnitInterval;
make_property!(
@@ -985,6 +986,16 @@ make_property!(
"geometricPrecision" => GeometricPrecision,
);
+make_property!(
+ /// `transform` property.
+ ///
+ /// https://www.w3.org/TR/css-transforms-1/#transform-property
+ Transform,
+ default: TransformProperty::None,
+ inherits_automatically: false,
+ newtype_parse: TransformProperty,
+);
+
make_property!(
/// `unicode-bidi` property.
///
diff --git a/src/transform.rs b/src/transform.rs
index db77a3de..b1665f63 100644
--- a/src/transform.rs
+++ b/src/transform.rs
@@ -2,7 +2,7 @@
//!
//! This module handles `transform` values [per the SVG specification][spec].
//!
-//! [spec]: https://www.w3.org/TR/SVG11/coords.html#TransformAttribute
+//! [spec]: https://www.w3.org/TR/SVG11/coords.html#TransformAttribute and
https://www.w3.org/TR/css-transforms-1/#transform-property
use cssparser::{Parser, Token};
@@ -11,6 +11,94 @@ use crate::error::*;
use crate::parsers::{optional_comma, Parse};
use crate::rect::Rect;
+// https://www.w3.org/TR/css-transforms-1/#transform-property
+#[derive(Debug, Clone)]
+pub enum TransformProperty {
+ None,
+ List(TransformList),
+}
+
+#[derive(Debug, Clone)]
+pub type TransformList = Vec<TransformFunction>;
+
+// https://www.w3.org/TR/css-transforms-1/#typedef-transform-function
+#[derive(Debug, Clone)]
+enum TransformFunction {
+ Matrix(),
+ Translate(),
+ TranslateX(),
+ TranslateY(),
+ Scale(),
+ ScaleX(),
+ ScaleY(),
+ Rotate(),
+ Skew(),
+ SkewX(),
+ SkewY(),
+}
+
+impl Parse for TransformProperty {
+ fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<TransformProperty, ParseError<'i>> {
+ // look at the impl Parse later in this file for an example
+ let loc = parser.current_source_location();
+
+ let t = parse_transform_prop_function_list(parser)?;
+
+ Ok(TransformProperty::List(t))
+ }
+}
+
+fn parse_transform_prop_function_list<'i>(
+ parser: &mut Parser<'i, '_>,
+) -> Result<TransformList, ParseError<'i>> {
+ //TODO: What does this need to be set to?
+ let mut t = TransformFunction::Translate();
+
+ loop {
+ if parser.is_exhausted() {
+ break;
+ }
+ t = parse_transform_prop_function_command(parser)?.post_transform(&t);
+ }
+
+ Ok(t)
+}
+
+fn parse_transform_prop_function_command<'i>(
+ parser: &mut Parser<'i, '_>,
+) -> Result<TransformFunction, ParseError<'i>> {
+ let loc = parser.current_source_location();
+
+ match parser.next()?.clone() {
+ Token::Function(ref name) => parse_transform_prop_function_name(name, parser),
+ tok => Err(loc.new_unexpected_token_error(tok.clone())),
+ }
+}
+
+fn parse_transform_function_internal<'i>(
+ name: &str,
+ parser: &mut Parser<'i, '_>,
+) -> Result<Transform, ParseError<'i>> {
+ let loc = parser.current_source_location();
+
+ match name {
+ "matrix" => parse_matrix_args(parser),
+ "translate" => parse_translate_args(parser),
+ "translateX" => parse_translate_x_args(parser),
+ "translateY" => parse_translate_y_args(parser),
+ "scale" => parse_scale_args(parser),
+ "scaleX" => parse_scale_x_args(parser),
+ "scaleY" => parse_scale_y_args(parser),
+ "rotate" => parse_rotate_args(parser),
+ "skew" => parse_skew_args(parser),
+ "skewX" => parse_skew_x_args(parser),
+ "skewY" => parse_skew_y_args(parser),
+ _ => Err(loc.new_custom_error(ValueErrorKind::parse_error(
+ "expected matrix|translate|translateX|translateY|scale|scaleX|scaleY|rotate|skewX|skewY",
+ ))),
+ }
+}
+
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Transform {
pub xx: f64,
@@ -307,6 +395,22 @@ fn parse_translate_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, Pa
})
}
+fn parse_translate_x_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
+ parser.parse_nested_block(|p| {
+ let tx = f64::parse(p)?;
+
+ Ok(Transform::new_translate(tx, 0.0))
+ })
+}
+
+fn parse_translate_y_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
+ parser.parse_nested_block(|p| {
+ let ty = f64::parse(p)?;
+
+ Ok(Transform::new_translate(0.0, ty))
+ })
+}
+
fn parse_scale_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
parser.parse_nested_block(|p| {
let x = f64::parse(p)?;
@@ -322,6 +426,22 @@ fn parse_scale_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseE
})
}
+fn parse_scale_x_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
+ parser.parse_nested_block(|p| {
+ let x = f64::parse(p)?;
+
+ Ok(Transform::new_scale(x, 0.0))
+ })
+}
+
+fn parse_scale_y_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
+ parser.parse_nested_block(|p| {
+ let y = f64::parse(p)?;
+
+ Ok(Transform::new_scale(0.0, y))
+ })
+}
+
fn parse_rotate_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
parser.parse_nested_block(|p| {
let angle = Angle::from_degrees(f64::parse(p)?);
@@ -344,6 +464,21 @@ fn parse_rotate_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, Parse
})
}
+fn parse_skew_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
+ parser.parse_nested_block(|p| {
+ let ax = Angle::from_degrees(f64::parse(p)?);
+
+ let ay = Angle::from_degrees(
+ p.try_parse(|p| {
+ optional_comma(p);
+ f64::parse(p)
+ })
+ .unwrap_or(0.0),
+ );
+ Ok(Transform::new_skew(ax, ay))
+ })
+}
+
fn parse_skew_x_args<'i>(parser: &mut Parser<'i, '_>) -> Result<Transform, ParseError<'i>> {
parser.parse_nested_block(|p| {
let angle = Angle::from_degrees(f64::parse(p)?);
@@ -588,3 +723,8 @@ mod tests {
assert_transform_eq(&parse_transform("").unwrap(), &Transform::identity());
}
}
+
+#[test]
+fn test_parse_transform_property() {
+ // TODO for madds: put your tests in here
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]