]> granicus.if.org Git - graphviz/commitdiff
shapes: point_init/point_inside: fix clipping of edge at node outline
authorMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Fri, 16 Sep 2022 10:35:53 +0000 (12:35 +0200)
committerMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Tue, 11 Oct 2022 19:45:27 +0000 (21:45 +0200)
Take node penwidth into account for the point node shape

Following the fix for polygon and ellipse shapes except the 'point'
shape, this fixes the second part of arrow not respecting penwidth for
the 'point' shape. A similar fix needs to be applied to fix the second
part for the 'cylinder' node shape.

The test_edge_node_overlap_point_node_shape test now succeeds, so the
expectancy that it should fail is removed.

Towards https://gitlab.com/graphviz/graphviz/-/issues/372.

lib/common/shapes.c
tests/test_edge_node_overlap_point_node_shape.cpp

index a392816fb18bb3c84ce8465695e3dab805b9c1b3..d7ebb6825c1589d86827687db8fbea16469546cf 100644 (file)
@@ -3062,6 +3062,12 @@ static void point_init(node_t * n)
     else
        outp = peripheries;
     sides = 2;
+    const double penwidth = late_int(n, N_penwidth, DEFAULT_NODEPENWIDTH, MIN_NODEPENWIDTH);
+    if (peripheries >= 1 && penwidth > 0) {
+        // allocate extra vertices representing the outline, i.e., the outermost
+        // periphery with penwidth taken into account
+        ++outp;
+    }
     vertices = N_NEW(outp * sides, pointf);
     P.y = P.x = sz / 2.;
     vertices[0].x = -P.x;
@@ -3079,7 +3085,23 @@ static void point_init(node_t * n)
            i++;
        }
        sz = 2. * P.x;
+    } else {
+        i = sides;
+    }
+
+    if (outp > peripheries) {
+      // add an outline at half the penwidth outside the outermost periphery
+      P.x += penwidth / 2;
+      P.y += penwidth / 2;
+      vertices[i].x = -P.x;
+      vertices[i].y = -P.y;
+      i++;
+      vertices[i].x = P.x;
+      vertices[i].y = P.y;
+      i++;
     }
+    const double sz_outline = 2. * P.x;
+
     poly->regular = 1;
     poly->peripheries = peripheries;
     poly->sides = 2;
@@ -3089,6 +3111,7 @@ static void point_init(node_t * n)
     poly->vertices = vertices;
 
     ND_height(n) = ND_width(n) = PS2INCH(sz);
+    ND_outline_height(n) = ND_outline_width(n) = PS2INCH(sz_outline);
     ND_shape_info(n) = poly;
 }
 
@@ -3110,11 +3133,18 @@ static bool point_inside(inside_t * inside_context, pointf p)
     if (n != lastn) {
        int outp;
        polygon_t *poly = ND_shape_info(n);
+       const int sides = 2;
+       const double penwidth = late_int(n, N_penwidth, DEFAULT_NODEPENWIDTH, MIN_NODEPENWIDTH);
 
-       /* index to outer-periphery */
-       outp = 2 * (poly->peripheries - 1);
-       if (outp < 0)
-           outp = 0;
+       if (poly->peripheries >= 1 && penwidth > 0) {
+           /* index to outline, i.e., the outer-periphery with penwidth taken into account */
+           outp = sides * (poly->peripheries + 1 - 1);
+       } else {
+           /* index to outer-periphery */
+           outp = sides * (poly->peripheries - 1);
+           if (outp < 0)
+               outp = 0;
+       }
 
        radius = poly->vertices[outp + 1].x;
        lastn = n;
index 0ccfe24fa929f941545765037c82f0f72a5974e2..75928a13c03079ca4b7e580752a17f5af895a616 100644 (file)
@@ -7,8 +7,8 @@
 #include "test_utilities.h"
 
 TEST_CASE("Overlap point node shape",
-          "[!shouldfail] Test that an edge connected to a 'point' shaped node "
-          "touches that node and does not overlap it too much") {
+          "Test that an edge connected to a 'point' shaped node touches that "
+          "node and does not overlap it too much") {
 
   const auto shape = "point";
   INFO("Node shape: " << shape);