1 /****************************************************************************
2 * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
3 ****************************************************************************
4 * rrd_gfx.c graphics wrapper for rrdtool
5 **************************************************************************/
9 /* stupid MSVC doesnt support variadic macros = no debug for now! */
14 # define RRDPRINTF(...) fprintf(stderr, __VA_ARGS__);
16 # define RRDPRINTF(...)
21 #include "rrd_graph.h"
24 /* create a new line */
34 gfx_dashed_line(im, X0, Y0, X1, Y1, width, color, 0, 0);
58 cairo_set_line_width(cr, width);
59 gfx_line_fit(im, &x, &y);
60 gfx_line_fit(im, &X0, &Y0);
61 cairo_move_to(cr, X0, Y0);
62 gfx_line_fit(im, &X1, &Y1);
63 cairo_line_to(cr, X1, Y1);
64 if (dash_on > 0 || dash_off > 0)
65 cairo_set_dash(cr, dashes, 2, x);
66 cairo_set_source_rgba(cr, color.red, color.green, color.blue,
72 /* create a new area */
86 gfx_area_fit(im, &X0, &Y0);
87 cairo_move_to(cr, X0, Y0);
88 gfx_area_fit(im, &X1, &Y1);
89 cairo_line_to(cr, X1, Y1);
90 gfx_area_fit(im, &X2, &Y2);
91 cairo_line_to(cr, X2, Y2);
92 cairo_set_source_rgba(cr, color.red, color.green, color.blue,
96 /* add a point to a line or to an area */
102 cairo_t *cr = im->cr;
104 gfx_area_fit(im, &x, &y);
105 cairo_line_to(cr, x, y);
111 cairo_t *cr = im->cr;
113 cairo_close_path(cr);
117 /* create a text node */
118 static PangoLayout *gfx_prep_text(
127 static PangoLayout *layout = NULL;
128 static PangoContext *pango_context = NULL;
129 static PangoFontMap *pango_fontmap = NULL;
130 static char* last_font = NULL;
131 static double last_size = -1;
132 static double last_tabwidth = -1;
134 cairo_t *cr = im->cr;
136 /* for performance reasons we might
137 want todo that only once ... tabs will always
140 long tab_count = strlen(text);
141 long tab_shift = fmod(x, tabwidth);
142 int border = im->text_prop[TEXT_PROP_LEGEND].size * 2.0;
146 /* initialize pango only once ... */
148 pango_fontmap = pango_cairo_font_map_get_default ();
151 // fprintf(stderr,"c");
152 pango_context = pango_cairo_font_map_create_context ((PangoCairoFontMap *) (pango_fontmap));
153 pango_cairo_context_set_resolution(pango_context, 100);
156 // fprintf(stderr,"l");
157 layout = pango_layout_new (pango_context);
160 pango_cairo_context_set_font_options(pango_context, im->font_options);
162 pango_cairo_update_context (cr, pango_context);
165 if (last_tabwidth < 0 || last_tabwidth != tabwidth){
166 PangoTabArray *tab_array;
167 // fprintf(stderr,"t");
168 last_tabwidth = tabwidth;
169 tab_array = pango_tab_array_new(tab_count, (gboolean) (1));
170 for (i = 1; i <= tab_count; i++) {
171 pango_tab_array_set_tab(tab_array,
173 tabwidth * i - tab_shift + border);
175 pango_layout_set_tabs(layout, tab_array);
176 pango_tab_array_free(tab_array);
179 if (last_font == NULL || strcmp(font,last_font) != 0){
180 PangoFontDescription *font_desc;
181 // fprintf(stderr,"f:%s",font);
184 last_font = strdup(font);
185 font_desc = pango_font_description_from_string(font);
186 pango_layout_set_font_description(layout, font_desc);
187 pango_font_description_free(font_desc);
190 if (last_size < 0 || last_size != size ){
191 PangoFontDescription *font_desc;
192 font_desc = pango_layout_get_font_description (layout);
193 pango_font_description_set_size(font_desc, size * PANGO_SCALE);
194 pango_layout_set_font_description(layout, font_desc);
198 cairo_set_source_rgba(cr, color.red, color.green, color.blue,
200 /* layout = pango_cairo_create_layout(cr); */
202 // pango_cairo_context_set_font_options(pango_context, im->font_options);
203 // pango_cairo_context_set_resolution(pango_context, 100);
205 /* pango_cairo_update_context(cr, pango_context); */
208 /* pango expects the string to be utf-8 encoded */
209 utf8_text = g_locale_to_utf8((const gchar *) text, -1, NULL, NULL, NULL);
211 /* In case of an error, i.e. utf8_text == NULL (locale settings messed
212 * up?), we fall back to a possible "invalid UTF-8 string" warning instead
213 * of provoking a failed assertion in libpango. */
215 pango_layout_set_markup(layout, utf8_text ? utf8_text : text, -1);
217 pango_layout_set_text(layout, utf8_text ? utf8_text : text, -1);
224 double gfx_get_text_width(
233 PangoRectangle log_rect;
234 gfx_color_t color = { 0, 0, 0, 0 };
235 layout = gfx_prep_text(im, start, color, font, size, tabwidth, text);
236 pango_layout_get_pixel_extents(layout, NULL, &log_rect);
237 /* g_object_unref(layout); */
238 return log_rect.width;
250 enum gfx_h_align_en h_align,
251 enum gfx_v_align_en v_align,
255 PangoRectangle log_rect;
256 cairo_t *cr = im->cr;
261 cairo_translate(cr, x, y);
262 /* gfx_line(cr,-2,0,2,0,1,color);
263 gfx_line(cr,0,-2,0,2,1,color); */
264 layout = gfx_prep_text(im, x, color, font, size, tabwidth, text);
265 pango_layout_get_pixel_extents(layout, NULL, &log_rect);
266 cairo_rotate(cr, -angle * G_PI / 180.0);
270 sx -= log_rect.width;
273 sx -= log_rect.width / 2;
285 sy -= log_rect.height / 2;
288 sy -= log_rect.height;
293 pango_cairo_update_layout(cr, layout);
294 cairo_move_to(cr, sx, sy);
295 pango_cairo_show_layout(cr, layout);
296 /* g_object_unref(layout); */
302 struct gfx_color_t gfx_hex_to_col(
303 long unsigned int color)
305 struct gfx_color_t gfx_color;
307 gfx_color.red = 1.0 / 255.0 * ((color & 0xff000000) >> (3 * 8));
308 gfx_color.green = 1.0 / 255.0 * ((color & 0x00ff0000) >> (2 * 8));
309 gfx_color.blue = 1.0 / 255.0 * ((color & 0x0000ff00) >> (1 * 8));
310 gfx_color.alpha = 1.0 / 255.0 * (color & 0x000000ff);
321 cairo_t *cr = im->cr;
327 cairo_user_to_device(cr, x, y);
328 line_width = cairo_get_line_width(cr);
329 line_height = line_width;
330 cairo_user_to_device_distance(cr, &line_width, &line_height);
331 line_width = line_width / 2.0 - (long) (line_width / 2.0);
332 line_height = line_height / 2.0 - (long) (line_height / 2.0);
333 *x = (double) ((long) (*x + 0.5)) - line_width;
334 *y = (double) ((long) (*y + 0.5)) + line_height;
335 cairo_device_to_user(cr, x, y);
345 cairo_t *cr = im->cr;
349 cairo_user_to_device(cr, x, y);
350 *x = (double) ((long) (*x + 0.5));
351 *y = (double) ((long) (*y + 0.5));
352 cairo_device_to_user(cr, x, y);