#include #include #include #include #include #include /* * For original project details of this project go to http://www.codedrome.com/svg-library-in-c/ * * I'm adding some features, polyline, polygon, inline commenter, svg pixel-map... other geometries, and features intended for zellij design * To compile using this library: //gcc -g -Wall prog.c -o prog -lm * */ // -------------------------------------------------------- // STRUCT svg // -------------------------------------------------------- typedef struct svg{ char* svg; int height; int width; bool finalized; } svg; // -------------------------------------------------------- // FUNCTION PROTOTYPES // -------------------------------------------------------- //ok I just realized bruh did an obnoxious thing, and made all the shape functions take arguments in different patterns. //function( psvg, x,y, height, width, radius, fill, stroke, strokewidth ) //Ill fix that later, RN gonna make animation work. /*I too did an anoying thing and wrote animateRotate using the format of the former args patterns. * Using stdarg.h, functions require specifying the number of args for a function, these are as follows * * svg_ellipse: 8 * svg_polygon 8 * svg_text 8 * svg_line 7 * svg_rectangle 10 * * after which, args are passed to the animateRotate function * * Example animateRotate call: * svg_animateRotate( 8, svg_polygon, psvg, 100.0, 100.0, 50.0, 5, "blue", "green", 7, durration); * */ svg* svg_create(int width, int height); void svg_finalize(svg* psvg); void svg_print(svg* psvg); void svg_save(svg* psvg, char* filepath); void svg_free(svg* psvg); void svg_fill(svg* psvg, char* fill); void svg_circle(svg* psvg, char* stroke, int strokewidth, char* fill, int r, int cx, int cy); void svg_line(svg* psvg, char* stroke, int strokewidth, int x1, int y1, int x2, int y2); void svg_rectangle(svg* psvg, int width, int height, int x, int y, char* fill, char* stroke, int strokewidth, int radiusx, int radiusy); void svg_text(svg* psvg, int x, int y, char* fontfamily, int fontsize, char* fill, char* stroke, char* text); void svg_ellipse(svg* psvg, int cx, int cy, int rx, int ry, char* fill, char* stroke, int strokewidth); void svg_polygon(svg* psvg, double cx, double cy, float radius, int nsides, char* fill, char* stroke, int strokewidth ); //void svg_polyline(svg* psvg, int a[], char* stroke, int strokewidth); //comeback to this it was for a kinnect //void svg_starpolygon(svg* psvg, double cx, double cy, float radius, int npoints, char* fill, char* stroke, int strokewidth ); //void svg_gearpolygon(svg* psvg, double cx, double cy, float radius, int teeth, char* fill, char* stroke, int strokewidth ); //void svg_diamondpolygon(svg* psvg, double cx, double cy, float radius, char* fill, char* stroke, int strokewidth ); void svg_animateRotate(int num_args, ...); //take shape functions void svg_animateColor(int num_args, ...); // -------------------------------------------------------- // STATIC FUNCTION appendstringtosvg // -------------------------------------------------------- static void appendstringtosvg(svg* psvg, char* text){ int l = strlen(psvg->svg) + strlen(text) + 1; char* p = realloc(psvg->svg, l); if(p){ psvg->svg = p; } strcat(psvg->svg, text); } // -------------------------------------------------------- // STATIC FUNCTION appendnumbertosvg // -------------------------------------------------------- static void appendnumbertosvg(svg* psvg, int n){ char sn[16]; sprintf(sn, "%d", n); appendstringtosvg(psvg, sn); } // -------------------------------------------------------- // FUNCTION svg_create // -------------------------------------------------------- svg* svg_create(int width, int height){ svg* psvg = malloc(sizeof(svg)); if(psvg != NULL) { *psvg = (svg){.svg = NULL, .width = width, .height = height, .finalized = false}; psvg->svg = malloc(1); sprintf(psvg->svg, "%s", "\0"); appendstringtosvg(psvg, "\n"); return psvg; } else { return NULL; } } // -------------------------------------------------------- // FUNCTION svg_finalize // -------------------------------------------------------- void svg_finalize(svg* psvg){ appendstringtosvg(psvg, ""); psvg->finalized = true; } // -------------------------------------------------------- // FUNCTION svg_print // -------------------------------------------------------- void svg_print(svg* psvg){ printf("%s\n", psvg->svg); } // -------------------------------------------------------- // FUNCTION svg_save // -------------------------------------------------------- void svg_save(svg* psvg, char* filepath){ if(!psvg->finalized){ svg_finalize(psvg); } FILE* fp; fp = fopen(filepath, "w"); if(fp != NULL){ fwrite(psvg->svg, 1, strlen(psvg->svg), fp); fclose(fp); } } //---------------------------------------------------------------- // FUNCTION svg_free //---------------------------------------------------------------- void svg_free(svg* psvg){ free(psvg->svg); free(psvg); } //---------------------------------------------------------------- // FUNCTION svg_circle //---------------------------------------------------------------- void svg_circle(svg* psvg, char* stroke, int strokewidth, char* fill, int r, int cx, int cy){ appendstringtosvg(psvg, " \n"); } //---------------------------------------------------------------- // FUNCTION svg_line //---------------------------------------------------------------- void svg_line(svg* psvg, char* stroke, int strokewidth, int x1, int y1, int x2, int y2){ appendstringtosvg(psvg, " \n"); } //---------------------------------------------------------------- // FUNCTION svg_rectangle //---------------------------------------------------------------- void svg_rectangle(svg* psvg, int width, int height, int x, int y, char* fill, char* stroke, int strokewidth, int radiusx, int radiusy){ appendstringtosvg(psvg, " \n"); } // -------------------------------------------------------- // FUNCTION svg_fill // -------------------------------------------------------- void svg_fill(svg* psvg, char* Fill){ svg_rectangle(psvg, psvg->width, psvg->height, 0, 0, Fill, Fill, 0, 0, 0); } //---------------------------------------------------------------- // FUNCTION svg_text //---------------------------------------------------------------- void svg_text(svg* psvg, int x, int y, char* fontfamily, int fontsize, char* fill, char* stroke, char* text){ appendstringtosvg(psvg, " "); appendstringtosvg(psvg, text); appendstringtosvg(psvg, "\n"); } //---------------------------------------------------------------- // FUNCTION svg_ellipse //---------------------------------------------------------------- void svg_ellipse(svg* psvg, int cx, int cy, int rx, int ry, char* fill, char* stroke, int strokewidth){ appendstringtosvg(psvg, " \n"); } //--------------------------------------------------------- //FUNCTION svg_polyline: this function had been getting data from the kinect //--------------------------------------------------------- /* * void svg_polyline(svg* psvg, int a[], char* stroke, int strokewidth){ appendstringtosvg(psvg, " \n"); } */ //---------------------------------------------------------------- // FUNCTION svg_polygon //---------------------------------------------------------------- void svg_polygon(svg* psvg, double cx, double cy, float radius, int nsides, char* fill, char* stroke, int strokewidth ){ //cx,cy ==center point //put xi ,yi in an array float xi, yi=0.0; if (nsides<3){ printf("Error: Too Few Sides\n"); exit(0); } //start building the polygon: appendstringtosvg(psvg, " \n"); } //---------------------------------------------------------------- // FUNCTION svg_animate :: transform methods //---------------------------------------------------------------- /* * In SVG's animateTransform element, the type attribute specifies the type of transformation to be animated. The type attribute can take the following values: translate: Animates a translation transformation, which moves an element along the x and y axes. scale: Animates a scaling transformation, which changes the size of an element along the x and y axes. rotate: Animates a rotation transformation, which rotates an element around a specified point. skewX: Animates a skew transformation along the x-axis, which tilts an element horizontally. skewY: Animates a skew transformation along the y-axis, which tilts an element vertically. * */ //---------------------------------------------------------------- // FUNCTION svg_animateRotate //---------------------------------------------------------------- // Operator function that accepts variable arguments void svg_animateRotate(int num_args, ...) { va_list args; va_start(args, num_args); for (int i = 0; i < num_args; i++) { // Get the function pointer from the variable arguments void (*func)(svg*, ...); func = va_arg(args, void (*)(svg*, ...)); // Call the function with the remaining arguments if (func == svg_ellipse) { svg* psvg = va_arg(args, svg*); int cx = va_arg(args, int); int cy = va_arg(args, int); int rx = va_arg(args, int); int ry = va_arg(args, int); char* fill = va_arg(args, char*); char* stroke = va_arg(args, char*); int strokewidth = va_arg(args, int); int dur = va_arg(args,int); //maybe make that a float or double later appendstringtosvg(psvg, " \n\n"); svg_ellipse(psvg, cx, cy, rx, ry, fill, stroke, strokewidth); //write the shape appendstringtosvg(psvg, " \n \n\n"); } else if (func == svg_polygon) { //8 args svg* psvg = va_arg(args, svg*); double cx = va_arg(args, double); double cy = va_arg(args, double); float radius = va_arg(args, double); // Note: float is promoted to double in va_arg int nsides = va_arg(args, int); char* fill = va_arg(args, char*); char* stroke = va_arg(args, char*); int strokewidth = va_arg(args, int); int dur = va_arg(args,int); //maybe make that a float or double later appendstringtosvg(psvg, " \n\n"); svg_polygon(psvg, cx, cy, radius, nsides, fill, stroke, strokewidth); appendstringtosvg(psvg, " \n \n\n"); } else if (func == svg_text) { //This function doesn some BS related to groups. //void svg_text(svg* psvg, int x, int y, char* fontfamily, int fontsize, char* fill, char* stroke, char* text); svg* psvg = va_arg(args, svg*); int x = va_arg(args, int); int y = va_arg(args, int); char* fontfamily = va_arg(args, char*); // use system fonts int fontsize = va_arg(args, int); char* fill = va_arg(args, char*); char* stroke = va_arg(args, char*); char* text = va_arg(args, char*); int dur = va_arg(args,int); //durration of animation appendstringtosvg(psvg, " \n\n"); svg_text(psvg, x, y, fontfamily, fontsize, fill, stroke, text); appendstringtosvg(psvg, " \n\n\n"); } else if (func == svg_rectangle) { // svg_rectangle(psvg, width, height, x, y, fill, stroke, strokewidth, radiusx, radiusy); //all ints 10 args svg* psvg = va_arg(args, svg*); int width = va_arg(args, int); int height = va_arg(args, int); int x = va_arg(args, int); int y = va_arg(args, int); char* fill = va_arg(args, char*); char* stroke = va_arg(args, char*); int strokewidth = va_arg(args, int); int radiusx = va_arg(args, int); int radiusy = va_arg(args, int); int dur = va_arg(args,int); //durration of animation appendstringtosvg(psvg, " \n"); svg_rectangle(psvg, width, height, x, y, fill, stroke, strokewidth, radiusx, radiusy); appendstringtosvg(psvg, " \n\n\n"); } else if (func == svg_line) { //void svg_line(svg* psvg, char* stroke, int strokewidth, int x1, int y1, int x2, int y2); // svg_line(psvg, stroke, strokewidth, x1, y1, x2, y2); svg* psvg = va_arg(args, svg*); char* stroke = va_arg(args, char*); int strokewidth = va_arg(args, int); int x1 = va_arg(args, int); int y1 = va_arg(args, int); int x2 = va_arg(args, int); int y2 = va_arg(args, int); int dur = va_arg(args,int); //durration of animation appendstringtosvg(psvg, " \n"); svg_line(psvg, stroke, strokewidth, x1, y1, x2, y2); appendstringtosvg(psvg, " \n\n\n"); } }//end for loop va_end(args); }