summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 37bc480)
raw | patch | inline | side by side (parent: 37bc480)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Sun, 31 Aug 2008 22:53:49 +0000 (22:53 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Sun, 31 Aug 2008 22:53:49 +0000 (22:53 +0000) |
for the second one about 4-5 times faster ...
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1475 a5681a0c-68f1-0310-ab6d-d61299d08faa
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1475 a5681a0c-68f1-0310-ab6d-d61299d08faa
src/rrd_gfx.c | patch | blob | history | |
src/rrd_graph.c | patch | blob | history | |
src/rrd_graph.h | patch | blob | history | |
src/rrd_graph_helper.c | patch | blob | history |
diff --git a/src/rrd_gfx.c b/src/rrd_gfx.c
index 6f041355a98d43feb6ef25d283e0db5f779663f2..be536c5183020778822e2d1ac885c748f817c314 100644 (file)
--- a/src/rrd_gfx.c
+++ b/src/rrd_gfx.c
image_desc_t *im,
double x,
gfx_color_t color,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
const char *text)
{
- static PangoLayout *layout = NULL;
- static PangoContext *pango_context = NULL;
- static PangoFontMap *pango_fontmap = NULL;
- static char* last_font = NULL;
- static double last_size = -1;
+ PangoLayout *layout = im->layout;
+ PangoFontDescription *pfd;
+ cairo_t *cr = im->cr;
+
static double last_tabwidth = -1;
- cairo_t *cr = im->cr;
+
/* for performance reasons we might
want todo that only once ... tabs will always
gchar *utf8_text;
- /* initialize pango only once ... */
- if (!pango_fontmap){
- pango_fontmap = pango_cairo_font_map_get_default ();
- }
- if (!pango_context){
- // fprintf(stderr,"c");
- pango_context = pango_cairo_font_map_create_context ((PangoCairoFontMap *) (pango_fontmap));
- pango_cairo_context_set_resolution(pango_context, 100);
- }
- if (!layout){
- // fprintf(stderr,"l");
- layout = pango_layout_new (pango_context);
- }
-
- pango_cairo_context_set_font_options(pango_context, im->font_options);
-
- pango_cairo_update_context (cr, pango_context);
-
-
if (last_tabwidth < 0 || last_tabwidth != tabwidth){
PangoTabArray *tab_array;
// fprintf(stderr,"t");
pango_layout_set_tabs(layout, tab_array);
pango_tab_array_free(tab_array);
}
-
- if (last_font == NULL || strcmp(font,last_font) != 0){
- PangoFontDescription *font_desc;
- // fprintf(stderr,"f:%s",font);
- if (last_font)
- free(last_font);
- last_font = strdup(font);
- font_desc = pango_font_description_from_string(font);
+ pfd = pango_layout_get_font_description(layout);
+ if (pfd && pango_font_description_equal (pfd,font_desc)){
pango_layout_set_font_description(layout, font_desc);
- pango_font_description_free(font_desc);
}
- if (last_size < 0 || last_size != size ){
- PangoFontDescription *font_desc;
- font_desc = pango_layout_get_font_description (layout);
- pango_font_description_set_size(font_desc, size * PANGO_SCALE);
- pango_layout_set_font_description(layout, font_desc);
- }
-
- cairo_new_path(cr);
- cairo_set_source_rgba(cr, color.red, color.green, color.blue,
+ cairo_new_path(cr);
+ cairo_set_source_rgba(cr, color.red, color.green, color.blue,
color.alpha);
/* layout = pango_cairo_create_layout(cr); */
double gfx_get_text_width(
image_desc_t *im,
double start,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
char *text)
{
PangoLayout *layout;
PangoRectangle log_rect;
gfx_color_t color = { 0, 0, 0, 0 };
- layout = gfx_prep_text(im, start, color, font, size, tabwidth, text);
+ layout = gfx_prep_text(im, start, color, font_desc, tabwidth, text);
pango_layout_get_pixel_extents(layout, NULL, &log_rect);
/* g_object_unref(layout); */
return log_rect.width;
double x,
double y,
gfx_color_t color,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
double angle,
enum gfx_h_align_en h_align,
cairo_translate(cr, x, y);
/* gfx_line(cr,-2,0,2,0,1,color);
gfx_line(cr,0,-2,0,2,1,color); */
- layout = gfx_prep_text(im, x, color, font, size, tabwidth, text);
+ layout = gfx_prep_text(im, x, color, font_desc, tabwidth, text);
pango_layout_get_pixel_extents(layout, NULL, &log_rect);
cairo_rotate(cr, -angle * G_PI / 180.0);
sx = log_rect.x;
diff --git a/src/rrd_graph.c b/src/rrd_graph.c
index 6f1a1ac15ea5295d895a83871431119c43ab81e4..36dbddffe9566564e74da1349abe348b7ddd81a9 100644 (file)
--- a/src/rrd_graph.c
+++ b/src/rrd_graph.c
#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->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;
}
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 {
im->
text_prop
[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, im->gdes[ii].legend)
+ legspace[ii]
+ glue;
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);
return grinfo;
}
+static void
+rrd_set_font_desc (
+ image_desc_t *im,int prop,char *font, double size ){
+ static text_prop_t tp_cache[] = { {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}, {-1,"",NULL}};
+
+ if (tp_cache[prop].font_desc == NULL){
+ tp_cache[prop].font_desc = pango_font_description_new();
+ im->text_prop[prop].font_desc = pango_font_description_copy (tp_cache[prop].font_desc);
+ }
+
+ if (font != NULL && strcmp(tp_cache[prop].font,font) != 0){
+ pango_font_description_free(tp_cache[prop].font_desc);
+ pango_font_description_free(im->text_prop[prop].font_desc);
+ tp_cache[prop].font_desc = pango_font_description_from_string( font );
+ im->text_prop[prop].font_desc = pango_font_description_copy( tp_cache[prop].font_desc );
+ strncpy(tp_cache[prop].font, font, sizeof(text_prop[prop].font) - 1);
+ tp_cache[prop].font[sizeof(text_prop[prop].font) - 1] = '\0';
+ strcpy(im->text_prop[prop].font,tp_cache[prop].font);
+ }
+ if (size != 0 && size != (tp_cache[prop].size)){
+ pango_font_description_set_size(tp_cache[prop].font_desc, size * PANGO_SCALE);
+ pango_font_description_set_size(im->text_prop[prop].font_desc, size * PANGO_SCALE);
+ im->text_prop[prop].size = size;
+ tp_cache[prop].size = size;
+ }
+}
+
void rrd_graph_init(
image_desc_t
*im)
{
unsigned int i;
+ char *deffont = getenv("RRD_DEFAULT_FONT");
#ifdef HAVE_TZSET
tzset();
#endif
#endif
im->base = 1000;
- im->cr = 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++) {
+ rrd_set_font_desc(im,i, deffont ? deffont : text_prop[i].font,text_prop[i].size);
+ }
+
+ im->layout = pango_cairo_create_layout(im->cr);
+ pango_cairo_context_set_resolution(pango_layout_get_context(im->layout), 100);
+
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[],
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 (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'",
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
diff --git a/src/rrd_graph.h b/src/rrd_graph.h
index 2b1c05be921676622129bf4e400f919a8a1c2502..fefa982f3f5171cffbdade54f08d9333a93cfb18 100644 (file)
--- a/src/rrd_graph.h
+++ b/src/rrd_graph.h
TEXT_PROP_TITLE, /* properties for the title */
TEXT_PROP_AXIS, /* for the numbers next to the axis */
TEXT_PROP_UNIT, /* for the vertical unit description */
- TEXT_PROP_LEGEND, /* fot the legend below the graph */
+ TEXT_PROP_LEGEND, /* for the legend below the graph */
+ TEXT_PROP_WATERMARK, /* for the little text to the side of the graph */
TEXT_PROP_LAST
};
typedef struct text_prop_t {
double size;
char font[1024];
+ PangoFontDescription *font_desc;
} text_prop_t;
cairo_t *cr; /* drawin context */
cairo_font_options_t *font_options; /* cairo font options */
cairo_antialias_t graph_antialias; /* antialiasing for the graph */
-
+ PangoLayout *layout; /* the pango layout we use for writing fonts */
rrd_info_t *grinfo; /* root pointer to extra graph info */
rrd_info_t *grinfo_current; /* pointing to current entry */
} image_desc_t;
char *const);
void rrd_graph_init(
image_desc_t *);
+
void rrd_graph_options(
int,
char **,
double x,
double y,
gfx_color_t color,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
double angle,
enum gfx_h_align_en h_align,
double gfx_get_text_width(
image_desc_t *im,
double start,
- char *font,
- double size,
+ PangoFontDescription *font_desc,
double tabwidth,
char *text);
void grinfo_push(
image_desc_t *im,
char *key,
- rrd_info_type_t type,
- rrd_infoval_t value);
+ rrd_info_type_t type, rrd_infoval_t value);
diff --git a/src/rrd_graph_helper.c b/src/rrd_graph_helper.c
index d570e58a365db31b85662dc7ac4aef891e8db582..be85b9fea2834badbdc0e27f7f873ecd364f66a1 100644 (file)
--- a/src/rrd_graph_helper.c
+++ b/src/rrd_graph_helper.c
}
-/* Parsing of PART, VRULE, HRULE, LINE, AREA, STACK and TICK
+/* Parsing of VRULE, HRULE, LINE, AREA, STACK and TICK
** is done in one function.
**
-** Stacking PART, VRULE, HRULE or TICK is not allowed.
+** Stacking VRULE, HRULE or TICK is not allowed.
**
** If a number (which is valid to enter) is more than a
** certain amount of characters, it is caught as an error.
float one_space = gfx_get_text_width(im, 0,
im->
text_prop[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop[TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, " ") / 4.0;
float target_space = gfx_get_text_width(im, 0,
im->
text_prop
- [TEXT_PROP_LEGEND].font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].size,
+ [TEXT_PROP_LEGEND].font_desc,
im->tabwidth, "oo");
spacecnt = target_space / one_space;
}
(*eaten)++; /* after colon */
- /* PART, HRULE, VRULE and TICK cannot be stacked. */
+ /* HRULE, VRULE and TICK cannot be stacked. */
if ((gdp->gf != GF_HRULE)
&& (gdp->gf != GF_VRULE)
&& (gdp->gf != GF_TICK)) {