btwotch    

, Deutschland · männlich · registriert seit 2008 · heute zuletzt online


mailto, against spam!

Simple svg writing library

Computer ·

Features:

  • circle
  • line
  • color
  • opacity
  • animation

Code:

    1 #include <stdio.h>
    2 #include <string.h>
    3 #include <libxml/encoding.h>
    4 #include <libxml/xmlwriter.h>
    5 #include <libxml/xmlIO.h>
    6 
    7 #include "svg.h"
    8 
    9 xmlOutputWriteCallback iowrite(void *context, const char *buf, unsigned int
   10                                len)
   11 {
   12   FILE *fp = (FILE*)context;
   13   fprintf(fp, "%.*s\n", len, buf);
   14 
   15   return len;
   16 }
   17 
   18 xmlOutputCloseCallback ioclose(void *context)
   19 {
   20   FILE *fp = (FILE*)context;
   21   fclose(fp);
   22 
   23   return 0;
   24 }
   25 
   26 struct svg_ctx* svg_surface(char *filename, int width, int height)
   27 {
   28   char buf[20];
   29   FILE *fp;
   30   struct svg_ctx* ret;
   31   xmlOutputBufferPtr xobp;
   32   xmlTextWriterPtr xtwp;
   33 
   34   fp = fopen(filename, "w");
   35   if (fp == NULL)
   36     {
   37       fprintf(stderr, "could not open %s for writing\n", filename);
   38       exit(-1);
   39     }
   40 
   41   xobp = xmlOutputBufferCreateIO((xmlOutputWriteCallback)iowrite, (
   42          xmlOutputCloseCallback)ioclose, fp, NULL);
   43   xtwp = xmlNewTextWriter(xobp);
   44   xmlTextWriterSetIndent(xtwp, 1);
   45 
   46   xmlTextWriterStartDocument(xtwp, "1.0", "UTF-8", NULL);
   47   xmlTextWriterStartDTD(xtwp, (xmlChar*)"svg" , (xmlChar*)"-//W3C//DTD SVG
   48                         1.1//EN", (xmlChar*)"http://www.w3.
   49                         org/Graphics/SVG/1.1/DTD/svg11.dtd");
   50   xmlTextWriterEndDTD(xtwp);
   51 
   52 
   53   xmlTextWriterStartElement(xtwp, (xmlChar*)"svg");
   54   xmlTextWriterWriteAttribute(xtwp, (xmlChar*)"xmlns", (xmlChar*)"http:
   55                               //www.w3.org/2000/svg");
   56   xmlTextWriterWriteAttribute(xtwp, (xmlChar*)"version", (xmlChar*)"1.1");
   57   xmlTextWriterWriteAttribute(xtwp, (xmlChar*)"baseProfile", (xmlChar*)
   58                               "full");
   59   snprintf(buf, sizeof(buf)-1, "%dpx", width);
   60   xmlTextWriterWriteAttribute(xtwp, (xmlChar*)"width", (xmlChar*)buf);
   61   snprintf(buf, sizeof(buf)-1, "%dpx", height);
   62   xmlTextWriterWriteAttribute(xtwp, (xmlChar*)"height", (xmlChar*)buf);
   63 
   64   ret = malloc(sizeof(struct svg_ctx));
   65   ret->xtwp = xtwp;
   66   ret->fp = fp;
   67 
   68   return ret;
   69 }
   70 
   71 void svg_appearance_attributes(struct svg_ctx *sc, struct svg_appearance
   72                                *sa)
   73 {
   74   char buf[20];
   75 
   76   snprintf(buf, sizeof(buf)-1, "#%02x%02x%02x", sa->fill_color[0], sa->
   77            fill_color[1], sa->fill_color[2]);
   78   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"fill", (xmlChar*)buf);
   79   snprintf(buf, sizeof(buf)-1, "#%02x%02x%02x", sa->stroke_color[0], sa->
   80            stroke_color[1], sa->stroke_color[2]);
   81   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"stroke", (xmlChar*)buf);
   82   snprintf(buf, sizeof(buf)-1, "%f", sa->opacity);
   83   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"fill-opacity", (xmlChar*)
   84                               buf);
   85   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"stroke-opacity", (
   86                               xmlChar*)buf);
   87   snprintf(buf, sizeof(buf)-1, "%d", sa->stroke_width);
   88   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"stroke-width", (xmlChar*)
   89                               buf);
   90 }
   91 
   92 void svg_animate(struct svg_ctx *sc, char *attribute, float begin, float
   93                  duration, char *from, char *to)
   94 {
   95   char buf[20];
   96 
   97   xmlTextWriterStartElement(sc->xtwp, (xmlChar*)"animate");
   98   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"attributeName", (
   99                               xmlChar*)attribute);
  100   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"fill", (xmlChar*)
  101                               "freeze");
  102   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"attributeType", (
  103                               xmlChar*)"XML");
  104   snprintf(buf, sizeof(buf)-1, "%f", begin);
  105   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"begin", (xmlChar*)buf);
  106   snprintf(buf, sizeof(buf)-1, "%f", duration);
  107   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"dur", (xmlChar*)buf);
  108   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"from", (xmlChar*)from);
  109   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"to", (xmlChar*)to);
  110 
  111 
  112   xmlTextWriterEndElement(sc->xtwp);
  113 }
  114 
  115 void svg_animate_float(struct svg_ctx *sc, char *attribute, float begin,
  116                        float duration, float from, float to)
  117 {
  118   char from_c[20], to_c[20];
  119 
  120   snprintf(from_c, sizeof(from_c)-1, "%f", from);
  121   snprintf(to_c, sizeof(to_c)-1, "%f", to);
  122 
  123   svg_animate(sc, attribute, begin, duration, from_c, to_c);
  124 }
  125 
  126 void svg_pos_animate(struct svg_ctx *sc, struct svg_pos *sp, struct svg_pos
  127                      *spn, char *svg_x, char *svg_y, float begin, float
  128                      duration)
  129 {
  130   if (sp->x != spn->x)
  131     svg_animate_float(sc, svg_x, begin, duration, sp->x, spn->x);
  132   if (sp->y != spn->y)
  133     svg_animate_float(sc, svg_y, begin, duration, sp->y, spn->y);
  134 }
  135 
  136 void svg_appearance_animate(struct svg_ctx *sc, struct svg_appearance *sa,
  137                             struct svg_appearance *san, float begin, float
  138                             duration)
  139 {
  140   char from_c[20], to_c[20];
  141 
  142   if (sa->opacity != san->opacity)
  143     {
  144       svg_animate_float(sc, "fill-opacity", begin, duration, sa->opacity,
  145                         san->opacity);
  146       svg_animate_float(sc, "stroke-opacity", begin, duration, sa->opacity,
  147                         san->opacity);
  148     }
  149 
  150   if (sa->fill_color[0] != san->fill_color[0] ||
  151       sa->fill_color[1] != san->fill_color[1] ||
  152       sa->fill_color[2] != san->fill_color[2])
  153     {
  154       snprintf(from_c, sizeof(from_c)-1, "#%02x%02x%02x", sa->fill_color[0],
  155                sa->fill_color[1], sa->fill_color[2]);
  156       snprintf(to_c, sizeof(to_c)-1, "#%02x%02x%02x", san->fill_color[0],
  157                san->fill_color[1], san->fill_color[2]);
  158 
  159       svg_animate(sc, "fill", begin, duration, from_c, to_c);
  160     }
  161 
  162   if (sa->stroke_color[0] != san->stroke_color[0] ||
  163       sa->stroke_color[1] != san->stroke_color[1] ||
  164       sa->stroke_color[2] != san->stroke_color[2])
  165     {
  166       snprintf(from_c, sizeof(from_c)-1, "#%02x%02x%02x", sa->stroke_color[
  167                0], sa->stroke_color[1], sa->stroke_color[2]);
  168       snprintf(to_c, sizeof(to_c)-1, "#%02x%02x%02x", san->stroke_color[0],
  169                san->stroke_color[1], san->stroke_color[2]);
  170 
  171       svg_animate(sc, "stroke", begin, duration, from_c, to_c);
  172     }
  173 
  174   if (sa->stroke_width != san->stroke_width)
  175     {
  176       snprintf(from_c, sizeof(from_c)-1, "%d", sa->stroke_width);
  177       snprintf(to_c, sizeof(to_c)-1, "%d", san->stroke_width);
  178 
  179       svg_animate(sc, "stroke-width", begin, duration, from_c, to_c);
  180     }
  181 }
  182 
  183 void svg_circle(struct svg_ctx *sc, struct svg_circle *sci)
  184 {
  185   char buf[20];
  186   struct svg_circle *sci_first = sci;
  187 
  188   xmlTextWriterStartElement(sc->xtwp, (xmlChar*)"circle");
  189   snprintf(buf, sizeof(buf)-1, "%f", sci->pos.x);
  190   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"cx", (xmlChar*)buf);
  191   snprintf(buf, sizeof(buf)-1, "%f", sci->pos.y);
  192   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"cy", (xmlChar*)buf);
  193   snprintf(buf, sizeof(buf)-1, "%f", sci->r);
  194   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"r", (xmlChar*)buf);
  195 
  196   svg_appearance_attributes(sc, &sci->sa);
  197 
  198   // now animation
  199   while (sci->next != NULL && sci->next != sci_first)
  200     {
  201       svg_pos_animate(sc, &sci->pos, &sci->next->pos, "cx", "cy", sci->
  202                       begin, sci->duration);
  203       svg_appearance_animate(sc, &sci->sa, &sci->next->sa, sci->begin, sci->
  204                              duration);
  205       if (sci->next->r != sci->r)
  206         svg_animate_float(sc, "r", sci->begin, sci->duration, sci->r, sci->
  207                           next->r);
  208 
  209       sci = sci->next;
  210     }
  211 
  212   xmlTextWriterEndElement(sc->xtwp);
  213 }
  214 
  215 void svg_line(struct svg_ctx *sc, struct svg_line *sl)
  216 {
  217   char buf[20];
  218   struct svg_line *sl_first;
  219 
  220   xmlTextWriterStartElement(sc->xtwp, (xmlChar*)"line");
  221   snprintf(buf, sizeof(buf)-1, "%f", sl->pos1.x);
  222   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"x1", (xmlChar*)buf);
  223   snprintf(buf, sizeof(buf)-1, "%f", sl->pos1.y);
  224   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"y1", (xmlChar*)buf);
  225   snprintf(buf, sizeof(buf)-1, "%f", sl->pos2.x);
  226   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"x2", (xmlChar*)buf);
  227   snprintf(buf, sizeof(buf)-1, "%f", sl->pos2.y);
  228   xmlTextWriterWriteAttribute(sc->xtwp, (xmlChar*)"y2", (xmlChar*)buf);
  229 
  230   svg_appearance_attributes(sc, &sl->sa);
  231 
  232   // now animation
  233   while (sl->next != NULL && sl->next != sl_first)
  234     {
  235       svg_pos_animate(sc, &sl->pos1, &sl->next->pos1, "x1", "y1", sl->begin,
  236                       sl->duration);
  237       svg_pos_animate(sc, &sl->pos2, &sl->next->pos2, "x2", "y2", sl->begin,
  238                       sl->duration);
  239       svg_appearance_animate(sc, &sl->sa, &sl->next->sa, sl->begin, sl->
  240                              duration);
  241 
  242       sl = sl->next;
  243     }
  244 
  245   xmlTextWriterEndElement(sc->xtwp);
  246 }
  247 
  248 void svg_end(struct svg_ctx *sc)
  249 {
  250   xmlTextWriterEndElement(sc->xtwp);
  251   xmlFreeTextWriter(sc->xtwp);
  252 
  253   free(sc);
  254 }
  255 
  256 void svg_copy_appearance(struct svg_appearance *src, struct svg_appearance
  257                          *dest)
  258 {
  259   dest->opacity = src->opacity;
  260   dest->fill_color[0] = src->fill_color[0];
  261   dest->fill_color[1] = src->fill_color[1];
  262   dest->fill_color[2] = src->fill_color[2];
  263 
  264   dest->stroke_color[0] = src->stroke_color[0];
  265   dest->stroke_color[1] = src->stroke_color[1];
  266   dest->stroke_color[2] = src->stroke_color[2];
  267 
  268   dest->stroke_width = src->stroke_width;
  269 }
  270 
  271 void svg_fill_default_appearance(struct svg_appearance *sa)
  272 {
  273   sa->fill_color[0] = 0;
  274   sa->fill_color[1] = 0xff;
  275   sa->fill_color[2] = 0;
  276 
  277   sa->stroke_color[0] = 0;
  278   sa->stroke_color[1] = 0;
  279   sa->stroke_color[2] = 0xff;
  280 
  281   sa->opacity = 0.5;
  282   sa->stroke_width = 1;
  283 }
  284 
  285 int main(int argc, char **argv)
  286 {
  287   struct svg_ctx *sc;
  288   struct svg_circle sci, scj;
  289   struct svg_line sl, sm;
  290 
  291   sc = svg_surface("test.svg", 400, 300);
  292   svg_fill_default_appearance(&sci.sa);
  293 
  294   sci.pos.x = 100;
  295   sci.pos.y = 100;
  296   sci.r = 50;
  297   sci.begin = 5;
  298   sci.duration = 10;
  299   sci.next = &scj;
  300   scj.pos.x = sci.pos.x+90;
  301   scj.pos.y = sci.pos.y+30;
  302   scj.r = sci.r+10;
  303   scj.next = NULL;
  304   svg_copy_appearance(&sci.sa, &scj.sa);
  305   scj.sa.opacity = 1;
  306   scj.sa.fill_color[0] = 0xff;
  307   scj.sa.stroke_color[0] = 0xff;
  308   svg_circle(sc, &sci);
  309 
  310   svg_copy_appearance(&sci.sa, &sl.sa);
  311   sl.pos1.x = 300;
  312   sl.pos1.y = 100;
  313   sl.pos2.x = 100;
  314   sl.pos2.y = 100;
  315 
  316   svg_copy_appearance(&sl.sa, &sm.sa);
  317   sm.pos1.x = sl.pos1.x;
  318   sm.pos1.y = sl.pos1.y;
  319   sm.pos2.x = sl.pos2.x+30;
  320   sm.pos2.y = sl.pos2.y;
  321   sm.sa.stroke_width = 5;
  322   sl.duration = 5;
  323 
  324   sl.sa.opacity = 0.5;
  325   sl.sa.stroke_width = 2;
  326   sl.next = &sm;
  327   svg_line(sc, &sl);
  328 
  329   svg_end(sc);
  330 
  331   return 0;
  332 }

Header file (svg.h):

    1 #ifndef _SVG_H
    2 #define _SVG_H
    3 struct svg_ctx
    4 {
    5   xmlTextWriterPtr xtwp;
    6   FILE *fp;
    7 };
    8 
    9 struct svg_pos
   10 {
   11   float x, y;
   12 };
   13 
   14 struct svg_appearance
   15 {
   16   float opacity;
   17   unsigned char fill_color[3];
   18   unsigned char stroke_color[3];
   19 
   20   unsigned int stroke_width;
   21 };
   22 
   23 struct svg_circle
   24 {
   25   struct svg_pos pos;
   26   float r;
   27 
   28   struct svg_appearance sa;
   29 
   30   //animation
   31   struct svg_circle *next;
   32   float begin, duration;
   33 };
   34 
   35 struct svg_line
   36 {
   37   struct svg_pos pos1;
   38   struct svg_pos pos2;
   39 
   40   struct svg_appearance sa;
   41 
   42   //animation
   43   float begin, duration;
   44   struct svg_line *next;
   45 };
   46 #endif

Compile:
gcc `xml2-config --cflags --libs` svg.c -o svg -Wall -g
Open with firefox or chromium

Letzte Änderung: 29. Januar 2012 09:41

Tags:  ·  ·  ·

Blog durchsuchen
(nur öffentliche Einträge)

Willst du auch bloggen?
Kostenlos bloggen bei Spin.de
Diese Seite ist eine auf spin.de gelagerte persönliche Homepage, deren Verantwortlichkeit beim Nutzer liegt.
spin.de ist eine große Online-Community mit Chat, Blogs, Foren, Online-Spielen und vielem mehr.
Deine eigene Homepage mit Blog und Gästebuch

Impressum · Datenschutz · Sitemap