gfx/cairo/gdi-RGB24-ARGB32.patch

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial