From: ellson Date: Thu, 1 Nov 2007 21:01:07 +0000 (+0000) Subject: add support for imagescale attribute ( imagescale=[no|yes|width|height|both] ) X-Git-Tag: LAST_LIBGRAPH~32^2~5101 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=506383f70ea74d8b079d49356b19c3e5f5e5adcd;p=graphviz add support for imagescale attribute ( imagescale=[no|yes|width|height|both] ) --- diff --git a/lib/common/globals.h b/lib/common/globals.h index bac10fcac..bec2def3b 100644 --- a/lib/common/globals.h +++ b/lib/common/globals.h @@ -102,7 +102,7 @@ extern "C" { *N_fontsize, *N_fontname, *N_fontcolor, *N_label, *N_nojustify, *N_style, *N_showboxes, *N_sides, *N_peripheries, *N_orientation, - *N_skew, *N_distortion, *N_fixed, *N_layer, + *N_skew, *N_distortion, *N_fixed, *N_imagescale, *N_layer, *N_group, *N_comment, *N_vertices, *N_z; EXTERN attrsym_t *E_weight, *E_minlen, *E_color, diff --git a/lib/common/htmltable.c b/lib/common/htmltable.c index eb5330269..ae7ba7ef7 100644 --- a/lib/common/htmltable.c +++ b/lib/common/htmltable.c @@ -411,7 +411,7 @@ emit_html_img(GVJ_t * job, htmlimg_t * cp, htmlenv_t * env) A[3].x = A[0].x; A[3].y = A[2].y; - gvrender_usershape(job, cp->src, A, 4, TRUE, 0); + gvrender_usershape(job, cp->src, A, 4, TRUE, ""); } static void diff --git a/lib/common/input.c b/lib/common/input.c index 1fb1562bb..7919297d7 100644 --- a/lib/common/input.c +++ b/lib/common/input.c @@ -669,6 +669,7 @@ void graph_init(graph_t * g, boolean use_rankdir) N_orientation = agfindattr(g->proto->n, "orientation"); N_distortion = agfindattr(g->proto->n, "distortion"); N_fixed = agfindattr(g->proto->n, "fixedsize"); + N_imagescale = agfindattr(g->proto->n, "imagescale"); N_nojustify = agfindattr(g->proto->n, "nojustify"); N_layer = agfindattr(g->proto->n, "layer"); N_group = agfindattr(g->proto->n, "group"); diff --git a/lib/common/shapes.c b/lib/common/shapes.c index 218e5d74c..8372488c7 100644 --- a/lib/common/shapes.c +++ b/lib/common/shapes.c @@ -1474,7 +1474,7 @@ static void poly_gencode(GVJ_t * job, node_t * n) gvrender_polygon(job, AF, sides, filled); } } - gvrender_usershape(job, name, AF, sides, filled, mapbool(late_string(n, N_fixed, "false"))); + gvrender_usershape(job, name, AF, sides, filled, late_string(n, N_imagescale, "false")); filled = FALSE; /* with user shapes, we have done the fill if needed */ } diff --git a/lib/common/usershape.h b/lib/common/usershape.h index 3c6455476..3ce3e71df 100644 --- a/lib/common/usershape.h +++ b/lib/common/usershape.h @@ -28,6 +28,14 @@ extern "C" { FT_PDF, FT_PS, FT_EPS } imagetype_t; + typedef enum { + IMAGESCALE_NO, /* no image scaling */ + IMAGESCALE_YES, /* scale image to fit but keep aspect ratio */ + IMAGESCALE_WIDTH, /* scale image width to fit, keep height fixed */ + IMAGESCALE_HEIGHT, /* scale image height to fit, keep width fixed */ + IMAGESCALE_BOTH /* scale image to fit without regard for aspect ratio */ + } imagescale_t; + typedef struct usershape_s usershape_t; struct usershape_s { diff --git a/lib/gvc/gvcproc.h b/lib/gvc/gvcproc.h index 37bac1e38..87690b559 100644 --- a/lib/gvc/gvcproc.h +++ b/lib/gvc/gvcproc.h @@ -121,7 +121,7 @@ extern "C" { int arrow_at_start, int arrow_at_end, boolean filled); extern void gvrender_polyline(GVJ_t * job, pointf * AF, int n); extern void gvrender_comment(GVJ_t * job, char *str); - extern void gvrender_usershape(GVJ_t * job, char *name, pointf * AF, int n, boolean filled, boolean expand); + extern void gvrender_usershape(GVJ_t * job, char *name, pointf * AF, int n, boolean filled, char *imagescale); /* layout */ diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index a219af027..30c6bca1a 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -38,6 +38,7 @@ extern int emit_once(char *str); extern shape_desc *find_user_shape(char *name); +extern boolean mapbool(char *s); /* storage for temporary hacks until client API is FP */ static pointf *AF; @@ -929,12 +930,21 @@ void gvrender_comment(GVJ_t * job, char *str) #endif } +static imagescale_t get_imagescale(char *s) +{ + if (*s == '\0') return IMAGESCALE_YES; + if (!strcasecmp(s, "width")) return IMAGESCALE_WIDTH; + if (!strcasecmp(s, "height")) return IMAGESCALE_HEIGHT; + if (!strcasecmp(s, "both")) return IMAGESCALE_BOTH; + if (mapbool(s)) return IMAGESCALE_YES; + return IMAGESCALE_NO; +} + /* gvrender_usershape: - * If expand is true, if necessary expand user image to fill polygon a, - * maintaining aspect ratio. + * Scale image to fill polygon bounding box according to "imagescale" */ void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n, - boolean filled, boolean expand) + boolean filled, char *imagescale) { gvrender_engine_t *gvre = job->render.engine; usershape_t *us; @@ -965,10 +975,13 @@ void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n, ph = b.UR.y - b.LL.y; ih = (double)isz.y; iw = (double)isz.x; - if (expand) { - scalex = pw / iw; - scaley = ph / ih; - /* keep aspect ratio fixed by just using the smaller scale */ + + scalex = pw / iw; + scaley = ph / ih; + + switch (get_imagescale(imagescale)) { + case IMAGESCALE_YES: + /* keep aspect ratio fixed by just using the smaller scale */ if (scalex < scaley) { iw *= scalex; ih *= scalex; @@ -976,6 +989,20 @@ void gvrender_usershape(GVJ_t * job, char *name, pointf * a, int n, iw *= scaley; ih *= scaley; } + break; + case IMAGESCALE_WIDTH: + iw *= scalex; + break; + case IMAGESCALE_HEIGHT: + ih *= scaley; + break; + case IMAGESCALE_BOTH: + iw *= scalex; + ih *= scaley; + break; + case IMAGESCALE_NO: + default: + break; } /* if image is smaller than target area then center it */