summaryrefslogtreecommitdiff
path: root/examples/ui.c
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-08-10 18:03:55 +0200
committerMitya Selivanov <automainint@guattari.tech>2024-08-10 18:03:55 +0200
commit69ef269878d6b845a7bdb8e6e292485eee3f9744 (patch)
tree75c449d2c40e67b8d887311fa05b4ba9c0361cff /examples/ui.c
parent078e78f84addc76055dc89889745c38514286ede (diff)
downloadreduced_system_layer-69ef269878d6b845a7bdb8e6e292485eee3f9744.zip
Refactor print text
Diffstat (limited to 'examples/ui.c')
-rwxr-xr-xexamples/ui.c169
1 files changed, 113 insertions, 56 deletions
diff --git a/examples/ui.c b/examples/ui.c
index cdc34ef..157095a 100755
--- a/examples/ui.c
+++ b/examples/ui.c
@@ -174,80 +174,137 @@ Platform platform = {0};
#define CHAR_NUM_BITS_X 6
#define CHAR_NUM_BITS_Y 7
+#define CHAR_NUM_BITS (CHAR_NUM_BITS_X * CHAR_NUM_BITS_Y)
u64 bitfont[] = {
- 0x1041040000000000, 0x14500100, 0x38538429f28a7ca0, 0x621421f085084394, 0x10472450c614, 0x420410410420000, 0x233f312042082082, 0x411f10400001, 0x1f0000010800000, 0x4100040000000000, 0xc51451c004108208, 0x1c00070820830001, 0x71021070001c1084, 0x470001041c514000, 0x1c51c11800031070, 0x51c0002082107000, 0x31071470001c51c, 0x800000400010000, 0x102042100042000, 0x20400003c03c000, 0x20021050800421, 0xf24918e05955944e, 0x801c924724700924, 0x2492470062410491, 0xf00f0411c13c01c9, 0x4d04918004104704, 0x1c024924f2490062, 0x5104107007082082, 0x410092450c524008, 0x4557db4401c10410, 0x91804516554d1011, 0x411c924700624924, 0x2472062492491800, 0x62481811802491c9, 0x4924010410411f00, 0x10a4514510062492, 0x429100a7d5551440, 0x108429144045128, 0x410c03c108420f0, 0x41020820410c1041, 0x112840c20820820c, 0x3c00000000000000, 0xf206000000000081, 0x1c924704000624, 0x24e2000062412460, 0x604f246000389, 0x892460000821c218, 0x2491c10401883, 0x20c0080007083002, 0x4100514314500108, 0x55554f0000810410, 0x60002492491c0015, 0x472491c000624924, 0x14000838924e0000, 0x6206046000041043, 0x490000820821c000, 0x10a45144000e2492, 0xa44000a7d5451000, 0x108429100044a10, 0x821003c11883c00, 0x1041041041102081, 0x66604208408204, 0x0, 0x1,
+ 0x1041040000000000, 0x14500100, 0x38538429f28a7ca0, 0x621421f085084394, 0x10472450c614, 0x420410410420000, 0x233f312042082082, 0x411f10400001, 0x1f0000010800000, 0x4100040000000000, 0xc51451c004108208, 0x1c00070820830001, 0x71021070001c1084, 0x470001041c514000, 0x1c51c11800031070, 0x51c0002082107000, 0x31071470001c51c, 0x800000400010000, 0x102042100042000, 0x20400003c03c000, 0x20021050800421, 0xf24918e05955944e, 0x801c924724700924, 0x2492470062410491, 0xf00f0411c13c01c9, 0x4d04918004104704, 0x1c024924f2490062, 0x5104107007082082, 0x410092450c524008, 0x4557db4401c10410, 0x91804516554d1011, 0x411c924700624924, 0x2472062492491800, 0x62481811802491c9, 0x4924010410411f00, 0x10a4514510062492, 0x429100a7d5551440, 0x108429144045128, 0x410c03c108420f0, 0x41020820410c1041, 0x112840c20820820c, 0x3c00000000000000, 0xf206000000000081, 0x1c924704000624, 0x24e2000062412460, 0x604f246000389, 0x892460000821c218, 0x2491c10401883, 0x20c0080007083002, 0x4100514314500108, 0x55554f0000810410, 0x60002492491c0015, 0x472491c000624924, 0x14000838924e0000, 0x6206046000041043, 0x490000820821c000, 0x10a45144000e2492, 0xa44000a7d5451000, 0x108429100044a10, 0x821003c11883c00, 0x1041041041102081, 0x66604208408204,
};
-void print_text(u32 color, i32 x, i32 y, f64 width, f64 height, i64 num_chars, c8 *text) {
- assert(text != NULL);
+#define BITFONT_LEN ((i64) (sizeof bitfont / sizeof *bitfont))
- f64 dx = x;
- f64 dy = y;
- i64 w = (i64) floor(width + .5);
+b8 char_bit(c8 c, i64 column_index, i64 row_index) {
+ if (column_index < 0 || column_index >= CHAR_NUM_BITS_X || row_index < 0 || row_index >= CHAR_NUM_BITS_Y)
+ return 0;
- for (i64 n = 0; n < num_chars; ++n) {
- if (text[n] == '\r') {
- dx = x;
- continue;
- }
+ i64 bit_index = (c - 32) * CHAR_NUM_BITS + row_index * CHAR_NUM_BITS_X + column_index;
+ i64 qword_index = bit_index / 64;
+ u64 mask = 1ull << (bit_index % 64);
+
+ return qword_index < 0 || qword_index >= BITFONT_LEN ? 0 : !!(bitfont[qword_index] & mask);
+}
- if (text[n] == '\n') {
- dx = x;
- dy += (height * (CHAR_NUM_BITS_Y + 1)) / CHAR_NUM_BITS_Y;
+u64 char_column_convolved(c8 c, i64 column_index) {
+ if (column_index < 0 || column_index >= CHAR_NUM_BITS_X)
+ return 0;
+
+ 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;
+
+ // colvolution
+ if (mask != 1) column |= mask >> 1;
+ if (mask != 1ull << 63) column |= mask << 1;
+ }
+
+ return column;
+}
+
+b8 char_column_empty(c8 c, i64 column_index) {
+ if (column_index < 0 || column_index >= CHAR_NUM_BITS_X)
+ return 1;
+
+ for (i64 y = 0; y < CHAR_NUM_BITS_Y; ++y)
+ if (char_bit(c, column_index, y))
+ return 0;
+
+ return 1;
+}
+
+i64 char_width(c8 c) {
+ if (c < 32)
+ return 0;
+ if (c == ' ')
+ return 4;
+
+ i64 width = 0;
+
+ for (; width < CHAR_NUM_BITS_X; ++width)
+ if (char_column_empty(c, width) && char_column_empty(c, width + 1))
+ break;
+
+ return width;
+}
+
+i64 text_width(i64 num_chars, c8 *text) {
+ assert(text != NULL);
+
+ i64 width = 0;
+
+ for (i64 i = 0; i < num_chars; ++i) {
+ if (i > 0)
+ ++width;
+ width += char_width(text[i]);
+ }
+
+ return width;
+}
+
+void print_text(u32 color, i64 x0, i64 y0, f64 scale_x, f64 scale_y, i64 num_chars, c8 *text) {
+ assert(text != NULL);
+
+ f64 x = x0;
+ f64 y = y0;
+
+ f64 kx = scale_x / (CHAR_NUM_BITS_X + 1);
+ f64 h = (scale_y * CHAR_NUM_BITS_Y) / (CHAR_NUM_BITS_Y + 1);
+
+ for (i64 n = 0; n < num_chars; ++n) {
if (text[n] <= ' ') {
- dx += width;
+ if (text[n] == '\n') {
+ x = x0;
+ y += scale_y;
+ }
+ else if (text[n] == '\b' && n > 0)
+ x -= kx * (char_width(text[n - 1]) + 1);
+ else if (text[n] == '\r')
+ x = x0;
+ else
+ x += kx * (char_width(' ') + 1);
continue;
}
- i64 x0 = (i64) floor(dx + .5);
- i64 y0 = (i64) floor(dy + .5);
- i64 y1 = (i64) floor(dy + height + .5);
+ i64 num_cols = char_width(text[n]);
+ f64 w = num_cols * kx;
- i64 num_cols = 0;
+ i64 i0 = (i64) floor(x + .5);
+ i64 i1 = (i64) floor(x + w + .5);
+ i64 j0 = (i64) floor(y + .5);
+ i64 j1 = (i64) floor(y + h + .5);
- for (i64 i = x0; i < x0 + w; ++i, ++num_cols) {
- b8 empty_col = 1;
+ for (i64 j = j0; j < j1; ++j) {
+ if (j < 0) continue;
+ if (j >= platform.frame_height) break;
- i64 char_x = ((i - x0) * (CHAR_NUM_BITS_X + 1)) / w;
- if (char_x >= CHAR_NUM_BITS_X)
- break;
+ for (i64 i = i0; i < i1; ++i) {
+ if (i < 0) continue;
+ if (i >= platform.frame_width) break;
+
+ i64 column = ((i - i0) * num_cols) / (i1 - i0);
+ i64 row = ((j - j0) * CHAR_NUM_BITS_Y) / (j1 - j0);
- for (i64 j = y0; j < y1; ++j) {
- i64 char_y = ((j - y0) * CHAR_NUM_BITS_Y) / (y1 - y0);
- i64 bit_index = (text[n] - 32) * CHAR_NUM_BITS_X * CHAR_NUM_BITS_Y + char_y * CHAR_NUM_BITS_X + char_x;
- i64 qword_index = bit_index / 64;
- if (qword_index >= (i64) (sizeof bitfont / sizeof *bitfont))
- continue;
- u64 mask = 1ull << (bit_index % 64);
- if (!!(bitfont[qword_index] & mask)) {
- empty_col = 0;
- if (i < 0 || i >= platform.frame_width || j < 0 || j >= platform.frame_height)
- continue;
+ if (char_bit(text[n], column, row))
platform.pixels[j * platform.frame_width + i] = color;
- }
}
-
- if (empty_col && char_x + 1 < CHAR_NUM_BITS_X)
- for (i64 j = y; j < y1; ++j) {
- i64 char_y = ((j - y) * CHAR_NUM_BITS_Y) / (y1 - y);
- i64 bit_index = (text[n] - 32) * CHAR_NUM_BITS_X * CHAR_NUM_BITS_Y + char_y * CHAR_NUM_BITS_X + char_x + 1;
- i64 qword_index = bit_index / 64;
- if (qword_index >= (i64) (sizeof bitfont / sizeof *bitfont))
- continue;
- u64 mask = 1ull << (bit_index % 64);
- if (!!(bitfont[qword_index] & mask))
- empty_col = 0;
- }
-
- if (empty_col)
- break;
}
- dx += num_cols + width / CHAR_NUM_BITS_X;
+ x += kx * (num_cols + 1);
}
}
@@ -272,15 +329,15 @@ i32 main(i32 argc, c8 **argv) {
i64 color = 0xff7f7f;
- if (platform.cursor_x >= 80 && platform.cursor_x < 800 &&
+ if (platform.cursor_x >= 80 && platform.cursor_x < 80 + (text_width(14, "Hello, Sailor!") * 80) / (CHAR_NUM_BITS_X + 1) &&
platform.cursor_y >= 80 && platform.cursor_y < 180)
color = 0xffffff;
- print_text(color, 80, 80, 60., 100., 14, "Hello, Sailor!");
+ print_text(color, 80, 80, 80., 80., 14, "Hello, Sailor!");
c8 chars[] = "\"#$%&'()*+,-./\n0123456789:;<=>?@\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n[\\]^_`\nabcdefghijklmnopqrstuvwxyz\n{|}~";
- print_text(0x7fffff, 80, 200, 60., 100., sizeof chars - 1, chars);
+ print_text(0x7fffff, 80, 200, 80., 80., sizeof chars - 1, chars);
p_render_frame();
}