text_editor: add viewport scrolling
This commit is contained in:
parent
487289f3c9
commit
cf4b078d0a
@ -91,6 +91,7 @@ namespace ft6 {
|
|||||||
}
|
}
|
||||||
namespace ft6 {
|
namespace ft6 {
|
||||||
namespace scan_code {
|
namespace scan_code {
|
||||||
|
constexpr uint32_t first_printable = 0x4;
|
||||||
constexpr uint32_t last_printable = 0x38;
|
constexpr uint32_t last_printable = 0x38;
|
||||||
|
|
||||||
const uint8_t code_point[last_printable + 1][2] = {
|
const uint8_t code_point[last_printable + 1][2] = {
|
||||||
@ -154,4 +155,3 @@ namespace ft6 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ void gap_cursor_pos_abs(struct gap_buffer& gb, int32_t pos)
|
|||||||
gap_cursor_pos(gb, pos - gb.gap_start);
|
gap_cursor_pos(gb, pos - gb.gap_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t gap_column_number(struct gap_buffer& gb)
|
int32_t gap_column_number(const struct gap_buffer& gb)
|
||||||
{
|
{
|
||||||
int32_t line_start = 0;
|
int32_t line_start = 0;
|
||||||
if (gb.line.gap > 0)
|
if (gb.line.gap > 0)
|
||||||
|
@ -32,5 +32,5 @@ void gap_resize(struct gap_buffer& gb);
|
|||||||
void gap_append(struct gap_buffer& gb, char_type c);
|
void gap_append(struct gap_buffer& gb, char_type c);
|
||||||
void gap_pop(struct gap_buffer& gb);
|
void gap_pop(struct gap_buffer& gb);
|
||||||
void gap_cursor_pos(struct gap_buffer& gb, int32_t delta);
|
void gap_cursor_pos(struct gap_buffer& gb, int32_t delta);
|
||||||
int32_t gap_column_number(struct gap_buffer& gb);
|
int32_t gap_column_number(const struct gap_buffer& gb);
|
||||||
void gap_cursor_pos_line(struct gap_buffer& gb, int32_t delta);
|
void gap_cursor_pos_line(struct gap_buffer& gb, int32_t delta);
|
||||||
|
@ -119,14 +119,36 @@ void keyboard_debug(ft6::data_transfer::data_format * keyboards, uint32_t frame_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_shifted(const uint8_t modifier_key)
|
constexpr inline bool is_modified(uint32_t modifier, uint32_t bit)
|
||||||
{
|
{
|
||||||
return
|
uint32_t mask = ~(bit);
|
||||||
(ft6::data_transfer::modifier_key::right_shift() & modifier_key) ||
|
return ((modifier & bit) != 0) && ((modifier & mask) == 0);
|
||||||
(ft6::data_transfer::modifier_key::left_shift() & modifier_key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix, gap_buffer& gb)
|
constexpr inline bool is_unmodified(uint32_t modifier)
|
||||||
|
{
|
||||||
|
return modifier == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline bool is_shifted(uint32_t modifier)
|
||||||
|
{
|
||||||
|
uint32_t bit = ft6::data_transfer::modifier_key::right_shift() | ft6::data_transfer::modifier_key::left_shift();
|
||||||
|
return is_modified(modifier, bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline bool is_left_alted(uint32_t modifier)
|
||||||
|
{
|
||||||
|
uint32_t bit = (ft6::data_transfer::modifier_key::left_alt());
|
||||||
|
return is_modified(modifier, bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline bool is_ctrled(uint32_t modifier)
|
||||||
|
{
|
||||||
|
uint32_t bit = (ft6::data_transfer::modifier_key::left_control() | ft6::data_transfer::modifier_key::right_control());
|
||||||
|
return is_modified(modifier, bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix, gap_buffer& gb, viewport_window& vw)
|
||||||
{
|
{
|
||||||
uint32_t this_frame = (frame_ix + 0) & 1;
|
uint32_t this_frame = (frame_ix + 0) & 1;
|
||||||
uint32_t next_frame = (frame_ix + 1) & 1;
|
uint32_t next_frame = (frame_ix + 1) & 1;
|
||||||
@ -144,15 +166,21 @@ void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame
|
|||||||
}
|
}
|
||||||
if (make) {
|
if (make) {
|
||||||
// make
|
// make
|
||||||
|
int modifier_key = keyboards[this_frame].modifier_key;
|
||||||
uint8_t scan_code = keyboards[this_frame].scan_code_array[i];
|
uint8_t scan_code = keyboards[this_frame].scan_code_array[i];
|
||||||
if (scan_code <= ft6::scan_code::last_printable) {
|
|
||||||
bool shifted = is_shifted(keyboards[this_frame].modifier_key);
|
if (is_shifted(modifier_key) || is_unmodified(modifier_key)) {
|
||||||
|
if (scan_code >= ft6::scan_code::first_printable && scan_code <= ft6::scan_code::last_printable) {
|
||||||
|
bool shifted = is_shifted(modifier_key);
|
||||||
char_type code_point = ft6::scan_code::code_point[scan_code][shifted];
|
char_type code_point = ft6::scan_code::code_point[scan_code][shifted];
|
||||||
if (code_point != 0) {
|
if (code_point != 0) {
|
||||||
gap_append(gb, code_point);
|
gap_append(gb, code_point);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_unmodified(modifier_key)) {
|
||||||
switch (scan_code) {
|
switch (scan_code) {
|
||||||
case ft6::scan_code::_return: gap_append(gb, '\n'); break;
|
case ft6::scan_code::_return: gap_append(gb, '\n'); break;
|
||||||
case ft6::scan_code::backspace: gap_pop(gb); break;
|
case ft6::scan_code::backspace: gap_pop(gb); break;
|
||||||
@ -162,8 +190,32 @@ void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame
|
|||||||
case ft6::scan_code::right_arrow: gap_cursor_pos(gb, 1); break;
|
case ft6::scan_code::right_arrow: gap_cursor_pos(gb, 1); break;
|
||||||
case ft6::scan_code::up_arrow: gap_cursor_pos_line(gb, -1); break;
|
case ft6::scan_code::up_arrow: gap_cursor_pos_line(gb, -1); break;
|
||||||
case ft6::scan_code::down_arrow: gap_cursor_pos_line(gb, 1); break;
|
case ft6::scan_code::down_arrow: gap_cursor_pos_line(gb, 1); break;
|
||||||
default:
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_left_alted(modifier_key)) {
|
||||||
|
switch (scan_code) {
|
||||||
|
case ft6::scan_code::v_V:
|
||||||
|
vw.first_line -= 1;
|
||||||
|
if (vw.first_line < 0)
|
||||||
|
vw.first_line = 0;
|
||||||
break;
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_ctrled(modifier_key)) {
|
||||||
|
switch (scan_code) {
|
||||||
|
case ft6::scan_code::v_V:
|
||||||
|
vw.first_line += 1;
|
||||||
|
if ((vw.first_line - 1) >= gb.line.length) {
|
||||||
|
vw.first_line = gb.line.length;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
#include "maple/maple_bus_ft6.hpp"
|
#include "maple/maple_bus_ft6.hpp"
|
||||||
#include "gap_buffer.hpp"
|
#include "gap_buffer.hpp"
|
||||||
|
#include "viewport_window.hpp"
|
||||||
|
|
||||||
void keyboard_do_get_condition(ft6::data_transfer::data_format& data);
|
void keyboard_do_get_condition(ft6::data_transfer::data_format& data);
|
||||||
|
|
||||||
void keyboard_debug(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix);
|
void keyboard_debug(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix);
|
||||||
|
|
||||||
void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix, gap_buffer& gb);
|
void keyboard_update(ft6::data_transfer::data_format * keyboards, uint32_t frame_ix, gap_buffer& gb, viewport_window& vw);
|
||||||
|
70
text_editor/parse.cpp
Normal file
70
text_editor/parse.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "parse.hpp"
|
||||||
|
|
||||||
|
int parse_base10_digit(char c)
|
||||||
|
{
|
||||||
|
switch (c) {
|
||||||
|
case '0': return 0;
|
||||||
|
case '1': return 1;
|
||||||
|
case '2': return 2;
|
||||||
|
case '3': return 3;
|
||||||
|
case '4': return 4;
|
||||||
|
case '5': return 5;
|
||||||
|
case '6': return 6;
|
||||||
|
case '7': return 7;
|
||||||
|
case '8': return 8;
|
||||||
|
case '9': return 9;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * parse_base10(const char * s, int * n)
|
||||||
|
{
|
||||||
|
*n = 0;
|
||||||
|
int sign = 1;
|
||||||
|
|
||||||
|
if (*s == '-') {
|
||||||
|
sign = -1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int digit = parse_base10_digit(*s);
|
||||||
|
if (digit == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*n *= 10;
|
||||||
|
*n += digit;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n *= sign;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * parse_base10_64(const char * s, int64_t * n)
|
||||||
|
{
|
||||||
|
*n = 0;
|
||||||
|
int sign = 1;
|
||||||
|
|
||||||
|
if (*s == '-') {
|
||||||
|
sign = -1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int digit = parse_base10_digit(*s);
|
||||||
|
if (digit == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
*n *= 10;
|
||||||
|
*n += digit;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n *= sign;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
5
text_editor/parse.hpp
Normal file
5
text_editor/parse.hpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
int parse_base10_digit(char c);
|
||||||
|
const char * parse_base10(const char * s, int * n);
|
||||||
|
const char * parse_base10_64(const char * s, int64_t * n);
|
173
text_editor/printf.cpp
Normal file
173
text_editor/printf.cpp
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "parse.hpp"
|
||||||
|
#include "unparse.hpp"
|
||||||
|
#include "printf.hpp"
|
||||||
|
|
||||||
|
enum format_type {
|
||||||
|
FORMAT_BASE10_UNSIGNED,
|
||||||
|
FORMAT_BASE10,
|
||||||
|
FORMAT_BASE10_64,
|
||||||
|
FORMAT_POINTER,
|
||||||
|
FORMAT_BASE16,
|
||||||
|
FORMAT_STRING,
|
||||||
|
FORMAT_CHAR,
|
||||||
|
FORMAT_PERCENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct format {
|
||||||
|
enum format_type type;
|
||||||
|
int pad_length;
|
||||||
|
char fill_char;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * parse_escape(const char * format, struct format * ft);
|
||||||
|
|
||||||
|
static const char * parse_fill_pad(const char * format, struct format * ft)
|
||||||
|
{
|
||||||
|
if (*format == 0)
|
||||||
|
return format;
|
||||||
|
if (*format >= '1' || *format <= '9')
|
||||||
|
ft->fill_char = ' ';
|
||||||
|
else
|
||||||
|
ft->fill_char = *format++;
|
||||||
|
format = parse_base10(format, &ft->pad_length);
|
||||||
|
return parse_escape(format, ft);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * parse_escape(const char * format, struct format * ft)
|
||||||
|
{
|
||||||
|
switch (*format) {
|
||||||
|
case 0:
|
||||||
|
return format;
|
||||||
|
case 'u':
|
||||||
|
ft->type = FORMAT_BASE10_UNSIGNED;
|
||||||
|
return format + 1;
|
||||||
|
case 'd':
|
||||||
|
ft->type = FORMAT_BASE10;
|
||||||
|
return format + 1;
|
||||||
|
case 'l':
|
||||||
|
ft->type = FORMAT_BASE10_64;
|
||||||
|
return format + 1;
|
||||||
|
case 'p':
|
||||||
|
ft->type = FORMAT_POINTER;
|
||||||
|
return format + 1;
|
||||||
|
case 'x':
|
||||||
|
ft->type = FORMAT_BASE16;
|
||||||
|
return format + 1;
|
||||||
|
case 's':
|
||||||
|
ft->type = FORMAT_STRING;
|
||||||
|
return format + 1;
|
||||||
|
case 'c':
|
||||||
|
ft->type = FORMAT_CHAR;
|
||||||
|
return format + 1;
|
||||||
|
case '%':
|
||||||
|
ft->type = FORMAT_PERCENT;
|
||||||
|
return format + 1;
|
||||||
|
default:
|
||||||
|
return parse_fill_pad(format, ft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int copy_string(const char * src, int src_len, char * dst, int dst_len, int dst_ix)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < src_len; i++) {
|
||||||
|
if (dst_ix + i >= dst_len)
|
||||||
|
break;
|
||||||
|
dst[dst_ix + i] = src[i];
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snprintf(char * buf, int buf_len, const char * format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
int buf_ix = 0;
|
||||||
|
|
||||||
|
while (buf_ix < buf_len) {
|
||||||
|
if (*format == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (*format) {
|
||||||
|
case '%':
|
||||||
|
{
|
||||||
|
struct format ft;
|
||||||
|
ft.pad_length = 0;
|
||||||
|
ft.fill_char = 0;
|
||||||
|
format = parse_escape(format + 1, &ft);
|
||||||
|
switch (ft.type) {
|
||||||
|
case FORMAT_BASE10_UNSIGNED:
|
||||||
|
{
|
||||||
|
uint32_t num = va_arg(args, uint32_t);
|
||||||
|
char s[10];
|
||||||
|
int offset = unparse_base10_unsigned(s, num, ft.pad_length, ft.fill_char);
|
||||||
|
buf_ix += copy_string(s, offset, buf, buf_len, buf_ix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_BASE10:
|
||||||
|
{
|
||||||
|
int32_t num = va_arg(args, int32_t);
|
||||||
|
char s[10];
|
||||||
|
int offset = unparse_base10(s, num, ft.pad_length, ft.fill_char);
|
||||||
|
buf_ix += copy_string(s, offset, buf, buf_len, buf_ix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_BASE10_64:
|
||||||
|
{
|
||||||
|
int64_t num = va_arg(args, int64_t);
|
||||||
|
char s[20];
|
||||||
|
int offset = unparse_base10_64(s, num, ft.pad_length, ft.fill_char);
|
||||||
|
buf_ix += copy_string(s, offset, buf, buf_len, buf_ix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_POINTER:
|
||||||
|
{
|
||||||
|
const char s[2] = {'0', 'x'};
|
||||||
|
buf_ix += copy_string(s, 2, buf, buf_len, buf_ix);
|
||||||
|
}
|
||||||
|
/* fall through */;
|
||||||
|
case FORMAT_BASE16:
|
||||||
|
{
|
||||||
|
uint32_t num = va_arg(args, uint32_t);
|
||||||
|
char s[8];
|
||||||
|
int offset = unparse_base16(s, num, ft.pad_length, ft.fill_char);
|
||||||
|
buf_ix += copy_string(s, offset, buf, buf_len, buf_ix);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_STRING:
|
||||||
|
{
|
||||||
|
const char * s = va_arg(args, const char *);
|
||||||
|
while (*s != 0 && buf_ix < buf_len) {
|
||||||
|
buf[buf_ix++] = *s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_CHAR:
|
||||||
|
{
|
||||||
|
const int c = va_arg(args, const int);
|
||||||
|
buf[buf_ix++] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FORMAT_PERCENT:
|
||||||
|
buf[buf_ix++] = '%';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
char c = *format++;
|
||||||
|
buf[buf_ix++] = c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return buf_ix;
|
||||||
|
}
|
3
text_editor/printf.hpp
Normal file
3
text_editor/printf.hpp
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int snprintf(char * buf, int len, const char * format, ...);
|
@ -1,6 +1,7 @@
|
|||||||
#include "render.hpp"
|
#include "render.hpp"
|
||||||
#include "minmax.hpp"
|
#include "minmax.hpp"
|
||||||
#include "transform.hpp"
|
#include "transform.hpp"
|
||||||
|
#include "unparse.hpp"
|
||||||
|
|
||||||
#include "holly/ta_global_parameter.hpp"
|
#include "holly/ta_global_parameter.hpp"
|
||||||
#include "holly/ta_fifo_polygon_converter.hpp"
|
#include "holly/ta_fifo_polygon_converter.hpp"
|
||||||
@ -36,9 +37,11 @@ cursor_advance render_primary_buffer(ta_parameter_writer& writer,
|
|||||||
const gap_buffer& gb,
|
const gap_buffer& gb,
|
||||||
const viewport_window& window)
|
const viewport_window& window)
|
||||||
{
|
{
|
||||||
int32_t first_line = min(window.first_line, gb.line.length - 1);
|
int32_t first_line = window.first_line;
|
||||||
|
|
||||||
cursor_advance cursor = { 0 };
|
cursor_advance cursor = { 0 };
|
||||||
|
cursor.x = -1;
|
||||||
|
cursor.y = -1;
|
||||||
int32_t h_advance = 0;
|
int32_t h_advance = 0;
|
||||||
int32_t v_advance = 0;
|
int32_t v_advance = 0;
|
||||||
|
|
||||||
@ -47,7 +50,16 @@ cursor_advance render_primary_buffer(ta_parameter_writer& writer,
|
|||||||
|
|
||||||
int row = first_line;
|
int row = first_line;
|
||||||
|
|
||||||
int32_t init_i = first_line >= 0 ? gb.line.offsets[first_line] + 1 : 0;
|
// line 0 is prior to the beginning of gb.line.offsets
|
||||||
|
// gb.line.offsets is the index of the newline character
|
||||||
|
int32_t init_i;
|
||||||
|
if (first_line == 0) {
|
||||||
|
init_i = 0;
|
||||||
|
} else if ((first_line - 1) >= 0 && (first_line - 1) < gb.line.length) {
|
||||||
|
init_i = gb.line.offsets[first_line - 1] + 1;
|
||||||
|
} else {
|
||||||
|
init_i = gb.size;
|
||||||
|
}
|
||||||
for (int32_t i = init_i; i <= gb.size; i++) {
|
for (int32_t i = init_i; i <= gb.size; i++) {
|
||||||
if (i == gb.gap_start) {
|
if (i == gb.gap_start) {
|
||||||
uint32_t ix = get_font_ix(font, ' ');
|
uint32_t ix = get_font_ix(font, ' ');
|
||||||
@ -97,7 +109,41 @@ cursor_advance render_primary_buffer(ta_parameter_writer& writer,
|
|||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_cursor(ta_parameter_writer& parameter,
|
void render_text(ta_parameter_writer& writer,
|
||||||
|
const font * font,
|
||||||
|
const glyph * glyphs,
|
||||||
|
const char * buf,
|
||||||
|
int length,
|
||||||
|
int32_t x0,
|
||||||
|
int32_t y0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int32_t x = x0 + int_26_6(h_advance);
|
||||||
|
int32_t y = y0 + int_26_6(v_advance);
|
||||||
|
|
||||||
|
char_type c = buf[i];
|
||||||
|
uint32_t ix = get_font_ix(font, c);
|
||||||
|
auto& glyph = glyphs[ix];
|
||||||
|
|
||||||
|
transform_glyph(writer,
|
||||||
|
r_texture_width,
|
||||||
|
r_texture_height,
|
||||||
|
glyph,
|
||||||
|
x,
|
||||||
|
y
|
||||||
|
);
|
||||||
|
|
||||||
|
h_advance += glyph.metrics.horiAdvance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_cursor(ta_parameter_writer& writer,
|
||||||
const cursor_advance& cursor,
|
const cursor_advance& cursor,
|
||||||
const viewport_window& window)
|
const viewport_window& window)
|
||||||
{
|
{
|
||||||
@ -106,7 +152,7 @@ void render_cursor(ta_parameter_writer& parameter,
|
|||||||
float width = int_26_6(cursor.width);
|
float width = int_26_6(cursor.width);
|
||||||
float height = int_26_6(cursor.height);
|
float height = int_26_6(cursor.height);
|
||||||
|
|
||||||
transform_cursor(parameter,
|
transform_cursor(writer,
|
||||||
x, // x
|
x, // x
|
||||||
y, // y
|
y, // y
|
||||||
width,
|
width,
|
||||||
@ -114,6 +160,39 @@ void render_cursor(ta_parameter_writer& parameter,
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int copy_str(const char * s, char * d, int d_ix)
|
||||||
|
{
|
||||||
|
while (*s != 0) {
|
||||||
|
d[d_ix++] = *s++;
|
||||||
|
}
|
||||||
|
return d_ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_status(ta_parameter_writer& writer,
|
||||||
|
const font * font,
|
||||||
|
const glyph * glyphs,
|
||||||
|
const gap_buffer& gb,
|
||||||
|
const viewport_window& window)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
int ix = 0;
|
||||||
|
|
||||||
|
ix = copy_str("(", buf, ix);
|
||||||
|
ix += unparse_base10(&buf[ix], gb.line.gap, 0, 0);
|
||||||
|
ix = copy_str(",", buf, ix);
|
||||||
|
ix += unparse_base10(&buf[ix], gap_column_number(gb), 0, 0);
|
||||||
|
ix = copy_str(") ", buf, ix);
|
||||||
|
ix += unparse_base10(&buf[ix], window.first_line, 0, 0);
|
||||||
|
|
||||||
|
render_text(writer,
|
||||||
|
font,
|
||||||
|
glyphs,
|
||||||
|
buf,
|
||||||
|
ix,
|
||||||
|
window.box.x0,
|
||||||
|
480 - int_26_6(font->face_metrics.height) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
void render(ta_parameter_writer& writer,
|
void render(ta_parameter_writer& writer,
|
||||||
const font * font,
|
const font * font,
|
||||||
const glyph * glyphs,
|
const glyph * glyphs,
|
||||||
@ -124,6 +203,8 @@ void render(ta_parameter_writer& writer,
|
|||||||
font->texture_width,
|
font->texture_width,
|
||||||
font->texture_height);
|
font->texture_height);
|
||||||
|
|
||||||
|
render_status(writer, font, glyphs, gb, window);
|
||||||
|
|
||||||
cursor_advance cursor = render_primary_buffer(writer, font, glyphs, gb, window);
|
cursor_advance cursor = render_primary_buffer(writer, font, glyphs, gb, window);
|
||||||
|
|
||||||
render_cursor(writer, cursor, window);
|
render_cursor(writer, cursor, window);
|
||||||
|
@ -256,7 +256,7 @@ void main()
|
|||||||
struct editor_state state = { 0 };
|
struct editor_state state = { 0 };
|
||||||
gap_init_from_buf(state.gb, buf, buf_size, 0);
|
gap_init_from_buf(state.gb, buf, buf_size, 0);
|
||||||
line_init_from_buf(state.gb, offsets, offsets_size);
|
line_init_from_buf(state.gb, offsets, offsets_size);
|
||||||
viewport_init_fullscreen(state.window);
|
viewport_init_fullscreen(state.window, font);
|
||||||
|
|
||||||
ft6::data_transfer::data_format keyboards[2] = { 0 };
|
ft6::data_transfer::data_format keyboards[2] = { 0 };
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ void main()
|
|||||||
while (true) {
|
while (true) {
|
||||||
keyboard_do_get_condition(keyboards[frame_ix & 1]);
|
keyboard_do_get_condition(keyboards[frame_ix & 1]);
|
||||||
keyboard_debug(keyboards, frame_ix);
|
keyboard_debug(keyboards, frame_ix);
|
||||||
keyboard_update(keyboards, frame_ix, state.gb);
|
keyboard_update(keyboards, frame_ix, state.gb, state.window);
|
||||||
|
|
||||||
ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters[0].start,
|
ta_polygon_converter_init2(texture_memory_alloc.isp_tsp_parameters[0].start,
|
||||||
texture_memory_alloc.isp_tsp_parameters[0].end,
|
texture_memory_alloc.isp_tsp_parameters[0].end,
|
||||||
|
@ -4,6 +4,7 @@ TEXT_EDITOR_OBJ = \
|
|||||||
text_editor/render.o \
|
text_editor/render.o \
|
||||||
text_editor/keyboard.o \
|
text_editor/keyboard.o \
|
||||||
text_editor/transform.o \
|
text_editor/transform.o \
|
||||||
|
text_editor/unparse.o \
|
||||||
holly/video_output.o \
|
holly/video_output.o \
|
||||||
holly/core.o \
|
holly/core.o \
|
||||||
holly/region_array.o \
|
holly/region_array.o \
|
||||||
|
@ -204,6 +204,6 @@ void transform_glyph(ta_parameter_writer& writer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float z = 0.1f;
|
const float z = 0.1f;
|
||||||
uint32_t base_color = 0xff0080ff;
|
uint32_t base_color = 0xffffff;
|
||||||
transfer_quad_type_3(writer, out[0], out[1], out[2], out[3], z, base_color);
|
transfer_quad_type_3(writer, out[0], out[1], out[2], out[3], z, base_color);
|
||||||
}
|
}
|
||||||
|
165
text_editor/unparse.cpp
Normal file
165
text_editor/unparse.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#include "minmax.hpp"
|
||||||
|
#include "unparse.hpp"
|
||||||
|
|
||||||
|
int digits_base10(uint32_t n)
|
||||||
|
{
|
||||||
|
if (n >= 1000000000ul) return 10;
|
||||||
|
if (n >= 100000000ul) return 9;
|
||||||
|
if (n >= 10000000ul) return 8;
|
||||||
|
if (n >= 1000000ul) return 7;
|
||||||
|
if (n >= 100000ul) return 6;
|
||||||
|
if (n >= 10000ul) return 5;
|
||||||
|
if (n >= 1000ul) return 4;
|
||||||
|
if (n >= 100ul) return 3;
|
||||||
|
if (n >= 10ul) return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unparse_base10_unsigned(char * s, uint32_t n, int len, char fill)
|
||||||
|
{
|
||||||
|
int digits = 0;
|
||||||
|
digits += digits_base10(n);
|
||||||
|
len = max(digits, len);
|
||||||
|
int ret = len;
|
||||||
|
|
||||||
|
while (len > digits) {
|
||||||
|
*s++ = fill;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
const uint32_t digit = n % 10;
|
||||||
|
n = n / 10;
|
||||||
|
s[--len] = digit + 48;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unparse_base10(char * s, int32_t n, int len, char fill)
|
||||||
|
{
|
||||||
|
bool negative = false;
|
||||||
|
int digits = 0;
|
||||||
|
if (n < 0) {
|
||||||
|
digits += 1;
|
||||||
|
n = -n;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
digits += digits_base10(n);
|
||||||
|
len = max(digits, len);
|
||||||
|
int ret = len;
|
||||||
|
|
||||||
|
while (len > digits) {
|
||||||
|
*s++ = fill;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
*s++ = '-';
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
const uint32_t digit = n % 10;
|
||||||
|
n = n / 10;
|
||||||
|
s[--len] = digit + 48;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int digits_base10_64(uint64_t n)
|
||||||
|
{
|
||||||
|
if (n >= 10000000000000000000ull) return 20;
|
||||||
|
if (n >= 1000000000000000000ull) return 19;
|
||||||
|
if (n >= 100000000000000000ull) return 18;
|
||||||
|
if (n >= 10000000000000000ull) return 17;
|
||||||
|
if (n >= 1000000000000000ull) return 16;
|
||||||
|
if (n >= 100000000000000ull) return 15;
|
||||||
|
if (n >= 10000000000000ull) return 14;
|
||||||
|
if (n >= 1000000000000ull) return 13;
|
||||||
|
if (n >= 100000000000ull) return 12;
|
||||||
|
if (n >= 10000000000ull) return 11;
|
||||||
|
if (n >= 1000000000ull) return 10;
|
||||||
|
if (n >= 100000000ull) return 9;
|
||||||
|
if (n >= 10000000ull) return 8;
|
||||||
|
if (n >= 1000000ull) return 7;
|
||||||
|
if (n >= 100000ull) return 6;
|
||||||
|
if (n >= 10000ull) return 5;
|
||||||
|
if (n >= 1000ull) return 4;
|
||||||
|
if (n >= 100ull) return 3;
|
||||||
|
if (n >= 10ull) return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unparse_base10_64(char * s, int64_t n, int len, char fill)
|
||||||
|
{
|
||||||
|
bool negative = false;
|
||||||
|
int digits = 0;
|
||||||
|
if (n < 0) {
|
||||||
|
digits += 1;
|
||||||
|
n = -n;
|
||||||
|
negative = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
digits += digits_base10_64(n);
|
||||||
|
len = max(digits, len);
|
||||||
|
int ret = len;
|
||||||
|
|
||||||
|
while (len > digits) {
|
||||||
|
*s++ = fill;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negative) {
|
||||||
|
*s++ = '-';
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
const uint32_t digit = n % 10;
|
||||||
|
n = n / 10;
|
||||||
|
s[--len] = digit + 48;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int digits_base16(uint32_t n)
|
||||||
|
{
|
||||||
|
if (n <= 0xf) return 1;
|
||||||
|
if (n <= 0xff) return 2;
|
||||||
|
if (n <= 0xfff) return 3;
|
||||||
|
if (n <= 0xffff) return 4;
|
||||||
|
if (n <= 0xfffff) return 5;
|
||||||
|
if (n <= 0xffffff) return 6;
|
||||||
|
if (n <= 0xfffffff) return 7;
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unparse_base16(char * s, uint32_t n, int len, char fill)
|
||||||
|
{
|
||||||
|
int digits = digits_base16(n);
|
||||||
|
len = max(digits, len);
|
||||||
|
int ret = len;
|
||||||
|
|
||||||
|
while (len > digits) {
|
||||||
|
*s++ = fill;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
uint32_t nib = n & 0xf;
|
||||||
|
n = n >> 4;
|
||||||
|
if (nib > 9) {
|
||||||
|
nib += (97 - 10);
|
||||||
|
} else {
|
||||||
|
nib += (48 - 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
s[--len] = nib;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
8
text_editor/unparse.hpp
Normal file
8
text_editor/unparse.hpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int unparse_base10_unsigned(char * s, uint32_t n, int len, char fill);
|
||||||
|
int unparse_base10(char * s, int32_t n, int len, char fill);
|
||||||
|
int unparse_base10_64(char * s, int64_t n, int len, char fill);
|
||||||
|
int unparse_base16(char * s, uint32_t n, int len, char fill);
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "font/font.h"
|
||||||
|
|
||||||
struct viewport_window {
|
struct viewport_window {
|
||||||
int32_t first_line;
|
int32_t first_line;
|
||||||
struct {
|
struct {
|
||||||
@ -12,11 +14,11 @@ struct viewport_window {
|
|||||||
} box;
|
} box;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void viewport_init_fullscreen(viewport_window& window)
|
static inline void viewport_init_fullscreen(viewport_window& window, const font * font)
|
||||||
{
|
{
|
||||||
window.first_line = 0;
|
window.first_line = 0;
|
||||||
window.box.x0 = 10;
|
window.box.x0 = 10;
|
||||||
window.box.y0 = 20;
|
window.box.y0 = 20;
|
||||||
window.box.x1 = 640 - 10;
|
window.box.x1 = 640 - 10;
|
||||||
window.box.y1 = 480 - 20;
|
window.box.y1 = 480 - (font->face_metrics.height >> 6) * 2;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user