diff options
author | Benjamin Otte <otte@redhat.com> | 2010-06-24 10:25:27 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-06-24 10:25:27 +0200 |
commit | a52e27986181422fa1c9e7103373c440c1492cbe (patch) | |
tree | d33fb9f2b3376477b114eae50eebf47556831bc5 | |
parent | 8ca7870acd7c5b93e1bb569c55f36f1064f533e1 (diff) |
-rw-r--r-- | src/cairo-gl-surface.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index a36d7b7a..9e796902 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -40,6 +40,7 @@ #include "cairoint.h" +#include "cairo-boxes-private.h" #include "cairo-composite-rectangles-private.h" #include "cairo-error-private.h" #include "cairo-gl-private.h" @@ -1316,6 +1317,69 @@ _cairo_gl_surface_paint (void *abstract_surface, } static cairo_int_status_t +_cairo_gl_surface_boxes (cairo_gl_surface_t *dst, + cairo_operator_t op, + const cairo_pattern_t *src, + cairo_boxes_t *boxes, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *extents, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_region_t *clip_region = NULL; + cairo_span_renderer_t *renderer; + cairo_rectangular_scan_converter_t converter; + struct _cairo_boxes_chunk *chunk; + int i; + + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) + return CAIRO_STATUS_SUCCESS; + if (unlikely (_cairo_status_is_error (status))) + return status; + + if (status == CAIRO_INT_STATUS_UNSUPPORTED) + return UNSUPPORTED ("a clip surface would be required"); + } + + if (op == CAIRO_OPERATOR_SOURCE) + return UNSUPPORTED ("SOURCE compositing doesn't work in GL"); + if (op == CAIRO_OPERATOR_CLEAR) { + op = CAIRO_OPERATOR_DEST_OUT; + src = &_cairo_pattern_white.base; + } + + _cairo_rectangular_scan_converter_init (&converter, &extents->bounded); + + for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { + const cairo_box_t *box = chunk->base; + + for (i = 0; i < chunk->count; i++) { + status = _cairo_rectangular_scan_converter_add_box (&converter, &box[i], 1); + if (unlikely (status)) + goto CLEANUP_CONVERTER; + } + } + + renderer = _cairo_surface_create_span_renderer (op, src, &dst->base, + antialias, extents, + clip_region); + + status = converter.base.generate (&converter.base, renderer); + if (unlikely (status)) + goto CLEANUP_RENDERER; + + status = renderer->finish (renderer); + + CLEANUP_RENDERER: + renderer->destroy (renderer); + CLEANUP_CONVERTER: + converter.base.destroy (&converter.base); + return status; +} + +static cairo_int_status_t _cairo_gl_surface_polygon (cairo_gl_surface_t *dst, cairo_operator_t op, const cairo_pattern_t *src, @@ -1406,6 +1470,28 @@ _cairo_gl_surface_stroke (void *abstract_surface, return status; } + if (path->is_rectilinear) { + cairo_boxes_t boxes; + + _cairo_boxes_init (&boxes); + _cairo_boxes_limit (&boxes, clip_boxes, num_boxes); + + status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, + style, + ctm, + &boxes); + if (likely (status == CAIRO_STATUS_SUCCESS)) { + status = _cairo_gl_surface_boxes (surface, op, source, + &boxes, antialias, + &extents, clip); + } + + _cairo_boxes_fini (&boxes); + + if (likely (status != CAIRO_INT_STATUS_UNSUPPORTED)) + goto OUT; + } + _cairo_polygon_init (&polygon); _cairo_polygon_limit (&polygon, clip_boxes, num_boxes); @@ -1422,6 +1508,7 @@ _cairo_gl_surface_stroke (void *abstract_surface, _cairo_polygon_fini (&polygon); + OUT: if (have_clip) _cairo_clip_fini (&local_clip); @@ -1483,6 +1570,28 @@ _cairo_gl_surface_fill (void *abstract_surface, return status; } + if (_cairo_path_fixed_is_rectilinear_fill (path)) { + cairo_boxes_t boxes; + + _cairo_boxes_init (&boxes); + _cairo_boxes_limit (&boxes, clip_boxes, num_boxes); + + status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, + fill_rule, + &boxes); + if (unlikely (status)) + goto OUT; + + status = _cairo_gl_surface_boxes (surface, op, source, + &boxes, antialias, + &extents, clip); + + _cairo_boxes_fini (&boxes); + + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + goto OUT; + } + _cairo_polygon_init (&polygon); _cairo_polygon_limit (&polygon, clip_boxes, num_boxes); @@ -1495,6 +1604,7 @@ _cairo_gl_surface_fill (void *abstract_surface, _cairo_polygon_fini (&polygon); + OUT: if (clip_boxes != boxes_stack) free (clip_boxes); |