mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 19:37:15 +00:00
b=579676 use the same alpha recovery code for gfxWindowsNativeDrawing and gfxXlibNativeRenderer r=roc
This commit is contained in:
parent
76cb7d7b27
commit
ec38185fe5
@ -267,7 +267,7 @@ gfxASurface::GetDeviceOffset() const
|
||||
}
|
||||
|
||||
void
|
||||
gfxASurface::Flush()
|
||||
gfxASurface::Flush() const
|
||||
{
|
||||
cairo_surface_flush(mSurface);
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ public:
|
||||
void SetDeviceOffset(const gfxPoint& offset);
|
||||
gfxPoint GetDeviceOffset() const;
|
||||
|
||||
void Flush();
|
||||
void Flush() const;
|
||||
void MarkDirty();
|
||||
void MarkDirty(const gfxRect& r);
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -41,49 +40,6 @@
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
|
||||
struct gfxAlphaRecoveryResult {
|
||||
gfxAlphaRecoveryResult()
|
||||
: uniformColor(PR_FALSE),
|
||||
uniformAlpha(PR_FALSE)
|
||||
{ }
|
||||
PRBool uniformColor;
|
||||
PRBool uniformAlpha;
|
||||
gfxFloat alpha;
|
||||
gfxFloat r, g, b;
|
||||
};
|
||||
|
||||
static void _compute_alpha_values (unsigned int *black_data,
|
||||
unsigned int *white_data,
|
||||
gfxIntSize dimensions,
|
||||
gfxAlphaRecoveryResult *result);
|
||||
|
||||
already_AddRefed<gfxImageSurface>
|
||||
gfxAlphaRecovery::RecoverAlpha (gfxImageSurface *blackSurf,
|
||||
gfxImageSurface *whiteSurf,
|
||||
gfxIntSize dimensions)
|
||||
{
|
||||
|
||||
nsRefPtr<gfxImageSurface> resultSurf;
|
||||
resultSurf = new gfxImageSurface(dimensions, gfxASurface::ImageFormatARGB32);
|
||||
|
||||
// copy blackSurf into resultSurf
|
||||
gfxContext ctx(resultSurf);
|
||||
ctx.SetSource(blackSurf);
|
||||
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx.Paint();
|
||||
|
||||
gfxAlphaRecoveryResult result;
|
||||
_compute_alpha_values ((unsigned int*) resultSurf->Data(),
|
||||
(unsigned int*) whiteSurf->Data(),
|
||||
dimensions,
|
||||
&result);
|
||||
|
||||
// XX use result, maybe return pattern, etc.
|
||||
|
||||
NS_ADDREF(resultSurf.get());
|
||||
return resultSurf.get();
|
||||
}
|
||||
|
||||
/** from cairo-xlib-utils.c, modified */
|
||||
/**
|
||||
* Given the RGB data for two image surfaces, one a source image composited
|
||||
@ -106,66 +62,89 @@ gfxAlphaRecovery::RecoverAlpha (gfxImageSurface *blackSurf,
|
||||
#define SET_ALPHA(v, a) (((v) & ~(0xFF << 24)) | ((a) << 24))
|
||||
#define GREEN_OF(v) (((v) >> 8) & 0xFF)
|
||||
|
||||
static void
|
||||
_compute_alpha_values (unsigned int *black_data,
|
||||
unsigned int *white_data,
|
||||
gfxIntSize dimensions,
|
||||
gfxAlphaRecoveryResult *result)
|
||||
/* static */ PRBool
|
||||
gfxAlphaRecovery::RecoverAlpha(gfxImageSurface* blackSurf,
|
||||
const gfxImageSurface* whiteSurf,
|
||||
Analysis* analysis)
|
||||
{
|
||||
int num_pixels = dimensions.width * dimensions.height;
|
||||
int i;
|
||||
unsigned int first;
|
||||
unsigned int deltas = 0;
|
||||
unsigned char first_alpha;
|
||||
|
||||
if (num_pixels == 0) {
|
||||
if (result) {
|
||||
result->uniformAlpha = PR_TRUE;
|
||||
result->uniformColor = PR_TRUE;
|
||||
gfxIntSize size = blackSurf->GetSize();
|
||||
|
||||
if (size != whiteSurf->GetSize() ||
|
||||
(blackSurf->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
blackSurf->Format() != gfxASurface::ImageFormatRGB24) ||
|
||||
(whiteSurf->Format() != gfxASurface::ImageFormatARGB32 &&
|
||||
whiteSurf->Format() != gfxASurface::ImageFormatRGB24))
|
||||
return PR_FALSE;
|
||||
|
||||
if (size.width == 0 || size.height == 0) {
|
||||
if (analysis) {
|
||||
analysis->uniformAlpha = PR_TRUE;
|
||||
analysis->uniformColor = PR_TRUE;
|
||||
/* whatever we put here will be true */
|
||||
result->alpha = 1.0;
|
||||
result->r = result->g = result->b = 0.0;
|
||||
analysis->alpha = 1.0;
|
||||
analysis->r = analysis->g = analysis->b = 0.0;
|
||||
}
|
||||
return;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
first_alpha = 255 - (GREEN_OF(*white_data) - GREEN_OF(*black_data));
|
||||
unsigned char* blackData = blackSurf->Data();
|
||||
unsigned char* whiteData = whiteSurf->Data();
|
||||
if (!blackData || !whiteData)
|
||||
return PR_FALSE;
|
||||
|
||||
blackSurf->Flush();
|
||||
whiteSurf->Flush();
|
||||
|
||||
PRUint32 black = *reinterpret_cast<PRUint32*>(blackData);
|
||||
PRUint32 white = *reinterpret_cast<PRUint32*>(whiteData);
|
||||
unsigned char first_alpha =
|
||||
255 - (GREEN_OF(white) - GREEN_OF(black));
|
||||
/* set the alpha value of 'first' */
|
||||
first = SET_ALPHA(*black_data, first_alpha);
|
||||
|
||||
for (i = 0; i < num_pixels; ++i) {
|
||||
unsigned int black = *black_data;
|
||||
unsigned int white = *white_data;
|
||||
unsigned char pixel_alpha = 255 - (GREEN_OF(white) - GREEN_OF(black));
|
||||
PRUint32 first = SET_ALPHA(black, first_alpha);
|
||||
|
||||
PRUint32 deltas = 0;
|
||||
for (PRInt32 i = 0; i < size.height; ++i) {
|
||||
PRUint32* blackPixel = reinterpret_cast<PRUint32*>(blackData);
|
||||
const PRUint32* whitePixel = reinterpret_cast<PRUint32*>(whiteData);
|
||||
for (PRInt32 j = 0; j < size.width; ++j) {
|
||||
black = blackPixel[j];
|
||||
white = whitePixel[j];
|
||||
unsigned char pixel_alpha =
|
||||
255 - (GREEN_OF(white) - GREEN_OF(black));
|
||||
|
||||
black = SET_ALPHA(black, pixel_alpha);
|
||||
*black_data = black;
|
||||
deltas |= (first ^ black);
|
||||
|
||||
black_data++;
|
||||
white_data++;
|
||||
black = SET_ALPHA(black, pixel_alpha);
|
||||
blackPixel[j] = black;
|
||||
deltas |= (first ^ black);
|
||||
}
|
||||
blackData += blackSurf->Stride();
|
||||
whiteData += whiteSurf->Stride();
|
||||
}
|
||||
|
||||
blackSurf->MarkDirty();
|
||||
|
||||
if (result) {
|
||||
result->uniformAlpha = (deltas >> 24) == 0;
|
||||
if (result->uniformAlpha) {
|
||||
result->alpha = first_alpha/255.0;
|
||||
if (analysis) {
|
||||
analysis->uniformAlpha = (deltas >> 24) == 0;
|
||||
analysis->uniformColor = PR_FALSE;
|
||||
if (analysis->uniformAlpha) {
|
||||
analysis->alpha = first_alpha/255.0;
|
||||
/* we only set uniformColor when the alpha is already uniform.
|
||||
it's only useful in that case ... and if the alpha was nonuniform
|
||||
then computing whether the color is uniform would require unpremultiplying
|
||||
every pixel */
|
||||
result->uniformColor = (deltas & ~(0xFF << 24)) == 0;
|
||||
if (result->uniformColor) {
|
||||
analysis->uniformColor = (deltas & ~(0xFF << 24)) == 0;
|
||||
if (analysis->uniformColor) {
|
||||
if (first_alpha == 0) {
|
||||
/* can't unpremultiply, this is OK */
|
||||
result->r = result->g = result->b = 0.0;
|
||||
analysis->r = analysis->g = analysis->b = 0.0;
|
||||
} else {
|
||||
double d_first_alpha = first_alpha;
|
||||
result->r = (first & 0xFF)/d_first_alpha;
|
||||
result->g = ((first >> 8) & 0xFF)/d_first_alpha;
|
||||
result->b = ((first >> 16) & 0xFF)/d_first_alpha;
|
||||
analysis->r = (first & 0xFF)/d_first_alpha;
|
||||
analysis->g = ((first >> 8) & 0xFF)/d_first_alpha;
|
||||
analysis->b = ((first >> 16) & 0xFF)/d_first_alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -43,13 +43,22 @@
|
||||
|
||||
class THEBES_API gfxAlphaRecovery {
|
||||
public:
|
||||
/* Given two RGB24 surfaces with the same rendering, one on a black
|
||||
* background and the other on white, return a new surface
|
||||
* that contains the contents with recovered alpha.
|
||||
struct Analysis {
|
||||
PRBool uniformColor;
|
||||
PRBool uniformAlpha;
|
||||
gfxFloat alpha;
|
||||
gfxFloat r, g, b;
|
||||
};
|
||||
|
||||
/* Given two surfaces of equal size with the same rendering, one onto a
|
||||
* black background and the other onto white, recovers alpha values from
|
||||
* the difference and sets the alpha values on the black surface.
|
||||
* The surfaces must have format RGB24 or ARGB32.
|
||||
* Returns PR_TRUE on success.
|
||||
*/
|
||||
static already_AddRefed<gfxImageSurface> RecoverAlpha (gfxImageSurface *blackSurface,
|
||||
gfxImageSurface *whiteSurface,
|
||||
gfxIntSize dimensions);
|
||||
static PRBool RecoverAlpha (gfxImageSurface *blackSurface,
|
||||
const gfxImageSurface *whiteSurface,
|
||||
Analysis *analysis = nsnull);
|
||||
};
|
||||
|
||||
#endif /* _GFXALPHARECOVERY_H_ */
|
||||
|
@ -89,20 +89,18 @@ gfxImageSurface::gfxImageSurface(unsigned char *aData, const gfxIntSize& aSize,
|
||||
}
|
||||
|
||||
gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format) :
|
||||
mSize(size), mOwnsData(PR_FALSE), mFormat(format)
|
||||
mSize(size), mOwnsData(PR_FALSE), mData(nsnull), mFormat(format)
|
||||
{
|
||||
mStride = ComputeStride();
|
||||
|
||||
if (!CheckSurfaceSize(size))
|
||||
return;
|
||||
|
||||
// if we have a zero-sized surface, just set mData to nsnull
|
||||
// if we have a zero-sized surface, just leave mData nsnull
|
||||
if (mSize.height * mStride > 0) {
|
||||
mData = (unsigned char *) calloc(mSize.height, mStride);
|
||||
if (!mData)
|
||||
return;
|
||||
} else {
|
||||
mData = nsnull;
|
||||
}
|
||||
|
||||
mOwnsData = PR_TRUE;
|
||||
|
@ -283,8 +283,14 @@ gfxWindowsNativeDrawing::PaintToContext()
|
||||
} else if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE_DONE) {
|
||||
nsRefPtr<gfxImageSurface> black = mBlackSurface->GetImageSurface();
|
||||
nsRefPtr<gfxImageSurface> white = mWhiteSurface->GetImageSurface();
|
||||
if (!gfxAlphaRecovery::RecoverAlpha(black, white)) {
|
||||
NS_ERROR("Alpha recovery failure");
|
||||
return;
|
||||
}
|
||||
nsRefPtr<gfxImageSurface> alphaSurface =
|
||||
gfxAlphaRecovery::RecoverAlpha(black, white, mTempSurfaceSize);
|
||||
new gfxImageSurface(black->Data(), black->GetSize(),
|
||||
black->Stride(),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
||||
mContext->Save();
|
||||
mContext->Translate(mNativeRect.pos);
|
||||
|
@ -42,17 +42,9 @@
|
||||
#include "gfxXlibSurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxAlphaRecovery.h"
|
||||
#include "cairo-xlib.h"
|
||||
#include "cairo-xlib-xrender.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif HAVE_SYS_INT_TYPES_H
|
||||
#include <sys/int_types.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
@ -458,119 +450,27 @@ PRBool
|
||||
gfxXlibNativeRenderer::DrawOntoTempSurface(gfxXlibSurface *tempXlibSurface,
|
||||
nsIntPoint offset)
|
||||
{
|
||||
cairo_surface_t *temp_xlib_surface = tempXlibSurface->CairoSurface();
|
||||
cairo_surface_flush (temp_xlib_surface);
|
||||
tempXlibSurface->Flush();
|
||||
/* no clipping is needed because the callback can't draw outside the native
|
||||
surface anyway */
|
||||
nsresult rv = DrawWithXlib(tempXlibSurface, offset, NULL, 0);
|
||||
cairo_surface_mark_dirty (temp_xlib_surface);
|
||||
tempXlibSurface->MarkDirty();
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_copy_xlib_surface_to_image (gfxXlibSurface *tempXlibSurface,
|
||||
cairo_format_t format,
|
||||
int width, int height,
|
||||
unsigned char **data_out)
|
||||
static already_AddRefed<gfxImageSurface>
|
||||
CopyXlibSurfaceToImage(gfxXlibSurface *tempXlibSurface,
|
||||
gfxASurface::gfxImageFormat format)
|
||||
{
|
||||
unsigned char *data;
|
||||
cairo_surface_t *result;
|
||||
cairo_t *cr;
|
||||
|
||||
*data_out = data = (unsigned char*)malloc (width*height*4);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
result = cairo_image_surface_create_for_data (data, format, width, height, width*4);
|
||||
cr = cairo_create (result);
|
||||
cairo_set_source_surface (cr, tempXlibSurface->CairoSurface(), 0, 0);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
return result;
|
||||
}
|
||||
nsRefPtr<gfxImageSurface> result =
|
||||
new gfxImageSurface(tempXlibSurface->GetSize(), format);
|
||||
|
||||
#define SET_ALPHA(v, a) (((v) & ~(0xFF << 24)) | ((a) << 24))
|
||||
#define GREEN_OF(v) (((v) >> 8) & 0xFF)
|
||||
gfxContext copyCtx(result);
|
||||
copyCtx.SetSource(tempXlibSurface);
|
||||
copyCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
copyCtx.Paint();
|
||||
|
||||
/**
|
||||
* Given the RGB data for two image surfaces, one a source image composited
|
||||
* with OVER onto a black background, and one a source image composited with
|
||||
* OVER onto a white background, reconstruct the original image data into
|
||||
* black_data.
|
||||
*
|
||||
* Consider a single color channel and a given pixel. Suppose the original
|
||||
* premultiplied color value was C and the alpha value was A. Let the final
|
||||
* on-black color be B and the final on-white color be W. All values range
|
||||
* over 0-255.
|
||||
* Then B=C and W=(255*(255 - A) + C*255)/255. Solving for A, we get
|
||||
* A=255 - (W - C). Therefore it suffices to leave the black_data color
|
||||
* data alone and set the alpha values using that simple formula. It shouldn't
|
||||
* matter what color channel we pick for the alpha computation, but we'll
|
||||
* pick green because if we went through a color channel downsample the green
|
||||
* bits are likely to be the most accurate.
|
||||
*/
|
||||
static void
|
||||
_compute_alpha_values (uint32_t *black_data,
|
||||
uint32_t *white_data,
|
||||
int width, int height,
|
||||
gfxXlibNativeRenderer::DrawOutput *analysis)
|
||||
{
|
||||
int num_pixels = width*height;
|
||||
int i;
|
||||
uint32_t first;
|
||||
uint32_t deltas = 0;
|
||||
unsigned char first_alpha;
|
||||
|
||||
if (num_pixels == 0) {
|
||||
if (analysis) {
|
||||
analysis->mUniformAlpha = True;
|
||||
analysis->mUniformColor = True;
|
||||
/* whatever we put here will be true */
|
||||
analysis->mColor = gfxRGBA(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
first_alpha = 255 - (GREEN_OF(*white_data) - GREEN_OF(*black_data));
|
||||
/* set the alpha value of 'first' */
|
||||
first = SET_ALPHA(*black_data, first_alpha);
|
||||
|
||||
for (i = 0; i < num_pixels; ++i) {
|
||||
uint32_t black = *black_data;
|
||||
uint32_t white = *white_data;
|
||||
unsigned char pixel_alpha = 255 - (GREEN_OF(white) - GREEN_OF(black));
|
||||
|
||||
black = SET_ALPHA(black, pixel_alpha);
|
||||
*black_data = black;
|
||||
deltas |= (first ^ black);
|
||||
|
||||
black_data++;
|
||||
white_data++;
|
||||
}
|
||||
|
||||
if (analysis) {
|
||||
analysis->mUniformAlpha = (deltas >> 24) == 0;
|
||||
if (analysis->mUniformAlpha) {
|
||||
analysis->mColor.a = first_alpha/255.0;
|
||||
/* we only set uniform_color when the alpha is already uniform.
|
||||
it's only useful in that case ... and if the alpha was nonuniform
|
||||
then computing whether the color is uniform would require unpremultiplying
|
||||
every pixel */
|
||||
analysis->mUniformColor = (deltas & ~(0xFF << 24)) == 0;
|
||||
if (analysis->mUniformColor) {
|
||||
if (first_alpha == 0) {
|
||||
/* can't unpremultiply, this is OK */
|
||||
analysis->mColor = gfxRGBA(0.0, 0.0, 0.0, 0.0);
|
||||
} else {
|
||||
double d_first_alpha = first_alpha;
|
||||
analysis->mColor.r = (first & 0xFF)/d_first_alpha;
|
||||
analysis->mColor.g = ((first >> 8) & 0xFF)/d_first_alpha;
|
||||
analysis->mColor.b = ((first >> 16) & 0xFF)/d_first_alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
void
|
||||
@ -578,11 +478,6 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
||||
PRUint32 flags, Screen *screen, Visual *visual,
|
||||
DrawOutput* result)
|
||||
{
|
||||
cairo_surface_t *black_image_surface;
|
||||
cairo_surface_t *white_image_surface;
|
||||
unsigned char *black_data;
|
||||
unsigned char *white_data;
|
||||
|
||||
if (result) {
|
||||
result->mSurface = NULL;
|
||||
result->mUniformAlpha = PR_FALSE;
|
||||
@ -698,61 +593,55 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, nsIntSize size,
|
||||
return;
|
||||
}
|
||||
|
||||
int width = drawingRect.width;
|
||||
int height = drawingRect.height;
|
||||
black_image_surface =
|
||||
_copy_xlib_surface_to_image (tempXlibSurface, CAIRO_FORMAT_ARGB32,
|
||||
width, height, &black_data);
|
||||
nsRefPtr<gfxImageSurface> blackImage =
|
||||
CopyXlibSurfaceToImage(tempXlibSurface, gfxASurface::ImageFormatARGB32);
|
||||
|
||||
tmpCtx->SetDeviceColor(gfxRGBA(1.0, 1.0, 1.0));
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
tmpCtx->Paint();
|
||||
DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft());
|
||||
white_image_surface =
|
||||
_copy_xlib_surface_to_image (tempXlibSurface, CAIRO_FORMAT_RGB24,
|
||||
width, height, &white_data);
|
||||
nsRefPtr<gfxImageSurface> whiteImage =
|
||||
CopyXlibSurfaceToImage(tempXlibSurface, gfxASurface::ImageFormatRGB24);
|
||||
|
||||
if (black_image_surface && white_image_surface &&
|
||||
cairo_surface_status (black_image_surface) == CAIRO_STATUS_SUCCESS &&
|
||||
cairo_surface_status (white_image_surface) == CAIRO_STATUS_SUCCESS &&
|
||||
black_data != NULL && white_data != NULL) {
|
||||
cairo_surface_flush (black_image_surface);
|
||||
cairo_surface_flush (white_image_surface);
|
||||
_compute_alpha_values ((uint32_t*)black_data, (uint32_t*)white_data, width, height, result);
|
||||
cairo_surface_mark_dirty (black_image_surface);
|
||||
|
||||
cairo_t *cr = ctx->GetCairo();
|
||||
cairo_set_source_surface (cr, black_image_surface, offset.x, offset.y);
|
||||
if (blackImage->CairoStatus() == CAIRO_STATUS_SUCCESS &&
|
||||
blackImage->CairoStatus() == CAIRO_STATUS_SUCCESS) {
|
||||
gfxAlphaRecovery::Analysis analysis;
|
||||
if (!gfxAlphaRecovery::RecoverAlpha(blackImage, whiteImage,
|
||||
result ? &analysis : nsnull))
|
||||
return;
|
||||
|
||||
ctx->SetSource(blackImage, offset);
|
||||
|
||||
/* if the caller wants to retrieve the rendered image, put it into
|
||||
a 'similar' surface, and use that as the source for the drawing right
|
||||
now. This means we always return a surface similar to the surface
|
||||
used for 'cr', which is ideal if it's going to be cached and reused.
|
||||
We do not return an image if the result has uniform color and alpha. */
|
||||
if (result && (!result->mUniformAlpha || !result->mUniformColor)) {
|
||||
cairo_surface_t *target = cairo_get_group_target (cr);
|
||||
cairo_surface_t *similar_surface =
|
||||
cairo_surface_create_similar (target, CAIRO_CONTENT_COLOR_ALPHA,
|
||||
width, height);
|
||||
cairo_t *copy_cr = cairo_create (similar_surface);
|
||||
cairo_set_source_surface (copy_cr, black_image_surface, 0.0, 0.0);
|
||||
cairo_set_operator (copy_cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (copy_cr);
|
||||
cairo_destroy (copy_cr);
|
||||
|
||||
cairo_set_source_surface (cr, similar_surface, 0.0, 0.0);
|
||||
|
||||
result->mSurface = gfxASurface::Wrap(similar_surface);
|
||||
We do not return an image if the result has uniform color (including
|
||||
alpha). */
|
||||
if (result) {
|
||||
if (analysis.uniformAlpha) {
|
||||
result->mUniformAlpha = PR_TRUE;
|
||||
result->mColor.a = analysis.alpha;
|
||||
}
|
||||
if (analysis.uniformColor) {
|
||||
result->mUniformColor = PR_TRUE;
|
||||
result->mColor.r = analysis.r;
|
||||
result->mColor.g = analysis.g;
|
||||
result->mColor.b = analysis.b;
|
||||
} else {
|
||||
result->mSurface = target->
|
||||
CreateSimilarSurface(gfxASurface::CONTENT_COLOR_ALPHA,
|
||||
gfxIntSize(size.width, size.height));
|
||||
|
||||
gfxContext copyCtx(result->mSurface);
|
||||
copyCtx.SetSource(blackImage);
|
||||
copyCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
copyCtx.Paint();
|
||||
|
||||
ctx->SetSource(result->mSurface);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_paint (cr);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
if (black_image_surface) {
|
||||
cairo_surface_destroy (black_image_surface);
|
||||
}
|
||||
if (white_image_surface) {
|
||||
cairo_surface_destroy (white_image_surface);
|
||||
}
|
||||
free (black_data);
|
||||
free (white_data);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user