new rendering
parent
96bb6ba19f
commit
083b4409c5
|
@ -338,10 +338,10 @@ do_single_slider(i32 sub_id, Color_UI *ui, i32 channel, bool32 is_rgba,
|
||||||
|
|
||||||
x = lerp(slider.x0, color.v[channel], slider.x1);
|
x = lerp(slider.x0, color.v[channel], slider.x1);
|
||||||
draw_rectangle(
|
draw_rectangle(
|
||||||
target, real32R(x, slider.y0, x + 1, slider.y1), 0xff000000);
|
target, f32R(x, slider.y0, x + 1, slider.y1), 0xff000000);
|
||||||
|
|
||||||
draw_rectangle(
|
draw_rectangle(
|
||||||
target, real32R(x-2, click_box.y0, x+3, slider.y0-4), 0xff777777);
|
target, f32R(x-2, click_box.y0, x+3, slider.y0-4), 0xff777777);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
real32_Rect r = real32R(hit_region);
|
real32_Rect r = f32R(hit_region);
|
||||||
r.x0 += indx*ui->hex_advance+1;
|
r.x0 += indx*ui->hex_advance+1;
|
||||||
r.x1 = r.x0+ui->hex_advance+1;
|
r.x1 = r.x0+ui->hex_advance+1;
|
||||||
draw_rectangle(target, r, back);
|
draw_rectangle(target, r, back);
|
||||||
|
@ -789,7 +789,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
|
||||||
|
|
||||||
for (i32 i = 0; i < ArrayCount(ui->highlight.ids); ++i){
|
for (i32 i = 0; i < ArrayCount(ui->highlight.ids); ++i){
|
||||||
if (ui->highlight.ids[i] == id){
|
if (ui->highlight.ids[i] == id){
|
||||||
draw_rectangle_outline(target, real32R(bar), text_color);
|
draw_rectangle_outline(target, f32R(bar), text_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1959,106 +1959,44 @@ file_post_history(General_Memory *general, Editing_File *file,
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Full_Cursor
|
inline Full_Cursor
|
||||||
make_hint(i32 line_index, i32 *starts, i32 font_height, f32 *wrap_ys){
|
|
||||||
Full_Cursor hint;
|
|
||||||
hint.pos = starts[line_index];
|
|
||||||
hint.line = line_index + 1;
|
|
||||||
hint.character = 1;
|
|
||||||
hint.unwrapped_y = (f32)(line_index * font_height);
|
|
||||||
hint.unwrapped_x = 0;
|
|
||||||
hint.wrapped_y = wrap_ys[line_index];
|
|
||||||
hint.wrapped_x = 0;
|
|
||||||
return hint;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Full_Cursor
|
|
||||||
view_compute_cursor_from_pos(File_View *view, i32 pos){
|
view_compute_cursor_from_pos(File_View *view, i32 pos){
|
||||||
Editing_File *file = view->file;
|
Editing_File *file = view->file;
|
||||||
Style *style = view->style;
|
Style *style = view->style;
|
||||||
Font *font = style->font;
|
Font *font = style->font;
|
||||||
|
|
||||||
i32 *lines = file->buffer.line_starts;
|
|
||||||
|
|
||||||
i32 line_index = buffer_get_line_index(&file->buffer, pos, 0, file->buffer.line_count);
|
|
||||||
|
|
||||||
Full_Cursor result = make_hint(line_index, lines, font->height, view->line_wrap_y);
|
|
||||||
|
|
||||||
real32 max_width = view_compute_width(view);
|
real32 max_width = view_compute_width(view);
|
||||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||||
|
|
||||||
result = buffer_cursor_seek(&file->buffer, seek_pos(pos),
|
return buffer_cursor_from_pos(&file->buffer, pos, view->line_wrap_y,
|
||||||
max_width, (float)font->height,
|
max_width, (real32)font->height, opad.data, opad.stride);
|
||||||
opad.data, opad.stride, result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Full_Cursor
|
inline Full_Cursor
|
||||||
view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
||||||
bool32 round_down = 0){
|
bool32 round_down = 0){
|
||||||
Editing_File *file = view->file;
|
Editing_File *file = view->file;
|
||||||
Style *style = view->style;
|
Style *style = view->style;
|
||||||
Font *font = style->font;
|
Font *font = style->font;
|
||||||
|
|
||||||
i32 line_index = FLOOR32(seek_y / font->height);
|
|
||||||
if (line_index >= file->buffer.line_count) line_index = file->buffer.line_count - 1;
|
|
||||||
if (line_index < 0) line_index = 0;
|
|
||||||
|
|
||||||
Full_Cursor result = make_hint(line_index, file->buffer.line_starts, font->height, view->line_wrap_y);
|
|
||||||
|
|
||||||
real32 max_width = view_compute_width(view);
|
real32 max_width = view_compute_width(view);
|
||||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||||
|
|
||||||
result = buffer_cursor_seek(&file->buffer, seek_unwrapped_xy(seek_x, seek_y, round_down),
|
return buffer_cursor_from_unwrapped_xy(&file->buffer, seek_x, seek_y, round_down, view->line_wrap_y,
|
||||||
max_width, (float)font->height,
|
max_width, (real32)font->height, opad.data, opad.stride);
|
||||||
opad.data, opad.stride, result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Full_Cursor
|
inline Full_Cursor
|
||||||
view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_y,
|
||||||
bool32 round_down = 0){
|
bool32 round_down = 0){
|
||||||
Editing_File *file = view->file;
|
Editing_File *file = view->file;
|
||||||
Style *style = view->style;
|
Style *style = view->style;
|
||||||
Font *font = style->font;
|
Font *font = style->font;
|
||||||
real32 line_height = (real32)font->height;
|
|
||||||
|
|
||||||
real32 *line_wrap = view->line_wrap_y;
|
|
||||||
i32 line_index;
|
|
||||||
// NOTE(allen): binary search lines on wrapped y position
|
|
||||||
{
|
|
||||||
i32 start = 0;
|
|
||||||
i32 end = view->line_count;
|
|
||||||
while (1){
|
|
||||||
i32 i = (start + end) / 2;
|
|
||||||
if (line_wrap[i]+line_height <= seek_y){
|
|
||||||
start = i;
|
|
||||||
}
|
|
||||||
else if (line_wrap[i] > seek_y){
|
|
||||||
end = i;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
line_index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (start >= end - 1){
|
|
||||||
line_index = start;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Full_Cursor result = make_hint(line_index, file->buffer.line_starts, font->height, line_wrap);
|
|
||||||
|
|
||||||
real32 max_width = view_compute_width(view);
|
real32 max_width = view_compute_width(view);
|
||||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||||
|
|
||||||
result = buffer_cursor_seek(&file->buffer, seek_wrapped_xy(seek_x, seek_y, round_down),
|
return buffer_cursor_from_wrapped_xy(&file->buffer, seek_x, seek_y, round_down, view->line_wrap_y,
|
||||||
max_width, (real32)font->height,
|
max_width, (real32)font->height, opad.data, opad.stride);
|
||||||
opad.data, opad.stride, result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Full_Cursor
|
inline Full_Cursor
|
||||||
|
@ -3524,6 +3462,93 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
||||||
|
|
||||||
Assert(file && file->buffer.data && !file->is_dummy);
|
Assert(file && file->buffer.data && !file->is_dummy);
|
||||||
|
|
||||||
|
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
||||||
|
b32 tokens_use = file->tokens_complete && (file->token_stack.count > 0);
|
||||||
|
Cpp_Token_Stack token_stack = file->token_stack;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
Partition *part = &view_->mem->part;
|
||||||
|
Temp_Memory temp = begin_temp_memory(part);
|
||||||
|
|
||||||
|
partition_align(part, 4);
|
||||||
|
i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item);
|
||||||
|
Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max);
|
||||||
|
|
||||||
|
i32 count;
|
||||||
|
buffer_get_render_data(&file->buffer, view->line_wrap_y, items, max, &count,
|
||||||
|
(real32)rect.x0, (real32)rect.y0, view->scroll_x, view->scroll_y, view->unwrapped_lines,
|
||||||
|
(real32)max_x, (real32)max_y, opad.data, opad.stride, (real32)font->height);
|
||||||
|
Assert(count > 0);
|
||||||
|
|
||||||
|
i32 cursor_begin, cursor_end;
|
||||||
|
u32 cursor_color, at_cursor_color;
|
||||||
|
if (view->show_temp_highlight){
|
||||||
|
cursor_begin = view->temp_highlight.pos;
|
||||||
|
cursor_end = view->temp_highlight_end_pos;
|
||||||
|
cursor_color = style->main.highlight_color;
|
||||||
|
at_cursor_color = style->main.at_highlight_color;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
cursor_begin = view->cursor.pos;
|
||||||
|
cursor_end = cursor_begin + 1;
|
||||||
|
cursor_color = style->main.cursor_color;
|
||||||
|
at_cursor_color = style->main.at_cursor_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 token_i = 0;
|
||||||
|
u32 main_color = style->main.default_color;
|
||||||
|
if (tokens_use){
|
||||||
|
Cpp_Get_Token_Result result = cpp_get_token(&token_stack, items->index);
|
||||||
|
main_color = *style_get_color(style, token_stack.tokens[result.token_index]);
|
||||||
|
token_i = result.token_index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 mark_color = style->main.mark_color;
|
||||||
|
Buffer_Render_Item *item = items;
|
||||||
|
i32 prev_ind = -1;
|
||||||
|
for (i32 i = 0; i < count; ++i, ++item){
|
||||||
|
i32 ind = item->index;
|
||||||
|
if (tokens_use && ind != prev_ind){
|
||||||
|
Cpp_Token current_token = token_stack.tokens[token_i-1];
|
||||||
|
|
||||||
|
if (token_i < token_stack.count){
|
||||||
|
if (ind >= token_stack.tokens[token_i].start){
|
||||||
|
main_color =
|
||||||
|
*style_get_color(style, token_stack.tokens[token_i]);
|
||||||
|
current_token = token_stack.tokens[token_i];
|
||||||
|
++token_i;
|
||||||
|
}
|
||||||
|
else if (ind >= current_token.start + current_token.size){
|
||||||
|
main_color = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (current_token.type == CPP_TOKEN_JUNK &&
|
||||||
|
i >= current_token.start && i <= current_token.start + current_token.size){
|
||||||
|
highlight_color = style->main.highlight_junk_color;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
u32 char_color = main_color;
|
||||||
|
|
||||||
|
if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
|
||||||
|
if (is_active) draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
|
||||||
|
else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
|
||||||
|
char_color = at_cursor_color;
|
||||||
|
}
|
||||||
|
if (ind == view->mark && prev_ind != ind){
|
||||||
|
draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), mark_color);
|
||||||
|
}
|
||||||
|
font_draw_glyph(target, font, (u16)item->glyphid,
|
||||||
|
item->x0, item->y0, char_color);
|
||||||
|
prev_ind = ind;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_temp_memory(temp);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
i32 size = (i32)file->buffer.size;
|
i32 size = (i32)file->buffer.size;
|
||||||
u8 *data = (u8*)file->buffer.data;
|
u8 *data = (u8*)file->buffer.data;
|
||||||
|
|
||||||
|
@ -3541,11 +3566,9 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
||||||
real32 pos_x = 0;
|
real32 pos_x = 0;
|
||||||
real32 pos_y = 0;
|
real32 pos_y = 0;
|
||||||
|
|
||||||
Cpp_Token_Stack token_stack = file->token_stack;
|
|
||||||
u32 highlight_color = 0;
|
u32 highlight_color = 0;
|
||||||
u32 main_color = style->main.default_color;
|
u32 main_color = style->main.default_color;
|
||||||
i32 token_i = 0;
|
i32 token_i = 0;
|
||||||
bool32 tokens_use = file->tokens_complete && (file->token_stack.count > 0);
|
|
||||||
|
|
||||||
if (tokens_use){
|
if (tokens_use){
|
||||||
Cpp_Get_Token_Result result = cpp_get_token(&token_stack, start_character);
|
Cpp_Get_Token_Result result = cpp_get_token(&token_stack, start_character);
|
||||||
|
@ -3555,8 +3578,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
||||||
++token_i;
|
++token_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
Opaque_Font_Advance opad = get_opaque_font_advance(font);
|
|
||||||
|
|
||||||
data[size] = 0;
|
data[size] = 0;
|
||||||
for (i32 i = start_character; i <= size; ++i){
|
for (i32 i = start_character; i <= size; ++i){
|
||||||
u8 to_render;
|
u8 to_render;
|
||||||
|
@ -3605,15 +3626,13 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
||||||
|
|
||||||
i32 cursor_mode = 0;
|
i32 cursor_mode = 0;
|
||||||
if (view->show_temp_highlight){
|
if (view->show_temp_highlight){
|
||||||
if (view->temp_highlight.pos <= i && i < view->temp_highlight_end_pos){
|
if (view->temp_highlight.pos <= i && i < view->temp_highlight_end_pos)
|
||||||
cursor_mode = 2;
|
cursor_mode = 2;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else{
|
else{
|
||||||
if (view->cursor.pos == i){
|
if (view->cursor.pos == i)
|
||||||
cursor_mode = 1;
|
cursor_mode = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
real32_Rect cursor_rect =
|
real32_Rect cursor_rect =
|
||||||
real32XYWH(shift_x + pos_x, shift_y + pos_y,
|
real32XYWH(shift_x + pos_x, shift_y + pos_y,
|
||||||
|
@ -3705,6 +3724,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (view->widget.type != FWIDG_NONE){
|
if (view->widget.type != FWIDG_NONE){
|
||||||
UI_Style ui_style = get_ui_style_upper(style);
|
UI_Style ui_style = get_ui_style_upper(style);
|
||||||
|
|
10
4ed_math.cpp
10
4ed_math.cpp
|
@ -93,8 +93,8 @@ struct i32_Rect{
|
||||||
};
|
};
|
||||||
|
|
||||||
struct real32_Rect{
|
struct real32_Rect{
|
||||||
real32 x0, y0;
|
f32 x0, y0;
|
||||||
real32 x1, y1;
|
f32 x1, y1;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline i32_Rect
|
inline i32_Rect
|
||||||
|
@ -124,7 +124,7 @@ i32XYWH(i32 x, i32 y, i32 w, i32 h){
|
||||||
}
|
}
|
||||||
|
|
||||||
inline real32_Rect
|
inline real32_Rect
|
||||||
real32R(real32 l, real32 t, real32 r, real32 b){
|
f32R(real32 l, real32 t, real32 r, real32 b){
|
||||||
real32_Rect rect;
|
real32_Rect rect;
|
||||||
rect.x0 = l; rect.y0 = t;
|
rect.x0 = l; rect.y0 = t;
|
||||||
rect.x1 = r; rect.y1 = b;
|
rect.x1 = r; rect.y1 = b;
|
||||||
|
@ -132,7 +132,7 @@ real32R(real32 l, real32 t, real32 r, real32 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
inline real32_Rect
|
inline real32_Rect
|
||||||
real32R(i32_Rect r){
|
f32R(i32_Rect r){
|
||||||
real32_Rect rect;
|
real32_Rect rect;
|
||||||
rect.x0 = (real32)r.x0;
|
rect.x0 = (real32)r.x0;
|
||||||
rect.y0 = (real32)r.y0;
|
rect.y0 = (real32)r.y0;
|
||||||
|
@ -142,7 +142,7 @@ real32R(i32_Rect r){
|
||||||
}
|
}
|
||||||
|
|
||||||
inline real32_Rect
|
inline real32_Rect
|
||||||
real32XYWH(real32 x, real32 y, real32 w, real32 h){
|
f32XYWH(f32 x, f32 y, f32 w, f32 h){
|
||||||
real32_Rect rect;
|
real32_Rect rect;
|
||||||
rect.x0 = x; rect.y0 = y;
|
rect.x0 = x; rect.y0 = y;
|
||||||
rect.x1 = x+w; rect.y1 = y+h;
|
rect.x1 = x+w; rect.y1 = y+h;
|
||||||
|
|
|
@ -620,7 +620,7 @@ draw_gradient_2corner_clipped(Render_Target *target, real32_Rect rect,
|
||||||
inline void
|
inline void
|
||||||
draw_gradient_2corner_clipped(Render_Target *target, real32 l, real32 t, real32 r, real32 b,
|
draw_gradient_2corner_clipped(Render_Target *target, real32 l, real32 t, real32 r, real32 b,
|
||||||
Vec4 color_left, Vec4 color_right){
|
Vec4 color_left, Vec4 color_right){
|
||||||
draw_gradient_2corner_clipped(target, real32R(l,t,r,b), color_left, color_right);
|
draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -646,7 +646,7 @@ draw_rectangle_outline(Render_Target *target, real32_Rect rect, u32 color){
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
|
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
|
||||||
draw_rectangle_outline(target, real32R(rect), color);
|
draw_rectangle_outline(target, f32R(rect), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
|
@ -214,6 +214,7 @@ measure_character(void *advance_data, int stride, char character){
|
||||||
|
|
||||||
advances = (char*)advance_data;
|
advances = (char*)advance_data;
|
||||||
switch (character){
|
switch (character){
|
||||||
|
case 0: width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '0'); break;
|
||||||
case '\n': width = 0; break;
|
case '\n': width = 0; break;
|
||||||
case '\r': width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '\r'); break;
|
case '\r': width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * '\r'); break;
|
||||||
default: width = *(float*)(advances + stride * character);
|
default: width = *(float*)(advances + stride * character);
|
||||||
|
@ -465,8 +466,8 @@ typedef struct{
|
||||||
} Full_Cursor;
|
} Full_Cursor;
|
||||||
|
|
||||||
internal_4tech Full_Cursor
|
internal_4tech Full_Cursor
|
||||||
buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
|
buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek, float max_width, float font_height,
|
||||||
float max_width, float font_height, void *advance_data, int stride, Full_Cursor cursor){
|
void *advance_data, int stride, Full_Cursor cursor){
|
||||||
Full_Cursor prev_cursor;
|
Full_Cursor prev_cursor;
|
||||||
char *data, *advances;
|
char *data, *advances;
|
||||||
int size;
|
int size;
|
||||||
|
@ -578,6 +579,82 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
|
||||||
return(cursor);
|
return(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline_4tech Full_Cursor
|
||||||
|
make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height){
|
||||||
|
Full_Cursor hint;
|
||||||
|
hint.pos = starts[line_index];
|
||||||
|
hint.line = line_index + 1;
|
||||||
|
hint.character = 1;
|
||||||
|
hint.unwrapped_y = (f32)(line_index * font_height);
|
||||||
|
hint.unwrapped_x = 0;
|
||||||
|
hint.wrapped_y = wrap_ys[line_index];
|
||||||
|
hint.wrapped_x = 0;
|
||||||
|
return(hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_4tech Full_Cursor
|
||||||
|
buffer_cursor_from_pos(Buffer *buffer, int pos, float *wraps,
|
||||||
|
float max_width, float font_height, void *advance_data, int stride){
|
||||||
|
Full_Cursor result;
|
||||||
|
int line_index;
|
||||||
|
|
||||||
|
line_index = buffer_get_line_index(buffer, pos, 0, buffer->line_count);
|
||||||
|
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
|
||||||
|
result = buffer_cursor_seek(buffer, seek_pos(pos), max_width, font_height,
|
||||||
|
advance_data, stride, result);
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_4tech Full_Cursor
|
||||||
|
buffer_cursor_from_unwrapped_xy(Buffer *buffer, float x, float y, int round_down, float *wraps,
|
||||||
|
float max_width, float font_height, void *advance_data, int stride){
|
||||||
|
Full_Cursor result;
|
||||||
|
int line_index;
|
||||||
|
|
||||||
|
line_index = (int)(y / font_height);
|
||||||
|
if (line_index >= buffer->line_count) line_index = buffer->line_count - 1;
|
||||||
|
if (line_index < 0) line_index = 0;
|
||||||
|
|
||||||
|
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
|
||||||
|
result = buffer_cursor_seek(buffer, seek_unwrapped_xy(x, y, round_down), max_width, font_height,
|
||||||
|
advance_data, stride, result);
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_4tech Full_Cursor
|
||||||
|
buffer_cursor_from_wrapped_xy(Buffer *buffer, float x, float y, int round_down, float *wraps,
|
||||||
|
float max_width, float font_height, void *advance_data, int stride){
|
||||||
|
Full_Cursor result;
|
||||||
|
int line_index;
|
||||||
|
int start, end, i;
|
||||||
|
|
||||||
|
// NOTE(allen): binary search lines on wrapped y position
|
||||||
|
// TODO(allen): pull this out once other wrap handling code is ready
|
||||||
|
start = 0;
|
||||||
|
end = buffer->line_count;
|
||||||
|
for (;;){
|
||||||
|
i = (start + end) / 2;
|
||||||
|
if (wraps[i]+font_height <= y) start = i;
|
||||||
|
else if (wraps[i] > y) end = i;
|
||||||
|
else{
|
||||||
|
line_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (start >= end - 1){
|
||||||
|
line_index = start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = make_cursor_hint(line_index, buffer->line_starts, wraps, font_height);
|
||||||
|
result = buffer_cursor_seek(buffer, seek_wrapped_xy(x, y, round_down), max_width, font_height,
|
||||||
|
advance_data, stride, result);
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
int str_start, len;
|
int str_start, len;
|
||||||
int start, end;
|
int start, end;
|
||||||
|
@ -839,5 +916,166 @@ buffer_eol_convert_out(Buffer *buffer){
|
||||||
buffer->size = size;
|
buffer->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
int index;
|
||||||
|
int glyphid;
|
||||||
|
float x0, y0;
|
||||||
|
float x1, y1;
|
||||||
|
} Buffer_Render_Item;
|
||||||
|
|
||||||
|
internal_4tech void
|
||||||
|
buffer_get_render_data(Buffer *buffer, float *wraps, Buffer_Render_Item *items, int max, int *count,
|
||||||
|
float port_x, float port_y, float scroll_x, float scroll_y, int wrapped,
|
||||||
|
float width, float height, void *advance_data, int stride, float font_height){
|
||||||
|
Full_Cursor start_cursor;
|
||||||
|
Buffer_Render_Item *item;
|
||||||
|
char *data;
|
||||||
|
int size;
|
||||||
|
float shift_x, shift_y;
|
||||||
|
float x, y;
|
||||||
|
int i, item_i;
|
||||||
|
float ch_width;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
data = buffer->data;
|
||||||
|
size = buffer->size;
|
||||||
|
assert_4tech(size < buffer->max);
|
||||||
|
data[size] = 0;
|
||||||
|
|
||||||
|
shift_x = port_x - scroll_x;
|
||||||
|
shift_y = port_y - scroll_y;
|
||||||
|
if (wrapped){
|
||||||
|
start_cursor = buffer_cursor_from_wrapped_xy(buffer, 0, scroll_y, 0, wraps,
|
||||||
|
width, font_height, advance_data, stride);
|
||||||
|
shift_y += start_cursor.wrapped_y;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
start_cursor = buffer_cursor_from_unwrapped_xy(buffer, 0, scroll_y, 0, wraps,
|
||||||
|
width, font_height, advance_data, stride);
|
||||||
|
shift_y += start_cursor.unwrapped_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = start_cursor.pos;
|
||||||
|
|
||||||
|
x = shift_x;
|
||||||
|
y = shift_y;
|
||||||
|
item_i = 0;
|
||||||
|
item = items + item_i;
|
||||||
|
|
||||||
|
for (; i <= size; ++i){
|
||||||
|
ch = data[i];
|
||||||
|
ch_width = measure_character(advance_data, stride, ch);
|
||||||
|
|
||||||
|
if (ch_width + x > width + shift_x && wrapped){
|
||||||
|
x = shift_x;
|
||||||
|
y += font_height;
|
||||||
|
}
|
||||||
|
if (y > height + shift_y) break;
|
||||||
|
|
||||||
|
switch (ch){
|
||||||
|
case '\n':
|
||||||
|
ch_width = measure_character(advance_data, stride, ' ');
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = ' ';
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + ch_width;
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
|
||||||
|
x = shift_x;
|
||||||
|
y += font_height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
ch_width = measure_character(advance_data, stride, '\\');
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = '\\';
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + ch_width;
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
x += ch_width;
|
||||||
|
|
||||||
|
ch_width = measure_character(advance_data, stride, '0');
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = '0';
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + ch_width;
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
x += ch_width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\r':
|
||||||
|
ch_width = measure_character(advance_data, stride, '\\');
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = '\\';
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + ch_width;
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
x += ch_width;
|
||||||
|
|
||||||
|
ch_width = measure_character(advance_data, stride, 'r');
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = 'r';
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + ch_width;
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
x += ch_width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\t':
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = '\\';
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + measure_character(advance_data, stride, '\\');
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = 't';
|
||||||
|
item->x0 = (item-1)->x1;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = item->x0 + measure_character(advance_data, stride, 't');
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
x += ch_width;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
item->index = i;
|
||||||
|
item->glyphid = ch;
|
||||||
|
item->x0 = x;
|
||||||
|
item->y0 = y;
|
||||||
|
item->x1 = x + ch_width;
|
||||||
|
item->y1 = y + font_height;
|
||||||
|
++item_i;
|
||||||
|
++item;
|
||||||
|
x += ch_width;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (y > height + shift_y) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(allen): handle this with a control state
|
||||||
|
assert_4tech(item_i <= max);
|
||||||
|
*count = item_i;
|
||||||
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue