Index: skia/ext/skia_utils_mac.mm |
diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm |
index f67d3c1c02de34ec181e768770ab2db6fab9650c..8af5bcc80d66f0c538e0cfdbf9eab0decb61845d 100644 |
--- a/skia/ext/skia_utils_mac.mm |
+++ b/skia/ext/skia_utils_mac.mm |
@@ -356,7 +356,8 @@ foundRight: |
return; |
canvas_->save(); |
canvas_->concat(inverse); |
- canvas_->drawBitmap(subset, bounds.fLeft, bounds.fTop); |
+ canvas_->drawBitmap(subset, bounds.x() + bitmapOffset_.x(), |
+ bounds.y() + bitmapOffset_.y()); |
canvas_->restore(); |
} |
CGContextRelease(cgContext_); |
@@ -364,20 +365,29 @@ foundRight: |
} |
CGContextRef SkiaBitLocker::cgContext() { |
+ SkIRect clip_bounds; |
+ if (!canvas_->getClipDeviceBounds(&clip_bounds)) |
+ return 0; // the clip is empty, nothing to draw |
+ |
SkBaseDevice* device = canvas_->getTopDevice(); |
DCHECK(device); |
if (!device) |
return 0; |
+ |
releaseIfNeeded(); // This flushes any prior bitmap use |
const SkBitmap& deviceBits = device->accessBitmap(true); |
- useDeviceBits_ = deviceBits.getPixels(); |
+ // Only draw directly if we have pixels, and we're only rect-clipped. |
+ // If not, we allocate an offscreen and draw into that, relying on the |
+ // compositing step to apply skia's clip. |
+ useDeviceBits_ = deviceBits.getPixels() && canvas_->isClipRect(); |
if (useDeviceBits_) { |
bitmap_ = deviceBits; |
bitmap_.lockPixels(); |
f(malita)
2014/06/19 18:39:54
bitmapOffset_.setZero();
reed1
2014/06/19 18:57:18
It won't get read in this case, but I will add the
|
} else { |
- if (!bitmap_.allocN32Pixels(deviceBits.width(), deviceBits.height())) |
+ if (!bitmap_.allocN32Pixels(clip_bounds.width(), clip_bounds.height())) |
return 0; |
bitmap_.eraseColor(0); |
+ bitmapOffset_.set(clip_bounds.x(), clip_bounds.y()); |
} |
base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace( |
CGColorSpaceCreateDeviceRGB()); |
@@ -391,36 +401,17 @@ CGContextRef SkiaBitLocker::cgContext() { |
-device->height()); |
CGContextConcatCTM(cgContext_, contentsTransform); |
- const SkIPoint& pt = device->getOrigin(); |
- // Skip applying the clip when not writing directly to device. |
- // They're applied in the offscreen case when the bitmap is drawn. |
+ // get clip_bounds into the coordinate system of the top layer/device |
+ clip_bounds.offset(-device->getOrigin()); |
+ |
if (useDeviceBits_) { |
- // Apply clip in device coordinates. |
- CGMutablePathRef clipPath = CGPathCreateMutable(); |
- const SkRegion& clipRgn = canvas_->getTotalClip(); |
- if (clipRgn.isEmpty()) { |
- // CoreGraphics does not consider a newly created path to be empty. |
- // Explicitly set it to empty so the subsequent drawing is clipped out. |
- // It would be better to make the CGContext hidden if there was a CG |
- // call that does that. |
- CGPathAddRect(clipPath, 0, CGRectMake(0, 0, 0, 0)); |
- } |
- SkRegion::Iterator iter(clipRgn); |
- const SkIPoint& pt = device->getOrigin(); |
- for (; !iter.done(); iter.next()) { |
- SkIRect skRect = iter.rect(); |
- skRect.offset(-pt); |
- CGRect cgRect = SkIRectToCGRect(skRect); |
- CGPathAddRect(clipPath, 0, cgRect); |
- } |
- CGContextAddPath(cgContext_, clipPath); |
- CGContextClip(cgContext_); |
- CGPathRelease(clipPath); |
+ CGContextClipToRect(cgContext_, SkIRectToCGRect(clip_bounds)); |
} |
// Apply content matrix. |
SkMatrix skMatrix = canvas_->getTotalMatrix(); |
- skMatrix.postTranslate(-SkIntToScalar(pt.fX), -SkIntToScalar(pt.fY)); |
+ skMatrix.postTranslate(-SkIntToScalar(clip_bounds.x()), |
f(malita)
2014/06/19 18:39:54
Do we still need to include the clip offset here w
reed1
2014/06/19 18:57:18
I think so. From CG's perspective, both scenarios
|
+ -SkIntToScalar(clip_bounds.y())); |
CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix); |
CGContextConcatCTM(cgContext_, affine); |