diff options
Diffstat (limited to 'graphics.c')
-rw-r--r-- | graphics.c | 59 |
1 files changed, 31 insertions, 28 deletions
@@ -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; } } |