*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,
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
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");
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 */
}
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 {
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 */
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;
#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;
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;
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 */