From 4184a5b25140366974bd039ba4876ff7e4cf9c79 Mon Sep 17 00:00:00 2001 From: Gunko Vadim Date: Fri, 11 Apr 2025 18:43:12 +0500 Subject: [PATCH] Update text_unicode_font_example.c --- examples/text/text_unicode_font_example.c | 196 +++++++++++----------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/examples/text/text_unicode_font_example.c b/examples/text/text_unicode_font_example.c index 486b1058c..494ce159e 100644 --- a/examples/text/text_unicode_font_example.c +++ b/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 + + +static int AddCodeRange(int* codePoints, int* count, int start, int stop) +{ + // 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) { - 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++; - } - } + // 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();