static cairo_bool_t recording_pattern_contains_sample (const cairo_pattern_t *pattern, const cairo_rectangle_int_t *sample) { cairo_recording_surface_t *surface; if (! is_recording_pattern (pattern)) return FALSE; if (pattern->extend == CAIRO_EXTEND_NONE) return TRUE; surface = (cairo_recording_surface_t *) unwrap_source (pattern); if (surface->unbounded) return TRUE; return _cairo_rectangle_contains_rectangle (&surface->extents, sample); }
static cairo_bool_t _cairo_clip_contains_rectangle_box (const cairo_clip_t *clip, const cairo_rectangle_int_t *rect, const cairo_box_t *box) { int i; /* clip == NULL means no clip, so the clip contains everything */ if (clip == NULL) return TRUE; if (_cairo_clip_is_all_clipped (clip)) return FALSE; /* If we have a non-trivial path, just say no */ if (clip->path) return FALSE; if (! _cairo_rectangle_contains_rectangle (&clip->extents, rect)) return FALSE; if (clip->num_boxes == 0) return TRUE; /* Check for a clip-box that wholly contains the rectangle */ for (i = 0; i < clip->num_boxes; i++) { if (box->p1.x >= clip->boxes[i].p1.x && box->p1.y >= clip->boxes[i].p1.y && box->p2.x <= clip->boxes[i].p2.x && box->p2.y <= clip->boxes[i].p2.y) { return TRUE; } } return FALSE; }
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 ((stderr, "%s\n", __FUNCTION__)); TRACE_ (_cairo_debug_print_path (stderr, path)); TRACE_ (_cairo_debug_print_clip (stderr, extents->clip)); 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 (! _cairo_rectangle_contains_rectangle (&extents->unbounded, &extents->mask)) { if (extents->clip->num_boxes == 1) { _cairo_polygon_init (&polygon, extents->clip->boxes, 1); } else { 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)); polygon.num_limits = 0; 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 (! _cairo_rectangle_contains_rectangle (&extents->unbounded, &extents->mask)) { TRACE((stderr, "%s - clipping to bounds\n", __FUNCTION__)); if (extents->clip->num_boxes == 1) { _cairo_polygon_init (&polygon, extents->clip->boxes, 1); } else { 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); TRACE_ (_cairo_debug_print_polygon (stderr, &polygon)); polygon.num_limits = 0; 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); } TRACE_ (_cairo_debug_print_polygon (stderr, &polygon)); 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; }