mirror of
https://github.com/raysan5/raygui.git
synced 2026-01-30 10:49:19 -05:00
ADDED: GuiLoadStyleFromMemory() (binary only)
REVIEWED: `GetCodepointNext()`
This commit is contained in:
274
src/raygui.h
274
src/raygui.h
@ -1302,6 +1302,8 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only)
|
||||||
|
|
||||||
static int GetTextWidth(const char *text); // Gui get text width using gui font and style
|
static int GetTextWidth(const char *text); // Gui get text width using gui font and style
|
||||||
static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds
|
static Rectangle GetTextBounds(int control, Rectangle bounds); // Get text bounds considering control bounds
|
||||||
static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor
|
static const char *GetTextIcon(const char *text, int *iconId); // Get text icon if provided and move text cursor
|
||||||
@ -3429,125 +3431,24 @@ void GuiLoadStyle(const char *fileName)
|
|||||||
{
|
{
|
||||||
rgsFile = fopen(fileName, "rb");
|
rgsFile = fopen(fileName, "rb");
|
||||||
|
|
||||||
if (rgsFile == NULL) return;
|
if (rgsFile != NULL)
|
||||||
|
|
||||||
char signature[5] = { 0 };
|
|
||||||
short version = 0;
|
|
||||||
short reserved = 0;
|
|
||||||
int propertyCount = 0;
|
|
||||||
|
|
||||||
fread(signature, 1, 4, rgsFile);
|
|
||||||
fread(&version, sizeof(short), 1, rgsFile);
|
|
||||||
fread(&reserved, sizeof(short), 1, rgsFile);
|
|
||||||
fread(&propertyCount, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
if ((signature[0] == 'r') &&
|
|
||||||
(signature[1] == 'G') &&
|
|
||||||
(signature[2] == 'S') &&
|
|
||||||
(signature[3] == ' '))
|
|
||||||
{
|
{
|
||||||
short controlId = 0;
|
fseek(rgsFile, 0, SEEK_END);
|
||||||
short propertyId = 0;
|
int fileDataSize = ftell(rgsFile);
|
||||||
unsigned int propertyValue = 0;
|
fseek(rgsFile, 0, SEEK_SET);
|
||||||
|
|
||||||
for (int i = 0; i < propertyCount; i++)
|
if (fileDataSize > 0)
|
||||||
{
|
{
|
||||||
fread(&controlId, sizeof(short), 1, rgsFile);
|
unsigned char *fileData = (unsigned char *)RL_MALLOC(fileDataSize*sizeof(unsigned char));
|
||||||
fread(&propertyId, sizeof(short), 1, rgsFile);
|
fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile);
|
||||||
fread(&propertyValue, sizeof(unsigned int), 1, rgsFile);
|
|
||||||
|
GuiLoadStyleFromMemory(fileData, fileDataSize);
|
||||||
if (controlId == 0) // DEFAULT control
|
|
||||||
{
|
RL_FREE(fileData);
|
||||||
// If a DEFAULT property is loaded, it is propagated to all controls
|
|
||||||
// NOTE: All DEFAULT properties should be defined first in the file
|
|
||||||
GuiSetStyle(0, (int)propertyId, propertyValue);
|
|
||||||
|
|
||||||
if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) GuiSetStyle(i, (int)propertyId, propertyValue);
|
|
||||||
}
|
|
||||||
else GuiSetStyle((int)controlId, (int)propertyId, propertyValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Font loading is highly dependant on raylib API to load font data and image
|
fclose(rgsFile);
|
||||||
#if !defined(RAYGUI_STANDALONE)
|
|
||||||
// Load custom font if available
|
|
||||||
int fontDataSize = 0;
|
|
||||||
fread(&fontDataSize, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
if (fontDataSize > 0)
|
|
||||||
{
|
|
||||||
Font font = { 0 };
|
|
||||||
int fontType = 0; // 0-Normal, 1-SDF
|
|
||||||
Rectangle whiteRec = { 0 };
|
|
||||||
|
|
||||||
fread(&font.baseSize, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphCount, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&fontType, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
// Load font white rectangle
|
|
||||||
fread(&whiteRec, sizeof(Rectangle), 1, rgsFile);
|
|
||||||
|
|
||||||
// Load font image parameters
|
|
||||||
int fontImageUncompSize = 0;
|
|
||||||
int fontImageCompSize = 0;
|
|
||||||
fread(&fontImageUncompSize, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&fontImageCompSize, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
Image imFont = { 0 };
|
|
||||||
imFont.mipmaps = 1;
|
|
||||||
fread(&imFont.width, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&imFont.height, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&imFont.format, sizeof(int), 1, rgsFile);
|
|
||||||
|
|
||||||
if (fontImageCompSize < fontImageUncompSize)
|
|
||||||
{
|
|
||||||
// Compressed font atlas image data (DEFLATE), it requires DecompressData()
|
|
||||||
int dataUncompSize = 0;
|
|
||||||
unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize);
|
|
||||||
fread(compData, 1, fontImageCompSize, rgsFile);
|
|
||||||
imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize);
|
|
||||||
|
|
||||||
// Security check, dataUncompSize must match the provided fontImageUncompSize
|
|
||||||
if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted");
|
|
||||||
|
|
||||||
RAYGUI_FREE(compData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Font atlas image data is not compressed
|
|
||||||
imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize);
|
|
||||||
fread(imFont.data, 1, fontImageUncompSize, rgsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
|
|
||||||
font.texture = LoadTextureFromImage(imFont);
|
|
||||||
if (font.texture.id == 0) font = GetFontDefault();
|
|
||||||
|
|
||||||
RAYGUI_FREE(imFont.data);
|
|
||||||
|
|
||||||
// Load font recs data
|
|
||||||
font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle));
|
|
||||||
for (int i = 0; i < font.glyphCount; i++) fread(&font.recs[i], sizeof(Rectangle), 1, rgsFile);
|
|
||||||
|
|
||||||
// Load font chars info data
|
|
||||||
font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo));
|
|
||||||
for (int i = 0; i < font.glyphCount; i++)
|
|
||||||
{
|
|
||||||
fread(&font.glyphs[i].value, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphs[i].offsetX, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphs[i].offsetY, sizeof(int), 1, rgsFile);
|
|
||||||
fread(&font.glyphs[i].advanceX, sizeof(int), 1, rgsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
GuiSetFont(font);
|
|
||||||
|
|
||||||
// Set font texture source rectangle to be used as white texture to draw shapes
|
|
||||||
// NOTE: This way, all gui can be draw using a single draw call
|
|
||||||
if ((whiteRec.width != 0) && (whiteRec.height != 0)) SetShapesTexture(font.texture, whiteRec);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(rgsFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3785,6 +3686,145 @@ void GuiSetIconScale(int scale)
|
|||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Load style from memory (binary only)
|
||||||
|
static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize)
|
||||||
|
{
|
||||||
|
unsigned char *fileDataPtr = (unsigned char *)fileData;
|
||||||
|
|
||||||
|
char signature[5] = { 0 };
|
||||||
|
short version = 0;
|
||||||
|
short reserved = 0;
|
||||||
|
int propertyCount = 0;
|
||||||
|
|
||||||
|
memcpy(signature, fileDataPtr, 4);
|
||||||
|
memcpy(&version, fileDataPtr + 4, sizeof(short));
|
||||||
|
memcpy(&reserved, fileDataPtr + 4 + 2, sizeof(short));
|
||||||
|
memcpy(&propertyCount, fileDataPtr + 4 + 2 + 2, sizeof(int));
|
||||||
|
fileDataPtr += 12;
|
||||||
|
|
||||||
|
if ((signature[0] == 'r') &&
|
||||||
|
(signature[1] == 'G') &&
|
||||||
|
(signature[2] == 'S') &&
|
||||||
|
(signature[3] == ' '))
|
||||||
|
{
|
||||||
|
short controlId = 0;
|
||||||
|
short propertyId = 0;
|
||||||
|
unsigned int propertyValue = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < propertyCount; i++)
|
||||||
|
{
|
||||||
|
memcpy(&controlId, fileDataPtr, sizeof(short));
|
||||||
|
memcpy(&propertyId, fileDataPtr + 2, sizeof(short));
|
||||||
|
memcpy(&propertyValue, fileDataPtr + 2 + 2, sizeof(unsigned int));
|
||||||
|
fileDataPtr += 8;
|
||||||
|
|
||||||
|
if (controlId == 0) // DEFAULT control
|
||||||
|
{
|
||||||
|
// If a DEFAULT property is loaded, it is propagated to all controls
|
||||||
|
// NOTE: All DEFAULT properties should be defined first in the file
|
||||||
|
GuiSetStyle(0, (int)propertyId, propertyValue);
|
||||||
|
|
||||||
|
if (propertyId < RAYGUI_MAX_PROPS_BASE) for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) GuiSetStyle(i, (int)propertyId, propertyValue);
|
||||||
|
}
|
||||||
|
else GuiSetStyle((int)controlId, (int)propertyId, propertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Font loading is highly dependant on raylib API to load font data and image
|
||||||
|
|
||||||
|
#if !defined(RAYGUI_STANDALONE)
|
||||||
|
// Load custom font if available
|
||||||
|
int fontDataSize = 0;
|
||||||
|
memcpy(&fontDataSize, fileDataPtr, sizeof(int));
|
||||||
|
fileDataPtr += 4;
|
||||||
|
|
||||||
|
if (fontDataSize > 0)
|
||||||
|
{
|
||||||
|
Font font = { 0 };
|
||||||
|
int fontType = 0; // 0-Normal, 1-SDF
|
||||||
|
Rectangle whiteRec = { 0 };
|
||||||
|
|
||||||
|
memcpy(&font.baseSize, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&font.glyphCount, fileDataPtr + 4, sizeof(int));
|
||||||
|
memcpy(&fontType, fileDataPtr + 4 + 4, sizeof(int));
|
||||||
|
fileDataPtr += 12;
|
||||||
|
|
||||||
|
// Load font white rectangle
|
||||||
|
memcpy(&whiteRec, fileDataPtr, sizeof(Rectangle));
|
||||||
|
fileDataPtr += 16;
|
||||||
|
|
||||||
|
// Load font image parameters
|
||||||
|
int fontImageUncompSize = 0;
|
||||||
|
int fontImageCompSize = 0;
|
||||||
|
memcpy(&fontImageUncompSize, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&fontImageCompSize, fileDataPtr + 4, sizeof(int));
|
||||||
|
fileDataPtr += 8;
|
||||||
|
|
||||||
|
Image imFont = { 0 };
|
||||||
|
imFont.mipmaps = 1;
|
||||||
|
memcpy(&imFont.width, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&imFont.height, fileDataPtr + 4, sizeof(int));
|
||||||
|
memcpy(&imFont.format, fileDataPtr + 4 + 4, sizeof(int));
|
||||||
|
fileDataPtr += 12;
|
||||||
|
|
||||||
|
if (fontImageCompSize < fontImageUncompSize)
|
||||||
|
{
|
||||||
|
// Compressed font atlas image data (DEFLATE), it requires DecompressData()
|
||||||
|
int dataUncompSize = 0;
|
||||||
|
unsigned char *compData = (unsigned char *)RAYGUI_MALLOC(fontImageCompSize);
|
||||||
|
memcpy(compData, fileDataPtr, fontImageCompSize);
|
||||||
|
fileDataPtr += fontImageCompSize;
|
||||||
|
|
||||||
|
imFont.data = DecompressData(compData, fontImageCompSize, &dataUncompSize);
|
||||||
|
|
||||||
|
// Security check, dataUncompSize must match the provided fontImageUncompSize
|
||||||
|
if (dataUncompSize != fontImageUncompSize) RAYGUI_LOG("WARNING: Uncompressed font atlas image data could be corrupted");
|
||||||
|
|
||||||
|
RAYGUI_FREE(compData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Font atlas image data is not compressed
|
||||||
|
imFont.data = (unsigned char *)RAYGUI_MALLOC(fontImageUncompSize);
|
||||||
|
memcpy(imFont.data, fileDataPtr, fontImageUncompSize);
|
||||||
|
fileDataPtr += fontImageUncompSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font.texture.id != GetFontDefault().texture.id) UnloadTexture(font.texture);
|
||||||
|
font.texture = LoadTextureFromImage(imFont);
|
||||||
|
if (font.texture.id == 0) font = GetFontDefault();
|
||||||
|
|
||||||
|
RAYGUI_FREE(imFont.data);
|
||||||
|
|
||||||
|
// Load font recs data
|
||||||
|
font.recs = (Rectangle *)RAYGUI_CALLOC(font.glyphCount, sizeof(Rectangle));
|
||||||
|
for (int i = 0; i < font.glyphCount; i++)
|
||||||
|
{
|
||||||
|
memcpy(&font.recs[i], fileDataPtr, sizeof(Rectangle));
|
||||||
|
fileDataPtr += sizeof(Rectangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load font chars info data
|
||||||
|
font.glyphs = (GlyphInfo *)RAYGUI_CALLOC(font.glyphCount, sizeof(GlyphInfo));
|
||||||
|
for (int i = 0; i < font.glyphCount; i++)
|
||||||
|
{
|
||||||
|
memcpy(&font.glyphs[i].value, fileDataPtr, sizeof(int));
|
||||||
|
memcpy(&font.glyphs[i].offsetX, fileDataPtr + 4, sizeof(int));
|
||||||
|
memcpy(&font.glyphs[i].offsetY, fileDataPtr + 8, sizeof(int));
|
||||||
|
memcpy(&font.glyphs[i].advanceX, fileDataPtr + 12, sizeof(int));
|
||||||
|
fileDataPtr += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiSetFont(font);
|
||||||
|
|
||||||
|
// Set font texture source rectangle to be used as white texture to draw shapes
|
||||||
|
// NOTE: This way, all gui can be draw using a single draw call
|
||||||
|
if ((whiteRec.width != 0) && (whiteRec.height != 0)) SetShapesTexture(font.texture, whiteRec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Gui get text width considering icon
|
// Gui get text width considering icon
|
||||||
static int GetTextWidth(const char *text)
|
static int GetTextWidth(const char *text)
|
||||||
{
|
{
|
||||||
@ -4612,34 +4652,38 @@ static int GetCodepointNext(const char *text, int *codepointSize)
|
|||||||
{
|
{
|
||||||
const char *ptr = text;
|
const char *ptr = text;
|
||||||
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
||||||
*codepointSize = 0;
|
*codepointSize = 1;
|
||||||
|
|
||||||
// Get current codepoint and bytes processed
|
// Get current codepoint and bytes processed
|
||||||
if (0xf0 == (0xf8 & ptr[0]))
|
if (0xf0 == (0xf8 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 4 byte UTF-8 codepoint
|
// 4 byte UTF-8 codepoint
|
||||||
|
if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
|
||||||
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
|
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
|
||||||
*codepointSize = 4;
|
*codepointSize = 4;
|
||||||
}
|
}
|
||||||
else if (0xe0 == (0xf0 & ptr[0]))
|
else if (0xe0 == (0xf0 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 3 byte UTF-8 codepoint */
|
// 3 byte UTF-8 codepoint */
|
||||||
|
if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
|
||||||
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
|
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
|
||||||
*codepointSize = 3;
|
*codepointSize = 3;
|
||||||
}
|
}
|
||||||
else if (0xc0 == (0xe0 & ptr[0]))
|
else if (0xc0 == (0xe0 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 2 byte UTF-8 codepoint
|
// 2 byte UTF-8 codepoint
|
||||||
|
if((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks
|
||||||
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
|
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
|
||||||
*codepointSize = 2;
|
*codepointSize = 2;
|
||||||
}
|
}
|
||||||
else
|
else if (0x00 == (0x80 & ptr[0]))
|
||||||
{
|
{
|
||||||
// 1 byte UTF-8 codepoint
|
// 1 byte UTF-8 codepoint
|
||||||
codepoint = ptr[0];
|
codepoint = ptr[0];
|
||||||
*codepointSize = 1;
|
*codepointSize = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return codepoint;
|
return codepoint;
|
||||||
}
|
}
|
||||||
#endif // RAYGUI_STANDALONE
|
#endif // RAYGUI_STANDALONE
|
||||||
|
|||||||
Reference in New Issue
Block a user