From 5e003ca402aa3850109514f11465fec49377937a Mon Sep 17 00:00:00 2001 From: Magnus Jacobsson <Magnus.Jacobsson@berotec.se> Date: Sun, 27 Mar 2022 12:56:45 +0200 Subject: [PATCH] arrows: refactor arrow generating functions to return the actual start point This is currently a no-op, but upcoming commits will adjust the arrow start point to take pendwidth into account in order to avoid overlapping the node periphery and subsequent primitive arrow shapes of multi-shape arrows. The arrow start point is the point on the arrow which is farthest away along the edge from the node it is associated with. Towards https://gitlab.com/graphviz/graphviz/-/issues/372. --- lib/common/arrows.c | 56 +++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/lib/common/arrows.c b/lib/common/arrows.c index 515a35c1b..29284fbc3 100644 --- a/lib/common/arrows.c +++ b/lib/common/arrows.c @@ -107,18 +107,18 @@ static arrowname_t Arrownames[] = { typedef struct arrowtype_t { int type; double lenfact; /* ratio of length of this arrow type to standard arrow */ - void (*gen) (GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); /* generator function for type */ + pointf (*gen) (GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); /* generator function for type */ } arrowtype_t; /* forward declaration of functions used in Arrowtypes[] */ -static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_curve(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); -static void arrow_type_gap(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_normal(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_crow(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_tee(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_box(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_dot(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_curve(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); +static pointf arrow_type_gap(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag); static const arrowtype_t Arrowtypes[] = { {ARR_TYPE_NORM, 1.0, arrow_type_normal}, @@ -424,7 +424,7 @@ void arrowOrthoClip(edge_t* e, pointf* ps, int startp, int endp, bezier* spl, in } } -static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_normal(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; @@ -460,9 +460,11 @@ static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double arrowsize, gvrender_polygon(job, &a[2], 3, !(flag & ARR_MOD_OPEN)); else gvrender_polygon(job, &a[1], 3, !(flag & ARR_MOD_OPEN)); + + return q; } -static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_crow(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { pointf m, q, v, w, a[9]; double arrowwidth, shaftwidth; @@ -520,9 +522,11 @@ static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double arrowsize, d gvrender_polygon(job, &a[3], 6, 1); else gvrender_polygon(job, a, 9, 1); + + return q; } -static void arrow_type_gap(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_gap(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; (void)penwidth; @@ -535,9 +539,11 @@ static void arrow_type_gap(GVJ_t * job, pointf p, pointf u, double arrowsize, do a[0] = p; a[1] = q; gvrender_polyline(job, a, 2); + + return q; } -static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_tee(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; (void)penwidth; @@ -571,9 +577,11 @@ static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double arrowsize, do a[0] = p; a[1] = q; gvrender_polyline(job, a, 2); + + return q; } -static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_box(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; (void)penwidth; @@ -605,9 +613,11 @@ static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double arrowsize, do a[0] = m; a[1] = q; gvrender_polyline(job, a, 2); + + return q; } -static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; (void)penwidth; @@ -632,9 +642,11 @@ static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double arrowsize gvrender_polygon(job, a, 3, !(flag & ARR_MOD_OPEN)); else gvrender_polygon(job, a, 4, !(flag & ARR_MOD_OPEN)); + + return q; } -static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_dot(GVJ_t * job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; (void)penwidth; @@ -648,13 +660,17 @@ static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double arrowsize, do AF[1].x = p.x + u.x / 2. + r; AF[1].y = p.y + u.y / 2. + r; gvrender_ellipse(job, AF, !(flag & ARR_MOD_OPEN)); + + const pointf q = {p.x + u.x, p.y + u.y}; + + return q; } /* Draw a concave semicircle using a single cubic bezier curve that touches p at its midpoint. * See http://digerati-illuminatus.blogspot.com.au/2008/05/approximating-semicircle-with-cubic.html for details. */ -static void arrow_type_curve(GVJ_t* job, pointf p, pointf u, double arrowsize, double penwidth, int flag) +static pointf arrow_type_curve(GVJ_t* job, pointf p, pointf u, double arrowsize, double penwidth, int flag) { (void)arrowsize; @@ -698,6 +714,8 @@ static void arrow_type_curve(GVJ_t* job, pointf p, pointf u, double arrowsize, d else if (flag & ARR_MOD_RIGHT) Bezier(AF, 3, 0.5, AF, NULL); gvrender_beziercurve(job, AF, sizeof(AF) / sizeof(pointf), FALSE, FALSE, FALSE); + + return q; } @@ -711,9 +729,7 @@ static pointf arrow_gen_type(GVJ_t * job, pointf p, pointf u, double arrowsize, if (f == arrowtype->type) { u.x *= arrowtype->lenfact * arrowsize; u.y *= arrowtype->lenfact * arrowsize; - (arrowtype->gen) (job, p, u, arrowsize, penwidth, flag); - p.x = p.x + u.x; - p.y = p.y + u.y; + p = (arrowtype->gen) (job, p, u, arrowsize, penwidth, flag); break; } } -- 2.40.0