14 Commits

Author SHA1 Message Date
101502103a Fixed FLAG_IS_SET to check if all bits in the flag are set in the value (#5441) 2025-12-24 20:58:40 +01:00
Ray
20dd4641c8 REVIEWED: Potential security concerns while copying unbounded text data between strings
Note that issue has been reported by CodeQL static analysis system
2025-12-24 19:35:06 +01:00
Ray
fc843dc557 Create SECURITY.md 2025-12-24 19:21:43 +01:00
Ray
9103f6e055 ADDED: New platform backend for Web: Emscripten, not dependant on GLFW.js -WIP- 2025-12-24 18:58:20 +01:00
Ray
ced84333a9 Update rl_gputex.h 2025-12-24 18:02:24 +01:00
Ray
05f42aa119 Update core_highdpi_testbed.c 2025-12-24 18:02:04 +01:00
a1e84caa8c RGFW also requires RGBA8 images as window icons, as raylib already reports in raylib.h (#5431) 2025-12-24 09:04:41 +01:00
ddb827fb6f Fixed LoadCodepoints declaring a new local variable shadowing codpoints (#5430) 2025-12-24 08:59:51 +01:00
0a4583ca54 [rl_gputex.h] Possibly fixed the swizzling in rl_load_dds_from_memory() function (#5422)
* Possibly fixed the swizzling bug

* Removed examples, and generation.
2025-12-23 17:10:55 +01:00
6a701b2679 fix android SetWindowState (#5424) 2025-12-23 15:37:08 +01:00
Ray
aa2884bd78 Update rcore_desktop_glfw.c 2025-12-22 22:50:38 +01:00
Ray
f27f2d097f REVIEWED: HighDPI support on macOS (when requested by app)
Tested on two monitors with different DPI configuration, for HigDPI enabled and not, including window resizing (with framebuffer resizing if required). Verified mouse coordinates follow the requested screen size.
2025-12-22 22:48:08 +01:00
Ray
e4baf682ab Update rtext.c 2025-12-22 20:30:11 +01:00
Ray
8516750975 Remove internal function 2025-12-22 20:29:57 +01:00
11 changed files with 1829 additions and 119 deletions

18
SECURITY.md Normal file
View File

@ -0,0 +1,18 @@
# Security Policy
## Supported Versions
Most considerations of errors and defects can be handled using the project Issues and/or Discussions.
| Version | Supported |
| ------- | ------------------ |
| 6.0.x | :white_check_mark: |
| < 5.5 | :x: |
## Reporting a Vulnerability
Discovered vulnerability can be directly reported using the project Issues and/or Discussions.
_TODO: Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc._

View File

@ -27,7 +27,7 @@ int main(void)
const int screenWidth = 800;
const int screenHeight = 450;
SetConfigFlags(FLAG_WINDOW_HIGHDPI | FLAG_WINDOW_RESIZABLE);
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI);
InitWindow(screenWidth, screenHeight, "raylib [core] example - highdpi testbed");
Vector2 scaleDpi = GetWindowScaleDPI();

View File

@ -308,7 +308,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned char alpha = 0;
// NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1
for (int i = 0; i < image_pixel_size; i++)
for (int i = 0; i < data_size/sizeof(unsigned short); i++)
{
alpha = ((unsigned short *)image_data)[i] >> 15;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1;
@ -328,7 +328,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
unsigned char alpha = 0;
// NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4
for (int i = 0; i < image_pixel_size; i++)
for (int i = 0; i < data_size/sizeof(unsigned short); i++)
{
alpha = ((unsigned short *)image_data)[i] >> 12;
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4;
@ -339,7 +339,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
}
}
}
else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed
else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed
{
int data_size = image_pixel_size*3*sizeof(unsigned char);
if (header->mipmap_count > 1) data_size = data_size + data_size/3;
@ -362,7 +362,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
// NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment)
// DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA
// So, we must realign B8G8R8A8 to R8G8B8A8
for (int i = 0; i < image_pixel_size*4; i += 4)
for (int i = 0; i < data_size; i += 4)
{
blue = ((unsigned char *)image_data)[i];
((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2];

View File

@ -360,7 +360,7 @@ void SetWindowState(unsigned int flags)
if (!CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetWindowState does nothing before window initialization, Use \"SetConfigFlags\" instead");
// State change: FLAG_WINDOW_ALWAYS_RUN
if (!FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN);
if (FLAG_IS_SET(flags, FLAG_WINDOW_ALWAYS_RUN)) FLAG_SET(CORE.Window.flags, FLAG_WINDOW_ALWAYS_RUN);
}
// Clear window configuration state flags

View File

@ -135,12 +135,12 @@ static void ErrorCallback(int error, const char *description);
// Window callbacks events
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
static void FramebufferSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 FramebufferSize Callback, runs when window is resized
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale
static void WindowPosCallback(GLFWwindow *window, int x, int y); // GLFW3 WindowPos Callback, runs when window is moved
static void WindowIconifyCallback(GLFWwindow *window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
static void WindowMaximizeCallback(GLFWwindow *window, int maximized); // GLFW3 Window Maximize Callback, runs when window is maximized
static void WindowFocusCallback(GLFWwindow *window, int focused); // GLFW3 WindowFocus Callback, runs when window get/lose focus
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths); // GLFW3 Window Drop Callback, runs when drop files into window
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley); // GLFW3 Window Content Scale Callback, runs when window changes scale
// Input callbacks events
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
@ -156,8 +156,6 @@ static void *AllocateWrapper(size_t size, void *user);
static void *ReallocateWrapper(void *block, size_t size, void *user); // GLFW3 GLFWreallocatefun, wrapps around RL_REALLOC macro
static void DeallocateWrapper(void *block, void *user); // GLFW3 GLFWdeallocatefun, wraps around RL_FREE macro
static void SetDimensionsFromMonitor(GLFWmonitor *monitor); // Set screen dimensions from monitor/display dimensions
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
@ -1026,8 +1024,8 @@ Vector2 GetWindowPosition(void)
// Get window scale DPI factor for current monitor
Vector2 GetWindowScaleDPI(void)
{
Vector2 scale = { 0 };
glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
Vector2 scale = { 1.0f, 1.0f };
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) glfwGetWindowContentScale(platform.handle, &scale.x, &scale.y);
return scale;
}
@ -1454,12 +1452,18 @@ int InitPlatform(void)
// NOTE: This hint only has an effect on platforms where screen coordinates and
// pixels always map 1:1 such as Windows and X11
// On platforms like macOS the resolution of the framebuffer is changed independently of the window size
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); // Scale content area based on the monitor content scale where window is placed on
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
#if defined(__APPLE__)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
#endif
}
else glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
else
{
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE);
#if defined(__APPLE__)
glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE);
#endif
}
// Mouse passthrough
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MOUSE_PASSTHROUGH)) glfwWindowHint(GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE);
@ -1529,17 +1533,24 @@ int InitPlatform(void)
GLFWmonitor *monitor = NULL;
if (CORE.Window.fullscreen)
{
// According to glfwCreateWindow(), if the user does not have a choice, fullscreen applications
// should default to the primary monitor
// NOTE: Fullscreen applications default to the primary monitor
monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return -1;
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return -1;
}
SetDimensionsFromMonitor(monitor);
// Set dimensions from monitor
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
// Default display resolution to that of the current mode
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
// Remember center for switching from fullscreen to window
if ((CORE.Window.screen.height == CORE.Window.display.height) && (CORE.Window.screen.width == CORE.Window.display.width))
@ -1628,7 +1639,15 @@ int InitPlatform(void)
if (monitorIndex < monitorCount)
{
monitor = monitors[monitorIndex];
SetDimensionsFromMonitor(monitor);
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
// Default display resolution to that of the current mode
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
if (requestWindowedFullscreen) glfwSetWindowSize(platform.handle, CORE.Window.screen.width, CORE.Window.screen.height);
}
@ -1831,6 +1850,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
}
// GLFW3: Framebuffer size change callback, runs when framebuffer is resized
// WARNING: If FLAG_WINDOW_HIGHDPI is set, WindowContentScaleCallback() is called before this function
static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
{
//TRACELOG(LOG_INFO, "GLFW3: Window framebuffer size callback called [%i,%i]", width, height);
@ -1848,23 +1868,48 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height)
CORE.Window.currentFbo.height = height;
CORE.Window.resizedLastFrame = true;
if (IsWindowFullscreen()) return;
// Check if render size was actually scaled for high-dpi
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
// Set screen size to logical pixel size, considering content scaling
Vector2 scaleDpi = GetWindowScaleDPI();
width = (int)((float)width/scaleDpi.x);
height = (int)((float)height/scaleDpi.y);
CORE.Window.screen.width = (int)((float)width/scaleDpi.x);
CORE.Window.screen.height = (int)((float)height/scaleDpi.y);
}
else
{
// Set screen size to render size (physical pixel size)
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
}
// Set current screen size
CORE.Window.screen.width = width;
CORE.Window.screen.height = height;
// WARNING: If using a render texture, it is not scaled to new size
}
// GLFW3: Window content scale callback, runs on monitor content scale change detected
// WARNING: If FLAG_WINDOW_HIGHDPI is not set, this function is not called
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
{
TRACELOG(LOG_INFO, "GLFW3: Window content scale changed, scale: [%.2f,%.2f]", scalex, scaley);
float fbWidth = (float)CORE.Window.screen.width*scalex;
float fbHeight = (float)CORE.Window.screen.height*scaley;
// NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling
// Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
#if !defined(__APPLE__)
// Mouse input scaling for the new screen size
SetMouseScale((float)CORE.Window.screen.width/fbWidth, (float)CORE.Window.screen.height/fbHeight);
#endif
CORE.Window.render.width = (int)fbWidth;
CORE.Window.render.height = (int)fbHeight;
CORE.Window.currentFbo.width = (int)fbWidth;
CORE.Window.currentFbo.height = (int)fbHeight;
}
// GLFW3: Window position callback, runs when window position changes
static void WindowPosCallback(GLFWwindow *window, int x, int y)
{
@ -1873,29 +1918,6 @@ static void WindowPosCallback(GLFWwindow *window, int x, int y)
CORE.Window.position.y = y;
}
// GLFW3: Window content scale callback, runs on monitor content scale change detected
static void WindowContentScaleCallback(GLFWwindow *window, float scalex, float scaley)
{
TRACELOG(LOG_INFO, "GLFW3: Window content scale changed, scale: [%.2f,%.2f]", scalex, scaley);
float fbWidth = (float)CORE.Window.screen.width*scalex;
float fbHeight = (float)CORE.Window.screen.height*scaley;
#if !defined(__APPLE__)
// NOTE: On APPLE platforms system should manage window/input scaling and also framebuffer scaling
// Framebuffer scaling is activated with: glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_TRUE);
CORE.Window.screenScale = MatrixScale(scalex, scaley, 1.0f);
// Mouse input scaling for the new screen size
SetMouseScale(1.0f/scalex, 1.0f/scaley);
#endif
CORE.Window.render.width = (int)fbWidth;
CORE.Window.render.height = (int)fbHeight;
CORE.Window.currentFbo.width = (int)fbWidth;
CORE.Window.currentFbo.height = (int)fbHeight;
}
// GLFW3: Window iconify callback, runs when window is minimized/restored
static void WindowIconifyCallback(GLFWwindow *window, int iconified)
{
@ -1940,7 +1962,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[i], paths[i]);
strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
}
}
}
@ -2085,20 +2107,6 @@ static void JoystickCallback(int jid, int event)
}
}
// Set screen dimensions from monitor/display dimensions
static void SetDimensionsFromMonitor(GLFWmonitor *monitor)
{
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
// Default display resolution to that of the current mode
CORE.Window.display.width = mode->width;
CORE.Window.display.height = mode->height;
// Set screen width/height to the display width/height if they are 0
if (CORE.Window.screen.width == 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height == 0) CORE.Window.screen.height = CORE.Window.display.height;
}
#ifdef _WIN32
# define WIN32_CLIPBOARD_IMPLEMENTATION
# include "../external/win32_clipboard.h"

View File

@ -522,46 +522,15 @@ void ClearWindowState(unsigned int flags)
}
}
int RGFW_formatToChannels(int format)
{
switch (format)
{
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE:
case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float)
case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float)
return 1;
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels)
case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha)
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp
return 2;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha)
case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp
return 3;
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float)
case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float)
case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha)
case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp
return 4;
default: return 4;
}
}
// Set icon for window
void SetWindowIcon(Image image)
{
RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), RGFW_formatToChannels(image.format));
if (image.format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
return;
}
RGFW_window_setIcon(platform.window, (u8 *)image.data, RGFW_AREA(image.width, image.height), 4);
}
// Set icon for window
@ -578,12 +547,17 @@ void SetWindowIcons(Image *images, int count)
for (int i = 0; i < count; i++)
{
if (images[i].format != PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
{
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
continue;
}
if ((bigIcon == NULL) || ((images[i].width > bigIcon->width) && (images[i].height > bigIcon->height))) bigIcon = &images[i];
if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i];
}
if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), RGFW_formatToChannels(smallIcon->format), RGFW_iconWindow);
if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), RGFW_formatToChannels(bigIcon->format), RGFW_iconTaskbar);
if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, RGFW_AREA(smallIcon->width, smallIcon->height), 4, RGFW_iconWindow);
if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, RGFW_AREA(bigIcon->width, bigIcon->height), 4, RGFW_iconTaskbar);
}
}

View File

@ -1431,9 +1431,9 @@ void PollInputEvents(void)
// Event memory is now managed by SDL, so you should not free the data in SDL_EVENT_DROP_FILE,
// and if you want to hold onto the text in SDL_EVENT_TEXT_EDITING and SDL_EVENT_TEXT_INPUT events,
// you should make a copy of it. SDL_TEXTINPUTEVENT_TEXT_SIZE is no longer necessary and has been removed
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
#else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
SDL_free(event.drop.file);
#endif
@ -1444,9 +1444,9 @@ void PollInputEvents(void)
CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
#if defined(USING_VERSION_SDL3)
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data);
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.data, MAX_FILEPATH_LENGTH - 1);
#else
strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file);
strncpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event.drop.file, MAX_FILEPATH_LENGTH - 1);
SDL_free(event.drop.file);
#endif

View File

@ -1531,7 +1531,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++)
{
CORE.Window.dropFilepaths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char));
strcpy(CORE.Window.dropFilepaths[i], paths[i]);
strncpy(CORE.Window.dropFilepaths[i], paths[i], MAX_FILEPATH_LENGTH - 1);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -273,7 +273,7 @@
#define FLAG_SET(n, f) ((n) |= (f))
#define FLAG_CLEAR(n, f) ((n) &= ~(f))
#define FLAG_TOGGLE(n, f) ((n) ^= (f))
#define FLAG_IS_SET(n, f) (((n) & (f)) > 0)
#define FLAG_IS_SET(n, f) (((n) & (f)) == (f))
//----------------------------------------------------------------------------------
// Types and Structures Definition

View File

@ -700,7 +700,11 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
switch (type)
{
case FONT_DEFAULT:
case FONT_BITMAP: glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); break;
case FONT_BITMAP:
{
glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp,
&cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY);
} break;
case FONT_SDF:
{
if (cp != 32)
@ -1593,14 +1597,13 @@ float TextToFloat(const char *text)
#if defined(SUPPORT_TEXT_MANIPULATION)
// Copy one string to another, returns bytes copied
// NOTE: Alternative implementation to strcpy(dst, src) from C standard library
int TextCopy(char *dst, const char *src)
{
int bytes = 0;
if ((src != NULL) && (dst != NULL))
{
// NOTE: Alternative: use strcpy(dst, src)
while (*src != '\0')
{
*dst = *src;
@ -1713,11 +1716,13 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
{
char *insertPoint = NULL; // Next insert point
char *temp = NULL; // Temp pointer
int textLen = 0; // Text string length
int searchLen = 0; // Search string length of (the string to remove)
int replaceLen = 0; // Replacement length (the string to replace by)
int lastReplacePos = 0; // Distance between next search and end of last replace
int count = 0; // Number of replacements
textLen = TextLength(text);
searchLen = TextLength(search);
if (searchLen == 0) return NULL; // Empty search causes infinite loop during count
@ -1728,7 +1733,8 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
for (count = 0; (temp = strstr(insertPoint, search)); count++) insertPoint = temp + searchLen;
// Allocate returning string and point temp to it
temp = result = (char *)RL_MALLOC(TextLength(text) + (replaceLen - searchLen)*count + 1);
int tempLen = textLen + (replaceLen - searchLen)*count + 1;
temp = result = (char *)RL_MALLOC(tempLen);
if (!result) return NULL; // Memory could not be allocated
@ -1740,13 +1746,16 @@ char *TextReplace(const char *text, const char *search, const char *replacement)
{
insertPoint = (char *)strstr(text, search);
lastReplacePos = (int)(insertPoint - text);
temp = strncpy(temp, text, lastReplacePos) + lastReplacePos;
temp = strcpy(temp, replacement) + replaceLen;
temp = strncpy(temp, text, tempLen - 1) + lastReplacePos;
tempLen -= lastReplacePos;
temp = strncpy(temp, replacement, tempLen - 1) + replaceLen;
tempLen -= replaceLen;
text += lastReplacePos + searchLen; // Move to next "end of replace"
}
// Copy remaind text part after replacement to result (pointed by moving temp)
strcpy(temp, text);
strncpy(temp, text, tempLen - 1);
}
return result;
@ -2086,7 +2095,7 @@ int *LoadCodepoints(const char *text, int *count)
int textLength = TextLength(text);
// Allocate a big enough buffer to store as many codepoints as text bytes
int *codepoints = (int *)RL_CALLOC(textLength, sizeof(int));
codepoints = (int *)RL_CALLOC(textLength, sizeof(int));
int codepointSize = 0;
for (int i = 0; i < textLength; codepointCount++)