imgFrame::SurfaceWithFormat imgFrame::SurfaceForDrawing(bool aDoPadding, bool aDoPartialDecode, bool aDoTile, const nsIntMargin& aPadding, gfxMatrix& aUserSpaceToImageSpace, gfxRect& aFill, gfxRect& aSubimage, gfxRect& aSourceRect, gfxRect& aImageRect) { gfxIntSize size(PRInt32(aImageRect.Width()), PRInt32(aImageRect.Height())); if (!aDoPadding && !aDoPartialDecode) { NS_ASSERTION(!mSinglePixel, "This should already have been handled"); return SurfaceWithFormat(new gfxSurfaceDrawable(ThebesSurface(), size), mFormat); } gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height); if (aDoTile || mSinglePixel) { // Create a temporary surface. // Give this surface an alpha channel because there are // transparent pixels in the padding or undecoded area gfxImageSurface::gfxImageFormat format = gfxASurface::ImageFormatARGB32; nsRefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, gfxImageSurface::ContentFromFormat(format)); if (!surface || surface->CairoStatus()) return SurfaceWithFormat(); // Fill 'available' with whatever we've got gfxContext tmpCtx(surface); tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE); if (mSinglePixel) { tmpCtx.SetDeviceColor(mSinglePixelColor); } else { tmpCtx.SetSource(ThebesSurface(), gfxPoint(aPadding.left, aPadding.top)); } tmpCtx.Rectangle(available); tmpCtx.Fill(); return SurfaceWithFormat(new gfxSurfaceDrawable(surface, size), format); } // Not tiling, and we have a surface, so we can account for // padding and/or a partial decode just by twiddling parameters. // First, update our user-space fill rect. aSourceRect = aSourceRect.Intersect(available); gfxMatrix imageSpaceToUserSpace = aUserSpaceToImageSpace; imageSpaceToUserSpace.Invert(); aFill = imageSpaceToUserSpace.Transform(aSourceRect); aSubimage = aSubimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top); aUserSpaceToImageSpace.Multiply(gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top))); aSourceRect = aSourceRect - gfxPoint(aPadding.left, aPadding.top); aImageRect = gfxRect(0, 0, mSize.width, mSize.height); gfxIntSize availableSize(mDecoded.width, mDecoded.height); return SurfaceWithFormat(new gfxSurfaceDrawable(ThebesSurface(), availableSize), mFormat); }
static bool AccumulateLayerTransforms2D(Layer* aLayer, Layer* aAncestor, gfxMatrix& aMatrix) { // Accumulate the transforms between this layer and the subtree root layer. for (Layer* l = aLayer; l && l != aAncestor; l = l->GetParent()) { gfxMatrix l2D; if (!GetBaseTransform2D(l, &l2D)) { return false; } aMatrix.Multiply(l2D); } return true; }