From cebb418a32e9ab0911d04bb76e0ff3feade22a40 Mon Sep 17 00:00:00 2001 From: Henry Song Date: Fri, 7 Oct 2011 15:34:13 -0700 Subject: [PATCH 4/4] cairo-gl-msaa-compositor: Support for solid color strokes. Add support for basic solid color strokes using the fixed path stroke shaper. Currently components of the stroke overlap, but that will be handled in the following patch. --- src/cairo-gl-composite.c | 17 +++++- src/cairo-gl-msaa-compositor.c | 128 +++++++++++++++++++++++++++++++++++++++- src/cairo-gl-private.h | 7 ++- 3 files changed, 148 insertions(+), 4 deletions(-) diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index 10d2e4a..b394e30 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -791,7 +791,7 @@ _cairo_gl_composite_init (cairo_gl_composite_t *setup, static void _cairo_gl_composite_emit_tristrip_vertex (cairo_gl_context_t *ctx, - cairo_point_t *point) + const cairo_point_t *point) { GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; @@ -843,7 +843,7 @@ _cairo_gl_composite_append_vertex_indices (cairo_gl_context_t *ctx, cairo_int_status_t _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, - cairo_point_t quad[4]) + const cairo_point_t quad[4]) { _cairo_gl_composite_prepare_buffer (ctx, 4); @@ -859,6 +859,19 @@ _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, return _cairo_gl_composite_append_vertex_indices (ctx, 4); } +cairo_int_status_t +_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + const cairo_point_t triangle[3]) +{ + _cairo_gl_composite_prepare_buffer (ctx, 3); + + _cairo_gl_composite_emit_tristrip_vertex (ctx, &triangle[0]); + _cairo_gl_composite_emit_tristrip_vertex (ctx, &triangle[1]); + _cairo_gl_composite_emit_tristrip_vertex (ctx, &triangle[2]); + return _cairo_gl_composite_append_vertex_indices (ctx, 3); +} + cairo_status_t _cairo_gl_composite_begin_tristrip (cairo_gl_composite_t *setup, cairo_gl_context_t **ctx_out) diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c index 94c24a6..96f2253 100644 --- a/src/cairo-gl-msaa-compositor.c +++ b/src/cairo-gl-msaa-compositor.c @@ -47,6 +47,11 @@ #include "cairo-gl-private.h" #include "cairo-traps-private.h" +struct _tristrip_composite_info { + cairo_gl_context_t *ctx; + cairo_gl_composite_t *setup; +}; + static cairo_int_status_t _draw_trap (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, @@ -93,6 +98,33 @@ _draw_traps (cairo_gl_context_t *ctx, return status; } +static cairo_int_status_t +_draw_triangle_fan (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + const cairo_point_t *midpt, + const cairo_point_t *points, + int npoints) +{ + int i; + + /* Our strategy here is to not even try to build a triangle fan, but to + draw each triangle as if it was an unconnected member of a triangle strip. */ + for (i = 1; i < npoints; i++) { + cairo_status_t status; + cairo_point_t triangle[3]; + + triangle[0] = *midpt; + triangle[1] = points[i - 1]; + triangle[2] = points[i]; + + status = _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle); + if (unlikely (status)) + return status; + } + + return CAIRO_STATUS_SUCCESS; +} + static cairo_status_t _draw_clip (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, @@ -181,6 +213,32 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, return CAIRO_INT_STATUS_UNSUPPORTED; } +static cairo_status_t +_stroke_shaper_add_triangle (void *closure, + const cairo_point_t triangle[3]) +{ + struct _tristrip_composite_info *info = closure; + return _cairo_gl_composite_emit_triangle_as_tristrip (info->ctx, info->setup, triangle); +} + +static cairo_status_t +_stroke_shaper_add_triangle_fan (void *closure, + const cairo_point_t *midpoint, + const cairo_point_t *points, + int npoints) +{ + struct _tristrip_composite_info *info = closure; + return _draw_triangle_fan (info->ctx, info->setup, midpoint, points, npoints); +} + +static cairo_status_t +_stroke_shaper_add_quad (void *closure, + const cairo_point_t quad[4]) +{ + struct _tristrip_composite_info *info = closure; + return _cairo_gl_composite_emit_quad_as_tristrip (info->ctx, info->setup, quad); +} + static cairo_int_status_t _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor, cairo_composite_rectangles_t *extents, @@ -191,7 +249,75 @@ _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor, double tolerance, cairo_antialias_t antialias) { - return CAIRO_INT_STATUS_UNSUPPORTED; + cairo_status_t status; + cairo_gl_composite_t setup; + cairo_gl_surface_t *dst = (cairo_gl_surface_t *) extents->surface; + cairo_gl_context_t *ctx = NULL; + struct _tristrip_composite_info info; + + if (antialias != CAIRO_ANTIALIAS_NONE) { + return compositor->delegate->stroke (compositor->delegate, + extents, + path, + style, + ctm, + ctm_inverse, + tolerance, + antialias); + } + + status = _cairo_gl_composite_init (&setup, + extents->op, + dst, + FALSE, /* assume_component_alpha */ + &extents->bounded); + if (unlikely (status)) + return status; + + status = _cairo_gl_composite_set_source (&setup, + &extents->source_pattern.base, + extents->bounded.x, + extents->bounded.y, + extents->bounded.x, + extents->bounded.y, + extents->bounded.width, + extents->bounded.height); + if (unlikely (status)) + goto FINISH; + + status = _cairo_gl_composite_begin_tristrip (&setup, &ctx); + if (unlikely (status)) + goto FINISH; + + status = _draw_clip_to_stencil_buffer (ctx, &setup, extents->clip); + if (unlikely (status)) + goto FINISH; + + info.ctx = ctx; + info.setup = &setup; + status = _cairo_path_fixed_stroke_to_shaper ((cairo_path_fixed_t *) path, + style, + ctm, + ctm_inverse, + tolerance, + _stroke_shaper_add_triangle, + _stroke_shaper_add_triangle_fan, + _stroke_shaper_add_quad, + &info); + if (unlikely (status)) + goto FINISH; + + _cairo_gl_composite_flush (ctx); + +FINISH: + _cairo_gl_composite_fini (&setup); + + if (ctx) { + _disable_stencil_buffer (); + status = _cairo_gl_context_release (ctx, status); + } + + return status; } static cairo_int_status_t diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 91fb40b..7c0d03c 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -508,7 +508,12 @@ _cairo_gl_composite_begin_tristrip (cairo_gl_composite_t *setup, cairo_int_status_t _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, - cairo_point_t quad[4]); + const cairo_point_t quad[4]); + +cairo_int_status_t +_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + const cairo_point_t triangle[3]); cairo_private void _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx, -- 1.7.4.1