mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 14:00:09 +00:00
Merge branch 'contour-cosmetics' into 'main'
contour: Fixes for rects and rounded rects See merge request GNOME/gtk!6397
This commit is contained in:
commit
4b45f8415f
853
gsk/gskcontour.c
853
gsk/gskcontour.c
File diff suppressed because it is too large
Load Diff
@ -653,6 +653,13 @@ gsk_path_builder_quad_to (GskPathBuilder *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
/* skip the quad if it collapses to a point */
|
||||
if (graphene_point_equal (&self->current_point,
|
||||
&GRAPHENE_POINT_INIT (x1, y1)) &&
|
||||
graphene_point_equal (&GRAPHENE_POINT_INIT (x1, y1),
|
||||
&GRAPHENE_POINT_INIT (x2, y2)))
|
||||
return;
|
||||
|
||||
self->flags &= ~GSK_PATH_FLAT;
|
||||
gsk_path_builder_append_current (self,
|
||||
GSK_PATH_QUAD,
|
||||
@ -729,6 +736,15 @@ gsk_path_builder_cubic_to (GskPathBuilder *self,
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
/* skip the cubic if it collapses to a point */
|
||||
if (graphene_point_equal (&self->current_point,
|
||||
&GRAPHENE_POINT_INIT (x1, y1)) &&
|
||||
graphene_point_equal (&GRAPHENE_POINT_INIT (x1, y1),
|
||||
&GRAPHENE_POINT_INIT (x2, y2)) &&
|
||||
graphene_point_equal (&GRAPHENE_POINT_INIT (x2, y2),
|
||||
&GRAPHENE_POINT_INIT (x3, y3)))
|
||||
return;
|
||||
|
||||
self->flags &= ~GSK_PATH_FLAT;
|
||||
gsk_path_builder_append_current (self,
|
||||
GSK_PATH_CUBIC,
|
||||
@ -818,6 +834,13 @@ gsk_path_builder_conic_to (GskPathBuilder *self,
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (weight > 0);
|
||||
|
||||
/* skip the conic if it collapses to a point */
|
||||
if (graphene_point_equal (&self->current_point,
|
||||
&GRAPHENE_POINT_INIT (x1, y1)) &&
|
||||
graphene_point_equal (&GRAPHENE_POINT_INIT (x1, y1),
|
||||
&GRAPHENE_POINT_INIT (x2, y2)))
|
||||
return;
|
||||
|
||||
self->flags &= ~GSK_PATH_FLAT;
|
||||
gsk_path_builder_append_current (self,
|
||||
GSK_PATH_CONIC,
|
||||
|
@ -180,6 +180,9 @@ gsk_path_point_get_position (const GskPathPoint *point,
|
||||
* point, and the direction coming out of it. The @direction
|
||||
* argument lets you choose which one to get.
|
||||
*
|
||||
* If the path is just a single point (e.g. a circle with
|
||||
* radius zero), then @tangent is set to `0, 0`.
|
||||
*
|
||||
* If you want to orient something in the direction of the
|
||||
* path, [method@Gsk.PathPoint.get_rotation] may be more
|
||||
* convenient to use.
|
||||
|
@ -139,11 +139,14 @@ test_rounded_rect_roundtrip (void)
|
||||
const GskContour *contour;
|
||||
char *s;
|
||||
|
||||
/* our parser only recognizes 'complete' rounded rects
|
||||
* (i.e. no empty curves omitted).
|
||||
*/
|
||||
rr.bounds = GRAPHENE_RECT_INIT (100, 100, 200, 150);
|
||||
rr.corner[GSK_CORNER_TOP_LEFT] = GRAPHENE_SIZE_INIT (10, 10);
|
||||
rr.corner[GSK_CORNER_TOP_RIGHT] = GRAPHENE_SIZE_INIT (20, 10);
|
||||
rr.corner[GSK_CORNER_BOTTOM_RIGHT] = GRAPHENE_SIZE_INIT (20, 0);
|
||||
rr.corner[GSK_CORNER_BOTTOM_LEFT] = GRAPHENE_SIZE_INIT (0, 0);
|
||||
rr.corner[GSK_CORNER_BOTTOM_RIGHT] = GRAPHENE_SIZE_INIT (20, 20);
|
||||
rr.corner[GSK_CORNER_BOTTOM_LEFT] = GRAPHENE_SIZE_INIT (5, 10);
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rounded_rect (builder, &rr);
|
||||
|
@ -773,7 +773,7 @@ test_rotated_arc (void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_rounded_rect (void)
|
||||
test_rounded_rect_basic (void)
|
||||
{
|
||||
GskRoundedRect rect;
|
||||
GskPathBuilder *builder;
|
||||
@ -813,7 +813,7 @@ test_rounded_rect (void)
|
||||
}
|
||||
|
||||
static void
|
||||
test_rect (void)
|
||||
test_rect_in_fill (void)
|
||||
{
|
||||
graphene_rect_t rect;
|
||||
GskPathBuilder *builder;
|
||||
@ -1049,6 +1049,471 @@ test_circle_point (void)
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rect_plain (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GskPathPoint point;
|
||||
graphene_point_t pos;
|
||||
graphene_vec2_t tan, v;
|
||||
char *s;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (10, 10, 100, 200));
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
s = gsk_path_to_string (path);
|
||||
g_assert_cmpstr (s, ==, "M 10 10 h 100 v 200 h -100 z");
|
||||
g_free (s);
|
||||
|
||||
measure = gsk_path_measure_new (path);
|
||||
|
||||
g_assert_true (gsk_path_measure_get_length (measure) == 600);
|
||||
|
||||
gsk_path_get_start_point (path, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (10, 10)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, -1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, 1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, -1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 1, 0)));
|
||||
|
||||
gsk_path_measure_get_point (measure, 100, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (110, 10)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, -1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, -1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, 1)));
|
||||
|
||||
gsk_path_measure_get_point (measure, 300, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (110, 210)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, 1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, -1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, -1, 0)));
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rect_zero_height (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GskPathPoint point;
|
||||
graphene_point_t pos;
|
||||
graphene_vec2_t tan, v;
|
||||
char *s;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (10, 10, 100, 0));
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
s = gsk_path_to_string (path);
|
||||
g_assert_cmpstr (s, ==, "M 10 10 h 100 v 0 h -100 z");
|
||||
g_free (s);
|
||||
|
||||
measure = gsk_path_measure_new (path);
|
||||
|
||||
g_assert_true (gsk_path_measure_get_length (measure) == 200);
|
||||
|
||||
gsk_path_measure_get_point (measure, 100, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (110, 10)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, -1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 1, 0)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, -1, 0)));
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rect_zero_width (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GskPathPoint point;
|
||||
graphene_point_t pos;
|
||||
graphene_vec2_t tan, v;
|
||||
char *s;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (10, 10, 0, 100));
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
s = gsk_path_to_string (path);
|
||||
g_assert_cmpstr (s, ==, "M 10 10 h 0 v 100 h -0 z");
|
||||
g_free (s);
|
||||
|
||||
measure = gsk_path_measure_new (path);
|
||||
|
||||
g_assert_true (gsk_path_measure_get_length (measure) == 200);
|
||||
|
||||
gsk_path_measure_get_point (measure, 100, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (10, 110)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, 1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, -1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, 1)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_init (&v, 0, -1)));
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rect_zero (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GskPathPoint point;
|
||||
graphene_point_t pos;
|
||||
graphene_vec2_t tan;
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (10, 10, 0, 0));
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
measure = gsk_path_measure_new (path);
|
||||
|
||||
g_assert_true (gsk_path_measure_get_length (measure) == 0);
|
||||
|
||||
gsk_path_measure_get_point (measure, 0, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_equal (&pos, &GRAPHENE_POINT_INIT (10, 10)));
|
||||
|
||||
gsk_path_point_get_tangent (&point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_equal (&tan, graphene_vec2_zero ()));
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
check_rounded_rect_point (const GskPathPoint *point,
|
||||
GskPath *path,
|
||||
const graphene_point_t *pos,
|
||||
const graphene_vec2_t *tan1,
|
||||
const graphene_vec2_t *tan2,
|
||||
float k1,
|
||||
float k2)
|
||||
{
|
||||
graphene_point_t p;
|
||||
graphene_vec2_t tan;
|
||||
|
||||
gsk_path_point_get_position (point, path, &p);
|
||||
g_assert_true (graphene_point_near (pos, &p, 0.0001));
|
||||
|
||||
gsk_path_point_get_tangent (point, path, GSK_PATH_FROM_START, &tan);
|
||||
g_assert_true (graphene_vec2_near (tan1, &tan, 0.0001));
|
||||
|
||||
gsk_path_point_get_tangent (point, path, GSK_PATH_TO_END, &tan);
|
||||
g_assert_true (graphene_vec2_near (tan2, &tan, 0.0001));
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (k1, gsk_path_point_get_curvature (point, path, GSK_PATH_FROM_START, NULL), 0.0001);
|
||||
g_assert_cmpfloat_with_epsilon (k2, gsk_path_point_get_curvature (point, path, GSK_PATH_TO_END, NULL), 0.0001);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rounded_rect_plain (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GskPathPoint point;
|
||||
GskRoundedRect rect;
|
||||
graphene_vec2_t v1, v2;
|
||||
graphene_point_t pos;
|
||||
char *s;
|
||||
|
||||
rect.bounds = GRAPHENE_RECT_INIT (10, 10, 100, 200);
|
||||
rect.corner[0] = GRAPHENE_SIZE_INIT (10, 10);
|
||||
rect.corner[1] = GRAPHENE_SIZE_INIT (10, 10);
|
||||
rect.corner[2] = GRAPHENE_SIZE_INIT (10, 10);
|
||||
rect.corner[3] = GRAPHENE_SIZE_INIT (10, 10);
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rounded_rect (builder, &rect);
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
s = gsk_path_to_string (path);
|
||||
g_assert_cmpstr (s, ==, "M 20 10 L 100 10 O 110 10, 110 20, 0.70710676908493042 L 110 200 O 110 210, 100 210, 0.70710676908493042 L 20 210 O 10 210, 10 200, 0.70710676908493042 L 10 20 O 10 10, 20 10, 0.70710676908493042 Z");
|
||||
g_free (s);
|
||||
|
||||
measure = gsk_path_measure_new (path);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gsk_path_measure_get_length (measure),
|
||||
600 - 4 * 20 + 2 * M_PI * 10,
|
||||
0.0001);
|
||||
|
||||
gsk_path_get_start_point (path, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (20, 10), 0.0001));
|
||||
|
||||
/* Checking the curvature with the measured points is difficult,
|
||||
* because rounding might put us on the arc. Therefore, set points
|
||||
* precisely for these checks.
|
||||
*/
|
||||
point.contour = 0;
|
||||
point.idx = 1;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (20, 10),
|
||||
graphene_vec2_init (&v1, 1, 0),
|
||||
graphene_vec2_init (&v2, 1, 0),
|
||||
0.1, 0);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (100, 10), 0.0001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 2;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (100, 10),
|
||||
graphene_vec2_init (&v1, 1, 0),
|
||||
graphene_vec2_init (&v2, 1, 0),
|
||||
0, 0.1);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80 + (2 * M_PI * 10)/4, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (110, 20), 0.0001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 3;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (110, 20),
|
||||
graphene_vec2_init (&v1, 0, 1),
|
||||
graphene_vec2_init (&v2, 0, 1),
|
||||
0.1, 0);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80 + (2 * M_PI * 10)/4 + 180, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (110, 200), 0.0001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 4;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (110, 200),
|
||||
graphene_vec2_init (&v1, 0, 1),
|
||||
graphene_vec2_init (&v2, 0, 1),
|
||||
0, 0.1);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80 + 180 + (2 * M_PI * 10)/2, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (100, 210), 0.00001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 5;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (100, 210),
|
||||
graphene_vec2_init (&v1, -1, 0),
|
||||
graphene_vec2_init (&v2, -1, 0),
|
||||
0.1, 0);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80 + 180 + 80 + (2 * M_PI * 10)/2, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (20, 210), 0.00001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 6;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (20, 210),
|
||||
graphene_vec2_init (&v1, -1, 0),
|
||||
graphene_vec2_init (&v2, -1, 0),
|
||||
0, 0.1);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80 + 180 + 80 + (2 * M_PI * 10)*3/4, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (10, 200), 0.00001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 7;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (10, 200),
|
||||
graphene_vec2_init (&v1, 0, -1),
|
||||
graphene_vec2_init (&v2, 0, -1),
|
||||
0.1, 0);
|
||||
|
||||
gsk_path_measure_get_point (measure, 80 + 180 + 80 + 180 + (2 * M_PI * 10)*3/4, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (10, 20), 0.00001));
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 8;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (10, 20),
|
||||
graphene_vec2_init (&v1, 0, -1),
|
||||
graphene_vec2_init (&v2, 0, -1),
|
||||
0, 0.1);
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
static void
|
||||
test_rounded_rect_tricky (void)
|
||||
{
|
||||
GskPathBuilder *builder;
|
||||
GskPath *path;
|
||||
GskPathMeasure *measure;
|
||||
GskPathPoint point;
|
||||
GskRoundedRect rect;
|
||||
graphene_vec2_t v1, v2;
|
||||
graphene_point_t pos;
|
||||
char *s;
|
||||
|
||||
rect.bounds = GRAPHENE_RECT_INIT (10, 10, 100, 200);
|
||||
rect.corner[0] = GRAPHENE_SIZE_INIT (0, 0);
|
||||
rect.corner[1] = GRAPHENE_SIZE_INIT (0, 100);
|
||||
rect.corner[2] = GRAPHENE_SIZE_INIT (0, 100);
|
||||
rect.corner[3] = GRAPHENE_SIZE_INIT (10, 10);
|
||||
|
||||
builder = gsk_path_builder_new ();
|
||||
gsk_path_builder_add_rounded_rect (builder, &rect);
|
||||
path = gsk_path_builder_free_to_path (builder);
|
||||
|
||||
s = gsk_path_to_string (path);
|
||||
g_assert_cmpstr (s, ==, "M 10 10 L 110 10 L 110 110 L 110 210 L 20 210 O 10 210, 10 200, 0.70710676908493042 L 10 10 Z");
|
||||
g_free (s);
|
||||
|
||||
measure = gsk_path_measure_new (path);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gsk_path_measure_get_length (measure),
|
||||
600 - 20 + (2 * M_PI * 10) / 4,
|
||||
0.0001);
|
||||
|
||||
gsk_path_get_start_point (path, &point);
|
||||
gsk_path_point_get_position (&point, path, &pos);
|
||||
g_assert_true (graphene_point_near (&pos, &GRAPHENE_POINT_INIT (10, 10), 0.0001));
|
||||
|
||||
/* Checking the curvature with the measured points is difficult,
|
||||
* because rounding might put us on the arc. Therefore, set points
|
||||
* precisely for these checks.
|
||||
*/
|
||||
point.contour = 0;
|
||||
point.idx = 1;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (10, 10),
|
||||
graphene_vec2_init (&v1, 0, -1),
|
||||
graphene_vec2_init (&v2, 1, 0),
|
||||
0, 0);
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 2;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (110, 10),
|
||||
graphene_vec2_init (&v2, 1, 0),
|
||||
graphene_vec2_init (&v1, 0, 1),
|
||||
0, 0);
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 3;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (110, 110),
|
||||
graphene_vec2_init (&v1, 0, 1),
|
||||
graphene_vec2_init (&v2, 0, 1),
|
||||
0, 0);
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 4;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (110, 210),
|
||||
graphene_vec2_init (&v1, 0, 1),
|
||||
graphene_vec2_init (&v2, -1, 0),
|
||||
0, 0);
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 5;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (20, 210),
|
||||
graphene_vec2_init (&v1, -1, 0),
|
||||
graphene_vec2_init (&v2, -1, 0),
|
||||
0, 0.1);
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 6;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (10, 200),
|
||||
graphene_vec2_init (&v2, 0, -1),
|
||||
graphene_vec2_init (&v2, 0, -1),
|
||||
0.1, 0);
|
||||
|
||||
point.contour = 0;
|
||||
point.idx = 7;
|
||||
point.t = 0;
|
||||
check_rounded_rect_point (&point, path,
|
||||
&GRAPHENE_POINT_INIT (10, 10),
|
||||
graphene_vec2_init (&v1, 0, -1),
|
||||
graphene_vec2_init (&v2, 1, 0),
|
||||
0, 0);
|
||||
|
||||
gsk_path_measure_unref (measure);
|
||||
gsk_path_unref (path);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -1064,12 +1529,18 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/path/unclosed-in-fill", test_unclosed_in_fill);
|
||||
g_test_add_func ("/path/builder/add", test_path_builder_add);
|
||||
g_test_add_func ("/path/rotated-arc", test_rotated_arc);
|
||||
g_test_add_func ("/path/rounded-rect", test_rounded_rect);
|
||||
g_test_add_func ("/path/rect", test_rect);
|
||||
g_test_add_func ("/path/rounded-rect/basic", test_rounded_rect_basic);
|
||||
g_test_add_func ("/path/rect/in-fill", test_rect_in_fill);
|
||||
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);
|
||||
g_test_add_func ("/path/rect/plain", test_rect_plain);
|
||||
g_test_add_func ("/path/rect/zero-height", test_rect_zero_height);
|
||||
g_test_add_func ("/path/rect/zero-width", test_rect_zero_width);
|
||||
g_test_add_func ("/path/rect/zero", test_rect_zero);
|
||||
g_test_add_func ("/path/rounded-rect/plain", test_rounded_rect_plain);
|
||||
g_test_add_func ("/path/rounded-rect/tricky", test_rounded_rect_tricky);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user