Bug 892964. Rewrite DrawTargetCG::MaskSurface to avoid using FillRect(). r=mattwoodrow

With FillRect we were setting the transform twice.

The patch looks really bad because I needed to move the implementation of
MaskSurface so that it was below the helper methods.

The actual change is:

-  FillRect(Rect(aOffset.x, aOffset.y, size.width, size.height), aSource, aDrawOptions);
-
+  if (isGradient(aSource)) {
+    // we shouldn't need to clip to an additional rectangle
+    // as the cliping to the mask should be sufficient.
+    DrawGradient(cg, aSource);
+  } else {
+    SetFillFromPattern(cg, mColorSpace, aSource);
+    CGContextFillRect(cg, CGRectMake(aOffset.x, aOffset.y, size.width, size.height));
+  }

This also avoids setting up other state like alpha and the unboundness fixer twice.

--HG--
extra : rebase_source : 762f2d94ddaff129d584aab1e1f429ddfea99277
This commit is contained in:
Jeff Muizelaar 2013-07-08 17:35:56 -04:00
parent a218c2bf40
commit a814b7f1d1

View File

@ -300,40 +300,6 @@ DrawTargetCG::DrawSurface(SourceSurface *aSurface,
CGImageRelease(subimage);
}
void
DrawTargetCG::MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
const DrawOptions &aDrawOptions)
{
MarkChanged();
CGImageRef image;
CGContextSaveGState(mCg);
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
UnboundnessFixer fixer;
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
image = GetImageFromSourceSurface(aMask);
CGContextScaleCTM(cg, 1, -1);
IntSize size = aMask->GetSize();
CGContextClipToMask(cg, CGRectMake(aOffset.x, -(aOffset.y + size.height), size.width, size.height), image);
CGContextScaleCTM(cg, 1, -1);
FillRect(Rect(aOffset.x, aOffset.y, size.width, size.height), aSource, aDrawOptions);
fixer.Fix(mCg);
CGContextRestoreGState(mCg);
}
static CGColorRef ColorToCGColor(CGColorSpaceRef aColorSpace, const Color& aColor)
{
CGFloat components[4] = {aColor.r, aColor.g, aColor.b, aColor.a};
@ -547,6 +513,48 @@ SetStrokeFromPattern(CGContextRef cg, CGColorSpaceRef aColorSpace, const Pattern
}
void
DrawTargetCG::MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
const DrawOptions &aDrawOptions)
{
MarkChanged();
CGImageRef image;
CGContextSaveGState(mCg);
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
UnboundnessFixer fixer;
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
image = GetImageFromSourceSurface(aMask);
// use a negative-y so that the mask image draws right ways up
CGContextScaleCTM(cg, 1, -1);
IntSize size = aMask->GetSize();
CGContextClipToMask(cg, CGRectMake(aOffset.x, -(aOffset.y + size.height), size.width, size.height), image);
CGContextScaleCTM(cg, 1, -1);
if (isGradient(aSource)) {
// we shouldn't need to clip to an additional rectangle
// as the cliping to the mask should be sufficient.
DrawGradient(cg, aSource);
} else {
SetFillFromPattern(cg, mColorSpace, aSource);
CGContextFillRect(cg, CGRectMake(aOffset.x, aOffset.y, size.width, size.height));
}
fixer.Fix(mCg);
CGContextRestoreGState(mCg);
}
void
DrawTargetCG::FillRect(const Rect &aRect,