[canvas] replace simple shape helpers with normal paths operations instead of having dedicated primitives for rounded rects/ellipses and so on
This commit is contained in:
		
							parent
							
								
									c6e89c1869
								
							
						
					
					
						commit
						03b5802529
					
				| 
						 | 
				
			
			@ -126,6 +126,7 @@ int main()
 | 
			
		|||
			mg_set_color_rgba(0, 0, 1, 1);
 | 
			
		||||
			mg_fill();
 | 
			
		||||
*/
 | 
			
		||||
/*
 | 
			
		||||
			mg_set_joint(MG_JOINT_NONE);
 | 
			
		||||
			mg_set_max_joint_excursion(20);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +151,9 @@ int main()
 | 
			
		|||
			mg_close_path();
 | 
			
		||||
			mg_set_color_rgba(0, 0, 1, 1);
 | 
			
		||||
			mg_stroke();
 | 
			
		||||
*/
 | 
			
		||||
			mg_set_color_rgba(1, 0, 0, 1);
 | 
			
		||||
			mg_rounded_rectangle_fill(100, 100, 200, 300, 20);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
			mg_move_to(x+8, y+8);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -598,6 +598,7 @@ int main()
 | 
			
		|||
		mem_arena_clear(mem_scratch());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mg_surface_destroy(surface);
 | 
			
		||||
	mp_terminate();
 | 
			
		||||
 | 
			
		||||
	return(0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										290
									
								
								src/graphics.c
								
								
								
								
							
							
						
						
									
										290
									
								
								src/graphics.c
								
								
								
								
							| 
						 | 
				
			
			@ -2136,195 +2136,6 @@ void mg_render_stroke(mg_canvas_data* canvas,
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------------------------------------
 | 
			
		||||
// Fast shapes primitives
 | 
			
		||||
//-----------------------------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
void mg_render_rectangle_fill(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
 | 
			
		||||
{
 | 
			
		||||
	u32 baseIndex = mg_vertices_base_index(canvas);
 | 
			
		||||
	i32* indices = mg_reserve_indices(canvas, 6);
 | 
			
		||||
 | 
			
		||||
	mg_next_shape(canvas, attributes);
 | 
			
		||||
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x, rect.y});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w, rect.y});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w, rect.y + rect.h});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x, rect.y + rect.h});
 | 
			
		||||
 | 
			
		||||
	indices[0] = baseIndex + 0;
 | 
			
		||||
	indices[1] = baseIndex + 1;
 | 
			
		||||
	indices[2] = baseIndex + 2;
 | 
			
		||||
	indices[3] = baseIndex + 0;
 | 
			
		||||
	indices[4] = baseIndex + 2;
 | 
			
		||||
	indices[5] = baseIndex + 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_rectangle_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
 | 
			
		||||
{
 | 
			
		||||
	//NOTE(martin): stroke a rectangle by fill two scaled rectangles with the same shapeIndex.
 | 
			
		||||
	u32 baseIndex = mg_vertices_base_index(canvas);
 | 
			
		||||
	i32* indices = mg_reserve_indices(canvas, 12);
 | 
			
		||||
 | 
			
		||||
	mg_next_shape(canvas, attributes);
 | 
			
		||||
 | 
			
		||||
	//NOTE(martin): limit stroke width to the minimum dimension of the rectangle
 | 
			
		||||
	f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
 | 
			
		||||
	f32 halfW = width/2;
 | 
			
		||||
 | 
			
		||||
	// outer points
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x - halfW, rect.y - halfW});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w + halfW, rect.y - halfW});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w + halfW, rect.y + rect.h + halfW});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x - halfW, rect.y + rect.h + halfW});
 | 
			
		||||
 | 
			
		||||
	// innter points
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + halfW, rect.y + halfW});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w - halfW, rect.y + halfW});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w - halfW, rect.y + rect.h - halfW});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + halfW, rect.y + rect.h - halfW});
 | 
			
		||||
 | 
			
		||||
	indices[0] = baseIndex + 0;
 | 
			
		||||
	indices[1] = baseIndex + 1;
 | 
			
		||||
	indices[2] = baseIndex + 2;
 | 
			
		||||
	indices[3] = baseIndex + 0;
 | 
			
		||||
	indices[4] = baseIndex + 2;
 | 
			
		||||
	indices[5] = baseIndex + 3;
 | 
			
		||||
	indices[6] = baseIndex + 4;
 | 
			
		||||
	indices[7] = baseIndex + 5;
 | 
			
		||||
	indices[8] = baseIndex + 6;
 | 
			
		||||
	indices[9] = baseIndex + 4;
 | 
			
		||||
	indices[10] = baseIndex + 6;
 | 
			
		||||
	indices[11] = baseIndex + 7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_fill_arc_corner(mg_canvas_data* canvas, f32 x, f32 y, f32 rx, f32 ry)
 | 
			
		||||
{
 | 
			
		||||
	//NOTE(martin): draw a precomputed arc corner, using a bezier approximation
 | 
			
		||||
	u32 baseIndex = mg_vertices_base_index(canvas);
 | 
			
		||||
	i32* indices = mg_reserve_indices(canvas, 6);
 | 
			
		||||
 | 
			
		||||
	f32 cx = rx*4*(sqrt(2)-1)/3;
 | 
			
		||||
	f32 cy = ry*4*(sqrt(2)-1)/3;
 | 
			
		||||
 | 
			
		||||
	mg_push_vertex_cubic(canvas, (vec2){x, y + ry}, (vec4){-3.76797, -9.76362, 5.47912, -1});
 | 
			
		||||
	mg_push_vertex_cubic(canvas, (vec2){x, y + ry - cy}, (vec4){-4.19896, -9.45223, 7.534, -1});
 | 
			
		||||
	mg_push_vertex_cubic(canvas, (vec2){x + rx - cx, y}, (vec4){-4.19896, -7.534, 9.45223, -1});
 | 
			
		||||
	mg_push_vertex_cubic(canvas, (vec2){x + rx, y}, (vec4){-3.76797, -5.47912, 9.76362, -1});
 | 
			
		||||
 | 
			
		||||
	indices[0] = baseIndex + 0;
 | 
			
		||||
	indices[1] = baseIndex + 1;
 | 
			
		||||
	indices[2] = baseIndex + 2;
 | 
			
		||||
	indices[3] = baseIndex + 0;
 | 
			
		||||
	indices[4] = baseIndex + 2;
 | 
			
		||||
	indices[5] = baseIndex + 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_rounded_rectangle_fill_path(mg_canvas_data* canvas,
 | 
			
		||||
							               mg_rounded_rect rect)
 | 
			
		||||
{
 | 
			
		||||
	//NOTE(martin): draw a rounded rectangle by drawing a normal rectangle and 4 corners,
 | 
			
		||||
	//              approximating an arc by a precomputed bezier curve
 | 
			
		||||
 | 
			
		||||
	u32 baseIndex = mg_vertices_base_index(canvas);
 | 
			
		||||
	i32* indices = mg_reserve_indices(canvas, 18);
 | 
			
		||||
 | 
			
		||||
	//NOTE(martin): inner cutted corner rectangle
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.r, rect.y});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w - rect.r, rect.y});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w, rect.y + rect.r});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w, rect.y + rect.h - rect.r});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w - rect.r, rect.y + rect.h});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.r, rect.y + rect.h});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x, rect.y + rect.h - rect.r});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x, rect.y + rect.r});
 | 
			
		||||
 | 
			
		||||
	static const i32 fanIndices[18] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 }; // inner fan
 | 
			
		||||
	for(int i=0; i<18; i++)
 | 
			
		||||
	{
 | 
			
		||||
		indices[i] = fanIndices[i] + baseIndex;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x, rect.y, rect.r, rect.r);
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y, -rect.r, rect.r);
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y + rect.h, -rect.r, -rect.r);
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x, rect.y + rect.h, rect.r, -rect.r);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void mg_render_rounded_rectangle_fill(mg_canvas_data* canvas,
 | 
			
		||||
                                      mg_rounded_rect rect,
 | 
			
		||||
					                  mg_attributes* attributes)
 | 
			
		||||
{
 | 
			
		||||
	mg_next_shape(canvas, attributes);
 | 
			
		||||
	mg_render_rounded_rectangle_fill_path(canvas, rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_rounded_rectangle_stroke(mg_canvas_data* canvas,
 | 
			
		||||
                                        mg_rounded_rect rect,
 | 
			
		||||
                                        mg_attributes* attributes)
 | 
			
		||||
{
 | 
			
		||||
	//NOTE(martin): stroke rounded rectangle by filling two scaled rounded rectangles with the same shapeIndex
 | 
			
		||||
	f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
 | 
			
		||||
	f32 halfW = width/2;
 | 
			
		||||
 | 
			
		||||
	mg_rounded_rect inner = {rect.x + halfW, rect.y + halfW, rect.w - width, rect.h - width, rect.r - halfW};
 | 
			
		||||
	mg_rounded_rect outer = {rect.x - halfW, rect.y - halfW, rect.w + width, rect.h + width, rect.r + halfW};
 | 
			
		||||
 | 
			
		||||
	mg_next_shape(canvas, attributes);
 | 
			
		||||
	mg_render_rounded_rectangle_fill_path(canvas, outer);
 | 
			
		||||
	mg_render_rounded_rectangle_fill_path(canvas, inner);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_ellipse_fill_path(mg_canvas_data* canvas, mp_rect rect)
 | 
			
		||||
{
 | 
			
		||||
	//NOTE(martin): draw a filled ellipse by drawing a diamond and 4 corners,
 | 
			
		||||
	//              approximating an arc by a precomputed bezier curve
 | 
			
		||||
	f32 rx = rect.w/2;
 | 
			
		||||
	f32 ry = rect.h/2;
 | 
			
		||||
 | 
			
		||||
	u32 baseIndex = mg_vertices_base_index(canvas);
 | 
			
		||||
	i32* indices = mg_reserve_indices(canvas, 6);
 | 
			
		||||
 | 
			
		||||
	//NOTE(martin): inner diamond
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x, rect.y + ry});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rx, rect.y});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rect.w, rect.y + ry});
 | 
			
		||||
	mg_push_vertex(canvas, (vec2){rect.x + rx, rect.y + rect.h});
 | 
			
		||||
 | 
			
		||||
	indices[0] = baseIndex + 0;
 | 
			
		||||
	indices[1] = baseIndex + 1;
 | 
			
		||||
	indices[2] = baseIndex + 2;
 | 
			
		||||
	indices[3] = baseIndex + 0;
 | 
			
		||||
	indices[4] = baseIndex + 2;
 | 
			
		||||
	indices[5] = baseIndex + 3;
 | 
			
		||||
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x, rect.y, rx, ry);
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y, -rx, ry);
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y + rect.h, -rx, -ry);
 | 
			
		||||
	mg_render_fill_arc_corner(canvas, rect.x, rect.y + rect.h, rx, -ry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_ellipse_fill(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
 | 
			
		||||
{
 | 
			
		||||
	mg_next_shape(canvas, attributes);
 | 
			
		||||
	mg_render_ellipse_fill_path(canvas, rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_render_ellipse_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
 | 
			
		||||
{
 | 
			
		||||
	//NOTE(martin): stroke by filling two scaled ellipsis with the same shapeIndex
 | 
			
		||||
	f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
 | 
			
		||||
	f32 halfW = width/2;
 | 
			
		||||
 | 
			
		||||
	mp_rect inner = {rect.x + halfW, rect.y + halfW, rect.w - width, rect.h - width};
 | 
			
		||||
	mp_rect outer = {rect.x - halfW, rect.y - halfW, rect.w + width, rect.h + width};
 | 
			
		||||
 | 
			
		||||
	mg_next_shape(canvas, attributes);
 | 
			
		||||
	mg_render_ellipse_fill_path(canvas, outer);
 | 
			
		||||
	mg_render_ellipse_fill_path(canvas, inner);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------------------
 | 
			
		||||
//NOTE(martin): fonts
 | 
			
		||||
//------------------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -3029,31 +2840,6 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
 | 
			
		|||
							 &primitive->attributes);
 | 
			
		||||
			} break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_RECT_FILL:
 | 
			
		||||
				mg_render_rectangle_fill(canvas, primitive->rect, &primitive->attributes);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_RECT_STROKE:
 | 
			
		||||
				mg_render_rectangle_stroke(canvas, primitive->rect, &primitive->attributes);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_ROUND_RECT_FILL:
 | 
			
		||||
				mg_render_rounded_rectangle_fill(canvas, primitive->roundedRect, &primitive->attributes);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_ROUND_RECT_STROKE:
 | 
			
		||||
				mg_render_rounded_rectangle_stroke(canvas, primitive->roundedRect, &primitive->attributes);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_ELLIPSE_FILL:
 | 
			
		||||
				mg_render_ellipse_fill(canvas, primitive->rect, &primitive->attributes);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_ELLIPSE_STROKE:
 | 
			
		||||
				mg_render_ellipse_stroke(canvas, primitive->rect, &primitive->attributes);
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case MG_CMD_JUMP:
 | 
			
		||||
			{
 | 
			
		||||
				if(primitive->jump == ~0)
 | 
			
		||||
| 
						 | 
				
			
			@ -3613,51 +3399,58 @@ void mg_stroke()
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------------------
 | 
			
		||||
//NOTE(martin): 'fast' shapes primitives
 | 
			
		||||
//NOTE(martin): simple shape helpers
 | 
			
		||||
//------------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
void mg_rectangle_path(f32 x, f32 y, f32 w, f32 h)
 | 
			
		||||
{
 | 
			
		||||
	mg_move_to(x, y);
 | 
			
		||||
	mg_line_to(x+w, y);
 | 
			
		||||
	mg_line_to(x+w, y+h);
 | 
			
		||||
	mg_line_to(x, y+h);
 | 
			
		||||
	mg_close_path();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_rectangle_fill(f32 x, f32 y, f32 w, f32 h)
 | 
			
		||||
{
 | 
			
		||||
	mg_canvas_data* canvas = __mgCurrentCanvas;
 | 
			
		||||
	if(canvas)
 | 
			
		||||
	{
 | 
			
		||||
		mg_primitive primitive = {.cmd = MG_CMD_RECT_FILL, .rect = (mp_rect){x, y, w, h}};
 | 
			
		||||
		mg_push_command(canvas, primitive);
 | 
			
		||||
	}
 | 
			
		||||
	mg_rectangle_path(x, y, w, h);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_rectangle_stroke(f32 x, f32 y, f32 w, f32 h)
 | 
			
		||||
{
 | 
			
		||||
	mg_canvas_data* canvas = __mgCurrentCanvas;
 | 
			
		||||
	if(canvas)
 | 
			
		||||
	{
 | 
			
		||||
		mg_primitive primitive = {.cmd = MG_CMD_RECT_STROKE, .rect = (mp_rect){x, y, w, h}};
 | 
			
		||||
		mg_push_command(canvas, primitive);
 | 
			
		||||
	}
 | 
			
		||||
	mg_rectangle_path(x, y, w, h);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_rounded_rectangle_path(f32 x, f32 y, f32 w, f32 h, f32 r)
 | 
			
		||||
{
 | 
			
		||||
	f32 c = r*4*(sqrt(2)-1)/3;
 | 
			
		||||
 | 
			
		||||
	mg_move_to(x+r, y);
 | 
			
		||||
	mg_line_to(x+w-r, y);
 | 
			
		||||
	mg_cubic_to(x+w-r+c, y, x+w, y+r-c, x+w, y+r);
 | 
			
		||||
	mg_line_to(x+w, y+h-r);
 | 
			
		||||
	mg_cubic_to(x+w, y+h-r+c, x+w-r+c, y+h, x+w-r, y+h);
 | 
			
		||||
	mg_line_to(x+r, y+h);
 | 
			
		||||
	mg_cubic_to(x+r-c, y+h, x, y+h-r+c, x, y+h-r);
 | 
			
		||||
	mg_line_to(x, y+r);
 | 
			
		||||
	mg_cubic_to(x, y+r-c, x+r-c, y, x+r, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r)
 | 
			
		||||
{
 | 
			
		||||
	mg_canvas_data* canvas = __mgCurrentCanvas;
 | 
			
		||||
	if(canvas)
 | 
			
		||||
	{
 | 
			
		||||
		mg_primitive primitive = {.cmd = MG_CMD_ROUND_RECT_FILL,
 | 
			
		||||
		                          .roundedRect = (mg_rounded_rect){x, y, w, h, r}};
 | 
			
		||||
		mg_push_command(canvas, primitive);
 | 
			
		||||
	}
 | 
			
		||||
	mg_rounded_rectangle_path(x, y, w, h, r);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r)
 | 
			
		||||
{
 | 
			
		||||
	mg_canvas_data* canvas = __mgCurrentCanvas;
 | 
			
		||||
	if(canvas)
 | 
			
		||||
	{
 | 
			
		||||
		mg_primitive primitive = {.cmd = MG_CMD_ROUND_RECT_STROKE,
 | 
			
		||||
		                          .roundedRect = (mg_rounded_rect){x, y, w, h, r}};
 | 
			
		||||
		mg_push_command(canvas, primitive);
 | 
			
		||||
	}
 | 
			
		||||
	mg_rounded_rectangle_path(x, y, w, h, r);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry)
 | 
			
		||||
void mg_ellipse_path(f32 x, f32 y, f32 rx, f32 ry)
 | 
			
		||||
{
 | 
			
		||||
	f32 cx = rx*4*(sqrt(2)-1)/3;
 | 
			
		||||
	f32 cy = ry*4*(sqrt(2)-1)/3;
 | 
			
		||||
| 
						 | 
				
			
			@ -3667,19 +3460,18 @@ void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry)
 | 
			
		|||
	mg_cubic_to(x+cx, y+ry, x+rx, y+cy, x+rx, y);
 | 
			
		||||
	mg_cubic_to(x+rx, y-cy, x+cx, y-ry, x, y-ry);
 | 
			
		||||
	mg_cubic_to(x-cx, y-ry, x-rx, y-cy, x-rx, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry)
 | 
			
		||||
{
 | 
			
		||||
	mg_ellipse_path(x, y, rx, ry);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry)
 | 
			
		||||
{
 | 
			
		||||
	mg_canvas_data* canvas = __mgCurrentCanvas;
 | 
			
		||||
	if(canvas)
 | 
			
		||||
	{
 | 
			
		||||
		mg_primitive primitive = {.cmd = MG_CMD_ELLIPSE_STROKE,
 | 
			
		||||
		                          .rect = (mp_rect){x-rx, y-ry, 2*rx, 2*ry}};
 | 
			
		||||
		mg_push_command(canvas, primitive);
 | 
			
		||||
	}
 | 
			
		||||
	mg_ellipse_path(x, y, rx, ry);
 | 
			
		||||
	mg_stroke();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mg_circle_fill(f32 x, f32 y, f32 r)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -178,12 +178,6 @@ typedef struct mg_rounded_rect
 | 
			
		|||
 | 
			
		||||
typedef enum { MG_CMD_FILL,
 | 
			
		||||
	           MG_CMD_STROKE,
 | 
			
		||||
	           MG_CMD_RECT_FILL,
 | 
			
		||||
	           MG_CMD_RECT_STROKE,
 | 
			
		||||
	           MG_CMD_ROUND_RECT_FILL,
 | 
			
		||||
	           MG_CMD_ROUND_RECT_STROKE,
 | 
			
		||||
	           MG_CMD_ELLIPSE_FILL,
 | 
			
		||||
	           MG_CMD_ELLIPSE_STROKE,
 | 
			
		||||
	           MG_CMD_JUMP,
 | 
			
		||||
	           MG_CMD_CLIP_PUSH,
 | 
			
		||||
	           MG_CMD_CLIP_POP,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								src/ui.c
								
								
								
								
							
							
						
						
									
										1
									
								
								src/ui.c
								
								
								
								
							| 
						 | 
				
			
			@ -2121,6 +2121,7 @@ void ui_select_popup_draw_arrow(ui_box* box, void* data)
 | 
			
		|||
	mg_move_to(box->rect.x + 0.25*box->rect.w, box->rect.y + 0.45*box->rect.h);
 | 
			
		||||
	mg_line_to(box->rect.x + 0.5*box->rect.w, box->rect.y + 0.75*box->rect.h);
 | 
			
		||||
	mg_line_to(box->rect.x + 0.75*box->rect.w, box->rect.y + 0.45*box->rect.h);
 | 
			
		||||
	mg_close_path();
 | 
			
		||||
 | 
			
		||||
	mg_set_color(box->style.color);
 | 
			
		||||
	mg_fill();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue