Browse Source

Started on clipping

master
Patrick Jakobsen 7 months ago
parent
commit
b2b8e68046
1 changed files with 129 additions and 12 deletions
  1. +129
    -12
      gui/gui.c

+ 129
- 12
gui/gui.c View File

@ -192,8 +192,7 @@ struct GUI_Subtree {
RDIC_Context rdic;
// TODO(Zelaven):
// GUI_Rectangle cliprect;
GUI_Node_Reference clipnode;
GUI_Node_Reference relative_to;
int flat_offset_x;
@ -691,6 +690,7 @@ GUI_Node_Reference gui_push_subtree(
//subtree->structural_parent = context->current_subtree;
//context->current_subtree = subtree;
subtree.node->relative_to = relative_to;
subtree.node->clipnode = relative_to;
GUI_Node_Reference new_root_reference = {
.rdic_ref = rdic_context_start_frame(
@ -1720,7 +1720,7 @@ void test_gui__subtree(
context, middle_subtree, middle_subtree_root,
GUI_LAYOUT_VERTICAL, &element_style, test_size, middle);
{
static GUI_Color test_image_pixels[10*10] = {
static GUI_Color test_image_pixels[10*12] = {
0, ~0, 0, ~0, 0, ~0, 0, ~0, 0, ~0,
~0, 0, ~0, 0, ~0, 0, ~0, 0, ~0, 0,
0, ~0, 0, ~0, 0, ~0, 0, ~0, 0, ~0,
@ -1731,11 +1731,13 @@ void test_gui__subtree(
~0, 0, ~0, 0, ~0, 0, ~0, 0, ~0, 0,
0, ~0, 0, ~0, 0, ~0, 0, ~0, 0, ~0,
~0, 0, ~0, 0, ~0, 0, ~0, 0, ~0, 0,
~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
};
static Pixel_Buffer test_image = {
.pixels = test_image_pixels,
.width = 10,
.height = 10,
.height = 12,
};
static GUI_Node_Reference inner_top = {0};
inner_top = gui_dumb_block(context, inner_top, &outer_style, element_size);
@ -2072,6 +2074,7 @@ void draw_rect3(
}
}
#define SET_PIXEL(pixel_buffer, x, y, color) (pixel_buffer)->pixels[(y)*(pixel_buffer)->width + (x)] = (color)
#define GET_PIXEL(pixel_buffer, x, y) (pixel_buffer)->pixels[(y)*(pixel_buffer)->width + (x)]
@ -3263,8 +3266,6 @@ void gui_draw_image(
return;
}
// TODO(Zelaven): Clipping.
int off_x = draw_command->rectangle.x0;
int off_y = draw_command->rectangle.y0;
Pixel_Buffer *image = draw_command->image;
@ -3284,7 +3285,109 @@ void gui_draw_image(
}
}
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
void gui_draw_image_clipped(
Pixel_Buffer *pixel_buffer,
GUI_Draw_Command *draw_command,
GUI_Rectangle *cliprect)
{
if(draw_command->image == NULL) {
return;
}
//int off_x = cliprect->x0;
//int off_y = cliprect->y0;
Pixel_Buffer *image = draw_command->image;
int w = image->width;
int clipwidth = cliprect->x1 - cliprect->x0;
w = MIN(w, clipwidth);
int h = image->height;
int clipheight = cliprect->y1 - cliprect->y0;
h = MIN(h, clipheight);
int startx = cliprect->x0 - draw_command->rectangle.x0;
startx = MAX(startx, 0);
int starty = cliprect->y0 - draw_command->rectangle.y0;
starty = MAX(starty, 0);
int off_x = cliprect->x0 - startx;
int off_y = cliprect->y0 - starty;
for(int j=starty; j < h; ++j)
{
for(int i=startx; i < w; ++i)
{
int image_x = i;
int image_y = j;
int image_index = image_y * w + image_x;
GUI_Color pixel = image->pixels[image_index];
SET_PIXEL(pixel_buffer, off_x+i, off_y+j, pixel);
}
}
}
GUI_Rectangle gui_intersect_rectangles(
GUI_Rectangle *r1,
GUI_Rectangle *r2)
{
GUI_Rectangle r = {
.x0 = MAX(r1->x0, r2->x0),
.x1 = MIN(r1->x1, r2->x1),
.y0 = MAX(r1->y0, r2->y0),
.y1 = MIN(r1->y1, r2->y1),
};
return r;
}
void gui_draw_rect_clipped(
Pixel_Buffer *pixel_buffer,
GUI_Draw_Command *draw_command,
GUI_Rectangle *clip)
{
if(clip->x0 <= draw_command->rectangle.x0
&& clip->y0 <= draw_command->rectangle.y0
&& clip->x1 <= draw_command->rectangle.x1
&& clip->y1 <= draw_command->rectangle.y1)
{
gui_draw_rect(pixel_buffer, draw_command);
}
else
{
if(draw_command->roundedness == 0)
{
GUI_Rectangle clipped_rect = gui_intersect_rectangles(
clip,
&draw_command->rectangle);
// TODO(Zelaven) Don't double-draw on the space covered by the inner
// rectangle.
draw_rect3(
pixel_buffer, clipped_rect, draw_command->border_color);
GUI_Rectangle inner = clipped_rect;
inner.x0 += draw_command->border_thickness;
inner.y0 += draw_command->border_thickness;
inner.x1 -= draw_command->border_thickness;
inner.y1 -= draw_command->border_thickness;
if(inner.x0 < inner.x1 && inner.y0 < inner.y1)
{
draw_rect3(pixel_buffer, inner, draw_command->color);
}
}
else
{
assert(!"TODO");
if(draw_command->border_thickness == 0)
{
gui_draw_rounded_rect(pixel_buffer, draw_command);
}
else
{
gui_draw_rounded_rect_with_border(pixel_buffer, draw_command);
}
}
}
}
//CURSOR
void gui_layout_and_draw_subtree(
GUI_Context *context,
@ -3299,12 +3402,26 @@ void gui_layout_and_draw_subtree(
GUI_Draw_Command *draw_commands =
(GUI_Draw_Command*)(context->draw_command_arena->memory);
for(int i = 0; i < context->num_draw_commands; i++)
{
GUI_Draw_Command *draw_command = draw_commands+i;
gui_draw_rect (pixel_buffer, draw_command);
gui_draw_image(pixel_buffer, draw_command);
gui_draw_text (pixel_buffer, draw_command);
GUI_Node_Reference clipnode = subtree->clipnode;
if(rdic_node_reference_valid(clipnode.rdic_ref)) {
GUI_Rectangle *cliprect = &clipnode.node->rect;
for(int i = 0; i < context->num_draw_commands; i++)
{
GUI_Draw_Command *draw_command = draw_commands+i;
gui_draw_rect_clipped(pixel_buffer, draw_command, cliprect);
//gui_draw_image(pixel_buffer, draw_command);//, cliprect);
gui_draw_image_clipped(pixel_buffer, draw_command, cliprect);
gui_draw_text (pixel_buffer, draw_command);//, cliprect);
}
}
else {
for(int i = 0; i < context->num_draw_commands; i++)
{
GUI_Draw_Command *draw_command = draw_commands+i;
gui_draw_rect (pixel_buffer, draw_command);
gui_draw_image(pixel_buffer, draw_command);
gui_draw_text (pixel_buffer, draw_command);
}
}
// TODO NOTE(Zelaven): There may arise an issue where the subtrees won't

Loading…
Cancel
Save