Exemple #1
0
static void
_adg_do_chamfer(AdgPath *path, CpmlPrimitive *current)
{
    AdgPathPrivate *data;
    CpmlPrimitive *last;
    gdouble delta1, delta2;
    gdouble len1, len2;
    CpmlPair pair;

    data = path->data;
    last = &data->last;
    delta1 = data->operation.data.chamfer.delta1;
    len1 = cpml_primitive_get_length(last);

    if (delta1 >= len1) {
        g_warning(_("%s: first chamfer delta of %lf is greather than the available %lf length"),
                  G_STRLOC, delta1, len1);
        return;
    }

    delta2 = data->operation.data.chamfer.delta2;
    len2 = cpml_primitive_get_length(current);

    if (delta2 >= len2) {
        g_warning(_("%s: second chamfer delta of %lf is greather than the available %lf length"),
                  G_STRLOC, delta1, len1);
        return;
    }

    /* Change the end point of the last primitive */
    cpml_primitive_put_pair_at(last, 1. - delta1 / len1, &pair);
    cpml_primitive_set_point(last, -1, &pair);

    /* Change the start point of the current primitive */
    cpml_primitive_put_pair_at(current, delta2 / len2, &pair);
    cpml_primitive_set_point(current, 0, &pair);

    /* Add the chamfer line */
    data->operation.action = ADG_ACTION_NONE;
    adg_path_append(path, CPML_LINE, &pair);
}
Exemple #2
0
static void
offset(CpmlPrimitive *line, double offset)
{
    CpmlPair p1, p2;
    CpmlVector normal;

    cpml_primitive_put_point(line, 0, &p1);
    cpml_primitive_put_point(line, -1, &p2);

    put_vector_at(line, 0, &normal);
    cpml_vector_normal(&normal);
    cpml_vector_set_length(&normal, offset);

    p1.x += normal.x;
    p1.y += normal.y;
    p2.x += normal.x;
    p2.y += normal.y;

    cpml_primitive_set_point(line, 0, &p1);
    cpml_primitive_set_point(line, -1, &p2);
}
Exemple #3
0
static void
_cpml_sanity_set_point(gint i)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlPair pair = { 1, 1 };

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

    switch (i) {
    case 1:
        cpml_primitive_set_point(NULL, 1, &pair);
        break;
    case 2:
        cpml_primitive_set_point(&primitive, 1, NULL);
        break;
    default:
        g_test_trap_assert_failed();
        break;
    }
}
Exemple #4
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);
}
Exemple #5
0
static void
_adg_do_fillet(AdgPath *path, CpmlPrimitive *current)
{
    AdgPathPrivate *data;
    CpmlPrimitive *last, *current_dup, *last_dup;
    gdouble radius, offset, pos;
    CpmlPair center, vector, p[3];

    data = path->data;
    last = &data->last;
    current_dup = cpml_primitive_deep_dup(current);
    last_dup = cpml_primitive_deep_dup(last);
    radius = data->operation.data.fillet.radius;
    offset = _adg_is_convex(last_dup, current_dup) ? -radius : radius;

    /* Find the center of the fillet from the intersection between
     * the last and current primitives offseted by radius */
    cpml_primitive_offset(current_dup, offset);
    cpml_primitive_offset(last_dup, offset);
    if (cpml_primitive_put_intersections(current_dup, last_dup, 1, &center) == 0) {
        g_warning(_("%s: fillet with radius of %lf is not applicable here"),
                  G_STRLOC, radius);
        g_free(current_dup);
        g_free(last_dup);
        return;
    }

    /* Compute the start point of the fillet */
    pos = cpml_primitive_get_closest_pos(last_dup, &center);
    cpml_primitive_put_vector_at(last_dup, pos, &vector);
    cpml_vector_set_length(&vector, offset);
    cpml_vector_normal(&vector);
    p[0].x = center.x - vector.x;
    p[0].y = center.y - vector.y;

    /* Compute the mid point of the fillet */
    cpml_pair_from_cairo(&vector, current->org);
    vector.x -= center.x;
    vector.y -= center.y;
    cpml_vector_set_length(&vector, radius);
    p[1].x = center.x + vector.x;
    p[1].y = center.y + vector.y;

    /* Compute the end point of the fillet */
    pos = cpml_primitive_get_closest_pos(current_dup, &center);
    cpml_primitive_put_vector_at(current_dup, pos, &vector);
    cpml_vector_set_length(&vector, offset);
    cpml_vector_normal(&vector);
    p[2].x = center.x - vector.x;
    p[2].y = center.y - vector.y;

    g_free(current_dup);
    g_free(last_dup);

    /* Change the end point of the last primitive */
    cpml_primitive_set_point(last, -1, &p[0]);

    /* Change the start point of the current primitive */
    cpml_primitive_set_point(current, 0, &p[2]);

    /* Add the fillet arc */
    data->operation.action = ADG_ACTION_NONE;
    adg_path_append(path, CPML_ARC, &p[1], &p[2]);
}