summaryrefslogtreecommitdiff
path: root/graphics.c
diff options
context:
space:
mode:
Diffstat (limited to 'graphics.c')
-rw-r--r--graphics.c59
1 files changed, 31 insertions, 28 deletions
diff --git a/graphics.c b/graphics.c
index ffe620a..d0cbdec 100644
--- a/graphics.c
+++ b/graphics.c
@@ -183,6 +183,9 @@ b8 hit_line (vec2 vertices[2], f64 width, vec2 point);
Stencil_Buffer default_stencil(i64 width, i64 height);
+vec2 lcd_text_area (vec2 scale, i64 num_chars, c32 *text);
+void lcd_text_render_to_stencil(Stencil_Buffer dst, vec2 position, vec2 scale, i64 num_chars, c32 *text);
+
void fill_stencil_to_stencil (Stencil_Buffer dst, u8 value, Box area, Stencil_Buffer src);
void fill_rectangle_to_stencil (Stencil_Buffer dst, u8 value, Box area);
void fill_triangle_to_stencil (Stencil_Buffer dst, u8 value, vec2 vertices[3]);
@@ -190,8 +193,6 @@ void fill_triangles_to_stencil (Stencil_Buffer dst, u8 value, vec2 position, ve
void fill_quad_to_stencil (Stencil_Buffer dst, u8 value, vec2 vertices[4]);
void fill_ellipse_to_stencil (Stencil_Buffer dst, u8 value, Box area);
void fill_line_to_stencil (Stencil_Buffer dst, u8 value, vec2 vertices[2], f64 width);
-vec2 lcd_text_area (vec2 scale, i64 num_chars, c32 *text);
-void lcd_text_render_to_stencil (Stencil_Buffer dst, vec2 position, vec2 scale, i64 num_chars, c32 *text);
void draw_text_area_to_stencil (Stencil_Buffer dst, u8 value, i32 font, Box area, vec2 max_size, i64 num_chars, c32 *text);
void draw_text_cursor_to_stencil(Stencil_Buffer dst, u8 value, i32 font, Box area, vec2 max_size, i64 num_chars, c32 *text, i64 cursor, i64 selection);
@@ -1315,14 +1316,9 @@ static i64 lcd_char_width_(c32 c) {
return _lcd_widths[index];
}
-static i64 lcd_spacing_(i64 num_chars, c32 *text, i64 index) {
- if (text == NULL)
- return 0;
- if (index < 0 || index + 1 >= num_chars)
- return 0;
-
- i64 a = text[index] - LCD_First;
- i64 b = text[index + 1] - LCD_First;
+static i64 lcd_spacing_(c32 c0, c32 c1) {
+ i64 a = c0 - LCD_First;
+ i64 b = c1 - LCD_First;
if (a < 0 || a >= LCD_Len || b < 0 || b >= LCD_Len)
return 0;
@@ -1339,17 +1335,19 @@ static i64 lcd_enum_text_columns_(i64 num_chars, c32 *text) {
i64 cols = 0;
i64 n = 0;
- for (i64 i = 0; i < num_chars; ++i) {
- if (text[i] <= ' ') {
- if (text[i] == '\n') {
+ for (c32 *s = text, *s_end = text + num_chars; s < s_end; ++s) {
+ if (*s <= ' ') {
+ if (*s == '\n') {
if (cols < n)
cols = n;
n = 0;
} else
- n += lcd_char_width_(' ') + lcd_spacing_(num_chars, text, i);
+ n += lcd_char_width_(' ');
continue;
}
- n += lcd_char_width_(text[i]) + lcd_spacing_(num_chars, text, i);
+ n += lcd_char_width_(*s);
+ if (s + 1 < s_end)
+ n += lcd_spacing_(s[0], s[1]);
}
if (cols < n)
@@ -1388,24 +1386,29 @@ void lcd_text_render_to_stencil(Stencil_Buffer dst, vec2 position, vec2 scale, i
if (h < EPSILON)
return;
+ u32 h_inv = (u32) floor(0x10000 / h + 0.5);
+ u32 h_half = h_inv / 2;
+
f64 x = position.x;
f64 y = position.y;
- for (i64 n = 0; n < num_chars; ++n) {
- if (text[n] <= ' ') {
- if (text[n] == '\n') {
+ for (c32 *s = text, *s_end = text + num_chars; s < s_end; ++s) {
+ if (*s <= ' ') {
+ if (*s == '\n') {
x = position.x;
y += scale.y * (LCD_Height + 1);
} else
- x += kx * (lcd_char_width_(' ') + lcd_spacing_(num_chars, text, n));
+ x += kx * lcd_char_width_(' ');
continue;
}
- i64 num_cols = lcd_char_width_(text[n]);
+ i64 num_cols = lcd_char_width_(*s);
f64 w = num_cols * kx;
- i64 index = text[n] - LCD_First;
+ i64 index = *s - LCD_First;
if (w >= EPSILON && index >= 0 && index < LCD_Len) {
+ u64 bits = _lcd_bits[index];
+
i64 i0 = (i64) floor(x + 0.5);
i64 i1 = (i64) floor(x + w + 0.5);
i64 j0 = (i64) floor(y + 0.5);
@@ -1419,24 +1422,24 @@ void lcd_text_render_to_stencil(Stencil_Buffer dst, vec2 position, vec2 scale, i
if (j0 < 0) j0 = 0;
if (j1 > dst.height) j1 = dst.height;
- u32 w_inv = (u32) floor(0x10000 / w + 0.5);
- u32 h_inv = (u32) floor(0x10000 / h + 0.5);
-
+ u32 w_inv = (u32) floor(0x10000 / w + 0.5);
u32 w_half = w_inv / 2;
- u32 h_half = h_inv / 2;
for (i64 j = j0; j < j1; ++j) {
- u32 row = (((j - j00) * LCD_Height) * h_inv + h_half) >> 16;
+ u32 row_8 = ((((j - j00) * LCD_Height) * h_inv + h_half) >> 16) * 8;
for (i64 i = i0; i < i1; ++i) {
u32 column = (((i - i00) * num_cols) * w_inv + w_half) >> 16;
- if ((_lcd_bits[index] & (1ull << (row * 8 + column))) != 0)
+ if ((bits & (1ull << (row_8 + column))) != 0)
dst.pixels[j * dst.stride + i] = max2_u8_(dst.pixels[j * dst.stride + i], 255);
}
}
}
- x += kx * (num_cols + lcd_spacing_(num_chars, text, n));
+ if (s + 1 < s_end)
+ num_cols += lcd_spacing_(s[0], s[1]);
+
+ x += kx * num_cols;
}
}