--font-render-mode is back, and there is also
authoroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Mon, 11 Jun 2007 15:11:10 +0000 (15:11 +0000)
committeroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Mon, 11 Jun 2007 15:11:10 +0000 (15:11 +0000)
--graph-render-mode now. It allows to enable
mono graphs that look strikingly like rrdtool 1.0.x
--tobi

git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1107 a5681a0c-68f1-0310-ab6d-d61299d08faa

NEWS
configure.ac
doc/rrdgraph.pod
src/Makefile.am
src/rrd_gfx.c
src/rrd_gfx.h [deleted file]
src/rrd_graph.c
src/rrd_graph.h
src/rrd_graph_helper.c

diff --git a/NEWS b/NEWS
index 32ee7d4..28b801c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,10 @@ Graphing
 --------
 * libart has been replaced by cairo/pango
 * pango markup is supported
 --------
 * libart has been replaced by cairo/pango
 * pango markup is supported
-* full gridfitting
+* full gridfitting 
+* --graph-render-mode=mono for non antialiased graphing
+* --font-render-mode=mono for non antialiased fonts
+
 
 RRDTOOL NEWS
 ============
 
 RRDTOOL NEWS
 ============
index b27a3e7..e88f287 100644 (file)
@@ -605,9 +605,9 @@ dnl EX_CHECK_ALL(z,          zlibVersion,               zlib.h,
 dnl EX_CHECK_ALL(png,        png_access_version_number, png.h,                  libpng,      1.2.10,  http://prdownloads.sourceforge.net/libpng/, "")
 dnl EX_CHECK_ALL(freetype,   FT_Init_FreeType,          ft2build.h,                    freetype2,   2.1.10,  http://prdownloads.sourceforge.net/freetype/, /usr/include/freetype2)
 dnl EX_CHECK_ALL(fontconfig, FcInit,                    fontconfig.h,              fontconfig,  2.3.1,  http://fontconfig.org/release/, /usr/include)
 dnl EX_CHECK_ALL(png,        png_access_version_number, png.h,                  libpng,      1.2.10,  http://prdownloads.sourceforge.net/libpng/, "")
 dnl EX_CHECK_ALL(freetype,   FT_Init_FreeType,          ft2build.h,                    freetype2,   2.1.10,  http://prdownloads.sourceforge.net/freetype/, /usr/include/freetype2)
 dnl EX_CHECK_ALL(fontconfig, FcInit,                    fontconfig.h,              fontconfig,  2.3.1,  http://fontconfig.org/release/, /usr/include)
-EX_CHECK_ALL(cairo,      cairo_version,             cairo.h,                cairo-png,   1.4.6,  http://cairographics.org/releases/, "")
+EX_CHECK_ALL(cairo,      cairo_font_options_create,     cairo.h,                cairo-png,   1.4.6,  http://cairographics.org/releases/, "")
 dnl EX_CHECK_ALL(glib-2.0,   glib_check_version,        glib.h,                 glib-2.0,    2.12.12, ftp://ftp.gtk.org/pub/glib/2.12/, "")
 dnl EX_CHECK_ALL(glib-2.0,   glib_check_version,        glib.h,                 glib-2.0,    2.12.12, ftp://ftp.gtk.org/pub/glib/2.12/, "")
-EX_CHECK_ALL(pango-1.0,  pango_version_check,       pango/pango.h,          pangocairo,  1.17,    http://ftp.gnome.org/pub/GNOME/sources/pango/1.17, "")
+EX_CHECK_ALL(pango-1.0,  pango_cairo_context_set_font_options,  pango/pango.h,  pangocairo,  1.17,    http://ftp.gnome.org/pub/GNOME/sources/pango/1.17, "")
 
 if test "$EX_CHECK_ALL_ERR" = "YES"; then
   AC_MSG_ERROR([Please fix the library issues listed above and try again.])
 
 if test "$EX_CHECK_ALL_ERR" = "YES"; then
   AC_MSG_ERROR([Please fix the library issues listed above and try again.])
index 812b247..8485675 100644 (file)
@@ -146,13 +146,10 @@ and thus the throughput may be higher than the WAN line speed.
 
 [B<-N>|B<--no-gridfit>]
 
 
 [B<-N>|B<--no-gridfit>]
 
-In order to avoid anti-aliasing effects gridlines are placed on
-integer pixel values. This is by default done by extending
-the scale so that gridlines happens to be spaced using an
-integer number of pixels and also start on an integer pixel value.
-This might extend the scale too much for some logarithmic scales
-and for linear scales where B<--alt-autoscale> is needed.
-Using B<--no-gridfit> disables modification of the scale.
+In order to avoid anti-aliasing blurring effects rrdtool snaps
+points to device resolution pixels, this results in a crisper
+aperance. If this is not to your liking, you can use this switch
+to turn this behaviour off.
 
 =item Grid
 
 
 =item Grid
 
@@ -320,13 +317,16 @@ gravity, and I<SIZE> is a decimal number (size in points) or optionally
 followed by the unit modifier "px" for absolute size. Any one of the options
 may be absent.
 
 followed by the unit modifier "px" for absolute size. Any one of the options
 may be absent.
 
-[B<-R>|B<--font-render-mode> {I<normal>,I<light>,I<mono>}]
+[B<-R>|B<--font-render-mode> {B<normal>,B<light>,B<mono>}]
 
 
-(this gets ignored in 1.3 for now!)
+There are 3 font render modes:
+
+B<normal>: Full Hinting and Antialiasing (default)
+
+B<light>: Slight Hinting and Antialiasing
+
+B<mono>: Full Hinting and NO Antialiasing
 
 
-This lets you customize the strength of the font smoothing,
-or disable it entirely using I<mono>. By default, I<normal>
-font smoothing is used.
 
 [B<-B>|B<--font-smoothing-threshold> I<size>]
 
 
 [B<-B>|B<--font-smoothing-threshold> I<size>]
 
@@ -336,6 +336,14 @@ This specifies the largest font size which will be rendered
 bitmapped, that is, without any font smoothing. By default,
 no text is rendered bitmapped.
 
 bitmapped, that is, without any font smoothing. By default,
 no text is rendered bitmapped.
 
+[B<-G>|B<--graph-render-mode> {B<normal>,B<mono>}]
+
+There are 2 render modes:
+
+B<normal>: Graphs are fully Antialiased (default)
+
+B<mono>: No Antialiasing
+
 [B<-E>|B<--slope-mode>]
 
 RRDtool graphs are composed of stair case curves by default. This is in line with
 [B<-E>|B<--slope-mode>]
 
 RRDtool graphs are composed of stair case curves by default. This is in line with
index 43f7ce4..6878068 100644 (file)
@@ -49,7 +49,6 @@ RRD_C_FILES =         \
 
 noinst_HEADERS = \
        unused.h \
 
 noinst_HEADERS = \
        unused.h \
-       rrd_gfx.h \
        rrd_getopt.h parsetime.h \
        rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_hw.h rrd_rpncalc.h \
        rrd_nan_inf.h fnv.h rrd_graph.h \
        rrd_getopt.h parsetime.h \
        rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_hw.h rrd_rpncalc.h \
        rrd_nan_inf.h fnv.h rrd_graph.h \
index ec6a574..8a18ce4 100644 (file)
 #endif                          /* _MSC_VER */
 
 #include "rrd_tool.h"
 #endif                          /* _MSC_VER */
 
 #include "rrd_tool.h"
-#include "rrd_gfx.h"
+#include "rrd_graph.h"
 
 
 /* create a new line */
 void gfx_line(
 
 
 /* create a new line */
 void gfx_line(
-    cairo_t * cr,
+    image_desc_t *im,
     double X0,
     double Y0,
     double X1,
     double X0,
     double Y0,
     double X1,
@@ -31,11 +31,11 @@ void gfx_line(
     double width,
     gfx_color_t color)
 {
     double width,
     gfx_color_t color)
 {
-    gfx_dashed_line(cr, X0, Y0, X1, Y1, width, color, 0, 0);
+    gfx_dashed_line(im, X0, Y0, X1, Y1, width, color, 0, 0);
 }
 
 void gfx_dashed_line(
 }
 
 void gfx_dashed_line(
-    cairo_t * cr,
+    image_desc_t *im,
     double X0,
     double Y0,
     double X1,
     double X0,
     double Y0,
     double X1,
@@ -45,6 +45,7 @@ void gfx_dashed_line(
     double dash_on,
     double dash_off)
 {
     double dash_on,
     double dash_off)
 {
+    cairo_t  *cr = im->cr;
     double    dashes[] = { dash_on, dash_off };
     double    x = 0;
     double    y = 0;
     double    dashes[] = { dash_on, dash_off };
     double    x = 0;
     double    y = 0;
@@ -52,10 +53,10 @@ void gfx_dashed_line(
     cairo_save(cr);
     cairo_new_path(cr);
     cairo_set_line_width(cr, width);
     cairo_save(cr);
     cairo_new_path(cr);
     cairo_set_line_width(cr, width);
-    gfx_line_fit(cr, &x, &y);
-    gfx_line_fit(cr, &X0, &Y0);
+    gfx_line_fit(im, &x, &y);
+    gfx_line_fit(im, &X0, &Y0);
     cairo_move_to(cr, X0, Y0);
     cairo_move_to(cr, X0, Y0);
-    gfx_line_fit(cr, &X1, &Y1);
+    gfx_line_fit(im, &X1, &Y1);
     cairo_line_to(cr, X1, Y1);
     if (dash_on > 0 || dash_off > 0)
         cairo_set_dash(cr, dashes, 2, x);
     cairo_line_to(cr, X1, Y1);
     if (dash_on > 0 || dash_off > 0)
         cairo_set_dash(cr, dashes, 2, x);
@@ -67,7 +68,7 @@ void gfx_dashed_line(
 
 /* create a new area */
 void gfx_new_area(
 
 /* create a new area */
 void gfx_new_area(
-    cairo_t * cr,
+    image_desc_t *im,
     double X0,
     double Y0,
     double X1,
     double X0,
     double Y0,
     double X1,
@@ -76,12 +77,14 @@ void gfx_new_area(
     double Y2,
     gfx_color_t color)
 {
     double Y2,
     gfx_color_t color)
 {
+    cairo_t  *cr = im->cr;
+
     cairo_new_path(cr);
     cairo_new_path(cr);
-    gfx_area_fit(cr, &X0, &Y0);
+    gfx_area_fit(im, &X0, &Y0);
     cairo_move_to(cr, X0, Y0);
     cairo_move_to(cr, X0, Y0);
-    gfx_area_fit(cr, &X1, &Y1);
+    gfx_area_fit(im, &X1, &Y1);
     cairo_line_to(cr, X1, Y1);
     cairo_line_to(cr, X1, Y1);
-    gfx_area_fit(cr, &X2, &Y2);
+    gfx_area_fit(im, &X2, &Y2);
     cairo_line_to(cr, X2, Y2);
     cairo_set_source_rgba(cr, color.red, color.green, color.blue,
                           color.alpha);
     cairo_line_to(cr, X2, Y2);
     cairo_set_source_rgba(cr, color.red, color.green, color.blue,
                           color.alpha);
@@ -89,24 +92,28 @@ void gfx_new_area(
 
 /* add a point to a line or to an area */
 void gfx_add_point(
 
 /* add a point to a line or to an area */
 void gfx_add_point(
-    cairo_t * cr,
+    image_desc_t *im,
     double x,
     double y)
 {
     double x,
     double y)
 {
-    gfx_area_fit(cr, &x, &y);
+    cairo_t  *cr = im->cr;
+
+    gfx_area_fit(im, &x, &y);
     cairo_line_to(cr, x, y);
 }
 
 void gfx_close_path(
     cairo_line_to(cr, x, y);
 }
 
 void gfx_close_path(
-    cairo_t * cr)
+    image_desc_t *im)
 {
 {
+    cairo_t  *cr = im->cr;
+
     cairo_close_path(cr);
     cairo_fill(cr);
 }
 
 /* create a text node */
 static PangoLayout *gfx_prep_text(
     cairo_close_path(cr);
     cairo_fill(cr);
 }
 
 /* create a text node */
 static PangoLayout *gfx_prep_text(
-    cairo_t * cr,
+    image_desc_t *im,
     double x,
     gfx_color_t color,
     char *font,
     double x,
     gfx_color_t color,
     char *font,
@@ -116,6 +123,7 @@ static PangoLayout *gfx_prep_text(
 {
     PangoLayout *layout;
     PangoFontDescription *font_desc;
 {
     PangoLayout *layout;
     PangoFontDescription *font_desc;
+    cairo_t  *cr = im->cr;
 
     /* for performance reasons we might
        want todo that only once ... tabs will always
 
     /* for performance reasons we might
        want todo that only once ... tabs will always
@@ -125,6 +133,7 @@ static PangoLayout *gfx_prep_text(
     long      tab_shift = fmod(x, tabwidth);
 
     PangoTabArray *tab_array;
     long      tab_shift = fmod(x, tabwidth);
 
     PangoTabArray *tab_array;
+    PangoContext *pango_context;
 
     tab_array = pango_tab_array_new(tab_count, (gboolean) (1));
     for (i = 1; i <= tab_count; i++) {
 
     tab_array = pango_tab_array_new(tab_count, (gboolean) (1));
     for (i = 1; i <= tab_count; i++) {
@@ -135,6 +144,9 @@ static PangoLayout *gfx_prep_text(
     cairo_set_source_rgba(cr, color.red, color.green, color.blue,
                           color.alpha);
     layout = pango_cairo_create_layout(cr);
     cairo_set_source_rgba(cr, color.red, color.green, color.blue,
                           color.alpha);
     layout = pango_cairo_create_layout(cr);
+    pango_context = pango_layout_get_context(layout);
+    pango_cairo_context_set_font_options(pango_context, im->font_options);
+    pango_cairo_update_context(cr, pango_context);
 
     pango_layout_set_tabs(layout, tab_array);
     font_desc = pango_font_description_from_string(font);
 
     pango_layout_set_tabs(layout, tab_array);
     font_desc = pango_font_description_from_string(font);
@@ -146,7 +158,7 @@ static PangoLayout *gfx_prep_text(
 
 /* Size Text Node */
 double gfx_get_text_width(
 
 /* Size Text Node */
 double gfx_get_text_width(
-    cairo_t * cr,
+    image_desc_t *im,
     double start,
     char *font,
     double size,
     double start,
     char *font,
     double size,
@@ -159,11 +171,11 @@ double gfx_get_text_width(
     char     *tab;
 
     /* turn \\t into tab */
     char     *tab;
 
     /* turn \\t into tab */
-    while (tab = strstr(text, "\\t")) {
+    while ((tab = strstr(text, "\\t"))) {
         memmove(tab + 1, tab + 2, strlen(tab + 2));
         tab[0] = (char) 9;
     }
         memmove(tab + 1, tab + 2, strlen(tab + 2));
         tab[0] = (char) 9;
     }
-    layout = gfx_prep_text(cr, start, color, font, size, tabwidth, text);
+    layout = gfx_prep_text(im, start, color, font, size, tabwidth, text);
     pango_layout_get_pixel_extents(layout, NULL, &log_rect);
     pango_tab_array_free(pango_layout_get_tabs(layout));
     g_object_unref(layout);
     pango_layout_get_pixel_extents(layout, NULL, &log_rect);
     pango_tab_array_free(pango_layout_get_tabs(layout));
     g_object_unref(layout);
@@ -171,7 +183,7 @@ double gfx_get_text_width(
 }
 
 void gfx_text(
 }
 
 void gfx_text(
-    cairo_t * cr,
+    image_desc_t *im,
     double x,
     double y,
     gfx_color_t color,
     double x,
     double y,
     gfx_color_t color,
@@ -186,6 +198,7 @@ void gfx_text(
     PangoLayout *layout;
     PangoRectangle log_rect;
     PangoRectangle ink_rect;
     PangoLayout *layout;
     PangoRectangle log_rect;
     PangoRectangle ink_rect;
+    cairo_t  *cr = im->cr;
     double    sx = 0;
     double    sy = 0;
 
     double    sx = 0;
     double    sy = 0;
 
@@ -193,11 +206,10 @@ void gfx_text(
     cairo_translate(cr, x, y);
 /*    gfx_line(cr,-2,0,2,0,1,color);
     gfx_line(cr,0,-2,0,2,1,color); */
     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(cr, x, color, font, size, tabwidth, text);
+    layout = gfx_prep_text(im, x, color, font, size, tabwidth, text);
     pango_layout_get_pixel_extents(layout, &ink_rect, &log_rect);
     cairo_rotate(cr, -angle * G_PI / 180.0);
     sx = log_rect.x;
     pango_layout_get_pixel_extents(layout, &ink_rect, &log_rect);
     cairo_rotate(cr, -angle * G_PI / 180.0);
     sx = log_rect.x;
-    sy = ink_rect.y;
     switch (h_align) {
     case GFX_H_RIGHT:
         sx -= log_rect.width;
     switch (h_align) {
     case GFX_H_RIGHT:
         sx -= log_rect.width;
@@ -210,7 +222,7 @@ void gfx_text(
     case GFX_H_NULL:
         break;
     }
     case GFX_H_NULL:
         break;
     }
-    sy += log_rect.y;
+    sy = log_rect.y;
     switch (v_align) {
     case GFX_V_TOP:
         break;
     switch (v_align) {
     case GFX_V_TOP:
         break;
@@ -248,20 +260,23 @@ struct gfx_color_t gfx_hex_to_col(
 /* gridfit_lines */
 
 void gfx_line_fit(
 /* gridfit_lines */
 
 void gfx_line_fit(
-    cairo_t * cr,
+    image_desc_t *im,
     double *x,
     double *y)
 {
     double *x,
     double *y)
 {
+    cairo_t  *cr = im->cr;
     double    line_width;
     double    line_height;
 
     double    line_width;
     double    line_height;
 
+    if (!im->gridfit)
+        return;
     cairo_user_to_device(cr, x, y);
     line_width = cairo_get_line_width(cr);
     line_height = line_width;
     cairo_user_to_device_distance(cr, &line_width, &line_height);
     line_width = line_width / 2.0 - (long) (line_width / 2.0);
     line_height = line_height / 2.0 - (long) (line_height / 2.0);
     cairo_user_to_device(cr, x, y);
     line_width = cairo_get_line_width(cr);
     line_height = line_width;
     cairo_user_to_device_distance(cr, &line_width, &line_height);
     line_width = line_width / 2.0 - (long) (line_width / 2.0);
     line_height = line_height / 2.0 - (long) (line_height / 2.0);
-    *x = (double) ((long) (*x + 0.5)) + line_width;
+    *x = (double) ((long) (*x + 0.5)) - line_width;
     *y = (double) ((long) (*y + 0.5)) + line_height;
     cairo_device_to_user(cr, x, y);
 }
     *y = (double) ((long) (*y + 0.5)) + line_height;
     cairo_device_to_user(cr, x, y);
 }
@@ -269,10 +284,14 @@ void gfx_line_fit(
 /* gridfit_areas */
 
 void gfx_area_fit(
 /* gridfit_areas */
 
 void gfx_area_fit(
-    cairo_t * cr,
+    image_desc_t *im,
     double *x,
     double *y)
 {
     double *x,
     double *y)
 {
+    cairo_t  *cr = im->cr;
+
+    if (!im->gridfit)
+        return;
     cairo_user_to_device(cr, x, y);
     *x = (double) ((long) (*x + 0.5));
     *y = (double) ((long) (*y + 0.5));
     cairo_user_to_device(cr, x, y);
     *x = (double) ((long) (*x + 0.5));
     *y = (double) ((long) (*y + 0.5));
diff --git a/src/rrd_gfx.h b/src/rrd_gfx.h
deleted file mode 100644 (file)
index c3cd1e3..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
- * RRDtool 1.2.23  Copyright by Tobi Oetiker, 1997-2007
- ****************************************************************************
- * rrd_gfx.h generic graphics adapter library
- ****************************************************************************/
-
-#ifndef RRD_GFX_H
-#define RRD_GFX_H
-
-#define y0 cairo_y0
-#define y1 cairo_y1
-#define index cairo_index
-
-#include <cairo-pdf.h>
-#include <cairo-svg.h>
-#include <cairo-ps.h>
-#include <pango/pangocairo.h>
-
-enum gfx_if_en { IF_PNG = 0, IF_SVG, IF_EPS, IF_PDF };
-enum gfx_en { GFX_LINE = 0, GFX_AREA, GFX_TEXT };
-enum gfx_h_align_en { GFX_H_NULL = 0, GFX_H_LEFT, GFX_H_RIGHT, GFX_H_CENTER };
-enum gfx_v_align_en { GFX_V_NULL = 0, GFX_V_TOP, GFX_V_BOTTOM, GFX_V_CENTER };
-
-/* cairo color components */
-typedef struct gfx_color_t {
-    double    red;
-    double    green;
-    double    blue;
-    double    alpha;
-} gfx_color_t;
-
-
-/* create a new line */
-void      gfx_line(
-    cairo_t * cr,
-    double X0,
-    double Y0,
-    double X1,
-    double Y1,
-    double width,
-    gfx_color_t color);
-
-void      gfx_dashed_line(
-    cairo_t * cr,
-    double X0,
-    double Y0,
-    double X1,
-    double Y1,
-    double width,
-    gfx_color_t color,
-    double dash_on,
-    double dash_off);
-
-/* create a new area */
-void      gfx_new_area(
-    cairo_t * cr,
-    double X0,
-    double Y0,
-    double X1,
-    double Y1,
-    double X2,
-    double Y2,
-    gfx_color_t color);
-
-/* add a point to a line or to an area */
-void      gfx_add_point(
-    cairo_t * cr,
-    double x,
-    double y);
-
-/* close current path so it ends at the same point as it started */
-void      gfx_close_path(
-    cairo_t * cr);
-
-
-/* create a text node */
-void      gfx_text(
-    cairo_t * cr,
-    double x,
-    double y,
-    gfx_color_t color,
-    char *font,
-    double size,
-    double tabwidth,
-    double angle,
-    enum gfx_h_align_en h_align,
-    enum gfx_v_align_en v_align,
-    const char *text);
-
-/* measure width of a text string */
-double    gfx_get_text_width(
-    cairo_t * cr,
-    double start,
-    char *font,
-    double size,
-    double tabwidth,
-    char *text);
-
-
-/* convert color */
-gfx_color_t gfx_hex_to_col(
-    long unsigned int);
-void      gfx_line_fit(
-    cairo_t *,
-    double *,
-    double *);
-void      gfx_area_fit(
-    cairo_t *,
-    double *,
-    double *);
-#endif
index d23d071..6648d9c 100644 (file)
@@ -326,6 +326,8 @@ int im_free(
     free(im->gdes);
     if (im->surface)
         cairo_surface_destroy(im->surface);
     free(im->gdes);
     if (im->surface)
         cairo_surface_destroy(im->surface);
+    if (im->font_options)
+        cairo_font_options_destroy(im->font_options);
     return 0;
 }
 
     return 0;
 }
 
@@ -1638,7 +1640,7 @@ int leg_place(
                     /* no interleg space if string ends in \g */
                     fill += legspace[i];
                 }
                     /* no interleg space if string ends in \g */
                     fill += legspace[i];
                 }
-                fill += gfx_get_text_width(im->cr, fill + border,
+                fill += gfx_get_text_width(im, fill + border,
                                            im->text_prop[TEXT_PROP_LEGEND].
                                            font,
                                            im->text_prop[TEXT_PROP_LEGEND].
                                            im->text_prop[TEXT_PROP_LEGEND].
                                            font,
                                            im->text_prop[TEXT_PROP_LEGEND].
@@ -1690,7 +1692,7 @@ int leg_place(
                     im->gdes[ii].leg_x = leg_x;
                     im->gdes[ii].leg_y = leg_y;
                     leg_x +=
                     im->gdes[ii].leg_x = leg_x;
                     im->gdes[ii].leg_y = leg_y;
                     leg_x +=
-                        gfx_get_text_width(im->cr, leg_x,
+                        gfx_get_text_width(im, leg_x,
                                            im->text_prop[TEXT_PROP_LEGEND].
                                            font,
                                            im->text_prop[TEXT_PROP_LEGEND].
                                            im->text_prop[TEXT_PROP_LEGEND].
                                            font,
                                            im->text_prop[TEXT_PROP_LEGEND].
@@ -1900,33 +1902,33 @@ int draw_horizontal_grid(
                 }
                 nlabels++;
 
                 }
                 nlabels++;
 
-                gfx_text(im->cr,
+                gfx_text(im,
                          X0 - im->text_prop[TEXT_PROP_AXIS].size, Y0,
                          im->graph_col[GRC_FONT],
                          im->text_prop[TEXT_PROP_AXIS].font,
                          im->text_prop[TEXT_PROP_AXIS].size,
                          im->tabwidth, 0.0, GFX_H_RIGHT, GFX_V_CENTER,
                          graph_label);
                          X0 - im->text_prop[TEXT_PROP_AXIS].size, Y0,
                          im->graph_col[GRC_FONT],
                          im->text_prop[TEXT_PROP_AXIS].font,
                          im->text_prop[TEXT_PROP_AXIS].size,
                          im->tabwidth, 0.0, GFX_H_RIGHT, GFX_V_CENTER,
                          graph_label);
-                gfx_line(im->cr,
+                gfx_line(im,
                          X0 - 2, Y0,
                          X0, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
                          X0 - 2, Y0,
                          X0, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
-                gfx_line(im->cr,
+                gfx_line(im,
                          X1, Y0,
                          X1 + 2, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
                          X1, Y0,
                          X1 + 2, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
-                gfx_dashed_line(im->cr,
+                gfx_dashed_line(im,
                                 X0 - 2, Y0,
                                 X1 + 2, Y0,
                                 MGRIDWIDTH, im->graph_col[GRC_MGRID],
                                 im->grid_dash_on, im->grid_dash_off);
 
             } else if (!(im->extra_flags & NOMINOR)) {
                                 X0 - 2, Y0,
                                 X1 + 2, Y0,
                                 MGRIDWIDTH, im->graph_col[GRC_MGRID],
                                 im->grid_dash_on, im->grid_dash_off);
 
             } else if (!(im->extra_flags & NOMINOR)) {
-                gfx_line(im->cr,
+                gfx_line(im,
                          X0 - 2, Y0,
                          X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                          X0 - 2, Y0,
                          X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-                gfx_line(im->cr,
+                gfx_line(im,
                          X1, Y0,
                          X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                          X1, Y0,
                          X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-                gfx_dashed_line(im->cr,
+                gfx_dashed_line(im,
                                 X0 - 1, Y0,
                                 X1 + 1, Y0,
                                 GRIDWIDTH, im->graph_col[GRC_GRID],
                                 X0 - 1, Y0,
                                 X1 + 1, Y0,
                                 GRIDWIDTH, im->graph_col[GRC_GRID],
@@ -2069,13 +2071,13 @@ int horizontal_log_grid(
 
         /* major grid line */
 
 
         /* major grid line */
 
-        gfx_line(im->cr,
+        gfx_line(im,
                  X0 - 2, Y0, X0, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
                  X0 - 2, Y0, X0, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
-        gfx_line(im->cr,
+        gfx_line(im,
                  X1, Y0, X1 + 2, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
 
 
                  X1, Y0, X1 + 2, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
 
 
-        gfx_dashed_line(im->cr,
+        gfx_dashed_line(im,
                         X0 - 2, Y0,
                         X1 + 2, Y0,
                         MGRIDWIDTH, im->graph_col[GRC_MGRID],
                         X0 - 2, Y0,
                         X1 + 2, Y0,
                         MGRIDWIDTH, im->graph_col[GRC_MGRID],
@@ -2103,7 +2105,7 @@ int horizontal_log_grid(
             sprintf(graph_label, "%3.0f %c", pvalue, symbol);
         } else
             sprintf(graph_label, "%3.0e", value);
             sprintf(graph_label, "%3.0f %c", pvalue, symbol);
         } else
             sprintf(graph_label, "%3.0e", value);
-        gfx_text(im->cr,
+        gfx_text(im,
                  X0 - im->text_prop[TEXT_PROP_AXIS].size, Y0,
                  im->graph_col[GRC_FONT],
                  im->text_prop[TEXT_PROP_AXIS].font,
                  X0 - im->text_prop[TEXT_PROP_AXIS].size, Y0,
                  im->graph_col[GRC_FONT],
                  im->text_prop[TEXT_PROP_AXIS].font,
@@ -2137,13 +2139,13 @@ int horizontal_log_grid(
                     break;
 
                 /* draw lines */
                     break;
 
                 /* draw lines */
-                gfx_line(im->cr,
+                gfx_line(im,
                          X0 - 2, Y0,
                          X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                          X0 - 2, Y0,
                          X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-                gfx_line(im->cr,
+                gfx_line(im,
                          X1, Y0,
                          X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                          X1, Y0,
                          X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-                gfx_dashed_line(im->cr,
+                gfx_dashed_line(im,
                                 X0 - 1, Y0,
                                 X1 + 1, Y0,
                                 GRIDWIDTH, im->graph_col[GRC_GRID],
                                 X0 - 1, Y0,
                                 X1 + 1, Y0,
                                 GRIDWIDTH, im->graph_col[GRC_GRID],
@@ -2160,13 +2162,13 @@ int horizontal_log_grid(
                     break;
 
                 /* draw lines */
                     break;
 
                 /* draw lines */
-                gfx_line(im->cr,
+                gfx_line(im,
                          X0 - 2, Y0,
                          X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                          X0 - 2, Y0,
                          X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-                gfx_line(im->cr,
+                gfx_line(im,
                          X1, Y0,
                          X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                          X1, Y0,
                          X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-                gfx_dashed_line(im->cr,
+                gfx_dashed_line(im,
                                 X0 - 1, Y0,
                                 X1 + 1, Y0,
                                 GRIDWIDTH, im->graph_col[GRC_GRID],
                                 X0 - 1, Y0,
                                 X1 + 1, Y0,
                                 GRIDWIDTH, im->graph_col[GRC_GRID],
@@ -2208,11 +2210,11 @@ int horizontal_log_grid(
                 break;
 
             /* draw lines */
                 break;
 
             /* draw lines */
-            gfx_line(im->cr,
+            gfx_line(im,
                      X0 - 2, Y0, X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                      X0 - 2, Y0, X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-            gfx_line(im->cr,
+            gfx_line(im,
                      X1, Y0, X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                      X1, Y0, X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-            gfx_dashed_line(im->cr,
+            gfx_dashed_line(im,
                             X0 - 1, Y0,
                             X1 + 1, Y0,
                             GRIDWIDTH, im->graph_col[GRC_GRID],
                             X0 - 1, Y0,
                             X1 + 1, Y0,
                             GRIDWIDTH, im->graph_col[GRC_GRID],
@@ -2231,11 +2233,11 @@ int horizontal_log_grid(
                 break;
 
             /* draw lines */
                 break;
 
             /* draw lines */
-            gfx_line(im->cr,
+            gfx_line(im,
                      X0 - 2, Y0, X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                      X0 - 2, Y0, X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-            gfx_line(im->cr,
+            gfx_line(im,
                      X1, Y0, X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
                      X1, Y0, X1 + 2, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
-            gfx_dashed_line(im->cr,
+            gfx_dashed_line(im,
                             X0 - 1, Y0,
                             X1 + 1, Y0,
                             GRIDWIDTH, im->graph_col[GRC_GRID],
                             X0 - 1, Y0,
                             X1 + 1, Y0,
                             GRIDWIDTH, im->graph_col[GRC_GRID],
@@ -2310,11 +2312,11 @@ void vertical_grid(
             if (ti == timajor)
                 continue;   /* skip as falls on major grid line */
             X0 = xtr(im, ti);
             if (ti == timajor)
                 continue;   /* skip as falls on major grid line */
             X0 = xtr(im, ti);
-            gfx_line(im->cr, X0, Y1 - 2, X0, Y1, GRIDWIDTH,
+            gfx_line(im, X0, Y1 - 2, X0, Y1, GRIDWIDTH,
                      im->graph_col[GRC_GRID]);
                      im->graph_col[GRC_GRID]);
-            gfx_line(im->cr, X0, Y0, X0, Y0 + 2, GRIDWIDTH,
+            gfx_line(im, X0, Y0, X0, Y0 + 2, GRIDWIDTH,
                      im->graph_col[GRC_GRID]);
                      im->graph_col[GRC_GRID]);
-            gfx_dashed_line(im->cr, X0, Y1 - 1, X0, Y0 + 1, GRIDWIDTH,
+            gfx_dashed_line(im, X0, Y0 + 1, X0, Y1 - 1, GRIDWIDTH,
                             im->graph_col[GRC_GRID],
                             im->grid_dash_on, im->grid_dash_off);
 
                             im->graph_col[GRC_GRID],
                             im->grid_dash_on, im->grid_dash_off);
 
@@ -2332,11 +2334,11 @@ void vertical_grid(
         if (ti < im->start || ti > im->end)
             continue;
         X0 = xtr(im, ti);
         if (ti < im->start || ti > im->end)
             continue;
         X0 = xtr(im, ti);
-        gfx_line(im->cr, X0, Y1 - 2, X0, Y1, MGRIDWIDTH,
+        gfx_line(im, X0, Y1 - 2, X0, Y1, MGRIDWIDTH,
                  im->graph_col[GRC_MGRID]);
                  im->graph_col[GRC_MGRID]);
-        gfx_line(im->cr, X0, Y0, X0, Y0 + 3, MGRIDWIDTH,
+        gfx_line(im, X0, Y0, X0, Y0 + 3, MGRIDWIDTH,
                  im->graph_col[GRC_MGRID]);
                  im->graph_col[GRC_MGRID]);
-        gfx_dashed_line(im->cr, X0, Y1 - 2, X0, Y0 + 3, MGRIDWIDTH,
+        gfx_dashed_line(im, X0, Y0 + 3, X0, Y1 - 2, MGRIDWIDTH,
                         im->graph_col[GRC_MGRID],
                         im->grid_dash_on, im->grid_dash_off);
 
                         im->graph_col[GRC_MGRID],
                         im->grid_dash_on, im->grid_dash_off);
 
@@ -2359,9 +2361,9 @@ void vertical_grid(
 #else
 # error "your libc has no strftime I guess we'll abort the exercise here."
 #endif
 #else
 # error "your libc has no strftime I guess we'll abort the exercise here."
 #endif
-        gfx_text(im->cr,
+        gfx_text(im,
                  xtr(im, tilab),
                  xtr(im, tilab),
-                 Y0 + 1,
+                 Y0 + 3,
                  im->graph_col[GRC_FONT],
                  im->text_prop[TEXT_PROP_AXIS].font,
                  im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 0.0,
                  im->graph_col[GRC_FONT],
                  im->text_prop[TEXT_PROP_AXIS].font,
                  im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 0.0,
@@ -2384,23 +2386,23 @@ void axis_paint(
        im->xorigin+im->xsize,im->yorigin-im->ysize,
        GRIDWIDTH, im->graph_col[GRC_AXIS]); */
 
        im->xorigin+im->xsize,im->yorigin-im->ysize,
        GRIDWIDTH, im->graph_col[GRC_AXIS]); */
 
-    gfx_line(im->cr, im->xorigin - 4, im->yorigin,
+    gfx_line(im, im->xorigin - 4, im->yorigin,
              im->xorigin + im->xsize + 4, im->yorigin,
              MGRIDWIDTH, im->graph_col[GRC_AXIS]);
 
              im->xorigin + im->xsize + 4, im->yorigin,
              MGRIDWIDTH, im->graph_col[GRC_AXIS]);
 
-    gfx_line(im->cr, im->xorigin, im->yorigin + 4,
+    gfx_line(im, im->xorigin, im->yorigin + 4,
              im->xorigin, im->yorigin - im->ysize - 4,
              MGRIDWIDTH, im->graph_col[GRC_AXIS]);
 
 
     /* arrow for X and Y axis direction */
              im->xorigin, im->yorigin - im->ysize - 4,
              MGRIDWIDTH, im->graph_col[GRC_AXIS]);
 
 
     /* arrow for X and Y axis direction */
-    gfx_new_area(im->cr, im->xorigin + im->xsize + 2, im->yorigin - 2, im->xorigin + im->xsize + 2, im->yorigin + 3, im->xorigin + im->xsize + 7, im->yorigin + 0.5,    /* LINEOFFSET */
+    gfx_new_area(im, im->xorigin + im->xsize + 2, im->yorigin - 2, im->xorigin + im->xsize + 2, im->yorigin + 3, im->xorigin + im->xsize + 7, im->yorigin + 0.5,    /* LINEOFFSET */
                  im->graph_col[GRC_ARROW]);
                  im->graph_col[GRC_ARROW]);
-    gfx_close_path(im->cr);
+    gfx_close_path(im);
 
 
-    gfx_new_area(im->cr, im->xorigin - 2, im->yorigin - im->ysize - 2, im->xorigin + 3, im->yorigin - im->ysize - 2, im->xorigin + 0.5, im->yorigin - im->ysize - 7,    /* LINEOFFSET */
+    gfx_new_area(im, im->xorigin - 2, im->yorigin - im->ysize - 2, im->xorigin + 3, im->yorigin - im->ysize - 2, im->xorigin + 0.5, im->yorigin - im->ysize - 7,    /* LINEOFFSET */
                  im->graph_col[GRC_ARROW]);
                  im->graph_col[GRC_ARROW]);
-    gfx_close_path(im->cr);
+    gfx_close_path(im);
 
 
 }
 
 
 }
@@ -2414,20 +2416,20 @@ void grid_paint(
     struct gfx_color_t water_color;
 
     /* draw 3d border */
     struct gfx_color_t water_color;
 
     /* draw 3d border */
-    gfx_new_area(im->cr, 0, im->yimg,
+    gfx_new_area(im, 0, im->yimg,
                  2, im->yimg - 2, 2, 2, im->graph_col[GRC_SHADEA]);
                  2, im->yimg - 2, 2, 2, im->graph_col[GRC_SHADEA]);
-    gfx_add_point(im->cr, im->ximg - 2, 2);
-    gfx_add_point(im->cr, im->ximg, 0);
-    gfx_add_point(im->cr, 0, 0);
-    gfx_close_path(im->cr);
+    gfx_add_point(im, im->ximg - 2, 2);
+    gfx_add_point(im, im->ximg, 0);
+    gfx_add_point(im, 0, 0);
+    gfx_close_path(im);
 
 
-    gfx_new_area(im->cr, 2, im->yimg - 2,
+    gfx_new_area(im, 2, im->yimg - 2,
                  im->ximg - 2, im->yimg - 2,
                  im->ximg - 2, 2, im->graph_col[GRC_SHADEB]);
                  im->ximg - 2, im->yimg - 2,
                  im->ximg - 2, 2, im->graph_col[GRC_SHADEB]);
-    gfx_add_point(im->cr, im->ximg, 0);
-    gfx_add_point(im->cr, im->ximg, im->yimg);
-    gfx_add_point(im->cr, 0, im->yimg);
-    gfx_close_path(im->cr);
+    gfx_add_point(im, im->ximg, 0);
+    gfx_add_point(im, im->ximg, im->yimg);
+    gfx_add_point(im, 0, im->yimg);
+    gfx_close_path(im);
 
 
     if (im->draw_x_grid == 1)
 
 
     if (im->draw_x_grid == 1)
@@ -2444,7 +2446,7 @@ void grid_paint(
         if (!res) {
             char     *nodata = "No Data found";
 
         if (!res) {
             char     *nodata = "No Data found";
 
-            gfx_text(im->cr, im->ximg / 2,
+            gfx_text(im, im->ximg / 2,
                      (2 * im->yorigin - im->ysize) / 2,
                      im->graph_col[GRC_FONT],
                      im->text_prop[TEXT_PROP_AXIS].font,
                      (2 * im->yorigin - im->ysize) / 2,
                      im->graph_col[GRC_FONT],
                      im->text_prop[TEXT_PROP_AXIS].font,
@@ -2454,7 +2456,7 @@ void grid_paint(
     }
 
     /* yaxis unit description */
     }
 
     /* yaxis unit description */
-    gfx_text(im->cr,
+    gfx_text(im,
              10, (im->yorigin - im->ysize / 2),
              im->graph_col[GRC_FONT],
              im->text_prop[TEXT_PROP_UNIT].font,
              10, (im->yorigin - im->ysize / 2),
              im->graph_col[GRC_FONT],
              im->text_prop[TEXT_PROP_UNIT].font,
@@ -2462,8 +2464,8 @@ void grid_paint(
              RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend);
 
     /* graph title */
              RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend);
 
     /* graph title */
-    gfx_text(im->cr,
-             im->ximg / 2, 4,
+    gfx_text(im,
+             im->ximg / 2, 6,
              im->graph_col[GRC_FONT],
              im->text_prop[TEXT_PROP_TITLE].font,
              im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, 0.0,
              im->graph_col[GRC_FONT],
              im->text_prop[TEXT_PROP_TITLE].font,
              im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, 0.0,
@@ -2471,8 +2473,8 @@ void grid_paint(
     /* rrdtool 'logo' */
     water_color = im->graph_col[GRC_FONT];
     water_color.alpha = 0.3;
     /* rrdtool 'logo' */
     water_color = im->graph_col[GRC_FONT];
     water_color.alpha = 0.3;
-    gfx_text(im->cr,
-             im->ximg - 4, 7,
+    gfx_text(im,
+             im->ximg - 4, 5,
              water_color,
              im->text_prop[TEXT_PROP_AXIS].font,
              5.5, im->tabwidth, -90,
              water_color,
              im->text_prop[TEXT_PROP_AXIS].font,
              5.5, im->tabwidth, -90,
@@ -2480,7 +2482,7 @@ void grid_paint(
 
     /* graph watermark */
     if (im->watermark[0] != '\0') {
 
     /* graph watermark */
     if (im->watermark[0] != '\0') {
-        gfx_text(im->cr,
+        gfx_text(im,
                  im->ximg / 2, im->yimg - 6,
                  water_color,
                  im->text_prop[TEXT_PROP_AXIS].font,
                  im->ximg / 2, im->yimg - 6,
                  water_color,
                  im->text_prop[TEXT_PROP_AXIS].font,
@@ -2497,7 +2499,7 @@ void grid_paint(
             /* im->gdes[i].leg_y is the bottom of the legend */
             X0 = im->gdes[i].leg_x;
             Y0 = im->gdes[i].leg_y;
             /* im->gdes[i].leg_y is the bottom of the legend */
             X0 = im->gdes[i].leg_x;
             Y0 = im->gdes[i].leg_y;
-            gfx_text(im->cr, X0, Y0,
+            gfx_text(im, X0, Y0,
                      im->graph_col[GRC_FONT],
                      im->text_prop[TEXT_PROP_LEGEND].font,
                      im->text_prop[TEXT_PROP_LEGEND].size,
                      im->graph_col[GRC_FONT],
                      im->text_prop[TEXT_PROP_LEGEND].font,
                      im->text_prop[TEXT_PROP_LEGEND].size,
@@ -2507,44 +2509,52 @@ void grid_paint(
                enough space for the box */
             if (im->gdes[i].gf != GF_PRINT &&
                 im->gdes[i].gf != GF_GPRINT && im->gdes[i].gf != GF_COMMENT) {
                enough space for the box */
             if (im->gdes[i].gf != GF_PRINT &&
                 im->gdes[i].gf != GF_GPRINT && im->gdes[i].gf != GF_COMMENT) {
-                int       boxH, boxV;
+                double    boxH, boxV;
+                double    X1, Y1;
 
 
-                boxH = gfx_get_text_width(im->cr, 0,
+
+                boxH = gfx_get_text_width(im, 0,
                                           im->text_prop[TEXT_PROP_LEGEND].
                                           font,
                                           im->text_prop[TEXT_PROP_LEGEND].
                                           size, im->tabwidth, "o") * 1.2;
                                           im->text_prop[TEXT_PROP_LEGEND].
                                           font,
                                           im->text_prop[TEXT_PROP_LEGEND].
                                           size, im->tabwidth, "o") * 1.2;
-                boxV = boxH * 1.1;
+                boxV = boxH;
 
                 /* shift the box up a bit */
 
                 /* shift the box up a bit */
-                Y0 -= boxV * 0.3;
+                Y0 -= boxV * 0.4;
 
                 /* make sure transparent colors show up the same way as in the graph */
 
 
                 /* make sure transparent colors show up the same way as in the graph */
 
-                gfx_new_area(im->cr,
+                gfx_new_area(im,
                              X0, Y0 - boxV,
                              X0, Y0, X0 + boxH, Y0, im->graph_col[GRC_BACK]);
                              X0, Y0 - boxV,
                              X0, Y0, X0 + boxH, Y0, im->graph_col[GRC_BACK]);
-                gfx_add_point(im->cr, X0 + boxH, Y0 - boxV);
-                gfx_close_path(im->cr);
+                gfx_add_point(im, X0 + boxH, Y0 - boxV);
+                gfx_close_path(im);
 
 
-                gfx_new_area(im->cr,
+                gfx_new_area(im,
                              X0, Y0 - boxV,
                              X0, Y0, X0 + boxH, Y0, im->gdes[i].col);
                              X0, Y0 - boxV,
                              X0, Y0, X0 + boxH, Y0, im->gdes[i].col);
-                gfx_add_point(im->cr, X0 + boxH, Y0 - boxV);
-                gfx_close_path(im->cr);
-
-                gfx_line(im->cr,
-                         X0, Y0 - boxV,
-                         X0, Y0, 1.0, im->graph_col[GRC_FRAME]);
-                gfx_line(im->cr,
-                         X0, Y0,
-                         X0 + boxH, Y0, 1.0, im->graph_col[GRC_FRAME]);
-                gfx_line(im->cr,
-                         X0 + boxH, Y0,
-                         X0 + boxH, Y0 - boxV, 1.0, im->graph_col[GRC_FRAME]);
-                gfx_line(im->cr,
-                         X0 + boxH, Y0 - boxV,
-                         X0, Y0 - boxV, 1.0, im->graph_col[GRC_FRAME]);
+                gfx_add_point(im, X0 + boxH, Y0 - boxV);
+                gfx_close_path(im);
+
+                cairo_save(im->cr);
+                cairo_new_path(im->cr);
+                cairo_set_line_width(im->cr, 1.0);
+                X1 = X0 + boxH;
+                Y1 = Y0 - boxV;
+                gfx_line_fit(im, &X0, &Y0);
+                gfx_line_fit(im, &X1, &Y1);
+                cairo_move_to(im->cr, X0, Y0);
+                cairo_line_to(im->cr, X1, Y0);
+                cairo_line_to(im->cr, X1, Y1);
+                cairo_line_to(im->cr, X0, Y1);
+                cairo_close_path(im->cr);
+                cairo_set_source_rgba(im->cr, im->graph_col[GRC_FRAME].red,
+                                      im->graph_col[GRC_FRAME].green,
+                                      im->graph_col[GRC_FRAME].blue,
+                                      im->graph_col[GRC_FRAME].alpha);
+                cairo_stroke(im->cr);
+                cairo_restore(im->cr);
             }
         }
     }
             }
         }
     }
@@ -2644,7 +2654,7 @@ int graph_size_location(
             Yxlabel = im->text_prop[TEXT_PROP_AXIS].size * 2.5;
         }
         if (im->draw_y_grid || im->forceleftspace) {
             Yxlabel = im->text_prop[TEXT_PROP_AXIS].size * 2.5;
         }
         if (im->draw_y_grid || im->forceleftspace) {
-            Xylabel = gfx_get_text_width(im->cr, 0,
+            Xylabel = gfx_get_text_width(im, 0,
                                          im->text_prop[TEXT_PROP_AXIS].font,
                                          im->text_prop[TEXT_PROP_AXIS].size,
                                          im->tabwidth, "0") * im->unitslength;
                                          im->text_prop[TEXT_PROP_AXIS].font,
                                          im->text_prop[TEXT_PROP_AXIS].size,
                                          im->tabwidth, "0") * im->unitslength;
@@ -2837,9 +2847,10 @@ int graph_paint(
     int       lazy = lazy_check(im);
 
     double    areazero = 0.0;
     int       lazy = lazy_check(im);
 
     double    areazero = 0.0;
+    graph_desc_t *lastgdes = NULL;
+
     PangoFontMap *font_map = pango_cairo_font_map_get_default();
 
     PangoFontMap *font_map = pango_cairo_font_map_get_default();
 
-    graph_desc_t *lastgdes = NULL;
 
     /* if we are lazy and there is nothing to PRINT ... quit now */
     if (lazy && im->prt_c == 0)
 
     /* if we are lazy and there is nothing to PRINT ... quit now */
     if (lazy && im->prt_c == 0)
@@ -2888,8 +2899,12 @@ int graph_paint(
     if (!calc_horizontal_grid(im))
         return -1;
 
     if (!calc_horizontal_grid(im))
         return -1;
 
-    if (im->gridfit)
-        apply_gridfit(im);
+    /* reset precalc */
+    ytr(im, DNAN);
+
+/*   if (im->gridfit)
+     apply_gridfit(im); */
+
 
     /* the actual graph is created by going through the individual
        graph elements and then drawing them */
 
     /* the actual graph is created by going through the individual
        graph elements and then drawing them */
@@ -2921,24 +2936,25 @@ int graph_paint(
         break;
     };
     im->cr = cairo_create(im->surface);
         break;
     };
     im->cr = cairo_create(im->surface);
-    pango_cairo_font_map_set_resolution(font_map, 100);
+    pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
+    cairo_set_antialias(im->cr, im->graph_antialias);
     cairo_scale(im->cr, im->zoom, im->zoom);
 
     cairo_scale(im->cr, im->zoom, im->zoom);
 
-    gfx_new_area(im->cr,
+    gfx_new_area(im,
                  0, 0,
                  0, im->yimg, im->ximg, im->yimg, im->graph_col[GRC_BACK]);
 
                  0, 0,
                  0, im->yimg, im->ximg, im->yimg, im->graph_col[GRC_BACK]);
 
-    gfx_add_point(im->cr, im->ximg, 0);
-    gfx_close_path(im->cr);
+    gfx_add_point(im, im->ximg, 0);
+    gfx_close_path(im);
 
 
-    gfx_new_area(im->cr,
+    gfx_new_area(im,
                  im->xorigin, im->yorigin,
                  im->xorigin + im->xsize, im->yorigin,
                  im->xorigin + im->xsize, im->yorigin - im->ysize,
                  im->graph_col[GRC_CANVAS]);
 
                  im->xorigin, im->yorigin,
                  im->xorigin + im->xsize, im->yorigin,
                  im->xorigin + im->xsize, im->yorigin - im->ysize,
                  im->graph_col[GRC_CANVAS]);
 
-    gfx_add_point(im->cr, im->xorigin, im->yorigin - im->ysize);
-    gfx_close_path(im->cr);
+    gfx_add_point(im, im->xorigin, im->yorigin - im->ysize);
+    gfx_close_path(im);
 
     if (im->minval > 0.0)
         areazero = im->minval;
 
     if (im->minval > 0.0)
         areazero = im->minval;
@@ -2963,14 +2979,14 @@ int graph_paint(
                 if (!isnan(im->gdes[i].p_data[ii]) &&
                     im->gdes[i].p_data[ii] != 0.0) {
                     if (im->gdes[i].yrule > 0) {
                 if (!isnan(im->gdes[i].p_data[ii]) &&
                     im->gdes[i].p_data[ii] != 0.0) {
                     if (im->gdes[i].yrule > 0) {
-                        gfx_line(im->cr,
+                        gfx_line(im,
                                  im->xorigin + ii, im->yorigin,
                                  im->xorigin + ii,
                                  im->yorigin -
                                  im->gdes[i].yrule * im->ysize, 1.0,
                                  im->gdes[i].col);
                     } else if (im->gdes[i].yrule < 0) {
                                  im->xorigin + ii, im->yorigin,
                                  im->xorigin + ii,
                                  im->yorigin -
                                  im->gdes[i].yrule * im->ysize, 1.0,
                                  im->gdes[i].col);
                     } else if (im->gdes[i].yrule < 0) {
-                        gfx_line(im->cr,
+                        gfx_line(im,
                                  im->xorigin + ii,
                                  im->yorigin - im->ysize,
                                  im->xorigin + ii,
                                  im->xorigin + ii,
                                  im->yorigin - im->ysize,
                                  im->xorigin + ii,
@@ -3030,22 +3046,22 @@ int graph_paint(
                                 double    x = ii - 1 + im->xorigin;
                                 double    y = last_y;
 
                                 double    x = ii - 1 + im->xorigin;
                                 double    y = last_y;
 
-                                gfx_line_fit(im->cr, &x, &y);
+                                gfx_line_fit(im, &x, &y);
                                 cairo_move_to(im->cr, x, y);
                                 x = ii + im->xorigin;
                                 y = last_y;
                                 cairo_move_to(im->cr, x, y);
                                 x = ii + im->xorigin;
                                 y = last_y;
-                                gfx_line_fit(im->cr, &x, &y);
+                                gfx_line_fit(im, &x, &y);
                                 cairo_line_to(im->cr, x, y);
                             } else {
                                 double    x = ii - 1 + im->xorigin;
                                 double    y = ytr(im,
                                                   im->gdes[i].p_data[ii - 1]);
 
                                 cairo_line_to(im->cr, x, y);
                             } else {
                                 double    x = ii - 1 + im->xorigin;
                                 double    y = ytr(im,
                                                   im->gdes[i].p_data[ii - 1]);
 
-                                gfx_line_fit(im->cr, &x, &y);
+                                gfx_line_fit(im, &x, &y);
                                 cairo_move_to(im->cr, x, y);
                                 x = ii + im->xorigin;
                                 y = last_y;
                                 cairo_move_to(im->cr, x, y);
                                 x = ii + im->xorigin;
                                 y = last_y;
-                                gfx_line_fit(im->cr, &x, &y);
+                                gfx_line_fit(im, &x, &y);
                                 cairo_line_to(im->cr, x, y);
                             }
                             draw_on = 1;
                                 cairo_line_to(im->cr, x, y);
                             }
                             draw_on = 1;
@@ -3058,11 +3074,11 @@ int graph_paint(
                                 double    x = ii - 1 + im->xorigin;
                                 double    y = y1;
 
                                 double    x = ii - 1 + im->xorigin;
                                 double    y = y1;
 
-                                gfx_line_fit(im->cr, &x, &y);
+                                gfx_line_fit(im, &x, &y);
                                 cairo_line_to(im->cr, x, y);
                             };
                             last_y = y1;
                                 cairo_line_to(im->cr, x, y);
                             };
                             last_y = y1;
-                            gfx_line_fit(im->cr, &x1, &y1);
+                            gfx_line_fit(im, &x1, &y1);
                             cairo_line_to(im->cr, x1, y1);
                         };
 
                             cairo_line_to(im->cr, x1, y1);
                         };
 
@@ -3098,7 +3114,7 @@ int graph_paint(
                                                               4)) {
                                 cntI++;
                             }
                                                               4)) {
                                 cntI++;
                             }
-                            gfx_new_area(im->cr,
+                            gfx_new_area(im,
                                          backX[0], backY[0],
                                          foreX[0], foreY[0],
                                          foreX[cntI], foreY[cntI],
                                          backX[0], backY[0],
                                          foreX[0], foreY[0],
                                          foreX[cntI], foreY[cntI],
@@ -3116,10 +3132,9 @@ int graph_paint(
                                                                      1], 4)) {
                                     cntI++;
                                 }
                                                                      1], 4)) {
                                     cntI++;
                                 }
-                                gfx_add_point(im->cr, foreX[cntI],
-                                              foreY[cntI]);
+                                gfx_add_point(im, foreX[cntI], foreY[cntI]);
                             }
                             }
-                            gfx_add_point(im->cr, backX[idxI], backY[idxI]);
+                            gfx_add_point(im, backX[idxI], backY[idxI]);
                             while (idxI > 1) {
                                 lastI = idxI;
                                 idxI--;
                             while (idxI > 1) {
                                 lastI = idxI;
                                 idxI--;
@@ -3133,12 +3148,11 @@ int graph_paint(
                                                                      1], 4)) {
                                     idxI--;
                                 }
                                                                      1], 4)) {
                                     idxI--;
                                 }
-                                gfx_add_point(im->cr, backX[idxI],
-                                              backY[idxI]);
+                                gfx_add_point(im, backX[idxI], backY[idxI]);
                             }
                             idxI = -1;
                             drawem = 0;
                             }
                             idxI = -1;
                             drawem = 0;
-                            gfx_close_path(im->cr);
+                            gfx_close_path(im);
                         }
                         if (drawem != 0) {
                             drawem = 0;
                         }
                         if (drawem != 0) {
                             drawem = 0;
@@ -3226,7 +3240,7 @@ int graph_paint(
         case GF_HRULE:
             if (im->gdes[i].yrule >= im->minval
                 && im->gdes[i].yrule <= im->maxval)
         case GF_HRULE:
             if (im->gdes[i].yrule >= im->minval
                 && im->gdes[i].yrule <= im->maxval)
-                gfx_line(im->cr,
+                gfx_line(im,
                          im->xorigin, ytr(im, im->gdes[i].yrule),
                          im->xorigin + im->xsize, ytr(im,
                                                       im->gdes[i].yrule),
                          im->xorigin, ytr(im, im->gdes[i].yrule),
                          im->xorigin + im->xsize, ytr(im,
                                                       im->gdes[i].yrule),
@@ -3235,7 +3249,7 @@ int graph_paint(
         case GF_VRULE:
             if (im->gdes[i].xrule >= im->start
                 && im->gdes[i].xrule <= im->end)
         case GF_VRULE:
             if (im->gdes[i].xrule >= im->start
                 && im->gdes[i].xrule <= im->end)
-                gfx_line(im->cr,
+                gfx_line(im,
                          xtr(im, im->gdes[i].xrule), im->yorigin,
                          xtr(im, im->gdes[i].xrule),
                          im->yorigin - im->ysize, 1.0, im->gdes[i].col);
                          xtr(im, im->gdes[i].xrule), im->yorigin,
                          xtr(im, im->gdes[i].xrule),
                          im->yorigin - im->ysize, 1.0, im->gdes[i].col);
@@ -3483,6 +3497,15 @@ void rrd_graph_init(
     im->grid_dash_off = 1;
     im->tabwidth = 40.0;
     im->zoom = 1;
     im->grid_dash_off = 1;
     im->tabwidth = 40.0;
     im->zoom = 1;
+    im->font_options = cairo_font_options_create();
+    im->graph_antialias = CAIRO_ANTIALIAS_GRAY;
+
+    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];
 
     for (i = 0; i < DIM(graph_col); i++)
         im->graph_col[i] = graph_col[i];
@@ -3587,6 +3610,7 @@ void rrd_graph_options(
             {"step", required_argument, 0, 'S'},
             {"tabwidth", required_argument, 0, 'T'},
             {"font-render-mode", required_argument, 0, 'R'},
             {"step", required_argument, 0, 'S'},
             {"tabwidth", required_argument, 0, 'T'},
             {"font-render-mode", required_argument, 0, 'R'},
+            {"graph-render-mode", required_argument, 0, 'G'},
             {"font-smoothing-threshold", required_argument, 0, 'B'},
             {"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 */
             {"font-smoothing-threshold", required_argument, 0, 'B'},
             {"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 */
@@ -3870,9 +3894,36 @@ void rrd_graph_options(
             break;
 
         case 'R':
             break;
 
         case 'R':
-            /* not supported curently */
+            if (strcmp(optarg, "normal") == 0) {
+                cairo_font_options_set_antialias(im->font_options,
+                                                 CAIRO_ANTIALIAS_GRAY);
+                cairo_font_options_set_hint_style(im->font_options,
+                                                  CAIRO_HINT_STYLE_FULL);
+            } else if (strcmp(optarg, "light") == 0) {
+                cairo_font_options_set_antialias(im->font_options,
+                                                 CAIRO_ANTIALIAS_GRAY);
+                cairo_font_options_set_hint_style(im->font_options,
+                                                  CAIRO_HINT_STYLE_SLIGHT);
+            } else if (strcmp(optarg, "mono") == 0) {
+                cairo_font_options_set_antialias(im->font_options,
+                                                 CAIRO_ANTIALIAS_NONE);
+                cairo_font_options_set_hint_style(im->font_options,
+                                                  CAIRO_HINT_STYLE_FULL);
+            } else {
+                rrd_set_error("unknown font-render-mode '%s'", optarg);
+                return;
+            }
+            break;
+        case 'G':
+            if (strcmp(optarg, "normal") == 0)
+                im->graph_antialias = CAIRO_ANTIALIAS_GRAY;
+            else if (strcmp(optarg, "mono") == 0)
+                im->graph_antialias = CAIRO_ANTIALIAS_NONE;
+            else {
+                rrd_set_error("unknown graph-render-mode '%s'", optarg);
+                return;
+            }
             break;
             break;
-
         case 'B':
             /* not supported curently */
             break;
         case 'B':
             /* not supported curently */
             break;
index dd03615..502fefe 100644 (file)
@@ -1,9 +1,17 @@
 #ifndef _RRD_GRAPH_H
 #define _RRD_GRAPH_H
 
 #ifndef _RRD_GRAPH_H
 #define _RRD_GRAPH_H
 
+#define y0 cairo_y0
+#define y1 cairo_y1
+#define index cairo_index
+
+#include <cairo-pdf.h>
+#include <cairo-svg.h>
+#include <cairo-ps.h>
+#include <pango/pangocairo.h>
+
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
-#include "rrd_gfx.h"
 
 #define MAX_VNAME_LEN 255
 #define DEF_NAM_FMT "%255[-_A-Za-z0-9]"
 
 #define MAX_VNAME_LEN 255
 #define DEF_NAM_FMT "%255[-_A-Za-z0-9]"
@@ -36,9 +44,6 @@ enum grc_en { GRC_CANVAS = 0, GRC_BACK, GRC_SHADEA, GRC_SHADEB,
 enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
     GF_AREA, GF_STACK, GF_TICK,
     GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
 enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
     GF_AREA, GF_STACK, GF_TICK,
     GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
-#ifdef WITH_PIECHART
-    GF_PART,
-#endif
     GF_XPORT
 };
 
     GF_XPORT
 };
 
@@ -62,6 +67,21 @@ enum text_prop_en { TEXT_PROP_DEFAULT = 0,  /* default settings */
     TEXT_PROP_LAST
 };
 
     TEXT_PROP_LAST
 };
 
+
+enum gfx_if_en { IF_PNG = 0, IF_SVG, IF_EPS, IF_PDF };
+enum gfx_en { GFX_LINE = 0, GFX_AREA, GFX_TEXT };
+enum gfx_h_align_en { GFX_H_NULL = 0, GFX_H_LEFT, GFX_H_RIGHT, GFX_H_CENTER };
+enum gfx_v_align_en { GFX_V_NULL = 0, GFX_V_TOP, GFX_V_BOTTOM, GFX_V_CENTER };
+
+/* cairo color components */
+typedef struct gfx_color_t {
+    double    red;
+    double    green;
+    double    blue;
+    double    alpha;
+} gfx_color_t;
+
+
 typedef struct text_prop_t {
     double    size;
     char      font[1024];
 typedef struct text_prop_t {
     double    size;
     char      font[1024];
@@ -156,9 +176,6 @@ typedef struct image_desc_t {
     char      graphfile[MAXPATH];   /* filename for graphic */
     FILE     *graphhandle;  /* FILE to use if filename is "-" */
     long      xsize, ysize; /* graph area size in pixels */
     char      graphfile[MAXPATH];   /* filename for graphic */
     FILE     *graphhandle;  /* FILE to use if filename is "-" */
     long      xsize, ysize; /* graph area size in pixels */
-#ifdef WITH_PIECHART
-    long      piesize;  /* size of the piechart */
-#endif
     struct gfx_color_t graph_col[__GRC_END__];  /* real colors for the graph */
     text_prop_t text_prop[TEXT_PROP_LAST];  /* text properties */
     char      ylegend[210]; /* legend along the yaxis */
     struct gfx_color_t graph_col[__GRC_END__];  /* real colors for the graph */
     text_prop_t text_prop[TEXT_PROP_LAST];  /* text properties */
     char      ylegend[210]; /* legend along the yaxis */
@@ -193,9 +210,6 @@ typedef struct image_desc_t {
     /* status information */
 
     long      xorigin, yorigin; /* where is (0,0) of the graph */
     /* status information */
 
     long      xorigin, yorigin; /* where is (0,0) of the graph */
-#ifdef WITH_PIECHART
-    long      pie_x, pie_y; /* where is the centerpoint */
-#endif
     long      ximg, yimg;   /* total size of the image */
     double    zoom;
     double    magfact;  /* numerical magnitude */
     long      ximg, yimg;   /* total size of the image */
     double    zoom;
     double    magfact;  /* numerical magnitude */
@@ -214,6 +228,8 @@ typedef struct image_desc_t {
     graph_desc_t *gdes; /* points to an array of graph elements */
     cairo_surface_t *surface;   /* graphics library */
     cairo_t  *cr;       /* drawin context */
     graph_desc_t *gdes; /* points to an array of graph elements */
     cairo_surface_t *surface;   /* graphics library */
     cairo_t  *cr;       /* drawin context */
+    cairo_font_options_t *font_options; /* cairo font options */
+    cairo_antialias_t graph_antialias;  /* antialiasing for the graph */
 } image_desc_t;
 
 /* Prototypes */
 } image_desc_t;
 
 /* Prototypes */
@@ -300,16 +316,6 @@ int       graph_paint(
     image_desc_t *,
     char ***);
 
     image_desc_t *,
     char ***);
 
-#ifdef WITH_PIECHART
-void      pie_part(
-    image_desc_t *,
-    gfx_color_t,
-    double,
-    double,
-    double,
-    double,
-    double);
-#endif
 int       gdes_alloc(
     image_desc_t *);
 int       scan_for_col(
 int       gdes_alloc(
     image_desc_t *);
 int       scan_for_col(
@@ -355,10 +361,88 @@ int       vdef_percent_compar(
 int       graph_size_location(
     image_desc_t *,
     int
 int       graph_size_location(
     image_desc_t *,
     int
-#ifdef WITH_PIECHART
-    ,
-    int
-#endif
     );
 
     );
 
+
+/* create a new line */
+void      gfx_line(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double width,
+    gfx_color_t color);
+
+void      gfx_dashed_line(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double width,
+    gfx_color_t color,
+    double dash_on,
+    double dash_off);
+
+/* create a new area */
+void      gfx_new_area(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double X2,
+    double Y2,
+    gfx_color_t color);
+
+/* add a point to a line or to an area */
+void      gfx_add_point(
+    image_desc_t *im,
+    double x,
+    double y);
+
+/* close current path so it ends at the same point as it started */
+void      gfx_close_path(
+    image_desc_t *im);
+
+
+/* create a text node */
+void      gfx_text(
+    image_desc_t *im,
+    double x,
+    double y,
+    gfx_color_t color,
+    char *font,
+    double size,
+    double tabwidth,
+    double angle,
+    enum gfx_h_align_en h_align,
+    enum gfx_v_align_en v_align,
+    const char *text);
+
+/* measure width of a text string */
+double    gfx_get_text_width(
+    image_desc_t *im,
+    double start,
+    char *font,
+    double size,
+    double tabwidth,
+    char *text);
+
+
+/* convert color */
+gfx_color_t gfx_hex_to_col(
+    long unsigned int);
+
+void      gfx_line_fit(
+    image_desc_t *im,
+    double *x,
+    double *y);
+
+void      gfx_area_fit(
+    image_desc_t *im,
+    double *x,
+    double *y);
+
 #endif
 #endif
index 0991b3b..708c223 100644 (file)
@@ -497,7 +497,7 @@ int rrd_parse_PVHLAST(
     static int spacecnt = 0;
 
     if (spacecnt == 0) {
     static int spacecnt = 0;
 
     if (spacecnt == 0) {
-        float     one_space = gfx_get_text_width(im->cr, 0,
+        float     one_space = gfx_get_text_width(im, 0,
                                                  im->
                                                  text_prop[TEXT_PROP_LEGEND].
                                                  font,
                                                  im->
                                                  text_prop[TEXT_PROP_LEGEND].
                                                  font,
@@ -505,7 +505,7 @@ int rrd_parse_PVHLAST(
                                                  text_prop[TEXT_PROP_LEGEND].
                                                  size,
                                                  im->tabwidth, "    ") / 4.0;
                                                  text_prop[TEXT_PROP_LEGEND].
                                                  size,
                                                  im->tabwidth, "    ") / 4.0;
-        float     target_space = gfx_get_text_width(im->cr, 0,
+        float     target_space = gfx_get_text_width(im, 0,
                                                     im->
                                                     text_prop
                                                     [TEXT_PROP_LEGEND].font,
                                                     im->
                                                     text_prop
                                                     [TEXT_PROP_LEGEND].font,