Example #1
0
File: cpml-line.c Project: bert/adg
static double
get_closest_pos(const CpmlPrimitive *line, const CpmlPair *pair)
{
    CpmlPair p1_4[4];
    CpmlVector normal;
    CpmlPair dummy;
    double pos;

    cpml_primitive_put_point(line, 0, &p1_4[0]);
    cpml_primitive_put_point(line, -1, &p1_4[1]);

    normal.x = p1_4[1].x - p1_4[0].x;
    normal.y = p1_4[1].y - p1_4[0].y;
    cpml_vector_normal(&normal);

    cpml_pair_copy(&p1_4[2], pair);

    p1_4[3].x = pair->x + normal.x;
    p1_4[3].y = pair->y + normal.y;

    /* Ensure to return 0 if intersection() fails */
    pos = 0;
    /* The destination pair cannot be NULL to avoid crashes */
    intersection(p1_4, &dummy, &pos);

    /* Clamp the result to 0..1 */
    if (pos < 0)
        pos = 0;
    else if (pos > 1.)
        pos = 1.;

    return pos;
}
Example #2
0
File: cpml-line.c Project: bert/adg
static double
get_length(const CpmlPrimitive *line)
{
    CpmlPair p1, p2;

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

    return cpml_pair_distance(&p1, &p2);
}
Example #3
0
File: cpml-line.c Project: bert/adg
static void
put_vector_at(const CpmlPrimitive *line, double pos, CpmlVector *vector)
{
    CpmlPair p1, p2;

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

    vector->x = p2.x - p1.x;
    vector->y = p2.y - p1.y;
}
Example #4
0
File: cpml-line.c Project: bert/adg
static void
put_pair_at(const CpmlPrimitive *line, double pos, CpmlPair *pair)
{
    CpmlPair p1, p2;

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

    pair->x = p1.x + (p2.x - p1.x) * pos;
    pair->y = p1.y + (p2.y - p1.y) * pos;
}
Example #5
0
File: cpml-line.c Project: bert/adg
static size_t
put_intersections(const CpmlPrimitive *line, const CpmlPrimitive *primitive,
                  size_t n_dest, CpmlPair *dest)
{
    CpmlPair p1_4[4];

    cpml_primitive_put_point(line, 0, &p1_4[0]);
    cpml_primitive_put_point(line, -1, &p1_4[1]);
    cpml_primitive_put_point(primitive, 0, &p1_4[2]);
    cpml_primitive_put_point(primitive, -1, &p1_4[3]);

    return intersection(p1_4, dest, NULL) ? 1 : 0;
}
Example #6
0
File: cpml-line.c Project: bert/adg
static void
put_extents(const CpmlPrimitive *line, CpmlExtents *extents)
{
    CpmlPair p1, p2;

    extents->is_defined = 0;

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

    cpml_extents_pair_add(extents, &p1);
    cpml_extents_pair_add(extents, &p2);
}
Example #7
0
/**
 * cpml_segment_offset:
 * @segment: a #CpmlSegment
 * @offset: the offset distance
 *
 * Offsets a segment of the specified amount, that is builds a "parallel"
 * segment at the @offset distance from the original one and returns the
 * result by replacing the original @segment.
 *
 * <important>
 * <title>TODO</title>
 * <itemizedlist>
 * <listitem>Closed path are not yet managed: an elegant solution is not
 *           so obvious: use <function>cpml_close_offset</function> when
 *           will be available.</listitem>
 * <listitem>Degenerated primitives, such as lines of length 0, are not
 *           managed properly.</listitem>
 * </itemizedlist>
 * </important>
 *
 * Since: 1.0
 **/
void
cpml_segment_offset(CpmlSegment *segment, double offset)
{
    CpmlPrimitive primitive;
    CpmlPrimitive last_primitive;
    CpmlPair old_end;
    cairo_path_data_t org, *old_org;
    int first_cycle;

    cpml_primitive_from_segment(&primitive, segment);
    first_cycle = 1;

    do {
        if (! first_cycle) {
            cpml_pair_to_cairo(&old_end, &org);
            old_org = primitive.org;
            primitive.org = &org;
        }

        cpml_primitive_put_point(&primitive, -1, &old_end);
        cpml_primitive_offset(&primitive, offset);

        if (! first_cycle) {
            cpml_primitive_join(&last_primitive, &primitive);
            primitive.org = old_org;
        }

        cpml_primitive_copy(&last_primitive, &primitive);
        first_cycle = 0;
    } while (cpml_primitive_next(&primitive));
}
Example #8
0
File: cpml-arc.c Project: bert/adg
static void
put_extents(const CpmlPrimitive *arc, CpmlExtents *extents)
{
    double r, start, end;
    CpmlPair center, pair;

    extents->is_defined = 0;

    if (!cpml_arc_info(arc, &center, &r, &start, &end))
        return;

    /* Add the right quadrant point if needed */
    if (ANGLE_INCLUDED(0) || ANGLE_INCLUDED(M_PI * 2)) {
        pair.x = center.x + r;
        pair.y = center.y;
        cpml_extents_pair_add(extents, &pair);
    }

    /* Add the bottom quadrant point if needed */
    if (ANGLE_INCLUDED(M_PI_2) || ANGLE_INCLUDED(M_PI_2 * 5)) {
        pair.x = center.x;
        pair.y = center.y + r;
        cpml_extents_pair_add(extents, &pair);
    }

    /* Add the left quadrant point if needed */
    if (ANGLE_INCLUDED(M_PI)) {
        pair.x = center.x - r;
        pair.y = center.y;
        cpml_extents_pair_add(extents, &pair);
    }

    /* Add the top quadrant point if needed */
    if (ANGLE_INCLUDED(M_PI_2 * 3) || ANGLE_INCLUDED(-M_PI_2)) {
        pair.x = center.x;
        pair.y = center.y - r;
        cpml_extents_pair_add(extents, &pair);
    }

    /* Add the start point */
    cpml_primitive_put_point(arc, 0, &pair);
    cpml_extents_pair_add(extents, &pair);

    /* Add the end point */
    cpml_primitive_put_point(arc, -1, &pair);
    cpml_extents_pair_add(extents, &pair);
}
Example #9
0
File: cpml-line.c Project: bert/adg
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);
}
Example #10
0
static void
_cpml_sanity_put_point(gint i)
{
    CpmlSegment segment;
    CpmlPrimitive primitive;
    CpmlPair pair;

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

    switch (i) {
    case 1:
        cpml_primitive_put_point(NULL, 0, &pair);
        break;
    case 2:
        cpml_primitive_put_point(&primitive, 0, NULL);
        break;
    default:
        g_test_trap_assert_failed();
        break;
    }
}
Example #11
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 #12
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);
}