[librsvg/rustification] bgo#763386 - Handle curveto segments where only three control points are coincident



commit f52d96f657f99c205f282fb9dec70459902bff48
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Dec 8 12:33:38 2016 -0600

    bgo#763386 - Handle curveto segments where only three control points are coincident
    
    For curveto segments with control points 1, 2, 3, 4, we correctly
    handled cases where 1/2 and 3/4 were coincident.  However, we failed at
    computing the directionality when 1/2/3 or 2/3/4 are coincident.
    
    Thanks to Massimo <sixtysix inwind it> for the original test case.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763386

 rust/src/marker.rs                                 |   37 +++++++++++++------
 .../reftests/bugs/763386-marker-coincident-ref.png |  Bin 0 -> 943 bytes
 .../reftests/bugs/763386-marker-coincident.svg     |   13 +++++++
 3 files changed, 38 insertions(+), 12 deletions(-)
---
diff --git a/rust/src/marker.rs b/rust/src/marker.rs
index c1d7de2..665680f 100644
--- a/rust/src/marker.rs
+++ b/rust/src/marker.rs
@@ -58,18 +58,6 @@ fn make_curve (x1: f64, y1: f64,
                mut x2: f64, mut y2: f64,
                mut x3: f64, mut y3: f64,
                x4: f64, y4: f64) -> Segment {
-    /* Fix the tangents for when the middle control points coincide with their respective endpoints */
-
-    if double_equals (x2, x1) && double_equals (y2, y1) {
-        x2 = x3;
-        y2 = y3;
-    }
-
-    if double_equals (x3, x4) && double_equals (y3, y4) {
-        x3 = x2;
-        y3 = y2;
-    }
-
     Segment::LineOrCurve {
         x1: x1, y1: y1,
         x2: x2, y2: y2,
@@ -207,6 +195,14 @@ fn get_segment_directionalities (segment: &Segment) -> Option <(f64, f64, f64, f
         Segment::LineOrCurve { x1, y1, x2, y2, x3, y3, x4, y4 } => {
             if points_equal (x1, y1, x2, y2) && points_equal (x1, y1, x3, y3) && points_equal (x1, y1, x4, 
y4) {
                 None
+            } else if points_equal (x1, y1, x2, y2) && points_equal (x1, y1, x3, y3) {
+                Some ((x4 - x1, y4 - y1, x4 - x3, y4 - y3))
+            } else if points_equal (x2, y2, x3, y3) && points_equal (x2, y2, x4, y4) {
+                Some ((x2 - x1, y2 - y1, x4 - x1, y4 - y1))
+            } else if points_equal (x1, y1, x2, y2) {
+                Some  ((x3 - x1, y3 - y1, x4 - x3, y4 - y3))
+            } else if points_equal (x3, y3, x4, y4) {
+                Some ((x2 - x1, y2 - y1, x4 - x2, y4 - y2))
             } else {
                 Some ((x2 - x1, y2 - y1, x4 - x3, y4 - y3))
             }
@@ -715,4 +711,21 @@ mod tests {
     fn curve_with_coincident_control_points_has_no_directionality () {
         assert! (super::get_segment_directionalities (&curve (1.0, 2.0, 1.0, 2.0, 1.0, 2.0, 1.0, 
2.0)).is_none ());
     }
+
+    #[test]
+    fn curve_with_123_coincident_has_directionality () {
+        let (v1x, v1y, v2x, v2y) =
+            super::get_segment_directionalities (&curve (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 40.0)).unwrap 
();
+        assert_eq! ((20.0, 40.0), (v1x, v1y));
+        assert_eq! ((20.0, 40.0), (v2x, v2y));
+    }
+
+    #[test]
+    fn curve_with_234_coincident_has_directionality () {
+        let (v1x, v1y, v2x, v2y) =
+            super::get_segment_directionalities (&curve (20.0, 40.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)).unwrap 
();
+
+        assert_eq! ((-20.0, -40.0), (v1x, v1y));
+        assert_eq! ((-20.0, -40.0), (v2x, v2y));
+    }
 }
diff --git a/tests/fixtures/reftests/bugs/763386-marker-coincident-ref.png 
b/tests/fixtures/reftests/bugs/763386-marker-coincident-ref.png
new file mode 100644
index 0000000..09e8852
Binary files /dev/null and b/tests/fixtures/reftests/bugs/763386-marker-coincident-ref.png differ
diff --git a/tests/fixtures/reftests/bugs/763386-marker-coincident.svg 
b/tests/fixtures/reftests/bugs/763386-marker-coincident.svg
new file mode 100644
index 0000000..6829102
--- /dev/null
+++ b/tests/fixtures/reftests/bugs/763386-marker-coincident.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg";
+     xmlns:xlink="http://www.w3.org/1999/xlink";
+     viewBox="0 0 130 64">
+    <marker id="marker"
+            viewBox="-4 -4 8 8"
+            orient="auto">
+      <path d="M -1 -4, -1, 4, 1, 0 Z"/>
+    </marker>
+    <path stroke-width="8" marker-start="url(#marker)" marker-end="url(#marker)"
+          stroke="red" d="M 12,12 c 0,0 0,0 40,40"/>
+    <path stroke-width="8" marker-start="url(#marker)" marker-end="url(#marker)"
+          stroke="red" d="M 118,12 c -40,40 -40,40 -40,40"/>
+</svg>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]