diff --git a/src/rrd_graph.c b/src/rrd_graph.c
index 6f1a1ac15ea5295d895a83871431119c43ab81e4..8aa71560b8c60ef554c00c50cc28d0bad2ca5ff8 100644 (file)
--- a/src/rrd_graph.c
+++ b/src/rrd_graph.c
/****************************************************************************
- * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.2 Copyright by Tobi Oetiker, 1997-2008
****************************************************************************
* rrd__graph.c produce graphs from data in rrdfiles
****************************************************************************/
#endif
#include "rrd_graph.h"
+#include "rrd_client.h"
/* some constant definitions */
#endif
text_prop_t text_prop[] = {
- {8.0, RRD_DEFAULT_FONT}
+ {8.0, RRD_DEFAULT_FONT,NULL}
, /* default */
- {9.0, RRD_DEFAULT_FONT}
+ {9.0, RRD_DEFAULT_FONT,NULL}
, /* title */
- {7.0, RRD_DEFAULT_FONT}
+ {7.0, RRD_DEFAULT_FONT,NULL}
, /* axis */
- {8.0, RRD_DEFAULT_FONT}
+ {8.0, RRD_DEFAULT_FONT,NULL}
, /* unit */
- {8.0, RRD_DEFAULT_FONT} /* legend */
+ {8.0, RRD_DEFAULT_FONT,NULL} /* legend */
+ ,
+ {5.5, RRD_DEFAULT_FONT,NULL} /* watermark */
};
xlab_t xlab[] = {
conv_if(AXIS, TEXT_PROP_AXIS);
conv_if(UNIT, TEXT_PROP_UNIT);
conv_if(LEGEND, TEXT_PROP_LEGEND);
+ conv_if(WATERMARK, TEXT_PROP_WATERMARK);
return -1;
}
if (im == NULL)
return 0;
+
+ if (im->daemon_addr != NULL)
+ free(im->daemon_addr);
+
for (i = 0; i < (unsigned) im->gdes_c; i++) {
if (im->gdes[i].data_first) {
/* careful here, because a single pointer can occur several times */
if (im->rendered_image) {
free(im->rendered_image);
}
+
+ if (im->layout) {
+ g_object_unref (im->layout);
+ }
+
if (im->surface)
cairo_surface_destroy(im->surface);
+
if (status)
fprintf(stderr, "OOPS: Cairo has issues it can't even die: %s\n",
cairo_status_to_string(status));
-
+
return 0;
}
if (!skip) {
unsigned long ft_step = im->gdes[i].step; /* ft_step will record what we got from fetch */
+ /* Flush the file if
+ * - a connection to the daemon has been established
+ * - this is the first occurrence of that RRD file
+ */
+ if (rrdc_is_connected(im->daemon_addr))
+ {
+ int status;
+
+ status = 0;
+ for (ii = 0; ii < i; ii++)
+ {
+ if (strcmp (im->gdes[i].rrd, im->gdes[ii].rrd) == 0)
+ {
+ status = 1;
+ break;
+ }
+ }
+
+ if (status == 0)
+ {
+ status = rrdc_flush (im->gdes[i].rrd);
+ if (status != 0)
+ {
+ rrd_set_error ("rrdc_flush (%s) failed with status %i.",
+ im->gdes[i].rrd, status);
+ return (-1);
+ }
+ }
+ } /* if (rrdc_is_connected()) */
+
if ((rrd_fetch_fn(im->gdes[i].rrd,
im->gdes[i].cf,
&im->gdes[i].start,
return -1;
}
-/* find the largest common denominator for all the numbers
+/* find the greatest common divisor for all the numbers
in the 0 terminated num array */
long lcd(
long *num)
int border = im->text_prop[TEXT_PROP_LEGEND].size * 2.0;
int fill = 0, fill_last;
int leg_c = 0;
- int leg_x = border;
+ double leg_x = border;
int leg_y = im->yimg;
int leg_y_prev = im->yimg;
int leg_cc;
- int glue = 0;
+ double glue = 0;
int i, ii, mark = 0;
char prt_fctn; /*special printfunctions */
char default_txtalign = TXA_JUSTIFIED; /*default line orientation */
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, im->gdes[i].legend);
leg_c++;
} else {
if (prt_fctn != '\0') {
leg_x = border;
if (leg_c >= 2 && prt_fctn == 'j') {
- glue = (im->ximg - fill - 2 * border) / (leg_c - 1);
+ glue = (double)(im->ximg - fill - 2 * border) / (double)(leg_c - 1);
} else {
glue = 0;
}
if (prt_fctn == 'c')
- leg_x = (im->ximg - fill) / 2.0;
+ leg_x = (double)(im->ximg - fill) / 2.0;
if (prt_fctn == 'r')
leg_x = im->ximg - fill - border;
for (ii = mark; ii <= i; ii++) {
im->gdes[ii].leg_x = leg_x;
im->gdes[ii].leg_y = leg_y;
leg_x +=
- gfx_get_text_width(im, leg_x,
+ (double)gfx_get_text_width(im, leg_x,
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, im->gdes[ii].legend)
- + legspace[ii]
+ +(double)legspace[ii]
+ glue;
}
leg_y_prev = leg_y;
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_RIGHT, GFX_V_CENTER, graph_label);
gfx_line(im, X0 - 2, Y0, X0, Y0,
MGRIDWIDTH, im->graph_col[GRC_MGRID]);
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_RIGHT, GFX_V_CENTER, graph_label);
/* minor grid */
if (mid < 4 && exfrac == 1) {
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_CENTER, GFX_V_TOP, graph_label);
}
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_AXIS].
- font,
- im->
- text_prop[TEXT_PROP_AXIS].
- size, im->tabwidth, 0.0,
+ font_desc,
+ im->tabwidth, 0.0,
GFX_H_CENTER, GFX_V_CENTER, nodata);
}
}
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_UNIT].
- font,
- im->
- text_prop[TEXT_PROP_UNIT].
- size, im->tabwidth,
+ font_desc,
+ im->tabwidth,
RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend);
/* graph title */
gfx_text(im,
im->graph_col[GRC_FONT],
im->
text_prop[TEXT_PROP_TITLE].
- font,
- im->
- text_prop[TEXT_PROP_TITLE].
- size, im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_TOP, im->title);
+ font_desc,
+ im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_TOP, im->title);
/* rrdtool 'logo' */
water_color = im->graph_col[GRC_FONT];
water_color.alpha = 0.3;
gfx_text(im, im->ximg - 4, 5,
water_color,
im->
- text_prop[TEXT_PROP_AXIS].
- font, 5.5, im->tabwidth,
+ text_prop[TEXT_PROP_WATERMARK].
+ font_desc, im->tabwidth,
-90, GFX_H_LEFT, GFX_V_TOP, "RRDTOOL / TOBI OETIKER");
/* graph watermark */
if (im->watermark[0] != '\0') {
im->ximg / 2, im->yimg - 6,
water_color,
im->
- text_prop[TEXT_PROP_AXIS].
- font, 5.5, im->tabwidth, 0,
+ text_prop[TEXT_PROP_WATERMARK].
+ font_desc, im->tabwidth, 0,
GFX_H_CENTER, GFX_V_BOTTOM, im->watermark);
}
im->graph_col[GRC_FONT],
im->
text_prop
- [TEXT_PROP_LEGEND].font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].size,
+ [TEXT_PROP_LEGEND].font_desc,
im->tabwidth, 0.0,
GFX_H_LEFT, GFX_V_BOTTOM, im->gdes[i].legend);
/* The legend for GRAPH items starts with "M " to have
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size, im->tabwidth, "o") * 1.2;
+ font_desc,
+ im->tabwidth, "o") * 1.2;
boxV = boxH;
/* shift the box up a bit */
Y0 -= boxV * 0.4;
im->
text_prop
[TEXT_PROP_AXIS].
- font,
- im->
- text_prop
- [TEXT_PROP_AXIS].
- size, im->tabwidth, "0") * im->unitslength;
+ font_desc,
+ im->tabwidth, "0") * im->unitslength;
}
}
double areazero = 0.0;
graph_desc_t *lastgdes = NULL;
rrd_infoval_t info;
- PangoFontMap *font_map = pango_cairo_font_map_get_default();
+
+// PangoFontMap *font_map = pango_cairo_font_map_get_default();
/* if we want and can be lazy ... quit now */
if (lazy) {
im->cr = cairo_create(im->surface);
cairo_set_antialias(im->cr, im->graph_antialias);
cairo_scale(im->cr, im->zoom, im->zoom);
- pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
+// pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
gfx_new_area(im, 0, 0, 0, im->yimg,
im->ximg, im->yimg, im->graph_col[GRC_BACK]);
gfx_add_point(im, im->ximg, 0);
{
image_desc_t im;
rrd_info_t *grinfo;
-
rrd_graph_init(&im);
/* a dummy surface so that we can measure text sizes for placements */
- im.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
- im.cr = cairo_create(im.surface);
+
rrd_graph_options(argc, argv, &im);
if (rrd_test_error()) {
rrd_info_free(im.grinfo);
if (im.imginfo) {
rrd_infoval_t info;
+ char *path;
char *filename;
- filename = im.graphfile + strlen(im.graphfile);
- while (filename > im.graphfile) {
- if (*(filename - 1) == '/' || *(filename - 1) == '\\')
- break;
- filename--;
- }
+ path = strdup(im.graphfile);
+ filename = basename(path);
info.u_str =
sprintf_alloc(im.imginfo,
filename,
im.ximg), (long) (im.zoom * im.yimg));
grinfo_push(&im, sprintf_alloc("image_info"), RD_I_STR, info);
free(info.u_str);
+ free(path);
}
if (im.rendered_image) {
rrd_infoval_t img;
return grinfo;
}
+static void
+rrd_set_font_desc (
+ image_desc_t *im,int prop,char *font, double size ){
+ if (font){
+ strncpy(im->text_prop[prop].font, font, sizeof(text_prop[prop].font) - 1);
+ im->text_prop[prop].font[sizeof(text_prop[prop].font) - 1] = '\0';
+ im->text_prop[prop].font_desc = pango_font_description_from_string( font );
+ };
+ if (size > 0){
+ im->text_prop[prop].size = size;
+ };
+ if (im->text_prop[prop].font_desc && im->text_prop[prop].size ){
+ pango_font_description_set_size(im->text_prop[prop].font_desc, im->text_prop[prop].size * PANGO_SCALE);
+ };
+}
+
void rrd_graph_init(
image_desc_t
*im)
{
unsigned int i;
+ char *deffont = getenv("RRD_DEFAULT_FONT");
+ static PangoFontMap *fontmap = NULL;
+ PangoContext *context;
#ifdef HAVE_TZSET
tzset();
#endif
#endif
im->base = 1000;
- im->cr = NULL;
+ im->daemon_addr = NULL;
im->draw_x_grid = 1;
im->draw_y_grid = 1;
im->extra_flags = 0;
im->rendered_image = NULL;
im->slopemode = 0;
im->step = 0;
- im->surface = NULL;
im->symbol = ' ';
im->tabwidth = 40.0;
im->title[0] = '\0';
im->yorigin = 0;
im->ysize = 100;
im->zoom = 1;
+
+ im->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
+ im->cr = cairo_create(im->surface);
+
+ for (i = 0; i < DIM(text_prop); i++) {
+ im->text_prop[i].size = -1;
+ rrd_set_font_desc(im,i, deffont ? deffont : text_prop[i].font,text_prop[i].size);
+ }
+
+ if (fontmap == NULL){
+ fontmap = pango_cairo_font_map_get_default();
+ }
+
+ context = pango_cairo_font_map_create_context((PangoCairoFontMap*)fontmap);
+
+ pango_cairo_context_set_resolution(context, 100);
+
+ pango_cairo_update_context(im->cr,context);
+
+ im->layout = pango_layout_new(context);
+
+// im->layout = pango_cairo_create_layout(im->cr);
+
+
cairo_font_options_set_hint_style
(im->font_options, CAIRO_HINT_STYLE_FULL);
cairo_font_options_set_hint_metrics
(im->font_options, CAIRO_HINT_METRICS_ON);
cairo_font_options_set_antialias(im->font_options, CAIRO_ANTIALIAS_GRAY);
+
+
+
for (i = 0; i < DIM(graph_col); i++)
im->graph_col[i] = graph_col[i];
- {
- char *deffont;
-
- deffont = getenv("RRD_DEFAULT_FONT");
- if (deffont != NULL) {
- for (i = 0; i < DIM(text_prop); i++) {
- strncpy(text_prop[i].font, deffont,
- sizeof(text_prop[i].font) - 1);
- text_prop[i].font[sizeof(text_prop[i].font) - 1] = '\0';
- }
- }
- }
- for (i = 0; i < DIM(text_prop); i++) {
- im->text_prop[i].size = text_prop[i].size;
- strcpy(im->text_prop[i].font, text_prop[i].font);
- }
+
+
}
+
void rrd_graph_options(
int argc,
char *argv[],
{ "watermark", required_argument, 0, 'W'},
{ "alt-y-mrtg", no_argument, 0, 1000}, /* this has no effect it is just here to save old apps from crashing when they use it */
{ "pango-markup", no_argument, 0, 'P'},
+ { "daemon", required_argument, 0, 'd'},
{ 0, 0, 0, 0}
};
/* *INDENT-ON* */
int col_start, col_end;
opt = getopt_long(argc, argv,
- "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kP",
+ "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:kPd:",
long_options, &option_index);
if (opt == EOF)
break;
for (propidx = sindex;
propidx < TEXT_PROP_LAST; propidx++) {
if (size > 0) {
- im->text_prop[propidx].size = size;
+ rrd_set_font_desc(im,propidx,NULL,size);
}
- if ((int) strlen(optarg) > end) {
+ if ((int) strlen(optarg) > end+2) {
if (optarg[end] == ':') {
- strncpy(im->text_prop[propidx].font,
- optarg + end + 1, 255);
- im->text_prop[propidx].font[255] = '\0';
+ rrd_set_font_desc(im,propidx,optarg + end + 1,0);
} else {
rrd_set_error
("expected : after font size in '%s'",
strncpy(im->watermark, optarg, 100);
im->watermark[99] = '\0';
break;
+ case 'd':
+ {
+ if (im->daemon_addr != NULL)
+ {
+ rrd_set_error ("You cannot specify --daemon "
+ "more than once.");
+ return;
+ }
+
+ im->daemon_addr = strdup(optarg);
+ if (im->daemon_addr == NULL)
+ {
+ rrd_set_error("strdup failed");
+ return;
+ }
+
+ break;
+ }
case '?':
if (optopt != 0)
rrd_set_error("unknown option '%c'", optopt);
rrd_set_error("unknown option '%s'", argv[optind - 1]);
return;
}
+ } /* while (1) */
+
+ { /* try to connect to rrdcached */
+ int status = rrdc_connect(im->daemon_addr);
+ if (status != 0) return;
}
+
+ pango_cairo_context_set_font_options(pango_layout_get_context(im->layout), im->font_options);
+ pango_layout_context_changed(im->layout);
+
+
if (im->logarithmic && im->minval <= 0) {
rrd_set_error
graph_desc_t *src, *dst;
rrd_value_t *data;
long step, steps;
- unsigned long end;
dst = &im->gdes[gdi];
src = &im->gdes[dst->vidx];
data = src->data + src->ds;
- end =
- src->end_orig % (long) src->step ==
- 0 ? src->end_orig : (src->end_orig + (long) src->step -
- src->end_orig % (long) src->step);
- steps = (end - src->start) / src->step;
+ steps = (src->end - src->start) / src->step;
#if 0
printf
("DEBUG: start == %lu, end == %lu, %lu steps\n",
- src->start, src->end_orig, steps);
+ src->start, src->end, steps);
#endif
switch (dst->vf.op) {
case VDEF_PERCENT:{