diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-12-05 02:56:55 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-12-12 10:05:38 -0500 |
commit | 137eef6465dc275fad1b3548ded9fa4aa6c30acb (patch) | |
tree | 5b97f4f4ab430cf44d8b6b54a0da7d360244d513 | |
parent | dfb25771a7e1419fc8ce312ac1aa04212a7e4b9b (diff) | |
download | gtk+-fix-rect-closest-point.tar.gz |
Fix get_closest_point for rectanglesfix-rect-closest-point
This was still returning wrong offsets for one of the four
sides. Add a testcase for rectangles and circles to prevent
this happening again in the future.
-rw-r--r-- | gsk/gskcontour.c | 9 | ||||
-rw-r--r-- | testsuite/gsk/path-special-cases.c | 51 |
2 files changed, 58 insertions, 2 deletions
diff --git a/gsk/gskcontour.c b/gsk/gskcontour.c index c7c74e9cff..8d47b456a4 100644 --- a/gsk/gskcontour.c +++ b/gsk/gskcontour.c @@ -359,8 +359,13 @@ gsk_rect_contour_get_closest_point (const GskContour *contour, *out_pos = p; if (out_offset) - *out_offset = (t.x == 0.0 && self->width > 0 ? 2 - t.y : t.y) * ABS (self->height) + - (t.y == 1.0 ? 2 - t.x : t.x) * ABS (self->width); + { + if (t.x == 0.0 && t.y == 0.0) + *out_offset = 0.0; + else + *out_offset = (t.x == 0.0 && self->width > 0 ? 2 - t.y : t.y) * ABS (self->height) + + (t.y > 0 ? 2 - t.x : t.x) * ABS (self->width); + } if (out_tangent) { diff --git a/testsuite/gsk/path-special-cases.c b/testsuite/gsk/path-special-cases.c index 04a575ac1f..3f65556064 100644 --- a/testsuite/gsk/path-special-cases.c +++ b/testsuite/gsk/path-special-cases.c @@ -306,6 +306,56 @@ test_serialize_custom_contours (void) gsk_path_unref (path1); } +/* Test that get_closest_point works for rectangles and circles */ +static void +test_closest_point_custom_contours (void) +{ + static const float tolerance = 0.5; + GskPathBuilder *builder; + GskPath *path; + GskPathMeasure *measure; + float length, offset, closest_offset, distance; + graphene_point_t point, closest_point; + guint i, j; + + for (i = 0; i < 2; i++) + { + builder = gsk_path_builder_new (); + if (i == 0) + gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (100, 100, 200, 200)); + else + gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (100, 100), 200); + + path = gsk_path_builder_free_to_path (builder); + + measure = gsk_path_measure_new_with_tolerance (path, tolerance); + length = gsk_path_measure_get_length (measure); + + for (j = 0; j < 100; j++) + { + offset = g_test_rand_double_range (0, length); + + gsk_path_measure_get_point (measure, + offset, + &point, + NULL); + g_assert_true (gsk_path_measure_get_closest_point_full (measure, + &point, + tolerance, + &distance, + &closest_point, + &closest_offset, + NULL)); + g_assert_cmpfloat (distance, <=, tolerance); + g_assert_cmpfloat (graphene_point_distance (&point, &closest_point, NULL, NULL), <=, tolerance); + g_assert_cmpfloat_with_epsilon (closest_offset, offset, tolerance); + } + + gsk_path_measure_unref (measure); + gsk_path_unref (path); + } +} + int main (int argc, char *argv[]) @@ -314,6 +364,7 @@ main (int argc, g_test_add_func ("/path/rsvg-parse", test_rsvg_parse); g_test_add_func ("/path/serialize-custom-contours", test_serialize_custom_contours); + g_test_add_func ("/path/closest-point-custom-contours", test_closest_point_custom_contours); return g_test_run (); } |