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:
parent
75e5cd86d7
commit
c03ab03627
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user