1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/gdi-RGB24-ARGB32.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,141 @@ 1.4 +changeset: 106848:28db6dbdd9ea 1.5 +tag: gdi-patch 1.6 +tag: qbase 1.7 +tag: qtip 1.8 +tag: tip 1.9 +user: Jeff Muizelaar <jmuizelaar@mozilla.com> 1.10 +date: Wed Sep 12 22:52:06 2012 -0400 1.11 +summary: Bug 788794. Use BitBlt to do SOURCE and OVER from RGB24 to ARGB32. r=nical 1.12 + 1.13 +diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c 1.14 +--- a/gfx/cairo/cairo/src/cairo-win32-surface.c 1.15 ++++ b/gfx/cairo/cairo/src/cairo-win32-surface.c 1.16 +@@ -884,16 +884,28 @@ static cairo_int_status_t 1.17 + src_x, src_y, 1.18 + src_w, src_h, 1.19 + blend_function)) 1.20 + return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(AlphaBlend)"); 1.21 + 1.22 + return CAIRO_STATUS_SUCCESS; 1.23 + } 1.24 + 1.25 ++/* makes the alpha channel in a RGB24 surface 0xff */ 1.26 ++static void 1.27 ++make_opaque (cairo_image_surface_t *image, cairo_rectangle_int_t src_r) 1.28 ++{ 1.29 ++ int x; int y; 1.30 ++ for (y = src_r.y; y < src_r.height; y++) { 1.31 ++ for (x = src_r.x; x < src_r.width; x++) { 1.32 ++ image->data[y * image->stride + x*4 + 3] = 0xff; 1.33 ++ } 1.34 ++ } 1.35 ++} 1.36 ++ 1.37 + static cairo_int_status_t 1.38 + _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src, 1.39 + cairo_image_surface_t *src_image, 1.40 + cairo_win32_surface_t *dst, 1.41 + cairo_rectangle_int_t src_extents, 1.42 + cairo_rectangle_int_t src_r, 1.43 + cairo_rectangle_int_t dst_r, 1.44 + int alpha, 1.45 +@@ -935,16 +947,24 @@ static cairo_int_status_t 1.46 + src_r.width, - (int) src_r.height, 1.47 + src_image->data, 1.48 + &bi, 1.49 + DIB_RGB_COLORS, 1.50 + SRCCOPY)) 1.51 + return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(StretchDIBits)"); 1.52 + } 1.53 + } else if (!needs_alpha) { 1.54 ++ if (src->format == CAIRO_FORMAT_RGB24 && dst->format == CAIRO_FORMAT_ARGB32) { 1.55 ++ /* Because we store RGB24 & ARGB32 in the same way GDI has no way 1.56 ++ * to ignore the alpha channel from a RGB24 source. Therefore, we set 1.57 ++ * the alpha channel in our RGB24 source to opaque so that we can treat 1.58 ++ * it like ARGB32. */ 1.59 ++ GdiFlush(); 1.60 ++ make_opaque(src->image, src_r); 1.61 ++ } 1.62 + /* BitBlt or StretchBlt? */ 1.63 + if (!needs_scale && (dst->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT)) { 1.64 + if (!BitBlt (dst->dc, 1.65 + dst_r.x, dst_r.y, 1.66 + dst_r.width, dst_r.height, 1.67 + src->dc, 1.68 + src_r.x, src_r.y, 1.69 + SRCCOPY)) 1.70 +@@ -1184,28 +1204,36 @@ static cairo_int_status_t 1.71 + } 1.72 + } else { 1.73 + needs_repeat = TRUE; 1.74 + } 1.75 + 1.76 + /* 1.77 + * Operations that we can do: 1.78 + * 1.79 ++ * AlphaBlend uses the following formula for alpha when not use the per-pixel alpha (AlphaFormat = 0) 1.80 ++ * Dst.Alpha = Src.Alpha * (SCA/255.0) + Dst.Alpha * (1.0 - (SCA/255.0)) 1.81 ++ * This turns into Dst.Alpha = Src.Alpha when SCA = 255. 1.82 ++ * (http://msdn.microsoft.com/en-us/library/aa921335.aspx) 1.83 ++ * 1.84 + * RGB OVER RGB -> BitBlt (same as SOURCE) 1.85 +- * RGB OVER ARGB -> UNSUPPORTED (AlphaBlend treats this as a BitBlt, even with SCA 255 and no AC_SRC_ALPHA) 1.86 ++ * RGB OVER ARGB -> Partially supported, We convert this operation into a ARGB SOURCE ARGB 1.87 ++ * by setting the alpha values of the source to 255. 1.88 + * ARGB OVER ARGB -> AlphaBlend, with AC_SRC_ALPHA 1.89 + * ARGB OVER RGB -> AlphaBlend, with AC_SRC_ALPHA; we'll have junk in the dst A byte 1.90 + * 1.91 + * RGB OVER RGB + mask -> AlphaBlend, no AC_SRC_ALPHA 1.92 +- * RGB OVER ARGB + mask -> UNSUPPORTED 1.93 ++ * RGB OVER ARGB + mask -> Partially supported, We convert this operation into a ARGB OVER ARGB + mask 1.94 ++ * by setting the alpha values of the source to 255. 1.95 + * ARGB OVER ARGB + mask -> AlphaBlend, with AC_SRC_ALPHA 1.96 + * ARGB OVER RGB + mask -> AlphaBlend, with AC_SRC_ALPHA; junk in the dst A byte 1.97 + * 1.98 + * RGB SOURCE RGB -> BitBlt 1.99 +- * RGB SOURCE ARGB -> UNSUPPORTED (AlphaBlend treats this as a BitBlt, even with SCA 255 and no AC_SRC_ALPHA) 1.100 ++ * RGB SOURCE ARGB -> Partially supported, We convert this operation into a ARGB SOURCE ARGB 1.101 ++ * by setting the alpha values of the source to 255. 1.102 + * ARGB SOURCE ARGB -> BitBlt 1.103 + * ARGB SOURCE RGB -> BitBlt 1.104 + * 1.105 + * RGB SOURCE RGB + mask -> unsupported 1.106 + * RGB SOURCE ARGB + mask -> unsupported 1.107 + * ARGB SOURCE ARGB + mask -> unsupported 1.108 + * ARGB SOURCE RGB + mask -> unsupported 1.109 + */ 1.110 +@@ -1222,22 +1250,32 @@ static cairo_int_status_t 1.111 + needs_alpha = FALSE; 1.112 + } else { 1.113 + needs_alpha = TRUE; 1.114 + } 1.115 + } else if (src_format == CAIRO_FORMAT_ARGB32 && 1.116 + dst->format == CAIRO_FORMAT_RGB24) 1.117 + { 1.118 + needs_alpha = TRUE; 1.119 ++ } else if (src_format == CAIRO_FORMAT_RGB24 && 1.120 ++ dst->format == CAIRO_FORMAT_ARGB32 && 1.121 ++ src->image) 1.122 ++ { 1.123 ++ if (alpha == 255) { 1.124 ++ needs_alpha = FALSE; 1.125 ++ } else { 1.126 ++ needs_alpha = TRUE; 1.127 ++ } 1.128 + } else { 1.129 + goto UNSUPPORTED; 1.130 + } 1.131 + } else if (alpha == 255 && op == CAIRO_OPERATOR_SOURCE) { 1.132 + if ((src_format == dst->format) || 1.133 +- (src_format == CAIRO_FORMAT_ARGB32 && dst->format == CAIRO_FORMAT_RGB24)) 1.134 ++ (src_format == CAIRO_FORMAT_ARGB32 && dst->format == CAIRO_FORMAT_RGB24) || 1.135 ++ (src_format == CAIRO_FORMAT_RGB24 && dst->format == CAIRO_FORMAT_ARGB32 && src->image)) 1.136 + { 1.137 + needs_alpha = FALSE; 1.138 + } else { 1.139 + goto UNSUPPORTED; 1.140 + } 1.141 + } else { 1.142 + goto UNSUPPORTED; 1.143 + } 1.144 +