As gfx_canvas_t now has excatly the same lifespan as image_desc_t, I've
authoroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Wed, 3 Apr 2002 14:52:15 +0000 (14:52 +0000)
committeroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Wed, 3 Apr 2002 14:52:15 +0000 (14:52 +0000)
made 'gfx_canvas_t canvas' a member of image_desc_t and dropped it as a
separate parameter in all function calls.

imgformat, interlaced and zoom are moved to gfx_canvas_t. I have dropped
my old fontlib-enum as imgformat contains that information. The
gfx_render_xxx switch is moved to rrd_gfx so rrd_graph is (almost) only
bothered with image formats in cmd line parsing.

gfx_close_path is added.

gfx_new_dashed_line is added with 2 new arguments: length of a dash and
length between dashes. gfx_new_line is still there for plain lines.
Having dash-length == 0 creates normal line.
rrd_graph.c is not updated for dashed lines. It's not decided how one
should specify which and how lines are dashed. An extension of the color
specification?

svg is updated for dashes and opacity, but libart code is not. I've
fixed indent in SVG, all lines had a space before func decl. etc.
Misc small fixes, e.g. sscanf of gfx_color_t, position of x-axis arrow.
--- Peter Speck <speck@ruc.dk>

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

src/rrd_gfx.c
src/rrd_gfx.h
src/rrd_graph.c
src/rrd_graph.h

index e36910d..7ca6450 100644 (file)
@@ -32,6 +32,7 @@ gfx_node_t *gfx_new_node( gfx_canvas_t *canvas,enum gfx_en type){
   node->path = NULL;        /* path */
   node->points = 0;
   node->points_max =0;
+  node->closed_path = 0;
   node->svp = NULL;         /* svp */
   node->filename = NULL;             /* font or image filename */
   node->text = NULL;
@@ -56,6 +57,9 @@ gfx_canvas_t *gfx_new_canvas (void) {
     gfx_canvas_t *canvas = art_new(gfx_canvas_t,1);
     canvas->firstnode = NULL;
     canvas->lastnode = NULL;
+    canvas->imgformat = IF_PNG; /* we default to PNG output */
+    canvas->interlaced = 0;
+    canvas->zoom = 1.0;
     return canvas;    
 }
 
@@ -64,6 +68,14 @@ gfx_node_t  *gfx_new_line(gfx_canvas_t *canvas,
                           double x0, double y0, 
                           double x1, double y1,
                           double width, gfx_color_t color){
+  return gfx_new_dashed_line(canvas, x0, y0, x1, y1, width, color, 0, 0);
+}
+
+gfx_node_t  *gfx_new_dashed_line(gfx_canvas_t *canvas, 
+                          double x0, double y0, 
+                          double x1, double y1,
+                          double width, gfx_color_t color,
+                          double dash_on, double dash_off){
 
   gfx_node_t *node;
   ArtVpath *vec;
@@ -79,6 +91,8 @@ gfx_node_t  *gfx_new_line(gfx_canvas_t *canvas,
   node->points_max = 3;
   node->color = color;
   node->size  = width;
+  node->dash_on = dash_on;
+  node->dash_off = dash_off;
   node->path  = vec;
   return node;
 }
@@ -153,7 +167,9 @@ int           gfx_add_point  (gfx_node_t *node,
   return 0;
 }
 
-
+void           gfx_close_path  (gfx_node_t *node) {
+    node->closed_path = 1;
+}
 
 /* create a text node */
 gfx_node_t   *gfx_new_text   (gfx_canvas_t *canvas,  
@@ -182,7 +198,32 @@ gfx_node_t   *gfx_new_text   (gfx_canvas_t *canvas,
    return node;
 }
 
-double gfx_get_text_width ( double start, char* font, double size,                           
+int           gfx_render(gfx_canvas_t *canvas, 
+                             art_u32 width, art_u32 height, 
+                             gfx_color_t background, FILE *fp){
+  switch (canvas->imgformat) {
+  case IF_PNG: 
+    return gfx_render_png (canvas, width, height, background, fp);
+  case IF_SVG: 
+    return gfx_render_svg (canvas, width, height, background, fp);
+  default:
+    return -1;
+  }
+}
+
+double gfx_get_text_width ( gfx_canvas_t *canvas,
+                           double start, char* font, double size,
+                           double tabwidth, char* text){
+  switch (canvas->imgformat) {
+  case IF_PNG: 
+    return gfx_get_text_width_libart (canvas, start, font, size, tabwidth, text);
+  default:
+    return size * strlen(text);
+  }
+}
+
+double gfx_get_text_width_libart ( gfx_canvas_t *canvas,
+                           double start, char* font, double size,
                            double tabwidth, char* text){
 
   FT_GlyphSlot  slot;
@@ -237,7 +278,6 @@ static int gfx_save_png (art_u8 *buffer, FILE *fp,
 /* render grafics into png image */
 int           gfx_render_png (gfx_canvas_t *canvas, 
                              art_u32 width, art_u32 height, 
-                             double zoom, 
                              gfx_color_t background, FILE *fp){
     
     
@@ -245,8 +285,8 @@ int           gfx_render_png (gfx_canvas_t *canvas,
     gfx_node_t *node = canvas->firstnode;    
     art_u8 red = background >> 24, green = (background >> 16) & 0xff;
     art_u8 blue = (background >> 8) & 0xff, alpha = ( background & 0xff );
-    unsigned long pys_width = width * zoom;
-    unsigned long pys_height = height * zoom;
+    unsigned long pys_width = width * canvas->zoom;
+    unsigned long pys_height = height * canvas->zoom;
     const int bytes_per_pixel = 3;
     unsigned long rowstride = pys_width*bytes_per_pixel; /* bytes per pixel */
     art_u8 *buffer = art_new (art_u8, rowstride*pys_height);
@@ -259,12 +299,17 @@ int           gfx_render_png (gfx_canvas_t *canvas,
             ArtVpath *vec;
             double dst[6];     
             ArtSVP *svp;
-            art_affine_scale(dst,zoom,zoom);
+           if (node->closed_path) { 
+               /* libart uses end==start for closed as indicator of closed path */
+               gfx_add_point(node, node->path[0].x, node->path[0].y);
+               node->closed_path = 0;
+           }
+            art_affine_scale(dst,canvas->zoom,canvas->zoom);
             vec = art_vpath_affine_transform(node->path,dst);
             if(node->type == GFX_LINE){
                 svp = art_svp_vpath_stroke ( vec, ART_PATH_STROKE_JOIN_ROUND,
                                              ART_PATH_STROKE_CAP_ROUND,
-                                             node->size*zoom,1,1);
+                                             node->size*canvas->zoom,1,1);
             } else {
                 svp = art_svp_from_vpath ( vec );
             }
@@ -303,11 +348,11 @@ int           gfx_render_png (gfx_canvas_t *canvas,
             error = FT_Set_Char_Size(face,   /* handle to face object            */
                                      (long)(node->size*64),
                                      (long)(node->size*64),
-                                     (long)(100*zoom),
-                                     (long)(100*zoom));
+                                     (long)(100*canvas->zoom),
+                                     (long)(100*canvas->zoom));
             if ( error ) break;
-            pen_x = node->x * zoom;
-            pen_y = node->y * zoom;
+            pen_x = node->x * canvas->zoom;
+            pen_y = node->y * canvas->zoom;
             slot = face->glyph;
 
             for(text=(unsigned char *)node->text;*text;text++) {       
@@ -471,8 +516,14 @@ static int gfx_save_png (art_u8 *buffer, FILE *fp,  long width, long height, lon
 }
 
  
+/* ------- SVG -------
+   SVG reference:
+   http://www.w3.org/TR/SVG/
+*/
 static int svg_indent = 0;
 static int svg_single_line = 0;
+static const char *svg_default_font = "Helvetica";
+
 static void svg_print_indent(FILE *fp)
 {
   int i;
@@ -483,28 +534,28 @@ static void svg_print_indent(FILE *fp)
 }
  
 static void svg_start_tag(FILE *fp, const char *name)
- {
+{
    svg_print_indent(fp);
    putc('<', fp);
    fputs(name, fp);
    svg_indent++;
- }
+}
  
- static void svg_close_tag_single_line(FILE *fp)
- {
+static void svg_close_tag_single_line(FILE *fp)
+{
    svg_single_line++;
    putc('>', fp);
- }
+}
  
- static void svg_close_tag(FILE *fp)
- {
+static void svg_close_tag(FILE *fp)
+{
    putc('>', fp);
    if (!svg_single_line)
      putc('\n', fp);
- }
+}
  
- static void svg_end_tag(FILE *fp, const char *name)
- {
+static void svg_end_tag(FILE *fp, const char *name)
+{
    /* name is NULL if closing empty-node tag */
    svg_indent--;
    if (svg_single_line)
@@ -518,15 +569,15 @@ static void svg_start_tag(FILE *fp, const char *name)
      putc('/', fp);
    }
    svg_close_tag(fp);
- }
+}
  
- static void svg_close_tag_empty_node(FILE *fp)
- {
+static void svg_close_tag_empty_node(FILE *fp)
+{
    svg_end_tag(fp, NULL);
- }
+}
  
- static void svg_write_text(FILE *fp, const char *p)
- {
+static void svg_write_text(FILE *fp, const char *p)
+{
    char ch;
    const char *start, *last;
    if (!p)
@@ -554,10 +605,10 @@ static void svg_start_tag(FILE *fp, const char *name)
        default: putc(ch, fp);
      }
    }
- }
+}
  
- static void svg_write_number(FILE *fp, double d)
- {
+static void svg_write_number(FILE *fp, double d)
+{
    /* omit decimals if integer to reduce filesize */
    char buf[60], *p;
    snprintf(buf, sizeof(buf), "%.2f", d);
@@ -575,41 +626,64 @@ static void svg_start_tag(FILE *fp, const char *name)
      break;
    }
    fputs(buf, fp);
- }
+}
  
- static int svg_color_is_black(int c)
- {
-   /* gfx_color_t is RRGGBBAA, svg can use #RRGGBB like html */
-   c = (int)((c >> 8) & 0xFFFFFF);
-   return !c;
- }
+static int svg_color_is_black(int c)
+{
+  /* gfx_color_t is RRGGBBAA */
+  return c == 0x000000FF;
+}
  
- static void svg_write_color(FILE *fp, int c)
- {
-   /* gfx_color_t is RRGGBBAA, svg can use #RRGGBB like html */
-   c = (int)((c >> 8) & 0xFFFFFF);
-   if ((c & 0x0F0F0F) == ((c >> 4) & 0x0F0F0F)) {
+static void svg_write_color(FILE *fp, gfx_color_t c, const char *attr)
+{
+  /* gfx_color_t is RRGGBBAA, svg can use #RRGGBB and #RGB like html */
+  gfx_color_t rrggbb = (int)((c >> 8) & 0xFFFFFF);
+  gfx_color_t opacity = c & 0xFF;
+  fprintf(fp, " %s=\"", attr);
+  if ((rrggbb & 0x0F0F0F) == ((rrggbb >> 4) & 0x0F0F0F)) {
      /* css2 short form, #rgb is #rrggbb, not #r0g0b0 */
-     fprintf(fp, "#%03X",
-           ( ((c >> 8) & 0xF00)
-           | ((c >> 4) & 0x0F0)
-           | ( c       & 0x00F)));
+    fprintf(fp, "#%03lX",
+          ( ((rrggbb >> 8) & 0xF00)
+          | ((rrggbb >> 4) & 0x0F0)
+          | ( rrggbb       & 0x00F)));
    } else {
-     fprintf(fp, "#%06X", c);
+    fprintf(fp, "#%06lX", rrggbb);
    }
+  fputs("\"", fp);
+  if (opacity != 0xFF) {
+    fprintf(fp, " stroke-opacity=\"");
+    svg_write_number(fp, opacity / 255.0);
+    fputs("\"", fp);
  }
+}
  
- static int svg_is_int_step(double a, double b)
- {
+static void svg_common_path_attributes(FILE *fp, gfx_node_t *node)
+{
+  fputs(" stroke-width=\"", fp);
+  svg_write_number(fp, node->size);
+  fputs("\"", fp);
+  svg_write_color(fp, node->color, "stroke");
+  fputs(" fill=\"none\"", fp);
+  if (node->dash_on != 0 && node->dash_off != 0) {
+    fputs(" stroke-dasharray=\"", fp);
+    svg_write_number(fp, node->dash_on);
+    fputs(",", fp);
+    svg_write_number(fp, node->dash_off);
+    fputs("\"", fp);
+  }
+}
+
+static int svg_is_int_step(double a, double b)
+{
    double diff = fabs(a - b);
    return floor(diff) == diff;
- }
+}
  
- static int svg_path_straight_segment(FILE *fp,
+static int svg_path_straight_segment(FILE *fp,
      double lastA, double currentA, double currentB,
      gfx_node_t *node,
      int segment_idx, int isx, char absChar, char relChar)
- {
+{
    if (!svg_is_int_step(lastA, currentA)) {
      putc(absChar, fp);
      svg_write_number(fp, currentA);
@@ -630,23 +704,18 @@ static void svg_start_tag(FILE *fp, const char *name)
    putc(relChar, fp);
    svg_write_number(fp, currentA - lastA);
    return 0;
- }
+}
  
- static void svg_path(FILE *fp, gfx_node_t *node, int multi)
- {
+static void svg_path(FILE *fp, gfx_node_t *node, int multi)
+{
    int i;
    double lastX = 0, lastY = 0;
    /* for straight lines <path..> tags take less space than
       <line..> tags because of the efficient packing
       in the 'd' attribute */
    svg_start_tag(fp, "path");
-   if (!multi) {
-     fputs(" stroke-width=\"", fp);
-     svg_write_number(fp, node->size);
-     fputs("\" stroke=\"", fp);
-     svg_write_color(fp, node->color);
-     fputs("\" fill=\"none\"", fp);
-   }
+  if (!multi)
+    svg_common_path_attributes(fp, node);
    fputs(" d=\"", fp);
    /* specification of the 'd' attribute: */
    /* http://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation */
@@ -684,12 +753,14 @@ static void svg_start_tag(FILE *fp, const char *name)
      lastX = x;
      lastY = y;
    }
+  if (node->closed_path)
+    fputs(" Z", fp);
    fputs("\"", fp);
    svg_close_tag_empty_node(fp);
- }
+}
  
- static void svg_multi_path(FILE *fp, gfx_node_t **nodeR)
- {
+static void svg_multi_path(FILE *fp, gfx_node_t **nodeR)
+{
    /* optimize for multiple paths with the same color, penwidth, etc. */
    int num = 1;
    gfx_node_t *node = *nodeR;
@@ -697,7 +768,9 @@ static void svg_start_tag(FILE *fp, const char *name)
    while (next) {
      if (next->type != node->type
          || next->size != node->size
-         || next->color != node->color)
+        || next->color != node->color
+        || next->dash_on != node->dash_on
+        || next->dash_off != node->dash_off)
        break;
      next = next->next;
      num++;
@@ -707,11 +780,7 @@ static void svg_start_tag(FILE *fp, const char *name)
      return;
    }
    svg_start_tag(fp, "g");
-   fputs(" stroke-width=\"", fp);
-   svg_write_number(fp, node->size);
-   fputs("\" stroke=\"", fp);
-   svg_write_color(fp, node->color);
-   fputs("\" fill=\"none\"", fp);
+  svg_common_path_attributes(fp, node);
    svg_close_tag(fp);
    while (num && node) {
      svg_path(fp, node, 1);
@@ -721,16 +790,16 @@ static void svg_start_tag(FILE *fp, const char *name)
      *nodeR = node;
    }
    svg_end_tag(fp, "g");
- }
+}
  
- static void svg_area(FILE *fp, gfx_node_t *node)
- {
+static void svg_area(FILE *fp, gfx_node_t *node)
+{
    int i;
    double startX = 0, startY = 0;
    svg_start_tag(fp, "polygon");
-   fputs(" fill=\"", fp);
-   svg_write_color(fp, node->color);
-   fputs("\" points=\"", fp);
+  fputs(" ", fp);
+  svg_write_color(fp, node->color, "fill");
+  fputs(" points=\"", fp);
    for (i = 0; i < node->points; i++) {
      ArtVpath *vec = node->path + i;
      double x = vec->x - LINEOFFSET;
@@ -761,10 +830,10 @@ static void svg_start_tag(FILE *fp, const char *name)
    }
    fputs("\"", fp);
    svg_close_tag_empty_node(fp);
- }
+}
  
- static void svg_text(FILE *fp, gfx_node_t *node)
- {
+static void svg_text(FILE *fp, gfx_node_t *node)
+{
    double x = node->x - LINEOFFSET;
    double y = node->y - LINEOFFSET;
    if (node->angle != 0) {
@@ -790,14 +859,13 @@ static void svg_start_tag(FILE *fp, const char *name)
    svg_write_number(fp, x);
    fputs("\" y=\"", fp);
    svg_write_number(fp, y);
+  if (strcmp(node->filename, svg_default_font))
+    fprintf(fp, " font-family=\"%s\"", node->filename);
    fputs("\" font-size=\"", fp);
    svg_write_number(fp, node->size);
    fputs("\"", fp);
-   if (!svg_color_is_black(node->color)) {
-     fputs(" fill=\"", fp);
-     svg_write_color(fp, node->color);
-     fputs("\"", fp);
-   }
+  if (!svg_color_is_black(node->color))
+    svg_write_color(fp, node->color, "fill");
    switch (node->halign) {
    case GFX_H_RIGHT:  fputs(" text-anchor=\"end\"", fp); break;
    case GFX_H_CENTER: fputs(" text-anchor=\"middle\"", fp); break;
@@ -810,32 +878,31 @@ static void svg_start_tag(FILE *fp, const char *name)
    svg_end_tag(fp, "text");
    if (node->angle != 0)
      svg_end_tag(fp, "g");
- }
+}
  
- int       gfx_render_svg (gfx_canvas_t *canvas,
+int       gfx_render_svg (gfx_canvas_t *canvas,
                  art_u32 width, art_u32 height,
-                 double zoom,
                  gfx_color_t background, FILE *fp){
    gfx_node_t *node = canvas->firstnode;
    fputs(
- "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
- "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n"
- "   \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
- "<!--\n"
- "   SVG file created by RRDtool,\n"
- "   Tobias Oetiker <tobi@oetike.ch>, http://tobi.oetiker.ch\n"
- "\n"
- "   The width/height attributes in the outhermost svg node\n"
- "   are just default sizes for the browser which is used\n"
- "   if the svg file is openened directly without being\n"
- "   embedded in an html file.\n"
- "   The viewBox is the local coord system for rrdtool.\n"
- "-->\n", fp);
+"<?xml version=\"1.0\" standalone=\"no\"?>\n"
+"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n"
+"   \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
+"<!--\n"
+"   SVG file created by RRDtool,\n"
+"   Tobias Oetiker <tobi@oetike.ch>, http://tobi.oetiker.ch\n"
+"\n"
+"   The width/height attributes in the outhermost svg node\n"
+"   are just default sizes for the browser which is used\n"
+"   if the svg file is openened directly without being\n"
+"   embedded in an html file.\n"
+"   The viewBox is the local coord system for rrdtool.\n"
+"-->\n", fp);
    svg_start_tag(fp, "svg");
    fputs(" width=\"", fp);
-   svg_write_number(fp, width * zoom);
+  svg_write_number(fp, width * canvas->zoom);
    fputs("\" height=\"", fp);
-   svg_write_number(fp, height * zoom);
+  svg_write_number(fp, height * canvas->zoom);
    fputs("\" x=\"0\" y=\"0\" viewBox=\"", fp);
    svg_write_number(fp, -LINEOFFSET);
    fputs(" ", fp);
@@ -845,13 +912,12 @@ static void svg_start_tag(FILE *fp, const char *name)
    fputs(" ", fp);
    svg_write_number(fp, height - LINEOFFSET);
    fputs("\" preserveAspectRatio=\"xMidYMid\"", fp);
-   fputs(" font-family=\"Helvetica\"", fp); /* default font */
+  fprintf(fp, " font-family=\"%s\"", svg_default_font); /* default font */
+  fputs(" stroke-linecap=\"round\" stroke-linejoin=\"round\"", fp);
    svg_close_tag(fp);
    svg_start_tag(fp, "rect");
    fprintf(fp, " x=\"0\" y=\"0\" width=\"%d\" height=\"%d\"", width, height);
-   fputs(" style=\"fill:", fp);
-   svg_write_color(fp, background);
-   fputs("\"", fp);
+  svg_write_color(fp, background, "fill");
    svg_close_tag_empty_node(fp);
    while (node) {
      switch (node->type) {
@@ -868,4 +934,4 @@ static void svg_start_tag(FILE *fp, const char *name)
    }
    svg_end_tag(fp, "svg");
    return 0;
- }
+}
index 504f425..ed107cb 100644 (file)
@@ -9,6 +9,7 @@
 #define LIBART_COMPILATION
 #include <libart.h>
 
+enum gfx_if_en {IF_PNG=0,IF_SVG};
 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 };
@@ -18,14 +19,16 @@ typedef struct  gfx_node_t {
   enum gfx_en   type;         /* type of graph element */
   gfx_color_t   color;        /* color of element  0xRRGGBBAA  alpha 0xff is solid*/
   double        size;         /* font size, line width */
+  double        dash_on, dash_off; /* dash line fragments lengths */
   ArtVpath      *path;        /* path */
+  int           closed_path;
   int           points;
   int           points_max;
   ArtSVP        *svp;         /* svp */
   char *filename;             /* font or image filename */
   char *text;
   double        x,y;          /* position */
-  double      angle;
+  double        angle;        /* text angle */
   enum gfx_h_align_en halign; /* text alignement */
   enum gfx_v_align_en valign; /* text alignement */
   double        tabwidth; 
@@ -37,6 +40,9 @@ typedef struct gfx_canvas_t
 {
     struct gfx_node_t *firstnode;
     struct gfx_node_t *lastnode;
+    enum gfx_if_en imgformat;      /* image format */
+    int            interlaced;     /* will the graph be interlaced? */
+    double         zoom;           /* zoom for graph */
 } gfx_canvas_t;
 
 
@@ -48,6 +54,12 @@ gfx_node_t   *gfx_new_line   (gfx_canvas_t *canvas,
                              double x1, double y1,
                              double width, gfx_color_t color);
 
+gfx_node_t   *gfx_new_dashed_line   (gfx_canvas_t *canvas, 
+                             double x0, double y0, 
+                             double x1, double y1,
+                             double width, gfx_color_t color,
+                             double dash_on, double dash_off);
+
 /* create a new area */
 gfx_node_t   *gfx_new_area   (gfx_canvas_t *canvas, 
                              double x0, double y0,
@@ -58,6 +70,9 @@ gfx_node_t   *gfx_new_area   (gfx_canvas_t *canvas,
 /* add a point to a line or to an area */
 int           gfx_add_point  (gfx_node_t *node, double x, double y);
 
+/* close current path so it ends at the same point as it started */
+void          gfx_close_path  (gfx_node_t *node);
+
 
 /* create a text node */
 gfx_node_t   *gfx_new_text   (gfx_canvas_t *canvas,  
@@ -69,7 +84,8 @@ gfx_node_t   *gfx_new_text   (gfx_canvas_t *canvas,
                               char* text);
 
 /* measure width of a text string */
-double gfx_get_text_width ( double start, char* font, double size,                           
+double gfx_get_text_width ( gfx_canvas_t *canvas,
+                           double start, char* font, double size,
                            double tabwidth, char* text);
 
 
@@ -77,9 +93,14 @@ double gfx_get_text_width ( double start, char* font, double size,
 /* turn graph into a png image */
 int       gfx_render_png (gfx_canvas_t *canvas,
                               art_u32 width, art_u32 height,
-                              double zoom,
                               gfx_color_t background, FILE *fo);
+double gfx_get_text_width_libart ( gfx_canvas_t *canvas,
+                           double start, char* font, double size,
+                           double tabwidth, char* text);
                                                                                           
+int       gfx_render (gfx_canvas_t *canvas,
+                              art_u32 width, art_u32 height,
+                              gfx_color_t background, FILE *fo);
                                                                                          
 /* free memory used by nodes this will also remove memory required for
    node chain and associated material */
@@ -90,7 +111,6 @@ int           gfx_destroy    (gfx_canvas_t *canvas);
 /* turn graph into an svg image */
 int       gfx_render_svg (gfx_canvas_t *canvas,
                               art_u32 width, art_u32 height,
-                              double zoom,
                               gfx_color_t background, FILE *fo);
 
 
index 8b9e679..537a03f 100644 (file)
@@ -179,9 +179,10 @@ enum gf_en gf_conv(char *string){
     return (-1);
 }
 
-enum if_en if_conv(char *string){
+enum gfx_if_en if_conv(char *string){
     
     conv_if(PNG,IF_PNG)
+    conv_if(SVG,IF_SVG)
 
     return (-1);
 }
@@ -247,6 +248,7 @@ im_free(image_desc_t *im)
       free (im->gdes[i].rpnp);
     }
     free(im->gdes);
+    gfx_destroy(im->canvas);
     return 0;
 }
 
@@ -1291,7 +1293,8 @@ leg_place(image_desc_t *im)
                im->gdes[i].gf != GF_COMMENT) { 
                fill += box;       
            }
-          fill += gfx_get_text_width(fill+border,im->text_prop[TEXT_PROP_LEGEND].font,
+          fill += gfx_get_text_width(im->canvas, fill+border,
+                                     im->text_prop[TEXT_PROP_LEGEND].font,
                                      im->text_prop[TEXT_PROP_LEGEND].size,
                                      im->tabwidth,
                                      im->gdes[i].legend);
@@ -1338,7 +1341,8 @@ leg_place(image_desc_t *im)
                im->gdes[ii].leg_x = leg_x;
                im->gdes[ii].leg_y = leg_y;
                leg_x += 
-                gfx_get_text_width(leg_x,im->text_prop[TEXT_PROP_LEGEND].font,
+                gfx_get_text_width(im->canvas, leg_x,
+                                     im->text_prop[TEXT_PROP_LEGEND].font,
                                      im->text_prop[TEXT_PROP_LEGEND].size,
                                      im->tabwidth,
                                      im->gdes[ii].legend) 
@@ -1370,7 +1374,7 @@ leg_place(image_desc_t *im)
 
 
 int
-horizontal_grid(gfx_canvas_t *canvas, image_desc_t   *im)
+horizontal_grid(image_desc_t   *im)
 {
     double   range;
     double   scaledrange;
@@ -1379,7 +1383,7 @@ horizontal_grid(gfx_canvas_t *canvas, image_desc_t   *im)
     double   gridstep;
     double   scaledstep;
     char     graph_label[100];
-    double   x0,x1,y0,y1;
+    double   x0,x1,y0;
     int      labfact,gridind;
     int      decimals, fractionals;
     char     labfmt[64];
@@ -1480,20 +1484,20 @@ horizontal_grid(gfx_canvas_t *canvas, image_desc_t   *im)
                    }
                }
 
-              gfx_new_text ( canvas,
+              gfx_new_text ( im->canvas,
                              x0-im->text_prop[TEXT_PROP_AXIS].size/1.5, 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_new_line ( canvas,
+              gfx_new_line ( im->canvas,
                              x0-2,y0,
                              x1+2,y0,
                              MGRIDWIDTH, im->graph_col[GRC_MGRID] );          
               
            } else {            
-              gfx_new_line ( canvas,
+              gfx_new_line ( im->canvas,
                              x0-1,y0,
                              x1+1,y0,
                              GRIDWIDTH, im->graph_col[GRC_GRID] );            
@@ -1506,13 +1510,13 @@ horizontal_grid(gfx_canvas_t *canvas, image_desc_t   *im)
 
 /* logaritmic horizontal grid */
 int
-horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t   *im)   
+horizontal_log_grid(image_desc_t   *im)   
 {
     double   pixpex;
     int      ii,i;
     int      minoridx=0, majoridx=0;
     char     graph_label[100];
-    double   x0,x1,y0,y1;   
+    double   x0,x1,y0;   
     double   value, pixperstep, minstep;
 
     /* find grid spaceing */
@@ -1547,7 +1551,7 @@ horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t   *im)
        while(yloglab[minoridx][++i] > 0){          
           y0 = ytr(im,value * yloglab[minoridx][i]);
           if (y0 <= im->yorigin - im->ysize) break;
-          gfx_new_line ( canvas,
+          gfx_new_line ( im->canvas,
                          x0-1,y0,
                          x1+1,y0,
                          GRIDWIDTH, im->graph_col[GRC_GRID] );
@@ -1564,13 +1568,13 @@ horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t   *im)
        while(yloglab[majoridx][++i] > 0){          
           y0 = ytr(im,value * yloglab[majoridx][i]);    
           if (y0 <= im->yorigin - im->ysize) break;
-          gfx_new_line ( canvas,
+          gfx_new_line ( im->canvas,
                          x0-2,y0,
                          x1+2,y0,
                          MGRIDWIDTH, im->graph_col[GRC_MGRID] );
           
           sprintf(graph_label,"%3.0e",value * yloglab[majoridx][i]);
-          gfx_new_text ( canvas,
+          gfx_new_text ( im->canvas,
                          x0-im->text_prop[TEXT_PROP_AXIS].size/1.5, y0,
                          im->graph_col[GRC_FONT],
                          im->text_prop[TEXT_PROP_AXIS].font,
@@ -1585,7 +1589,6 @@ horizontal_log_grid(gfx_canvas_t *canvas, image_desc_t   *im)
 
 void
 vertical_grid(
-    gfx_canvas_t   *canvas,
     image_desc_t   *im )
 {   
     int xlab_sel;              /* which sort of label and grid ? */
@@ -1629,7 +1632,7 @@ vertical_grid(
        /* are we inside the graph ? */
        if (ti < im->start || ti > im->end) continue;
        x0 = xtr(im,ti);       
-       gfx_new_line(canvas,x0,y0+1, x0,y1-1,GRIDWIDTH, im->graph_col[GRC_GRID]);
+       gfx_new_line(im->canvas,x0,y0+1, x0,y1-1,GRIDWIDTH, im->graph_col[GRC_GRID]);
        
     }
 
@@ -1643,7 +1646,7 @@ vertical_grid(
        /* are we inside the graph ? */
        if (ti < im->start || ti > im->end) continue;
        x0 = xtr(im,ti);
-       gfx_new_line(canvas,x0,y0+2, x0,y1-2,MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+       gfx_new_line(im->canvas,x0,y0+2, x0,y1-2,MGRIDWIDTH, im->graph_col[GRC_MGRID]);
        
     }
     /* paint the labels below the graph */
@@ -1662,7 +1665,7 @@ vertical_grid(
 #else
 # error "your libc has no strftime I guess we'll abort the exercise here."
 #endif
-       gfx_new_text ( canvas,
+       gfx_new_text ( im->canvas,
                      xtr(im,tilab), y0+im->text_prop[TEXT_PROP_AXIS].size/1.5,
                      im->graph_col[GRC_FONT],
                      im->text_prop[TEXT_PROP_AXIS].font,
@@ -1677,33 +1680,32 @@ vertical_grid(
 
 void 
 axis_paint(
-   image_desc_t   *im,
-   gfx_canvas_t   *canvas
+   image_desc_t   *im
           )
 {   
     /* draw x and y axis */
-    gfx_new_line ( canvas, im->xorigin+im->xsize,im->yorigin,
+    gfx_new_line ( im->canvas, im->xorigin+im->xsize,im->yorigin,
                      im->xorigin+im->xsize,im->yorigin-im->ysize,
                      GRIDWIDTH, im->graph_col[GRC_GRID]);
        
-       gfx_new_line ( canvas, im->xorigin,im->yorigin-im->ysize,
+       gfx_new_line ( im->canvas, im->xorigin,im->yorigin-im->ysize,
                         im->xorigin+im->xsize,im->yorigin-im->ysize,
                         GRIDWIDTH, im->graph_col[GRC_GRID]);
    
-       gfx_new_line ( canvas, im->xorigin-4,im->yorigin,
+       gfx_new_line ( im->canvas, im->xorigin-4,im->yorigin,
                         im->xorigin+im->xsize+4,im->yorigin,
                         MGRIDWIDTH, im->graph_col[GRC_GRID]);
    
-       gfx_new_line ( canvas, im->xorigin,im->yorigin+4,
+       gfx_new_line ( im->canvas, im->xorigin,im->yorigin+4,
                         im->xorigin,im->yorigin-im->ysize-4,
                         MGRIDWIDTH, im->graph_col[GRC_GRID]);
    
     
     /* arrow for X axis direction */
-    gfx_new_area ( canvas, 
-                  im->xorigin+im->xsize+4,  im->yorigin-3,
-                  im->xorigin+im->xsize+4,  im->yorigin+3,
-                  im->xorigin+im->xsize+9,  im->yorigin,  
+    gfx_new_area ( im->canvas, 
+                  im->xorigin+im->xsize+3,  im->yorigin-3,
+                  im->xorigin+im->xsize+3,  im->yorigin+4,
+                  im->xorigin+im->xsize+8,  im->yorigin+0.5,   // LINEOFFSET
                   im->graph_col[GRC_ARROW]);
    
    
@@ -1711,19 +1713,15 @@ axis_paint(
 }
 
 void
-grid_paint(
-    image_desc_t   *im,
-    gfx_canvas_t   *canvas
-          
-    )
+grid_paint(image_desc_t   *im)
 {   
     long i;
     int res=0;
-    double x0,x1,x2,x3,y0,y1,y2,y3; /* points for filled graph and more*/
+    double x0,y0; /* points for filled graph and more*/
     gfx_node_t *node;
 
     /* draw 3d border */
-    node = gfx_new_area (canvas, 0,im->ygif,
+    node = gfx_new_area (im->canvas, 0,im->ygif,
                                  2,im->ygif-2,
                                  2,2,im->graph_col[GRC_SHADEA]);
     gfx_add_point( node , im->xgif - 2, 2 );
@@ -1731,7 +1729,7 @@ grid_paint(
     gfx_add_point( node , 0,0 );
 /*    gfx_add_point( node , 0,im->ygif ); */
    
-    node =  gfx_new_area (canvas, 2,im->ygif-2,
+    node =  gfx_new_area (im->canvas, 2,im->ygif-2,
                                   im->xgif-2,im->ygif-2,
                                   im->xgif - 2, 2,
                                  im->graph_col[GRC_SHADEB]);
@@ -1742,19 +1740,19 @@ grid_paint(
    
    
     if (im->draw_x_grid == 1 )
-      vertical_grid(canvas, im);
+      vertical_grid(im);
     
     if (im->draw_y_grid == 1){
        if(im->logarithmic){
-               res = horizontal_log_grid(canvas,im);
+               res = horizontal_log_grid(im);
        } else {
-               res = horizontal_grid(canvas,im);
+               res = horizontal_grid(im);
        }
 
        /* dont draw horizontal grid if there is no min and max val */
        if (! res ) {
          char *nodata = "No Data found";
-          gfx_new_text(canvas,im->xgif/2, (2*im->yorigin-im->ysize) / 2,
+          gfx_new_text(im->canvas,im->xgif/2, (2*im->yorigin-im->ysize) / 2,
                        im->graph_col[GRC_FONT],
                        im->text_prop[TEXT_PROP_AXIS].font,
                        im->text_prop[TEXT_PROP_AXIS].size,
@@ -1764,15 +1762,15 @@ grid_paint(
     }
 
     /* yaxis description */
-       #if 0
-           gfx_new_text( canvas,
+       if (im->canvas->imgformat != IF_PNG) {
+           gfx_new_text( im->canvas,
                          7, (im->yorigin - im->ysize/2),
                          im->graph_col[GRC_FONT],
                          im->text_prop[TEXT_PROP_AXIS].font,
                          im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 270.0,
                          GFX_H_CENTER, GFX_V_CENTER,
                          im->ylegend);
-       #else
+       } else {
            /* horrible hack until we can actually print vertically */
            {
                int n;
@@ -1781,7 +1779,7 @@ grid_paint(
                for (n=0;n<strlen(im->ylegend);n++) {
                    s[0]=im->ylegend[n];
                    s[1]='\0';
-                   gfx_new_text(canvas,7,im->text_prop[TEXT_PROP_AXIS].size*(l-n),
+                   gfx_new_text(im->canvas,7,im->text_prop[TEXT_PROP_AXIS].size*(l-n),
                        im->graph_col[GRC_FONT],
                        im->text_prop[TEXT_PROP_AXIS].font,
                        im->text_prop[TEXT_PROP_AXIS].size, im->tabwidth, 270.0,
@@ -1789,10 +1787,10 @@ grid_paint(
                        s);
                }
            }
-       #endif
+       }
    
     /* graph title */
-    gfx_new_text( canvas,
+    gfx_new_text( im->canvas,
                  im->xgif/2, im->text_prop[TEXT_PROP_TITLE].size,
                  im->graph_col[GRC_FONT],
                  im->text_prop[TEXT_PROP_TITLE].font,
@@ -1814,27 +1812,27 @@ grid_paint(
                        && im->gdes[i].gf != GF_COMMENT) {
                    int boxH, boxV;
 
-                   boxH = gfx_get_text_width(0,
+                   boxH = gfx_get_text_width(im->canvas, 0,
                                im->text_prop[TEXT_PROP_AXIS].font,
                                im->text_prop[TEXT_PROP_AXIS].size,
                                im->tabwidth,"M") * 1.25;
                    boxV = boxH;
 
-                   node = gfx_new_area(canvas,
+                   node = gfx_new_area(im->canvas,
                                x0,y0-boxV,
                                x0,y0,
                                x0+boxH,y0,
                                im->gdes[i].col);
                    gfx_add_point ( node, x0+boxH, y0-boxV );
-                   node = gfx_new_line(canvas,
+                   node = gfx_new_line(im->canvas,
                                x0,y0-boxV, x0,y0,
                                1,0x000000FF);
                    gfx_add_point(node,x0+boxH,y0);
                    gfx_add_point(node,x0+boxH,y0-boxV);
-                   gfx_add_point(node,x0,y0-boxV);
+                   gfx_close_path(node);
                    x0 += boxH / 1.25 * 2;
                }
-               gfx_new_text ( canvas, x0, y0,
+               gfx_new_text ( im->canvas, x0, y0,
                                   im->graph_col[GRC_FONT],
                                   im->text_prop[TEXT_PROP_AXIS].font,
                                   im->text_prop[TEXT_PROP_AXIS].size,
@@ -1864,17 +1862,19 @@ int lazy_check(image_desc_t *im){
       return 0;
     if ((fd = fopen(im->graphfile,"rb")) == NULL) 
       return 0; /* the file does not exist */
-    switch (im->imgformat) {
+    switch (im->canvas->imgformat) {
     case IF_PNG:
           size = PngSize(fd,&(im->xgif),&(im->ygif));
           break;
+    default:
+          size = 1;
     }
     fclose(fd);
     return size;
 }
 
 void
-pie_part(gfx_canvas_t *canvas, gfx_color_t color,
+pie_part(image_desc_t *im, gfx_color_t color,
            double PieCenterX, double PieCenterY, double Radius,
            double startangle, double endangle)
 {
@@ -1904,7 +1904,7 @@ pie_part(gfx_canvas_t *canvas, gfx_color_t color,
        Radius *= 0.8;
     }
 
-    node=gfx_new_area(canvas,
+    node=gfx_new_area(im->canvas,
                PieCenterX+sin(startangle)*Radius,
                PieCenterY-cos(startangle)*Radius,
                PieCenterX,
@@ -1961,7 +1961,7 @@ graph_size_location(image_desc_t *im, int elements, int piechart )
        ** automatically has some vertical spacing.  The horizontal
        ** spacing is added here, on each side.
        */
-       Xtitle = gfx_get_text_width(0,
+       Xtitle = gfx_get_text_width(im->canvas, 0,
                im->text_prop[TEXT_PROP_TITLE].font,
                im->text_prop[TEXT_PROP_TITLE].size,
                im->tabwidth,
@@ -2074,7 +2074,6 @@ graph_paint(image_desc_t *im, char ***calcpr)
   int piechart = 0;
   double PieStart=0.0;
   FILE  *fo;
-  gfx_canvas_t *canvas;
   gfx_node_t *node;
   
   double areazero = 0.0;
@@ -2130,12 +2129,10 @@ graph_paint(image_desc_t *im, char ***calcpr)
   if(graph_size_location(im,i,piechart)==-1)
     return -1;
 
-  canvas=gfx_new_canvas();
-
   /* the actual graph is created by going through the individual
      graph elements and then drawing them */
   
-  node=gfx_new_area ( canvas,
+  node=gfx_new_area ( im->canvas,
                       0, 0,
                       im->xgif, 0,
                       im->xgif, im->ygif,
@@ -2144,7 +2141,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
   gfx_add_point(node,0, im->ygif);
 
   if (piechart != 2) {
-    node=gfx_new_area ( canvas,
+    node=gfx_new_area ( im->canvas,
                       im->xorigin,             im->yorigin, 
                       im->xorigin + im->xsize, im->yorigin,
                       im->xorigin + im->xsize, im->yorigin-im->ysize,
@@ -2157,11 +2154,11 @@ graph_paint(image_desc_t *im, char ***calcpr)
     if (im->maxval < 0.0)
       areazero = im->maxval;
   
-    axis_paint(im,canvas);
+    axis_paint(im);
   }
 
   if (piechart) {
-    pie_part(canvas,im->graph_col[GRC_CANVAS],im->pie_x,im->pie_y,im->piesize*0.5,0,2*M_PI);
+    pie_part(im,im->graph_col[GRC_CANVAS],im->pie_x,im->pie_y,im->piesize*0.5,0,2*M_PI);
   }
 
   for(i=0;i<im->gdes_c;i++){
@@ -2182,7 +2179,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
               im->gdes[i].p_data[ii] > 0.0)
             { 
               /* generate a tick */
-              gfx_new_line(canvas, im -> xorigin + ii, 
+              gfx_new_line(im->canvas, im -> xorigin + ii, 
                            im -> yorigin - (im -> gdes[i].yrule * im -> ysize),
                            im -> xorigin + ii, 
                            im -> yorigin,
@@ -2215,7 +2212,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
             if ( ! isnan(im->gdes[i].p_data[ii-1])
                  && ! isnan(im->gdes[i].p_data[ii])){
               if (node == NULL){
-                node = gfx_new_line(canvas,
+                node = gfx_new_line(im->canvas,
                                     ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]),
                                     ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]),
                                     im->gdes[i].linewidth,
@@ -2242,7 +2239,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
                   ybase =  ytr(im,areazero);
                 }
                 area_start = ii-1;
-                node = gfx_new_area(canvas,
+                node = gfx_new_area(im->canvas,
                                     ii-1+im->xorigin,ybase,
                                     ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]),
                                     ii+im->xorigin,ytr(im,im->gdes[i].p_data[ii]),
@@ -2288,7 +2285,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
        im->gdes[i].yrule = im->gdes[im->gdes[i].vidx].vf.val;
      
       if (finite(im->gdes[i].yrule)) { /* even the fetched var can be NaN */
-       pie_part(canvas,im->gdes[i].col,
+       pie_part(im,im->gdes[i].col,
                im->pie_x,im->pie_y,im->piesize*0.4,
                M_PI*2.0*PieStart/100.0,
                M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0);
@@ -2302,7 +2299,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
     im->draw_y_grid=0;
   }
   /* grid_paint also does the text */
-  grid_paint(im,canvas);
+  grid_paint(im);
   
   /* the RULES are the last thing to paint ... */
   for(i=0;i<im->gdes_c;i++){    
@@ -2314,7 +2311,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
       };
       if(im->gdes[i].yrule >= im->minval
          && im->gdes[i].yrule <= im->maxval)
-        gfx_new_line(canvas,
+        gfx_new_line(im->canvas,
                      im->xorigin,ytr(im,im->gdes[i].yrule),
                      im->xorigin+im->xsize,ytr(im,im->gdes[i].yrule),
                      1.0,im->gdes[i].col); 
@@ -2325,7 +2322,7 @@ graph_paint(image_desc_t *im, char ***calcpr)
       };
       if(im->gdes[i].xrule >= im->start
          && im->gdes[i].xrule <= im->end)
-        gfx_new_line(canvas,
+        gfx_new_line(im->canvas,
                      xtr(im,im->gdes[i].xrule),im->yorigin,
                      xtr(im,im->gdes[i].xrule),im->yorigin-im->ysize,
                      1.0,im->gdes[i].col); 
@@ -2349,15 +2346,9 @@ graph_paint(image_desc_t *im, char ***calcpr)
       return (-1);
     }
   }
-  switch (im->imgformat) {
-  case IF_PNG:
-    gfx_render_png (canvas,im->xgif,im->ygif,im->zoom,0x0,fo);
-    break;
-  }
+  gfx_render (im->canvas,im->xgif,im->ygif,0x0,fo);
   if (strcmp(im->graphfile,"-") != 0)
     fclose(fo);
-   
-  gfx_destroy(canvas);
   return 0;
 }
 
@@ -2485,7 +2476,7 @@ rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize)
            filename--;
        }
 
-       sprintf((*prdata)[0],im.imginfo,filename,(long)(im.zoom*im.xgif),(long)(im.zoom*im.ygif));
+       sprintf((*prdata)[0],im.imginfo,filename,(long)(im.canvas->zoom*im.xgif),(long)(im.canvas->zoom*im.ygif));
     }
     im_free(&im);
     return 0;
@@ -2506,7 +2497,6 @@ rrd_graph_init(image_desc_t *im)
     im->title[0] = '\0';
     im->minval = DNAN;
     im->maxval = DNAN;    
-    im->interlaced = 0;
     im->unitsexponent= 9999;
     im->extra_flags= 0;
     im->rigid = 0;
@@ -2520,8 +2510,7 @@ rrd_graph_init(image_desc_t *im)
     im->prt_c = 0;
     im->gdes_c = 0;
     im->gdes = NULL;
-    im->zoom = 1.0;
-    im->imgformat = IF_PNG; /* we default to PNG output */
+    im->canvas = gfx_new_canvas();
 
     for(i=0;i<DIM(graph_col);i++)
         im->graph_col[i]=graph_col[i];
@@ -2709,7 +2698,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
            im->ysize = long_tmp;
            break;
        case 'i':
-           im->interlaced = 1;
+           im->canvas->interlaced = 1;
            break;
        case 'r':
            im->rigid = 1;
@@ -2718,7 +2707,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
            im->imginfo = optarg;
            break;
        case 'a':
-           if((im->imgformat = if_conv(optarg)) == -1) {
+           if((im->canvas->imgformat = if_conv(optarg)) == -1) {
                rrd_set_error("unsupported graphics format '%s'",optarg);
                return;
            }
@@ -2733,7 +2722,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
            break;
         case 'c':
             if(sscanf(optarg,
-                      "%10[A-Z]#%8x",
+                      "%10[A-Z]#%8lx",
                       col_nam,&color) == 2){
                 int ci;
                 if((ci=grc_conv(col_nam)) != -1){
@@ -2743,7 +2732,7 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
                 }
             } else {
                 rrd_set_error("invalid color def format");
-                return -1;
+                return;
             }
             break;        
         case 'n':{
@@ -2788,8 +2777,8 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
            break;          
        }
         case 'm':
-           im->zoom= atof(optarg);
-           if (im->zoom <= 0.0) {
+           im->canvas->zoom = atof(optarg);
+           if (im->canvas->zoom <= 0.0) {
                rrd_set_error("zoom factor must be > 0");
                return;
            }
@@ -3100,12 +3089,12 @@ rrd_graph_color(image_desc_t *im, char *var, char *err, int optional)
 
        switch (n) {
            case 7:
-               sscanf(color,"#%6x%n",&col,&n);
+               sscanf(color,"#%6lx%n",&col,&n);
                 col = (col << 8) + 0xff /* shift left by 8 */;
                if (n!=7) rrd_set_error("Color problem in %s",err);
                break;
            case 9:
-               sscanf(color,"#%8x%n",&col,&n);
+               sscanf(color,"#%8lx%n",&col,&n);
                if (n==9) break;
            default:
                rrd_set_error("Color problem in %s",err);
index 8fb96d6..3abb154 100644 (file)
@@ -25,8 +25,6 @@ enum gf_en {GF_PRINT=0,GF_GPRINT,GF_COMMENT,GF_HRULE,GF_VRULE,GF_LINE,
            GF_DEF, GF_CDEF, GF_VDEF,
            GF_PART};
 
-enum if_en {IF_PNG=0,IF_SVG};
-
 enum vdef_op_en {
                 VDEF_MAXIMUM   /* like the MAX in (G)PRINT */
                ,VDEF_MINIMUM   /* like the MIN in (G)PRINT */
@@ -119,7 +117,6 @@ typedef struct image_desc_t {
 
     char           graphfile[MAXPATH]; /* filename for graphic */
     long           xsize,ysize,piesize;    /* graph area size in pixels */
-    double         zoom;           /* zoom for graph */
     gfx_color_t    graph_col[__GRC_END__]; /* real colors for the graph */   
     text_prop_t    text_prop[TEXT_PROP_LAST]; /* text properties */
     char           ylegend[200];   /* legend along the yaxis */
@@ -142,14 +139,12 @@ typedef struct image_desc_t {
     int            lazy;           /* only update the gif if there is reasonable
                                      probablility that the existing one is out of date */
     int            logarithmic;    /* scale the yaxis logarithmic */
-    enum if_en     imgformat;      /* image format */
     
     /* status information */
            
     long           xorigin,yorigin;/* where is (0,0) of the graph */
     long           pie_x,pie_y;    /* where is the centerpoint */
     long           xgif,ygif;      /* total size of the gif */
-    int            interlaced;     /* will the graph be interlaced? */
     double         magfact;        /* numerical magnitude*/
     long         base;            /* 1000 or 1024 depending on what we graph */
     char           symbol;         /* magnitude symbol for y-axis */
@@ -160,14 +155,14 @@ typedef struct image_desc_t {
     long  prt_c;                  /* number of print elements */
     long  gdes_c;                  /* number of graphics elements */
     graph_desc_t   *gdes;          /* points to an array of graph elements */
-
+    gfx_canvas_t   *canvas;        /* graphics library */
 } image_desc_t;
 
 /* Prototypes */
 int xtr(image_desc_t *,time_t);
 int ytr(image_desc_t *, double);
 enum gf_en gf_conv(char *);
-enum if_en if_conv(char *);
+enum gfx_if_en if_conv(char *);
 enum tmt_en tmt_conv(char *);
 enum grc_en grc_conv(char *);
 enum grc_en text_prop_conv(char *);
@@ -186,14 +181,14 @@ time_t find_first_time( time_t,  enum tmt_en,  long);
 time_t find_next_time( time_t,  enum tmt_en,  long);
 int print_calc(image_desc_t *, char ***);
 int leg_place(image_desc_t *);
-int horizontal_grid(gfx_canvas_t *,image_desc_t *);
-int horizontal_log_grid(gfx_canvas_t *, image_desc_t *);
-void vertical_grid(gfx_canvas_t *, image_desc_t *);
-void axis_paint( image_desc_t *, gfx_canvas_t *);
-void grid_paint( image_desc_t *, gfx_canvas_t *);
+int horizontal_grid(image_desc_t *);
+int horizontal_log_grid(image_desc_t *);
+void vertical_grid(image_desc_t *);
+void axis_paint(image_desc_t *);
+void grid_paint(image_desc_t *);
 int lazy_check(image_desc_t *);
 int graph_paint(image_desc_t *, char ***);
-void pie_part(gfx_canvas_t *, gfx_color_t, double, double, double, double, double);
+void pie_part(image_desc_t *, gfx_color_t, double, double, double, double, double);
 int gdes_alloc(image_desc_t *);
 int scan_for_col(char *, int, char *);
 int rrd_graph(int, char **, char ***, int *, int *);