CCCPaste
#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);
}