1changeset: 29338:f2a10f325734 2tag: qtip 3tag: tip 4tag: win32-raster-mask2.patch 5tag: qbase 6user: Jeff Muizelaar <jmuizelaar@mozilla.com> 7date: Mon Jun 22 14:26:07 2009 -0400 8summary: imported patch win32-raster-mask2.patch 9 10diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c 11--- a/gfx/cairo/cairo/src/cairo-image-surface.c 12+++ b/gfx/cairo/cairo/src/cairo-image-surface.c 13@@ -1232,27 +1232,27 @@ typedef struct _cairo_image_surface_span 14 cairo_composite_rectangles_t composite_rectangles; 15 } cairo_image_surface_span_renderer_t; 16 17-static cairo_status_t 18-_cairo_image_surface_span_renderer_render_row ( 19- void *abstract_renderer, 20+void 21+_cairo_image_surface_span_render_row ( 22 int y, 23 const cairo_half_open_span_t *spans, 24- unsigned num_spans) 25+ unsigned num_spans, 26+ cairo_image_surface_t *mask, 27+ const cairo_composite_rectangles_t *rects) 28 { 29- cairo_image_surface_span_renderer_t *renderer = abstract_renderer; 30- int xmin = renderer->composite_rectangles.mask.x; 31- int xmax = xmin + renderer->composite_rectangles.width; 32+ int xmin = rects->mask.x; 33+ int xmax = xmin + rects->width; 34 uint8_t *row; 35 int prev_x = xmin; 36 int prev_alpha = 0; 37 unsigned i; 38 39 /* Make sure we're within y-range. */ 40- y -= renderer->composite_rectangles.mask.y; 41- if (y < 0 || y >= renderer->composite_rectangles.height) 42+ y -= rects->mask.y; 43+ if (y < 0 || y >= rects->height) 44 return CAIRO_STATUS_SUCCESS; 45 46- row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin; 47+ row = (uint8_t*)(mask->data) + y*(size_t)mask->stride - xmin; 48 49 /* Find the first span within x-range. */ 50 for (i=0; i < num_spans && spans[i].x < xmin; i++) {} 51@@ -1286,7 +1286,17 @@ _cairo_image_surface_span_renderer_rende 52 if (prev_alpha != 0 && prev_x < xmax) { 53 memset(row + prev_x, prev_alpha, xmax - prev_x); 54 } 55+} 56 57+static cairo_status_t 58+_cairo_image_surface_span_renderer_render_row ( 59+ void *abstract_renderer, 60+ int y, 61+ const cairo_half_open_span_t *spans, 62+ unsigned num_spans) 63+{ 64+ cairo_image_surface_span_renderer_t *renderer = abstract_renderer; 65+ _cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles); 66 return CAIRO_STATUS_SUCCESS; 67 } 68 69diff --git a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c 70--- a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c 71+++ b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c 72@@ -295,9 +295,9 @@ typedef int grid_area_t; 73 #elif GRID_XY == 15 74 # define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) 75 #elif GRID_XY == 2*256*15 76-# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9) 77+# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) 78 #else 79-# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */ 80+# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) 81 #endif 82 83 #define UNROLL3(x) x x x 84diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c 85--- a/gfx/cairo/cairo/src/cairo-win32-surface.c 86+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c 87@@ -2048,6 +2048,148 @@ _cairo_win32_surface_reset (void *abstra 88 return CAIRO_STATUS_SUCCESS; 89 } 90 91+typedef struct _cairo_win32_surface_span_renderer { 92+ cairo_span_renderer_t base; 93+ 94+ cairo_operator_t op; 95+ const cairo_pattern_t *pattern; 96+ cairo_antialias_t antialias; 97+ 98+ cairo_image_surface_t *mask; 99+ cairo_win32_surface_t *dst; 100+ 101+ cairo_composite_rectangles_t composite_rectangles; 102+} cairo_win32_surface_span_renderer_t; 103+ 104+static cairo_status_t 105+_cairo_win32_surface_span_renderer_render_row ( 106+ void *abstract_renderer, 107+ int y, 108+ const cairo_half_open_span_t *spans, 109+ unsigned num_spans) 110+{ 111+ cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; 112+ _cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles); 113+ return CAIRO_STATUS_SUCCESS; 114+} 115+ 116+static void 117+_cairo_win32_surface_span_renderer_destroy (void *abstract_renderer) 118+{ 119+ cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; 120+ if (!renderer) return; 121+ 122+ if (renderer->mask != NULL) 123+ cairo_surface_destroy (&renderer->mask->base); 124+ 125+ free (renderer); 126+} 127+ 128+static cairo_status_t 129+_cairo_win32_surface_span_renderer_finish (void *abstract_renderer) 130+{ 131+ cairo_win32_surface_span_renderer_t *renderer = abstract_renderer; 132+ cairo_status_t status = CAIRO_STATUS_SUCCESS; 133+ 134+ if (renderer->pattern == NULL || renderer->mask == NULL) 135+ return CAIRO_STATUS_SUCCESS; 136+ 137+ status = cairo_surface_status (&renderer->mask->base); 138+ if (status == CAIRO_STATUS_SUCCESS) { 139+ cairo_composite_rectangles_t *rects = &renderer->composite_rectangles; 140+ cairo_win32_surface_t *dst = renderer->dst; 141+ cairo_pattern_t *mask_pattern = cairo_pattern_create_for_surface (&renderer->mask->base); 142+ /* composite onto the image surface directly if we can */ 143+ if (dst->image) { 144+ GdiFlush(); 145+ 146+ status = dst->image->backend->composite (renderer->op, 147+ renderer->pattern, mask_pattern, dst->image, 148+ rects->src.x, 149+ rects->src.y, 150+ 0, 0, /* mask.x, mask.y */ 151+ rects->dst.x, rects->dst.y, 152+ rects->width, rects->height); 153+ } else { 154+ /* otherwise go through the fallback_composite path which 155+ * will do the appropriate surface acquisition */ 156+ status = _cairo_surface_fallback_composite ( 157+ renderer->op, 158+ renderer->pattern, mask_pattern, dst, 159+ rects->src.x, 160+ rects->src.y, 161+ 0, 0, /* mask.x, mask.y */ 162+ rects->dst.x, rects->dst.y, 163+ rects->width, rects->height); 164+ } 165+ cairo_pattern_destroy (mask_pattern); 166+ 167+ } 168+ if (status != CAIRO_STATUS_SUCCESS) 169+ return _cairo_span_renderer_set_error (abstract_renderer, 170+ status); 171+ return CAIRO_STATUS_SUCCESS; 172+} 173+ 174+static cairo_bool_t 175+_cairo_win32_surface_check_span_renderer (cairo_operator_t op, 176+ const cairo_pattern_t *pattern, 177+ void *abstract_dst, 178+ cairo_antialias_t antialias, 179+ const cairo_composite_rectangles_t *rects) 180+{ 181+ (void) op; 182+ (void) pattern; 183+ (void) abstract_dst; 184+ (void) antialias; 185+ (void) rects; 186+ return TRUE; 187+} 188+ 189+static cairo_span_renderer_t * 190+_cairo_win32_surface_create_span_renderer (cairo_operator_t op, 191+ const cairo_pattern_t *pattern, 192+ void *abstract_dst, 193+ cairo_antialias_t antialias, 194+ const cairo_composite_rectangles_t *rects) 195+{ 196+ cairo_win32_surface_t *dst = abstract_dst; 197+ cairo_win32_surface_span_renderer_t *renderer 198+ = calloc(1, sizeof(*renderer)); 199+ cairo_status_t status; 200+ int width = rects->width; 201+ int height = rects->height; 202+ 203+ if (renderer == NULL) 204+ return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); 205+ 206+ renderer->base.destroy = _cairo_win32_surface_span_renderer_destroy; 207+ renderer->base.finish = _cairo_win32_surface_span_renderer_finish; 208+ renderer->base.render_row = 209+ _cairo_win32_surface_span_renderer_render_row; 210+ renderer->op = op; 211+ renderer->pattern = pattern; 212+ renderer->antialias = antialias; 213+ renderer->dst = dst; 214+ 215+ renderer->composite_rectangles = *rects; 216+ 217+ /* TODO: support rendering to A1 surfaces (or: go add span 218+ * compositing to pixman.) */ 219+ renderer->mask = (cairo_image_surface_t *) 220+ cairo_image_surface_create (CAIRO_FORMAT_A8, 221+ width, height); 222+ 223+ status = cairo_surface_status (&renderer->mask->base); 224+ 225+ if (status != CAIRO_STATUS_SUCCESS) { 226+ _cairo_win32_surface_span_renderer_destroy (renderer); 227+ return _cairo_span_renderer_create_in_error (status); 228+ } 229+ return &renderer->base; 230+} 231+ 232+ 233 static const cairo_surface_backend_t cairo_win32_surface_backend = { 234 CAIRO_SURFACE_TYPE_WIN32, 235 _cairo_win32_surface_create_similar, 236@@ -2060,8 +2202,8 @@ static const cairo_surface_backend_t cai 237 _cairo_win32_surface_composite, 238 _cairo_win32_surface_fill_rectangles, 239 NULL, /* composite_trapezoids */ 240- NULL, /* create_span_renderer */ 241- NULL, /* check_span_renderer */ 242+ _cairo_win32_surface_create_span_renderer, 243+ _cairo_win32_surface_check_span_renderer, 244 NULL, /* copy_page */ 245 NULL, /* show_page */ 246 _cairo_win32_surface_set_clip_region, 247diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h 248--- a/gfx/cairo/cairo/src/cairoint.h 249+++ b/gfx/cairo/cairo/src/cairoint.h 250@@ -2193,6 +2193,12 @@ _cairo_image_surface_set_clip_region (vo 251 cairo_private cairo_image_surface_t * 252 _cairo_image_surface_coerce (cairo_image_surface_t *surface, 253 cairo_format_t format); 254+cairo_private void 255+_cairo_image_surface_span_render_row (int y, 256+ const cairo_half_open_span_t *spans, 257+ unsigned num_spans, 258+ cairo_image_surface_t *mask, 259+ const cairo_composite_rectangles_t *rects); 260 261 cairo_private cairo_image_transparency_t 262 _cairo_image_analyze_transparency (cairo_image_surface_t *image); 263