diff --git a/docs/reference/gsk/gsk4.toml.in b/docs/reference/gsk/gsk4.toml.in index 0f684aaaa0..dd595cd092 100644 --- a/docs/reference/gsk/gsk4.toml.in +++ b/docs/reference/gsk/gsk4.toml.in @@ -37,6 +37,8 @@ content_files = [ ] content_images = [ "gtk-logo.svg", + "images/arc-dark.png", + "images/arc-light.png", "images/caps-dark.png", "images/caps-light.png", "images/conic-light.png", diff --git a/docs/reference/gsk/images/arc-dark.png b/docs/reference/gsk/images/arc-dark.png new file mode 100644 index 0000000000..8e728d664b Binary files /dev/null and b/docs/reference/gsk/images/arc-dark.png differ diff --git a/docs/reference/gsk/images/arc-light.png b/docs/reference/gsk/images/arc-light.png new file mode 100644 index 0000000000..1f0d5d2cb1 Binary files /dev/null and b/docs/reference/gsk/images/arc-light.png differ diff --git a/docs/reference/gsk/images/arc.svg b/docs/reference/gsk/images/arc.svg new file mode 100644 index 0000000000..9488b7036f --- /dev/null +++ b/docs/reference/gsk/images/arc.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + diff --git a/gsk/gskpathbuilder.c b/gsk/gskpathbuilder.c index e48a933a75..86973ce87f 100644 --- a/gsk/gskpathbuilder.c +++ b/gsk/gskpathbuilder.c @@ -487,7 +487,6 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self, const GskRoundedRect *rect) { graphene_point_t current; - const float weight = M_SQRT1_2; g_return_if_fail (self != NULL); g_return_if_fail (rect != NULL); @@ -502,45 +501,41 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self, rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_TOP_RIGHT].width, rect->bounds.origin.y); /* topright corner */ - gsk_path_builder_conic_to (self, - rect->bounds.origin.x + rect->bounds.size.width, - rect->bounds.origin.y, - rect->bounds.origin.x + rect->bounds.size.width, - rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_RIGHT].height, - weight); + gsk_path_builder_arc_to (self, + rect->bounds.origin.x + rect->bounds.size.width, + rect->bounds.origin.y, + rect->bounds.origin.x + rect->bounds.size.width, + rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_RIGHT].height); /* right */ gsk_path_builder_line_to (self, rect->bounds.origin.x + rect->bounds.size.width, rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_RIGHT].height); /* bottomright corner */ - gsk_path_builder_conic_to (self, - rect->bounds.origin.x + rect->bounds.size.width, - rect->bounds.origin.y + rect->bounds.size.height, - rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_BOTTOM_RIGHT].width, - rect->bounds.origin.y + rect->bounds.size.height, - weight); + gsk_path_builder_arc_to (self, + rect->bounds.origin.x + rect->bounds.size.width, + rect->bounds.origin.y + rect->bounds.size.height, + rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_BOTTOM_RIGHT].width, + rect->bounds.origin.y + rect->bounds.size.height); /* bottom */ gsk_path_builder_line_to (self, rect->bounds.origin.x + rect->corner[GSK_CORNER_BOTTOM_LEFT].width, rect->bounds.origin.y + rect->bounds.size.height); /* bottomleft corner */ - gsk_path_builder_conic_to (self, - rect->bounds.origin.x, - rect->bounds.origin.y + rect->bounds.size.height, - rect->bounds.origin.x, - rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_LEFT].height, - weight); + gsk_path_builder_arc_to (self, + rect->bounds.origin.x, + rect->bounds.origin.y + rect->bounds.size.height, + rect->bounds.origin.x, + rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_LEFT].height); /* left */ gsk_path_builder_line_to (self, rect->bounds.origin.x, rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_LEFT].height); /* topleft corner */ - gsk_path_builder_conic_to (self, - rect->bounds.origin.x, - rect->bounds.origin.y, - rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width, - rect->bounds.origin.y, - weight); + gsk_path_builder_arc_to (self, + rect->bounds.origin.x, + rect->bounds.origin.y, + rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width, + rect->bounds.origin.y); /* done */ gsk_path_builder_close (self); self->current_point = current; @@ -564,7 +559,6 @@ gsk_path_builder_add_circle (GskPathBuilder *self, float radius) { graphene_point_t current; - const float weight = M_SQRT1_2; g_return_if_fail (self != NULL); g_return_if_fail (center != NULL); @@ -574,25 +568,21 @@ gsk_path_builder_add_circle (GskPathBuilder *self, gsk_path_builder_move_to (self, center->x + radius, center->y); // bottom right quarter - gsk_path_builder_conic_to (self, - center->x + radius, center->y + radius, - center->x, center->y + radius, - weight); + gsk_path_builder_arc_to (self, + center->x + radius, center->y + radius, + center->x, center->y + radius); // bottom left quarter - gsk_path_builder_conic_to (self, - center->x - radius, center->y + radius, - center->x - radius, center->y, - weight); + gsk_path_builder_arc_to (self, + center->x - radius, center->y + radius, + center->x - radius, center->y); // top left quarter - gsk_path_builder_conic_to (self, - center->x - radius, center->y - radius, - center->x, center->y - radius, - weight); + gsk_path_builder_arc_to (self, + center->x - radius, center->y - radius, + center->x, center->y - radius); // top right quarter - gsk_path_builder_conic_to (self, - center->x + radius, center->y - radius, - center->x + radius, center->y, - weight); + gsk_path_builder_arc_to (self, + center->x + radius, center->y - radius, + center->x + radius, center->y); // done gsk_path_builder_close (self); self->current_point = current; @@ -949,6 +939,43 @@ gsk_path_builder_rel_conic_to (GskPathBuilder *self, weight); } +/** + * gsk_path_builder_arc_to: + * @self: a `GskPathBuilder` + * @x1: x coordinate of first control point + * @y1: y coordinate of first control point + * @x2: x coordinate of second control point + * @y2: y coordinate of second control point + * + * Adds an elliptical arc from the current point to @x3, @y3 + * with @x1, @y1 determining the tangent directions. + * + * After this, @x3, @y3 will be the new current point. + * + * Note: Two points and their tangents do not determine + * a unique ellipse, so GSK just picks one. If you need more + * precise control, use [method@Gsk.PathBuilder.conic_to] + * or [method@Gsk.PathBuilder.svg_arc_to]. + * + * + * + * Arc To + * + * + * Since: 4.14 + */ +void +gsk_path_builder_arc_to (GskPathBuilder *self, + float x1, + float y1, + float x2, + float y2) +{ + g_return_if_fail (self != NULL); + + gsk_path_builder_conic_to (self, x1, y1, x2, y2, M_SQRT1_2); +} + /** * gsk_path_builder_close: * @self: a `GskPathBuilder` diff --git a/gsk/gskpathbuilder.h b/gsk/gskpathbuilder.h index 3c3e224d7f..ed79b45b98 100644 --- a/gsk/gskpathbuilder.h +++ b/gsk/gskpathbuilder.h @@ -136,6 +136,13 @@ void gsk_path_builder_rel_conic_to (GskPathBuilder float y2, float weight); +GDK_AVAILABLE_IN_4_14 +void gsk_path_builder_arc_to (GskPathBuilder *self, + float x1, + float y1, + float x2, + float y2); + GDK_AVAILABLE_IN_4_14 void gsk_path_builder_svg_arc_to (GskPathBuilder *self, float rx,