summaryrefslogtreecommitdiffstats
path: root/chromium/skia/ext/skia_utils_mac.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/skia/ext/skia_utils_mac.mm')
-rw-r--r--chromium/skia/ext/skia_utils_mac.mm96
1 files changed, 38 insertions, 58 deletions
diff --git a/chromium/skia/ext/skia_utils_mac.mm b/chromium/skia/ext/skia_utils_mac.mm
index dcc2cccffc6..4f7ddd98f2d 100644
--- a/chromium/skia/ext/skia_utils_mac.mm
+++ b/chromium/skia/ext/skia_utils_mac.mm
@@ -27,13 +27,7 @@ SkBitmap NSImageOrNSImageRepToSkBitmapWithColorSpace(
DCHECK((image != 0) ^ (image_rep != 0));
SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config,
- size.width,
- size.height,
- 0,
- is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
-
- if (!bitmap.allocPixels())
+ if (!bitmap.allocN32Pixels(size.width, size.height, is_opaque))
return bitmap; // Return |bitmap| which should respond true to isNull().
@@ -134,10 +128,10 @@ CGRect SkRectToCGRect(const SkRect& rect) {
SkColor CGColorRefToSkColor(CGColorRef color) {
DCHECK(CGColorGetNumberOfComponents(color) == 4);
const CGFloat* components = CGColorGetComponents(color);
- return SkColorSetARGB(SkScalarRound(255.0 * components[3]), // alpha
- SkScalarRound(255.0 * components[0]), // red
- SkScalarRound(255.0 * components[1]), // green
- SkScalarRound(255.0 * components[2])); // blue
+ return SkColorSetARGB(SkScalarRoundToInt(255.0 * components[3]), // alpha
+ SkScalarRoundToInt(255.0 * components[0]), // red
+ SkScalarRoundToInt(255.0 * components[1]), // green
+ SkScalarRoundToInt(255.0 * components[2])); // blue
}
// Converts ARGB to CGColorRef.
@@ -155,10 +149,10 @@ SkColor NSDeviceColorToSkColor(NSColor* color) {
CGFloat red, green, blue, alpha;
color = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
[color getRed:&red green:&green blue:&blue alpha:&alpha];
- return SkColorSetARGB(SkScalarRound(255.0 * alpha),
- SkScalarRound(255.0 * red),
- SkScalarRound(255.0 * green),
- SkScalarRound(255.0 * blue));
+ return SkColorSetARGB(SkScalarRoundToInt(255.0 * alpha),
+ SkScalarRoundToInt(255.0 * red),
+ SkScalarRoundToInt(255.0 * green),
+ SkScalarRoundToInt(255.0 * blue));
}
// Converts ARGB to NSColor.
@@ -362,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_);
@@ -370,20 +365,36 @@ 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
+
+ // remember the top/left, in case we need to compose this later
+ bitmapOffset_.set(clip_bounds.x(), clip_bounds.y());
+
+ // Now make clip_bounds be relative to the current layer/device
+ clip_bounds.offset(-device->getOrigin());
+
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;
+ if (!deviceBits.extractSubset(&bitmap_, clip_bounds))
+ return 0;
bitmap_.lockPixels();
} else {
- bitmap_.setConfig(
- SkBitmap::kARGB_8888_Config, deviceBits.width(), deviceBits.height());
- bitmap_.allocPixels();
+ if (!bitmap_.allocN32Pixels(clip_bounds.width(), clip_bounds.height()))
+ return 0;
bitmap_.eraseColor(0);
}
base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace(
@@ -392,44 +403,13 @@ CGContextRef SkiaBitLocker::cgContext() {
bitmap_.height(), 8, bitmap_.rowBytes(), colorSpace,
kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
- // Apply device matrix.
- CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
- contentsTransform = CGAffineTransformTranslate(contentsTransform, 0,
- -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.
- 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);
- }
+ SkMatrix matrix = canvas_->getTotalMatrix();
+ matrix.postTranslate(-SkIntToScalar(bitmapOffset_.x()),
+ -SkIntToScalar(bitmapOffset_.y()));
+ matrix.postScale(1, -1);
+ matrix.postTranslate(0, SkIntToScalar(bitmap_.height()));
- // Apply content matrix.
- SkMatrix skMatrix = canvas_->getTotalMatrix();
- skMatrix.postTranslate(-SkIntToScalar(pt.fX), -SkIntToScalar(pt.fY));
- CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix);
- CGContextConcatCTM(cgContext_, affine);
+ CGContextConcatCTM(cgContext_, SkMatrixToCGAffineTransform(matrix));
return cgContext_;
}