changeset: 29338:f2a10f325734 tag: qtip tag: tip tag: win32-raster-mask2.patch tag: qbase user: Jeff Muizelaar date: Mon Jun 22 14:26:07 2009 -0400 summary: imported patch win32-raster-mask2.patch diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c --- a/gfx/cairo/cairo/src/cairo-image-surface.c +++ b/gfx/cairo/cairo/src/cairo-image-surface.c @@ -1232,27 +1232,27 @@ typedef struct _cairo_image_surface_span cairo_composite_rectangles_t composite_rectangles; } cairo_image_surface_span_renderer_t; -static cairo_status_t -_cairo_image_surface_span_renderer_render_row ( - void *abstract_renderer, +void +_cairo_image_surface_span_render_row ( int y, const cairo_half_open_span_t *spans, - unsigned num_spans) + unsigned num_spans, + cairo_image_surface_t *mask, + const cairo_composite_rectangles_t *rects) { - cairo_image_surface_span_renderer_t *renderer = abstract_renderer; - int xmin = renderer->composite_rectangles.mask.x; - int xmax = xmin + renderer->composite_rectangles.width; + int xmin = rects->mask.x; + int xmax = xmin + rects->width; uint8_t *row; int prev_x = xmin; int prev_alpha = 0; unsigned i; /* Make sure we're within y-range. */ - y -= renderer->composite_rectangles.mask.y; - if (y < 0 || y >= renderer->composite_rectangles.height) + y -= rects->mask.y; + if (y < 0 || y >= rects->height) return CAIRO_STATUS_SUCCESS; - row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin; + row = (uint8_t*)(mask->data) + y*(size_t)mask->stride - xmin; /* Find the first span within x-range. */ for (i=0; i < num_spans && spans[i].x < xmin; i++) {} @@ -1286,7 +1286,17 @@ _cairo_image_surface_span_renderer_rende if (prev_alpha != 0 && prev_x < xmax) { memset(row + prev_x, prev_alpha, xmax - prev_x); } +} +static cairo_status_t +_cairo_image_surface_span_renderer_render_row ( + void *abstract_renderer, + int y, + const cairo_half_open_span_t *spans, + unsigned num_spans) +{ + cairo_image_surface_span_renderer_t *renderer = abstract_renderer; + _cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles); return CAIRO_STATUS_SUCCESS; } diff --git a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c --- a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c +++ b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c @@ -295,9 +295,9 @@ typedef int grid_area_t; #elif GRID_XY == 15 # define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) #elif GRID_XY == 2*256*15 -# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9) +# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) #else -# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */ +# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) #endif #define UNROLL3(x) x x x diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c --- a/gfx/cairo/cairo/src/cairo-win32-surface.c +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c @@ -2048,6 +2048,148 @@ _cairo_win32_surface_reset (void *abstra return CAIRO_STATUS_SUCCESS; } +typedef struct _cairo_win32_surface_span_renderer { + cairo_span_renderer_t base; + + cairo_operator_t op; + const cairo_pattern_t *pattern; + cairo_antialias_t antialias; + + cairo_image_surface_t *mask; + cairo_win32_surface_t *dst; + + cairo_composite_rectangles_t composite_rectangles; +} cairo_win32_surface_span_renderer_t; + +static cairo_status_t +_cairo_win32_surface_span_renderer_render_row ( + void *abstract_renderer, + int y, + const cairo_half_open_span_t *spans, + unsigned num_spans) +{ + cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; + _cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles); + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_win32_surface_span_renderer_destroy (void *abstract_renderer) +{ + cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; + if (!renderer) return; + + if (renderer->mask != NULL) + cairo_surface_destroy (&renderer->mask->base); + + free (renderer); +} + +static cairo_status_t +_cairo_win32_surface_span_renderer_finish (void *abstract_renderer) +{ + cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + if (renderer->pattern == NULL || renderer->mask == NULL) + return CAIRO_STATUS_SUCCESS; + + status = cairo_surface_status (&renderer->mask->base); + if (status == CAIRO_STATUS_SUCCESS) { + cairo_composite_rectangles_t *rects = &renderer->composite_rectangles; + cairo_win32_surface_t *dst = renderer->dst; + cairo_pattern_t *mask_pattern = cairo_pattern_create_for_surface (&renderer->mask->base); + /* composite onto the image surface directly if we can */ + if (dst->image) { + GdiFlush(); + + status = dst->image->backend->composite (renderer->op, + renderer->pattern, mask_pattern, dst->image, + rects->src.x, + rects->src.y, + 0, 0, /* mask.x, mask.y */ + rects->dst.x, rects->dst.y, + rects->width, rects->height); + } else { + /* otherwise go through the fallback_composite path which + * will do the appropriate surface acquisition */ + status = _cairo_surface_fallback_composite ( + renderer->op, + renderer->pattern, mask_pattern, dst, + rects->src.x, + rects->src.y, + 0, 0, /* mask.x, mask.y */ + rects->dst.x, rects->dst.y, + rects->width, rects->height); + } + cairo_pattern_destroy (mask_pattern); + + } + if (status != CAIRO_STATUS_SUCCESS) + return _cairo_span_renderer_set_error (abstract_renderer, + status); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_bool_t +_cairo_win32_surface_check_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + void *abstract_dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + (void) op; + (void) pattern; + (void) abstract_dst; + (void) antialias; + (void) rects; + return TRUE; +} + +static cairo_span_renderer_t * +_cairo_win32_surface_create_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + void *abstract_dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + cairo_win32_surface_t *dst = abstract_dst; + cairo_win32_surface_span_renderer_t *renderer + = calloc(1, sizeof(*renderer)); + cairo_status_t status; + int width = rects->width; + int height = rects->height; + + if (renderer == NULL) + return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); + + renderer->base.destroy = _cairo_win32_surface_span_renderer_destroy; + renderer->base.finish = _cairo_win32_surface_span_renderer_finish; + renderer->base.render_row = + _cairo_win32_surface_span_renderer_render_row; + renderer->op = op; + renderer->pattern = pattern; + renderer->antialias = antialias; + renderer->dst = dst; + + renderer->composite_rectangles = *rects; + + /* TODO: support rendering to A1 surfaces (or: go add span + * compositing to pixman.) */ + renderer->mask = (cairo_image_surface_t *) + cairo_image_surface_create (CAIRO_FORMAT_A8, + width, height); + + status = cairo_surface_status (&renderer->mask->base); + + if (status != CAIRO_STATUS_SUCCESS) { + _cairo_win32_surface_span_renderer_destroy (renderer); + return _cairo_span_renderer_create_in_error (status); + } + return &renderer->base; +} + + static const cairo_surface_backend_t cairo_win32_surface_backend = { CAIRO_SURFACE_TYPE_WIN32, _cairo_win32_surface_create_similar, @@ -2060,8 +2202,8 @@ static const cairo_surface_backend_t cai _cairo_win32_surface_composite, _cairo_win32_surface_fill_rectangles, NULL, /* composite_trapezoids */ - NULL, /* create_span_renderer */ - NULL, /* check_span_renderer */ + _cairo_win32_surface_create_span_renderer, + _cairo_win32_surface_check_span_renderer, NULL, /* copy_page */ NULL, /* show_page */ _cairo_win32_surface_set_clip_region, diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h --- a/gfx/cairo/cairo/src/cairoint.h +++ b/gfx/cairo/cairo/src/cairoint.h @@ -2193,6 +2193,12 @@ _cairo_image_surface_set_clip_region (vo cairo_private cairo_image_surface_t * _cairo_image_surface_coerce (cairo_image_surface_t *surface, cairo_format_t format); +cairo_private void +_cairo_image_surface_span_render_row (int y, + const cairo_half_open_span_t *spans, + unsigned num_spans, + cairo_image_surface_t *mask, + const cairo_composite_rectangles_t *rects); cairo_private cairo_image_transparency_t _cairo_image_analyze_transparency (cairo_image_surface_t *image);