diff --git a/games/transmission/screens/screen_ending.c b/games/transmission/screens/screen_ending.c index d9ed46962..e6ab3518c 100644 --- a/games/transmission/screens/screen_ending.c +++ b/games/transmission/screens/screen_ending.c @@ -113,7 +113,7 @@ void InitEndingScreen(void) strcpy(headline, title); // Base headline updated - free(title); + if (title != NULL) free(title); } } diff --git a/src/raylib.h b/src/raylib.h index fba973d0e..782dd4e5b 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -948,19 +948,20 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) +RLAPI void UnloadSpriteFont(SpriteFont font); // Unload SpriteFont from GPU memory (VRAM) // Text drawing functions RLAPI void DrawFPS(int posX, int posY); // Shows current FPS RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) -RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters +RLAPI void DrawTextEx(SpriteFont font, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters float fontSize, int spacing, Color tint); // Text misc. functions RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font -RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont +RLAPI Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont RLAPI const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed' RLAPI const char *SubText(const char *text, int position, int length); // Get a piece of a text string +RLAPI int GetGlyphIndex(SpriteFont font, int character); // Returns index position for a unicode character on sprite font //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) diff --git a/src/text.c b/src/text.c index 227992e65..2a05773cb 100644 --- a/src/text.c +++ b/src/text.c @@ -90,11 +90,9 @@ static SpriteFont defaultFont; // Default font provided by raylib //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static int GetCharIndex(SpriteFont font, int letter); - static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style) #if defined(SUPPORT_FILEFORMAT_FNT) -static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) +static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) #endif #if defined(SUPPORT_FILEFORMAT_TTF) static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data @@ -345,13 +343,13 @@ SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, } // Unload SpriteFont from GPU memory (VRAM) -void UnloadSpriteFont(SpriteFont spriteFont) +void UnloadSpriteFont(SpriteFont font) { // NOTE: Make sure spriteFont is not default font (fallback) - if (spriteFont.texture.id != GetDefaultFont().texture.id) + if (font.texture.id != GetDefaultFont().texture.id) { - UnloadTexture(spriteFont.texture); - free(spriteFont.chars); + UnloadTexture(font.texture); + free(font.chars); TraceLog(LOG_DEBUG, "Unloaded sprite font data"); } @@ -377,7 +375,7 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color) // Draw text using SpriteFont // NOTE: chars spacing is NOT proportional to fontSize -void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float fontSize, int spacing, Color tint) +void DrawTextEx(SpriteFont font, const char *text, Vector2 position, float fontSize, int spacing, Color tint) { int length = strlen(text); int textOffsetX = 0; // Offset between characters @@ -387,7 +385,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float unsigned char letter; // Current character int index; // Index position in sprite font - scaleFactor = fontSize/spriteFont.baseSize; + scaleFactor = fontSize/font.baseSize; // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly // written in C code files (codified by default as UTF-8) @@ -397,7 +395,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float if ((unsigned char)text[i] == '\n') { // NOTE: Fixed line spacing of 1.5 lines - textOffsetY += (int)((spriteFont.baseSize + spriteFont.baseSize/2)*scaleFactor); + textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor); textOffsetX = 0; } else @@ -406,29 +404,29 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float { // Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿) letter = (unsigned char)text[i + 1]; - index = GetCharIndex(spriteFont, (int)letter); + index = GetGlyphIndex(font, (int)letter); i++; } else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK! { // Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ) letter = (unsigned char)text[i + 1]; - index = GetCharIndex(spriteFont, (int)letter + 64); + index = GetGlyphIndex(font, (int)letter + 64); i++; } - else index = GetCharIndex(spriteFont, (unsigned char)text[i]); + else index = GetGlyphIndex(font, (unsigned char)text[i]); if ((unsigned char)text[i] != ' ') { - DrawTexturePro(spriteFont.texture, spriteFont.chars[index].rec, - (Rectangle){ position.x + textOffsetX + spriteFont.chars[index].offsetX*scaleFactor, - position.y + textOffsetY + spriteFont.chars[index].offsetY*scaleFactor, - spriteFont.chars[index].rec.width*scaleFactor, - spriteFont.chars[index].rec.height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); + DrawTexturePro(font.texture, font.chars[index].rec, + (Rectangle){ position.x + textOffsetX + font.chars[index].offsetX*scaleFactor, + position.y + textOffsetY + font.chars[index].offsetY*scaleFactor, + font.chars[index].rec.width*scaleFactor, + font.chars[index].rec.height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); } - if (spriteFont.chars[index].advanceX == 0) textOffsetX += (int)(spriteFont.chars[index].rec.width*scaleFactor + spacing); - else textOffsetX += (int)(spriteFont.chars[index].advanceX*scaleFactor + spacing); + if (font.chars[index].advanceX == 0) textOffsetX += (int)(font.chars[index].rec.width*scaleFactor + spacing); + else textOffsetX += (int)(font.chars[index].advanceX*scaleFactor + spacing); } } } @@ -490,7 +488,7 @@ int MeasureText(const char *text, int fontSize) } // Measure string size for SpriteFont -Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) +Vector2 MeasureTextEx(SpriteFont font, const char *text, float fontSize, int spacing) { int len = strlen(text); int tempLen = 0; // Used to count longer text line num chars @@ -499,8 +497,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i float textWidth = 0; float tempTextWidth = 0; // Used to count longer text line width - float textHeight = (float)spriteFont.baseSize; - float scaleFactor = fontSize/(float)spriteFont.baseSize; + float textHeight = (float)font.baseSize; + float scaleFactor = fontSize/(float)font.baseSize; for (int i = 0; i < len; i++) { @@ -508,17 +506,17 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (text[i] != '\n') { - int index = GetCharIndex(spriteFont, (int)text[i]); + int index = GetGlyphIndex(font, (int)text[i]); - if (spriteFont.chars[index].advanceX != 0) textWidth += spriteFont.chars[index].advanceX; - else textWidth += (spriteFont.chars[index].rec.width + spriteFont.chars[index].offsetX); + if (font.chars[index].advanceX != 0) textWidth += font.chars[index].advanceX; + else textWidth += (font.chars[index].rec.width + font.chars[index].offsetX); } else { if (tempTextWidth < textWidth) tempTextWidth = textWidth; lenCounter = 0; textWidth = 0; - textHeight += ((float)spriteFont.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines + textHeight += ((float)font.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines } if (tempLen < lenCounter) tempLen = lenCounter; @@ -533,6 +531,28 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i return vec; } +// Returns index position for a unicode character on spritefont +int GetGlyphIndex(SpriteFont font, int character) +{ +#define UNORDERED_CHARSET +#if defined(UNORDERED_CHARSET) + int index = 0; + + for (int i = 0; i < font.charsCount; i++) + { + if (font.chars[i].value == character) + { + index = i; + break; + } + } + + return index; +#else + return (character - 32); +#endif +} + // Shows current FPS on top-left corner // NOTE: Uses default font void DrawFPS(int posX, int posY) @@ -559,27 +579,6 @@ void DrawFPS(int posX, int posY) // Module specific Functions Definition //---------------------------------------------------------------------------------- -static int GetCharIndex(SpriteFont font, int letter) -{ -#define UNORDERED_CHARSET -#if defined(UNORDERED_CHARSET) - int index = 0; - - for (int i = 0; i < font.charsCount; i++) - { - if (font.chars[i].value == letter) - { - index = i; - break; - } - } - - return index; -#else - return (letter - 32); -#endif -} - // Load an Image font file (XNA style) static SpriteFont LoadImageFont(Image image, Color key, int firstChar) { diff --git a/src/textures.c b/src/textures.c index 2772e2463..ba0bad543 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1374,6 +1374,8 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing { int length = strlen(text); int posX = 0; + int index; // Index position in sprite font + unsigned char character; // Current character Vector2 imSize = MeasureTextEx(font, text, font.baseSize, spacing); @@ -1389,13 +1391,39 @@ Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing for (int i = 0; i < length; i++) { - CharInfo letter = font.chars[(int)text[i] - 32]; - - ImageDraw(&imText, imFont, letter.rec, (Rectangle){ posX + letter.offsetX, - letter.offsetY, letter.rec.width, letter.rec.height }); + if ((unsigned char)text[i] == '\n') + { + // TODO: Support line break + } + else + { + if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK! + { + // Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿) + character = (unsigned char)text[i + 1]; + index = GetGlyphIndex(font, (int)character); + i++; + } + else if ((unsigned char)text[i] == 0xc3) // UTF-8 encoding identification HACK! + { + // Support UTF-8 encoded values from [0xc3 0x80](À) -> [0xc3 0xbf](ÿ) + character = (unsigned char)text[i + 1]; + index = GetGlyphIndex(font, (int)character + 64); + i++; + } + else index = GetGlyphIndex(font, (unsigned char)text[i]); - if (letter.advanceX == 0) posX += letter.rec.width + spacing; - else posX += letter.advanceX + spacing; + CharInfo letter = font.chars[index]; + + if ((unsigned char)text[i] != ' ') + { + ImageDraw(&imText, imFont, letter.rec, (Rectangle){ posX + letter.offsetX, + letter.offsetY, letter.rec.width, letter.rec.height }); + } + + if (letter.advanceX == 0) posX += letter.rec.width + spacing; + else posX += letter.advanceX + spacing; + } } UnloadImage(imFont);