mirror of
https://github.com/lexmount/moli.git
synced 2026-11-04 08:07:27 +00:00
fix(svg): reject nonfinite fill points and support fill rules
This commit is contained in:
+50
-4
@@ -23,12 +23,13 @@ pub use transform::{
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
SvgGeometryElement, SvgGeometryPoint, SvgGeometrySegment, SvgLengthUnit,
|
||||
SvgFillRule, SvgGeometryElement, SvgGeometryPoint, SvgGeometrySegment, SvgLengthUnit,
|
||||
SvgMatrixComponents, SvgTransform, SvgTransformKind, bounding_box_for_element,
|
||||
bounding_box_for_segments, bounding_box_for_transformed_element,
|
||||
consolidate_transform_matrices, is_point_in_fill, parse_length, parse_length_list,
|
||||
parse_number, parse_number_list, parse_point_list, parse_transform_attribute,
|
||||
point_at_length, segments_for_element, serialize_number, serialize_transform_list,
|
||||
consolidate_transform_matrices, is_point_in_fill, is_point_in_fill_with_rule, parse_length,
|
||||
parse_length_list, parse_number, parse_number_list, parse_point_list,
|
||||
parse_transform_attribute, point_at_length, segments_for_element, serialize_number,
|
||||
serialize_transform_list,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -537,6 +538,51 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fill_containment_rejects_nonfinite_coordinates() {
|
||||
let circle = SvgGeometryElement::Circle {
|
||||
cx: 0.0,
|
||||
cy: 0.0,
|
||||
r: 10.0,
|
||||
};
|
||||
for value in [f64::NAN, f64::INFINITY, f64::NEG_INFINITY] {
|
||||
for point in [
|
||||
SvgGeometryPoint::new(value, 0.0),
|
||||
SvgGeometryPoint::new(0.0, value),
|
||||
] {
|
||||
for rule in [SvgFillRule::NonZero, SvgFillRule::EvenOdd] {
|
||||
assert!(!is_point_in_fill_with_rule(&circle, point, rule));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evenodd_fill_excludes_nested_interiors_but_includes_boundaries() {
|
||||
let rings = SvgGeometryElement::Path {
|
||||
d: "M0 0H10V10H0Z M2 2H8V8H2Z".to_owned(),
|
||||
};
|
||||
let center = SvgGeometryPoint::new(5.0, 5.0);
|
||||
assert!(is_point_in_fill(&rings, center));
|
||||
assert!(!is_point_in_fill_with_rule(
|
||||
&rings,
|
||||
center,
|
||||
SvgFillRule::EvenOdd
|
||||
));
|
||||
for point in [
|
||||
SvgGeometryPoint::new(1.0, 5.0),
|
||||
SvgGeometryPoint::new(2.0, 5.0),
|
||||
SvgGeometryPoint::new(8.0, 5.0),
|
||||
SvgGeometryPoint::new(10.0, 5.0),
|
||||
] {
|
||||
assert!(is_point_in_fill_with_rule(
|
||||
&rings,
|
||||
point,
|
||||
SvgFillRule::EvenOdd
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn curve_bounding_box_uses_bezier_extrema() {
|
||||
let path = path_segments("M0 0 C100 100 100-100 200 0");
|
||||
|
||||
Reference in New Issue
Block a user