]> granicus.if.org Git - graphviz/commitdiff
support for svg images in -Tsvg:svg
authorellson <devnull@localhost>
Wed, 26 Dec 2007 16:53:24 +0000 (16:53 +0000)
committerellson <devnull@localhost>
Wed, 26 Dec 2007 16:53:24 +0000 (16:53 +0000)
Patch from:  Alex Poylisher <sher@komkon.org>

lib/common/usershape.h
lib/gvc/gvusershape.c
plugin/core/gvloadimage_core.c

index 1cd77c88efb37e96e019f10eb45c6a661f512281..1c50eea65c1d973b507a44f306268220c75fd00e 100644 (file)
@@ -25,7 +25,7 @@ extern "C" {
 
     typedef enum { FT_NULL,
                FT_BMP, FT_GIF, FT_PNG, FT_JPEG,
-               FT_PDF, FT_PS, FT_EPS
+               FT_PDF, FT_PS, FT_EPS, FT_SVG
     } imagetype_t;
 
     typedef enum {
index e01da654ff4f70c586fc70fcbbcab89a00672b6e..9d359f9898d7e5b8781589eec2435ea0ccfa5c37 100644 (file)
@@ -48,6 +48,9 @@ typedef struct {
 #define PDF_MAGIC  "%PDF-"
 #define EPS_MAGIC  "\xC5\xD0\xD3\xC6"
 
+#define XML_MAGIC  "<?xml"
+#define SVG_MAGIC  "<svg"
+
 static knowntype_t knowntypes[] = {
     { PNG_MAGIC,  sizeof(PNG_MAGIC)-1,  FT_PNG,  "png",  },
     { PS_MAGIC,   sizeof(PS_MAGIC)-1,   FT_PS,   "ps",   },
@@ -61,8 +64,32 @@ static knowntype_t knowntypes[] = {
 static int imagetype (usershape_t *us)
 {
     char header[HDRLEN];
+    char line[200];
     int i;
 
+    int firstLine = 1;
+
+// check for SVG first
+
+    while (fgets(line, sizeof(line), us->f) != NULL) {
+
+               if (firstLine == 1) {
+                       if (!memcmp(line, XML_MAGIC, sizeof(XML_MAGIC)-1)) {
+                               firstLine = 0;
+                               continue;
+                       } else {
+                               break;
+                       }
+               }       
+
+               if (!memcmp(line, SVG_MAGIC, sizeof(SVG_MAGIC)-1)) {
+                       us->stringtype = "svg";
+                       return (us->type = FT_SVG);
+               }
+    }
+
+    rewind(us->f);
+
     if (us->f && fread(header, 1, HDRLEN, us->f) == HDRLEN) {
         for (i = 0; i < sizeof(knowntypes) / sizeof(knowntype_t); i++) {
            if (!memcmp (header, knowntypes[i].template, knowntypes[i].size)) {
@@ -71,6 +98,7 @@ static int imagetype (usershape_t *us)
            }
         }
     }
+
     us->stringtype = "(lib)";
     us->type = FT_NULL;
     return FT_NULL;
@@ -105,6 +133,63 @@ static boolean get_int_msb_first (FILE *f, unsigned int sz, unsigned int *val)
     return TRUE;
 }
 
+static void svg_size (usershape_t *us)
+{
+       unsigned int w, h;
+       float iw, ih;
+
+       char *token;
+    
+       char line[200];
+
+       int wFlag = 0;
+       int hFlag = 0;
+
+       us->dpi = POINTS_PER_INCH;
+
+       rewind(us->f);
+
+       while (fgets(line, sizeof(line), us->f) != NULL) {
+               if (!memcmp(line, SVG_MAGIC, sizeof(SVG_MAGIC)-1)) {
+                       break;
+               }
+       }
+
+       token = strtok(line, " ");
+
+       while (token != NULL) {
+               if (strncmp(token, "width", 5) == 0) {
+                       if (sscanf(token, "width=\"%fin\"", &iw) == 0 ) {
+                               sscanf(token, "width=\"%dpx\"", &w);
+                       } else {
+                               w = (int)(iw * POINTS_PER_INCH);
+                       }
+
+                       wFlag = 1;
+               }
+
+               if (strncmp(token, "height", 6) == 0) {
+                       if (sscanf(token, "height=\"%fin\"", &ih) == 0 ) {
+                               sscanf(token, "height=\"%dpx\"", &h);
+                       } else {
+                               h = (int)(ih * POINTS_PER_INCH);
+                       }
+
+                       hFlag = 1;
+               }
+
+
+               if (wFlag == 1 && hFlag == 1) {
+                       break;
+               }
+
+               token =  strtok(NULL, " ");
+       }
+
+       us->w = w;
+       us->h = h;
+}
+
 static void png_size (usershape_t *us)
 {
     unsigned int w, h;
@@ -317,6 +402,9 @@ static usershape_t *gvusershape_open (char *name)
            case FT_PS:
                ps_size(us);
                break;
+           case FT_SVG:
+               svg_size(us);
+               break;
            case FT_PDF:   /* no pdf_size code available */
            case FT_EPS:   /* no eps_size code available */
            default:
index 5ca4b1605273156731a58ffec35e087d067d028f..4b76b8b2a9e68a0f5ba56af86a3b1edb28b0e9fd 100644 (file)
@@ -39,7 +39,7 @@ typedef enum {
     FORMAT_PNG_XDOT, FORMAT_GIF_XDOT, FORMAT_JPEG_XDOT,
     FORMAT_PNG_FIG, FORMAT_GIF_FIG, FORMAT_JPEG_FIG,
     FORMAT_PNG_VRML, FORMAT_GIF_VRML, FORMAT_JPEG_VRML,
-    FORMAT_PS_PS, FORMAT_PSLIB_PS,
+    FORMAT_PS_PS, FORMAT_PSLIB_PS, FORMAT_SVG_SVG,
 } format_type;
 
 static void core_loadimage_svg(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
@@ -294,5 +294,6 @@ gvplugin_installed_t gvloadimage_core_types[] = {
     {FORMAT_JPEG_XDOT, "jpeg:xdot", 1, &engine_xdot, NULL},
     {FORMAT_JPEG_XDOT, "jpe:xdot", 1, &engine_xdot, NULL},
     {FORMAT_JPEG_XDOT, "jpg:xdot", 1, &engine_xdot, NULL},
+    {FORMAT_SVG_SVG, "svg:svg", 1, &engine_svg, NULL},
     {0, NULL, 0, NULL, NULL}
 };