Exemple #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;
    }
}
Exemple #2
0
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));
}
Exemple #3
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);
}
Exemple #4
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);
}
Exemple #5
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);
}
Exemple #6
0
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;
}