зеркало из https://github.com/mozilla/pjs.git
canvas3d fixes for bug 396972; npotb
This commit is contained in:
Родитель
eb54eb176b
Коммит
5feeb26948
|
@ -52,39 +52,29 @@ EXPORT_LIBRARY = 0
|
||||||
IS_COMPONENT = 1
|
IS_COMPONENT = 1
|
||||||
MODULE_NAME = nsCanvas3DModule
|
MODULE_NAME = nsCanvas3DModule
|
||||||
GRE_MODULE = 1
|
GRE_MODULE = 1
|
||||||
MOZILLA_INTERNAL_API = 1
|
|
||||||
BUILD_STATIC_LIBS =
|
BUILD_STATIC_LIBS =
|
||||||
|
|
||||||
REQUIRES = \
|
REQUIRES = \
|
||||||
xpcom \
|
xpcom \
|
||||||
string \
|
string \
|
||||||
gfx \
|
unicharutil \
|
||||||
|
xpconnect \
|
||||||
|
thebes \
|
||||||
|
cairo \
|
||||||
content \
|
content \
|
||||||
|
dom \
|
||||||
|
caps \
|
||||||
|
js \
|
||||||
|
imglib2 \
|
||||||
|
necko \
|
||||||
|
gfx \
|
||||||
layout \
|
layout \
|
||||||
widget \
|
widget \
|
||||||
dom \
|
|
||||||
js \
|
|
||||||
locale \
|
locale \
|
||||||
unicharutil \
|
|
||||||
necko \
|
|
||||||
view \
|
|
||||||
pref \
|
pref \
|
||||||
docshell \
|
view \
|
||||||
xpconnect \
|
|
||||||
xuldoc \
|
|
||||||
caps \
|
|
||||||
imglib2 \
|
|
||||||
mimetype \
|
|
||||||
exthandler \
|
|
||||||
uconv \
|
|
||||||
intl \
|
|
||||||
cairo \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifdef MOZ_ENABLE_CAIRO_GFX
|
|
||||||
REQUIRES += thebes
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef MOZ_X11
|
ifdef MOZ_X11
|
||||||
EXTRA_DSO_LIBS += GL
|
EXTRA_DSO_LIBS += GL
|
||||||
endif
|
endif
|
||||||
|
@ -109,12 +99,7 @@ CPPSRCS = nsCanvas3DModule.cpp \
|
||||||
|
|
||||||
DEFINES += -DXPCOM_GLUE -DXPCOM_GLUE_USE_NSPR -DGLEW_MX -DGLEW_STATIC
|
DEFINES += -DXPCOM_GLUE -DXPCOM_GLUE_USE_NSPR -DGLEW_MX -DGLEW_STATIC
|
||||||
|
|
||||||
EXTRA_DSO_LIBS += js3250 xpcom xpcom_core unicharutil_s
|
EXTRA_DSO_LIBS += js3250 xpcom xul
|
||||||
# mozcairo mozlibpixman
|
|
||||||
|
|
||||||
ifdef MOZ_ENABLE_CAIRO_GFX
|
|
||||||
EXTRA_DSO_LDOPTS += $(DEPTH)/gfx/thebes/src/thebes.lib $(DEPTH)/gfx/src/gkgfx.lib
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Hack for getting an extension built against static vs. dynamic versions of firefox
|
# Hack for getting an extension built against static vs. dynamic versions of firefox
|
||||||
##ifeq (,$(BUILD_STATIC_LIBS))
|
##ifeq (,$(BUILD_STATIC_LIBS))
|
||||||
|
@ -138,4 +123,4 @@ endif
|
||||||
ifneq (,$(filter $(MOZ_WIDGET_TOOLKIT),mac cocoa))
|
ifneq (,$(filter $(MOZ_WIDGET_TOOLKIT),mac cocoa))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXTRA_DSO_LDOPTS += $(LIBS_DIR) $(EXTRA_DSO_LIBS)
|
EXTRA_DSO_LDOPTS += $(LIBS_DIR) $(EXTRA_DSO_LIBS) $(XPCOM_GLUE_LDOPTS)
|
||||||
|
|
|
@ -50,9 +50,7 @@
|
||||||
#include "nsIView.h"
|
#include "nsIView.h"
|
||||||
#include "nsIViewManager.h"
|
#include "nsIViewManager.h"
|
||||||
|
|
||||||
#ifndef MOZILLA_1_8_BRANCH
|
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
|
|
||||||
|
@ -68,20 +66,17 @@
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
#include "nsIImage.h"
|
#include "nsIImage.h"
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIJSRuntimeService.h"
|
#include "nsIJSRuntimeService.h"
|
||||||
|
|
||||||
#ifndef MOZILLA_1_8_BRANCH
|
#include "nsIPrefService.h"
|
||||||
|
|
||||||
#include "nsIClassInfoImpl.h"
|
#include "nsIClassInfoImpl.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
|
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
|
|
||||||
|
@ -90,34 +85,8 @@
|
||||||
|
|
||||||
// we're hoping that something is setting us up the remap
|
// we're hoping that something is setting us up the remap
|
||||||
|
|
||||||
#include "cairo.h"
|
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxASurface.h"
|
#include "gfxASurface.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_WIN
|
|
||||||
#ifdef MOZILLA_1_8_BRANCH
|
|
||||||
struct _cairo_surface_win32_hack {
|
|
||||||
void *ptr;
|
|
||||||
unsigned int refcnt;
|
|
||||||
cairo_status_t st;
|
|
||||||
cairo_bool_t finished;
|
|
||||||
/* array_t */
|
|
||||||
int sz;
|
|
||||||
int num_el;
|
|
||||||
int el_sz;
|
|
||||||
void *elements;
|
|
||||||
double dx, dy, dxs, dys;
|
|
||||||
unsigned int a;
|
|
||||||
unsigned int b;
|
|
||||||
|
|
||||||
/* win32 */
|
|
||||||
cairo_format_t format;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
@ -544,13 +513,8 @@ nsCanvasRenderingContextGLPrivate::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This is identical to nsCanvasRenderingContext2D::Render, we just don't
|
|
||||||
* have a good place to put it; though maybe I want a CanvasContextImpl that
|
|
||||||
* all this stuff can derive from?
|
|
||||||
*/
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContextGLPrivate::Render(nsIRenderingContext *rc)
|
nsCanvasRenderingContextGLPrivate::Render(gfxContext *ctx)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
@ -560,8 +524,6 @@ nsCanvasRenderingContextGLPrivate::Render(nsIRenderingContext *rc)
|
||||||
if (!mGLPbuffer->ThebesSurface())
|
if (!mGLPbuffer->ThebesSurface())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
|
||||||
gfxContext* ctx = (gfxContext*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
|
||||||
nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface();
|
nsRefPtr<gfxASurface> surf = mGLPbuffer->ThebesSurface();
|
||||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
|
nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
|
||||||
|
|
||||||
|
@ -570,171 +532,13 @@ nsCanvasRenderingContextGLPrivate::Render(nsIRenderingContext *rc)
|
||||||
ctx->NewPath();
|
ctx->NewPath();
|
||||||
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat);
|
||||||
ctx->Fill();
|
ctx->Fill();
|
||||||
#else
|
|
||||||
|
|
||||||
// non-Thebes; this becomes exciting
|
|
||||||
cairo_surface_t *dest = nsnull;
|
|
||||||
cairo_t *dest_cr = nsnull;
|
|
||||||
|
|
||||||
#ifdef XP_WIN
|
|
||||||
void *ptr = nsnull;
|
|
||||||
#ifdef MOZILLA_1_8_BRANCH
|
|
||||||
rv = rc->RetrieveCurrentNativeGraphicData(&ptr);
|
|
||||||
if (NS_FAILED(rv) || !ptr)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
#else
|
|
||||||
ptr = rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC);
|
|
||||||
#endif
|
|
||||||
HDC dc = (HDC) ptr;
|
|
||||||
|
|
||||||
dest = cairo_win32_surface_create (dc);
|
|
||||||
dest_cr = cairo_create (dest);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_GTK2
|
|
||||||
GdkDrawable *gdkdraw = nsnull;
|
|
||||||
#ifdef MOZILLA_1_8_BRANCH
|
|
||||||
rv = rc->RetrieveCurrentNativeGraphicData((void**) &gdkdraw);
|
|
||||||
if (NS_FAILED(rv) || !gdkdraw)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
#else
|
|
||||||
gdkdraw = (GdkDrawable*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_GDK_DRAWABLE);
|
|
||||||
if (!gdkdraw)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gint w, h;
|
|
||||||
gdk_drawable_get_size (gdkdraw, &w, &h);
|
|
||||||
dest = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY(gdkdraw),
|
|
||||||
GDK_DRAWABLE_XID(gdkdraw),
|
|
||||||
GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(gdkdraw)),
|
|
||||||
w, h);
|
|
||||||
dest_cr = cairo_create (dest);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsTransform2D *tx = nsnull;
|
|
||||||
rc->GetCurrentTransform(tx);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDeviceContext> dctx;
|
|
||||||
rc->GetDeviceContext(*getter_AddRefs(dctx));
|
|
||||||
|
|
||||||
// Until we can use the quartz2 surface, mac will be different,
|
|
||||||
// since we'll use CG to render.
|
|
||||||
#ifndef XP_MACOSX
|
|
||||||
|
|
||||||
float x0 = 0.0, y0 = 0.0;
|
|
||||||
float sx = 1.0, sy = 1.0;
|
|
||||||
if (tx->GetType() & MG_2DTRANSLATION) {
|
|
||||||
tx->Transform(&x0, &y0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx->GetType() & MG_2DSCALE) {
|
|
||||||
sx = sy = dctx->DevUnitsToTwips();
|
|
||||||
tx->TransformNoXLate(&sx, &sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_translate (dest_cr, NSToIntRound(x0), NSToIntRound(y0));
|
|
||||||
if (sx != 1.0 || sy != 1.0)
|
|
||||||
cairo_scale (dest_cr, sx, sy);
|
|
||||||
|
|
||||||
cairo_rectangle (dest_cr, 0, 0, mWidth, mHeight);
|
|
||||||
cairo_clip (dest_cr);
|
|
||||||
|
|
||||||
cairo_set_source_surface (dest_cr, mCairoImageSurface, 0, 0);
|
|
||||||
cairo_paint (dest_cr);
|
|
||||||
|
|
||||||
if (dest_cr)
|
|
||||||
cairo_destroy (dest_cr);
|
|
||||||
if (dest)
|
|
||||||
cairo_surface_destroy (dest);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// OSX path
|
|
||||||
|
|
||||||
CGrafPtr port = nsnull;
|
|
||||||
#ifdef MOZILLA_1_8_BRANCH
|
|
||||||
rv = rc->RetrieveCurrentNativeGraphicData((void**) &port);
|
|
||||||
if (NS_FAILED(rv) || !port)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
#else
|
|
||||||
port = (CGrafPtr) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_MAC_THING);
|
|
||||||
if (!port)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct Rect portRect;
|
|
||||||
GetPortBounds(port, &portRect);
|
|
||||||
|
|
||||||
CGContextRef cgc;
|
|
||||||
OSStatus status;
|
|
||||||
status = QDBeginCGContext (port, &cgc);
|
|
||||||
if (status != noErr)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
CGDataProviderRef dataProvider;
|
|
||||||
CGImageRef img;
|
|
||||||
|
|
||||||
dataProvider = CGDataProviderCreateWithData (NULL, mImageBuffer,
|
|
||||||
mWidth * mHeight * 4,
|
|
||||||
NULL);
|
|
||||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
|
||||||
img = CGImageCreate (mWidth, mHeight, 8, 32, mWidth * 4, rgb,
|
|
||||||
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
|
|
||||||
dataProvider, NULL, false, kCGRenderingIntentDefault);
|
|
||||||
CGColorSpaceRelease (rgb);
|
|
||||||
CGDataProviderRelease (dataProvider);
|
|
||||||
|
|
||||||
float x0 = 0.0, y0 = 0.0;
|
|
||||||
float sx = 1.0, sy = 1.0;
|
|
||||||
if (tx->GetType() & MG_2DTRANSLATION) {
|
|
||||||
tx->Transform(&x0, &y0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx->GetType() & MG_2DSCALE) {
|
|
||||||
float p2t = dctx->DevUnitsToTwips();
|
|
||||||
sx = p2t, sy = p2t;
|
|
||||||
tx->TransformNoXLate(&sx, &sy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compensate for the bottom-left Y origin */
|
|
||||||
CGContextTranslateCTM (cgc, NSToIntRound(x0),
|
|
||||||
portRect.bottom - portRect.top - NSToIntRound(y0) - NSToIntRound(mHeight * sy));
|
|
||||||
if (sx != 1.0 || sy != 1.0)
|
|
||||||
CGContextScaleCTM (cgc, sx, sy);
|
|
||||||
|
|
||||||
CGContextDrawImage (cgc, CGRectMake(0, 0, mWidth, mHeight), img);
|
|
||||||
|
|
||||||
CGImageRelease (img);
|
|
||||||
|
|
||||||
status = QDEndCGContext (port, &cgc);
|
|
||||||
/* if EndCGContext fails, what can we do? */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContextGLPrivate::RenderToSurface(cairo_surface_t *surf)
|
nsCanvasRenderingContextGLPrivate::GetInputStream(const char* aMimeType,
|
||||||
{
|
const PRUnichar* aEncoderOptions,
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame*
|
|
||||||
nsCanvasRenderingContextGLPrivate::GetCanvasLayoutFrame()
|
|
||||||
{
|
|
||||||
if (!mCanvasElement)
|
|
||||||
return nsnull;
|
|
||||||
|
|
||||||
nsIFrame *fr = nsnull;
|
|
||||||
mCanvasElement->GetPrimaryCanvasFrame(&fr);
|
|
||||||
return fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsCanvasRenderingContextGLPrivate::GetInputStream(const nsACString& aMimeType,
|
|
||||||
const nsAString& aEncoderOptions,
|
|
||||||
nsIInputStream **aStream)
|
nsIInputStream **aStream)
|
||||||
{
|
{
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
@ -746,7 +550,7 @@ nsCanvasRenderingContextGLPrivate::GetInputStream(const nsACString& aMimeType,
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt,
|
nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt,
|
||||||
cairo_surface_t **aCairoSurface,
|
gfxASurface **aThebesSurface,
|
||||||
PRUint8 **imgData,
|
PRUint8 **imgData,
|
||||||
PRInt32 *widthOut, PRInt32 *heightOut,
|
PRInt32 *widthOut, PRInt32 *heightOut,
|
||||||
nsIURI **uriOut, PRBool *forceWriteOnlyOut)
|
nsIURI **uriOut, PRBool *forceWriteOnlyOut)
|
||||||
|
@ -781,23 +585,20 @@ nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt
|
||||||
rv = canvas->GetSize(&w, &h);
|
rv = canvas->GetSize(&w, &h);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
PRUint8 *data = (PRUint8*) PR_Malloc(w * h * 4);
|
nsRefPtr<gfxImageSurface> surf =
|
||||||
cairo_surface_t *surf =
|
new gfxImageSurface (gfxIntSize(w, h), gfxASurface::ImageFormatARGB32);
|
||||||
cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32,
|
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||||
w, h, w*4);
|
ctx->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||||
cairo_t *cr = cairo_create (surf);
|
ctx->Paint();
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
|
ctx->SetOperator(gfxContext::OPERATOR_OVER);
|
||||||
cairo_paint (cr);
|
|
||||||
cairo_destroy (cr);
|
|
||||||
|
|
||||||
rv = canvas->RenderContextsToSurface(surf);
|
rv = canvas->RenderContexts(ctx);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv))
|
||||||
cairo_surface_destroy (surf);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
|
|
||||||
*aCairoSurface = surf;
|
NS_ADDREF(surf.get());
|
||||||
*imgData = data;
|
*aThebesSurface = surf;
|
||||||
|
*imgData = surf->Data();
|
||||||
*widthOut = w;
|
*widthOut = w;
|
||||||
*heightOut = h;
|
*heightOut = h;
|
||||||
|
|
||||||
|
@ -831,266 +632,10 @@ nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt
|
||||||
if (heightOut)
|
if (heightOut)
|
||||||
*heightOut = imgHeight;
|
*heightOut = imgHeight;
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
rv = img->GetSurface(aThebesSurface);
|
||||||
gfxASurface* gfxsurf = nsnull;
|
|
||||||
rv = img->GetSurface(&gfxsurf);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
*aCairoSurface = gfxsurf->CairoSurface();
|
|
||||||
cairo_surface_reference (*aCairoSurface);
|
|
||||||
*imgData = nsnull;
|
*imgData = nsnull;
|
||||||
#else
|
|
||||||
//
|
|
||||||
// We now need to create a cairo_surface with the same data as
|
|
||||||
// this image element.
|
|
||||||
//
|
|
||||||
|
|
||||||
PRUint8 *cairoImgData = (PRUint8 *)nsMemory::Alloc(imgHeight * imgWidth * 4);
|
|
||||||
PRUint8 *outData = cairoImgData;
|
|
||||||
|
|
||||||
gfx_format format;
|
|
||||||
rv = frame->GetFormat(&format);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = frame->LockImageData();
|
|
||||||
if (img->GetHasAlphaMask())
|
|
||||||
rv |= frame->LockAlphaData();
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
nsMemory::Free(cairoImgData);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRUint8 *inPixBits, *inAlphaBits = nsnull;
|
|
||||||
PRUint32 inPixStride, inAlphaStride = 0;
|
|
||||||
inPixBits = img->GetBits();
|
|
||||||
inPixStride = img->GetLineStride();
|
|
||||||
if (img->GetHasAlphaMask()) {
|
|
||||||
inAlphaBits = img->GetAlphaBits();
|
|
||||||
inAlphaStride = img->GetAlphaLineStride();
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool topToBottom = img->GetIsRowOrderTopToBottom();
|
|
||||||
PRBool useBGR;
|
|
||||||
|
|
||||||
// The gtk backend optimizes away the alpha mask of images
|
|
||||||
// with a fully opaque alpha, but doesn't update its format (bug?);
|
|
||||||
// you end up with a RGB_A8 image with GetHasAlphaMask() == false.
|
|
||||||
// We need to treat that case as RGB.
|
|
||||||
|
|
||||||
if ((format == gfxIFormats::RGB || format == gfxIFormats::BGR) ||
|
|
||||||
(!(img->GetHasAlphaMask()) && (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8)))
|
|
||||||
{
|
|
||||||
useBGR = (format & 1);
|
|
||||||
|
|
||||||
#ifdef IS_BIG_ENDIAN
|
|
||||||
useBGR = !useBGR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
|
||||||
PRUint32 rowIndex;
|
|
||||||
if (topToBottom)
|
|
||||||
rowIndex = j;
|
|
||||||
else
|
|
||||||
rowIndex = imgHeight - j - 1;
|
|
||||||
|
|
||||||
PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
|
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
|
||||||
// handle rgb data; no alpha to premultiply
|
|
||||||
#ifdef XP_MACOSX
|
|
||||||
// skip extra OSX byte
|
|
||||||
inrowrgb++;
|
|
||||||
#endif
|
|
||||||
PRUint8 r, g, b;
|
|
||||||
if (useBGR) {
|
|
||||||
b = *inrowrgb++;
|
|
||||||
g = *inrowrgb++;
|
|
||||||
r = *inrowrgb++;
|
|
||||||
} else {
|
|
||||||
r = *inrowrgb++;
|
|
||||||
g = *inrowrgb++;
|
|
||||||
b = *inrowrgb++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IS_BIG_ENDIAN
|
|
||||||
// alpha
|
|
||||||
*outData++ = 0xff;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*outData++ = r;
|
|
||||||
*outData++ = g;
|
|
||||||
*outData++ = b;
|
|
||||||
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
// alpha
|
|
||||||
*outData++ = 0xff;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv = NS_OK;
|
|
||||||
} else if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
|
|
||||||
useBGR = (format & 1);
|
|
||||||
|
|
||||||
#ifdef IS_BIG_ENDIAN
|
|
||||||
useBGR = !useBGR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
|
||||||
PRUint32 rowIndex;
|
|
||||||
if (topToBottom)
|
|
||||||
rowIndex = j;
|
|
||||||
else
|
|
||||||
rowIndex = imgHeight - j - 1;
|
|
||||||
|
|
||||||
PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
|
|
||||||
PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
|
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
|
||||||
// pull out the bit value into alpha
|
|
||||||
PRInt32 bit = i % 8;
|
|
||||||
PRInt32 byte = i / 8;
|
|
||||||
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
PRUint8 a = (inrowalpha[byte] >> (7-bit)) & 1;
|
|
||||||
#else
|
|
||||||
PRUint8 a = (inrowalpha[byte] >> bit) & 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
|
||||||
// skip extra X8 byte on OSX
|
|
||||||
inrowrgb++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// handle rgb data; need to multiply the alpha out,
|
|
||||||
// but we short-circuit that here since we know that a
|
|
||||||
// can only be 0 or 1
|
|
||||||
if (a) {
|
|
||||||
PRUint8 r, g, b;
|
|
||||||
|
|
||||||
if (useBGR) {
|
|
||||||
b = *inrowrgb++;
|
|
||||||
g = *inrowrgb++;
|
|
||||||
r = *inrowrgb++;
|
|
||||||
} else {
|
|
||||||
r = *inrowrgb++;
|
|
||||||
g = *inrowrgb++;
|
|
||||||
b = *inrowrgb++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IS_BIG_ENDIAN
|
|
||||||
// alpha
|
|
||||||
*outData++ = 0xff;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*outData++ = r;
|
|
||||||
*outData++ = g;
|
|
||||||
*outData++ = b;
|
|
||||||
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
// alpha
|
|
||||||
*outData++ = 0xff;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
// alpha is 0, so we need to write all 0's,
|
|
||||||
// ignoring input color
|
|
||||||
inrowrgb += 3;
|
|
||||||
*outData++ = 0;
|
|
||||||
*outData++ = 0;
|
|
||||||
*outData++ = 0;
|
|
||||||
*outData++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv = NS_OK;
|
|
||||||
} else if (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8) {
|
|
||||||
useBGR = (format & 1);
|
|
||||||
|
|
||||||
#ifdef IS_BIG_ENDIAN
|
|
||||||
useBGR = !useBGR;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
|
||||||
PRUint32 rowIndex;
|
|
||||||
if (topToBottom)
|
|
||||||
rowIndex = j;
|
|
||||||
else
|
|
||||||
rowIndex = imgHeight - j - 1;
|
|
||||||
|
|
||||||
PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
|
|
||||||
PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
|
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
|
||||||
// pull out alpha; we'll need it to premultiply
|
|
||||||
PRUint8 a = *inrowalpha++;
|
|
||||||
|
|
||||||
// handle rgb data; we need to fully premultiply
|
|
||||||
// with the alpha
|
|
||||||
#ifdef XP_MACOSX
|
|
||||||
// skip extra X8 byte on OSX
|
|
||||||
inrowrgb++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// XXX gcc bug: gcc seems to push "r" into a register
|
|
||||||
// early, and pretends that it's in that register
|
|
||||||
// throughout the 3 macros below. At the end
|
|
||||||
// of the 3rd macro, the correct r value is
|
|
||||||
// calculated but never stored anywhere -- the r variable
|
|
||||||
// has the value of the low byte of register that it
|
|
||||||
// was stuffed into, which has the result of some
|
|
||||||
// intermediate calculation.
|
|
||||||
// I've seen this on gcc 3.4.2 x86 (Fedora Core 3)
|
|
||||||
// and gcc 3.3 PPC (OS X 10.3)
|
|
||||||
|
|
||||||
//PRUint8 b, g, r;
|
|
||||||
//FAST_DIVIDE_BY_255(b, *inrowrgb++ * a - a / 2);
|
|
||||||
//FAST_DIVIDE_BY_255(g, *inrowrgb++ * a - a / 2);
|
|
||||||
//FAST_DIVIDE_BY_255(r, *inrowrgb++ * a - a / 2);
|
|
||||||
|
|
||||||
PRUint8 r, g, b;
|
|
||||||
if (useBGR) {
|
|
||||||
b = (*inrowrgb++ * a - a / 2) / 255;
|
|
||||||
g = (*inrowrgb++ * a - a / 2) / 255;
|
|
||||||
r = (*inrowrgb++ * a - a / 2) / 255;
|
|
||||||
} else {
|
|
||||||
r = (*inrowrgb++ * a - a / 2) / 255;
|
|
||||||
g = (*inrowrgb++ * a - a / 2) / 255;
|
|
||||||
b = (*inrowrgb++ * a - a / 2) / 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IS_BIG_ENDIAN
|
|
||||||
*outData++ = a;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*outData++ = r;
|
|
||||||
*outData++ = g;
|
|
||||||
*outData++ = b;
|
|
||||||
|
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
|
||||||
*outData++ = a;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rv = NS_OK;
|
|
||||||
} else {
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (img->GetHasAlphaMask())
|
|
||||||
frame->UnlockAlphaData();
|
|
||||||
frame->UnlockImageData();
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
nsMemory::Free(cairoImgData);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_surface_t *imgSurf =
|
|
||||||
cairo_image_surface_create_for_data(cairoImgData, CAIRO_FORMAT_ARGB32,
|
|
||||||
imgWidth, imgHeight, imgWidth*4);
|
|
||||||
|
|
||||||
*aCairoSurface = imgSurf;
|
|
||||||
*imgData = cairoImgData;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1125,27 +670,6 @@ nsCanvasRenderingContextGLPrivate::DoDrawImageSecurityCheck(nsIURI* aURI, PRBool
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "DoDrawImageSecuritycheck this 5: %p\n", this);
|
fprintf (stderr, "DoDrawImageSecuritycheck this 5: %p\n", this);
|
||||||
#ifdef MOZILLA_1_8_BRANCH
|
|
||||||
#if 0
|
|
||||||
nsCOMPtr<nsIDOMNode> elem = do_QueryInterface(mCanvasElement);
|
|
||||||
if (elem && ssm) {
|
|
||||||
nsCOMPtr<nsIPrincipal> elemPrincipal;
|
|
||||||
nsCOMPtr<nsIPrincipal> uriPrincipal;
|
|
||||||
nsCOMPtr<nsIDocument> elemDocument;
|
|
||||||
nsContentUtils::GetDocumentAndPrincipal(elem, getter_AddRefs(elemDocument), getter_AddRefs(elemPrincipal));
|
|
||||||
ssm->GetCodebasePrincipal(aURI, getter_AddRefs(uriPrincipal));
|
|
||||||
|
|
||||||
if (uriPrincipal && elemPrincipal) {
|
|
||||||
nsresult rv =
|
|
||||||
ssm->CheckSameOriginPrincipal(elemPrincipal, uriPrincipal);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
// Same origin
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
|
nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
|
||||||
if (elem && ssm) {
|
if (elem && ssm) {
|
||||||
nsCOMPtr<nsIPrincipal> uriPrincipal;
|
nsCOMPtr<nsIPrincipal> uriPrincipal;
|
||||||
|
@ -1160,7 +684,6 @@ nsCanvasRenderingContextGLPrivate::DoDrawImageSecurityCheck(nsIURI* aURI, PRBool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf (stderr, "DoDrawImageSecuritycheck this 6: %p\n", this); fflush(stderr);
|
fprintf (stderr, "DoDrawImageSecuritycheck this 6: %p\n", this); fflush(stderr);
|
||||||
mCanvasElement->SetWriteOnly();
|
mCanvasElement->SetWriteOnly();
|
||||||
|
@ -1221,43 +744,11 @@ nsCanvasRenderingContextGLPrivate::DoSwapBuffers()
|
||||||
{
|
{
|
||||||
mGLPbuffer->SwapBuffers();
|
mGLPbuffer->SwapBuffers();
|
||||||
|
|
||||||
// then invalidate the region and do a sync redraw
|
// then invalidate the region and do a redraw
|
||||||
// (uh, why sync?)
|
if (!mCanvasElement)
|
||||||
nsIFrame *frame = GetCanvasLayoutFrame();
|
return NS_OK;
|
||||||
if (frame) {
|
|
||||||
nsRect r = frame->GetRect();
|
|
||||||
r.x = r.y = 0;
|
|
||||||
|
|
||||||
// sync redraw
|
|
||||||
//frame->Invalidate(r, PR_TRUE);
|
|
||||||
|
|
||||||
// nsIFrame::Invalidate is an internal non-virtual method,
|
|
||||||
// so we basically recreate it here. I would suggest
|
|
||||||
// an InvalidateExternal for the trunk.
|
|
||||||
nsIPresShell *shell = frame->PresContext()->GetPresShell();
|
|
||||||
if (shell) {
|
|
||||||
PRBool suppressed = PR_FALSE;
|
|
||||||
shell->IsPaintingSuppressed(&suppressed);
|
|
||||||
if (suppressed)
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe VMREFRESH_IMMEDIATE in some cases,
|
|
||||||
// need to think
|
|
||||||
PRUint32 flags = NS_VMREFRESH_NO_SYNC;
|
|
||||||
if (frame->HasView()) {
|
|
||||||
nsIView* view = frame->GetViewExternal();
|
|
||||||
view->GetViewManager()->UpdateView(view, r, flags);
|
|
||||||
} else {
|
|
||||||
nsPoint offset;
|
|
||||||
nsIView *view;
|
|
||||||
frame->GetOffsetFromView(offset, &view);
|
|
||||||
NS_ASSERTION(view, "no view");
|
|
||||||
r += offset;
|
|
||||||
view->GetViewManager()->UpdateView(view, r, flags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mCanvasElement->InvalidateFrame();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1298,3 +789,16 @@ nsCanvasRenderingContextGLPrivate::SafeToCreateCanvas3DContext()
|
||||||
|
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need this here, because nsAString has a different type name based on whether it's
|
||||||
|
* used internally or externally. BeginPrinting isn't ever called, but gfxImageSurface
|
||||||
|
* wants to inherit the default definition, and it can't find it. So instead, we just
|
||||||
|
* stick a stub here to shut the compiler up, because we never call this method.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
gfxASurface::BeginPrinting(const nsAString& aTitle, const nsAString& aPrintToFileName)
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "prmem.h"
|
#include "prmem.h"
|
||||||
|
|
||||||
|
#include "nsStringGlue.h"
|
||||||
|
|
||||||
#include "nsICanvasRenderingContextGLBuffer.h"
|
#include "nsICanvasRenderingContextGLBuffer.h"
|
||||||
#include "nsICanvasRenderingContextInternal.h"
|
#include "nsICanvasRenderingContextInternal.h"
|
||||||
#include "nsIDOMHTMLCanvasElement.h"
|
#include "nsIDOMHTMLCanvasElement.h"
|
||||||
|
@ -64,7 +66,6 @@
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
#include "nsIImage.h"
|
#include "nsIImage.h"
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIJSRuntimeService.h"
|
#include "nsIJSRuntimeService.h"
|
||||||
|
|
||||||
|
@ -73,12 +74,13 @@
|
||||||
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "gfxContext.h"
|
||||||
|
|
||||||
#include "glew.h"
|
#include "glew.h"
|
||||||
|
|
||||||
#include "nsGLPbuffer.h"
|
#include "nsGLPbuffer.h"
|
||||||
|
@ -122,18 +124,16 @@ public:
|
||||||
// nsICanvasRenderingContextInternal
|
// nsICanvasRenderingContextInternal
|
||||||
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
|
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
|
||||||
NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
|
NS_IMETHOD SetDimensions(PRInt32 width, PRInt32 height);
|
||||||
NS_IMETHOD Render(nsIRenderingContext *rc);
|
NS_IMETHOD Render(gfxContext *ctx);
|
||||||
NS_IMETHOD RenderToSurface(cairo_surface_t *surf);
|
NS_IMETHOD GetInputStream(const char* aMimeType,
|
||||||
NS_IMETHOD GetInputStream(const nsACString& aMimeType,
|
const PRUnichar* aEncoderOptions,
|
||||||
const nsAString& aEncoderOptions,
|
|
||||||
nsIInputStream **aStream);
|
nsIInputStream **aStream);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PRBool SafeToCreateCanvas3DContext();
|
PRBool SafeToCreateCanvas3DContext();
|
||||||
nsIFrame *GetCanvasLayoutFrame();
|
|
||||||
nsresult DoSwapBuffers();
|
nsresult DoSwapBuffers();
|
||||||
nsresult CairoSurfaceFromElement(nsIDOMElement *imgElt,
|
nsresult CairoSurfaceFromElement(nsIDOMElement *imgElt,
|
||||||
cairo_surface_t **aCairoSurface,
|
gfxASurface **aThebesSurface,
|
||||||
PRUint8 **imgData,
|
PRUint8 **imgData,
|
||||||
PRInt32 *widthOut, PRInt32 *heightOut,
|
PRInt32 *widthOut, PRInt32 *heightOut,
|
||||||
nsIURI **uriOut, PRBool *forceWriteOnlyOut);
|
nsIURI **uriOut, PRBool *forceWriteOnlyOut);
|
||||||
|
@ -412,6 +412,8 @@ public:
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We can't use ns*Substring, because we don't have internal linkage
|
||||||
|
#if 0
|
||||||
PRBool DefineProperty(const char *name, const nsCSubstring& val) {
|
PRBool DefineProperty(const char *name, const nsCSubstring& val) {
|
||||||
JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
|
JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val.BeginReading(), val.Length());
|
||||||
if (!jsstr ||
|
if (!jsstr ||
|
||||||
|
@ -427,6 +429,7 @@ public:
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PRBool DefineProperty(const char *name, const char *val, PRUint32 len) {
|
PRBool DefineProperty(const char *name, const char *val, PRUint32 len) {
|
||||||
JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val, len);
|
JSString *jsstr = JS_NewStringCopyN(mCtx->ctx, val, len);
|
||||||
|
|
|
@ -53,9 +53,7 @@
|
||||||
|
|
||||||
#include "nsICanvasGLPrivate.h"
|
#include "nsICanvasGLPrivate.h"
|
||||||
|
|
||||||
#ifndef MOZILLA_1_8_BRANCH
|
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
|
|
||||||
|
@ -73,28 +71,18 @@
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
#include "nsIImage.h"
|
#include "nsIImage.h"
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIJSRuntimeService.h"
|
#include "nsIJSRuntimeService.h"
|
||||||
|
|
||||||
#ifndef MOZILLA_1_8_BRANCH
|
|
||||||
#include "nsIClassInfoImpl.h"
|
#include "nsIClassInfoImpl.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
|
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
|
||||||
#include "gfxContext.h"
|
|
||||||
#include "gfxASurface.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -102,7 +90,8 @@
|
||||||
// GLEW will pull in the GL bits that we want/need
|
// GLEW will pull in the GL bits that we want/need
|
||||||
#include "glew.h"
|
#include "glew.h"
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "gfxImageSurface.h"
|
||||||
|
#include "gfxContext.h"
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
PRLogModuleInfo* gGLES11Log = nsnull;
|
PRLogModuleInfo* gGLES11Log = nsnull;
|
||||||
|
@ -1132,13 +1121,14 @@ NS_IMETHODIMP
|
||||||
nsCanvasRenderingContextGLES11::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElement *imageOrCanvas)
|
nsCanvasRenderingContextGLES11::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElement *imageOrCanvas)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
cairo_surface_t *cairo_surf = nsnull;
|
nsRefPtr<gfxASurface> surf;
|
||||||
PRUint8 *image_data = nsnull, *local_image_data = nsnull;
|
nsRefPtr<gfxImageSurface> tmpImageSurface;
|
||||||
|
PRUint8 *image_data = nsnull;
|
||||||
PRInt32 width, height;
|
PRInt32 width, height;
|
||||||
nsCOMPtr<nsIURI> element_uri;
|
nsCOMPtr<nsIURI> element_uri;
|
||||||
PRBool force_write_only = PR_FALSE;
|
PRBool force_write_only = PR_FALSE;
|
||||||
|
|
||||||
rv = CairoSurfaceFromElement(imageOrCanvas, &cairo_surf, &image_data,
|
rv = CairoSurfaceFromElement(imageOrCanvas, getter_AddRefs(surf), &image_data,
|
||||||
&width, &height, getter_AddRefs(element_uri), &force_write_only);
|
&width, &height, getter_AddRefs(element_uri), &force_write_only);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1157,26 +1147,15 @@ nsCanvasRenderingContextGLES11::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElemen
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image_data) {
|
if (!image_data) {
|
||||||
local_image_data = (PRUint8*) PR_Malloc(width * height * 4);
|
nsRefPtr<gfxImageSurface> tmpImageSurface = new gfxImageSurface(gfxIntSize(width, height),
|
||||||
if (!local_image_data)
|
gfxASurface::ImageFormatARGB32);
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
cairo_surface_t *tmp = cairo_image_surface_create_for_data (local_image_data,
|
nsRefPtr<gfxContext> cx = new gfxContext(tmpImageSurface);
|
||||||
CAIRO_FORMAT_ARGB32,
|
cx->SetSource(surf);
|
||||||
width, height, width * 4);
|
cx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
if (!tmp) {
|
cx->Paint();
|
||||||
PR_Free(local_image_data);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_t *tmp_cr = cairo_create (tmp);
|
image_data = tmpImageSurface->Data();
|
||||||
cairo_set_source_surface (tmp_cr, cairo_surf, 0, 0);
|
|
||||||
cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_paint (tmp_cr);
|
|
||||||
cairo_destroy (tmp_cr);
|
|
||||||
cairo_surface_destroy (tmp);
|
|
||||||
|
|
||||||
image_data = local_image_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Er, I can do this with glPixelStore, no?
|
// Er, I can do this with glPixelStore, no?
|
||||||
|
@ -1209,9 +1188,6 @@ nsCanvasRenderingContextGLES11::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElemen
|
||||||
|
|
||||||
glTexImage2D(target, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
glTexImage2D(target, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
||||||
|
|
||||||
if (local_image_data)
|
|
||||||
PR_Free(local_image_data);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,7 @@
|
||||||
#include "nsIView.h"
|
#include "nsIView.h"
|
||||||
#include "nsIViewManager.h"
|
#include "nsIViewManager.h"
|
||||||
|
|
||||||
#ifndef MOZILLA_1_8_BRANCH
|
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
|
|
||||||
|
@ -71,28 +69,18 @@
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
#include "nsIImage.h"
|
#include "nsIImage.h"
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIJSRuntimeService.h"
|
#include "nsIJSRuntimeService.h"
|
||||||
|
|
||||||
#ifndef MOZILLA_1_8_BRANCH
|
|
||||||
#include "nsIClassInfoImpl.h"
|
#include "nsIClassInfoImpl.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
|
|
||||||
#include "nsContentUtils.h"
|
|
||||||
|
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
|
||||||
#include "gfxContext.h"
|
|
||||||
#include "gfxASurface.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -102,7 +90,8 @@
|
||||||
|
|
||||||
// we're hoping that something is setting us up the remap
|
// we're hoping that something is setting us up the remap
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "gfxImageSurface.h"
|
||||||
|
#include "gfxContext.h"
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
PRLogModuleInfo* gGLES20Log = nsnull;
|
PRLogModuleInfo* gGLES20Log = nsnull;
|
||||||
|
@ -1012,13 +1001,14 @@ NS_IMETHODIMP
|
||||||
nsCanvasRenderingContextGLWeb20::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElement *imageOrCanvas)
|
nsCanvasRenderingContextGLWeb20::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElement *imageOrCanvas)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
cairo_surface_t *cairo_surf = nsnull;
|
nsRefPtr<gfxASurface> surf;
|
||||||
PRUint8 *image_data = nsnull, *local_image_data = nsnull;
|
nsRefPtr<gfxImageSurface> tmpImageSurface;
|
||||||
|
PRUint8 *image_data = nsnull;
|
||||||
PRInt32 width, height;
|
PRInt32 width, height;
|
||||||
nsCOMPtr<nsIURI> element_uri;
|
nsCOMPtr<nsIURI> element_uri;
|
||||||
PRBool force_write_only = PR_FALSE;
|
PRBool force_write_only = PR_FALSE;
|
||||||
|
|
||||||
rv = CairoSurfaceFromElement(imageOrCanvas, &cairo_surf, &image_data,
|
rv = CairoSurfaceFromElement(imageOrCanvas, getter_AddRefs(surf), &image_data,
|
||||||
&width, &height, getter_AddRefs(element_uri), &force_write_only);
|
&width, &height, getter_AddRefs(element_uri), &force_write_only);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1037,26 +1027,15 @@ nsCanvasRenderingContextGLWeb20::TexImage2DHTML(PRUint32 target, nsIDOMHTMLEleme
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image_data) {
|
if (!image_data) {
|
||||||
local_image_data = (PRUint8*) PR_Malloc(width * height * 4);
|
nsRefPtr<gfxImageSurface> tmpImageSurface = new gfxImageSurface(gfxIntSize(width, height),
|
||||||
if (!local_image_data)
|
gfxASurface::ImageFormatARGB32);
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
cairo_surface_t *tmp = cairo_image_surface_create_for_data (local_image_data,
|
nsRefPtr<gfxContext> cx = new gfxContext(tmpImageSurface);
|
||||||
CAIRO_FORMAT_ARGB32,
|
cx->SetSource(surf);
|
||||||
width, height, width * 4);
|
cx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||||
if (!tmp) {
|
cx->Paint();
|
||||||
PR_Free(local_image_data);
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_t *tmp_cr = cairo_create (tmp);
|
image_data = tmpImageSurface->Data();
|
||||||
cairo_set_source_surface (tmp_cr, cairo_surf, 0, 0);
|
|
||||||
cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_paint (tmp_cr);
|
|
||||||
cairo_destroy (tmp_cr);
|
|
||||||
cairo_surface_destroy (tmp);
|
|
||||||
|
|
||||||
image_data = local_image_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Er, I can do this with glPixelStore, no?
|
// Er, I can do this with glPixelStore, no?
|
||||||
|
@ -1089,9 +1068,6 @@ nsCanvasRenderingContextGLWeb20::TexImage2DHTML(PRUint32 target, nsIDOMHTMLEleme
|
||||||
|
|
||||||
glTexImage2D(target, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
glTexImage2D(target, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
|
||||||
|
|
||||||
if (local_image_data)
|
|
||||||
PR_Free(local_image_data);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче