Exemplo n.º 1
0
cairo_status_t
_cairo_pen_init (cairo_pen_t *pen, double radius, cairo_gstate_t *gstate)
{
    int i;
    int reflect;
    double  det;

    if (pen->num_vertices) {
	/* XXX: It would be nice to notice that the pen is already properly constructed.
	   However, this test would also have to account for possible changes in the transformation
	   matrix.
	   if (pen->radius == radius && pen->tolerance == tolerance)
	   return CAIRO_STATUS_SUCCESS;
	*/
	_cairo_pen_fini (pen);
    }

    pen->radius = radius;
    pen->tolerance = gstate->tolerance;

    _cairo_matrix_compute_determinant (&gstate->ctm, &det);
    if (det >= 0) {
	reflect = 0;
    } else {
	reflect = 1;
    }

    pen->num_vertices = _cairo_pen_vertices_needed (gstate->tolerance,
						    radius,
						    &gstate->ctm);
    
    pen->vertices = malloc (pen->num_vertices * sizeof (cairo_pen_vertex_t));
    if (pen->vertices == NULL) {
	return CAIRO_STATUS_NO_MEMORY;
    }

    /*
     * Compute pen coordinates.  To generate the right ellipse, compute points around
     * a circle in user space and transform them to device space.  To get a consistent
     * orientation in device space, flip the pen if the transformation matrix
     * is reflecting
     */
    for (i=0; i < pen->num_vertices; i++) {
	double theta = 2 * M_PI * i / (double) pen->num_vertices;
	double dx = radius * cos (reflect ? -theta : theta);
	double dy = radius * sin (reflect ? -theta : theta);
	cairo_pen_vertex_t *v = &pen->vertices[i];
	cairo_matrix_transform_distance (&gstate->ctm, &dx, &dy);
	v->point.x = _cairo_fixed_from_double (dx);
	v->point.y = _cairo_fixed_from_double (dy);
    }

    _cairo_pen_compute_slopes (pen);

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 2
0
cairo_status_t
_cairo_pen_init (cairo_pen_t	*pen,
		 double		 radius,
		 double		 tolerance,
		 const cairo_matrix_t	*ctm)
{
    int i;
    int reflect;

    if (CAIRO_INJECT_FAULT ())
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));

    pen->radius = radius;
    pen->tolerance = tolerance;

    reflect = _cairo_matrix_compute_determinant (ctm) < 0.;

    pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
						    radius,
						    ctm);

    if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
	pen->vertices = _cairo_malloc_ab (pen->num_vertices,
					  sizeof (cairo_pen_vertex_t));
	if (unlikely (pen->vertices == NULL))
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    } else {
	pen->vertices = pen->vertices_embedded;
    }

    /*
     * Compute pen coordinates.  To generate the right ellipse, compute points around
     * a circle in user space and transform them to device space.  To get a consistent
     * orientation in device space, flip the pen if the transformation matrix
     * is reflecting
     */
    for (i=0; i < pen->num_vertices; i++) {
	cairo_pen_vertex_t *v = &pen->vertices[i];
	double theta = 2 * M_PI * i / (double) pen->num_vertices, dx, dy;
	if (reflect)
	    theta = -theta;
	dx = radius * cos (theta);
	dy = radius * sin (theta);
	cairo_matrix_transform_distance (ctm, &dx, &dy);
	v->point.x = _cairo_fixed_from_double (dx);
	v->point.y = _cairo_fixed_from_double (dy);
    }

    _cairo_pen_compute_slopes (pen);

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 3
0
cairo_int_status_t
_cairo_compositor_stroke (const cairo_compositor_t	*compositor,
              cairo_surface_t		*surface,
              cairo_operator_t		 op,
              const cairo_pattern_t		*source,
              const cairo_path_fixed_t	*path,
              const cairo_stroke_style_t	*style,
              const cairo_matrix_t		*ctm,
              const cairo_matrix_t		*ctm_inverse,
              double			 tolerance,
              cairo_antialias_t		 antialias,
              const cairo_clip_t		*clip)
{
    cairo_composite_rectangles_t extents;
    cairo_int_status_t status;

    TRACE ((stderr, "%s\n", __FUNCTION__));

    if (_cairo_pen_vertices_needed (tolerance, style->line_width/2, ctm) <= 1)
    return CAIRO_INT_STATUS_NOTHING_TO_DO;

    status = _cairo_composite_rectangles_init_for_stroke (&extents, surface,
                              op, source,
                              path, style, ctm,
                              clip);
    if (unlikely (status))
    return status;

    do {
    while (compositor->stroke == XNULL)
        compositor = compositor->delegate;

    status = compositor->stroke (compositor, &extents,
                     path, style, ctm, ctm_inverse,
                     tolerance, antialias);

    compositor = compositor->delegate;
    } while (status == CAIRO_INT_STATUS_UNSUPPORTED);

    if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
    TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
        __FUNCTION__,
        extents.unbounded.x, extents.unbounded.y,
        extents.unbounded.width, extents.unbounded.height));
    surface->damage = _cairo_damage_add_rectangle (surface->damage,
                               &extents.unbounded);
    }

    _cairo_composite_rectangles_fini (&extents);

    return status;
}
Exemplo n.º 4
0
cairo_status_t
_cairo_pen_init (cairo_pen_t	*pen,
		 double		 radius,
		 double		 tolerance,
		 cairo_matrix_t	*ctm)
{
    int i;
    int reflect;
    double  det;

    pen->radius = radius;
    pen->tolerance = tolerance;

    _cairo_matrix_compute_determinant (ctm, &det);
    if (det >= 0) {
	reflect = 0;
    } else {
	reflect = 1;
    }

    pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
						    radius,
						    ctm);

    pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t));
    if (pen->vertices == NULL) {
	return CAIRO_STATUS_NO_MEMORY;
    }

    /*
     * Compute pen coordinates.  To generate the right ellipse, compute points around
     * a circle in user space and transform them to device space.  To get a consistent
     * orientation in device space, flip the pen if the transformation matrix
     * is reflecting
     */
    for (i=0; i < pen->num_vertices; i++) {
	double theta = 2 * M_PI * i / (double) pen->num_vertices;
	double dx = radius * cos (reflect ? -theta : theta);
	double dy = radius * sin (reflect ? -theta : theta);
	cairo_pen_vertex_t *v = &pen->vertices[i];
	cairo_matrix_transform_distance (ctm, &dx, &dy);
	v->point.x = _cairo_fixed_from_double (dx);
	v->point.y = _cairo_fixed_from_double (dy);
    }

    _cairo_pen_compute_slopes (pen);

    return CAIRO_STATUS_SUCCESS;
}