diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp index b6b5fdd40d9..b423d197b6d 100644 --- a/content/canvas/src/nsCanvasRenderingContext2D.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp @@ -54,12 +54,6 @@ #include "nsIPresShell.h" #include "nsIVariant.h" -#ifdef MOZILLA_1_8_BRANCH -#include "nsIScriptGlobalObject.h" -#include "nsIViewManager.h" -#include "nsIScrollableView.h" -#endif - #include "imgIRequest.h" #include "imgIContainer.h" #include "gfxIImageFrame.h" @@ -103,79 +97,17 @@ #include "cairo.h" #include "imgIEncoder.h" -#ifdef MOZILLA_1_8_BRANCH -#define imgIEncoder imgIEncoder_MOZILLA_1_8_BRANCH -#endif -#ifdef MOZ_CAIRO_GFX #include "gfxContext.h" #include "gfxASurface.h" #include "gfxPlatform.h" -#include "nsDisplayList.h" -#include "nsIViewManager.h" -#include "nsIScrollableView.h" #include "nsFrameManager.h" -#include "nsRegion.h" - -#include "stdio.h" -#endif - -#ifdef XP_WIN -#include "cairo-win32.h" - -#ifdef MOZILLA_1_8_BRANCH -extern "C" { -cairo_surface_t * -_cairo_win32_surface_create_dib (cairo_format_t format, - int width, - int height); -} -#endif #ifndef M_PI #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 #endif -#endif - -#ifdef XP_OS2 -#define INCL_WINWINDOWMGR -#define INCL_GPIBITMAPS -#include -#include "nsDrawingSurfaceOS2.h" -#include "cairo-os2.h" -#endif - -#ifdef MOZ_WIDGET_GTK2 -#include "cairo-xlib.h" -#include "cairo-xlib-xrender.h" -#include -#include -#endif - -#ifdef XP_MACOSX -#include -#include - -/* This has to be 0 on machines less than 10.4 (which are always PPC); - * otherwise the older CG gets confused if we pass in - * kCGBitmapByteOrder32Big since it doesn't understand it. - */ -#ifdef __BIG_ENDIAN__ -#define CG_BITMAP_BYTE_ORDER_FLAG 0 -#else /* Little endian. */ -/* x86, and will be a 10.4u SDK; ByteOrder32Host will be defined */ -#define CG_BITMAP_BYTE_ORDER_FLAG kCGBitmapByteOrder32Host -#endif - -#ifndef MOZ_CAIRO_GFX -#include "nsDrawingSurfaceMac.h" -#endif - -#endif - -static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID); /* Maximum depth of save() which has style information saved */ #define STYLE_STACK_DEPTH 50 @@ -233,11 +165,7 @@ static PRBool FloatValidate (double f1, double f2, double f3, double f4, double class nsCanvasGradient : public nsIDOMCanvasGradient { public: -#ifdef MOZILLA_1_8_BRANCH - NS_DEFINE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID) -#else NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID) -#endif nsCanvasGradient(cairo_pattern_t *cpat, nsICSSParser *cssparser) : mPattern(cpat), mCSSParser(cssparser) @@ -284,9 +212,7 @@ protected: nsCOMPtr mCSSParser; }; -#ifndef MOZILLA_1_8_BRANCH NS_DEFINE_STATIC_IID_ACCESSOR(nsCanvasGradient, NS_CANVASGRADIENT_PRIVATE_IID) -#endif NS_IMPL_ADDREF(nsCanvasGradient) NS_IMPL_RELEASE(nsCanvasGradient) @@ -306,11 +232,7 @@ NS_INTERFACE_MAP_END class nsCanvasPattern : public nsIDOMCanvasPattern { public: -#ifdef MOZILLA_1_8_BRANCH - NS_DEFINE_STATIC_IID_ACCESSOR(NS_CANVASPATTERN_PRIVATE_IID) -#else NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERN_PRIVATE_IID) -#endif nsCanvasPattern(cairo_pattern_t *cpat, PRUint8 *dataToFree, nsIURI* URIForSecurityCheck, PRBool forceWriteOnly) @@ -340,9 +262,7 @@ protected: PRPackedBool mForceWriteOnly; }; -#ifndef MOZILLA_1_8_BRANCH NS_DEFINE_STATIC_IID_ACCESSOR(nsCanvasPattern, NS_CANVASPATTERN_PRIVATE_IID) -#endif NS_IMPL_ADDREF(nsCanvasPattern) NS_IMPL_RELEASE(nsCanvasPattern) @@ -424,10 +344,8 @@ protected: nsCOMPtr mCSSParser; // yay cairo -#ifdef MOZ_CAIRO_GFX nsRefPtr mThebesContext; nsRefPtr mThebesSurface; -#endif PRUint32 mSaveCount; cairo_t *mCairo; @@ -483,10 +401,6 @@ protected: return mStyleStack[mSaveCount]; } -#ifdef MOZ_WIDGET_GTK2 - Pixmap mSurfacePixmap; -#endif - // stolen from nsJSUtils static PRBool ConvertJSValToUint32(PRUint32* aProp, JSContext* aContext, jsval aValue); @@ -501,11 +415,6 @@ protected: PRUint8 **imgDataOut, PRInt32 *widthOut, PRInt32 *heightOut, nsIURI **uriOut, PRBool *forceWriteOnlyOut); - - nsresult DrawNativeSurfaces(nsIDrawingSurface* aBlackSurface, - nsIDrawingSurface* aWhiteSurface, - const nsIntSize& aSurfaceSize, - nsIRenderingContext* aBlackContext); }; NS_IMPL_ADDREF(nsCanvasRenderingContext2D) @@ -537,9 +446,6 @@ nsCanvasRenderingContext2D::nsCanvasRenderingContext2D() : mCanvasElement(nsnull), mSaveCount(0), mCairo(nsnull), mSurface(nsnull), mImageSurfaceData(nsnull), mStyleStack(20) { -#ifdef MOZ_WIDGET_GTK2 - mSurfacePixmap = None; -#endif } nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D() @@ -571,13 +477,6 @@ nsCanvasRenderingContext2D::Destroy() mSurface = nsnull; } -#ifdef MOZ_WIDGET_GTK2 - if (mSurfacePixmap != None) { - XFreePixmap(GDK_DISPLAY(), mSurfacePixmap); - mSurfacePixmap = None; - } -#endif - if (mImageSurfaceData) { PR_Free (mImageSurfaceData); mImageSurfaceData = nsnull; @@ -698,25 +597,6 @@ nsCanvasRenderingContext2D::DoDrawImageSecurityCheck(nsIURI* aURI, PRBool forceW nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); -#ifdef MOZILLA_1_8_BRANCH - nsCOMPtr elem = do_QueryInterface(mCanvasElement); - if (elem && ssm) { - nsCOMPtr elemPrincipal; - nsCOMPtr uriPrincipal; - nsCOMPtr 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; - } - } - } -#else nsCOMPtr elem = do_QueryInterface(mCanvasElement); if (elem && ssm) { nsCOMPtr uriPrincipal; @@ -731,7 +611,6 @@ nsCanvasRenderingContext2D::DoDrawImageSecurityCheck(nsIURI* aURI, PRBool forceW } } } -#endif mCanvasElement->SetWriteOnly(); } @@ -800,7 +679,6 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height) mWidth = width; mHeight = height; -#ifdef MOZ_CAIRO_GFX mThebesSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32); mThebesContext = new gfxContext(mThebesSurface); @@ -808,61 +686,6 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height) cairo_surface_reference(mSurface); mCairo = mThebesContext->GetCairo(); cairo_reference(mCairo); -#else - // non-cairo gfx -#ifdef XP_WIN -#ifndef MOZILLA_1_8_BRANCH - mSurface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, - mWidth, mHeight); -#else - mSurface = _cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, - mWidth, mHeight); -#endif -#elif MOZ_WIDGET_GTK2 - // On most current X servers, using the software-only surface - // actually provides a much smoother and faster display. - // However, we provide MOZ_CANVAS_USE_RENDER for whomever wants to - // go that route. - if (getenv("MOZ_CANVAS_USE_RENDER")) { - XRenderPictFormat *fmt = XRenderFindStandardFormat (GDK_DISPLAY(), - PictStandardARGB32); - if (fmt) { - int npfmts = 0; - XPixmapFormatValues *pfmts = XListPixmapFormats(GDK_DISPLAY(), &npfmts); - for (int i = 0; i < npfmts; i++) { - if (pfmts[i].depth == 32) { - npfmts = -1; - break; - } - } - XFree(pfmts); - - if (npfmts == -1) { - mSurfacePixmap = XCreatePixmap (GDK_DISPLAY(), - DefaultRootWindow(GDK_DISPLAY()), - width, height, 32); - mSurface = cairo_xlib_surface_create_with_xrender_format - (GDK_DISPLAY(), mSurfacePixmap, DefaultScreenOfDisplay(GDK_DISPLAY()), - fmt, mWidth, mHeight); - } - } - } -#endif - - // fall back to image surface - if (!mSurface) { - mImageSurfaceData = (PRUint8*) PR_Malloc (mWidth * mHeight * 4); - if (!mImageSurfaceData) - return NS_ERROR_OUT_OF_MEMORY; - - mSurface = cairo_image_surface_create_for_data (mImageSurfaceData, - CAIRO_FORMAT_ARGB32, - mWidth, mHeight, - mWidth * 4); - } - - mCairo = cairo_create(mSurface); -#endif // set up the initial canvas defaults mStyleStack.Clear(); @@ -897,8 +720,6 @@ nsCanvasRenderingContext2D::Render(nsIRenderingContext *rc) { nsresult rv = NS_OK; -#ifdef MOZ_CAIRO_GFX - gfxContext* ctx = (gfxContext*) rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT); nsRefPtr pat = new gfxPattern(mThebesSurface); @@ -908,159 +729,6 @@ nsCanvasRenderingContext2D::Render(nsIRenderingContext *rc) ctx->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, mWidth, mHeight), pat); 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 XP_OS2 - void *ptr = nsnull; -#ifdef MOZILLA_1_8_BRANCH - rv = rc->RetrieveCurrentNativeGraphicData(&ptr); - if (NS_FAILED(rv) || !ptr) - return NS_ERROR_FAILURE; -#else - /* OS/2 also uses NATIVE_WINDOWS_DC to get a native OS/2 PS */ - ptr = rc->GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC); -#endif - - HPS hps = (HPS)ptr; - nsDrawingSurfaceOS2 *surface; /* to get the dimensions from this */ - PRUint32 width, height; - rc->GetDrawingSurface((nsIDrawingSurface**)&surface); - surface->GetDimensions(&width, &height); - - dest = cairo_os2_surface_create(hps, width, height); - cairo_surface_mark_dirty(dest); // needed on OS/2 for initialization - 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 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, mSurface, 0, 0); - cairo_paint (dest_cr); - - if (dest_cr) - cairo_destroy (dest_cr); - if (dest) - cairo_surface_destroy (dest); - -#else - - // OSX path - nsIDrawingSurface *ds = nsnull; - rc->GetDrawingSurface(&ds); - if (!ds) - return NS_ERROR_FAILURE; - - nsDrawingSurfaceMac *macds = NS_STATIC_CAST(nsDrawingSurfaceMac*, ds); - CGContextRef cgc = macds->StartQuartzDrawing(); - - CGDataProviderRef dataProvider; - CGImageRef img; - - dataProvider = CGDataProviderCreateWithData (NULL, mImageSurfaceData, - mWidth * mHeight * 4, - NULL); - CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); - img = CGImageCreate (mWidth, mHeight, 8, 32, mWidth * 4, rgb, - (CGImageAlphaInfo)(kCGImageAlphaPremultipliedFirst | CG_BITMAP_BYTE_ORDER_FLAG), - 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); - } - - CGContextTranslateCTM (cgc, NSToIntRound(x0), NSToIntRound(y0)); - if (sx != 1.0 || sy != 1.0) - CGContextScaleCTM (cgc, sx, sy); - - // flip, so that the image gets drawn correct-side up - CGContextScaleCTM (cgc, 1.0, -1.0); - CGContextDrawImage (cgc, CGRectMake(0, -mHeight, mWidth, mHeight), img); - - CGImageRelease (img); - - macds->EndQuartzDrawing(cgc); - - rv = NS_OK; -#endif -#endif - return rv; } @@ -2236,7 +1904,6 @@ nsCanvasRenderingContext2D::CairoSurfaceFromElement(nsIDOMElement *imgElt, if (heightOut) *heightOut = imgHeight; -#ifdef MOZ_CAIRO_GFX gfxASurface* gfxsurf = nsnull; rv = img->GetSurface(&gfxsurf); NS_ENSURE_SUCCESS(rv, rv); @@ -2244,254 +1911,6 @@ nsCanvasRenderingContext2D::CairoSurfaceFromElement(nsIDOMElement *imgElt, *aCairoSurface = gfxsurf->CairoSurface(); cairo_surface_reference (*aCairoSurface); *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 b = *inrowrgb++; - PRUint8 g = *inrowrgb++; - PRUint8 r = *inrowrgb++; - -#ifdef IS_BIG_ENDIAN - // alpha - *outData++ = 0xff; -#endif - - if (useBGR) { - *outData++ = b; - *outData++ = g; - *outData++ = r; - } else { - *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 b = *inrowrgb++; - PRUint8 g = *inrowrgb++; - PRUint8 r = *inrowrgb++; - -#ifdef IS_BIG_ENDIAN - // alpha - *outData++ = 0xff; -#endif - - if (useBGR) { - *outData++ = b; - *outData++ = g; - *outData++ = r; - } else { - *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 b = (*inrowrgb++ * a - a / 2) / 255; - PRUint8 g = (*inrowrgb++ * a - a / 2) / 255; - PRUint8 r = (*inrowrgb++ * a - a / 2) / 255; - -#ifdef IS_BIG_ENDIAN - *outData++ = a; -#endif - - if (useBGR) { - *outData++ = b; - *outData++ = g; - *outData++ = r; - } else { - *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; } @@ -2594,15 +2013,6 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, PRInt32 aX, PRInt3 FlushLayoutForTree(aWindow); nsCOMPtr presContext; -#ifdef MOZILLA_1_8_BRANCH - nsCOMPtr sgo = do_QueryInterface(aWindow); - if (sgo) { - nsIDocShell* docshell = sgo->GetDocShell(); - if (docshell) { - docshell->GetPresContext(getter_AddRefs(presContext)); - } - } -#else nsCOMPtr win = do_QueryInterface(aWindow); if (win) { nsIDocShell* docshell = win->GetDocShell(); @@ -2610,154 +2020,29 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, PRInt32 aX, PRInt3 docshell->GetPresContext(getter_AddRefs(presContext)); } } -#endif if (!presContext) return NS_ERROR_FAILURE; -#ifdef MOZILLA_1_8_BRANCH - // Dig down past the viewport scroll stuff - nsIViewManager* vm = presContext->GetViewManager(); - nsIView* view; - vm->GetRootView(view); - NS_ASSERTION(view, "Must have root view!"); -#endif - nscolor bgColor; nsresult rv = mCSSParser->ParseColorString(PromiseFlatString(aBGColor), nsnull, 0, PR_TRUE, &bgColor); NS_ENSURE_SUCCESS(rv, rv); -#ifndef MOZILLA_1_8_BRANCH nsIPresShell* presShell = presContext->PresShell(); -#endif + NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); -#ifdef MOZ_CAIRO_GFX - mThebesContext->Save(); - //mThebesContext->NewPath(); - //mThebesContext->Rectangle(gfxRect(0, 0, aW, aH)); - //mThebesContext->Clip(); - - // XXX vlad says this shouldn't both be COLOR_ALPHA but that it is a workaround for some bug - mThebesContext->PushGroup(NS_GET_A(bgColor) == 0xff ? gfxASurface::CONTENT_COLOR_ALPHA : gfxASurface::CONTENT_COLOR_ALPHA); - - // draw background color - if (NS_GET_A(bgColor) > 0) { - mThebesContext->SetColor(gfxRGBA(bgColor)); - mThebesContext->SetOperator(gfxContext::OPERATOR_SOURCE); - mThebesContext->Paint(); - } - - // we want the window to be composited as a single image using - // whatever operator was set, so set this to the default OVER; - // the original operator will be present when we PopGroup - mThebesContext->SetOperator(gfxContext::OPERATOR_OVER); - - nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame(); - if (rootFrame) { - // XXX This shadows the other |r|, above. - nsRect r(nsPresContext::CSSPixelsToAppUnits(aX), - nsPresContext::CSSPixelsToAppUnits(aY), - nsPresContext::CSSPixelsToAppUnits(aW), - nsPresContext::CSSPixelsToAppUnits(aH)); - - nsDisplayListBuilder builder(rootFrame, PR_FALSE, PR_FALSE); - nsDisplayList list; - nsIScrollableView* scrollingView = nsnull; - presContext->GetViewManager()->GetRootScrollableView(&scrollingView); - - if (scrollingView) { - nscoord x, y; - scrollingView->GetScrollPosition(x, y); - r.MoveBy(-x, -y); - builder.SetIgnoreScrollFrame(presShell->GetRootScrollFrame()); - } - - rv = rootFrame->BuildDisplayListForStackingContext(&builder, r, &list); - if (NS_SUCCEEDED(rv)) { - nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); - // Ensure that r.x,r.y gets drawn at (0,0) - mThebesContext->Save(); - mThebesContext->Translate(gfxPoint(-NSAppUnitsToFloatPixels(r.x,appUnitsPerDevPixel), - -NSAppUnitsToFloatPixels(r.y,appUnitsPerDevPixel))); - - nsIDeviceContext* devCtx = presContext->DeviceContext(); - nsCOMPtr rc; - devCtx->CreateRenderingContextInstance(*getter_AddRefs(rc)); - rc->Init(devCtx, mThebesContext); - - nsRegion region(r); - list.OptimizeVisibility(&builder, ®ion); - list.Paint(&builder, rc, r); - // Flush the list so we don't trigger the IsEmpty-on-destruction assertion - list.DeleteAll(); - - mThebesContext->Restore(); - } - } - - mThebesContext->PopGroupToSource(); - mThebesContext->Paint(); - mThebesContext->Restore(); + nsRect r(nsPresContext::CSSPixelsToAppUnits(aX), + nsPresContext::CSSPixelsToAppUnits(aY), + nsPresContext::CSSPixelsToAppUnits(aW), + nsPresContext::CSSPixelsToAppUnits(aH)); + presShell->RenderDocument(r, PR_FALSE, PR_TRUE, bgColor, + mThebesContext); // get rid of the pattern surface ref, just in case cairo_set_source_rgba (mCairo, 1, 1, 1, 1); DirtyAllStyles(); Redraw(); -#else - - nsCOMPtr blackCtx; -#ifdef MOZILLA_1_8_BRANCH - rv = vm->RenderOffscreen(view, r, PR_FALSE, PR_TRUE, - NS_ComposeColors(NS_RGB(0, 0, 0), bgColor), - getter_AddRefs(blackCtx)); -#else - rv = presShell->RenderOffscreen(r, PR_FALSE, PR_TRUE, - NS_ComposeColors(NS_RGB(0, 0, 0), bgColor), - getter_AddRefs(blackCtx)); -#endif - NS_ENSURE_SUCCESS(rv, rv); - - nsIDrawingSurface* blackSurface; - blackCtx->GetDrawingSurface(&blackSurface); - if (!blackSurface) - return NS_ERROR_FAILURE; - - // Render it! - if (NS_GET_A(bgColor) == 0xFF) { - // opaque background. Do it the easy way. - rv = DrawNativeSurfaces(blackSurface, nsnull, nsSize(aW, aH), blackCtx); - blackCtx->DestroyDrawingSurface(blackSurface); - return rv; - } - - // transparent background. Do it the hard way. We've drawn onto black, - // now draw onto white so we can recover the translucency information. - // But we need to compose our given background color onto black/white - // to get the real background to use. - nsCOMPtr whiteCtx; -#ifdef MOZILLA_1_8_BRANCH - rv = vm->RenderOffscreen(view, r, PR_FALSE, PR_TRUE, - NS_ComposeColors(NS_RGB(255, 255, 255), bgColor), - getter_AddRefs(whiteCtx)); -#else - rv = presShell->RenderOffscreen(r, PR_FALSE, PR_TRUE, - NS_ComposeColors(NS_RGB(255, 255, 255), bgColor), - getter_AddRefs(whiteCtx)); -#endif - if (NS_SUCCEEDED(rv)) { - nsIDrawingSurface* whiteSurface; - whiteCtx->GetDrawingSurface(&whiteSurface); - if (!whiteSurface) { - rv = NS_ERROR_FAILURE; - } else { - rv = DrawNativeSurfaces(blackSurface, whiteSurface, nsSize(aW, aH), blackCtx); - whiteCtx->DestroyDrawingSurface(whiteSurface); - } - } - - blackCtx->DestroyDrawingSurface(blackSurface); -#endif return rv; } @@ -2781,195 +2066,6 @@ static PRUint32 ComputeScaleFactor(PRUint32 aBits) return table[aBits]; } -nsresult -nsCanvasRenderingContext2D::DrawNativeSurfaces(nsIDrawingSurface* aBlackSurface, - nsIDrawingSurface* aWhiteSurface, - const nsIntSize& aSurfaceSize, - nsIRenderingContext* aBlackContext) -{ - // check if the dimensions are too large; - // if they are, we may easily overflow malloc later on - if (!CheckSaneImageSize (aSurfaceSize.width, aSurfaceSize.height)) - return NS_ERROR_FAILURE; - - // Acquire alpha values - nsAutoArrayPtr alphas; - nsresult rv; - if (aWhiteSurface) { - // There is transparency. Use the blender to recover alphas. - nsCOMPtr blender = do_CreateInstance(kBlenderCID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr dc; - aBlackContext->GetDeviceContext(*getter_AddRefs(dc)); - rv = blender->Init(dc); - NS_ENSURE_SUCCESS(rv, rv); - - rv = blender->GetAlphas(nsRect(0, 0, aSurfaceSize.width, aSurfaceSize.height), - aBlackSurface, aWhiteSurface, getter_Transfers(alphas)); - NS_ENSURE_SUCCESS(rv, rv); - } - - // We use aBlackSurface to get the image color data - PRUint8* data; - PRInt32 rowLen, rowSpan; - rv = aBlackSurface->Lock(0, 0, aSurfaceSize.width, aSurfaceSize.height, - (void**)&data, &rowSpan, &rowLen, - NS_LOCK_SURFACE_READ_ONLY); - if (NS_FAILED(rv)) - return rv; - - // Get info about native surface layout - PRUint32 bytesPerPix = rowLen/aSurfaceSize.width; - nsPixelFormat format; - -#ifndef XP_MACOSX - rv = aBlackSurface->GetPixelFormat(&format); - if (NS_FAILED(rv)) { - aBlackSurface->Unlock(); - return rv; - } -#else - // On the mac, GetPixelFormat returns NS_ERROR_NOT_IMPLEMENTED; - // we fake the pixel format here. The data that we care about - // will be in ABGR format, either 8-8-8 or 5-5-5. - - if (bytesPerPix == 4) { - format.mRedZeroMask = 0xff; - format.mGreenZeroMask = 0xff; - format.mBlueZeroMask = 0xff; - format.mAlphaZeroMask = 0; - - format.mRedMask = 0x00ff0000; - format.mGreenMask = 0x0000ff00; - format.mBlueMask = 0x000000ff; - format.mAlphaMask = 0; - - format.mRedCount = 8; - format.mGreenCount = 8; - format.mBlueCount = 8; - format.mAlphaCount = 0; - - format.mRedShift = 16; - format.mGreenShift = 8; - format.mBlueShift = 0; - format.mAlphaShift = 0; - } else if (bytesPerPix == 2) { - format.mRedZeroMask = 0x1f; - format.mGreenZeroMask = 0x1f; - format.mBlueZeroMask = 0x1f; - format.mAlphaZeroMask = 0; - - format.mRedMask = 0x7C00; - format.mGreenMask = 0x03E0; - format.mBlueMask = 0x001F; - format.mAlphaMask = 0; - - format.mRedCount = 5; - format.mGreenCount = 5; - format.mBlueCount = 5; - format.mAlphaCount = 0; - - format.mRedShift = 10; - format.mGreenShift = 5; - format.mBlueShift = 0; - format.mAlphaShift = 0; - } else { - // no clue! - aBlackSurface->Unlock(); - return NS_ERROR_FAILURE; - } - -#endif - - // Create a temporary surface to hold the full-size image in cairo - // image format. - nsAutoArrayPtr tmpBuf(new (std::nothrow) PRUint8[aSurfaceSize.width*aSurfaceSize.height*4]); - if (!tmpBuf) { - aBlackSurface->Unlock(); - return NS_ERROR_OUT_OF_MEMORY; - } - - cairo_surface_t *tmpSurf = - cairo_image_surface_create_for_data(tmpBuf.get(), - CAIRO_FORMAT_ARGB32, aSurfaceSize.width, aSurfaceSize.height, - aSurfaceSize.width*4); - if (!tmpSurf) { - aBlackSurface->Unlock(); - return NS_ERROR_OUT_OF_MEMORY; - } - -#ifdef IS_BIG_ENDIAN -#define BLUE_BYTE 3 -#define GREEN_BYTE 2 -#define RED_BYTE 1 -#define ALPHA_BYTE 0 -#else -#define BLUE_BYTE 0 -#define GREEN_BYTE 1 -#define RED_BYTE 2 -#define ALPHA_BYTE 3 -#endif - -// Mac surfaces are big endian. -#if defined(IS_BIG_ENDIAN) || defined(XP_MACOSX) -#define NATIVE_SURFACE_IS_BIG_ENDIAN -#endif - -// OS/2 needs this painted the other way around -#ifdef XP_OS2 -#define NATIVE_SURFACE_IS_VERTICALLY_FLIPPED -#endif - - // Convert the data - PRUint8* dest = tmpBuf; - PRInt32 index = 0; - - PRUint32 RScale = ComputeScaleFactor(format.mRedCount); - PRUint32 GScale = ComputeScaleFactor(format.mGreenCount); - PRUint32 BScale = ComputeScaleFactor(format.mBlueCount); - - for (PRInt32 i = 0; i < aSurfaceSize.height; ++i) { -#ifdef NATIVE_SURFACE_IS_VERTICALLY_FLIPPED - PRUint8* src = data + (aSurfaceSize.height-1 - i)*rowSpan; -#else - PRUint8* src = data + i*rowSpan; -#endif - for (PRInt32 j = 0; j < aSurfaceSize.width; ++j) { - /* v is the pixel value */ -#ifdef NATIVE_SURFACE_IS_BIG_ENDIAN - PRUint32 v = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; - v >>= (32 - 8*bytesPerPix); -#else - PRUint32 v = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); -#endif - // Note that because aBlackSurface is the image rendered - // onto black, the channel values we get here have - // effectively been premultipled by the alpha value. - dest[BLUE_BYTE] = - (PRUint8)((((v & format.mBlueMask) >> format.mBlueShift)*BScale) >> 8); - dest[GREEN_BYTE] = - (PRUint8)((((v & format.mGreenMask) >> format.mGreenShift)*GScale) >> 8); - dest[RED_BYTE] = - (PRUint8)((((v & format.mRedMask) >> format.mRedShift)*RScale) >> 8); - dest[ALPHA_BYTE] = alphas ? alphas[index++] : 0xFF; - src += bytesPerPix; - dest += 4; - } - } - -#undef RED_BYTE -#undef GREEN_BYTE -#undef BLUE_BYTE -#undef ALPHA_BYTE - - cairo_set_source_surface(mCairo, tmpSurf, 0, 0); - cairo_paint_with_alpha(mCairo, CurrentState().globalAlpha); - - cairo_surface_destroy(tmpSurf); - aBlackSurface->Unlock(); - return Redraw(); -} - // // device pixel getting/setting //