Skip to content

Commit 4184a5b

Browse files
committed
Update text_unicode_font_example.c
1 parent 5d7e801 commit 4184a5b

File tree

1 file changed

+98
-98
lines changed

1 file changed

+98
-98
lines changed

examples/text/text_unicode_font_example.c

Lines changed: 98 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4,178 +4,178 @@
44

55
#define SCREEN_WIDTH 800
66
#define SCREEN_HEIGHT 450
7+
#define INITIAL_CAPACITY 65536 // 2^16 - sufficient for most Unicode BMP characters
78

8-
Font LoadUnicodeFont(const char* fileName, int fontSize, int textureFilter)
9+
10+
static int AddCodeRange(int* codePoints, int* count, int start, int stop)
911
{
10-
int* cp = NULL; // Array to store Unicode codepoints
11-
int capacity = 65536; // Initial capacity
12-
int count = 0; // Counter for codepoints
13-
14-
// Allocate initial array
15-
cp = (int*)malloc(capacity * sizeof(int));
16-
if (!cp) return GetFontDefault();
17-
18-
// Helper function to add a range of Unicode codepoints
19-
void AddRange(int start, int stop)
20-
{
21-
while (start <= stop)
22-
{
23-
// Expand array if needed
24-
if (count >= capacity)
25-
{
26-
capacity += 1024;
27-
int* newCp = (int*)realloc(cp, capacity * sizeof(int));
28-
if (!newCp)
29-
{
30-
free(cp);
31-
return GetFontDefault();
32-
}
33-
cp = newCp;
34-
}
35-
36-
// Add current codepoint and increment
37-
cp[count] = start;
38-
count++;
39-
start++;
40-
}
12+
// Verify we have enough capacity for this range
13+
if (*count + (stop - start + 1) > INITIAL_CAPACITY) {
14+
return 0; // Not enough space
15+
}
16+
17+
// Add all code points in the range
18+
while (start <= stop) {
19+
codePoints[*count] = start;
20+
(*count)++;
21+
start++;
4122
}
23+
return 1; // Success
24+
}
25+
26+
Font LoadUnicodeFont(const char* fileName, int fontSize, int textureFilter)
27+
{
28+
// Allocate memory for code points (fixed size - no reallocation needed)
29+
int* codePoints = (int*)malloc(INITIAL_CAPACITY * sizeof(int));
30+
if (!codePoints) return GetFontDefault();
4231

32+
int count = 0; // Tracks number of added code points
33+
4334
// --------------------------------------------------
4435
// 1. BASIC ASCII CHARACTERS
4536
// --------------------------------------------------
46-
AddRange(32, 126); // Basic Latin (letters, digits, punctuation)
37+
AddCodeRange(codePoints, &count, 32, 126); // Basic Latin (letters, digits, punctuation)
4738

4839
// --------------------------------------------------
4940
// 2. EUROPEAN LANGUAGES (LATIN SCRIPT)
5041
// --------------------------------------------------
51-
AddRange(0xC0, 0x17F); // Latin-1 Supplement + Latin Extended-A
52-
AddRange(0x180, 0x24F); // Latin Extended-B
53-
AddRange(0x1E00, 0x1EFF); // Latin Extended Additional
54-
AddRange(0x2C60, 0x2C7F); // Latin Extended-C
42+
AddCodeRange(codePoints, &count, 0xC0, 0x17F); // Latin-1 Supplement + Latin Extended-A
43+
AddCodeRange(codePoints, &count, 0x180, 0x24F); // Latin Extended-B
44+
AddCodeRange(codePoints, &count, 0x1E00, 0x1EFF); // Latin Extended Additional
45+
AddCodeRange(codePoints, &count, 0x2C60, 0x2C7F); // Latin Extended-C
5546

5647
// --------------------------------------------------
5748
// 3. GREEK AND COPTIC
5849
// --------------------------------------------------
59-
AddRange(0x370, 0x3FF); // Greek and Coptic
60-
AddRange(0x1F00, 0x1FFF); // Greek Extended
50+
AddCodeRange(codePoints, &count, 0x370, 0x3FF); // Greek and Coptic
51+
AddCodeRange(codePoints, &count, 0x1F00, 0x1FFF); // Greek Extended
6152

6253
// --------------------------------------------------
6354
// 4. CYRILLIC SCRIPTS
6455
// --------------------------------------------------
65-
AddRange(0x400, 0x4FF); // Basic Cyrillic
66-
AddRange(0x500, 0x52F); // Cyrillic Supplement
67-
AddRange(0x2DE0, 0x2DFF); // Cyrillic Extended-A
68-
AddRange(0xA640, 0xA69F); // Cyrillic Extended-B
56+
AddCodeRange(codePoints, &count, 0x400, 0x4FF); // Basic Cyrillic
57+
AddCodeRange(codePoints, &count, 0x500, 0x52F); // Cyrillic Supplement
58+
AddCodeRange(codePoints, &count, 0x2DE0, 0x2DFF); // Cyrillic Extended-A
59+
AddCodeRange(codePoints, &count, 0xA640, 0xA69F); // Cyrillic Extended-B
6960

7061
// --------------------------------------------------
7162
// 5. CJK LANGUAGES (CHINESE, JAPANESE, KOREAN)
7263
// --------------------------------------------------
73-
AddRange(0x4E00, 0x9FFF); // CJK Unified Ideographs
74-
AddRange(0x3400, 0x4DBF); // CJK Extension A
75-
AddRange(0x3000, 0x303F); // CJK Symbols and Punctuation
76-
AddRange(0x3040, 0x309F); // Hiragana (Japanese)
77-
AddRange(0x30A0, 0x30FF); // Katakana (Japanese)
78-
AddRange(0x31F0, 0x31FF); // Katakana Phonetic Extensions
79-
AddRange(0xFF00, 0xFFEF); // Halfwidth and Fullwidth Forms
80-
AddRange(0xAC00, 0xD7AF); // Hangul Syllables (Korean)
81-
AddRange(0x1100, 0x11FF); // Hangul Jamo
64+
AddCodeRange(codePoints, &count, 0x4E00, 0x9FFF); // CJK Unified Ideographs
65+
AddCodeRange(codePoints, &count, 0x3400, 0x4DBF); // CJK Extension A
66+
AddCodeRange(codePoints, &count, 0x3000, 0x303F); // CJK Symbols and Punctuation
67+
AddCodeRange(codePoints, &count, 0x3040, 0x309F); // Hiragana (Japanese)
68+
AddCodeRange(codePoints, &count, 0x30A0, 0x30FF); // Katakana (Japanese)
69+
AddCodeRange(codePoints, &count, 0x31F0, 0x31FF); // Katakana Phonetic Extensions
70+
AddCodeRange(codePoints, &count, 0xFF00, 0xFFEF); // Halfwidth and Fullwidth Forms
71+
AddCodeRange(codePoints, &count, 0xAC00, 0xD7AF); // Hangul Syllables (Korean)
72+
AddCodeRange(codePoints, &count, 0x1100, 0x11FF); // Hangul Jamo
8273

8374
// --------------------------------------------------
8475
// 6. SOUTHEAST ASIAN LANGUAGES
8576
// --------------------------------------------------
86-
AddRange(0x0E00, 0x0E7F); // Thai
87-
AddRange(0x0E80, 0x0EFF); // Lao
88-
AddRange(0x1780, 0x17FF); // Khmer
89-
AddRange(0x1000, 0x109F); // Myanmar
90-
AddRange(0x1980, 0x19DF); // New Tai Lue
77+
AddCodeRange(codePoints, &count, 0x0E00, 0x0E7F); // Thai
78+
AddCodeRange(codePoints, &count, 0x0E80, 0x0EFF); // Lao
79+
AddCodeRange(codePoints, &count, 0x1780, 0x17FF); // Khmer
80+
AddCodeRange(codePoints, &count, 0x1000, 0x109F); // Myanmar
81+
AddCodeRange(codePoints, &count, 0x1980, 0x19DF); // New Tai Lue
9182

9283
// --------------------------------------------------
9384
// 7. INDIAN SUBCONTINENT LANGUAGES
9485
// --------------------------------------------------
95-
AddRange(0x900, 0x97F); // Devanagari (Hindi, Sanskrit)
96-
AddRange(0x980, 0x9FF); // Bengali
97-
AddRange(0xA00, 0xA7F); // Gurmukhi (Punjabi)
98-
AddRange(0xA80, 0xAFF); // Gujarati
99-
AddRange(0xB00, 0xB7F); // Oriya
100-
AddRange(0xB80, 0xBFF); // Tamil
101-
AddRange(0xC00, 0xC7F); // Telugu
102-
AddRange(0xC80, 0xCFF); // Kannada
103-
AddRange(0xD00, 0xD7F); // Malayalam
104-
AddRange(0xD80, 0xDFF); // Sinhala
86+
AddCodeRange(codePoints, &count, 0x900, 0x97F); // Devanagari (Hindi, Sanskrit)
87+
AddCodeRange(codePoints, &count, 0x980, 0x9FF); // Bengali
88+
AddCodeRange(codePoints, &count, 0xA00, 0xA7F); // Gurmukhi (Punjabi)
89+
AddCodeRange(codePoints, &count, 0xA80, 0xAFF); // Gujarati
90+
AddCodeRange(codePoints, &count, 0xB00, 0xB7F); // Oriya
91+
AddCodeRange(codePoints, &count, 0xB80, 0xBFF); // Tamil
92+
AddCodeRange(codePoints, &count, 0xC00, 0xC7F); // Telugu
93+
AddCodeRange(codePoints, &count, 0xC80, 0xCFF); // Kannada
94+
AddCodeRange(codePoints, &count, 0xD00, 0xD7F); // Malayalam
95+
AddCodeRange(codePoints, &count, 0xD80, 0xDFF); // Sinhala
10596

10697
// --------------------------------------------------
10798
// 8. MIDDLE EASTERN LANGUAGES
10899
// --------------------------------------------------
109-
AddRange(0x600, 0x6FF); // Arabic
110-
AddRange(0x750, 0x77F); // Arabic Supplement
111-
AddRange(0x8A0, 0x8FF); // Arabic Extended-A
112-
AddRange(0xFB50, 0xFDFF); // Arabic Presentation Forms-A
113-
AddRange(0x5D0, 0x5EA); // Hebrew
114-
AddRange(0x591, 0x5C7); // Hebrew Extended
115-
AddRange(0x7C0, 0x7FF); // N'Ko
116-
AddRange(0x640, 0x6FF); // Syriac
100+
AddCodeRange(codePoints, &count, 0x600, 0x6FF); // Arabic
101+
AddCodeRange(codePoints, &count, 0x750, 0x77F); // Arabic Supplement
102+
AddCodeRange(codePoints, &count, 0x8A0, 0x8FF); // Arabic Extended-A
103+
AddCodeRange(codePoints, &count, 0xFB50, 0xFDFF); // Arabic Presentation Forms-A
104+
AddCodeRange(codePoints, &count, 0x5D0, 0x5EA); // Hebrew
105+
AddCodeRange(codePoints, &count, 0x591, 0x5C7); // Hebrew Extended
106+
AddCodeRange(codePoints, &count, 0x7C0, 0x7FF); // N'Ko
107+
AddCodeRange(codePoints, &count, 0x640, 0x6FF); // Syriac
117108

118109
// --------------------------------------------------
119110
// 9. AFRICAN LANGUAGES
120111
// --------------------------------------------------
121-
AddRange(0x2C80, 0x2CFF); // Coptic
122-
AddRange(0x2D30, 0x2D7F); // Tifinagh
123-
AddRange(0xA6A0, 0xA6FF); // Bamum
124-
AddRange(0xAB00, 0xAB2F); // Ethiopic Extended
112+
AddCodeRange(codePoints, &count, 0x2C80, 0x2CFF); // Coptic
113+
AddCodeRange(codePoints, &count, 0x2D30, 0x2D7F); // Tifinagh
114+
AddCodeRange(codePoints, &count, 0xA6A0, 0xA6FF); // Bamum
115+
AddCodeRange(codePoints, &count, 0xAB00, 0xAB2F); // Ethiopic Extended
125116

126117
// --------------------------------------------------
127118
// 10. SPECIAL CHARACTERS AND SYMBOLS
128119
// --------------------------------------------------
129-
AddRange(0x300, 0x36F); // Combining Diacritical Marks
130-
AddRange(0x1DC0, 0x1DFF); // Combining Diacritical Marks Supplement
131-
AddRange(0x2000, 0x206F); // General Punctuation
132-
AddRange(0x20A0, 0x20CF); // Currency Symbols
133-
AddRange(0x2100, 0x214F); // Letterlike Symbols
134-
AddRange(0x2190, 0x21FF); // Arrows
135-
AddRange(0x2200, 0x22FF); // Mathematical Operators
120+
AddCodeRange(codePoints, &count, 0x300, 0x36F); // Combining Diacritical Marks
121+
AddCodeRange(codePoints, &count, 0x1DC0, 0x1DFF); // Combining Diacritical Marks Supplement
122+
AddCodeRange(codePoints, &count, 0x2000, 0x206F); // General Punctuation
123+
AddCodeRange(codePoints, &count, 0x20A0, 0x20CF); // Currency Symbols
124+
AddCodeRange(codePoints, &count, 0x2100, 0x214F); // Letterlike Symbols
125+
AddCodeRange(codePoints, &count, 0x2190, 0x21FF); // Arrows
126+
AddCodeRange(codePoints, &count, 0x2200, 0x22FF); // Mathematical Operators
136127

137-
138128
Font result = {0};
139129

140-
if (FileExists(fileName))
141-
result = LoadFontEx(fileName, fontSize, cp, count);
130+
// Attempt to load the font with collected code points
131+
if (FileExists(fileName)) {
132+
result = LoadFontEx(fileName, fontSize, codePoints, count);
133+
}
142134

143-
if (result.texture.id == 0)
135+
// Fallback to default font if loading fails
136+
if (result.texture.id == 0) {
144137
result = GetFontDefault();
138+
}
145139

140+
// Apply texture filtering
146141
SetTextureFilter(result.texture, textureFilter);
147-
free(cp);
142+
143+
// Clean up
144+
free(codePoints);
148145
return result;
149146
}
150147

148+
/**
149+
* Main entry point
150+
*/
151151
int main(void)
152152
{
153-
// Initialization
153+
// Initialize window
154154
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Unicode Font Example");
155155
SetTargetFPS(60);
156156

157157
// Load font with Unicode support
158158
Font myFont = LoadUnicodeFont("resources/NotoSansTC-Regular.ttf", 36, TEXTURE_FILTER_BILINEAR);
159159

160-
// Main game loop
160+
// Main render loop
161161
while (!WindowShouldClose())
162162
{
163163
BeginDrawing();
164164
ClearBackground(RAYWHITE);
165165

166-
// Draw text
166+
// Render test strings in different languages
167167
DrawTextEx(myFont, "English: Hello World!", (Vector2){50, 50}, 36, 1, DARKGRAY);
168168
DrawTextEx(myFont, "Русский: Привет мир!", (Vector2){50, 100}, 36, 0, DARKGRAY);
169169
DrawTextEx(myFont, "中文: 你好世界!", (Vector2){50, 150}, 36, 1, DARKGRAY);
170170
DrawTextEx(myFont, "日本語: こんにちは世界!", (Vector2){50, 200}, 36, 1, DARKGRAY);
171171

172-
173-
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);
174-
172+
// Display font attribution
173+
DrawText("Font: Noto Sans TC. License: SIL Open Font License 1.1",
174+
10, SCREEN_HEIGHT - 20, 10, GRAY);
175175
EndDrawing();
176176
}
177177

178-
// Cleanup
178+
// Cleanup resources
179179
UnloadFont(myFont);
180180
CloseWindow();
181181

0 commit comments

Comments
 (0)