@@ -173,6 +173,7 @@ int sth_add_font_from_memory(struct sth_stash* stash, unsigned char* buffer) {
173173 fnt -> idx = idx ;
174174 fnt -> type = TTFONT_MEM ;
175175 fnt -> next = stash -> fonts ;
176+ fnt -> nfallbacks = 0 ;
176177 stash -> fonts = fnt ;
177178 return idx ++ ;
178179
@@ -328,7 +329,26 @@ inline int sth_add_glyph_for_char(struct sth_stash* stash, int idx, GLuint id,
328329 return sth_add_glyph_for_codepoint (stash , idx , id , codepoint , size , base , x ,
329330 y , w , h , xoffset , yoffset , xadvance );
330331}
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+ }
332352struct sth_glyph * get_glyph (struct sth_stash * stash , struct sth_font * fnt ,
333353 unsigned int codepoint , short isize ) {
334354 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,
354374
355375 // For bitmap fonts: ignore this glyph.
356376 if (fnt -> type == BMFONT ) return 0 ;
357-
377+ struct sth_font * temp_fnt = fnt ;
358378 // For truetype fonts: create this glyph.
359- scale = stbtt_ScaleForPixelHeight (& fnt -> font , size );
360379 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+ }
361399 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 );
364403 gw = x1 - x0 ;
365404 gh = y1 - y0 ;
366405
@@ -450,7 +489,7 @@ struct sth_glyph* get_glyph(struct sth_stash* stash, struct sth_font* fnt,
450489 // Rasterize
451490 bmp = (unsigned char * )malloc (gw * gh );
452491 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 );
454493 // Update texture
455494 glBindTexture (GL_TEXTURE_2D , texture -> id );
456495 glPixelStorei (GL_UNPACK_ALIGNMENT , 1 );
0 commit comments