Skip to content

Commit f1e523d

Browse files
committed
add fallback font
1 parent b31a5eb commit f1e523d

File tree

4 files changed

+82
-6
lines changed

4 files changed

+82
-6
lines changed

lib/libgui/fontstash.c

+45-6
Original file line numberDiff line numberDiff line change
@@ -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+
}
332352
struct 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);

lib/libgui/fontstash.h

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
#define TTFONT_MEM 2
5555
#define BMFONT 3
5656

57+
#ifndef FONS_MAX_FALLBACKS
58+
# define FONS_MAX_FALLBACKS 20
59+
#endif
60+
5761
enum sth_flags {
5862
FONS_ZERO_TOPLEFT = 1,
5963
FONS_ZERO_BOTTOMLEFT = 2,
@@ -89,6 +93,8 @@ struct sth_font {
8993
float descender;
9094
float lineh;
9195
struct sth_font* next;
96+
int fallbacks[FONS_MAX_FALLBACKS];
97+
int nfallbacks;
9298
};
9399

94100
struct sth_texture {
@@ -179,4 +185,7 @@ int sth_pos(struct sth_stash* stash, int idx, float size, float width, char* s,
179185
float sth_get_start(struct sth_stash* stash, float size);
180186
float sth_get_line(struct sth_stash* stash, float size);
181187

188+
struct sth_font* get_font_by_index(struct sth_stash* stash, int idx);
189+
int sth_add_fallback_font(struct sth_font* font,int idx);
190+
182191
#endif // FONTSTASH_H

lib/libgui/graphic.c

+27
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ void mvp_set_mvp(mvp_t* mvp) {
4646
mvp->projection.data);
4747
}
4848

49+
50+
font_t * add_fallback_font(font_t* font,char* fallbackname){
51+
printf("load fallback %s\n",fallbackname);
52+
font->fallback_id = sth_add_font(font->stash,fallbackname);
53+
struct sth_font * fnt=get_font_by_index(font->stash,font->id);
54+
int n=sth_add_fallback_font(fnt,font->fallback_id);
55+
return font;
56+
}
57+
4958
font_t* new_font(char* name, float size) {
5059
LOGI("new_font %s %f\n",name,size);
5160
font_t* font = malloc(sizeof(font_t));
@@ -54,6 +63,24 @@ font_t* new_font(char* name, float size) {
5463
font->size = size;
5564
font->stash = sth_create(512, 512);
5665
font->id = sth_add_font(font->stash, name);
66+
char fallbackname[1024];
67+
char ext[20];
68+
int len=strlen(name);
69+
strcpy(fallbackname,name);
70+
strcpy(ext,&name[len-4]);
71+
fallbackname[len-4]=0;
72+
sprintf(fallbackname,"%s%s%s",fallbackname,"Fallback",ext);
73+
if (!access(fallbackname, 0)) {
74+
printf("load fallback %s\n",fallbackname);
75+
add_fallback_font(font,fallbackname);
76+
}else{
77+
strcpy(fallbackname,name);
78+
fallbackname[len-4]=0;
79+
sprintf(fallbackname,"%s%s%s",fallbackname,"-Fallback",ext);
80+
if (!access(fallbackname, 0)) {
81+
add_fallback_font(font,fallbackname);
82+
}
83+
}
5784
// font->stash->fonts->lineh = font->stash->fonts->lineh * 2.0;
5885
// printf("new font %f %f\n",font->stash->fonts->lineh,size);
5986
// LOGI("new_font font=>%p stash=>%p %p\n",font,font->stash,*(font->stash) );

lib/libgui/graphic.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ typedef struct {
5555
int id;
5656
char *name;
5757
unsigned char *data;
58+
int fallback_id;
5859
} font_t;
5960

6061
float measure_text(font_t* font, float size, char* text, int count);

0 commit comments

Comments
 (0)