#include #include #include #include #include #include "BVGTypes.h" #include "raylib.h" #include "extString.h" void BVGDrawRectangle(BVGRectangle *rectangle) { if (rectangle->fill) { DrawRectangleRec(rectangle->rayrectangle, rectangle->color); } else { DrawRectangleLinesEx(rectangle->rayrectangle, rectangle->lineThickness, rectangle->color); } return; } void BVGDrawRoundedRectangle(BVGRoundedRectangle *rectangle) { if (rectangle->rectangle.fill) { DrawRectangleRounded(rectangle->rectangle.rayrectangle, rectangle->roundness, rectangle->segments, rectangle->rectangle.color); } else { DrawRectangleRoundedLines(rectangle->rectangle.rayrectangle, rectangle->roundness, rectangle->segments, rectangle->rectangle.lineThickness, rectangle->rectangle.color); } return; } void BVGDrawCircle(BVGCircle *circle) { Vector2 center = {circle->centerX, circle->centerY}; if (circle->drawSector) { DrawCircleSector(center, circle->radius, circle->startAngle, circle->endAngle, circle->segments, circle->color); } else { DrawCircle(circle->centerX, circle->centerY, circle->radius, circle->color); } return; } void BVGDrawRing(BVGRing *ring) { Vector2 center = {ring->centerX, ring->centerY}; DrawRing(center, ring->inRadius, ring->outRadius, ring->startAngle, ring->endAngle, ring->segmets, ring->color); } void BVGDrawEllipse(BVGEllipse *ellipse) { if (ellipse->fill) { DrawEllipse(ellipse->centerX, ellipse->centerY, ellipse->horizontalRadius, ellipse->verticalRadius, ellipse->color); } else { DrawEllipseLines(ellipse->centerX, ellipse->centerY, ellipse->horizontalRadius, ellipse->verticalRadius, ellipse->color); } return; } void BVGDrawTriangle(BVGTriangle *triangle) { if (triangle->fill) { DrawTriangle(triangle->corner1, triangle->corner2, triangle->corner3, triangle->color); } else { DrawTriangleLines(triangle->corner1, triangle->corner2, triangle->corner3, triangle->color); } return; } void BVGDrawText(BVGText *text) { DrawText(text->text, text->x, text->y, text->fontSize, text->color); return; } // reads a given file FILE *readFile(char *path) { FILE *fp = fopen (path, "r"); if (fp == NULL) { perror ("Failed to open file!"); exit(1); } return fp; } /* Converts a multiline function call into a single line call */ char *multiToSingle(char *s) { char *midresult; char *notab; char *result; midresult = replaceStr(s, "\n", ""); notab = replaceStr(midresult, "\t", ""); result = replaceStr(midresult, ", ", ","); free(midresult); free(notab); return result; } /* Collects all arguments from a function call arguments are seperated with a , */ void collectArgs(char *res[], char *call, int n) { char **arg; char *args[n]; for (arg = args; (*arg = strsep(&call, ",")) != NULL;) if (**arg != '\0') if (++arg >= &args[n]) break; memcpy(res, args, sizeof(args)); } /* Order the arguments in the order specified with knownArgs the res array contains only the values of each argument */ void orderArgs(char *res[], char *argv[], int n, char *knownArgs[]) { if (argv == NULL || knownArgs == NULL) exit(1); for(int i=0; ir=r; clr->g=g; clr->b=b; clr->a=255; } else { sscanf(hex, "%02x%02x%02x%02x", &r, &g, &b, &a); clr->r=r; clr->g=g; clr->b=b; clr->a=a; } return clr; } /* Converts a given char pointer to a corresponding boolean value expects the char to only contain true/false without any whitespace or similiar case is ignored If no match is found, true is returned by default */ bool parseBoolValue(char *value) { char *valueLower = strdup(strlwr(value)); if (strcmp(valueLower, "false") == 0) { free(valueLower); return false; } else { free(valueLower); return true; } } BVGIMG *BVGParseIMG(char *argv[2]) { BVGIMG *result = malloc(sizeof(BVGIMG)); size_t argN = 2; char *args[argN]; char *knownArgs[2] = {"width", "height"}; orderArgs(args, argv, argN, knownArgs); int width, height; sscanf(args[0], "%d", &width); sscanf(args[1], "%d", &height); result->width=width; result->height=height; return result; } /* Creates a BVGRectangle based on a BVG function call */ BVGRectangle *BVGParseRectangle(char *argv[7]) { BVGRectangle *result = malloc(sizeof(BVGRectangle)); Rectangle *rectangle = malloc(sizeof(Rectangle)); size_t argN = 7; char *args[argN]; char *knownArgs[7] = {"x", "y", "width", "height", "color", "fill", "thickness"}; orderArgs(args, argv, argN, knownArgs); printf("119 Parsing...%s \n", args[0]); int x, y, width, height, r, g, b, a; float thickness = 1.0; bool fill = true; sscanf(args[0], "%d", &x); sscanf(args[1], "%d", &y); sscanf(args[2], "%d", &width); sscanf(args[3], "%d", &height); args[4] = args[4]+2; args[4][strlen(args[4])-1] = '\0'; Color *clr = parseColorFromHex(args[4]); sscanf(args[6], "%fd", &thickness); fill = parseBoolValue(args[5]); printf("X: %d, Y: %d\n", x, y); printf("Width: %d, Height: %d\n", width, height); printf("Color: %d, %d, %d\n", r, g, b); printf("Fill: %d, Thickness: %f\n", fill, thickness); rectangle->x=x; rectangle->y=y; rectangle->height=height; rectangle->width=width; result->rayrectangle=*rectangle; result->color=*clr; result->fill=fill; result->lineThickness=thickness; free(clr); free(rectangle); return result; } /* Creates a BVGRoundedrectangle based on a BVG function call */ BVGRoundedRectangle *BVGParseRoundedRectangle(char *argv[9]) { BVGRoundedRectangle *result = malloc(sizeof(BVGRoundedRectangle)); BVGRectangle *bvgrectangle = malloc(sizeof(BVGRectangle)); Rectangle *rectangle = malloc(sizeof(Rectangle)); size_t argN = 9; char *args[argN]; char *knownArgs[9] = {"x", "y", "width", "height", "color", "fill", "thickness", "roundness", "segments"}; orderArgs(args, argv, argN, knownArgs); bvgrectangle = BVGParseRectangle(argv); result->rectangle = *bvgrectangle; float roundness; int segments; sscanf(args[7], "%fd", &roundness); sscanf(args[8], "%d", &segments); printf("Roundness: %fd, Segments: %d\n", roundness, segments); result->roundness = roundness; result->segments = segments; return result; } BVGCircle *BVGParseCircle(char *argv[4]) { BVGCircle *result = malloc(sizeof(BVGCircle)); size_t argN = 4; char *args[argN]; char *knownArgs[4] = {"x", "y", "radius", "color"}; orderArgs(args, argv, argN, knownArgs); int x, y; float radius; Color *clr; sscanf(args[0], "%d", &x); sscanf(args[1], "%d", &y); sscanf(args[2], "%fd", &radius); args[3] = args[3]+2; args[3][strlen(args[3])-1] = '\0'; clr = parseColorFromHex(args[3]); printf("X: %d, Y: %d\n", x, y); printf("radius: %f, color: %s\n", radius, args[3]); result->drawSector=false; result->centerX=x; result->centerY=y; result->color=*clr; result->radius=radius; free(clr); return result; } BVGCircle *BVGParseCircleSegment(char *argv[7]) { BVGCircle *result = malloc(sizeof(BVGCircle)); size_t argN = 7; char *args[argN]; char *knownArgs[7] = {"x", "y", "radius", "color", "startangle", "endangle", "segments"}; orderArgs(args, argv, argN, knownArgs); int x, y, segments; float radius, startAngle, endAngle; Color *clr; sscanf(args[0], "%d", &x); sscanf(args[1], "%d", &y); sscanf(args[2], "%fd", &radius); sscanf(args[4], "%fd", &startAngle); sscanf(args[5], "%fd", &endAngle); sscanf(args[6], "%d", &segments); args[3] = args[3]+2; args[3][strlen(args[3])-1] = '\0'; clr = parseColorFromHex(args[3]); printf("X: %d, Y: %d\n", x, y); printf("radius: %f, color: %s\n", radius, args[3]); result->drawSector=true; result->centerX=x; result->centerY=y; result->color=*clr; result->radius=radius; result->segments=segments; result->startAngle=startAngle; result->endAngle=endAngle; free(clr); return result; } BVGRing *BVGParseRing(char *argv[8]) { BVGRing *result = malloc(sizeof(BVGRing)); size_t argN = 8; char *args[argN]; char *knownArgs[8] = {"x", "y", "innerradius", "outerradius", "startangle", "endangle", "segments", "color"}; orderArgs(args, argv, argN, knownArgs); int x, y, segments; float innerRadius, outerRadius, startAngle, endAngle; Color *clr; sscanf(args[0], "%d", &x); sscanf(args[1], "%d", &y); sscanf(args[2], "%f", &innerRadius); sscanf(args[3], "%f", &outerRadius); sscanf(args[4], "%f", &startAngle); sscanf(args[5], "%f", &endAngle); sscanf(args[6], "%d", &segments); args[7] = args[7]+2; args[7][strlen(args[7])-1] = '\0'; clr = parseColorFromHex(args[7]); result->centerX=x; result->centerY=y; result->inRadius=innerRadius; result->outRadius=outerRadius; result->startAngle=startAngle; result->endAngle=endAngle; result->segmets=segments; result->color=*clr; free(clr); return result; } BVGEllipse *BVGParseEllipse(char *argv[6]) { BVGEllipse *result = malloc(sizeof(BVGEllipse)); size_t argN = 6; char *args[argN]; char *knownArgs[6] = {"x", "y", "horizontalradius", "verticalradius", "fill", "color"}; orderArgs(args, argv, argN, knownArgs); int x, y; float horizontalRadius, verticalRadius; bool fill; Color *clr; sscanf(args[0], "%d", &x); sscanf(args[1], "%d", &y); sscanf(args[2], "%f", &horizontalRadius); sscanf(args[3], "%f", &verticalRadius); fill = parseBoolValue(args[4]); args[5] = args[5]+2; args[5][strlen(args[5])-1] = '\0'; clr = parseColorFromHex(args[5]); printf("X: %d, Y: %d", x, y); printf("hRad: %f, vRad: %f", horizontalRadius, verticalRadius); printf("fill: %d, Color: %s", fill, args[5]); result->centerX=x; result->centerY=y; result->horizontalRadius=horizontalRadius; result->verticalRadius=verticalRadius; result->fill=fill; result->color=*clr; free(clr); return result; } BVGTriangle *BVGParseTriangle(char *argv[8]) { BVGTriangle *result = malloc(sizeof(BVGTriangle)); size_t argN = 8; char *args[argN]; char *knownArgs[8] = {"x1", "y1", "x2", "y2", "x3", "y3", "fill", "color"}; orderArgs(args, argv, argN, knownArgs); int x1, x2, x3; int y1, y2, y3; bool fill; Color *clr; sscanf(args[0], "%d", &x1); sscanf(args[1], "%d", &y1); sscanf(args[2], "%d", &x2); sscanf(args[3], "%d", &y2); sscanf(args[4], "%d", &x3); sscanf(args[5], "%d", &y3); fill = parseBoolValue(args[6]); args[7] = args[7]+2; args[7][strlen(args[7])-1] = '\0'; clr = parseColorFromHex(args[7]); result->corner1 = (Vector2){x1, y1}; result->corner2 = (Vector2){x2, y2}; result->corner3 = (Vector2){x3, y3}; result->fill = fill; result->color = *clr; free(clr); return result; } BVGText *BVGParseText(char *argv[5]) { BVGText *result = malloc(sizeof(BVGText)); size_t argN = 5; char *args[argN]; char *knownArgs[5] = {"text", "x", "y", "size", "color"}; orderArgs(args, argv, argN, knownArgs); args[0] = args[0]+1; args[0][strlen(args[0])-1] = '\0'; char *text = args[0]; int x, y, size; Color *clr; sscanf(args[1], "%d", &x); sscanf(args[2], "%d", &y); sscanf(args[3], "%d", &size); args[4] = args[4]+2; args[4][strlen(args[4])-1] = '\0'; printf("Text: %s\n", text); printf("X: %d, Y: %d\n", x, y); printf("Size: %d, Color: %s\n", size, args[4]); clr = parseColorFromHex(args[4]); result->text=text; result->x=x; result->y=y; result->fontSize=size; result->color=*clr; free(clr); return result; } /* Takes a BVG function call and calls the according C function */ void matchFunctionCall(char *call) { printf("Matching %s\n", call); char *funcCall = strdup(call); char *funcName = strsep(&funcCall, "("); char *function = trim(strlwr(funcName)); free(funcName); printf("Got function %s\n", function); call[strlen(call)-1]='\0'; if (strcmp(function, "rectangle") == 0) { char *argv[7]; call = call+strlen("rectangle ("); collectArgs(argv, call, 7); BVGRectangle *shape = BVGParseRectangle(argv); BVGDrawRectangle(shape); free(shape); } else if (strcmp(function, "roundedrectangle") == 0) { char *argv[9]; call = call+strlen("roundedrectangle ("); collectArgs(argv, call, 9); BVGRoundedRectangle *shape = BVGParseRoundedRectangle(argv); BVGDrawRoundedRectangle(shape); free(shape); } else if (strcmp(function, "circle") == 0) { char *argv[4]; call = call+strlen("circle ("); collectArgs(argv, call, 4); BVGCircle *shape = BVGParseCircle(argv); BVGDrawCircle(shape); free(shape); } else if (strcmp(function, "circlesegment") == 0) { char *argv[7]; call = call+strlen("circlesegment ("); collectArgs(argv, call, 7); BVGCircle *shape = BVGParseCircleSegment(argv); BVGDrawCircle(shape); free(shape); } else if (strcmp(function, "ring") == 0) { char *argv[8]; call = call+strlen("ring ("); collectArgs(argv, call, 8); BVGRing *shape = BVGParseRing(argv); BVGDrawRing(shape); free(shape); } else if (strcmp(function, "ellipse") == 0) { char *argv[6]; call = call+strlen("ellipse ("); collectArgs(argv, call, 6); BVGEllipse *shape = BVGParseEllipse(argv); BVGDrawEllipse(shape); free(shape); } else if (strcmp(function, "triangle") == 0) { char *argv[8]; call = call+strlen("triangle ("); collectArgs(argv, call, 8); BVGTriangle *shape = BVGParseTriangle(argv); BVGDrawTriangle(shape); free(shape); } else if (strcmp(function, "text") == 0) { char *argv[5]; call = call+strlen("text ("); collectArgs(argv, call, 5); BVGText *shape = BVGParseText(argv); BVGDrawText(shape); free(shape); } free(function); return; }