@@ -173,6 +173,7 @@ int sth_add_font_from_memory(struct sth_stash* stash, unsigned char* buffer) {
173
173
fnt -> idx = idx ;
174
174
fnt -> type = TTFONT_MEM ;
175
175
fnt -> next = stash -> fonts ;
176
+ fnt -> nfallbacks = 0 ;
176
177
stash -> fonts = fnt ;
177
178
return idx ++ ;
178
179
@@ -328,7 +329,26 @@ inline int sth_add_glyph_for_char(struct sth_stash* stash, int idx, GLuint id,
328
329
return sth_add_glyph_for_codepoint (stash , idx , id , codepoint , size , base , x ,
329
330
y , w , h , xoffset , yoffset , xadvance );
330
331
}
331
-
332
+ //
333
+ int sth_add_fallback_font (struct sth_font * font ,int fallback_id ){
334
+ if (font -> nfallbacks <=FONS_MAX_FALLBACKS ){
335
+ font -> fallbacks [font -> nfallbacks ]= fallback_id ;
336
+ font -> nfallbacks ++ ;
337
+ return font -> nfallbacks ;
338
+ }else {
339
+ return -1 ;
340
+ }
341
+ }
342
+ struct sth_font * get_font_by_index (struct sth_stash * stash , int idx ){
343
+ struct sth_font * fnt = stash -> fonts ;
344
+ while (fnt != NULL ){
345
+ if (fnt -> idx == idx ){
346
+ return fnt ;
347
+ }
348
+ fnt = fnt -> next ;
349
+ }
350
+ return NULL ;
351
+ }
332
352
struct sth_glyph * get_glyph (struct sth_stash * stash , struct sth_font * fnt ,
333
353
unsigned int codepoint , short isize ) {
334
354
int i , g , advance , lsb , x0 , y0 , x1 , y1 , gw , gh ;
@@ -354,13 +374,32 @@ struct sth_glyph* get_glyph(struct sth_stash* stash, struct sth_font* fnt,
354
374
355
375
// For bitmap fonts: ignore this glyph.
356
376
if (fnt -> type == BMFONT ) return 0 ;
357
-
377
+ struct sth_font * temp_fnt = fnt ;
358
378
// For truetype fonts: create this glyph.
359
- scale = stbtt_ScaleForPixelHeight (& fnt -> font , size );
360
379
g = stbtt_FindGlyphIndex (& fnt -> font , codepoint );
380
+ // Try to find the glyph in fallback fonts.
381
+ if (g == 0 ) {
382
+ // printf("====> fnt %p nfallbacks=%d idx=%d\n",fnt, fnt->nfallbacks,fnt->idx);
383
+ for (i = 0 ; i < fnt -> nfallbacks ; ++ i ) {
384
+ int index = fnt -> fallbacks [i ];
385
+ struct sth_font * fallback_font = get_font_by_index (stash ,index );
386
+ if (fallback_font != NULL ){
387
+ int fallbackIndex = stbtt_FindGlyphIndex (& fallback_font -> font , codepoint );
388
+ if (fallbackIndex != 0 ) {
389
+ g = fallbackIndex ;
390
+ temp_fnt = fallback_font ;
391
+ break ;
392
+ }
393
+ }
394
+ }
395
+
396
+ // It is possible that we did not find a fallback glyph.
397
+ // In that case the glyph index 'g' is 0, and we'll proceed below and cache empty glyph.
398
+ }
361
399
if (!g ) return 0 ; /* @rlyeh: glyph not found, ie, arab chars */
362
- stbtt_GetGlyphHMetrics (& fnt -> font , g , & advance , & lsb );
363
- stbtt_GetGlyphBitmapBox (& fnt -> font , g , scale , scale , & x0 , & y0 , & x1 , & y1 );
400
+ scale = stbtt_ScaleForPixelHeight (& temp_fnt -> font , size );
401
+ stbtt_GetGlyphHMetrics (& temp_fnt -> font , g , & advance , & lsb );
402
+ stbtt_GetGlyphBitmapBox (& temp_fnt -> font , g , scale , scale , & x0 , & y0 , & x1 , & y1 );
364
403
gw = x1 - x0 ;
365
404
gh = y1 - y0 ;
366
405
@@ -450,7 +489,7 @@ struct sth_glyph* get_glyph(struct sth_stash* stash, struct sth_font* fnt,
450
489
// Rasterize
451
490
bmp = (unsigned char * )malloc (gw * gh );
452
491
if (bmp ) {
453
- stbtt_MakeGlyphBitmap (& fnt -> font , bmp , gw , gh , gw , scale , scale , g );
492
+ stbtt_MakeGlyphBitmap (& temp_fnt -> font , bmp , gw , gh , gw , scale , scale , g );
454
493
// Update texture
455
494
glBindTexture (GL_TEXTURE_2D , texture -> id );
456
495
glPixelStorei (GL_UNPACK_ALIGNMENT , 1 );
0 commit comments