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; }
void _cairo_boxes_init_with_clip (cairo_boxes_t *boxes, cairo_clip_t *clip) { _cairo_boxes_init (boxes); if (clip) _cairo_boxes_limit (boxes, clip->boxes, clip->num_boxes); }
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; }
static cairo_int_status_t _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor, cairo_composite_rectangles_t *extents, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias) { const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor; cairo_int_status_t status; TRACE((stderr, "%s op=%d, antialias=%d\n", __FUNCTION__, extents->op, antialias)); status = CAIRO_INT_STATUS_UNSUPPORTED; if (_cairo_path_fixed_fill_is_rectilinear (path)) { cairo_boxes_t boxes; TRACE((stderr, "%s - rectilinear\n", __FUNCTION__)); _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_fill_rectilinear_to_boxes (path, fill_rule, 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; TRACE((stderr, "%s - polygon\n", __FUNCTION__)); if (extents->mask.width > extents->unbounded.width || extents->mask.height > extents->unbounded.height) { cairo_box_t limits; TRACE((stderr, "%s - clipping to bounds\n", __FUNCTION__)); _cairo_box_from_rectangle (&limits, &extents->unbounded); _cairo_polygon_init (&polygon, &limits, 1); } else { _cairo_polygon_init (&polygon, NULL, 0); } status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) { TRACE((stderr, "%s - polygon intersect with %d clip boxes\n", __FUNCTION__, extents->clip->num_boxes)); 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) { TRACE((stderr, "%s - polygon discard clip boxes\n", __FUNCTION__)); 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); TRACE((stderr, "%s - polygon status=%d\n", __FUNCTION__, status)); } return status; }
static cairo_int_status_t _cairo_spans_compositor_fill (const cairo_compositor_t *_compositor, cairo_composite_rectangles_t *extents, const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, 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_fill_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_fill_rectilinear_to_boxes (path, fill_rule, 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_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_fill_to_polygon (path, tolerance, &polygon); if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule, extents->clip->boxes, extents->clip->num_boxes); } if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { if (extents->is_bounded) { if (extents->clip->boxes != &extents->clip->embedded_box) free (extents->clip->boxes); extents->clip->num_boxes = 1; extents->clip->boxes = &extents->clip->embedded_box; extents->clip->boxes[0] = polygon.extents; } status = clip_and_composite_polygon (compositor, extents, &polygon, fill_rule, antialias); } _cairo_polygon_fini (&polygon); } return status; }