mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-22 05:33:45 -04: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)
|
if (tll_length(names) == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct font *res = NULL;
|
struct font *font = NULL;
|
||||||
|
|
||||||
bool have_attrs = attributes != NULL && strlen(attributes) > 0;
|
bool have_attrs = attributes != NULL && strlen(attributes) > 0;
|
||||||
size_t attr_len = have_attrs ? strlen(attributes) + 1 : 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) {
|
tll_foreach(names, it) {
|
||||||
const char *base_name = it->item;
|
const char *base_name = it->item;
|
||||||
|
|
||||||
char primary_name[strlen(base_name) + attr_len + 1];
|
char name[strlen(base_name) + attr_len + 1];
|
||||||
strcpy(primary_name, base_name);
|
strcpy(name, base_name);
|
||||||
if (have_attrs) {
|
if (have_attrs) {
|
||||||
strcat(primary_name, ":");
|
strcat(name, ":");
|
||||||
strcat(primary_name, attributes);
|
strcat(name, attributes);
|
||||||
}
|
|
||||||
|
|
||||||
struct font *font = from_name(primary_name, !first);
|
|
||||||
if (font == NULL) {
|
|
||||||
if (first)
|
|
||||||
return NULL;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
res = font;
|
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
|
font = from_name(name, false);
|
||||||
|
if (font == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
continue;
|
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
|
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 */
|
/* No glyph in this font, try fallback fonts */
|
||||||
|
|
||||||
tll_foreach(font->fallbacks, it) {
|
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)",
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -598,7 +604,12 @@ font_destroy(struct font *font)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free(font->name);
|
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) {
|
if (font->face != NULL) {
|
||||||
mtx_lock(&ft_lock);
|
mtx_lock(&ft_lock);
|
||||||
|
|
|
||||||
7
font.h
7
font.h
|
|
@ -29,6 +29,11 @@ struct glyph {
|
||||||
|
|
||||||
typedef tll(struct glyph) hash_entry_t;
|
typedef tll(struct glyph) hash_entry_t;
|
||||||
|
|
||||||
|
struct font_fallback {
|
||||||
|
char *pattern;
|
||||||
|
struct font *font;
|
||||||
|
};
|
||||||
|
|
||||||
struct font {
|
struct font {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
|
@ -52,7 +57,7 @@ struct font {
|
||||||
} strikeout;
|
} strikeout;
|
||||||
|
|
||||||
bool is_fallback;
|
bool is_fallback;
|
||||||
tll(struct font *) fallbacks;
|
tll(struct font_fallback) fallbacks;
|
||||||
|
|
||||||
size_t ref_counter;
|
size_t ref_counter;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue