static cairo_status_t
_cairo_stroker_init (cairo_stroker_t		*stroker,
		     const cairo_stroke_style_t	*stroke_style,
		     const cairo_matrix_t	*ctm,
		     const cairo_matrix_t	*ctm_inverse,
		     double			 tolerance)
{
    cairo_status_t status;

    stroker->style = *stroke_style;
    stroker->ctm = ctm;
    stroker->ctm_inverse = ctm_inverse;
    stroker->tolerance = tolerance;

    stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm);
    stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0;

    status = _cairo_pen_init (&stroker->pen,
		              stroke_style->line_width / 2.0,
			      tolerance, ctm);
    if (unlikely (status))
	return status;

    stroker->has_bounds = FALSE;

    stroker->has_current_face = FALSE;
    stroker->has_first_face = FALSE;
    stroker->has_initial_sub_path = FALSE;

    _cairo_stroker_dash_init (&stroker->dash, stroke_style);

    stroker->add_external_edge = NULL;

    return CAIRO_STATUS_SUCCESS;
}
static cairo_bool_t
_cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t	*stroker,
				 const cairo_stroke_style_t	*stroke_style,
				 const cairo_matrix_t		*ctm,
				 cairo_antialias_t		 antialias,
				 cairo_boxes_t			*boxes)
{
    /* This special-case rectilinear stroker only supports
     * miter-joined lines (not curves) and a translation-only matrix
     * (though it could probably be extended to support a matrix with
     * uniform, integer scaling).
     *
     * It also only supports horizontal and vertical line_to
     * elements. But we don't catch that here, but instead return
     * UNSUPPORTED from _cairo_rectilinear_stroker_line_to if any
     * non-rectilinear line_to is encountered.
     */
    if (stroke_style->line_join	!= CAIRO_LINE_JOIN_MITER)
	return FALSE;

    /* If the miter limit turns right angles into bevels, then we
     * can't use this optimization. Remember, the ratio is
     * 1/sin(ɸ/2). So the cutoff is 1/sin(π/4.0) or ⎷2,
     * which we round for safety. */
    if (stroke_style->miter_limit < M_SQRT2)
	return FALSE;

    //TODO PROBABLY NOT add LINE_CAP_TRIANGULAR

    if (! (stroke_style->line_cap == CAIRO_LINE_CAP_BUTT ||
	   stroke_style->line_cap == CAIRO_LINE_CAP_SQUARE))
    {
	return FALSE;
    }

    if (! _cairo_matrix_is_scale (ctm))
	return FALSE;

    stroker->stroke_style = stroke_style;
    stroker->ctm = ctm;
    stroker->antialias = antialias;

    stroker->half_line_x =
	_cairo_fixed_from_double (fabs(ctm->xx) * stroke_style->line_width / 2.0);
    stroker->half_line_y =
	_cairo_fixed_from_double (fabs(ctm->yy) * stroke_style->line_width / 2.0);

    stroker->open_sub_path = FALSE;
    stroker->segments = stroker->segments_embedded;
    stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded);
    stroker->num_segments = 0;

    _cairo_stroker_dash_init (&stroker->dash, stroke_style);

    stroker->has_bounds = FALSE;

    stroker->boxes = boxes;

    return TRUE;
}
Exemple #3
0
static cairo_status_t
_cairo_stroker_init (cairo_stroker_t		*stroker,
		     cairo_stroke_style_t	*stroke_style,
		     const cairo_matrix_t	*ctm,
		     const cairo_matrix_t	*ctm_inverse,
		     double			 tolerance,
		     cairo_traps_t		*traps)
{
    cairo_status_t status;

    stroker->style = stroke_style;
    stroker->ctm = ctm;
    stroker->ctm_inverse = ctm_inverse;
    stroker->tolerance = tolerance;
    stroker->traps = traps;

    stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm);
    stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0;

    status = _cairo_pen_init (&stroker->pen,
		              stroke_style->line_width / 2.0,
			      tolerance, ctm);
    if (unlikely (status))
	return status;

    stroker->has_current_face = FALSE;
    stroker->has_first_face = FALSE;
    stroker->has_initial_sub_path = FALSE;

    _cairo_stroker_dash_init (&stroker->dash, stroke_style);

    stroker->has_bounds = _cairo_traps_get_limit (traps, &stroker->bounds);
    if (stroker->has_bounds) {
	/* Extend the bounds in each direction to account for the maximum area
	 * we might generate trapezoids, to capture line segments that are outside
	 * of the bounds but which might generate rendering that's within bounds.
	 */
	double dx, dy;
	cairo_fixed_t fdx, fdy;

	_cairo_stroke_style_max_distance_from_path (stroker->style,
						    stroker->ctm,
						    &dx, &dy);

	fdx = _cairo_fixed_from_double (dx);
	stroker->bounds.p1.x -= fdx;
	stroker->bounds.p2.x += fdx;

	fdy = _cairo_fixed_from_double (dy);
	stroker->bounds.p1.y -= fdy;
	stroker->bounds.p2.y += fdy;
    }

    return CAIRO_STATUS_SUCCESS;
}
Exemple #4
0
static void
_cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t	*stroker,
				 cairo_stroke_style_t		*stroke_style,
				 const cairo_matrix_t		*ctm,
				 cairo_traps_t			*traps)
{
    stroker->stroke_style = stroke_style;
    stroker->ctm = ctm;

    stroker->half_line_width =
	_cairo_fixed_from_double (stroke_style->line_width / 2.0);
    stroker->traps = traps;
    stroker->open_sub_path = FALSE;
    stroker->segments = stroker->segments_embedded;
    stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded);
    stroker->num_segments = 0;

    _cairo_stroker_dash_init (&stroker->dash, stroke_style);

    stroker->has_bounds = FALSE;
}