Browse Source

REVIEWED: `LoadImageSvg()`

Ray 1 year ago
parent
commit
d6f3891009
2 changed files with 65 additions and 72 deletions
  1. 1 2
      src/raylib.h
  2. 64 70
      src/rtextures.c

+ 1 - 2
src/raylib.h

@@ -1245,8 +1245,7 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
 // NOTE: These functions do not require GPU access
 RLAPI Image LoadImage(const char *fileName);                                                             // Load image from file into CPU memory (RAM)
 RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize);       // Load image from RAW file data
-RLAPI Image LoadImageSvg(const char *fileName, int width, int height);                                   // Load image from SVG file data with specified size
-RLAPI Image LoadImageSvgFromString(const char *string, int width, int height);                           // Load an image from a SVG string with custom size
+RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height);                           // Load image from SVG file data or string with specified size
 RLAPI Image LoadImageAnim(const char *fileName, int *frames);                                            // Load image sequence from file (frames appended to image.data)
 RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize);      // Load image from memory buffer, fileType refers to extension: i.e. '.png'
 RLAPI Image LoadImageFromTexture(Texture2D texture);                                                     // Load image from GPU texture data

+ 64 - 70
src/rtextures.c

@@ -318,67 +318,60 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
     return image;
 }
 
-// Load an image from SVG file data with a custom size
-Image LoadImageSvg(const char *fileName, int width, int height)
+// Load an image from a SVG file or string with custom size
+Image LoadImageSvg(const char *fileNameOrString, int width, int height)
 {
     Image image = { 0 };
-
-    unsigned int dataSize = 0;
-    unsigned char *string = LoadFileData(fileName, &dataSize);
-
-    if (string != NULL)
+    bool isSvgStringValid = false;
+    
+    // TODO: Validate fileName or string
+    if (fileNameOrString != NULL)
     {
-        image = LoadImageSvgFromString(string, width, height);
-        RL_FREE(string);
-    }
+        if (FileExists(fileNameOrString))
+        {
+            int dataSize = 0;
+            unsigned char *fileData = LoadFileData(fileNameOrString, &dataSize);
+            isSvgStringValid = true;
+        }
+        else
+        {
+            // TODO: Validate it's a valid SVG string
+            isSvgStringValid = true;
+        }
 
-    return image;
-}
+        if (isSvgStringValid != NULL)
+        {
+            struct NSVGimage *svgImage = nsvgParse(fileNameOrString, "px", 96.0f);
+            
+            unsigned char *img = RL_MALLOC(width*height*4);
 
-// Load an image from a SVG string with custom size
-Image LoadImageSvgFromString(const char *string, int width, int height)
-{
-    Image image = { 0 };
+            // Calculate scales for both the width and the height
+            const float scaleWidth = width/svgImage->width;
+            const float scaleHeight = height/svgImage->height;
 
-    if (string != NULL)
-    {
-        struct NSVGimage *svgImage = nsvgParse(string, "px", 96.0f);
+            // Set the largest of the 2 scales to be the scale to use
+            const float scale = (scaleHeight > scaleWidth)? scaleWidth : scaleHeight;
 
-        // Allocate memory for image
-        unsigned char *img = malloc(width*height*4);
+            int offsetX = 0;
+            int offsetY = 0;
 
-        // Calculate scales for both the width and the height
-        const float scaleWidth = width/svgImage->width;
-        const float scaleHeight = height/svgImage->height;
+            if (scaleHeight > scaleWidth) offsetY = (height - svgImage->height*scale) / 2;
+            else offsetX = (width - svgImage->width*scale) / 2;
 
-        // Set the largest of the 2 scales to be the scale to use
-        const float scale = (scaleHeight > scaleWidth) ? scaleWidth : scaleHeight;
+            // Rasterize
+            struct NSVGrasterizer *rast = nsvgCreateRasterizer();
+            nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4);
 
-        int offsetX = 0;
-        int offsetY = 0;
+            // Populate image struct with all data
+            image.data = img;
+            image.width = width;
+            image.height = height;
+            image.mipmaps = 1;
+            image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
 
-        if (scaleHeight > scaleWidth)
-        {
-            offsetY = (height - svgImage->height*scale) / 2;
-        }
-        else
-        {
-            offsetX = (width - svgImage->width*scale) / 2;
+            // Free used memory
+            nsvgDelete(svgImage);
         }
-
-        // Rasterize
-        struct NSVGrasterizer* rast = nsvgCreateRasterizer();
-        nsvgRasterize(rast, svgImage, (int)offsetX, (int)offsetY, scale, img, width, height, width*4);
-
-        // Populate image struct with all data
-        image.data = img;
-        image.width = width;
-        image.height = height;
-        image.mipmaps = 1;
-        image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
-
-        // Delete
-        nsvgDelete(svgImage);
     }
 
     return image;
@@ -515,6 +508,28 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
         image.mipmaps = 1;
     }
 #endif
+#if defined(SUPPORT_FILEFORMAT_SVG)
+    else if ((strcmp(fileType, ".svg") == 0) || (strcmp(fileType, ".SVG") == 0))
+    {
+        // TODO: Validate fileData as valid SVG string data
+        
+        struct NSVGimage *svgImage = nsvgParse(fileData, "px", 96.0f);
+        unsigned char *img = RL_MALLOC(svgImage->width*svgImage->height*4);
+        
+        // Rasterize
+        struct NSVGrasterizer *rast = nsvgCreateRasterizer();
+        nsvgRasterize(rast, svgImage, 0, 0, 1.0f, img, svgImage->width, svgImage->height, svgImage->width*4);
+
+        // Populate image struct with all data
+        image.data = img;
+        image.width = svgImage->width;
+        image.height = svgImage->height;
+        image.mipmaps = 1;
+        image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
+
+        nsvgDelete(svgImage);
+    }
+#endif
 #if defined(SUPPORT_FILEFORMAT_DDS)
     else if ((strcmp(fileType, ".dds") == 0) || (strcmp(fileType, ".DDS") == 0))
     {
@@ -544,27 +559,6 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
     {
         image.data = rl_load_astc_from_memory(fileData, dataSize, &image.width, &image.height, &image.format, &image.mipmaps);
     }
-#endif
-#if defined(SUPPORT_FILEFORMAT_SVG)
-    else if (strcmp(fileType, ".svg") == 0)
-    {
-	    if (fileData != NULL)
-	    {
-            // Creating a duplicate svg to read sizes from due to nsvgParse modifiying the string buffer.
-            unsigned char *duplicate = (unsigned char*)RL_MALLOC(dataSize);
-            memcpy(duplicate, fileData, dataSize);
-	        struct NSVGimage *svgImage = nsvgParse(duplicate, "px", 96.0f);
-            RL_FREE(duplicate);
-
-	    	const int width = (int)svgImage->width;
-	        const int height = (int)svgImage->height;
-	        // Delete
-	        nsvgDelete(svgImage);
-            
-
-	        image = LoadImageSvgFromString(fileData, width, height);
-	    }
-    }
 #endif
     else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported");