]> granicus.if.org Git - graphviz/commitdiff
tests: test_edge_node_overlap_utilities: check min edge stem/arrow overlap
authorMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Wed, 24 Aug 2022 10:08:13 +0000 (12:08 +0200)
committerMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Tue, 20 Sep 2022 15:53:06 +0000 (17:53 +0200)
tests/test_edge_node_overlap_utilities.cpp
tests/test_edge_node_overlap_utilities.h
tests/test_max_edge_node_overlap_polygon_node_shapes.cpp
tests/test_max_edge_node_overlap_simple.cpp
tests/test_min_edge_node_overlap_polygon_node_shapes.cpp
tests/test_min_edge_node_overlap_simple.cpp

index 5b15dea97e5a67ada0773bf8b3f7fd256eb202e9..3be32b9f7e8d4b73863b4a7a8f8598f781893d3f 100644 (file)
@@ -172,13 +172,15 @@ static bool skip_min_check_at_tail_node(std::string_view rankdir,
   return shapes_not_meeting_edge(rankdir).contains(node_shape);
 }
 
-/// check overlap between the edge and the nodes
+/// check overlap between the edge and the nodes and between the edge stem and
+/// the edge arrows
 static bool check_analyzed_svg(SVGAnalyzer &svg_analyzer,
                                const graph_options &graph_options,
                                const check_options &check_options) {
 
   const auto rankdir = graph_options.rankdir;
   const auto node_shape = graph_options.node_shape;
+  const auto dir = graph_options.dir;
 
   REQUIRE(svg_analyzer.graphs().size() == 1);
   auto &recreated_graph = svg_analyzer.graphs().back();
@@ -258,6 +260,51 @@ static bool check_analyzed_svg(SVGAnalyzer &svg_analyzer,
     }
   }
 
+  auto &edge_stem = edge.stem();
+  const auto edge_stem_bbox = edge_stem.outline_bbox();
+
+  // check overlap of edge stem and arrowhead
+  if (dir == "forward" || dir == "both") {
+    auto edge_arrowhead = dir == "forward" ? edge.arrow(0) : edge.arrow(1);
+    const auto edge_arrowhead_bbox = edge_arrowhead.outline_bbox();
+    const auto overlap_bbox = edge_stem_bbox.intersection(edge_arrowhead_bbox);
+    INFO("Edge stem and arrowhead overlap:");
+    INFO(fmt::format("  width:  {:.3f}", overlap_bbox.width));
+    INFO(fmt::format("  height: {:.3f}", overlap_bbox.height));
+    const auto edge_stem_arrowhead_overlap =
+        overlap_in_rank_direction(overlap_bbox, rankdir);
+
+    // check minimum overlap of edge stem and arrowhead
+    if (check_options.check_min_edge_stem_arrow_overlap) {
+      const auto min_edge_stem_arrowhead_overlap =
+          check_options.min_edge_stem_arrow_overlap;
+      DO_CHECK(edge_stem_arrowhead_overlap >=
+               min_edge_stem_arrowhead_overlap -
+                   check_options.svg_rounding_error * 2);
+    }
+  }
+
+  // check overlap of edge stem and arrowtail
+  if (dir == "back" || dir == "both") {
+    auto edge_arrowtail = edge.arrow(0);
+    const auto edge_arrowtail_bbox = edge_arrowtail.outline_bbox();
+    const auto overlap_bbox = edge_stem_bbox.intersection(edge_arrowtail_bbox);
+    INFO("Edge stem and arrowtail overlap:");
+    INFO(fmt::format("  width:  {:.3f}", overlap_bbox.width));
+    INFO(fmt::format("  height: {:.3f}", overlap_bbox.height));
+    const auto edge_stem_arrowtail_overlap =
+        overlap_in_rank_direction(overlap_bbox, rankdir);
+
+    // check minimum overlap of edge stem and arrowtail
+    if (check_options.check_min_edge_stem_arrow_overlap) {
+      const auto min_edge_stem_arrowtail_overlap =
+          check_options.min_edge_stem_arrow_overlap;
+      DO_CHECK(edge_stem_arrowtail_overlap >=
+               min_edge_stem_arrowtail_overlap -
+                   check_options.svg_rounding_error * 2);
+    }
+  }
+
   return success;
 }
 
@@ -337,8 +384,11 @@ void test_edge_node_overlap(const graph_options &graph_options,
           tc_check_options.check_max_edge_node_overlap,
       .check_min_edge_node_overlap =
           tc_check_options.check_min_edge_node_overlap,
+      .check_min_edge_stem_arrow_overlap =
+          tc_check_options.check_min_edge_stem_arrow_overlap,
       .max_node_edge_overlap = graphviz_bezier_clip_margin,
       .min_node_edge_overlap = 0,
+      .min_edge_stem_arrow_overlap = 0,
       .svg_rounding_error = graphviz_max_svg_rounding_error,
   };
 
index d101c8c00fea165e870f60f9b6c5b2c7d094556e..ea509caf71a2ea8917468487308f01e6cff8a182 100644 (file)
@@ -9,6 +9,8 @@ struct tc_check_options {
   bool check_max_edge_node_overlap = true;
   /// whether to check that there is enough overlap
   bool check_min_edge_node_overlap = true;
+  /// whether to check that there is enough overlap between edge stem and arrow
+  bool check_min_edge_stem_arrow_overlap = true;
 };
 
 struct check_options {
@@ -16,10 +18,14 @@ struct check_options {
   bool check_max_edge_node_overlap = true;
   /// whether to check that there is enough overlap
   bool check_min_edge_node_overlap = true;
+  /// whether to check that there is enough overlap between edge stem and arrow
+  bool check_min_edge_stem_arrow_overlap = true;
   /// maximum allowed overlap between edge and node
   double max_node_edge_overlap;
   /// minimum required overlap between edge and node
   double min_node_edge_overlap;
+  /// minimum required overlap between edge stem and arrow
+  double min_edge_stem_arrow_overlap;
   /// rounding error caused by limited precision in SVG attribute values
   double svg_rounding_error;
 };
index bb42b1c0c9b4561fc8786a35ff2f5459350ecde4..b48ba659a0993858f743343024653167778a54e9 100644 (file)
@@ -21,6 +21,7 @@ TEST_CASE(
   const tc_check_options check_options = {
       .check_max_edge_node_overlap = true,
       .check_min_edge_node_overlap = false,
+      .check_min_edge_stem_arrow_overlap = false,
   };
 
   const auto filename_base =
index 7b4ba89bbd9dcad196dd6c94e529eae1480c2dff..380850a182244b601b8ba5fb7084d85930e443fa 100644 (file)
@@ -16,7 +16,9 @@ TEST_CASE("Maximum edge node overlap",
   };
 
   const tc_check_options check_options = {.check_max_edge_node_overlap = true,
-                                          .check_min_edge_node_overlap = false};
+                                          .check_min_edge_node_overlap = false,
+                                          .check_min_edge_stem_arrow_overlap =
+                                              false};
 
   const auto filename_base = AUTO_NAME();
 
index 5586eb6daed94c450f829fd29bcba5b451f689a4..0dd6783c0b8e92cb996e088887e843a09b71e2a7 100644 (file)
@@ -20,6 +20,7 @@ TEST_CASE("Minimum edge and node overlap for polygon node shapes",
   const tc_check_options check_options = {
       .check_max_edge_node_overlap = false,
       .check_min_edge_node_overlap = true,
+      .check_min_edge_stem_arrow_overlap = false,
   };
 
   const auto filename_base =
index 3a413b47e48ea8f7ff9f81563b49e860ccc0cfa4..9a7b9b9a45bf2254e46768abcea742f7d0e5c312 100644 (file)
@@ -15,7 +15,9 @@ TEST_CASE("Minimum edge node overlap",
   };
 
   const tc_check_options check_options = {.check_max_edge_node_overlap = false,
-                                          .check_min_edge_node_overlap = true};
+                                          .check_min_edge_node_overlap = true,
+                                          .check_min_edge_stem_arrow_overlap =
+                                              false};
 
   const auto filename_base = AUTO_NAME();