Exemplo n.º 1
0
cairo_int_status_t
_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t	*path,
				   const cairo_stroke_style_t	*stroke_style,
				   const cairo_matrix_t	*ctm,
				   const cairo_matrix_t	*ctm_inverse,
				   double		 tolerance,
				   cairo_traps_t	*traps)
{
    cairo_int_status_t status;
    cairo_polygon_t polygon;

    _cairo_polygon_init (&polygon, traps->limits, traps->num_limits);
    status = _cairo_path_fixed_stroke_to_polygon (path,
						  stroke_style,
						  ctm,
						  ctm_inverse,
						  tolerance,
						  &polygon);
    if (unlikely (status))
	goto BAIL;

    status = _cairo_polygon_status (&polygon);
    if (unlikely (status))
	goto BAIL;

    status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon,
							CAIRO_FILL_RULE_WINDING);

BAIL:
    _cairo_polygon_fini (&polygon);

    return status;
}
Exemplo n.º 2
0
cairo_status_t
_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t	*path,
				  const cairo_stroke_style_t	*stroke_style,
				  const cairo_matrix_t		*ctm,
				  const cairo_matrix_t		*ctm_inverse,
				  double			 tolerance,
				  cairo_rectangle_int_t		*extents)
{
    cairo_polygon_t polygon;
    cairo_status_t status;
    cairo_stroke_style_t style;

    /* When calculating extents for vector surfaces, ensure lines thinner
     * than the fixed point resolution are not optimized away. */
    double min_line_width = _cairo_fixed_to_double (CAIRO_FIXED_EPSILON*2);
    if (stroke_style->line_width < min_line_width)
    {
	style = *stroke_style;
	style.line_width = min_line_width;
	stroke_style = &style;
    }

    _cairo_polygon_init (&polygon, NULL, 0);
    status = _cairo_path_fixed_stroke_to_polygon (path,
						  stroke_style,
						  ctm, ctm_inverse,
						  tolerance,
						  &polygon);
    _cairo_box_round_to_rectangle (&polygon.extents, extents);
    _cairo_polygon_fini (&polygon);

    return status;
}
Exemplo n.º 3
0
static cairo_int_status_t
_cairo_spans_compositor_stroke (const cairo_compositor_t	*_compositor,
				cairo_composite_rectangles_t	 *extents,
				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_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
    cairo_int_status_t status;

    status = CAIRO_INT_STATUS_UNSUPPORTED;
    if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
	cairo_boxes_t boxes;

	_cairo_boxes_init (&boxes);
	if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask))
	    _cairo_boxes_limit (&boxes,
				extents->clip->boxes,
				extents->clip->num_boxes);

	status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
								style,
								ctm,
								antialias,
								&boxes);
	if (likely (status == CAIRO_INT_STATUS_SUCCESS))
	    status = clip_and_composite_boxes (compositor, extents, &boxes);
	_cairo_boxes_fini (&boxes);
    }

    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	cairo_polygon_t polygon;

	if (extents->mask.width  > extents->unbounded.width ||
	    extents->mask.height > extents->unbounded.height)
	{
	    _cairo_polygon_init_with_clip (&polygon, extents->clip);
	}
	else
	{
	    _cairo_polygon_init_with_clip (&polygon, NULL);
	}
	status = _cairo_path_fixed_stroke_to_polygon (path,
						      style,
						      ctm, ctm_inverse,
						      tolerance,
						      &polygon);
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
	    status = clip_and_composite_polygon (compositor, extents, &polygon,
						 CAIRO_FILL_RULE_WINDING,
						 antialias);
	}
	_cairo_polygon_fini (&polygon);
    }

    return status;
}
Exemplo n.º 4
0
cairo_status_t
_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t	*path,
                                  const cairo_stroke_style_t	*stroke_style,
                                  const cairo_matrix_t		*ctm,
                                  const cairo_matrix_t		*ctm_inverse,
                                  double			 tolerance,
                                  cairo_rectangle_int_t		*extents)
{
    cairo_polygon_t polygon;
    cairo_status_t status;

    _cairo_polygon_init (&polygon, NULL, 0);
    status = _cairo_path_fixed_stroke_to_polygon (path,
             stroke_style,
             ctm, ctm_inverse,
             tolerance,
             &polygon);
    _cairo_box_round_to_rectangle (&polygon.extents, extents);
    _cairo_polygon_fini (&polygon);

    return status;
}
Exemplo n.º 5
0
static cairo_int_status_t
_cairo_spans_compositor_stroke (const cairo_compositor_t	*_compositor,
				cairo_composite_rectangles_t	 *extents,
				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_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
    cairo_int_status_t status;

    TRACE_ (_cairo_debug_print_path (stderr, path));

    status = CAIRO_INT_STATUS_UNSUPPORTED;
    if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
	cairo_boxes_t boxes;

	_cairo_boxes_init (&boxes);
	if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask))
	    _cairo_boxes_limit (&boxes,
				extents->clip->boxes,
				extents->clip->num_boxes);

	status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
								style,
								ctm,
								antialias,
								&boxes);
	if (likely (status == CAIRO_INT_STATUS_SUCCESS))
	    status = clip_and_composite_boxes (compositor, extents, &boxes);
	_cairo_boxes_fini (&boxes);
    }

    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	cairo_polygon_t polygon;
	cairo_fill_rule_t fill_rule = CAIRO_FILL_RULE_WINDING;

	if (extents->mask.width  > extents->unbounded.width ||
	    extents->mask.height > extents->unbounded.height)
	{
	    cairo_box_t limits;
	    _cairo_box_from_rectangle (&limits, &extents->unbounded);
	    _cairo_polygon_init (&polygon, &limits, 1);
	}
	else
	{
	    _cairo_polygon_init (&polygon, NULL, 0);
	}
	status = _cairo_path_fixed_stroke_to_polygon (path,
						      style,
						      ctm, ctm_inverse,
						      tolerance,
						      &polygon);
	TRACE_ (_cairo_debug_print_polygon (stderr, &polygon));
	if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
	    status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
							  extents->clip->boxes,
							  extents->clip->num_boxes);
	}
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
	    cairo_clip_t *saved_clip = extents->clip;

	    if (extents->is_bounded) {
		extents->clip = _cairo_clip_copy_path (extents->clip);
		extents->clip = _cairo_clip_intersect_box(extents->clip,
							  &polygon.extents);
	    }

	    status = clip_and_composite_polygon (compositor, extents, &polygon,
						 fill_rule, antialias);

	    if (extents->is_bounded) {
		_cairo_clip_destroy (extents->clip);
		extents->clip = saved_clip;
	    }
	}
	_cairo_polygon_fini (&polygon);
    }

    return status;
}