Example #1
0
static void
_cpml_sanity_put_intersections_with_segment(gint i)
{
    CpmlPrimitive primitive;
    CpmlSegment segment;
    CpmlPair pair;

    /* Set primitive 1.1 and segment to 2
     * so there is an intersection point in (1,1) */
    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&primitive, &segment);

    cpml_segment_next(&segment);

    switch (i) {
    case 1:
        cpml_primitive_put_intersections_with_segment(NULL, &segment, 2, &pair);
        break;
    case 2:
        cpml_primitive_put_intersections_with_segment(&primitive, NULL, 2, &pair);
        break;
    case 3:
        cpml_primitive_put_intersections_with_segment(&primitive, &segment, 2, NULL);
        break;
    default:
        g_test_trap_assert_failed();
        break;
    }
}
Example #2
0
File: adg-path.c Project: bert/adg
static void
_adg_do_operation(AdgPath *path, cairo_path_data_t *path_data)
{
    AdgPathPrivate *data;
    AdgAction action;
    CpmlSegment segment;
    CpmlPrimitive current;
    cairo_path_data_t current_org;

    data = path->data;
    action = data->operation.action;
    cpml_segment_from_cairo(&segment, _adg_read_cairo_path(path));

    /* Construct the current primitive, that is the primitive to be
     * mixed with the last primitive with the specified operation.
     * Its org is a copy of the end point of the last primitive: it can be
     * modified without affecting anything else. It is expected the operation
     * functions will add to @path the primitives required but NOT to add
     * @current, as this one will be inserted automatically. */
    current.segment = &segment;
    current.org = &current_org;
    current.data = path_data;
    cpml_pair_to_cairo(&data->cp, &current_org);

    _adg_do_action(path, action, &current);
}
Example #3
0
static void
_cpml_method_get_n_points(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    size_t n_points;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    /* Line */
    cpml_primitive_from_segment(&primitive, &segment);
    n_points = cpml_primitive_get_n_points(&primitive);
    g_assert_cmpuint(n_points, ==, 2);

    /* Arc */
    cpml_primitive_next(&primitive);
    n_points = cpml_primitive_get_n_points(&primitive);
    g_assert_cmpuint(n_points, ==, 3);

    /* Curve */
    cpml_primitive_next(&primitive);
    n_points = cpml_primitive_get_n_points(&primitive);
    g_assert_cmpuint(n_points, ==, 4);

    /* Close: although the end point is not needed, the CPML API
     * returns 2 points to treat this primitive as a CPML_LINE */
    cpml_primitive_next(&primitive);
    n_points = cpml_primitive_get_n_points(&primitive);
    g_assert_cmpuint(n_points, ==, 2);
}
Example #4
0
File: adg-path.c Project: bert/adg
static void
_adg_rescan(AdgPath *path)
{
    AdgPathPrivate *data;
    CpmlSegment segment;
    CpmlPrimitive current, *last, *over;

    data = path->data;
    last = &data->last;
    over = &data->over;

    last->segment = NULL;
    last->org = NULL;
    last->data = NULL;
    over->segment = NULL;
    over->org = NULL;
    over->data = NULL;

    /* When no data is present, just bail out */
    if (! cpml_segment_from_cairo(&segment, _adg_read_cairo_path(path)))
        return;

    do {
        cpml_primitive_from_segment(&current, &segment);
        do {
            cpml_primitive_copy(over, last);
            cpml_primitive_copy(last, &current);
        } while (cpml_primitive_next(&current));
    } while (cpml_segment_next(&segment));
}
Example #5
0
static void
_cpml_method_put_pair_at(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlPair pair;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    /* Line */
    cpml_primitive_from_segment(&primitive, &segment);
    cpml_primitive_put_pair_at(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_pair_at(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 3);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
    adg_assert_isapprox(pair.x, 1.5);
    adg_assert_isapprox(pair.y, 1);

    /* Arc */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_pair_at(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, 3);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_pair_at(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 6);
    adg_assert_isapprox(pair.y, 7);
    cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
    adg_assert_isapprox(pair.x, 3.669);
    adg_assert_isapprox(pair.y, 4.415);

    /* Close */
    cpml_primitive_next(&primitive);
    /* TODO: not yet implemented
     * cpml_primitive_put_pair_at(&primitive, 0, &pair);
     * adg_assert_isapprox(pair.x, 6);
     * adg_assert_isapprox(pair.y, 7);
     * cpml_primitive_put_pair_at(&primitive, 1, &pair);
     * adg_assert_isapprox(pair.x, -2);
     * adg_assert_isapprox(pair.y, 2);
     * cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
     * adg_assert_isapprox(pair.x, 1);
     * adg_assert_isapprox(pair.y, 1); */

    /* Close */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_pair_at(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, -2);
    adg_assert_isapprox(pair.y, 2);
    cpml_primitive_put_pair_at(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_pair_at(&primitive, 0.5, &pair);
    adg_assert_isapprox(pair.x, -1);
    adg_assert_isapprox(pair.y, 1.5);
}
Example #6
0
static void
_cpml_method_put_vector_at(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlVector vector;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    /* Line */
    cpml_primitive_from_segment(&primitive, &segment);
    cpml_primitive_put_vector_at(&primitive, 0, &vector);
    adg_assert_isapprox(vector.x, 3);
    adg_assert_isapprox(vector.y, 0);
    cpml_primitive_put_vector_at(&primitive, 1, &vector);
    adg_assert_isapprox(vector.x, 3);
    adg_assert_isapprox(vector.y, 0);
    cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
    adg_assert_isapprox(vector.x, 3);
    adg_assert_isapprox(vector.y, 0);

    /* Arc */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_vector_at(&primitive, 0, &vector);
    adg_assert_isapprox(vector.x, -0.077);
    adg_assert_isapprox(vector.y, 0.997);
    cpml_primitive_put_vector_at(&primitive, 1, &vector);
    adg_assert_isapprox(vector.x, 0.844);
    adg_assert_isapprox(vector.y, 0.537);
    cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
    adg_assert_isapprox(vector.x, 0.447);
    adg_assert_isapprox(vector.y, 0.894);

    /* Close */
    cpml_primitive_next(&primitive);
    /* TODO: not yet implemented
     * cpml_primitive_put_vector_at(&primitive, 0, &vector);
     * adg_assert_isapprox(vector.x, 6);
     * adg_assert_isapprox(vector.y, 7);
     * cpml_primitive_put_vector_at(&primitive, 1, &vector);
     * adg_assert_isapprox(vector.x, -2);
     * adg_assert_isapprox(vector.y, 2);
     * cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
     * adg_assert_isapprox(vector.x, 1);
     * adg_assert_isapprox(vector.y, 1); */

    /* Close */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_vector_at(&primitive, 0, &vector);
    adg_assert_isapprox(vector.x, 2);
    adg_assert_isapprox(vector.y, -1);
    cpml_primitive_put_vector_at(&primitive, 1, &vector);
    adg_assert_isapprox(vector.x, 2);
    adg_assert_isapprox(vector.y, -1);
    cpml_primitive_put_vector_at(&primitive, 0.5, &vector);
    adg_assert_isapprox(vector.x, 2);
    adg_assert_isapprox(vector.y, -1);
}
Example #7
0
static void
_cpml_method_from_segment(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;

    g_assert_true(cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path()));

    cpml_primitive_from_segment(&primitive, &segment);
    g_assert_nonnull(primitive.segment);
    g_assert_nonnull(primitive.org);
    g_assert_nonnull(primitive.data);
}
Example #8
0
static void
_cpml_method_put_intersections(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive1, primitive2;
    CpmlPair pair[2];

    /* Set primitive1 to 1.1 (first segment, first primitive) */
    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&primitive1, &segment);

    /* Set primitive2 to 2.1 (second segment, first primitive) */
    cpml_segment_next(&segment);
    cpml_primitive_from_segment(&primitive2, &segment);

    /* primitive1 (1.1) does not intersect primitive2 (2.1) */
    g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 0);

    cpml_primitive_next(&primitive2);

    /* primitive1 (1.1) intersects primitive2 (2.2) in (1, 1) */
    g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 1);
    adg_assert_isapprox(pair[0].x, 1);
    adg_assert_isapprox(pair[0].y, 1);
    g_assert_cmpint(cpml_primitive_is_inside(&primitive1, pair), ==, 1);
    g_assert_cmpint(cpml_primitive_is_inside(&primitive2, pair), ==, 1);

    /* Check the intersection is not returned when not requested */
    g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 0, pair), ==, 0);

    cpml_primitive_next(&primitive1);

    /* primitive1 (1.2) does not intersect primitive2 (2.2) */
    g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 0);

    cpml_primitive_next(&primitive1);

    /* primitive1 (1.3) does not intersect primitive2 (2.2) */
    g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 0);

    cpml_primitive_next(&primitive1);

    /* primitive1 (1.4) intersects primitive2 (2.2), but outside their boundaries */
    g_assert_cmpuint(cpml_primitive_put_intersections(&primitive1, &primitive2, 2, pair), ==, 1);
    adg_assert_isapprox(pair[0].x, 1);
    adg_assert_isapprox(pair[0].y, -1);
    g_assert_cmpint(cpml_primitive_is_inside(&primitive1, pair), ==, 0);
    g_assert_cmpint(cpml_primitive_is_inside(&primitive2, pair), ==, 0);
}
Example #9
0
static void
_cpml_method_get_length(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_segment_next(&segment);
    cpml_primitive_from_segment(&primitive, &segment);

    adg_assert_isapprox(cpml_primitive_get_length(&primitive), 1);

    cpml_primitive_next(&primitive);
    adg_assert_isapprox(cpml_primitive_get_length(&primitive), 2);
}
Example #10
0
static void
_cpml_method_put_extents(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlExtents extents;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    /* Line */
    cpml_primitive_from_segment(&primitive, &segment);
    cpml_primitive_put_extents(&primitive, &extents);
    g_assert_true(extents.is_defined);
    adg_assert_isapprox(extents.org.x, 0);
    adg_assert_isapprox(extents.org.y, 1);
    adg_assert_isapprox(extents.size.x, 3);
    adg_assert_isapprox(extents.size.y, 0);

    /* Arc: the extents are computed precisely... let's ensure
     * at least all the 3 points are included */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_extents(&primitive, &extents);
    g_assert_true(extents.is_defined);
    g_assert_cmpfloat(extents.org.x, <=, 3);
    g_assert_cmpfloat(extents.org.y, <=, 1);
    g_assert_cmpfloat(extents.size.x, >=, 3);
    g_assert_cmpfloat(extents.size.y, >=, 6);

    /* Curve: actually the extents are computed by using the
     * convex hull (hence the exact coordinates of the points) */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_extents(&primitive, &extents);
    g_assert_true(extents.is_defined);
    adg_assert_isapprox(extents.org.x, -2);
    adg_assert_isapprox(extents.org.y, 2);
    adg_assert_isapprox(extents.size.x, 12);
    adg_assert_isapprox(extents.size.y, 9);

    /* Close */
    cpml_primitive_next(&primitive);
    cpml_primitive_put_extents(&primitive, &extents);
    g_assert_true(extents.is_defined);
    adg_assert_isapprox(extents.org.x, -2);
    adg_assert_isapprox(extents.org.y, 1);
    adg_assert_isapprox(extents.size.x, 2);
    adg_assert_isapprox(extents.size.y, 1);
}
Example #11
0
static void
_cpml_method_put_intersections_with_segment(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlPair pair[4];

    /* Set primitive to first segment, first primitive */
    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&primitive, &segment);

    /* Set segment to the second segment */
    cpml_segment_next(&segment);

    /* primitive (1.1) intersects segment (2) in (1, 1) */
    g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 1);
    adg_assert_isapprox(pair[0].x, 1);
    adg_assert_isapprox(pair[0].y, 1);

    cpml_primitive_next(&primitive);

    /* primitive (1.1) does not intersect segment (2) */
    g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 0);

    /* Set primitive to second segment, first primitive */
    cpml_primitive_from_segment(&primitive, &segment);

    /* Set segment to the first segment */
    cpml_segment_reset(&segment);

    /* primitive (2.1) intersects segment (1) in extrapolation.
     * TODO: change this behavior! They must not intersect. */
    g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 1);
    adg_assert_isapprox(pair[0].x, 2);
    adg_assert_isapprox(pair[0].y, 0);

    cpml_primitive_next(&primitive);

    /* primitive (2.2) wrongly intersects segment (1) */
    g_assert_cmpuint(cpml_primitive_put_intersections_with_segment(&primitive, &segment, 4, pair), ==, 1);
    adg_assert_isapprox(pair[0].x, 2);
    adg_assert_isapprox(pair[0].y, 0);
}
Example #12
0
static void
_cpml_method_copy_data(void)
{
    CpmlSegment segment;
    CpmlPrimitive original, *primitive;
    int n;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&original, &segment);

    /* Check incompatible primitives are not copied */
    primitive = cpml_primitive_deep_dup(&original);
    ++primitive->data[0].header.length;
    g_assert_cmpint(cpml_primitive_copy_data(primitive, &original), ==, 0);
    --primitive->data[0].header.length;
    ++primitive->data[0].header.type;
    g_assert_cmpint(cpml_primitive_copy_data(primitive, &original), ==, 0);
    --primitive->data[0].header.type;

    do {
        primitive = cpml_primitive_deep_dup(&original);
        ++primitive->org->point.x;
        ++primitive->org->point.y;
        for (n = 1; n < primitive->data[0].header.length; ++n) {
            ++primitive->data[n].point.x;
            ++primitive->data[n].point.y;
        }
        g_assert_cmpfloat(primitive->org->point.x, !=, original.org->point.x);
        g_assert_cmpfloat(primitive->org->point.y, !=, original.org->point.y);
        for (n = 1; n < primitive->data[0].header.length; ++n) {
            g_assert_cmpfloat(primitive->data[n].point.x, !=, original.data[n].point.x);
            g_assert_cmpfloat(primitive->data[n].point.y, !=, original.data[n].point.y);
        }
        g_assert_cmpint(cpml_primitive_copy_data(primitive, &original), ==, 1);
        adg_assert_isapprox(primitive->org->point.x, original.org->point.x);
        adg_assert_isapprox(primitive->org->point.y, original.org->point.y);
        for (n = 1; n < primitive->data[0].header.length; ++n) {
            adg_assert_isapprox(primitive->data[n].point.x, original.data[n].point.x);
            adg_assert_isapprox(primitive->data[n].point.y, original.data[n].point.y);
        }
        g_free(primitive);
    } while (cpml_primitive_next(&original));
}
Example #13
0
static void
_cpml_behavior_browsing(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive, primitive_copy;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    cpml_primitive_from_segment(&primitive, &segment);
    adg_assert_isapprox((primitive.org)->point.x, 0);
    adg_assert_isapprox((primitive.org)->point.y, 1);
    g_assert_cmpint((primitive.data)->header.type, ==, CPML_LINE);
    g_assert_true(cpml_primitive_next(&primitive));
    adg_assert_isapprox((primitive.org)->point.x, 3);
    adg_assert_isapprox((primitive.org)->point.y, 1);
    g_assert_cmpint((primitive.data)->header.type, ==, CPML_ARC);
    g_assert_true(cpml_primitive_next(&primitive));
    adg_assert_isapprox((primitive.org)->point.x, 6);
    adg_assert_isapprox((primitive.org)->point.y, 7);
    g_assert_cmpint((primitive.data)->header.type, ==, CPML_CURVE);
    g_assert_true(cpml_primitive_next(&primitive));
    adg_assert_isapprox((primitive.org)->point.x, -2);
    adg_assert_isapprox((primitive.org)->point.y, 2);
    g_assert_cmpint((primitive.data)->header.type, ==, CPML_CLOSE);
    g_assert_false(cpml_primitive_next(&primitive));

    cpml_primitive_reset(&primitive);
    g_assert_true(cpml_primitive_next(&primitive));
    cpml_primitive_reset(&primitive);
    cpml_primitive_reset(&primitive);
    g_assert_true(cpml_primitive_next(&primitive));
    g_assert_true(cpml_primitive_next(&primitive));
    g_assert_true(cpml_primitive_next(&primitive));
    g_assert_false(cpml_primitive_next(&primitive));

    cpml_primitive_copy(&primitive_copy, &primitive);
    g_assert_false(cpml_primitive_next(&primitive_copy));
    cpml_primitive_reset(&primitive);
    g_assert_false(cpml_primitive_next(&primitive_copy));
    cpml_primitive_reset(&primitive_copy);
    g_assert_true(cpml_primitive_next(&primitive_copy));
}
Example #14
0
static void
_cpml_sanity_from_segment(gint i)
{
    CpmlPrimitive primitive;
    CpmlSegment segment;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    switch (i) {
    case 1:
        cpml_primitive_from_segment(NULL, &segment);
        break;
    case 2:
        cpml_primitive_from_segment(&primitive, NULL);
        break;
    default:
        g_test_trap_assert_failed();
        break;
    }
}
Example #15
0
static void
_cpml_method_copy(void)
{
    CpmlSegment segment;
    CpmlPrimitive original;
    CpmlPrimitive primitive = { NULL, NULL, NULL };

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&original, &segment);

    g_assert_false(original.segment == primitive.segment);
    g_assert_false(original.org == primitive.org);
    g_assert_false(original.data == primitive.data);

    cpml_primitive_copy(&primitive, &original);

    g_assert_true(original.segment == primitive.segment);
    g_assert_true(original.org == primitive.org);
    g_assert_true(original.data == primitive.data);
}
Example #16
0
static void
_cpml_method_put_point(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlPair pair;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());

    /* Line */
    cpml_primitive_from_segment(&primitive, &segment);

    cpml_primitive_put_point(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_point(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 3);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_point(&primitive, 2, &pair);
    adg_assert_isapprox(pair.x, 3);
    adg_assert_isapprox(pair.y, 1);
    /* The negative indices are checked only against CPML_LINE */
    cpml_primitive_put_point(&primitive, -1, &pair);
    adg_assert_isapprox(pair.x, 3);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_point(&primitive, -2, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_point(&primitive, -3, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);

    /* Arc */
    cpml_primitive_next(&primitive);

    cpml_primitive_put_point(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, 3);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_point(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 4);
    adg_assert_isapprox(pair.y, 5);
    cpml_primitive_put_point(&primitive, 2, &pair);
    adg_assert_isapprox(pair.x, 6);
    adg_assert_isapprox(pair.y, 7);
    cpml_primitive_put_point(&primitive, 3, &pair);
    adg_assert_isapprox(pair.x, 6);
    adg_assert_isapprox(pair.y, 7);

    /* Curve */
    cpml_primitive_next(&primitive);

    cpml_primitive_put_point(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, 6);
    adg_assert_isapprox(pair.y, 7);
    cpml_primitive_put_point(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 8);
    adg_assert_isapprox(pair.y, 9);
    cpml_primitive_put_point(&primitive, 2, &pair);
    adg_assert_isapprox(pair.x, 10);
    adg_assert_isapprox(pair.y, 11);
    cpml_primitive_put_point(&primitive, 3, &pair);
    adg_assert_isapprox(pair.x, -2);
    adg_assert_isapprox(pair.y, 2);
    cpml_primitive_put_point(&primitive, 4, &pair);
    adg_assert_isapprox(pair.x, -2);
    adg_assert_isapprox(pair.y, 2);

    /* Close */
    cpml_primitive_next(&primitive);

    cpml_primitive_put_point(&primitive, 0, &pair);
    adg_assert_isapprox(pair.x, -2);
    adg_assert_isapprox(pair.y, 2);
    cpml_primitive_put_point(&primitive, 1, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);
    cpml_primitive_put_point(&primitive, 2, &pair);
    adg_assert_isapprox(pair.x, 0);
    adg_assert_isapprox(pair.y, 1);
}
Example #17
0
static void
_cpml_method_set_point(void)
{
    gsize data_size;
    CpmlSegment original, *segment;
    CpmlPrimitive primitive;
    CpmlPair pair, pair2;
    int equality;

    /* Work on a copy to not modify the original path data */
    cpml_segment_from_cairo(&original, (cairo_path_t *) adg_test_path());
    data_size = original.num_data * sizeof(cairo_path_data_t);
    segment = cpml_segment_deep_dup(&original);

    /* Line */
    cpml_primitive_from_segment(&primitive, segment);

    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);
    cpml_primitive_put_point(&primitive, 0, &pair);
    pair.x += 1;
    cpml_primitive_set_point(&primitive, 0, &pair);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    pair.x -= 1;
    cpml_primitive_set_point(&primitive, 0, &pair);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);
    cpml_primitive_put_point(&primitive, 1, &pair);
    pair.y += 1;
    cpml_primitive_set_point(&primitive, 1, &pair);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    /* On a CPML_LINE primitives, -1 and 1 indices are equals */
    cpml_primitive_put_point(&primitive, -1, &pair2);
    adg_assert_isapprox(pair.x, pair2.x);
    adg_assert_isapprox(pair.y, pair2.y);
    memcpy(segment->data, original.data, data_size);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);
    cpml_primitive_put_point(&primitive, 2, &pair);
    pair.x += 1;
    pair.y += 1;
    /* This should be a NOP without segfaults */
    cpml_primitive_set_point(&primitive, 2, &pair);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);

    /* From now on, memcpy() is assumed to force equality (as already
     * proved by the previous assertions) and pair2 is used as a
     * different-from-everything pair, that is setting pair2 on any
     * point will break the equality between segment->data and
     * original.data
     */
    pair2.x = 12345;
    pair2.y = 54321;

    /* Arc */
    cpml_primitive_next(&primitive);

    cpml_primitive_set_point(&primitive, 0, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 1, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 2, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 3, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);

    /* Curve */
    cpml_primitive_next(&primitive);

    cpml_primitive_set_point(&primitive, 0, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 1, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 2, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 3, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 4, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);

    /* Close */
    cpml_primitive_next(&primitive);

    cpml_primitive_set_point(&primitive, 0, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 1, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, !=, 0);
    memcpy(segment->data, original.data, data_size);
    cpml_primitive_set_point(&primitive, 2, &pair2);
    equality = memcmp(original.data, segment->data, data_size);
    g_assert_cmpint(equality, ==, 0);

    g_free(segment);
}
Example #18
0
static void
_cpml_method_get_closest_pos(void)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlPair pair;

    cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path());
    cpml_primitive_from_segment(&primitive, &segment);

    /* Line */
    pair.x = 0; pair.y = 1;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
    pair.x = 3; pair.y = 1;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
    pair.x = -1; pair.y = -1;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
    pair.x = 4; pair.y = 2;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
    pair.x = 1.5; pair.y = 0;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0.5);

    /* Arc */
    cpml_primitive_next(&primitive);
    /* TODO: not yet implemented
     * pair.x = 3; pair.y = 1;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
     * pair.x = 6; pair.y = 7;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
     * pair.x = 0; pair.y = 0;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
     * pair.x = 10; pair.y = 10;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
     */

    /* Close */
    cpml_primitive_next(&primitive);
    /* TODO: not yet implemented
     * pair.x = 6; pair.y = 7;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
     * pair.x = -2; pair.y = 2;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
     * pair.x = 10; pair.y = 10;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
     * pair.x = 0; pair.y = 0;
     * adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
     */

    /* Close */
    cpml_primitive_next(&primitive);
    pair.x = -2; pair.y = 2;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
    pair.x = 0; pair.y = 1;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
    pair.x = -3; pair.y = 3;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0);
    pair.x = 1; pair.y = 0;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 1);
    pair.x = -1; pair.y = 1.5;
    adg_assert_isapprox(cpml_primitive_get_closest_pos(&primitive, &pair), 0.5);
}
Example #19
0
static void
_cpml_method_offset(void)
{
    CpmlSegment original, *segment;
    CpmlPrimitive primitive, line, curve;
    CpmlPrimitive *backup;

    /* Work on a copy to avoid modifying the original cairo path */
    cpml_segment_from_cairo(&original, (cairo_path_t *) adg_test_path());
    segment = cpml_segment_deep_dup(&original);
    cpml_primitive_from_segment(&primitive, segment);

    /* Offsetting and de-offsetting can introduce rounding errors
     * so we use adg_assert_isapprox instead of g_assert_cmpfloat */

    /* Line */
    cpml_primitive_copy(&line, &primitive);
    cpml_primitive_offset(&primitive, 1);
    adg_assert_isapprox((primitive.org)->point.x, 0);
    adg_assert_isapprox((primitive.org)->point.y, 2);
    adg_assert_isapprox(primitive.data[1].point.x, 3);
    adg_assert_isapprox(primitive.data[1].point.y, 2);
    cpml_primitive_offset(&primitive, -1);
    adg_assert_isapprox((primitive.org)->point.x, 0);
    adg_assert_isapprox((primitive.org)->point.y, 1);
    adg_assert_isapprox(primitive.data[1].point.x, 3);
    adg_assert_isapprox(primitive.data[1].point.y, 1);

    /* Arc */
    cpml_primitive_next(&primitive);
    cpml_primitive_offset(&primitive, 1);
    adg_assert_isapprox((primitive.org)->point.x, 2.003);
    adg_assert_isapprox((primitive.org)->point.y, 0.923);
    adg_assert_isapprox(primitive.data[1].point.x, 3.156);
    adg_assert_isapprox(primitive.data[1].point.y, 5.537);
    adg_assert_isapprox(primitive.data[2].point.x, 5.463);
    adg_assert_isapprox(primitive.data[2].point.y, 7.844);
    cpml_primitive_offset(&primitive, -1);
    adg_assert_isapprox((primitive.org)->point.x, 3);
    adg_assert_isapprox((primitive.org)->point.y, 1);
    adg_assert_isapprox(primitive.data[1].point.x, 4);
    adg_assert_isapprox(primitive.data[1].point.y, 5);
    adg_assert_isapprox(primitive.data[2].point.x, 6);
    adg_assert_isapprox(primitive.data[2].point.y, 7);

    /* Curve */
    cpml_primitive_next(&primitive);
    cpml_primitive_copy(&curve, &primitive);
    /* The offset algorithm for curves is an approximation, so
     * offsetting +1 and -1 does not return the original curve.
     * Keeping a backup around to restore the original data.
     */
    backup = cpml_primitive_deep_dup(&curve);
    /* Testing different algorithms */
    cpml_curve_offset_algorithm(CPML_CURVE_OFFSET_ALGORITHM_GEOMETRICAL);
    cpml_primitive_offset(&primitive, 1);
    adg_assert_isapprox((primitive.org)->point.x, 5.293);
    adg_assert_isapprox((primitive.org)->point.y, 7.707);
    adg_assert_isapprox(primitive.data[1].point.x, 7.889);
    adg_assert_isapprox(primitive.data[1].point.y, 8.515);
    adg_assert_isapprox(primitive.data[2].point.x, 11.196);
    adg_assert_isapprox(primitive.data[2].point.y, 9.007);
    adg_assert_isapprox(primitive.data[3].point.x, -1.4);
    adg_assert_isapprox(primitive.data[3].point.y, 1.2);
    cpml_primitive_copy_data(&primitive, backup);
    cpml_curve_offset_algorithm(CPML_CURVE_OFFSET_ALGORITHM_BAIOCA);
    cpml_primitive_offset(&primitive, 1);
    adg_assert_isapprox((primitive.org)->point.x, 5.293);
    adg_assert_isapprox((primitive.org)->point.y, 7.707);
    adg_assert_isapprox(primitive.data[1].point.x, 6.901);
    adg_assert_isapprox(primitive.data[1].point.y, 9.315);
    adg_assert_isapprox(primitive.data[2].point.x, 10.806);
    adg_assert_isapprox(primitive.data[2].point.y, 10.355);
    adg_assert_isapprox(primitive.data[3].point.x, -1.4);
    adg_assert_isapprox(primitive.data[3].point.y, 1.2);
    cpml_primitive_copy_data(&primitive, backup);
    cpml_curve_offset_algorithm(CPML_CURVE_OFFSET_ALGORITHM_HANDCRAFT);
    cpml_primitive_offset(&primitive, 1);
    adg_assert_isapprox((primitive.org)->point.x, 5.293);
    adg_assert_isapprox((primitive.org)->point.y, 7.707);
    adg_assert_isapprox(primitive.data[1].point.x, -5.758);
    adg_assert_isapprox(primitive.data[1].point.y, -3.344);
    adg_assert_isapprox(primitive.data[2].point.x, 24.987);
    adg_assert_isapprox(primitive.data[2].point.y, 20.99);
    adg_assert_isapprox(primitive.data[3].point.x, -1.4);
    adg_assert_isapprox(primitive.data[3].point.y, 1.2);
    cpml_primitive_copy_data(&primitive, backup);

    g_free(backup);
    cpml_curve_offset_algorithm(CPML_CURVE_OFFSET_ALGORITHM_DEFAULT);

    /* Close: this primitive does not own data points but should
     * modify the points of the previous and next primitives */
    cpml_primitive_next(&primitive);
    cpml_primitive_offset(&primitive, 1);
    adg_assert_isapprox((curve.org)->point.x, 6);
    adg_assert_isapprox((curve.org)->point.y, 7);
    adg_assert_isapprox(curve.data[3].point.x, -1.553);
    adg_assert_isapprox(curve.data[3].point.y, 2.894);
    adg_assert_isapprox((line.org)->point.x, 0.447);
    adg_assert_isapprox((line.org)->point.y, 1.894);
    adg_assert_isapprox(line.data[1].point.x, 3);
    adg_assert_isapprox(line.data[1].point.y, 1);
    cpml_primitive_offset(&primitive, -1);
    adg_assert_isapprox((curve.org)->point.x, 6);
    adg_assert_isapprox((curve.org)->point.y, 7);
    adg_assert_isapprox(curve.data[3].point.x, -2);
    adg_assert_isapprox(curve.data[3].point.y, 2);
    adg_assert_isapprox((line.org)->point.x, 0);
    adg_assert_isapprox((line.org)->point.y, 1);
    adg_assert_isapprox(line.data[1].point.x, 3);
    adg_assert_isapprox(line.data[1].point.y, 1);

    g_free(segment);
}
Example #20
0
File: adg-path.c Project: bert/adg
static gboolean
_adg_append_operation(AdgPath *path, AdgAction action, ...)
{
    AdgPathPrivate *data;
    AdgOperation *operation;
    va_list var_args;

    data = path->data;

    if (data->last.data == NULL) {
        g_warning(_("%s: requested a '%s' operation on a path without current primitive"),
                  G_STRLOC, _adg_action_name(action));
        return FALSE;
    }

    operation = &data->operation;
    if (operation->action != ADG_ACTION_NONE) {
        g_warning(_("%s: requested a '%s' operation while a '%s' operation was active"),
                  G_STRLOC, _adg_action_name(action),
                  _adg_action_name(operation->action));
        /* XXX: http://dev.entidi.com/p/adg/issues/50/ */
        return FALSE;
    }

    va_start(var_args, action);

    switch (action) {

    case ADG_ACTION_CHAMFER:
        operation->data.chamfer.delta1 = va_arg(var_args, double);
        operation->data.chamfer.delta2 = va_arg(var_args, double);
        break;

    case ADG_ACTION_FILLET:
        operation->data.fillet.radius = va_arg(var_args, double);
        break;

    case ADG_ACTION_NONE:
        va_end(var_args);
        return TRUE;

    default:
        g_warning(_("%s: %d path operation not recognized"), G_STRLOC, action);
        va_end(var_args);
        return FALSE;
    }

    operation->action = action;
    va_end(var_args);

    if (data->last.data[0].header.type == CPML_CLOSE) {
        /* Special case: an action with the close primitive should
         * be resolved now by changing the close primitive to a
         * line-to and using it as second operand and use the first
         * primitive of the current segment as first operand */
        guint length;
        cairo_path_data_t *path_data;
        CpmlSegment segment;
        CpmlPrimitive current;

        length = data->cairo.array->len;

        /* Ensure the close path primitive is not the only data */
        g_return_val_if_fail(length > 1, FALSE);

        /* Allocate one more item once for all to accept the
         * conversion from a close to line-to primitive */
        data->cairo.array = g_array_set_size(data->cairo.array, length + 1);
        path_data = (cairo_path_data_t *) data->cairo.array->data;
        --data->cairo.array->len;

        /* Set segment and current (the first primitive of segment) */
        cpml_segment_from_cairo(&segment, _adg_read_cairo_path(path));
        while (cpml_segment_next(&segment))
            ;
        cpml_primitive_from_segment(&current, &segment);

        /* Convert close path to a line-to primitive */
        ++data->cairo.array->len;
        path_data[length - 1].header.type = CPML_LINE;
        path_data[length - 1].header.length = 2;
        path_data[length] = *current.org;

        data->last.segment = &segment;
        data->last.org = &path_data[length - 2];
        data->last.data = &path_data[length - 1];

        _adg_do_action(path, action, &current);
    }

    return TRUE;
}