|
@@ -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;
|
|
|
|
-
|
|
|
|
- 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] == ' '))
|
|
|
|
|
|
+ if (rgsFile != NULL)
|
|
{
|
|
{
|
|
- short controlId = 0;
|
|
|
|
- short propertyId = 0;
|
|
|
|
- unsigned int propertyValue = 0;
|
|
|
|
|
|
+ fseek(rgsFile, 0, SEEK_END);
|
|
|
|
+ int fileDataSize = ftell(rgsFile);
|
|
|
|
+ fseek(rgsFile, 0, SEEK_SET);
|
|
|
|
|
|
- for (int i = 0; i < propertyCount; i++)
|
|
|
|
|
|
+ if (fileDataSize > 0)
|
|
{
|
|
{
|
|
- fread(&controlId, sizeof(short), 1, rgsFile);
|
|
|
|
- fread(&propertyId, sizeof(short), 1, rgsFile);
|
|
|
|
- fread(&propertyValue, sizeof(unsigned int), 1, rgsFile);
|
|
|
|
-
|
|
|
|
- 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);
|
|
|
|
|
|
+ unsigned char *fileData = (unsigned char *)RL_MALLOC(fileDataSize*sizeof(unsigned char));
|
|
|
|
+ fread(fileData, sizeof(unsigned char), fileDataSize, rgsFile);
|
|
|
|
+
|
|
|
|
+ GuiLoadStyleFromMemory(fileData, fileDataSize);
|
|
|
|
+
|
|
|
|
+ RL_FREE(fileData);
|
|
}
|
|
}
|
|
|
|
|
|
- // 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;
|
|
|
|
- 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);
|
|
}
|
|
}
|
|
-
|
|
|
|
- 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
|