diff options
Diffstat (limited to 'chromium/skia/ext/skia_utils_mac.mm')
-rw-r--r-- | chromium/skia/ext/skia_utils_mac.mm | 96 |
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_; } |