263 строки
9.1 KiB
Diff
263 строки
9.1 KiB
Diff
changeset: 29338:f2a10f325734
|
|
tag: qtip
|
|
tag: tip
|
|
tag: win32-raster-mask2.patch
|
|
tag: qbase
|
|
user: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
|
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);
|