From def9c7e70df26779af4a59e0e82e9411b15f8199 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 10 Aug 2024 18:41:57 +0200 Subject: Text kerning --- examples/ui.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 16 deletions(-) (limited to 'examples/ui.c') diff --git a/examples/ui.c b/examples/ui.c index 157095a..afb9dbf 100755 --- a/examples/ui.c +++ b/examples/ui.c @@ -188,9 +188,10 @@ b8 char_bit(c8 c, i64 column_index, i64 row_index) { i64 bit_index = (c - 32) * CHAR_NUM_BITS + row_index * CHAR_NUM_BITS_X + column_index; i64 qword_index = bit_index / 64; + if (qword_index < 0 || qword_index >= BITFONT_LEN) + return 0; u64 mask = 1ull << (bit_index % 64); - - return qword_index < 0 || qword_index >= BITFONT_LEN ? 0 : !!(bitfont[qword_index] & mask); + return !!(bitfont[qword_index] & mask); } u64 char_column_convolved(c8 c, i64 column_index) { @@ -200,13 +201,11 @@ u64 char_column_convolved(c8 c, i64 column_index) { u64 column = 0; for (i64 y = 0; y < CHAR_NUM_BITS_Y; ++y) { - i64 bit_index = (c - 32) * CHAR_NUM_BITS + y * CHAR_NUM_BITS_X + column_index; - u64 mask = 1ull << (bit_index % 64); - if (!char_bit(c, column_index, y)) continue; - column |= mask; + u64 mask = 1ull << y; + column |= mask; // colvolution if (mask != 1) column |= mask >> 1; @@ -242,18 +241,61 @@ i64 char_width(c8 c) { return width; } -i64 text_width(i64 num_chars, c8 *text) { +i64 char_spacing(i64 num_chars, c8 *text, i64 index) { assert(text != NULL); - i64 width = 0; + if (index < 0 || index + 1 >= num_chars) + return 0; + + u64 a = char_column_convolved(text[index], char_width(text[index]) - 1); + u64 b = char_column_convolved(text[index + 1], 0); + + if (!!(a & b)) + return 1; + + return 0; +} + +i64 enum_text_columns(i64 num_chars, c8 *text) { + assert(text != NULL); + + i64 cols = 0; + i64 n = 0; for (i64 i = 0; i < num_chars; ++i) { - if (i > 0) - ++width; - width += char_width(text[i]); + if (text[i] <= ' ') { + if (text[i] == '\n') + n = 0; + else if (text[i] == '\b' && i > 0) + n -= char_width(text[i - 1]) + char_spacing(num_chars, text, i - 1); + else if (text[i] == '\r') + n = 0; + else + n += char_width(' ') + char_spacing(num_chars, text, i); + continue; + } + n += char_width(text[i]) + char_spacing(num_chars, text, i); } - return width; + if (cols < n) + cols = n; + + return cols; +} + +i64 enum_text_rows(i64 num_chars, c8 *text) { + assert(text != NULL); + + i64 rows = 0; + + for (i64 i = 0; i < num_chars; ++i) + if (text[i] == '\n') + ++rows; + + if (num_chars > 0 && text[num_chars - 1] != '\n') + ++rows; + + return rows; } void print_text(u32 color, i64 x0, i64 y0, f64 scale_x, f64 scale_y, i64 num_chars, c8 *text) { @@ -272,11 +314,11 @@ void print_text(u32 color, i64 x0, i64 y0, f64 scale_x, f64 scale_y, i64 num_cha y += scale_y; } else if (text[n] == '\b' && n > 0) - x -= kx * (char_width(text[n - 1]) + 1); + x -= kx * (char_width(text[n - 1]) + char_spacing(num_chars, text, n - 1)); else if (text[n] == '\r') x = x0; else - x += kx * (char_width(' ') + 1); + x += kx * (char_width(' ') + char_spacing(num_chars, text, n)); continue; } @@ -304,7 +346,7 @@ void print_text(u32 color, i64 x0, i64 y0, f64 scale_x, f64 scale_y, i64 num_cha } } - x += kx * (num_cols + 1); + x += kx * (num_cols + char_spacing(num_chars, text, n)); } } @@ -329,7 +371,7 @@ i32 main(i32 argc, c8 **argv) { i64 color = 0xff7f7f; - if (platform.cursor_x >= 80 && platform.cursor_x < 80 + (text_width(14, "Hello, Sailor!") * 80) / (CHAR_NUM_BITS_X + 1) && + if (platform.cursor_x >= 80 && platform.cursor_x < 80 + (enum_text_columns(14, "Hello, Sailor!") * 80) / (CHAR_NUM_BITS_X + 1) && platform.cursor_y >= 80 && platform.cursor_y < 180) color = 0xffffff; -- cgit v1.2.3