]> granicus.if.org Git - graphviz/commitdiff
Add insets to patchwork; add striped fill for boxes
authorEmden Gansner <erg@research.att.com>
Fri, 29 Jun 2012 20:23:41 +0000 (16:23 -0400)
committerEmden Gansner <erg@research.att.com>
Fri, 29 Jun 2012 20:23:41 +0000 (16:23 -0400)
lib/common/const.h
lib/common/emit.c
lib/common/render.h
lib/common/shapes.c
lib/gvc/gvrender.c

index f6c4ea9487493c6984197337994122181229d3b5..f067d4d358262501fba5f46e3997df0e8fbbec62 100644 (file)
 #define FOLDER (1 << 8)
 #define BOX3D (1 << 9)
 #define COMPONENT (1 << 10)
+#define STRIPED (1 << 11)
 
 /* fill types */
 #define FILL      1
 #define GRADIENT  2
 #define RGRADIENT 3
+#define NO_POLY   4    /* bit flag: if set, do fill only */
 
 /* label types */
 #define LT_NONE        (0 << 1)
index 9056dd3d6dbd82a69d33030cc37f7a06f842b2fe..9c351aa35b4ec0aac120bc41e6197095117ec445 100644 (file)
@@ -293,6 +293,13 @@ static char **checkClusterStyle(graph_t* sg, int *flagp)
                    qp++;
                    *(qp-1) = *qp;
                } while (*qp);
+           }else if (strcmp(p, "striped") == 0) {
+               istyle |= STRIPED;
+               qp = pp; /* remove rounded from list passed to renderer */
+               do {
+                   qp++;
+                   *(qp-1) = *qp;
+               } while (*qp);
            }else if (strcmp(p, "rounded") == 0) {
                istyle |= ROUNDED;
                qp = pp; /* remove rounded from list passed to renderer */
@@ -308,6 +315,68 @@ static char **checkClusterStyle(graph_t* sg, int *flagp)
     return pstyle;
 }
 
+static int
+splitColorList (char* clist, char*** carray)
+{
+    char* p;
+    char** colors;
+    char* buf;
+    int i, numc = 1;
+
+    /* count colors */
+    for (p = clist; *p; p++) {
+       if (*p == ':') numc++;
+    }
+    buf = strdup(clist);
+    colors = N_NEW(numc, char*);
+    for (i = 0, p = strtok(buf, ":"); p; i++, p = strtok(0, ":")) {
+       if (p[0] == '\0')
+           colors[i] = NULL;
+       else
+           colors[i] = p;
+    }
+
+    *carray = colors;
+    return numc;
+}
+
+/* stripedBox:
+ * Fill a rectangular box with verticle stripes of colors.
+ * AF gives 4 corner points, with AF[0] the LL corner and the points ordered CCW.
+ * clrs is a list of colon separated colors. 
+ * No boundaries are drawn.
+ */
+void
+stripedBox (GVJ_t * job, pointf* AF, char* clrs)
+{
+    char** colors;
+    int i, numclrs = splitColorList (clrs, &colors);
+    double xdelta;
+    pointf pts[4];
+    double lastx = AF[1].x;
+
+    if (numclrs < 1) numclrs = 1;
+    xdelta = (AF[1].x - AF[0].x)/numclrs;
+    pts[0] = AF[0];
+    pts[1] = AF[1];
+    pts[2] = AF[2];
+    pts[3] = AF[3];
+    if (numclrs > 1)
+       pts[1].x = pts[2].x = pts[0].x + xdelta;
+    for (i = 0; i < numclrs; i++) { 
+       gvrender_set_fillcolor (job, (colors[i]?colors[i]:DEFAULT_COLOR));
+       gvrender_polygon(job, pts, 4, FILL | NO_POLY);
+       pts[0].x = pts[3].x = pts[1].x;
+       if (i == numclrs-2) 
+           pts[1].x = pts[2].x = lastx;
+       else
+           pts[1].x = pts[2].x = pts[0].x + xdelta;
+    }
+    free (colors[0]);
+    free (colors);
+}
+
 void emit_map_rect(GVJ_t *job, boxf b)
 {
     obj_state_t *obj = job->obj;
@@ -3462,6 +3531,20 @@ void emit_clusters(GVJ_t * job, Agraph_t * g, int flags)
                round_corners(job, AF, 4, istyle, filled);
            }
        }
+       else if (istyle & STRIPED) {
+           AF[0] = GD_bb(sg).LL;
+           AF[2] = GD_bb(sg).UR;
+           AF[1].x = AF[2].x;
+           AF[1].y = AF[0].y;
+           AF[3].x = AF[0].x;
+           AF[3].y = AF[2].y;
+           if (late_int(sg, G_peripheries, 1, 0) == 0)
+               gvrender_set_pencolor(job, "transparent");
+           else
+               gvrender_set_pencolor(job, pencolor);
+           stripedBox (job, AF, fillcolor);
+           gvrender_box(job, GD_bb(sg), 0);
+       }
        else {
            if (late_int(sg, G_peripheries, 1, 0)) {
                gvrender_set_pencolor(job, pencolor);
index 36f0b0d2b0d2cfc39923c9b82a7d26f412f144af..d56bc32e362c2e2004474f26d65001ff2e9168a5 100644 (file)
@@ -152,6 +152,7 @@ extern "C" {
     extern shape_kind shapeOf(node_t *);
     extern void shape_clip(node_t * n, pointf curve[4]);
     extern void make_simple_label (graph_t* g, textlabel_t* rv);
+    extern void stripedBox (GVJ_t * job, pointf* AF, char* clrs);
     extern stroke_t* taper (bezier*, double (*radfunc_t)(double,double,double), double initwid, int linejoin, int linecap);
     extern stroke_t* taper0 (bezier* bez, double initwid);
     extern pointf textsize(graph_t *g, textpara_t * para, char *fontname, double fontsize);
index 76b3c31dda087282d8a06befc4d6b35d35bbafc9..6d5d659dd77602c8a8561060d2f336a363c0b7f0 100644 (file)
@@ -280,6 +280,19 @@ char *findAttrColor(void *obj, attrsym_t *colorattr, char *dflt){
     return color;
 }
 
+
+static int
+isBox (node_t* n)
+{
+    polygon_t *p;
+
+    if ((p = ND_shape(n)->polygon)) {
+       return (p->sides == 4 && (ROUND(p->orientation) % 90) == 0 && p->distortion == 0. && p->skew == 0.);
+    }
+    else
+       return 0;
+}
+
 static char **checkStyle(node_t * n, int *flagp)
 {
     char *style;
@@ -321,6 +334,13 @@ static char **checkStyle(node_t * n, int *flagp)
                    qp++;
                    *(qp - 1) = *qp;
                } while (*qp);
+           } else if (streq(p, "striped") && isBox(n)) {
+               istyle |= STRIPED;
+               qp = pp;        /* remove striped from list passed to renderer */
+               do {
+                   qp++;
+                   *(qp - 1) = *qp;
+               } while (*qp);
            } else
                pp++;
        }
@@ -1644,6 +1664,10 @@ static void poly_gencode(GVJ_t * job, node_t * n)
                filled = FILL;
            }
        }
+       else if (style & STRIPED) {
+           fillcolor = findFill (n);
+           filled = TRUE;
+       }
        else {
            filled = FALSE;
        }
@@ -1702,6 +1726,10 @@ static void poly_gencode(GVJ_t * job, node_t * n)
            if (style & DIAGONALS) {
                Mcircle_hack(job, n);
            }
+       } else if (style & STRIPED) {
+           if (j == 0)
+               stripedBox (job, AF, fillcolor);
+           gvrender_polygon(job, AF, sides, 0);
        } else if (SPECIAL_CORNERS(style)) {
            round_corners(job, AF, sides, style, filled);
        } else {
index 03ea2a277d752630c0018a4714a28a2878e8b982..079eeb052efc820b25289c8ce405909e21bfe95b 100644 (file)
@@ -569,9 +569,18 @@ void gvrender_ellipse(GVJ_t * job, pointf * pf, int n, int filled)
 
 void gvrender_polygon(GVJ_t * job, pointf * af, int n, int filled)
 {
+    int noPoly = 0;
+    gvcolor_t save_pencolor;
+
     gvrender_engine_t *gvre = job->render.engine;
     if (gvre) {
        if (gvre->polygon && job->obj->pen != PEN_NONE) {
+           if (filled & NO_POLY) {
+               noPoly = 1;
+               filled &= ~NO_POLY;
+               save_pencolor = job->obj->pencolor;
+               job->obj->pencolor = job->obj->fillcolor;
+           }
            if (job->flags & GVRENDER_DOES_TRANSFORM)
                gvre->polygon(job, af, n, filled);
            else {
@@ -582,6 +591,8 @@ void gvrender_polygon(GVJ_t * job, pointf * af, int n, int filled)
                gvrender_ptf_A(job, af, AF, n);
                gvre->polygon(job, AF, n, filled);
            }
+           if (noPoly)
+               job->obj->pencolor = save_pencolor;
        }
     }
 }