[librsvg: 5/10] Parse the blur() filter function
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 5/10] Parse the blur() filter function
- Date: Thu, 29 Apr 2021 00:06:46 +0000 (UTC)
commit d40e3b920d5afb45c78071f0ad0a3ceac4c388cf
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Apr 28 14:36:05 2021 -0500
Parse the blur() filter function
src/filter.rs | 15 ++++++++---
src/filter_func.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 4 deletions(-)
---
diff --git a/src/filter.rs b/src/filter.rs
index 8a26e416..f626b4f2 100644
--- a/src/filter.rs
+++ b/src/filter.rs
@@ -202,10 +202,17 @@ impl Parse for FilterValueList {
loop {
let loc = parser.current_source_location();
- let url = parser.expect_url()?;
- let node_id =
- NodeId::parse(&url).map_err(|e| loc.new_custom_error(ValueErrorKind::from(e)))?;
- result.0.push(FilterValue::Url(node_id));
+ let filter_value = if let Ok(func) = parser.try_parse(|p| FilterFunction::parse(p)) {
+ FilterValue::Function(func)
+ } else {
+ let url = parser.expect_url()?;
+ let node_id = NodeId::parse(&url)
+ .map_err(|e| loc.new_custom_error(ValueErrorKind::from(e)))?;
+
+ FilterValue::Url(node_id)
+ };
+
+ result.0.push(filter_value);
if parser.is_exhausted() {
break;
diff --git a/src/filter_func.rs b/src/filter_func.rs
index 5b664aff..eb84fff8 100644
--- a/src/filter_func.rs
+++ b/src/filter_func.rs
@@ -1,10 +1,60 @@
+use cssparser::Parser;
+
+use crate::error::*;
use crate::filters::{FilterResolveError, FilterSpec};
+use crate::length::*;
+use crate::parsers::Parse;
/// CSS Filter functions from the Filter Effects Module Level 1
///
/// https://www.w3.org/TR/filter-effects/#filter-functions
#[derive(Debug, Clone, PartialEq)]
pub enum FilterFunction {
+ Blur(Blur),
+}
+
+/// Parameters for the `blur()` filter function
+///
+/// https://www.w3.org/TR/filter-effects/#funcdef-filter-blur
+#[derive(Debug, Clone, PartialEq)]
+pub struct Blur {
+ std_deviation: Option<Length<Both>>,
+}
+
+fn parse_function<'i, F>(
+ parser: &mut Parser<'i, '_>,
+ name: &str,
+ f: F,
+) -> Result<FilterFunction, ParseError<'i>>
+where
+ F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result<FilterFunction, ParseError<'i>>,
+{
+ parser.expect_function_matching(name)?;
+ parser.parse_nested_block(f)
+}
+
+fn parse_blur<'i>(parser: &mut Parser<'i, '_>) -> Result<FilterFunction, ParseError<'i>> {
+ let length = if let Ok(length) = parser.try_parse(|p| Length::parse(p)) {
+ Some(length)
+ } else {
+ None
+ };
+
+ Ok(FilterFunction::Blur(Blur {
+ std_deviation: length,
+ }))
+}
+
+impl Parse for FilterFunction {
+ fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, crate::error::ParseError<'i>> {
+ let loc = parser.current_source_location();
+
+ parser
+ .try_parse(|p| parse_function(p, "blur", parse_blur))
+ .or_else(|_| {
+ Err(loc.new_custom_error(ValueErrorKind::parse_error("expected filter function")))
+ })
+ }
}
impl FilterFunction {
@@ -12,3 +62,31 @@ impl FilterFunction {
unimplemented!()
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parses_blur() {
+ assert_eq!(
+ FilterFunction::parse_str("blur()").unwrap(),
+ FilterFunction::Blur(Blur {
+ std_deviation: None
+ })
+ );
+
+ assert_eq!(
+ FilterFunction::parse_str("blur(5px)").unwrap(),
+ FilterFunction::Blur(Blur {
+ std_deviation: Some(Length::new(5.0, LengthUnit::Px))
+ })
+ );
+ }
+
+ #[test]
+ fn invalid_blur_yields_error() {
+ assert!(FilterFunction::parse_str("blur(foo)").is_err());
+ assert!(FilterFunction::parse_str("blur(42 43)").is_err());
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]