mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
font: load fallback fonts on demand
When instantiating a primary font, build the fallback font list, but don't actually instantiate the fallback fonts. Instead, remember the (full) pattern that we should use if/when we instantiate it. Then, when looking up a glyph and we need a fallback font, loop the list and instantiate the font(s) there and then.
This commit is contained in:
parent
e218e19ea3
commit
3c42691e1b
2 changed files with 35 additions and 19 deletions
47
font.c
47
font.c
|
|
@ -281,7 +281,7 @@ font_from_name(font_list_t names, const char *attributes)
|
|||
if (tll_length(names) == 0)
|
||||
return false;
|
||||
|
||||
struct font *res = NULL;
|
||||
struct font *font = NULL;
|
||||
|
||||
bool have_attrs = attributes != NULL && strlen(attributes) > 0;
|
||||
size_t attr_len = have_attrs ? strlen(attributes) + 1 : 0;
|
||||
|
|
@ -290,30 +290,29 @@ font_from_name(font_list_t names, const char *attributes)
|
|||
tll_foreach(names, it) {
|
||||
const char *base_name = it->item;
|
||||
|
||||
char primary_name[strlen(base_name) + attr_len + 1];
|
||||
strcpy(primary_name, base_name);
|
||||
char name[strlen(base_name) + attr_len + 1];
|
||||
strcpy(name, base_name);
|
||||
if (have_attrs) {
|
||||
strcat(primary_name, ":");
|
||||
strcat(primary_name, attributes);
|
||||
}
|
||||
|
||||
struct font *font = from_name(primary_name, !first);
|
||||
if (font == NULL) {
|
||||
if (first)
|
||||
return NULL;
|
||||
continue;
|
||||
strcat(name, ":");
|
||||
strcat(name, attributes);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
res = font;
|
||||
first = false;
|
||||
|
||||
font = from_name(name, false);
|
||||
if (font == NULL)
|
||||
return NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tll_push_back(res->fallbacks, font);
|
||||
assert(font != NULL);
|
||||
tll_push_back(
|
||||
font->fallbacks, ((struct font_fallback){.pattern = strdup(name)}));
|
||||
}
|
||||
|
||||
return res;
|
||||
return font;
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
|
@ -341,9 +340,16 @@ glyph_for_wchar(const struct font *font, wchar_t wc, struct glyph *glyph)
|
|||
/* No glyph in this font, try fallback fonts */
|
||||
|
||||
tll_foreach(font->fallbacks, it) {
|
||||
if (glyph_for_wchar(it->item, wc, glyph)) {
|
||||
if (it->item.font == NULL) {
|
||||
it->item.font = from_name(it->item.pattern, true);
|
||||
if (it->item.font == NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (glyph_for_wchar(it->item.font, wc, glyph)) {
|
||||
LOG_DBG("%C: used fallback: %s (fixup = %f)",
|
||||
wc, it->item->name, it->item->pixel_size_fixup);
|
||||
wc, it->item.font->name,
|
||||
it->item.font->pixel_size_fixup);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -598,7 +604,12 @@ font_destroy(struct font *font)
|
|||
return;
|
||||
|
||||
free(font->name);
|
||||
tll_free_and_free(font->fallbacks, font_destroy);
|
||||
|
||||
tll_foreach(font->fallbacks, it) {
|
||||
font_destroy(it->item.font);
|
||||
free(it->item.pattern);
|
||||
}
|
||||
tll_free(font->fallbacks);
|
||||
|
||||
if (font->face != NULL) {
|
||||
mtx_lock(&ft_lock);
|
||||
|
|
|
|||
7
font.h
7
font.h
|
|
@ -29,6 +29,11 @@ struct glyph {
|
|||
|
||||
typedef tll(struct glyph) hash_entry_t;
|
||||
|
||||
struct font_fallback {
|
||||
char *pattern;
|
||||
struct font *font;
|
||||
};
|
||||
|
||||
struct font {
|
||||
char *name;
|
||||
|
||||
|
|
@ -52,7 +57,7 @@ struct font {
|
|||
} strikeout;
|
||||
|
||||
bool is_fallback;
|
||||
tll(struct font *) fallbacks;
|
||||
tll(struct font_fallback) fallbacks;
|
||||
|
||||
size_t ref_counter;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue