mirror of
				https://github.com/raysan5/raylib.git
				synced 2025-10-26 12:27:01 +00:00 
			
		
		
		
	Added rudimentary SVG support. (#2738)
* Added rudimentary SVG support. Added 2 functions ImageLoadSvg and ImageLoadSvgWithSize. * Added an example on how to use ImageLoadSvgWithSize and adjusted Makefiles accordingly. * Added actual correct example file. * Reviewed the code to keep the raylib coding conventions in mind. Moved the LoadImageSvg() code into LoadImage() guarded by SUPPORT_FILEFORMAT_SVG. Renamed LoadImageSvgWithSize() to LoadImageSvg(). Added a LoadImageSvgFromString() function to parse the loaded SVG into an actual image. This does the bulk of the work. * Fixed typo. --------- Co-authored-by: Ray <raysan5@gmail.com>
This commit is contained in:
		| @@ -475,7 +475,8 @@ TEXTURES = \ | ||||
|     textures/textures_draw_tiled \ | ||||
|     textures/textures_polygon \ | ||||
|     textures/textures_gif_player \ | ||||
|     textures/textures_fog_of_war | ||||
|     textures/textures_fog_of_war \ | ||||
|     textures/textures_svg_loading | ||||
|  | ||||
| TEXT = \ | ||||
|     text/text_raylib_fonts \ | ||||
|   | ||||
| @@ -450,7 +450,8 @@ TEXTURES = \ | ||||
|     textures/textures_draw_tiled \ | ||||
|     textures/textures_polygon \ | ||||
|     textures/textures_gif_player \ | ||||
|     textures/textures_fog_of_war | ||||
|     textures/textures_fog_of_war \ | ||||
|     textures/textures_svg_loading | ||||
|  | ||||
| TEXT = \ | ||||
|     text/text_raylib_fonts \ | ||||
|   | ||||
							
								
								
									
										1
									
								
								examples/textures/resources/test.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/textures/resources/test.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 5.6 KiB | 
							
								
								
									
										72
									
								
								examples/textures/textures_svg_loading.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								examples/textures/textures_svg_loading.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /******************************************************************************************* | ||||
| * | ||||
| *   raylib [textures] example - SVG loading and texture creation | ||||
| * | ||||
| *   NOTE: Images are loaded in CPU memory (RAM); textures are loaded in GPU memory (VRAM) | ||||
| * | ||||
| *   Example originally created with raylib 4.2, last time updated with raylib 4.2 | ||||
| * | ||||
| *   Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, | ||||
| *   BSD-like license that allows static linking with closed source software | ||||
| * | ||||
| *   Copyright (c) 2022 Dennis Meinen (@bixxy#4258 on Discord) | ||||
| * | ||||
| ********************************************************************************************/ | ||||
|  | ||||
| #include "raylib.h" | ||||
|  | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Program main entry point | ||||
| //------------------------------------------------------------------------------------ | ||||
| int main(void) | ||||
| { | ||||
|     // Initialization | ||||
|     //-------------------------------------------------------------------------------------- | ||||
|     const int screenWidth = 800; | ||||
|     const int screenHeight = 450; | ||||
|  | ||||
|     InitWindow(screenWidth, screenHeight, "raylib [textures] example - svg loading"); | ||||
|  | ||||
|     // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) | ||||
|  | ||||
|     Image image = LoadImageSvg("resources/test.svg", 400, 350);     // Loaded in CPU memory (RAM) | ||||
|     Texture2D texture = LoadTextureFromImage(image);          // Image converted to texture, GPU memory (VRAM) | ||||
|     UnloadImage(image);   // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM | ||||
|  | ||||
|     SetTargetFPS(60);     // Set our game to run at 60 frames-per-second | ||||
|     //--------------------------------------------------------------------------------------- | ||||
|  | ||||
|     // Main game loop | ||||
|     while (!WindowShouldClose())    // Detect window close button or ESC key | ||||
|     { | ||||
|         // Update | ||||
|         //---------------------------------------------------------------------------------- | ||||
|         // TODO: Update your variables here | ||||
|         //---------------------------------------------------------------------------------- | ||||
|  | ||||
|         // Draw | ||||
|         //---------------------------------------------------------------------------------- | ||||
|         BeginDrawing(); | ||||
|  | ||||
|             ClearBackground(RAYWHITE); | ||||
|  | ||||
|             DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE); | ||||
|  | ||||
|             //Red border to illustrate how the SVG is centered within the specified dimensions | ||||
|             DrawRectangleLines((screenWidth / 2 - texture.width / 2) - 1, (screenHeight / 2 - texture.height / 2) - 1, texture.width + 2, texture.height + 2, RED); | ||||
|  | ||||
|             DrawText("this IS a texture loaded from an SVG file!", 300, 410, 10, GRAY); | ||||
|  | ||||
|         EndDrawing(); | ||||
|         //---------------------------------------------------------------------------------- | ||||
|     } | ||||
|  | ||||
|     // De-Initialization | ||||
|     //-------------------------------------------------------------------------------------- | ||||
|     UnloadTexture(texture);       // Texture unloading | ||||
|  | ||||
|     CloseWindow();                // Close window and OpenGL context | ||||
|     //-------------------------------------------------------------------------------------- | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								examples/textures/textures_svg_loading.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								examples/textures/textures_svg_loading.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 14 KiB | 
							
								
								
									
										30
									
								
								src/config.h
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/config.h
									
									
									
									
									
								
							| @@ -141,22 +141,22 @@ | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Module: rtextures - Configuration Flags | ||||
| //------------------------------------------------------------------------------------ | ||||
| // Select the desired fileformats to be supported for image data loading | ||||
| #define SUPPORT_FILEFORMAT_PNG          1 | ||||
| //#define SUPPORT_FILEFORMAT_BMP          1 | ||||
| //#define SUPPORT_FILEFORMAT_TGA          1 | ||||
| //#define SUPPORT_FILEFORMAT_JPG          1 | ||||
| #define SUPPORT_FILEFORMAT_GIF          1 | ||||
| #define SUPPORT_FILEFORMAT_QOI          1 | ||||
| //#define SUPPORT_FILEFORMAT_PSD          1 | ||||
| #define SUPPORT_FILEFORMAT_DDS          1 | ||||
| #define SUPPORT_FILEFORMAT_HDR          1 | ||||
| // Selecte desired fileformats to be supported for image data loading | ||||
| #define SUPPORT_FILEFORMAT_PNG      1 | ||||
| //#define SUPPORT_FILEFORMAT_BMP      1 | ||||
| //#define SUPPORT_FILEFORMAT_TGA      1 | ||||
| //#define SUPPORT_FILEFORMAT_JPG      1 | ||||
| #define SUPPORT_FILEFORMAT_GIF      1 | ||||
| #define SUPPORT_FILEFORMAT_QOI      1 | ||||
| //#define SUPPORT_FILEFORMAT_PSD      1 | ||||
| #define SUPPORT_FILEFORMAT_DDS      1 | ||||
| //#define SUPPORT_FILEFORMAT_HDR      1 | ||||
| //#define SUPPORT_FILEFORMAT_PIC          1 | ||||
| //#define SUPPORT_FILEFORMAT_PNM          1 | ||||
| //#define SUPPORT_FILEFORMAT_KTX          1 | ||||
| //#define SUPPORT_FILEFORMAT_ASTC         1 | ||||
| //#define SUPPORT_FILEFORMAT_PKM          1 | ||||
| //#define SUPPORT_FILEFORMAT_PVR          1 | ||||
| //#define SUPPORT_FILEFORMAT_KTX      1 | ||||
| //#define SUPPORT_FILEFORMAT_ASTC     1 | ||||
| //#define SUPPORT_FILEFORMAT_PKM      1 | ||||
| //#define SUPPORT_FILEFORMAT_PVR      1 | ||||
| #define SUPPORT_FILEFORMAT_SVG      1 | ||||
|  | ||||
| // Support image export functionality (.png, .bmp, .tga, .jpg, .qoi) | ||||
| #define SUPPORT_IMAGE_EXPORT            1 | ||||
|   | ||||
							
								
								
									
										3053
									
								
								src/external/nanosvg.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3053
									
								
								src/external/nanosvg.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1458
									
								
								src/external/nanosvgrast.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1458
									
								
								src/external/nanosvgrast.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1245,6 +1245,8 @@ 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 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 | ||||
|   | ||||
| @@ -215,6 +215,14 @@ | ||||
| #define STB_IMAGE_RESIZE_IMPLEMENTATION | ||||
| #include "external/stb_image_resize.h"  // Required for: stbir_resize_uint8() [ImageResize()] | ||||
|  | ||||
| #if defined(SUPPORT_FILEFORMAT_SVG) | ||||
| 	#define NANOSVG_IMPLEMENTATION	// Expands implementation | ||||
| 	#include "external/nanosvg.h" | ||||
|  | ||||
| 	#define NANOSVGRAST_IMPLEMENTATION | ||||
| 	#include "external/nanosvgrast.h" | ||||
| #endif | ||||
|  | ||||
| //---------------------------------------------------------------------------------- | ||||
| // Defines and Macros | ||||
| //---------------------------------------------------------------------------------- | ||||
| @@ -310,6 +318,72 @@ 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) | ||||
| { | ||||
|     Image image = { 0 }; | ||||
|  | ||||
|     unsigned int dataSize = 0; | ||||
|     unsigned char *string = LoadFileData(fileName, &dataSize); | ||||
|  | ||||
|     if (string != NULL) | ||||
|     { | ||||
|         image = LoadImageSvgFromString(string, width, height); | ||||
|         RL_FREE(string); | ||||
|     } | ||||
|  | ||||
|     return image; | ||||
| } | ||||
|  | ||||
| // Load an image from a SVG string with custom size | ||||
| Image LoadImageSvgFromString(const char *string, int width, int height) | ||||
| { | ||||
|     Image image = { 0 }; | ||||
|  | ||||
|     if (string != NULL) | ||||
|     { | ||||
|         struct NSVGimage *svgImage = nsvgParse(string, "px", 96.0f); | ||||
|  | ||||
|         // Allocate memory for image | ||||
|         unsigned char *img = malloc(width*height*4); | ||||
|  | ||||
|         // Calculate scales for both the width and the height | ||||
|         const float scaleWidth = width/svgImage->width; | ||||
|         const float scaleHeight = height/svgImage->height; | ||||
|  | ||||
|         // Set the largest of the 2 scales to be the scale to use | ||||
|         const float scale = (scaleHeight > scaleWidth) ? scaleWidth : scaleHeight; | ||||
|  | ||||
|         int offsetX = 0; | ||||
|         int offsetY = 0; | ||||
|  | ||||
|         if (scaleHeight > scaleWidth) | ||||
|         { | ||||
|             offsetY = (height - svgImage->height*scale) / 2; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             offsetX = (width - svgImage->width*scale) / 2; | ||||
|         } | ||||
|  | ||||
|         // 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; | ||||
| } | ||||
|  | ||||
| // Load animated image data | ||||
| //  - Image.data buffer includes all frames: [image#0][image#1][image#2][...] | ||||
| //  - Number of frames is returned through 'frames' parameter | ||||
| @@ -470,6 +544,27 @@ 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"); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bXi
					bXi