static cairo_int_status_t _cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst, cairo_gl_context_t *ctx, int x, int y, int width, int height) { cairo_gl_composite_t setup; cairo_status_t status; _cairo_gl_composite_flush (ctx); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE, dst, FALSE, NULL); if (unlikely (status)) goto CLEANUP; _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_BLACK); status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto CLEANUP; _cairo_gl_composite_emit_rect (ctx, x, y, x + width, y + height, 0); status = _cairo_gl_context_release (ctx, status); CLEANUP: _cairo_gl_composite_fini (&setup); _cairo_gl_composite_flush (ctx); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); return status; }
void _cairo_gl_context_emit_rect (cairo_gl_context_t *ctx, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { _cairo_gl_composite_emit_rect (ctx, x1, y1, x2, y2); }
cairo_int_status_t _cairo_gl_surface_fill_rectangles (void *abstract_dst, cairo_operator_t op, const cairo_color_t *color, cairo_rectangle_int_t *rects, int num_rects) { cairo_gl_surface_t *dst = abstract_dst; cairo_solid_pattern_t solid; cairo_gl_context_t *ctx; cairo_status_t status; cairo_gl_composite_t setup; int i; status = _cairo_gl_surface_deferred_clear (dst); if (unlikely (status)) return status; status = _cairo_gl_composite_init (&setup, op, dst, FALSE, /* XXX */ NULL); if (unlikely (status)) goto CLEANUP; _cairo_pattern_init_solid (&solid, color); status = _cairo_gl_composite_set_source (&setup, &solid.base, 0, 0, 0, 0, 0, 0, FALSE); if (unlikely (status)) goto CLEANUP; status = _cairo_gl_composite_set_mask (&setup, NULL, 0, 0, 0, 0, 0, 0); if (unlikely (status)) goto CLEANUP; status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto CLEANUP; for (i = 0; i < num_rects; i++) { _cairo_gl_composite_emit_rect (ctx, rects[i].x, rects[i].y, rects[i].x + rects[i].width, rects[i].y + rects[i].height, 0); } status = _cairo_gl_context_release (ctx, status); CLEANUP: _cairo_gl_composite_fini (&setup); return status; }
static cairo_status_t _cairo_gl_render_unbounded_spans (void *abstract_renderer, int y, int height, const cairo_half_open_span_t *spans, unsigned num_spans) { cairo_gl_surface_span_renderer_t *renderer = abstract_renderer; if (y > renderer->ymin) { _cairo_gl_composite_emit_rect (renderer->ctx, renderer->xmin, renderer->ymin, renderer->xmax, y, 0); } if (num_spans == 0) { _cairo_gl_composite_emit_rect (renderer->ctx, renderer->xmin, y, renderer->xmax, y + height, 0); } else { if (spans[0].x != renderer->xmin) { _cairo_gl_composite_emit_rect (renderer->ctx, renderer->xmin, y, spans[0].x, y + height, 0); } do { _cairo_gl_composite_emit_rect (renderer->ctx, spans[0].x, y, spans[1].x, y + height, spans[0].coverage); spans++; } while (--num_spans > 1); if (spans[0].x != renderer->xmax) { _cairo_gl_composite_emit_rect (renderer->ctx, spans[0].x, y, renderer->xmax, y + height, 0); } } renderer->ymin = y + height; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_gl_finish_unbounded_spans (void *abstract_renderer) { cairo_gl_surface_span_renderer_t *renderer = abstract_renderer; if (renderer->ymax > renderer->ymin) { _cairo_gl_composite_emit_rect (renderer->ctx, renderer->xmin, renderer->ymin, renderer->xmax, renderer->ymax, 0); } return _cairo_gl_context_release (renderer->ctx, CAIRO_STATUS_SUCCESS); }
static cairo_status_t _cairo_gl_render_bounded_spans (void *abstract_renderer, int y, int height, const cairo_half_open_span_t *spans, unsigned num_spans) { cairo_gl_surface_span_renderer_t *renderer = abstract_renderer; if (num_spans == 0) return CAIRO_STATUS_SUCCESS; do { if (spans[0].coverage) { _cairo_gl_composite_emit_rect (renderer->ctx, spans[0].x, y, spans[1].x, y + height, spans[0].coverage); } spans++; } while (--num_spans > 1); return CAIRO_STATUS_SUCCESS; }
cairo_int_status_t _cairo_gl_surface_composite (cairo_operator_t op, const cairo_pattern_t *src, const cairo_pattern_t *mask, void *abstract_dst, int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, unsigned int height, cairo_region_t *clip_region) { cairo_gl_surface_t *dst = abstract_dst; cairo_gl_context_t *ctx; cairo_status_t status; cairo_gl_composite_t setup; cairo_rectangle_int_t rect = { dst_x, dst_y, width, height }; int dx, dy; status = _cairo_gl_surface_deferred_clear (dst); if (unlikely (status)) return status; if (op == CAIRO_OPERATOR_SOURCE && mask == NULL && src->type == CAIRO_PATTERN_TYPE_SURFACE && _cairo_surface_is_image (((cairo_surface_pattern_t *) src)->surface) && _cairo_matrix_is_integer_translation (&src->matrix, &dx, &dy)) { cairo_image_surface_t *image = (cairo_image_surface_t *) ((cairo_surface_pattern_t *) src)->surface; dx += src_x; dy += src_y; if (dx >= 0 && dy >= 0 && dx + width <= (unsigned int) image->width && dy + height <= (unsigned int) image->height) { status = _cairo_gl_surface_draw_image (dst, image, dx, dy, width, height, dst_x, dst_y); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; } } status = _cairo_gl_composite_init (&setup, op, dst, mask && mask->has_component_alpha, &rect); if (unlikely (status)) goto CLEANUP; status = _cairo_gl_composite_set_source (&setup, src, src_x, src_y, dst_x, dst_y, width, height); if (unlikely (status)) goto CLEANUP; status = _cairo_gl_composite_set_mask (&setup, mask, mask_x, mask_y, dst_x, dst_y, width, height); if (unlikely (status)) goto CLEANUP; status = _cairo_gl_composite_begin (&setup, &ctx); if (unlikely (status)) goto CLEANUP; if (clip_region != NULL) { int i, num_rectangles; num_rectangles = cairo_region_num_rectangles (clip_region); for (i = 0; i < num_rectangles; i++) { cairo_rectangle_int_t rect; cairo_region_get_rectangle (clip_region, i, &rect); _cairo_gl_composite_emit_rect (ctx, rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, 0); } } else { _cairo_gl_composite_emit_rect (ctx, dst_x, dst_y, dst_x + width, dst_y + height, 0); } status = _cairo_gl_context_release (ctx, status); CLEANUP: _cairo_gl_composite_fini (&setup); return status; }