gfx/cairo/gdi-RGB24-ARGB32.patch

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 changeset: 106848:28db6dbdd9ea
michael@0 2 tag: gdi-patch
michael@0 3 tag: qbase
michael@0 4 tag: qtip
michael@0 5 tag: tip
michael@0 6 user: Jeff Muizelaar <jmuizelaar@mozilla.com>
michael@0 7 date: Wed Sep 12 22:52:06 2012 -0400
michael@0 8 summary: Bug 788794. Use BitBlt to do SOURCE and OVER from RGB24 to ARGB32. r=nical
michael@0 9
michael@0 10 diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
michael@0 11 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c
michael@0 12 +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
michael@0 13 @@ -884,16 +884,28 @@ static cairo_int_status_t
michael@0 14 src_x, src_y,
michael@0 15 src_w, src_h,
michael@0 16 blend_function))
michael@0 17 return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(AlphaBlend)");
michael@0 18
michael@0 19 return CAIRO_STATUS_SUCCESS;
michael@0 20 }
michael@0 21
michael@0 22 +/* makes the alpha channel in a RGB24 surface 0xff */
michael@0 23 +static void
michael@0 24 +make_opaque (cairo_image_surface_t *image, cairo_rectangle_int_t src_r)
michael@0 25 +{
michael@0 26 + int x; int y;
michael@0 27 + for (y = src_r.y; y < src_r.height; y++) {
michael@0 28 + for (x = src_r.x; x < src_r.width; x++) {
michael@0 29 + image->data[y * image->stride + x*4 + 3] = 0xff;
michael@0 30 + }
michael@0 31 + }
michael@0 32 +}
michael@0 33 +
michael@0 34 static cairo_int_status_t
michael@0 35 _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src,
michael@0 36 cairo_image_surface_t *src_image,
michael@0 37 cairo_win32_surface_t *dst,
michael@0 38 cairo_rectangle_int_t src_extents,
michael@0 39 cairo_rectangle_int_t src_r,
michael@0 40 cairo_rectangle_int_t dst_r,
michael@0 41 int alpha,
michael@0 42 @@ -935,16 +947,24 @@ static cairo_int_status_t
michael@0 43 src_r.width, - (int) src_r.height,
michael@0 44 src_image->data,
michael@0 45 &bi,
michael@0 46 DIB_RGB_COLORS,
michael@0 47 SRCCOPY))
michael@0 48 return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite(StretchDIBits)");
michael@0 49 }
michael@0 50 } else if (!needs_alpha) {
michael@0 51 + if (src->format == CAIRO_FORMAT_RGB24 && dst->format == CAIRO_FORMAT_ARGB32) {
michael@0 52 + /* Because we store RGB24 & ARGB32 in the same way GDI has no way
michael@0 53 + * to ignore the alpha channel from a RGB24 source. Therefore, we set
michael@0 54 + * the alpha channel in our RGB24 source to opaque so that we can treat
michael@0 55 + * it like ARGB32. */
michael@0 56 + GdiFlush();
michael@0 57 + make_opaque(src->image, src_r);
michael@0 58 + }
michael@0 59 /* BitBlt or StretchBlt? */
michael@0 60 if (!needs_scale && (dst->flags & CAIRO_WIN32_SURFACE_CAN_BITBLT)) {
michael@0 61 if (!BitBlt (dst->dc,
michael@0 62 dst_r.x, dst_r.y,
michael@0 63 dst_r.width, dst_r.height,
michael@0 64 src->dc,
michael@0 65 src_r.x, src_r.y,
michael@0 66 SRCCOPY))
michael@0 67 @@ -1184,28 +1204,36 @@ static cairo_int_status_t
michael@0 68 }
michael@0 69 } else {
michael@0 70 needs_repeat = TRUE;
michael@0 71 }
michael@0 72
michael@0 73 /*
michael@0 74 * Operations that we can do:
michael@0 75 *
michael@0 76 + * AlphaBlend uses the following formula for alpha when not use the per-pixel alpha (AlphaFormat = 0)
michael@0 77 + * Dst.Alpha = Src.Alpha * (SCA/255.0) + Dst.Alpha * (1.0 - (SCA/255.0))
michael@0 78 + * This turns into Dst.Alpha = Src.Alpha when SCA = 255.
michael@0 79 + * (http://msdn.microsoft.com/en-us/library/aa921335.aspx)
michael@0 80 + *
michael@0 81 * RGB OVER RGB -> BitBlt (same as SOURCE)
michael@0 82 - * RGB OVER ARGB -> UNSUPPORTED (AlphaBlend treats this as a BitBlt, even with SCA 255 and no AC_SRC_ALPHA)
michael@0 83 + * RGB OVER ARGB -> Partially supported, We convert this operation into a ARGB SOURCE ARGB
michael@0 84 + * by setting the alpha values of the source to 255.
michael@0 85 * ARGB OVER ARGB -> AlphaBlend, with AC_SRC_ALPHA
michael@0 86 * ARGB OVER RGB -> AlphaBlend, with AC_SRC_ALPHA; we'll have junk in the dst A byte
michael@0 87 *
michael@0 88 * RGB OVER RGB + mask -> AlphaBlend, no AC_SRC_ALPHA
michael@0 89 - * RGB OVER ARGB + mask -> UNSUPPORTED
michael@0 90 + * RGB OVER ARGB + mask -> Partially supported, We convert this operation into a ARGB OVER ARGB + mask
michael@0 91 + * by setting the alpha values of the source to 255.
michael@0 92 * ARGB OVER ARGB + mask -> AlphaBlend, with AC_SRC_ALPHA
michael@0 93 * ARGB OVER RGB + mask -> AlphaBlend, with AC_SRC_ALPHA; junk in the dst A byte
michael@0 94 *
michael@0 95 * RGB SOURCE RGB -> BitBlt
michael@0 96 - * RGB SOURCE ARGB -> UNSUPPORTED (AlphaBlend treats this as a BitBlt, even with SCA 255 and no AC_SRC_ALPHA)
michael@0 97 + * RGB SOURCE ARGB -> Partially supported, We convert this operation into a ARGB SOURCE ARGB
michael@0 98 + * by setting the alpha values of the source to 255.
michael@0 99 * ARGB SOURCE ARGB -> BitBlt
michael@0 100 * ARGB SOURCE RGB -> BitBlt
michael@0 101 *
michael@0 102 * RGB SOURCE RGB + mask -> unsupported
michael@0 103 * RGB SOURCE ARGB + mask -> unsupported
michael@0 104 * ARGB SOURCE ARGB + mask -> unsupported
michael@0 105 * ARGB SOURCE RGB + mask -> unsupported
michael@0 106 */
michael@0 107 @@ -1222,22 +1250,32 @@ static cairo_int_status_t
michael@0 108 needs_alpha = FALSE;
michael@0 109 } else {
michael@0 110 needs_alpha = TRUE;
michael@0 111 }
michael@0 112 } else if (src_format == CAIRO_FORMAT_ARGB32 &&
michael@0 113 dst->format == CAIRO_FORMAT_RGB24)
michael@0 114 {
michael@0 115 needs_alpha = TRUE;
michael@0 116 + } else if (src_format == CAIRO_FORMAT_RGB24 &&
michael@0 117 + dst->format == CAIRO_FORMAT_ARGB32 &&
michael@0 118 + src->image)
michael@0 119 + {
michael@0 120 + if (alpha == 255) {
michael@0 121 + needs_alpha = FALSE;
michael@0 122 + } else {
michael@0 123 + needs_alpha = TRUE;
michael@0 124 + }
michael@0 125 } else {
michael@0 126 goto UNSUPPORTED;
michael@0 127 }
michael@0 128 } else if (alpha == 255 && op == CAIRO_OPERATOR_SOURCE) {
michael@0 129 if ((src_format == dst->format) ||
michael@0 130 - (src_format == CAIRO_FORMAT_ARGB32 && dst->format == CAIRO_FORMAT_RGB24))
michael@0 131 + (src_format == CAIRO_FORMAT_ARGB32 && dst->format == CAIRO_FORMAT_RGB24) ||
michael@0 132 + (src_format == CAIRO_FORMAT_RGB24 && dst->format == CAIRO_FORMAT_ARGB32 && src->image))
michael@0 133 {
michael@0 134 needs_alpha = FALSE;
michael@0 135 } else {
michael@0 136 goto UNSUPPORTED;
michael@0 137 }
michael@0 138 } else {
michael@0 139 goto UNSUPPORTED;
michael@0 140 }
michael@0 141

mercurial