소스 검색

Support UTF8 basic characters on ImageTextEx()

Supported UTF8 range equivalent to [128..255] (80h..FFh)
Exposed and renamed text function GetGlyphIndex()
Renamed spriteFont parameter name to simply font
Small security check on transmission mission ending screen
raysan5 7 년 전
부모
커밋
4492a70a4b
4개의 변경된 파일86개의 추가작업 그리고 58개의 파일을 삭제
  1. 1 1
      games/transmission/screens/screen_ending.c
  2. 4 3
      src/raylib.h
  3. 47 48
      src/text.c
  4. 34 6
      src/textures.c

+ 1 - 1
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);
         }
     }
     

+ 4 - 3
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)

+ 47 - 48
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)
 {

+ 34 - 6
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);