]> granicus.if.org Git - graphviz/commitdiff
improves #1295
authorellson <devnull@localhost>
Thu, 28 Feb 2008 20:13:37 +0000 (20:13 +0000)
committerellson <devnull@localhost>
Thu, 28 Feb 2008 20:13:37 +0000 (20:13 +0000)
    more tuning required.....

lib/common/arrows.c
lib/common/emit.c
lib/common/render.h

index 161405ffa380d9b400e449624f3bed4e7cc8e381..9d77d32dfac72f835aa4f1f8e820ba6616f1f35d 100644 (file)
@@ -98,17 +98,17 @@ static arrowname_t Arrownames[] = {
 
 typedef struct arrowtype_t {
     int type;
-    double lenfact;            /* ratio of length of this arrow type to standards arrow */
-    void (*gen) (GVJ_t * job, pointf p, pointf u, double wscale, int flag);    /* generator function for type */
+    double lenfact;            /* ratio of length of this arrow type to standard arrow */
+    void (*gen) (GVJ_t * job, pointf p, pointf u, 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 wscale, int flag);
-static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
-static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double wscale, int flag);
+static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
+static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double penwidth, int flag);
 
 static arrowtype_t Arrowtypes[] = {
     {ARR_TYPE_NORM, 1.0, arrow_type_normal},
@@ -289,12 +289,17 @@ int arrowStartClip(edge_t* e, point * ps, int startp,
     return startp;
 }
 
-static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
     pointf q, v, a[5];
+    double arrowwidth;
 
-    v.x = -u.y * 0.35 * wscale;
-    v.y = u.x * 0.35 * wscale;
+    arrowwidth = 0.35;
+    if (penwidth > 4)
+        arrowwidth *= penwidth / 4;
+
+    v.x = -u.y * arrowwidth;
+    v.y = u.x * arrowwidth;
     q.x = p.x + u.x;
     q.y = p.y + u.y;
     if (flag & ARR_MOD_INV) {
@@ -320,12 +325,23 @@ static void arrow_type_normal(GVJ_t * job, pointf p, pointf u, double wscale, in
        gvrender_polygon(job, &a[1], 3, !(flag & ARR_MOD_OPEN));
 }
 
-static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
-    pointf m, n, q, v, a[7];
+    pointf m, n, q, v, w, a[9];
+    double arrowwidth, shaftwidth;
+
+    arrowwidth = 0.45;
+    if (penwidth > 4)
+        arrowwidth *= penwidth / 4;
+
+    shaftwidth = 0;
+    if (penwidth > 1)
+       shaftwidth = 0.05 * (penwidth - 1);
 
-    v.x = -u.y * 0.45;
-    v.y = u.x * 0.45;
+    v.x = -u.y * arrowwidth;
+    v.y = u.x * arrowwidth;
+    w.x = -u.y * shaftwidth;
+    w.y = u.x * shaftwidth;
     q.x = p.x + u.x;
     q.y = p.y + u.y;
     m.x = p.x + u.x * 0.3;
@@ -333,31 +349,45 @@ static void arrow_type_crow(GVJ_t * job, pointf p, pointf u, double wscale, int
     n.x = p.x + u.x * 0.7;
     n.y = p.y + u.y * 0.7;
     if (flag & ARR_MOD_INV) {
-       a[0] = a[6] = p;
+       a[0] = a[8] = p;
        a[1].x = q.x - v.x;
        a[1].y = q.y - v.y;
-       a[2] = a[4] = m;
-       a[3] = q;
-       a[5].x = q.x + v.x;
-       a[5].y = q.y + v.y;
+       a[2].x = m.x - w.x;
+       a[2].y = m.y - w.y;
+       a[3].x = q.x - w.x;
+       a[3].y = q.y - w.y;
+       a[4] = q;
+       a[5].x = q.x + w.x;
+       a[5].y = q.y + w.y;
+       a[6].x = m.x + w.x;
+       a[6].y = m.y + w.y;
+       a[7].x = q.x + v.x;
+       a[7].y = q.y + v.y;
     } else {
-       a[0] = a[6] = q;
+       a[0] = a[8] = q;
        a[1].x = p.x - v.x;
        a[1].y = p.y - v.y;
-       a[2] = a[4] = n;
-       a[3] = p;
-       a[5].x = p.x + v.x;
-       a[5].y = p.y + v.y;
+       a[2].x = n.x - w.x;
+       a[2].y = n.y - w.y;
+       a[3].x = p.x;
+       a[3].y = p.y;
+       a[4] = p;
+       a[5].x = p.x;
+       a[5].y = p.y;
+       a[6].x = n.x + w.x;
+       a[6].y = n.y + w.y;
+       a[7].x = p.x + v.x;
+       a[7].y = p.y + v.y;
     }
     if (flag & ARR_MOD_LEFT)
-       gvrender_polygon(job, a, 5, 1);
+       gvrender_polygon(job, a, 6, 1);
     else if (flag & ARR_MOD_RIGHT)
-       gvrender_polygon(job, &a[2], 5, 1);
+       gvrender_polygon(job, &a[3], 6, 1);
     else
-       gvrender_polygon(job, a, 7, 1);
+       gvrender_polygon(job, a, 9, 1);
 }
 
-static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
     pointf m, n, q, v, a[4];
 
@@ -390,7 +420,7 @@ static void arrow_type_tee(GVJ_t * job, pointf p, pointf u, double wscale, int f
     gvrender_polyline(job, a, 2);
 }
 
-static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
     pointf m, q, v, a[4];
 
@@ -421,7 +451,7 @@ static void arrow_type_box(GVJ_t * job, pointf p, pointf u, double wscale, int f
     gvrender_polyline(job, a, 2);
 }
 
-static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
     pointf q, r, v, a[5];
 
@@ -445,7 +475,7 @@ static void arrow_type_diamond(GVJ_t * job, pointf p, pointf u, double wscale, i
        gvrender_polygon(job, a, 4, !(flag & ARR_MOD_OPEN));
 }
 
-static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
     double r;
     pointf AF[2];
@@ -458,7 +488,7 @@ static void arrow_type_dot(GVJ_t * job, pointf p, pointf u, double wscale, int f
     gvrender_ellipse(job, AF, 2, !(flag & ARR_MOD_OPEN));
 }
 
-static pointf arrow_gen_type(GVJ_t * job, pointf p, pointf u, double wscale, int flag)
+static pointf arrow_gen_type(GVJ_t * job, pointf p, pointf u, double penwidth, int flag)
 {
     int f;
     arrowtype_t *arrowtype;
@@ -468,7 +498,7 @@ static pointf arrow_gen_type(GVJ_t * job, pointf p, pointf u, double wscale, int
        if (f == arrowtype->type) {
            u.x *= arrowtype->lenfact;
            u.y *= arrowtype->lenfact;
-           (arrowtype->gen) (job, p, u, wscale, flag);
+           (arrowtype->gen) (job, p, u, penwidth, flag);
            p.x = p.x + u.x;
            p.y = p.y + u.y;
            break;
@@ -515,7 +545,7 @@ boxf arrow_bb(pointf p, pointf u, double scale, int flag)
     return bb;
 }
 
-void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, double scale, double wscale, int flag)
+void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, double scale, double penwidth, int flag)
 {
     obj_state_t *obj = job->obj;
     double s;
@@ -542,12 +572,12 @@ void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, doub
 
     /* arrow head closest to node */
     f = flag & ((1 << 16) - 1);
-    p = arrow_gen_type(job, p, u, wscale, f);
+    p = arrow_gen_type(job, p, u, penwidth, f);
 
     /* arrow head furthest from node */
     /*   start where first one ended */
     f = (flag >> 16) & ((1 << 16) - 1);
-    arrow_gen_type(job, p, u, wscale, f);
+    arrow_gen_type(job, p, u, penwidth, f);
 
     gvrender_end_context(job);
 
@@ -555,11 +585,11 @@ void arrow_newgen(GVJ_t * job, emit_state_t emit_state, pointf p, pointf u, doub
 }
 
 /* FIXME emit.c and output.c require wrapper for int point coords */
-void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u, double scale, double wscale, int flag)
+void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u, double scale, double penwidth, int flag)
 {
     pointf P, U;
 
     P2PF(p, P);
     P2PF(u, U);
-    arrow_newgen(job, emit_state, P, U, scale, wscale, flag);
+    arrow_newgen(job, emit_state, P, U, scale, penwidth, flag);
 }
index ab93c111d1976c9bb680f68bf97dbbd444b05fac..ad45a32f33fc0f4af502415fea781da3bd85ec70 100644 (file)
@@ -1264,7 +1264,7 @@ static void emit_edge_graphics(GVJ_t * job, edge_t * e, char** styles)
     bezierf bzf;
     splinesf offspl, tmpspl;
     pointf pf0, pf1, pf2 = { 0, 0 }, pf3, *offlist, *tmplist;
-    double scale, wscale = 1., numc2;
+    double scale, numc2;
     char* p;
 
 #define SEP 2.0
@@ -1274,9 +1274,6 @@ static void emit_edge_graphics(GVJ_t * job, edge_t * e, char** styles)
        scale = late_double(e, E_arrowsz, 1.0, 0.0);
        color = late_string(e, E_color, "");
 
-       if (job->obj->penwidth > 4)
-           wscale = job->obj->penwidth / 4;
-
        /* need to know how many colors separated by ':' */
        for (p = color; *p; p++)
            if (*p == ':')
@@ -1386,7 +1383,7 @@ static void emit_edge_graphics(GVJ_t * job, edge_t * e, char** styles)
                    }
                }
                arrow_gen(job, EMIT_TDRAW, bz.sp, bz.list[0],
-                       scale, wscale, bz.sflag);
+                       scale, job->obj->penwidth, bz.sflag);
            }
            if (bz.eflag) {
                if (color != headcolor) {
@@ -1397,7 +1394,7 @@ static void emit_edge_graphics(GVJ_t * job, edge_t * e, char** styles)
                    }
                }
                arrow_gen(job, EMIT_HDRAW, bz.ep, bz.list[bz.size - 1],
-                       scale, wscale, bz.eflag);
+                       scale, job->obj->penwidth, bz.eflag);
            }
            free(colors);
            for (i = 0; i < offspl.size; i++) {
@@ -1431,11 +1428,11 @@ static void emit_edge_graphics(GVJ_t * job, edge_t * e, char** styles)
                                         FALSE, FALSE);
                    if (bz.sflag) {
                        arrow_gen(job, EMIT_TDRAW, bz.sp, bz.list[0],
-                               scale, wscale, bz.sflag);
+                               scale, job->obj->penwidth, bz.sflag);
                    }
                    if (bz.eflag) {
                        arrow_gen(job, EMIT_HDRAW, bz.ep, bz.list[bz.size - 1],
-                               scale, wscale, bz.eflag);
+                               scale, job->obj->penwidth, bz.eflag);
                    }
                     /* arrow_gen resets the job style 
                      * If we have more splines to do, restore the old one.
index 04fd2e7e9f3ab95ebdd03b20d58293ec11a8f9ba..22d5a84d17870728facbf42300327582ef5b05e5 100644 (file)
@@ -67,7 +67,7 @@ extern "C" {
     extern void arrow_flags(Agedge_t * e, int *sflag, int *eflag);
     extern boxf arrow_bb(pointf p, pointf u, double scale, int flag);
     extern void arrow_gen(GVJ_t * job, emit_state_t emit_state, point p, point u,
-                         double scale, double wscale, int flag);
+                         double scale, double penwidth, int flag);
     extern double arrow_length(edge_t * e, int flag);
     extern int arrowEndClip(edge_t*, point*, int, int , bezier*, int eflag);
     extern int arrowStartClip(edge_t*, point* ps, int, int, bezier*, int sflag);