diff options
author | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2020-12-22 22:37:50 +0100 |
---|---|---|
committer | sternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org> | 2020-12-22 22:40:30 +0100 |
commit | e46333e26c3d3d334dcb1852ca81d10c1769aca9 (patch) | |
tree | 9085e9a029a596b9b25047f1ccf891eb69e24e2a | |
parent | 7eec59dc976e5ce167d47562712068e9c089a034 (diff) |
feat(buchstabensuppe): font fallback
By default we now try to fallback to rendering 0xFFFD if a glyph is missing from a grapheme in all fonts. Also introduces BS_RENDER_NO_FALLBACK flag to disable this behavior. Implementation reuses bs_render_grapheme_append (recursively) which is probably overkill, but is concise and prevents code duplication.
-rw-r--r-- | buchstabensuppe.c | 17 | ||||
-rw-r--r-- | include/buchstabensuppe.h | 3 |
2 files changed, 19 insertions, 1 deletions
diff --git a/buchstabensuppe.c b/buchstabensuppe.c index ec9b211..5919073 100644 --- a/buchstabensuppe.c +++ b/buchstabensuppe.c @@ -12,6 +12,8 @@ #include <buchstabensuppe.h> +#define FALLBACK_CODEPOINT 0xFFFD + #define FONT_SCALE_MULTIPLIER 1 #define LOG(...) \ @@ -374,6 +376,21 @@ bool bs_render_grapheme_append(bs_context_t *ctx, bs_bitmap_t *target, bs_cursor font_index++; } + if(!have_glyphs && !(ctx->bs_rendering_flags & BS_RENDER_NO_FALLBACK)) { + bs_utf32_buffer_t fallback_grapheme = bs_utf32_buffer_new(1); + bs_utf32_buffer_append_single(FALLBACK_CODEPOINT, &fallback_grapheme); + + if(fallback_grapheme.bs_utf32_buffer_len > 0) { + // avoid infinite recursion + ctx->bs_rendering_flags |= BS_RENDER_NO_FALLBACK; + have_glyphs = bs_render_grapheme_append(ctx, + target, cursor, fallback_grapheme, 0, 1); + ctx->bs_rendering_flags ^= BS_RENDER_NO_FALLBACK; + } + + bs_utf32_buffer_free(&fallback_grapheme); + } + return have_glyphs; } diff --git a/include/buchstabensuppe.h b/include/buchstabensuppe.h index fc24698..7573aff 100644 --- a/include/buchstabensuppe.h +++ b/include/buchstabensuppe.h @@ -50,7 +50,8 @@ typedef struct bs_font { } bs_font_t; enum bs_rendering_flag { - BS_RENDER_BINARY = 0x01, + BS_RENDER_BINARY = 0b001, + BS_RENDER_NO_FALLBACK = 0b100, }; typedef struct bs_context { |