graphics: optimize Unifont rendering, remove builtin width info

This commit is contained in:
Edgaru089 2021-10-28 16:03:17 +08:00
parent 430a3abf7d
commit 4da91139a7
2 changed files with 32 additions and 13 deletions

View File

@ -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; const unsigned char *data = unifont_Data + codepoint * UNIFONT_CHAR_WIDTH * UNIFONT_CHAR_HEIGHT * 2 / 8;
bool wide = unifont_IsCharDoublewidth(codepoint); bool wide = unifont_IsCharDoublewidth(codepoint);
int charWidth = UNIFONT_CHAR_WIDTH * (wide ? 2 : 1); // HACK Assuming UNIFONT_CHAR_WIDTH is 8
if (wide) {
for (int x = 0; x < charWidth; x++) const uint8_t *line = data;
for (int y = 0; y < UNIFONT_CHAR_HEIGHT; y++) { for (int y = 0; y < UNIFONT_CHAR_HEIGHT; y++) {
int pos = y * charWidth + x; for (int x = 0; x < UNIFONT_CHAR_WIDTH; x++)
if (data[pos / 8] & (1u << (7 - pos % 8))) if (*line & (1u << (7 - x % 8)))
graphics_SetPixel(posX + x, posY + y, color); 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) { void unifont_DrawString(int posX, int posY, const HelosGraphics_Color *color, const uint32_t *codepoints, int count) {

View File

@ -13,14 +13,20 @@
#define UNIFONT_CHAR_HEIGHT 16 #define UNIFONT_CHAR_HEIGHT 16
extern const unsigned char unifont_Data[], unifont_Width[]; 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) { static inline bool unifont_IsCharDoublewidth(uint32_t ucs) {
const unsigned char *ptr = unifont_Width + codepoint / 8; return (ucs >= 0x1100 && /* formatting in clang-format is a nightmare */
if (ptr < unifont_Width_End) (ucs <= 0x115f || /* Hangul Jamo init. consonants */
return (*ptr) & (1u << (7 - codepoint % 8)); ucs == 0x2329 || ucs == 0x232a || /* Left/Right-Pointing Angle Bracket */
else (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || /* CJK ... Yi */
return false; (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); void unifont_DrawChar(int posX, int posY, const HelosGraphics_Color *color, uint32_t codepoint);