#include "render.hpp" #include "minmax.hpp" #include "transform.hpp" #include "holly/ta_global_parameter.hpp" #include "holly/ta_fifo_polygon_converter.hpp" #include "sh7091/serial.hpp" static inline uint32_t get_font_ix(const struct font * font, char_type c) { uint32_t ix; if (c >= font->first_char_code && c <= font->last_char_code) { ix = c - font->first_char_code; } else if (c == '\n') { ix = '#' - font->first_char_code; } else if ('%' <= font->last_char_code) { ix = '%' - font->first_char_code; } else { ix = 0; } return ix; } constexpr inline int32_t int_26_6(int32_t n) { int32_t v = n >> 6; //float d = n & 63; //return v + (d / 64.f); return v; } cursor_advance render_primary_buffer(ta_parameter_writer& writer, const font * font, const glyph * glyphs, const gap_buffer& gb, const viewport_window& window) { int32_t first_line = min(window.first_line, gb.line.length - 1); cursor_advance cursor = { 0 }; int32_t h_advance = 0; int32_t v_advance = 0; const float r_texture_width = 1.0f / font->texture_width; const float r_texture_height = 1.0f / font->texture_height; int row = first_line; int32_t init_i = first_line >= 0 ? gb.line.offsets[first_line] + 1 : 0; for (int32_t i = init_i; i <= gb.size; i++) { if (i == gb.gap_start) { uint32_t ix = get_font_ix(font, ' '); auto& glyph = glyphs[ix]; cursor.x = h_advance + glyph.metrics.horiBearingX; cursor.y = v_advance - glyph.metrics.horiBearingY; cursor.width = glyph.metrics.horiAdvance; cursor.height = font->face_metrics.height; i = gb.gap_end; } if (i == gb.size) break; int32_t x = window.box.x0 + int_26_6(h_advance); int32_t y = window.box.y0 + int_26_6(v_advance); char_type c = gb.buf[i]; uint32_t ix = get_font_ix(font, c); auto& glyph = glyphs[ix]; if (x + int_26_6(glyph.metrics.horiAdvance) <= window.box.x1) { transform_glyph(writer, r_texture_width, r_texture_height, glyph, x, y ); } if (c == '\n') { h_advance = 0; v_advance += font->face_metrics.height; row += 1; if (int_26_6(v_advance + font->face_metrics.height) > window.box.y1) { break; } } else { h_advance += glyph.metrics.horiAdvance; } } return cursor; } void render_cursor(ta_parameter_writer& parameter, const cursor_advance& cursor, const viewport_window& window) { float x = window.box.x0 + int_26_6(cursor.x); float y = window.box.y0 + int_26_6(cursor.y); float width = int_26_6(cursor.width); float height = int_26_6(cursor.height); transform_cursor(parameter, x, // x y, // y width, height ); } void render(ta_parameter_writer& writer, const font * font, const glyph * glyphs, const gap_buffer& gb, const viewport_window& window) { glyph_begin(writer, font->texture_width, font->texture_height); cursor_advance cursor = render_primary_buffer(writer, font, glyphs, gb, window); render_cursor(writer, cursor, window); writer.append() = ta_global_parameter::end_of_list(para_control::para_type::end_of_list); }