瀏覽代碼

Update text_unicode_font_example.c

Gunko Vadim 5 月之前
父節點
當前提交
4184a5b251
共有 1 個文件被更改,包括 98 次插入98 次删除
  1. 98 98
      examples/text/text_unicode_font_example.c

+ 98 - 98
examples/text/text_unicode_font_example.c

@@ -4,178 +4,178 @@
 
 #define SCREEN_WIDTH  800
 #define SCREEN_HEIGHT 450
+#define INITIAL_CAPACITY 65536  // 2^16 - sufficient for most Unicode BMP characters
 
-Font LoadUnicodeFont(const char* fileName, int fontSize, int textureFilter)
+
+static int AddCodeRange(int* codePoints, int* count, int start, int stop)
 {
-    int* cp = NULL;         // Array to store Unicode codepoints
-    int capacity = 65536;   // Initial capacity
-    int count = 0;          // Counter for codepoints
-    
-    // Allocate initial array
-    cp = (int*)malloc(capacity * sizeof(int));
-    if (!cp) return GetFontDefault();
-    
-    // Helper function to add a range of Unicode codepoints
-    void AddRange(int start, int stop)
-    {
-        while (start <= stop)
-        {
-            // Expand array if needed
-            if (count >= capacity)
-            {
-                capacity += 1024;
-                int* newCp = (int*)realloc(cp, capacity * sizeof(int));
-                if (!newCp)
-                {
-                    free(cp);
-                    return GetFontDefault();
-                }
-                cp = newCp;
-            }
-            
-            // Add current codepoint and increment
-            cp[count] = start;
-            count++;
-            start++;
-        }
+    // Verify we have enough capacity for this range
+    if (*count + (stop - start + 1) > INITIAL_CAPACITY) {
+        return 0;  // Not enough space
+    }
+
+    // Add all code points in the range
+    while (start <= stop) {
+        codePoints[*count] = start;
+        (*count)++;
+        start++;
     }
+    return 1;  // Success
+}
+
+Font LoadUnicodeFont(const char* fileName, int fontSize, int textureFilter)
+{
+    // Allocate memory for code points (fixed size - no reallocation needed)
+    int* codePoints = (int*)malloc(INITIAL_CAPACITY * sizeof(int));
+    if (!codePoints) return GetFontDefault();
     
+    int count = 0;  // Tracks number of added code points
+
     // --------------------------------------------------
     // 1. BASIC ASCII CHARACTERS
     // --------------------------------------------------
-    AddRange(32, 126);  // Basic Latin (letters, digits, punctuation)
+    AddCodeRange(codePoints, &count, 32, 126);  // Basic Latin (letters, digits, punctuation)
     
     // --------------------------------------------------
     // 2. EUROPEAN LANGUAGES (LATIN SCRIPT)
     // --------------------------------------------------
-    AddRange(0xC0, 0x17F);  // Latin-1 Supplement + Latin Extended-A
-    AddRange(0x180, 0x24F); // Latin Extended-B
-    AddRange(0x1E00, 0x1EFF); // Latin Extended Additional
-    AddRange(0x2C60, 0x2C7F); // Latin Extended-C
+    AddCodeRange(codePoints, &count, 0xC0, 0x17F);  // Latin-1 Supplement + Latin Extended-A
+    AddCodeRange(codePoints, &count, 0x180, 0x24F); // Latin Extended-B
+    AddCodeRange(codePoints, &count, 0x1E00, 0x1EFF); // Latin Extended Additional
+    AddCodeRange(codePoints, &count, 0x2C60, 0x2C7F); // Latin Extended-C
     
     // --------------------------------------------------
     // 3. GREEK AND COPTIC
     // --------------------------------------------------
-    AddRange(0x370, 0x3FF); // Greek and Coptic
-    AddRange(0x1F00, 0x1FFF); // Greek Extended
+    AddCodeRange(codePoints, &count, 0x370, 0x3FF); // Greek and Coptic
+    AddCodeRange(codePoints, &count, 0x1F00, 0x1FFF); // Greek Extended
     
     // --------------------------------------------------
     // 4. CYRILLIC SCRIPTS
     // --------------------------------------------------
-    AddRange(0x400, 0x4FF); // Basic Cyrillic
-    AddRange(0x500, 0x52F); // Cyrillic Supplement
-    AddRange(0x2DE0, 0x2DFF); // Cyrillic Extended-A
-    AddRange(0xA640, 0xA69F); // Cyrillic Extended-B
+    AddCodeRange(codePoints, &count, 0x400, 0x4FF); // Basic Cyrillic
+    AddCodeRange(codePoints, &count, 0x500, 0x52F); // Cyrillic Supplement
+    AddCodeRange(codePoints, &count, 0x2DE0, 0x2DFF); // Cyrillic Extended-A
+    AddCodeRange(codePoints, &count, 0xA640, 0xA69F); // Cyrillic Extended-B
     
     // --------------------------------------------------
     // 5. CJK LANGUAGES (CHINESE, JAPANESE, KOREAN)
     // --------------------------------------------------
-    AddRange(0x4E00, 0x9FFF); // CJK Unified Ideographs
-    AddRange(0x3400, 0x4DBF); // CJK Extension A
-    AddRange(0x3000, 0x303F); // CJK Symbols and Punctuation
-    AddRange(0x3040, 0x309F); // Hiragana (Japanese)
-    AddRange(0x30A0, 0x30FF); // Katakana (Japanese)
-    AddRange(0x31F0, 0x31FF); // Katakana Phonetic Extensions
-    AddRange(0xFF00, 0xFFEF); // Halfwidth and Fullwidth Forms
-    AddRange(0xAC00, 0xD7AF); // Hangul Syllables (Korean)
-    AddRange(0x1100, 0x11FF); // Hangul Jamo
+    AddCodeRange(codePoints, &count, 0x4E00, 0x9FFF); // CJK Unified Ideographs
+    AddCodeRange(codePoints, &count, 0x3400, 0x4DBF); // CJK Extension A
+    AddCodeRange(codePoints, &count, 0x3000, 0x303F); // CJK Symbols and Punctuation
+    AddCodeRange(codePoints, &count, 0x3040, 0x309F); // Hiragana (Japanese)
+    AddCodeRange(codePoints, &count, 0x30A0, 0x30FF); // Katakana (Japanese)
+    AddCodeRange(codePoints, &count, 0x31F0, 0x31FF); // Katakana Phonetic Extensions
+    AddCodeRange(codePoints, &count, 0xFF00, 0xFFEF); // Halfwidth and Fullwidth Forms
+    AddCodeRange(codePoints, &count, 0xAC00, 0xD7AF); // Hangul Syllables (Korean)
+    AddCodeRange(codePoints, &count, 0x1100, 0x11FF); // Hangul Jamo
     
     // --------------------------------------------------
     // 6. SOUTHEAST ASIAN LANGUAGES
     // --------------------------------------------------
-    AddRange(0x0E00, 0x0E7F); // Thai
-    AddRange(0x0E80, 0x0EFF); // Lao
-    AddRange(0x1780, 0x17FF); // Khmer
-    AddRange(0x1000, 0x109F); // Myanmar
-    AddRange(0x1980, 0x19DF); // New Tai Lue
+    AddCodeRange(codePoints, &count, 0x0E00, 0x0E7F); // Thai
+    AddCodeRange(codePoints, &count, 0x0E80, 0x0EFF); // Lao
+    AddCodeRange(codePoints, &count, 0x1780, 0x17FF); // Khmer
+    AddCodeRange(codePoints, &count, 0x1000, 0x109F); // Myanmar
+    AddCodeRange(codePoints, &count, 0x1980, 0x19DF); // New Tai Lue
     
     // --------------------------------------------------
     // 7. INDIAN SUBCONTINENT LANGUAGES
     // --------------------------------------------------
-    AddRange(0x900, 0x97F);  // Devanagari (Hindi, Sanskrit)
-    AddRange(0x980, 0x9FF);  // Bengali
-    AddRange(0xA00, 0xA7F);  // Gurmukhi (Punjabi)
-    AddRange(0xA80, 0xAFF);  // Gujarati
-    AddRange(0xB00, 0xB7F);  // Oriya
-    AddRange(0xB80, 0xBFF);  // Tamil
-    AddRange(0xC00, 0xC7F);  // Telugu
-    AddRange(0xC80, 0xCFF);  // Kannada
-    AddRange(0xD00, 0xD7F);  // Malayalam
-    AddRange(0xD80, 0xDFF);  // Sinhala
+    AddCodeRange(codePoints, &count, 0x900, 0x97F);  // Devanagari (Hindi, Sanskrit)
+    AddCodeRange(codePoints, &count, 0x980, 0x9FF);  // Bengali
+    AddCodeRange(codePoints, &count, 0xA00, 0xA7F);  // Gurmukhi (Punjabi)
+    AddCodeRange(codePoints, &count, 0xA80, 0xAFF);  // Gujarati
+    AddCodeRange(codePoints, &count, 0xB00, 0xB7F);  // Oriya
+    AddCodeRange(codePoints, &count, 0xB80, 0xBFF);  // Tamil
+    AddCodeRange(codePoints, &count, 0xC00, 0xC7F);  // Telugu
+    AddCodeRange(codePoints, &count, 0xC80, 0xCFF);  // Kannada
+    AddCodeRange(codePoints, &count, 0xD00, 0xD7F);  // Malayalam
+    AddCodeRange(codePoints, &count, 0xD80, 0xDFF);  // Sinhala
     
     // --------------------------------------------------
     // 8. MIDDLE EASTERN LANGUAGES
     // --------------------------------------------------
-    AddRange(0x600, 0x6FF);  // Arabic
-    AddRange(0x750, 0x77F);  // Arabic Supplement
-    AddRange(0x8A0, 0x8FF);  // Arabic Extended-A
-    AddRange(0xFB50, 0xFDFF); // Arabic Presentation Forms-A
-    AddRange(0x5D0, 0x5EA);  // Hebrew
-    AddRange(0x591, 0x5C7);  // Hebrew Extended
-    AddRange(0x7C0, 0x7FF);  // N'Ko
-    AddRange(0x640, 0x6FF);  // Syriac
+    AddCodeRange(codePoints, &count, 0x600, 0x6FF);  // Arabic
+    AddCodeRange(codePoints, &count, 0x750, 0x77F);  // Arabic Supplement
+    AddCodeRange(codePoints, &count, 0x8A0, 0x8FF);  // Arabic Extended-A
+    AddCodeRange(codePoints, &count, 0xFB50, 0xFDFF); // Arabic Presentation Forms-A
+    AddCodeRange(codePoints, &count, 0x5D0, 0x5EA);  // Hebrew
+    AddCodeRange(codePoints, &count, 0x591, 0x5C7);  // Hebrew Extended
+    AddCodeRange(codePoints, &count, 0x7C0, 0x7FF);  // N'Ko
+    AddCodeRange(codePoints, &count, 0x640, 0x6FF);  // Syriac
     
     // --------------------------------------------------
     // 9. AFRICAN LANGUAGES
     // --------------------------------------------------
-    AddRange(0x2C80, 0x2CFF); // Coptic
-    AddRange(0x2D30, 0x2D7F); // Tifinagh
-    AddRange(0xA6A0, 0xA6FF); // Bamum
-    AddRange(0xAB00, 0xAB2F); // Ethiopic Extended
+    AddCodeRange(codePoints, &count, 0x2C80, 0x2CFF); // Coptic
+    AddCodeRange(codePoints, &count, 0x2D30, 0x2D7F); // Tifinagh
+    AddCodeRange(codePoints, &count, 0xA6A0, 0xA6FF); // Bamum
+    AddCodeRange(codePoints, &count, 0xAB00, 0xAB2F); // Ethiopic Extended
     
     // --------------------------------------------------
     // 10. SPECIAL CHARACTERS AND SYMBOLS
     // --------------------------------------------------
-    AddRange(0x300, 0x36F);  // Combining Diacritical Marks
-    AddRange(0x1DC0, 0x1DFF); // Combining Diacritical Marks Supplement
-    AddRange(0x2000, 0x206F); // General Punctuation
-    AddRange(0x20A0, 0x20CF); // Currency Symbols
-    AddRange(0x2100, 0x214F); // Letterlike Symbols
-    AddRange(0x2190, 0x21FF); // Arrows
-    AddRange(0x2200, 0x22FF); // Mathematical Operators
+    AddCodeRange(codePoints, &count, 0x300, 0x36F);  // Combining Diacritical Marks
+    AddCodeRange(codePoints, &count, 0x1DC0, 0x1DFF); // Combining Diacritical Marks Supplement
+    AddCodeRange(codePoints, &count, 0x2000, 0x206F); // General Punctuation
+    AddCodeRange(codePoints, &count, 0x20A0, 0x20CF); // Currency Symbols
+    AddCodeRange(codePoints, &count, 0x2100, 0x214F); // Letterlike Symbols
+    AddCodeRange(codePoints, &count, 0x2190, 0x21FF); // Arrows
+    AddCodeRange(codePoints, &count, 0x2200, 0x22FF); // Mathematical Operators
 
-    
     Font result = {0};
     
-    if (FileExists(fileName))
-        result = LoadFontEx(fileName, fontSize, cp, count);
+    // Attempt to load the font with collected code points
+    if (FileExists(fileName)) {
+        result = LoadFontEx(fileName, fontSize, codePoints, count);
+    }
     
-    if (result.texture.id == 0)
+    // Fallback to default font if loading fails
+    if (result.texture.id == 0) {
         result = GetFontDefault();
+    }
     
+    // Apply texture filtering
     SetTextureFilter(result.texture, textureFilter);
-    free(cp);
+    
+    // Clean up
+    free(codePoints);
     return result;
 }
 
+/**
+ * Main entry point
+ */
 int main(void)
 {
-    // Initialization
+    // Initialize window
     InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Unicode Font Example");
     SetTargetFPS(60);
 
     // Load font with Unicode support
     Font myFont = LoadUnicodeFont("resources/NotoSansTC-Regular.ttf", 36, TEXTURE_FILTER_BILINEAR);
 
-    // Main game loop
+    // Main render loop
     while (!WindowShouldClose())
     {
         BeginDrawing();
             ClearBackground(RAYWHITE);
             
-            // Draw text
+            // Render test strings in different languages
             DrawTextEx(myFont, "English: Hello World!", (Vector2){50, 50}, 36, 1, DARKGRAY);
             DrawTextEx(myFont, "Русский: Привет мир!", (Vector2){50, 100}, 36, 0, DARKGRAY);
             DrawTextEx(myFont, "中文: 你好世界!", (Vector2){50, 150}, 36, 1, DARKGRAY);
             DrawTextEx(myFont, "日本語: こんにちは世界!", (Vector2){50, 200}, 36, 1, DARKGRAY);
 
-           
-            DrawText("Font: Noto Sans TC Thin. © 2014-2020 Adobe(http://www.adobe.com/). License: SIL Open Font License 1.1", 10, SCREEN_HEIGHT - 20, 10, GRAY);
-
+            // Display font attribution
+            DrawText("Font: Noto Sans TC. License: SIL Open Font License 1.1", 
+                    10, SCREEN_HEIGHT - 20, 10, GRAY);
         EndDrawing();
     }
 
-    // Cleanup
+    // Cleanup resources
     UnloadFont(myFont);
     CloseWindow();