summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-04-25 13:04:09 +0200
committerMitya Selivanov <automainint@guattari.tech>2025-04-25 13:04:09 +0200
commit32f60821408fe51d0acf45e430556c12711e5cc5 (patch)
tree6d369d3456b077666cf3049ae0d528cd7300cfb7
parent9251ce60ba4f68e813bd2c6fd06f7574e8b1f448 (diff)
downloadreduced_system_layer-32f60821408fe51d0acf45e430556c12711e5cc5.zip
Rework LCD font
-rw-r--r--graphics.c326
1 files changed, 227 insertions, 99 deletions
diff --git a/graphics.c b/graphics.c
index 38bbd7c..7a97aab 100644
--- a/graphics.c
+++ b/graphics.c
@@ -245,17 +245,6 @@ void clean_graphics_requests_cache(i64 amount);
#ifndef GRAPHICS_IMPL_GUARD_
#define GRAPHICS_IMPL_GUARD_
-// FIXME, PERF: Re-encode for faster rendering.
-static u64 _bitfont[] = {
- 0xbc0000000000, 0xc00300000, 0x5fd5040093f24fc9, 0xa00a2c2a1a280105, 0xc000415e6f, 0x400000020be0000, 0x1c38a8400000007d, 0x40002043e1020215, 0x408102000000010, 0x9800000000020002, 0xf913e00000033, 0x53200000207c8800, 0x3654880000099, 0x54b800000f840e00, 0xe953c000001a, 0x953e000000674080, 0x1e54b800000f, 0x490000000000240, 0x88a08000000, 0x20a220050a142850, 0x6520800000, 0x912f801eab260be, 0x800034952bf0001f, 0xc850bf0000921427, 0xf00010a54afc0003, 0xd29427800002142b, 0x840007e1023f0000, 0x7d09100000217e, 0x3f000188a08fc000, 0xc30c0cfc00000810, 0x27803f101013f00f, 0xc244bf0000f214, 0x4bf0002f21427800, 0xc254a480006c24, 0x407c00102fc08100, 0xf208080f0000fa0, 0x531007d81c607c0, 0xc208288c031141, 0x83fc00046954b10, 0x180e03000000, 0x41040000000ff04, 0x8102040810000404, 0x2a54600000000101, 0x309123e0000e, 0xc912180000a22447, 0x8000062a54700007, 0xe52a4300000029f0, 0xa0000602043e0001, 0x1d48000002074, 0x1f000003610f8000, 0x13e04f800000010, 0x470000780813e00f, 0x184893e0000e224, 0x23e0001f12243000, 0x82a54100000008, 0x40780000009f0200, 0xe208080e0001f20, 0xa22007981860780, 0x82082888022282, 0x16c200004ca95320, 0x7f000004, 0x408200000086d04, 0x8204,
-};
-
-enum {
- CHAR_NUM_BITS_X_ = 6,
- CHAR_NUM_BITS_Y_ = 7,
- CHAR_NUM_BITS_ = CHAR_NUM_BITS_X_ * CHAR_NUM_BITS_Y_,
-};
-
static void put_pixel_(vec4_f32 *dst, vec4_f32 color) {
if (color.w == 1.f)
*dst = color;
@@ -557,6 +546,8 @@ static b8 quad_from_line_(vec2 *dst, vec2 vertices[2], f64 width) {
}
void fill_line_to_buffer(Pixel_Buffer dst, vec4_f32 color, vec2 vertices[2], f64 width) {
+ // FIXME, PERF: Use Bresenham's algorithm when width is 1.
+
if (width < EPSILON) return;
PROFILER_begin(PROFILE_FILL_LINE);
@@ -568,75 +559,174 @@ void fill_line_to_buffer(Pixel_Buffer dst, vec4_f32 color, vec2 vertices[2], f64
PROFILER_end(PROFILE_FILL_LINE);
}
-static i64 char_column_offset_(c32 c, i64 column_index) {
- if (column_index < 0 || column_index >= CHAR_NUM_BITS_X_)
- return -1;
- return (c - 32) * CHAR_NUM_BITS_ + column_index * CHAR_NUM_BITS_Y_;
-}
+// ================================================================
+//
+// LCD text rendering
+//
+// ================================================================
-static b8 char_bit_(i64 column_offset, i64 row_index) {
- if (column_offset < 0 || row_index < 0 || row_index >= CHAR_NUM_BITS_Y_)
- return 0;
+static u64 _lcd_bits[] = {
+ 0x10001010101ull,
+ 0x505ull,
+ 0xa1f0a0a1f0a00ull,
+ 0x40e140e050e04ull,
+ 0x814081f020502ull,
+ 0x7090503060506ull,
+ 0x101ull,
+ 0x2010101010102ull,
+ 0x1020202020201ull,
+ 0x120c3f0c12ull,
+ 0x4041f040400ull,
+ 0x1020000000000ull,
+ 0x1f000000ull,
+ 0x10000000000ull,
+ 0x1010202020404ull,
+ 0x70505050700ull,
+ 0x70202020300ull,
+ 0x70102040700ull,
+ 0x70402040700ull,
+ 0x40407050500ull,
+ 0x30407010700ull,
+ 0x70507010600ull,
+ 0x20202040700ull,
+ 0x70507050700ull,
+ 0x30407050700ull,
+ 0x10000010000ull,
+ 0x1020000020000ull,
+ 0x40201020400ull,
+ 0x1f001f0000ull,
+ 0x10204020100ull,
+ 0x20002040502ull,
+ 0xe01191519110eull,
+ 0x9090f090906ull,
+ 0x70909070907ull,
+ 0x60901010906ull,
+ 0x70909090907ull,
+ 0xf010107010full,
+ 0x1010107010full,
+ 0x6090d010906ull,
+ 0x909090f0909ull,
+ 0x70202020207ull,
+ 0x20504040407ull,
+ 0x90905030509ull,
+ 0x70101010101ull,
+ 0x1111151f1b11ull,
+ 0x111119151311ull,
+ 0x60909090906ull,
+ 0x10107090907ull,
+ 0x8060909090906ull,
+ 0x90907090907ull,
+ 0x60908060106ull,
+ 0x4040404041full,
+ 0x60909090909ull,
+ 0x40a11111111ull,
+ 0xa1f15151111ull,
+ 0x11110a040a11ull,
+ 0x102040a1111ull,
+ 0xf010204080full,
+ 0x3010101010103ull,
+ 0x4040202020101ull,
+ 0x3020202020203ull,
+ 0x110a04ull,
+ 0x3f000000000000ull,
+ 0x201ull,
+ 0x6090f080600ull,
+ 0x70909070100ull,
+ 0x60901090600ull,
+ 0xe09090e0800ull,
+ 0x6010f090600ull,
+ 0x20207020600ull,
+ 0x6080e09090600ull,
+ 0x90907010100ull,
+ 0x70203000200ull,
+ 0x1020203000200ull,
+ 0x50503050500ull,
+ 0x20101010101ull,
+ 0x151515150f00ull,
+ 0x90909090700ull,
+ 0x60909090600ull,
+ 0x10709090700ull,
+ 0x80e09090e00ull,
+ 0x10101030500ull,
+ 0x60806010600ull,
+ 0x20202020700ull,
+ 0xe0909090900ull,
+ 0x40a11111100ull,
+ 0xa1f15111100ull,
+ 0x110a040a1100ull,
+ 0x102040a1100ull,
+ 0xf0106080f00ull,
+ 0x4020201020204ull,
+ 0x1010101010101ull,
+ 0x1020204020201ull,
+ 0x1926ull,
+};
+
+enum {
+ LCD_Width = 6,
+ LCD_Height = 7,
+ LCD_Num_Bits = LCD_Width * LCD_Height,
+ LCD_First = 33,
+ LCD_Space = 4,
+ LCD_Len = sizeof(_lcd_bits) / sizeof(*_lcd_bits),
+};
- i64 bit_index = column_offset + row_index;
- i64 qword_index = bit_index / 64;
- if (qword_index < 0 || qword_index >= (i64) (sizeof _bitfont / sizeof *_bitfont))
+static u64 lcd_column_convolved_(c32 c, i64 column_index) {
+ if (column_index < 0 || column_index >= LCD_Width)
return 0;
- u64 mask = 1ull << (bit_index % 64);
- return !!(_bitfont[qword_index] & mask);
-}
-static u64 char_column_convolved_(c32 c, i64 column_index) {
- if (column_index < 0 || column_index >= CHAR_NUM_BITS_X_)
+ i64 index = c - LCD_First;
+ if (index < 0 || index >= LCD_Len)
return 0;
u64 column = 0;
- i64 offset = char_column_offset_(c, column_index);
-
- for (i64 y = 0; y < CHAR_NUM_BITS_Y_; ++y)
- if (char_bit_(offset, y))
+ for (i64 y = 0; y < LCD_Height; ++y)
+ if ((_lcd_bits[index] & (1ull << (y * 8 + column_index))) != 0)
column |= 3ull << y;
-
return column;
}
-static b8 char_column_empty_(c32 c, i64 column_index) {
- if (column_index < 0 || column_index >= CHAR_NUM_BITS_X_)
+static b8 lcd_column_empty_(c32 c, i64 column_index) {
+ if (column_index < 0 || column_index >= LCD_Width)
return 1;
- i64 offset = char_column_offset_(c, column_index);
+ i64 index = c - LCD_First;
+ if (index < 0 || index >= LCD_Len)
+ return 1;
- for (i64 y = 0; y < CHAR_NUM_BITS_Y_; ++y)
- if (char_bit_(offset, y))
+ for (i64 y = 0; y < LCD_Height; ++y)
+ if ((_lcd_bits[index] & (1ull << (y * 8 + column_index))) != 0)
return 0;
-
return 1;
}
-static i64 char_width_(c32 c) {
- if (c < 32)
+static i64 lcd_char_width_(c32 c) {
+ // FIXME, PERF: Pre-calculate dimensions.
+
+ i64 index = c - LCD_First;
+ if (index < -1)
return 0;
- if (c == ' ' || c > 127)
- return 4;
+ if (index < 0 || index >= LCD_Len)
+ return LCD_Space;
i64 width = 0;
-
- for (; width < CHAR_NUM_BITS_X_; ++width)
- if (char_column_empty_(c, width) && char_column_empty_(c, width + 1))
+ for (; width < LCD_Width; ++width)
+ if (lcd_column_empty_(c, width) && lcd_column_empty_(c, width + 1))
break;
-
return width;
}
-static i64 char_spacing_(i64 num_chars, c32 *text, i64 index) {
+static i64 lcd_spacing_(i64 num_chars, c32 *text, i64 index) {
+ // FIXME, PERF: Pre-calculate kerning.
+
if (text == NULL)
return 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);
+ u64 a = lcd_column_convolved_(text[index], lcd_char_width_(text[index]) - 1);
+ u64 b = lcd_column_convolved_(text[index + 1], 0);
if (!!(a & b))
return 1;
@@ -644,7 +734,7 @@ static i64 char_spacing_(i64 num_chars, c32 *text, i64 index) {
return 0;
}
-static i64 text_cursor_(i64 num_chars, c32 *text) {
+static i64 lcd_cursor_(i64 num_chars, c32 *text) {
if (text == NULL)
return 0;
@@ -655,20 +745,20 @@ static i64 text_cursor_(i64 num_chars, c32 *text) {
if (text[i] == '\n')
cursor = 0;
else if (text[i] == '\b' && i > 0)
- cursor -= char_width_(text[i - 1]) + char_spacing_(num_chars, text, i - 1);
+ cursor -= lcd_char_width_(text[i - 1]) + lcd_spacing_(num_chars, text, i - 1);
else if (text[i] == '\r')
cursor = 0;
else
- cursor += char_width_(' ') + char_spacing_(num_chars, text, i);
+ cursor += lcd_char_width_(' ') + lcd_spacing_(num_chars, text, i);
continue;
}
- cursor += char_width_(text[i]) + char_spacing_(num_chars, text, i);
+ cursor += lcd_char_width_(text[i]) + lcd_spacing_(num_chars, text, i);
}
return cursor;
}
-static i64 enum_text_columns_(i64 num_chars, c32 *text) {
+static i64 lcd_enum_text_columns_(i64 num_chars, c32 *text) {
if (text == NULL)
return 0;
@@ -684,16 +774,16 @@ static i64 enum_text_columns_(i64 num_chars, c32 *text) {
} else if (text[i] == '\b' && i > 0) {
if (cols < n)
cols = n;
- n -= char_width_(text[i - 1]) + char_spacing_(num_chars, text, i - 1);
+ n -= lcd_char_width_(text[i - 1]) + lcd_spacing_(num_chars, text, i - 1);
} else if (text[i] == '\r') {
if (cols < n)
cols = n;
n = 0;
} else
- n += char_width_(' ') + char_spacing_(num_chars, text, i);
+ n += lcd_char_width_(' ') + lcd_spacing_(num_chars, text, i);
continue;
}
- n += char_width_(text[i]) + char_spacing_(num_chars, text, i);
+ n += lcd_char_width_(text[i]) + lcd_spacing_(num_chars, text, i);
}
if (cols < n)
@@ -702,7 +792,7 @@ static i64 enum_text_columns_(i64 num_chars, c32 *text) {
return cols;
}
-static i64 enum_text_rows_(i64 num_chars, c32 *text) {
+static i64 lcd_enum_text_rows_(i64 num_chars, c32 *text) {
if (text == NULL)
return 0;
@@ -712,15 +802,15 @@ static i64 enum_text_rows_(i64 num_chars, c32 *text) {
if (i == num_chars || text[i] == '\n') {
if (rows > 0)
++rows;
- rows += CHAR_NUM_BITS_Y_;
+ rows += LCD_Height;
}
return rows;
}
-static void draw_text_(Pixel_Buffer dst, vec4_f32 color, f64 x0, f64 y0, f64 scale_x, f64 scale_y, i64 num_chars, c32 *text) {
+static void lcd_draw_text_(Pixel_Buffer dst, vec4_f32 color, f64 x0, f64 y0, f64 scale_x, f64 scale_y, i64 num_chars, c32 *text) {
f64 kx = scale_x;
- f64 h = scale_y * CHAR_NUM_BITS_Y_;
+ f64 h = scale_y * LCD_Height;
if (h < EPSILON)
return;
@@ -732,25 +822,26 @@ static void draw_text_(Pixel_Buffer dst, vec4_f32 color, f64 x0, f64 y0, f64 sca
if (text[n] <= ' ') {
if (text[n] == '\n') {
x = x0;
- y += scale_y * (CHAR_NUM_BITS_Y_ + 1);
+ y += scale_y * (LCD_Height + 1);
}
else if (text[n] == '\b' && n > 0)
- x -= kx * (char_width_(text[n - 1]) + char_spacing_(num_chars, text, n - 1));
+ x -= kx * (lcd_char_width_(text[n - 1]) + lcd_spacing_(num_chars, text, n - 1));
else if (text[n] == '\r')
x = x0;
else
- x += kx * (char_width_(' ') + char_spacing_(num_chars, text, n));
+ x += kx * (lcd_char_width_(' ') + lcd_spacing_(num_chars, text, n));
continue;
}
- i64 num_cols = char_width_(text[n]);
+ i64 num_cols = lcd_char_width_(text[n]);
f64 w = num_cols * kx;
+ i64 index = text[n] - LCD_First;
- if (w >= EPSILON) {
- i64 i0 = (i64) floor(x);
- i64 i1 = (i64) ceil (x + w);
- i64 j0 = (i64) floor(y);
- i64 j1 = (i64) ceil (y + h);
+ if (w >= EPSILON && index >= 0 && index < LCD_Len) {
+ i64 i0 = (i64) floor(x + 0.5);
+ i64 i1 = (i64) floor(x + w - 0.5);
+ i64 j0 = (i64) floor(y + 0.5);
+ i64 j1 = (i64) floor(y + h - 0.5);
if (i0 < 0) i0 = 0;
if (i1 >= dst.width) i1 = dst.width - 1;
@@ -760,19 +851,20 @@ static void draw_text_(Pixel_Buffer dst, vec4_f32 color, f64 x0, f64 y0, f64 sca
f64 w_inv = 1. / w;
f64 h_inv = 1. / h;
- for (i64 i = i0; i <= i1; ++i) {
- i64 column = (i64) floor(((i - x + .5) * num_cols) * w_inv);
- i64 offset = char_column_offset_(text[n], column);
+ // FIXME, PERF: Use integer arithmetic.
+
+ for (i64 j = j0; j <= j1; ++j) {
+ i64 row = (i64) floor(((j - y + 0.5) * LCD_Height) * h_inv);
+ for (i64 i = i0; i <= i1; ++i) {
+ i64 column = (i64) floor(((i - x + 0.5) * num_cols) * w_inv);
- for (i64 j = j0; j <= j1; ++j) {
- i64 row = (i64) floor(((j - y + .5) * CHAR_NUM_BITS_Y_) * h_inv);
- if (char_bit_(offset, row))
+ if ((_lcd_bits[index] & (1ull << (row * 8 + column))) != 0)
put_pixel_(dst.pixels + j * dst.stride + i, color);
}
}
}
- x += kx * (num_cols + char_spacing_(num_chars, text, n));
+ x += kx * (num_cols + lcd_spacing_(num_chars, text, n));
}
}
@@ -808,8 +900,8 @@ void draw_text_area_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box ar
PROFILER_begin(PROFILE_DRAW_TEXT_AREA);
- i64 num_columns = enum_text_columns_(num_chars, text);
- i64 num_rows = enum_text_rows_(num_chars, text);
+ i64 num_columns = lcd_enum_text_columns_(num_chars, text);
+ i64 num_rows = lcd_enum_text_rows_(num_chars, text);
f64 scale_x = area.width / num_columns;
f64 scale_y = area.height / num_rows;
@@ -822,7 +914,7 @@ void draw_text_area_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box ar
kx = k * max_size.x;
ky = k * max_size.y;
- draw_text_(dst, color, area.x, area.y, kx, ky, num_chars, text);
+ lcd_draw_text_(dst, color, area.x, area.y, kx, ky, num_chars, text);
PROFILER_end(PROFILE_DRAW_TEXT_AREA);
}
@@ -835,10 +927,10 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box
PROFILER_begin(PROFILE_DRAW_TEXT_CURSOR);
- i64 num_columns = enum_text_columns_(num_chars, text);
- i64 num_rows = enum_text_rows_(num_chars, text);
- i64 cursor_x = text_cursor_(cursor, text);
- i64 cursor_y = enum_text_rows_(cursor, text);
+ i64 num_columns = lcd_enum_text_columns_(num_chars, text);
+ i64 num_rows = lcd_enum_text_rows_(num_chars, text);
+ i64 cursor_x = lcd_cursor_(cursor, text);
+ i64 cursor_y = lcd_enum_text_rows_(cursor, text);
f64 scale_x = area.width / num_columns;
f64 scale_y = area.height / num_rows;
@@ -855,13 +947,13 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box
i64 selection_x, selection_y;
if (selection > 0) {
- selection_x = text_cursor_(cursor + selection, text);
- selection_y = enum_text_rows_(cursor + selection, text);
+ selection_x = lcd_cursor_(cursor + selection, text);
+ selection_y = lcd_enum_text_rows_(cursor + selection, text);
} else {
selection_x = cursor_x;
selection_y = cursor_y;
- cursor_x = text_cursor_(cursor + selection, text);
- cursor_y = enum_text_rows_(cursor + selection, text);
+ cursor_x = lcd_cursor_(cursor + selection, text);
+ cursor_y = lcd_enum_text_rows_(cursor + selection, text);
}
if (cursor_y == selection_y)
@@ -870,9 +962,9 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box
color,
(Box) {
.x = area.x + kx * cursor_x,
- .y = area.y + ky * cursor_y - ky * (CHAR_NUM_BITS_Y_ + 1),
+ .y = area.y + ky * cursor_y - ky * (LCD_Height + 1),
.width = kx * (selection_x - cursor_x),
- .height = ky * (CHAR_NUM_BITS_Y_ + 1),
+ .height = ky * (LCD_Height + 1),
}
);
else {
@@ -881,20 +973,20 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box
color,
(Box) {
.x = area.x + kx * cursor_x,
- .y = area.y + ky * cursor_y - ky * (CHAR_NUM_BITS_Y_ + 1),
+ .y = area.y + ky * cursor_y - ky * (LCD_Height + 1),
.width = kx * (num_columns - cursor_x),
- .height = ky * (CHAR_NUM_BITS_Y_ + 1),
+ .height = ky * (LCD_Height + 1),
}
);
- for (i64 j = cursor_y + CHAR_NUM_BITS_Y_ + 1; j < selection_y; j += CHAR_NUM_BITS_Y_ + 1)
+ for (i64 j = cursor_y + LCD_Height + 1; j < selection_y; j += LCD_Height + 1)
fill_rectangle_to_buffer(
dst,
color,
(Box) {
.x = area.x,
- .y = area.y + ky * j - ky * (CHAR_NUM_BITS_Y_ + 1),
+ .y = area.y + ky * j - ky * (LCD_Height + 1),
.width = kx * num_columns,
- .height = ky * (CHAR_NUM_BITS_Y_ + 1),
+ .height = ky * (LCD_Height + 1),
}
);
fill_rectangle_to_buffer(
@@ -902,9 +994,9 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box
color,
(Box) {
.x = area.x,
- .y = area.y + ky * selection_y - ky * (CHAR_NUM_BITS_Y_ + 1),
+ .y = area.y + ky * selection_y - ky * (LCD_Height + 1),
.width = kx * selection_x,
- .height = ky * (CHAR_NUM_BITS_Y_ + 1),
+ .height = ky * (LCD_Height + 1),
}
);
}
@@ -914,9 +1006,9 @@ void draw_text_cursor_to_buffer(Pixel_Buffer dst, i32 font, vec4_f32 color, Box
color,
(Box) {
.x = area.x + kx * cursor_x,
- .y = area.y + ky * cursor_y - ky * CHAR_NUM_BITS_Y_,
+ .y = area.y + ky * cursor_y - ky * LCD_Height,
.width = kx * .5,
- .height = ky * (CHAR_NUM_BITS_Y_ - 1),
+ .height = ky * (LCD_Height - 1),
}
);
@@ -2559,6 +2651,15 @@ TEST("line") {
1.0
);
+ // printf("\n");
+ // for (i64 j = 0; j < h; ++j) {
+ // for (i64 i = 0; i < w; ++i) {
+ // printf(" %c", pixels[j * w + i].x > 0.5 ? 'x' : '.');
+ // }
+ // printf("\n");
+ // }
+ // printf("\n");
+
b8 expect_bits[100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
@@ -2608,6 +2709,15 @@ TEST("text letter A") {
(c32[1]) { 'A', }
);
+ // printf("\n");
+ // for (i64 j = 0; j < h; ++j) {
+ // for (i64 i = 0; i < w; ++i) {
+ // printf(" %c", pixels[j * w + i].x > 0.5 ? 'x' : '.');
+ // }
+ // printf("\n");
+ // }
+ // printf("\n");
+
b8 expect_bits[100] = {
0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
@@ -2657,6 +2767,15 @@ TEST("text letter z") {
(c32[1]) { 'z', }
);
+ // printf("\n");
+ // for (i64 j = 0; j < h; ++j) {
+ // for (i64 i = 0; i < w; ++i) {
+ // printf(" %c", pixels[j * w + i].x > 0.5 ? 'x' : '.');
+ // }
+ // printf("\n");
+ // }
+ // printf("\n");
+
b8 expect_bits[100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
@@ -2706,6 +2825,15 @@ TEST("text digits 42") {
(c32[2]) { '4', '2', }
);
+ // printf("\n");
+ // for (i64 j = 0; j < h; ++j) {
+ // for (i64 i = 0; i < w; ++i) {
+ // printf(" %c", pixels[j * w + i].x > 0.5 ? 'x' : '.');
+ // }
+ // printf("\n");
+ // }
+ // printf("\n");
+
b8 expect_bits[100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 1, 0, 0, 1, 1, 1, 1,