45extern bool mapbool(
const char *);
48#define BEZIERSUBDIVISION 10
59 alpha = (255 -
color->u.rgba[3]) * gdAlphaMax / 255;
61 if(
alpha == gdAlphaMax)
62 color->u.index = gdImageGetTransparent(im);
64 color->u.index = gdImageColorResolveAlpha(im,
74#define GD_XYMAX INT32_MAX
78 char *bgcolor_str =
NULL, *truecolor_str =
NULL;
79 bool truecolor_p =
false;
82 truecolor_str =
agget(job->
gvc->
g,
"truecolor");
83 bgcolor_str =
agget(job->
gvc->
g,
"bgcolor");
85 if (truecolor_str && truecolor_str[0])
86 truecolor_p =
mapbool(truecolor_str);
88 if (bgcolor_str && strcmp(bgcolor_str,
"transparent") == 0) {
98 fprintf(stderr,
"%s: using existing GD image\n", job->
common->
cmdname);
108 "%s: graph is too large for gd-renderer bitmaps. Scaling by %g to fit\n",
111 assert(job->
width <= INT_MAX);
112 assert(job->
height <= INT_MAX);
116 "%s: allocating a %0.fK TrueColor GD image (%d x %d pixels)\n",
120 im = gdImageCreateTrueColor((
int)job->
width, (
int)job->
height);
124 "%s: allocating a %.0fK PaletteColor GD image (%d x %d pixels)\n",
128 im = gdImageCreate((
int)job->
width, (
int)job->
height);
134 job->
common->
errorfn(
"gdImageCreate returned NULL. Malloc problem?\n");
141 gdRedMax - 1, gdGreenMax,
142 gdBlueMax, gdAlphaTransparent);
147 gdImageAlphaBlending(im,
false);
148 gdImageFill(im, im->sx / 2, im->sy / 2,
transparent);
151 gdImageAlphaBlending(im,
true);
162 gd_context.
job = job;
169 fprintf(stderr,
"gdgen_end_graph (to memory)\n");
179 gdImageTrueColorToPalette(im, 0, 256);
180 gdImageGifCtx(im, &gd_context.
ctx);
195#define JPEG_QUALITY -1
196 gdImageJpegCtx(im, &gd_context.
ctx, JPEG_QUALITY);
202 gdImagePngCtx(im, &gd_context.
ctx);
210 int black = gdImageColorResolveAlpha(im, 0, 0, 0, gdAlphaOpaque);
211 gdImageWBMPCtx(im,
black, &gd_context.
ctx);
222#define GD2_CHUNKSIZE 128
223#define GD2_COMPRESSED 2
224 gdImageGd2(im, job->
output_file, GD2_CHUNKSIZE, GD2_COMPRESSED);
235 fprintf(stderr,
"gdgen_end_graph (to file)\n");
242#define FONTSIZE_MUCH_TOO_SMALL 0.15
244#define FONTSIZE_TOO_SMALL 1.5
246void gdgen_text(gdImagePtr im,
pointf spf,
pointf epf,
int fontcolor,
double fontsize,
int fontdpi,
double fontangle,
char *fontname,
char *
str)
248 gdFTStringExtra strex;
254 strex.flags = gdFTEX_RESOLUTION;
255 strex.hdpi = strex.vdpi = fontdpi;
257 if (strchr(fontname,
'/'))
258 strex.flags |= gdFTEX_FONTPATHNAME;
260 strex.flags |= gdFTEX_FONTCONFIG;
266 gdImageLine(im, sp.
x, sp.
y, ep.
x, ep.
y, fontcolor);
268#ifdef HAVE_GD_FREETYPE
271#ifdef HAVE_GD_FONTCONFIG
272 char* fontlist = fontname;
274 extern char *gd_alternate_fontlist(
const char *
font);
275 char* fontlist = gd_alternate_fontlist(fontname);
277 err = gdImageStringFTEx(im, brect, fontcolor,
278 fontlist, fontsize, fontangle, sp.
x, sp.
y,
str, &strex);
279#ifndef HAVE_GD_FONTCONFIG
287 if (fontsize <= 8.5) {
288 gdImageString(im, gdFontTiny, sp.
x, sp.
y - 9, (
unsigned char*)
str, fontcolor);
289 }
else if (fontsize <= 9.5) {
290 gdImageString(im, gdFontSmall, sp.
x, sp.
y - 12, (
unsigned char*)
str, fontcolor);
291 }
else if (fontsize <= 10.5) {
292 gdImageString(im, gdFontMediumBold, sp.
x, sp.
y - 13, (
unsigned char*)
str, fontcolor);
293 }
else if (fontsize <= 11.5) {
294 gdImageString(im, gdFontLarge, sp.
x, sp.
y - 14, (
unsigned char*)
str, fontcolor);
296 gdImageString(im, gdFontGiant, sp.
x, sp.
y - 15, (
unsigned char*)
str, fontcolor);
298#ifdef HAVE_GD_FREETYPE
246void gdgen_text(gdImagePtr im,
pointf spf,
pointf epf,
int fontcolor,
double fontsize,
int fontdpi,
double fontangle,
char *fontname,
char *
str) {
…}
310#ifdef HAVE_GD_FONTCONFIG
317 switch (span->
just) {
326 spf.
x = -spanwidth / 2;
329 epf.
x = spf.
x + spanwidth;
332 spf.
y = -spf.
x + p.
y;
342#ifdef HAVE_GD_FONTCONFIG
362 int i, pen, width, dashstyle[20];
365 for (i = 0; i < 10; i++)
368 dashstyle[i] = gdTransparent;
369 gdImageSetStyle(im, dashstyle, 20);
372 for (i = 0; i < 2; i++)
375 dashstyle[i] = gdTransparent;
376 gdImageSetStyle(im, dashstyle, 12);
385 gdImageSetThickness(im, width);
389 *brush = gdImageCreateTrueColor(width,width);
392 *brush = gdImageCreate(width, width);
393 gdImagePaletteCopy(*brush, im);
395 gdImageFilledRectangle(*brush, 0, 0, width - 1, width - 1,
397 gdImageSetBrush(im, *brush);
399 pen = gdStyledBrushed;
412 bool pen_ok, fill_ok;
413 gdImagePtr brush =
NULL;
420 pen_ok = pen != gdImageGetTransparent(im);
421 fill_ok = filled && obj->
fillcolor.
u.
index != gdImageGetTransparent(im);
423 if (pen_ok || fill_ok) {
427 for (
size_t i = 0; i + 3 < n; i += 3) {
429 for (
size_t j = 1; j <= 3; j++)
437 gdImageLine(im,
F[1].x,
F[1].y,
F[2].x,
F[2].y, pen);
445 gdImageDestroy(brush);
454 gdImagePtr brush =
NULL;
456 bool pen_ok, fill_ok;
462 pen_ok = pen != gdImageGetTransparent(im);
463 fill_ok = filled && obj->
fillcolor.
u.
index != gdImageGetTransparent(im);
465 if (pen_ok || fill_ok) {
470 for (
size_t i = 0; i < n; i++) {
474 assert(n <= INT_MAX);
479 gdImagePolygon(im,
points, (
int)n, pen);
482 gdImageDestroy(brush);
491 bool pen_ok, fill_ok;
492 gdImagePtr brush =
NULL;
498 pen_ok = pen != gdImageGetTransparent(im);
499 fill_ok = filled && obj->
fillcolor.
u.
index != gdImageGetTransparent(im);
501 dx = 2 * (
A[1].x -
A[0].x);
502 dy = 2 * (
A[1].y -
A[0].y);
512 gdImageDestroy(brush);
520 gdImagePtr brush =
NULL;
526 pen_ok = pen != gdImageGetTransparent(im);
530 for (
size_t i = 1; i < n; i++) {
538 gdImageDestroy(brush);
582#if defined(HAVE_GD_GIF) || defined(HAVE_GD_JPEG)
591#if defined(HAVE_GD_GIF) || defined(HAVE_GD_PNG)
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
char * gd_psfontResolve(PostscriptAlias *pa)
int gvdevice_gd_putBuf(gdIOCtx *context, const void *buffer, int len)
void gvdevice_gd_putC(gdIOCtx *context, int C)
static pointf scale(double c, pointf p)
char * agget(void *obj, char *name)
#define GVDEVICE_NO_WRITER
#define GVDEVICE_DOES_TRUECOLOR
#define GVDEVICE_BINARY_FORMAT
#define GVRENDER_Y_GOES_DOWN
static void color(Agraph_t *g)
static const char black[]
pointf Bezier(pointf *V, double t, pointf *Left, pointf *Right)
static void gdgen_end_page(GVJ_t *job)
static void gdgen_polyline(GVJ_t *job, pointf *A, size_t n)
bool mapbool(const char *)
static int gdgen_set_penstyle(GVJ_t *job, gdImagePtr im, gdImagePtr *brush)
static void gdgen_ellipse(GVJ_t *job, pointf *A, int filled)
static void gdgen_bezier(GVJ_t *job, pointf *A, size_t n, int filled)
gvplugin_installed_t gvrender_gd_types[]
static void gdgen_resolve_color(GVJ_t *job, gvcolor_t *color)
static void gdgen_textspan(GVJ_t *job, pointf p, textspan_t *span)
static gvdevice_features_t device_features_gd_tc_no_writer
gvplugin_installed_t gvdevice_gd_types2[]
static void gdgen_begin_page(GVJ_t *job)
static size_t points_allocated
static gvrender_features_t render_features_gd
#define FONTSIZE_MUCH_TOO_SMALL
static void gdgen_polygon(GVJ_t *job, pointf *A, size_t n, int filled)
static gvrender_engine_t gdgen_engine
#define BEZIERSUBDIVISION
void gdgen_text(gdImagePtr im, pointf spf, pointf epf, int fontcolor, double fontsize, int fontdpi, double fontangle, char *fontname, char *str)
#define FONTSIZE_TOO_SMALL
textitem scanner parser str
void(* errorfn)(const char *fmt,...)
gvplugin_active_render_t render
gvrender_features_t * features
PostscriptAlias * postscript_alias
double yoffset_centerline