From: Emden Gansner Date: Fri, 29 Jun 2012 20:23:41 +0000 (-0400) Subject: Add insets to patchwork; add striped fill for boxes X-Git-Tag: LAST_LIBGRAPH~32^2~392 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8de050bdae4b08fd9c6e8ad25ec4e294dce72f2e;p=graphviz Add insets to patchwork; add striped fill for boxes --- diff --git a/lib/common/const.h b/lib/common/const.h index f6c4ea948..f067d4d35 100644 --- a/lib/common/const.h +++ b/lib/common/const.h @@ -213,11 +213,13 @@ #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) diff --git a/lib/common/emit.c b/lib/common/emit.c index 9056dd3d6..9c351aa35 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -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); diff --git a/lib/common/render.h b/lib/common/render.h index 36f0b0d2b..d56bc32e3 100644 --- a/lib/common/render.h +++ b/lib/common/render.h @@ -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); diff --git a/lib/common/shapes.c b/lib/common/shapes.c index 76b3c31dd..6d5d659dd 100644 --- a/lib/common/shapes.c +++ b/lib/common/shapes.c @@ -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 { diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index 03ea2a277..079eeb052 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -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; } } }