]> granicus.if.org Git - graphviz/commitdiff
arrows: arrow_length_tee: take edge penwidth into account when calculating length
authorMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Thu, 6 Oct 2022 10:36:48 +0000 (12:36 +0200)
committerMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Fri, 4 Nov 2022 17:47:53 +0000 (18:47 +0100)
The test_edge_node_overlap_tee_edge_arrow test case now succeeds, so
the expectancy that it should fail is removed.

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

CHANGELOG.md
lib/common/arrows.c
tests/test_edge_node_overlap_tee_edge_arrow.cpp

index dc55cfb99b02bb6b6e93f1df71a00c899eecaaf4..8dc98dd7385ec6aae7932103c8c667c50501fb56 100644 (file)
@@ -21,7 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 
 - Failure of arrowhead and arrowtail to respect penwidth #372 \
-  Fixed also for the `diamond` [edge arrow shape](https://graphviz.org/doc/info/arrows.html#primitive-shapes).
+  Fixed also for the `diamond` and `tee`
+  [edge arrow shapes](https://graphviz.org/doc/info/arrows.html#primitive-shapes).
 - The CMake build system no longer uses the final install location as the
   staging area for example graphs and templates during `cpack`. This bug was
   introduced in Graphviz 4.0.0. #2232
index d6bf26a1e09100440d9bec6c85baf6f689feebfe..7811d29f16729f3cda001dd07fae8d2ab4dc260a 100644 (file)
@@ -126,6 +126,7 @@ static pointf arrow_type_gap(GVJ_t * job, pointf p, pointf u, double arrowsize,
 
 static double arrow_length_generic(double lenfact, double arrowsize, double penwidth, int flag);
 static double arrow_length_normal(double lenfact, double arrowsize, double penwidth, int flag);
+static double arrow_length_tee(double lenfact, double arrowsize, double penwidth, int flag);
 static double arrow_length_box(double lenfact, double arrowsize, double penwidth, int flag);
 static double arrow_length_diamond(double lenfact, double arrowsize, double penwidth, int flag);
 static double arrow_length_dot(double lenfact, double arrowsize, double penwidth, int flag);
@@ -133,7 +134,7 @@ static double arrow_length_dot(double lenfact, double arrowsize, double penwidth
 static const arrowtype_t Arrowtypes[] = {
     {ARR_TYPE_NORM, 1.0, arrow_type_normal, arrow_length_normal},
     {ARR_TYPE_CROW, 1.0, arrow_type_crow, arrow_length_generic},
-    {ARR_TYPE_TEE, 0.5, arrow_type_tee, arrow_length_generic},
+    {ARR_TYPE_TEE, 0.5, arrow_type_tee, arrow_length_tee},
     {ARR_TYPE_BOX, 1.0, arrow_type_box, arrow_length_box},
     {ARR_TYPE_DIAMOND, 1.2, arrow_type_diamond, arrow_length_diamond},
     {ARR_TYPE_DOT, 0.8, arrow_type_dot, arrow_length_dot},
@@ -1054,6 +1055,33 @@ static double arrow_length_normal(double lenfact, double arrowsize,
   return full_length - overlap;
 }
 
+static double arrow_length_tee(double lenfact, double arrowsize,
+                              double penwidth, int flag) {
+    (void)flag;
+
+    // The `tee` arrow shape normally begins and ends with a polyline which
+    // doesn't extend visually beyond its starting point, so we only have to
+    // take penwidth into account if the polygon part visually extends the
+    // polyline part at the start or end points.
+
+    const double nominal_length = lenfact * arrowsize * ARROW_LENGTH;
+    double length = nominal_length;
+
+    // see the 'arrow_type_tee' function for the magical constants used below
+
+    const double polygon_extend_over_polyline_at_start = penwidth / 2 - (1 - 0.6) * nominal_length;
+    if (polygon_extend_over_polyline_at_start > 0) {
+       length += polygon_extend_over_polyline_at_start;
+    }
+
+    const double polygon_extend_over_polyline_at_end = penwidth / 2 - 0.2 * nominal_length;
+    if (polygon_extend_over_polyline_at_start > 0) {
+       length += polygon_extend_over_polyline_at_end;
+    }
+
+    return length;
+}
+
 static double arrow_length_box(double lenfact, double arrowsize,
                               double penwidth, int flag) {
   (void)flag;
index 383ca97c7e8d49414bcd17c7efcdd678e8cb5952..6bc6f074da296bf9c4be139d8aa9f1a7c9a8f31f 100644 (file)
@@ -6,8 +6,8 @@
 #include "test_utilities.h"
 
 TEST_CASE("Edge node overlap for 'tee' arrow",
-          "[!shouldfail] An edge connected to a node shall touch that node and "
-          "not overlap it too much") {
+          "An edge connected to a node shall touch that node and not overlap "
+          "it too much") {
 
   const std::string_view primitive_arrow_shape = "tee";