mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 18:30:08 +00:00
Allow circles with radius of zero
Not very useful, but we allow rects with width and height of zero, so lets be consistent. Curvature is infinite for such contours. Tests included.
This commit is contained in:
parent
6f3be310f4
commit
0dbff14555
@ -914,6 +914,7 @@ gsk_standard_contour_get_point (const GskContour *contour,
|
||||
{
|
||||
result->idx = curve_measure->idx;
|
||||
result->t = p->t;
|
||||
g_assert (0 <= result->t && result->t <= 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -941,9 +942,9 @@ gsk_standard_contour_get_point (const GskContour *contour,
|
||||
result->idx = curve_measure->idx;
|
||||
|
||||
fraction = (distance - p0->length) / (p1->length - p0->length);
|
||||
g_assert (fraction >= 0.f && fraction <= 1.f);
|
||||
g_assert (fraction >= 0 && fraction <= 1);
|
||||
result->t = p0->t * (1 - fraction) + p1->t * fraction;
|
||||
g_assert (result->t >= 0.f && result->t <= 1.f);
|
||||
g_assert (result->t >= 0 && result->t <= 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -986,7 +987,7 @@ gsk_standard_contour_get_distance (const GskContour *contour,
|
||||
g_assert (p0->t <= point->t && point->t <= p1->t);
|
||||
|
||||
fraction = (point->t - p0->t) / (p1->t - p0->t);
|
||||
g_assert (fraction >= 0.f && fraction <= 1.f);
|
||||
g_assert (fraction >= 0 && fraction <= 1);
|
||||
|
||||
return p0->length * (1 - fraction) + p1->length * fraction;
|
||||
}
|
||||
@ -1295,7 +1296,10 @@ gsk_circle_contour_get_curvature (const GskContour *contour,
|
||||
if (center)
|
||||
*center = self->center;
|
||||
|
||||
return 1 / self->radius;
|
||||
if (self->radius == 0)
|
||||
return INFINITY;
|
||||
|
||||
return 1.f / self->radius;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1377,13 +1381,17 @@ gsk_circle_contour_get_point (const GskContour *contour,
|
||||
const GskCircleContour *self = (const GskCircleContour *) contour;
|
||||
float t;
|
||||
|
||||
t = distance / (2 * M_PI * self->radius);
|
||||
if (self->radius == 0)
|
||||
t = 0;
|
||||
else
|
||||
t = distance / (2 * M_PI * self->radius);
|
||||
|
||||
if (self->ccw)
|
||||
t = 1 - t;
|
||||
|
||||
result->idx = 1;
|
||||
result->t = t;
|
||||
g_assert (result->t >= 0 && result->t <= 1);
|
||||
}
|
||||
|
||||
static float
|
||||
@ -1433,7 +1441,7 @@ gsk_circle_contour_new (const graphene_point_t *center,
|
||||
{
|
||||
GskCircleContour *self;
|
||||
|
||||
g_assert (radius > 0);
|
||||
g_assert (radius >= 0);
|
||||
|
||||
self = g_new0 (GskCircleContour, 1);
|
||||
|
||||
@ -1936,6 +1944,7 @@ gsk_rect_contour_get_point (const GskContour *contour,
|
||||
result->t = 0;
|
||||
else
|
||||
result->t = CLAMP (distance / self->length, 0, 1);
|
||||
g_assert (0 <= result->t && result->t <= 1);
|
||||
}
|
||||
|
||||
static float
|
||||
|
@ -497,6 +497,8 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self,
|
||||
*
|
||||
* The path is going around the circle in clockwise direction.
|
||||
*
|
||||
* If @radius is zero, the contour will be a closed point.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
void
|
||||
@ -506,7 +508,7 @@ gsk_path_builder_add_circle (GskPathBuilder *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (center != NULL);
|
||||
g_return_if_fail (radius > 0);
|
||||
g_return_if_fail (radius >= 0);
|
||||
|
||||
gsk_path_builder_add_contour (self, gsk_circle_contour_new (center, radius));
|
||||
}
|
||||
|
@ -285,6 +285,8 @@ gsk_path_point_get_rotation (const GskPathPoint *point,
|
||||
* Lines have a curvature of zero (indicating an osculating circle of
|
||||
* infinite radius. In this case, the @center is not modified.
|
||||
*
|
||||
* Circles with a radius of zero have `INFINITY` as curvature
|
||||
*
|
||||
* Note that certain points on a path may not have a single curvature,
|
||||
* such as sharp turns. At such points, there are two curvatures --
|
||||
* the (limit of) the curvature of the path going into the point,
|
||||
|
@ -938,7 +938,6 @@ test_circle (void)
|
||||
g_assert_true (gsk_path_in_fill (path6, &GRAPHENE_POINT_INIT (0, 0), GSK_FILL_RULE_WINDING));
|
||||
g_assert_false (gsk_path_in_fill (path6, &GRAPHENE_POINT_INIT (0, 0), GSK_FILL_RULE_EVEN_ODD));
|
||||
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_measure_unref (measure1);
|
||||
gsk_path_measure_unref (measure2);
|
||||
@ -1035,6 +1034,28 @@ test_rect_segment (void)
|
||||
gsk_path_measure_unref (measure2);
|
||||
}
|
||||
|
||||
static void
|
||||
test_circle_point (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathPoint point;
|
||||
graphene_point_t center;
|
||||
float k;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (1, 2), 0);
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
gsk_path_get_start_point (path, &point);
|
||||
k = gsk_path_point_get_curvature (&point, path, GSK_PATH_TO_END, ¢er);
|
||||
|
||||
g_assert_true (k == INFINITY);
|
||||
g_assert_true (graphene_point_equal (¢er, &GRAPHENE_POINT_INIT (1, 2)));
|
||||
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -1055,6 +1076,7 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/path/circle", test_circle);
|
||||
g_test_add_func ("/path/length", test_length);
|
||||
g_test_add_func ("/path/rect/segment", test_rect_segment);
|
||||
g_test_add_func ("/path/circle-point", test_circle_point);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
static GskPath *
|
||||
create_random_degenerate_path (guint max_contours)
|
||||
{
|
||||
#define N_DEGENERATE_PATHS 14
|
||||
#define N_DEGENERATE_PATHS 15
|
||||
GskPathBuilder *builder;
|
||||
guint i;
|
||||
|
||||
@ -132,6 +132,14 @@ create_random_degenerate_path (guint max_contours)
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* circle with radius 0 */
|
||||
gsk_path_builder_add_circle (builder,
|
||||
&GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000),
|
||||
g_test_rand_double_range (-1000, 1000)),
|
||||
0);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* a zero-length line */
|
||||
{
|
||||
graphene_point_t point = GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000),
|
||||
@ -141,7 +149,7 @@ create_random_degenerate_path (guint max_contours)
|
||||
}
|
||||
break;
|
||||
|
||||
case 13:
|
||||
case 14:
|
||||
/* a cubic with start == end */
|
||||
{
|
||||
graphene_point_t point = GRAPHENE_POINT_INIT (g_test_rand_double_range (-1000, 1000),
|
||||
|
Loading…
Reference in New Issue
Block a user