From 4da91139a7104b81827d45e1b76ed54d6a0e984e Mon Sep 17 00:00:00 2001 From: Edgaru089 Date: Thu, 28 Oct 2021 16:03:17 +0800 Subject: [PATCH] graphics: optimize Unifont rendering, remove builtin width info --- graphics/unifont.c | 25 +++++++++++++++++++------ graphics/unifont.h | 20 +++++++++++++------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/graphics/unifont.c b/graphics/unifont.c index 7910a1e..f574dca 100644 --- a/graphics/unifont.c +++ b/graphics/unifont.c @@ -9,14 +9,27 @@ void unifont_DrawChar(int posX, int posY, const HelosGraphics_Color *color, uint const unsigned char *data = unifont_Data + codepoint * UNIFONT_CHAR_WIDTH * UNIFONT_CHAR_HEIGHT * 2 / 8; bool wide = unifont_IsCharDoublewidth(codepoint); - int charWidth = UNIFONT_CHAR_WIDTH * (wide ? 2 : 1); - - for (int x = 0; x < charWidth; x++) + // HACK Assuming UNIFONT_CHAR_WIDTH is 8 + if (wide) { + const uint8_t *line = data; for (int y = 0; y < UNIFONT_CHAR_HEIGHT; y++) { - int pos = y * charWidth + x; - if (data[pos / 8] & (1u << (7 - pos % 8))) - graphics_SetPixel(posX + x, posY + y, color); + for (int x = 0; x < UNIFONT_CHAR_WIDTH; x++) + if (*line & (1u << (7 - x % 8))) + graphics_SetPixel(posX + x, posY + y, color); + line++; + for (int x = 0; x < UNIFONT_CHAR_WIDTH; x++) + if (*line & (1u << (7 - x % 8))) + graphics_SetPixel(posX + x + 8, posY + y, color); + line++; } + } else { + const uint8_t *line = data; + for (int y = 0; y < UNIFONT_CHAR_HEIGHT; y++, line++) { + for (int x = 0; x < UNIFONT_CHAR_WIDTH; x++) + if (*line & (1u << (7 - x % 8))) + graphics_SetPixel(posX + x, posY + y, color); + } + } } void unifont_DrawString(int posX, int posY, const HelosGraphics_Color *color, const uint32_t *codepoints, int count) { diff --git a/graphics/unifont.h b/graphics/unifont.h index b164151..beab176 100644 --- a/graphics/unifont.h +++ b/graphics/unifont.h @@ -13,14 +13,20 @@ #define UNIFONT_CHAR_HEIGHT 16 extern const unsigned char unifont_Data[], unifont_Width[]; -extern const unsigned char unifont_Data_End[], unifont_Width_End[]; // Past-the-end pointers for the data files -static inline bool unifont_IsCharDoublewidth(uint32_t codepoint) { - const unsigned char *ptr = unifont_Width + codepoint / 8; - if (ptr < unifont_Width_End) - return (*ptr) & (1u << (7 - codepoint % 8)); - else - return false; +static inline bool unifont_IsCharDoublewidth(uint32_t ucs) { + return (ucs >= 0x1100 && /* formatting in clang-format is a nightmare */ + (ucs <= 0x115f || /* Hangul Jamo init. consonants */ + ucs == 0x2329 || ucs == 0x232a || /* Left/Right-Pointing Angle Bracket */ + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */ + (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */ + (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */ + (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */ + (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ + (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ + (ucs >= 0xffe0 && ucs <= 0xffe6) || /* formatting in clang-format is a literal nightmare */ + (ucs >= 0x20000 && ucs <= 0x2fffd) || /* one can only use comments like this to control line breaking */ + (ucs >= 0x30000 && ucs <= 0x3fffd))); } void unifont_DrawChar(int posX, int posY, const HelosGraphics_Color *color, uint32_t codepoint);