Merge branch 'master' into font-size-points-option

This commit is contained in:
Ray 2026-07-23 11:26:30 +02:00 • committed by GitHub
commit e95a108d44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 21372 additions and 6309 deletions

View file

@ -71,7 +71,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -90,7 +90,7 @@ jobs:
cmake --build . --config $BUILD_TYPE
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
upload: false
@ -99,7 +99,7 @@ jobs:
# Filter out rules with low severity or high false positve rate
# Also filter out warnings in third-party code
- name: Filter out unwanted errors and warnings
uses: advanced-security/filter-sarif@v1
uses: advanced-security/filter-sarif@v1.1
with:
patterns: |
-**:cpp/path-injection
@ -121,7 +121,7 @@ jobs:
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
- name: Upload CodeQL results to code scanning
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: ${{ steps.step1.outputs.sarif-output }}
category: "/language:${{matrix.language}}"

View file

@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@master
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1
uses: microsoft/setup-msbuild@v3
- name: Build Library (MSVC16)
run: |

View file

@ -719,7 +719,6 @@ fn addExamples(
.shell_file_path = b.path("src/shell.html"),
.install_dir = install_dir,
});
b.getInstallStep().dependOn(emcc_step);
const html_filename = try std.fmt.allocPrint(b.allocator, "{s}.html", .{wasm.name});
const emrun_step = emsdk.emrunStep(

View file

@ -12,8 +12,8 @@
.lazy = true,
},
.raygui = .{
.url = "git+https://github.com/raysan5/raygui#3b2855842ab578a034f827c38cf8f62c042fc983",
.hash = "N-V-__8AAHvybwBw1kyBGn0BW_s1RqIpycNjLf_XbE-fpLUF",
.url = "git+https://github.com/raysan5/raygui#3f81e2bd02bf08dcd9d350e8e8b3cf58044d6877",
.hash = "N-V-__8AAPPCmABYkTrLoRGTR6whFQP1bvg7p5vpLsKIcn4G",
.lazy = true,
},
.emsdk = .{

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

6460
examples/text/raygui.h Normal file

File diff suppressed because it is too large Load diff

6460
examples/textures/raygui.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -107,6 +107,20 @@ endif ()
target_link_libraries(raylib PRIVATE $<BUILD_INTERFACE:${LIBS_PRIVATE}>)
target_link_libraries(raylib PUBLIC ${LIBS_PUBLIC})
# Static libraries must export their private link dependencies for installed consumers.
# LINK_ONLY keeps those dependencies out of the compile interface.
if (NOT BUILD_SHARED_LIBS)
set(raylib_install_private_libs ${LIBS_PRIVATE})
if (NOT glfw3_FOUND)
list(REMOVE_ITEM raylib_install_private_libs glfw)
endif()
foreach(lib IN LISTS raylib_install_private_libs)
target_link_libraries(raylib INTERFACE $<INSTALL_INTERFACE:$<LINK_ONLY:${lib}>>)
endforeach()
endif()
# Sets some compile time definitions for the pre-processor
# If CUSTOMIZE_BUILD option is on you will not use config.h by default
# and you will be able to select more build options

1516
src/external/rlsw.h vendored

File diff suppressed because it is too large Load diff

View file

@ -1198,7 +1198,7 @@ void OpenURL(const char *url)
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
{
char *cmd = (char *)RL_CALLOC(strlen(url) + 16, sizeof(char));
#if defined(_WIN32)
sprintf(cmd, "explorer \"%s\"", url);
@ -1211,7 +1211,7 @@ void OpenURL(const char *url)
#endif
// TODO: Replace system() call by custom process
int result = system(cmd);
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
RL_FREE(cmd);
}
@ -2186,12 +2186,12 @@ static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffs
// GLFW3: Cursor ennter callback, when cursor enters the window
static void CursorEnterCallback(GLFWwindow *window, int entered)
{
if (entered)
if (entered)
{
// NOTE: Mouse position updated by MouseCursorPosCallback()
CORE.Input.Mouse.cursorOnScreen = true;
}
else
else
{
CORE.Input.Mouse.cursorOnScreen = false;
CORE.Input.Mouse.currentPosition = (Vector2){ 0 };

View file

@ -1488,7 +1488,7 @@ void OpenURL(const char *url)
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
{
char *cmd = (char *)RL_CALLOC(strlen(url) + 16, sizeof(char));
#if defined(_WIN32)
sprintf(cmd, "explorer \"%s\"", url);
@ -1621,7 +1621,7 @@ void PollInputEvents(void)
while (mg_gamepads_check_event(&platform.minigamepad, &gamepad_event))
{
int gamepadIndex = gamepad_event.gamepad->index;
switch (gamepad_event.type)
{
case MG_EVENT_BUTTON_PRESS:
@ -1682,10 +1682,10 @@ void PollInputEvents(void)
if (platform.minigamepad.gamepads[gamepadIndex].axes[i].supported) axisCount += 1;
else break;
}
CORE.Input.Gamepad.axisCount[gamepadIndex] = axisCount;
snprintf(CORE.Input.Gamepad.name[gamepadIndex], MAX_GAMEPAD_NAME_LENGTH, "%s", platform.minigamepad.gamepads[gamepadIndex].name);
} break;
case MG_EVENT_GAMEPAD_DISCONNECT: CORE.Input.Gamepad.ready[gamepadIndex] = false; break;
default: break;

View file

@ -1264,11 +1264,11 @@ void OpenURL(const char *url)
TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols");
}
else
{
{
int len = strlen(url) + 16;
char *cmd = (char *)RL_CALLOC(len, sizeof(char));
snprintf(cmd, len, "explorer \"%s\"", url);
int result = system(cmd);
if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created");
RL_FREE(cmd);
@ -1299,7 +1299,7 @@ void SetMousePosition(int x, int y)
if (!CORE.Input.Mouse.cursorLocked)
{
CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y };
TRACELOG(LOG_WARNING, "SetMousePosition not implemented at platform level");
}
else TRACELOG(LOG_WARNING, "INPUT: MOUSE: Cursor not enabled");

View file

@ -1444,7 +1444,7 @@ int InitPlatform(void)
return -1;
}
// WARNING: Providing framebufferAttribs is not logically necessary,
// WARNING: Providing framebufferAttribs is not logically necessary,
// but it may prevent segfaults on some nvidia drivers
if (!eglChooseConfig(platform.device, framebufferAttribs, NULL, 0, &numConfigs))
{

View file

@ -1148,28 +1148,29 @@ RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custo
RLAPI int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists), returns 0 on success
RLAPI int FileRemove(const char *fileName); // Remove file (if exists), returns 0 on success
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist, returns 0 on success
RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist, returns 0 on success
RLAPI int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist, returns 0 on success
RLAPI int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist, returns 0 on success
RLAPI int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file, returns 0 on success
RLAPI int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file, returns -1 if index not found or index otherwise
RLAPI bool FileExists(const char *fileName); // Check if file exists
RLAPI bool DirectoryExists(const char *dirPath); // Check if directory path exists
RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (recommended include point: .png, .wav)
RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h)
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string)
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
RLAPI int ChangeDirectory(const char *dirPath); // Change working directory, returns 0 on success
RLAPI bool IsPathFile(const char *path); // Check if given path points to a file
RLAPI bool IsPathDirectory(const char *path); // Check if given path points to a directory
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
RLAPI int GetFileLength(const char *fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h)
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a provided fileName with path (uses static string)
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a provided path (uses static string)
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
RLAPI int ChangeDirectory(const char *dirPath); // Change working directory, returns 0 on success
RLAPI bool IsPathFile(const char *path); // Check if provided path points to a file
RLAPI bool IsPathDirectory(const char *path); // Check if provided path points to a directory
RLAPI bool IsPathAbsolute(const char *path); // Check if provided path is an absolute path
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
RLAPI bool IsFileDropped(void); // Check if file has been dropped into window
@ -1243,11 +1244,11 @@ RLAPI Vector2 GetMouseWheelMoveV(void); // Get mouse wheel movement for
RLAPI void SetMouseCursor(int cursor); // Set mouse cursor
// Input-related functions: touch
RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size)
RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size)
RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size)
RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index
RLAPI int GetTouchPointCount(void); // Get number of touch points
RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size)
RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size)
RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size)
RLAPI int GetTouchPointId(int index); // Get touch point identifier for provided index
RLAPI int GetTouchPointCount(void); // Get number of touch points
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: rgestures)
@ -1333,12 +1334,12 @@ RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vecto
RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point
RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points
// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f]
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
RLAPI Vector2 GetSplinePointBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier
// Spline segment point evaluation functions, for a provided t [0.0f .. 1.0f]
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
RLAPI Vector2 GetSplinePointBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier
RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier
// Basic shapes collision detection functions
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
@ -1423,9 +1424,9 @@ RLAPI Color GetImageColor(Image image, int x, int y); // Get image pixel
// Image drawing functions
// NOTE: Image software-rendering functions (CPU)
RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color
RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with provided color
RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
RLAPI void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color color); // Draw a line defining thickness within an image

View file

@ -110,7 +110,12 @@
#include <stdio.h> // Required for: FILE, fopen(), fseek(), ftell(), fread(), fwrite(), fprintf(), vprintf(), fclose(), sprintf() [Used in OpenURL()]
#include <string.h> // Required for: strlen(), strcmp(), strrchr(), memset(), memcpy(), strcat()
#include <stdarg.h> // Required for: va_list, va_start(), va_end() [Used in TraceLog()]
#ifndef PICO_RP2350
#include <time.h> // Required for: time() [Used in InitTimer()]
#else
#include "pico/rand.h" // Pico doesn't implement time, and will implement its own hardware timer elsewhere. However, we need something to get a random seed from...
#endif
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
#if defined(PLATFORM_MEMORY) || defined(PLATFORM_WEB)
@ -713,8 +718,12 @@ void InitWindow(int width, int height, const char *title)
CORE.Time.frameCounter = 0;
CORE.Window.shouldClose = false;
// Initialize random seed
// Initialize random seed using available timer source instead of standard time() on embedded platforms
#ifndef PICO_RP2350
SetRandomSeed((unsigned int)time(NULL));
#else
SetRandomSeed(get_rand_32());
#endif
TRACELOG(LOG_INFO, "SYSTEM: Working Directory: %s", GetWorkingDirectory());
}
@ -1804,7 +1813,6 @@ void UnloadRandomSequence(int *sequence)
}
// Takes a screenshot of current screen
// NOTE: Provided fileName should not contain paths, saving to working directory
void TakeScreenshot(const char *fileName)
{
#if SUPPORT_MODULE_RTEXTURES
@ -1819,7 +1827,8 @@ void TakeScreenshot(const char *fileName)
Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
char path[MAX_FILEPATH_LENGTH] = { 0 };
snprintf(path, MAX_FILEPATH_LENGTH, "%s", TextFormat("%s/%s", CORE.Storage.basePath, fileName));
if (!IsPathAbsolute(fileName)) snprintf(path, MAX_FILEPATH_LENGTH, "%s", TextFormat("%s/%s", CORE.Storage.basePath, fileName));
else snprintf(path, MAX_FILEPATH_LENGTH, "%s", fileName);
ExportImage(image, path); // WARNING: Module required: rtextures
RL_FREE(imgData);
@ -2522,7 +2531,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
return fileName;
}
// Get directory for a given filePath
// Get directory for a provided filePath
const char *GetDirectoryPath(const char *filePath)
{
/*
@ -2569,7 +2578,7 @@ const char *GetDirectoryPath(const char *filePath)
return dirPath;
}
// Get previous directory path for a given path
// Get previous directory path for a provided path
const char *GetPrevDirectoryPath(const char *dirPath)
{
static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 };
@ -2819,7 +2828,7 @@ int ChangeDirectory(const char *dirPath)
return result;
}
// Check if given path point to a file
// Check if provided path point to a file
bool IsPathFile(const char *path)
{
bool result = false;
@ -2832,7 +2841,7 @@ bool IsPathFile(const char *path)
return result;
}
// Check if given path point to a directory
// Check if provided path point to a directory
bool IsPathDirectory(const char *path)
{
bool result = false;
@ -2842,6 +2851,28 @@ bool IsPathDirectory(const char *path)
return result;
}
// Check if provided path is an absolute path
bool IsPathAbsolute(const char *path)
{
int result = false;
if ((path != NULL) && (path[0] != '\0'))
{
#if defined(_WIN32)
// UNC path (\\server\share)
if ((path[0] == '\\') && (path[1] == '\\')) result = true;
// Drive letter (e.g. C:\ or D:/)
else if (isalpha((unsigned char)path[0]) && (path[1] == ':') &&
((path[2] == '\\') || (path[2] == '/'))) result = true;
#else
// POSIX: must start with /
if (path[0] == '/') result = true;
#endif
}
return result;
}
// Check if fileName is valid for the platform/OS
bool IsFileNameValid(const char *fileName)
{
@ -4214,7 +4245,7 @@ Vector2 GetTouchPosition(int index)
return position;
}
// Get touch point identifier for given index
// Get touch point identifier for provided index
int GetTouchPointId(int index)
{
int id = -1;

View file

@ -3793,6 +3793,10 @@ unsigned char *rlReadScreenPixels(int width, int height)
{
unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char));
// NOTE: Buffer retrieved is GL_FRONT in single-buffered configurations
// and GL_BACK in double-buffered configurations, make sure to call it at the end of frame
//glReadBuffer(GL_BACK);
// NOTE: glReadPixels() returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
// WARNING: Getting alpha channel! Be careful, it can be transparent if not cleared properly!
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
@ -5239,7 +5243,7 @@ static int rlGetPixelDataSize(int width, int height, int format)
int blockHeight = (height + 3)/4;
unsigned long long dataSizeBytes = (unsigned long long)blockWidth*blockHeight*8;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
case RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA:
case RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA:
@ -5250,7 +5254,7 @@ static int rlGetPixelDataSize(int width, int height, int format)
int blockHeight = (height + 3)/4;
unsigned long long dataSizeBytes = (unsigned long long)blockWidth*blockHeight*16;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
case RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 4 bytes per each 4x4 block
{
@ -5258,7 +5262,7 @@ static int rlGetPixelDataSize(int width, int height, int format)
int blockHeight = (height + 3)/4;
unsigned long long dataSizeBytes = (unsigned long long)blockWidth*blockHeight*4;
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
} break;
default: break;
}
@ -5270,7 +5274,7 @@ static int rlGetPixelDataSize(int width, int height, int format)
unsigned long long dataSizeBytes = ((unsigned long long)width*height*bpp) >> 3; // Get size in bytes (dividing by 8)
if (dataSizeBytes < INT_MAX) dataSize = (int)dataSizeBytes;
}
if (dataSize == 0) TRACELOG(LOG_WARNING, "Requested image size is larger than 2GB, it can not be allocated");
return dataSize;

View file

@ -488,7 +488,7 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
float ringangle = DEG2RAD*(180.0f/(rings + 1)); // Angle between latitudinal parallels
float ringangle = DEG2RAD*(180.0f/rings); // Angle between latitudinal parallels
float sliceangle = DEG2RAD*(360.0f/slices); // Angle between longitudinal meridians
float cosring = cosf(ringangle);
@ -500,7 +500,7 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
vertices[2] = (Vector3){ 0, 1, 0 };
vertices[3] = (Vector3){ sinring, cosring, 0 };
for (int i = 0; i < rings + 1; i++)
for (int i = 0; i < rings; i++)
{
for (int j = 0; j < slices; j++)
{
@ -542,31 +542,42 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 0; i < (rings + 2); i++)
float ringangle = DEG2RAD*(180.0f/rings); // Angle between latitudinal parallels
float sliceangle = DEG2RAD*(360.0f/slices); // Angle between longitudinal meridians
float cosring = cosf(ringangle);
float sinring = sinf(ringangle);
float cosslice = cosf(sliceangle);
float sinslice = sinf(sliceangle);
Vector3 vertices[4] = { 0 }; // Required to store face vertices
vertices[2] = (Vector3){ 0, 1, 0 };
vertices[3] = (Vector3){ sinring, cosring, 0 };
for (int i = 0; i < rings; i++)
{
for (int j = 0; j < slices; j++)
{
rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*sinf(DEG2RAD*(360.0f*j/slices)),
sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*i)),
cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*cosf(DEG2RAD*(360.0f*j/slices)));
rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*(j + 1)/slices)),
sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*(j + 1)/slices)));
vertices[0] = vertices[2]; // Rotate around y axis to set up vertices for next face
vertices[1] = vertices[3];
vertices[2] = (Vector3){ cosslice*vertices[2].x - sinslice*vertices[2].z, vertices[2].y, sinslice*vertices[2].x + cosslice*vertices[2].z }; // Rotation matrix around y axis
vertices[3] = (Vector3){ cosslice*vertices[3].x - sinslice*vertices[3].z, vertices[3].y, sinslice*vertices[3].x + cosslice*vertices[3].z };
rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*(j + 1)/slices)),
sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*(j + 1)/slices)));
rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*j/slices)),
sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*j/slices)));
// Longitude Lines
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
rlVertex3f(vertices[1].x, vertices[1].y, vertices[1].z);
rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*sinf(DEG2RAD*(360.0f*j/slices)),
sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1))),
cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*(i + 1)))*cosf(DEG2RAD*(360.0f*j/slices)));
rlVertex3f(cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*sinf(DEG2RAD*(360.0f*j/slices)),
sinf(DEG2RAD*(270 + (180.0f/(rings + 1))*i)),
cosf(DEG2RAD*(270 + (180.0f/(rings + 1))*i))*cosf(DEG2RAD*(360.0f*j/slices)));
// Latitude Lines
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
rlVertex3f(vertices[2].x, vertices[2].y, vertices[2].z);
// Diagonal Lines
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
}
vertices[2] = vertices[3]; // Rotate around z axis to set up starting vertices for next ring
vertices[3] = (Vector3){ cosring*vertices[3].x + sinring*vertices[3].y, -sinring*vertices[3].x + cosring*vertices[3].y, vertices[3].z }; // Rotation matrix around z axis
}
rlEnd();
rlPopMatrix();
@ -6603,7 +6614,6 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
cgltf_animation_channel *translate;
cgltf_animation_channel *rotate;
cgltf_animation_channel *scale;
cgltf_interpolation_type interpolationType;
};
struct Channels *boneChannels = (struct Channels *)RL_CALLOC(animations[a].boneCount, sizeof(struct Channels));
@ -6625,8 +6635,6 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
if (boneIndex == -1) continue; // Animation channel for a node not in the skeleton
boneChannels[boneIndex].interpolationType = animData.channels[j].sampler->interpolation;
if (animData.channels[j].sampler->interpolation != cgltf_interpolation_type_max_enum)
{
if (channel.target_path == cgltf_animation_path_type_translation)
@ -6678,7 +6686,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
if (boneChannels[k].translate)
{
if (!GetPoseAtTimeGLTF(boneChannels[k].interpolationType, boneChannels[k].translate->sampler->input, boneChannels[k].translate->sampler->output, time, &translation))
if (!GetPoseAtTimeGLTF(boneChannels[k].translate->sampler->interpolation, boneChannels[k].translate->sampler->input, boneChannels[k].translate->sampler->output, time, &translation))
{
TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load translate pose data for bone %s", fileName, bones[k].name);
}
@ -6686,7 +6694,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
if (boneChannels[k].rotate)
{
if (!GetPoseAtTimeGLTF(boneChannels[k].interpolationType, boneChannels[k].rotate->sampler->input, boneChannels[k].rotate->sampler->output, time, &rotation))
if (!GetPoseAtTimeGLTF(boneChannels[k].rotate->sampler->interpolation, boneChannels[k].rotate->sampler->input, boneChannels[k].rotate->sampler->output, time, &rotation))
{
TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load rotate pose data for bone %s", fileName, bones[k].name);
}
@ -6694,7 +6702,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo
if (boneChannels[k].scale)
{
if (!GetPoseAtTimeGLTF(boneChannels[k].interpolationType, boneChannels[k].scale->sampler->input, boneChannels[k].scale->sampler->output, time, &scale))
if (!GetPoseAtTimeGLTF(boneChannels[k].scale->sampler->interpolation, boneChannels[k].scale->sampler->input, boneChannels[k].scale->sampler->output, time, &scale))
{
TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load scale pose data for bone %s", fileName, bones[k].name);
}

View file

@ -888,7 +888,90 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
// Draw rectangle with rounded edges
void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color)
{
DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color);
// Not a rounded rectangle
if (roundness <= 0.0f)
{
DrawRectangleLines((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, color);
return;
}
if (roundness >= 1.0f) roundness = 1.0f;
// Calculate corner radius
float radius = (rec.width > rec.height)? (rec.height*roundness)/2 : (rec.width*roundness)/2;
if (radius <= 0.0f) return;
// Calculate number of segments to use for the corners
if (segments < 4)
{
// Calculate the maximum angle between segments based on the error rate (usually 0.5f)
float th = acosf(2*powf(1 - SMOOTH_CIRCLE_ERROR_RATE/radius, 2) - 1);
segments = (int)ceilf((2*PI/th)/4.0f);
if (segments <= 0) segments = 4;
}
float stepLength = 90.0f/(float)segments;
/*
Quick sketch to make sense of all of this,
marks the 8 + 4 (corner centers P8-11) points used
P0 ------------------ P1
/ \
/ \
P7 / \ P2
| *P8 P9* |
| |
| |
P6 \ *P11 P10* / P3
\ /
\ /
P5 ------------------ P4
*/
const Vector2 point[8] = {
{(float)rec.x + radius + 0.5f, rec.y + 0.5f},
{(float)(rec.x + rec.width) - radius - 0.5f, rec.y + 0.5f},
{rec.x + rec.width - 0.5f, (float)rec.y + radius + 0.5f}, // PO, P1, P2
{rec.x + rec.width - 0.5f, (float)(rec.y + rec.height) - radius - 0.5f},
{(float)(rec.x + rec.width) - radius - 0.5f, rec.y + rec.height - 0.5f}, // P3, P4
{(float)rec.x + radius + 0.5f, rec.y + rec.height - 0.5f},
{rec.x + 0.5f, (float)(rec.y + rec.height) - radius - 0.5f},
{rec.x + 0.5f, (float)rec.y + radius + 0.5f}, // P5, P6, P7
};
const Vector2 centers[4] = {
{(float)rec.x + radius + 0.5f, (float)rec.y + radius + 0.5f},
{(float)(rec.x + rec.width) - radius - 0.5f, (float)rec.y + radius + 0.5f}, // P16, P17
{(float)(rec.x + rec.width) - radius - 0.5f, (float)(rec.y + rec.height) - radius - 0.5f},
{(float)rec.x + radius + 0.5f, (float)(rec.y + rec.height) - radius - 0.5f} // P18, P19
};
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f };
rlBegin(RL_LINES);
// Draw all the 4 corners first: Upper Left Corner, Upper Right Corner, Lower Right Corner, Lower Left Corner
for (int k = 0; k < 4; ++k) // Hope the compiler is smart enough to unroll this loop
{
float angle = angles[k];
const Vector2 center = centers[k];
for (int i = 0; i < segments; i++)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius);
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius);
angle += stepLength;
}
}
// And now the remaining 4 lines
for (int i = 0; i < 8; i += 2)
{
rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[i].x, point[i].y);
rlVertex2f(point[i + 1].x, point[i + 1].y);
}
rlEnd();
}
// Draw rectangle with rounded edges outline with line thickness
@ -1177,10 +1260,12 @@ void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Colo
void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float thick, Color color)
{
if (thick <= 0.0f) return;
if (sides < 3) sides = 3;
float centralAngle = rotation*DEG2RAD;
float exteriorAngle = 360.0f/(float)sides*DEG2RAD;
float innerRadius = radius - (thick*cosf(DEG2RAD*exteriorAngle/2.0f));
float innerRadius = fmaxf(0.0f, radius - (thick*cosf(DEG2RAD*exteriorAngle/2.0f)));
#if SUPPORT_QUADS_DRAW_MODE
rlSetTexture(GetShapesTexture().id);

View file

@ -1230,25 +1230,34 @@ Image ImageFromImage(Image image, Rectangle rec)
{
Image result = { 0 };
// Basic rectangle validation: size smaller than image size
if ((rec.x >= 0) && (rec.y >= 0) && (rec.width > 0) && (rec.height > 0) &&
(((int)rec.x + (int)rec.width) <= image.width) &&
(((int)rec.y + (int)rec.height) <= image.height))
{
int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
// Security check to avoid program crash
if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result;
result.width = (int)rec.width;
result.height = (int)rec.height;
result.data = RL_CALLOC((int)rec.width*(int)rec.height*bytesPerPixel, 1);
result.format = image.format;
result.mipmaps = 1;
for (int y = 0; y < (int)rec.height; y++)
if (image.format < PIXELFORMAT_COMPRESSED_DXT1_RGB)
{
// Basic rectangle validation: size smaller than image size
if ((rec.x >= 0) && (rec.y >= 0) && (rec.width > 0) && (rec.height > 0) &&
(((int)rec.x + (int)rec.width) <= image.width) &&
(((int)rec.y + (int)rec.height) <= image.height))
{
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel, ((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel, (int)rec.width*bytesPerPixel);
int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
result.width = (int)rec.width;
result.height = (int)rec.height;
result.data = RL_CALLOC((int)rec.width*(int)rec.height*bytesPerPixel, 1);
result.format = image.format;
result.mipmaps = 1;
for (int y = 0; y < (int)rec.height; y++)
{
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel,
((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel,
(int)rec.width*bytesPerPixel);
}
}
}
else TRACELOG(LOG_WARNING, "IMAGE: Rectangle provided for ImageToImage not valid");
else TRACELOG(LOG_WARNING, "IMAGE: ImageToImage(), rectangle provided not valid");
}
else TRACELOG(LOG_WARNING, "IMAGE: Image manipulation not supported for compressed formats");
return result;
}
@ -5514,7 +5523,7 @@ int GetPixelDataSize(int width, int height, int format)
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
default: break;
}
unsigned long long dataSizeBytes = ((unsigned long long)width*height*bpp) >> 3; // Get size in bytes (dividing by 8)
if (dataSizeBytes < INT_MAX)
@ -5529,7 +5538,7 @@ int GetPixelDataSize(int width, int height, int format)
else if ((format >= PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) dataSize = 16;
}
}
// NOTE: In case required image data larger than 2GB, no memory allocated at all (NULL)
if (dataSize == 0) TRACELOG(LOG_WARNING, "Requested image size is larger than 2GB, it can not be allocated");

View file

@ -4603,7 +4603,7 @@
},
{
"name": "GetDirectoryPath",
"description": "Get full path for a given fileName with path (uses static string)",
"description": "Get full path for a provided fileName with path (uses static string)",
"returnType": "const char *",
"params": [
{
@ -4614,7 +4614,7 @@
},
{
"name": "GetPrevDirectoryPath",
"description": "Get previous directory path for a given path (uses static string)",
"description": "Get previous directory path for a provided path (uses static string)",
"returnType": "const char *",
"params": [
{
@ -4657,7 +4657,7 @@
},
{
"name": "IsPathFile",
"description": "Check if given path points to a file",
"description": "Check if provided path points to a file",
"returnType": "bool",
"params": [
{
@ -4668,7 +4668,18 @@
},
{
"name": "IsPathDirectory",
"description": "Check if given path points to a directory",
"description": "Check if provided path points to a directory",
"returnType": "bool",
"params": [
{
"type": "const char *",
"name": "path"
}
]
},
{
"name": "IsPathAbsolute",
"description": "Check if provided path is an absolute path",
"returnType": "bool",
"params": [
{
@ -5379,7 +5390,7 @@
},
{
"name": "GetTouchPointId",
"description": "Get touch point identifier for given index",
"description": "Get touch point identifier for provided index",
"returnType": "int",
"params": [
{
@ -8099,7 +8110,7 @@
},
{
"name": "ImageClearBackground",
"description": "Clear image background with given color",
"description": "Clear image background with provided color",
"returnType": "void",
"params": [
{

View file

@ -4135,7 +4135,7 @@ return {
},
{
name = "GetDirectoryPath",
description = "Get full path for a given fileName with path (uses static string)",
description = "Get full path for a provided fileName with path (uses static string)",
returnType = "const char *",
params = {
{type = "const char *", name = "filePath"}
@ -4143,7 +4143,7 @@ return {
},
{
name = "GetPrevDirectoryPath",
description = "Get previous directory path for a given path (uses static string)",
description = "Get previous directory path for a provided path (uses static string)",
returnType = "const char *",
params = {
{type = "const char *", name = "dirPath"}
@ -4177,7 +4177,7 @@ return {
},
{
name = "IsPathFile",
description = "Check if given path points to a file",
description = "Check if provided path points to a file",
returnType = "bool",
params = {
{type = "const char *", name = "path"}
@ -4185,7 +4185,15 @@ return {
},
{
name = "IsPathDirectory",
description = "Check if given path points to a directory",
description = "Check if provided path points to a directory",
returnType = "bool",
params = {
{type = "const char *", name = "path"}
}
},
{
name = "IsPathAbsolute",
description = "Check if provided path is an absolute path",
returnType = "bool",
params = {
{type = "const char *", name = "path"}
@ -4671,7 +4679,7 @@ return {
},
{
name = "GetTouchPointId",
description = "Get touch point identifier for given index",
description = "Get touch point identifier for provided index",
returnType = "int",
params = {
{type = "int", name = "index"}
@ -6071,7 +6079,7 @@ return {
},
{
name = "ImageClearBackground",
description = "Clear image background with given color",
description = "Clear image background with provided color",
returnType = "void",
params = {
{type = "Image *", name = "dst"},

View file

@ -3001,13 +3001,13 @@
((type "const char *") (name "filePath"))))
((name "GetDirectoryPath")
(description "Get full path for a given fileName with path (uses static string)")
(description "Get full path for a provided fileName with path (uses static string)")
(return-type "const char *")
(params
((type "const char *") (name "filePath"))))
((name "GetPrevDirectoryPath")
(description "Get previous directory path for a given path (uses static string)")
(description "Get previous directory path for a provided path (uses static string)")
(return-type "const char *")
(params
((type "const char *") (name "dirPath"))))
@ -3033,13 +3033,19 @@
((type "const char *") (name "dirPath"))))
((name "IsPathFile")
(description "Check if given path points to a file")
(description "Check if provided path points to a file")
(return-type "bool")
(params
((type "const char *") (name "path"))))
((name "IsPathDirectory")
(description "Check if given path points to a directory")
(description "Check if provided path points to a directory")
(return-type "bool")
(params
((type "const char *") (name "path"))))
((name "IsPathAbsolute")
(description "Check if provided path is an absolute path")
(return-type "bool")
(params
((type "const char *") (name "path"))))
@ -3414,7 +3420,7 @@
((type "int") (name "index"))))
((name "GetTouchPointId")
(description "Get touch point identifier for given index")
(description "Get touch point identifier for provided index")
(return-type "int")
(params
((type "int") (name "index"))))
@ -4544,7 +4550,7 @@
((type "int") (name "y"))))
((name "ImageClearBackground")
(description "Clear image background with given color")
(description "Clear image background with provided color")
(return-type "void")
(params
((type "Image *") (name "dst"))

File diff suppressed because it is too large Load diff

View file

@ -681,7 +681,7 @@
<Param type="unsigned int" name="frames" desc="" />
</Callback>
</Callbacks>
<Functions count="612">
<Functions count="613">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" />
@ -1099,10 +1099,10 @@
<Function name="GetFileNameWithoutExt" retType="const char *" paramCount="1" desc="Get filename string without extension (uses static string)">
<Param type="const char *" name="filePath" desc="" />
</Function>
<Function name="GetDirectoryPath" retType="const char *" paramCount="1" desc="Get full path for a given fileName with path (uses static string)">
<Function name="GetDirectoryPath" retType="const char *" paramCount="1" desc="Get full path for a provided fileName with path (uses static string)">
<Param type="const char *" name="filePath" desc="" />
</Function>
<Function name="GetPrevDirectoryPath" retType="const char *" paramCount="1" desc="Get previous directory path for a given path (uses static string)">
<Function name="GetPrevDirectoryPath" retType="const char *" paramCount="1" desc="Get previous directory path for a provided path (uses static string)">
<Param type="const char *" name="dirPath" desc="" />
</Function>
<Function name="GetWorkingDirectory" retType="const char *" paramCount="0" desc="Get current working directory (uses static string)">
@ -1115,10 +1115,13 @@
<Function name="ChangeDirectory" retType="int" paramCount="1" desc="Change working directory, returns 0 on success">
<Param type="const char *" name="dirPath" desc="" />
</Function>
<Function name="IsPathFile" retType="bool" paramCount="1" desc="Check if given path points to a file">
<Function name="IsPathFile" retType="bool" paramCount="1" desc="Check if provided path points to a file">
<Param type="const char *" name="path" desc="" />
</Function>
<Function name="IsPathDirectory" retType="bool" paramCount="1" desc="Check if given path points to a directory">
<Function name="IsPathDirectory" retType="bool" paramCount="1" desc="Check if provided path points to a directory">
<Param type="const char *" name="path" desc="" />
</Function>
<Function name="IsPathAbsolute" retType="bool" paramCount="1" desc="Check if provided path is an absolute path">
<Param type="const char *" name="path" desc="" />
</Function>
<Function name="IsFileNameValid" retType="bool" paramCount="1" desc="Check if fileName is valid for the platform/OS">
@ -1319,7 +1322,7 @@
<Function name="GetTouchPosition" retType="Vector2" paramCount="1" desc="Get touch position XY for a touch point index (relative to screen size)">
<Param type="int" name="index" desc="" />
</Function>
<Function name="GetTouchPointId" retType="int" paramCount="1" desc="Get touch point identifier for given index">
<Function name="GetTouchPointId" retType="int" paramCount="1" desc="Get touch point identifier for provided index">
<Param type="int" name="index" desc="" />
</Function>
<Function name="GetTouchPointCount" retType="int" paramCount="0" desc="Get number of touch points">
@ -2039,7 +2042,7 @@
<Param type="int" name="x" desc="" />
<Param type="int" name="y" desc="" />
</Function>
<Function name="ImageClearBackground" retType="void" paramCount="2" desc="Clear image background with given color">
<Function name="ImageClearBackground" retType="void" paramCount="2" desc="Clear image background with provided color">
<Param type="Image *" name="dst" desc="" />
<Param type="Color" name="color" desc="" />
</Function>