new rendering

master
Allen Webster 2015-10-22 21:42:50 -04:00
parent 96bb6ba19f
commit 083b4409c5
5 changed files with 352 additions and 94 deletions

View File

@ -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;
} }
} }

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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