| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "skia/ext/skia_utils_mac.h" | 5 #include "skia/ext/skia_utils_mac.h" | 
| 6 | 6 | 
| 7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> | 
| 8 | 8 | 
| 9 #include "base/logging.h" | 9 #include "base/logging.h" | 
| 10 #include "base/mac/scoped_cftyperef.h" | 10 #include "base/mac/scoped_cftyperef.h" | 
|  | 11 #include "base/memory/scoped_nsobject.h" | 
| 11 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" | 
| 12 #include "skia/ext/bitmap_platform_device_mac.h" | 13 #include "skia/ext/bitmap_platform_device_mac.h" | 
| 13 #include "third_party/skia/include/utils/mac/SkCGUtils.h" | 14 #include "third_party/skia/include/utils/mac/SkCGUtils.h" | 
| 14 | 15 | 
| 15 namespace gfx { | 16 namespace gfx { | 
| 16 | 17 | 
| 17 CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix) { | 18 CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix) { | 
| 18   // CGAffineTransforms don't support perspective transforms, so make sure | 19   // CGAffineTransforms don't support perspective transforms, so make sure | 
| 19   // we don't get those. | 20   // we don't get those. | 
| 20   DCHECK(matrix[SkMatrix::kMPersp0] == 0.0f); | 21   DCHECK(matrix[SkMatrix::kMPersp0] == 0.0f); | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 109   CGContextDrawImage(context, rect, image); | 110   CGContextDrawImage(context, rect, image); | 
| 110 | 111 | 
| 111   // Because |device| will be cleaned up and will take its pixels with it, we | 112   // Because |device| will be cleaned up and will take its pixels with it, we | 
| 112   // copy it to the stack and return it. | 113   // copy it to the stack and return it. | 
| 113   SkBitmap bitmap = device->accessBitmap(false); | 114   SkBitmap bitmap = device->accessBitmap(false); | 
| 114 | 115 | 
| 115   return bitmap; | 116   return bitmap; | 
| 116 } | 117 } | 
| 117 | 118 | 
| 118 SkBitmap NSImageToSkBitmap(NSImage* image, NSSize size, bool is_opaque) { | 119 SkBitmap NSImageToSkBitmap(NSImage* image, NSSize size, bool is_opaque) { | 
|  | 120   return NSImageRepToSkBitmap([image bestRepresentationForDevice:nil], | 
|  | 121                               size, is_opaque); | 
|  | 122 } | 
|  | 123 | 
|  | 124 SkBitmap NSImageRepToSkBitmap(NSImageRep* image, NSSize size, bool is_opaque) { | 
| 119   SkBitmap bitmap; | 125   SkBitmap bitmap; | 
| 120   bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width, size.height); | 126   bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width, size.height); | 
| 121   if (bitmap.allocPixels() != true) | 127   if (!bitmap.allocPixels()) | 
| 122     return bitmap;  // Return |bitmap| which should respond true to isNull(). | 128     return bitmap;  // Return |bitmap| which should respond true to isNull(). | 
| 123 | 129 | 
| 124   bitmap.setIsOpaque(is_opaque); | 130   bitmap.setIsOpaque(is_opaque); | 
| 125 | 131 | 
| 126   base::mac::ScopedCFTypeRef<CGColorSpaceRef> color_space( | 132   base::mac::ScopedCFTypeRef<CGColorSpaceRef> color_space( | 
| 127     CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | 133       CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | 
| 128   void* data = bitmap.getPixels(); | 134   void* data = bitmap.getPixels(); | 
| 129 | 135 | 
| 130   // Allocate a bitmap context with 4 components per pixel (BGRA). Apple | 136   // Allocate a bitmap context with 4 components per pixel (BGRA). Apple | 
| 131   // recommends these flags for improved CG performance. | 137   // recommends these flags for improved CG performance. | 
| 132 #define HAS_ARGB_SHIFTS(a, r, g, b) \ | 138 #define HAS_ARGB_SHIFTS(a, r, g, b) \ | 
| 133             (SK_A32_SHIFT == (a) && SK_R32_SHIFT == (r) \ | 139             (SK_A32_SHIFT == (a) && SK_R32_SHIFT == (r) \ | 
| 134              && SK_G32_SHIFT == (g) && SK_B32_SHIFT == (b)) | 140              && SK_G32_SHIFT == (g) && SK_B32_SHIFT == (b)) | 
| 135 #if defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0) | 141 #if defined(SK_CPU_LENDIAN) && HAS_ARGB_SHIFTS(24, 16, 8, 0) | 
| 136   base::mac::ScopedCFTypeRef<CGContextRef> context( | 142   base::mac::ScopedCFTypeRef<CGContextRef> context( | 
| 137     CGBitmapContextCreate(data, size.width, size.height, 8, size.width*4, | 143     CGBitmapContextCreate(data, size.width, size.height, 8, size.width*4, | 
| 138                           color_space, | 144                           color_space, | 
| 139                           kCGImageAlphaPremultipliedFirst | | 145                           kCGImageAlphaPremultipliedFirst | | 
| 140                               kCGBitmapByteOrder32Host)); | 146                               kCGBitmapByteOrder32Host)); | 
| 141 #else | 147 #else | 
| 142 #error We require that Skia's and CoreGraphics's recommended \ | 148 #error We require that Skia's and CoreGraphics's recommended \ | 
| 143        image memory layout match. | 149        image memory layout match. | 
| 144 #endif | 150 #endif | 
| 145 #undef HAS_ARGB_SHIFTS | 151 #undef HAS_ARGB_SHIFTS | 
| 146 | 152 | 
| 147   // Something went really wrong. Best guess is that the bitmap data is invalid. | 153   // Something went really wrong. Best guess is that the bitmap data is invalid. | 
| 148   DCHECK(context != NULL); | 154   DCHECK(context); | 
| 149 | 155 | 
| 150   // Save the current graphics context so that we can restore it later. | 156   // Save the current graphics context so that we can restore it later. | 
| 151   [NSGraphicsContext saveGraphicsState]; | 157   [NSGraphicsContext saveGraphicsState]; | 
| 152 | 158 | 
| 153   // Dummy context that we will draw into. | 159   // Dummy context that we will draw into. | 
| 154   NSGraphicsContext* context_cocoa = | 160   NSGraphicsContext* context_cocoa = | 
| 155     [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]; | 161       [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]; | 
| 156   [NSGraphicsContext setCurrentContext:context_cocoa]; | 162   [NSGraphicsContext setCurrentContext:context_cocoa]; | 
| 157 | 163 | 
| 158   // This will stretch any images to |size| if it does not fit or is non-square. | 164   // This will stretch any images to |size| if it does not fit or is non-square. | 
| 159   [image drawInRect:NSMakeRect(0, 0, size.width, size.height) | 165   [image drawInRect:NSMakeRect(0, 0, size.width, size.height)]; | 
| 160            fromRect:NSZeroRect |  | 
| 161           operation:NSCompositeCopy |  | 
| 162            fraction:1.0]; |  | 
| 163 | 166 | 
| 164   // Done drawing, restore context. | 167   // Done drawing, restore context. | 
| 165   [NSGraphicsContext restoreGraphicsState]; | 168   [NSGraphicsContext restoreGraphicsState]; | 
| 166 | 169 | 
| 167   return bitmap; | 170   return bitmap; | 
| 168 } | 171 } | 
| 169 | 172 | 
| 170 NSImage* SkBitmapToNSImageWithColorSpace(const SkBitmap& skiaBitmap, | 173 NSImage* SkBitmapToNSImageWithColorSpace(const SkBitmap& skiaBitmap, | 
| 171                                          CGColorSpaceRef colorSpace) { | 174                                          CGColorSpaceRef colorSpace) { | 
| 172   if (skiaBitmap.isNull()) | 175   if (skiaBitmap.isNull()) | 
| 173     return nil; | 176     return nil; | 
| 174 | 177 | 
| 175   // First convert SkBitmap to CGImageRef. | 178   // First convert SkBitmap to CGImageRef. | 
| 176   CGImageRef cgimage = | 179   base::mac::ScopedCFTypeRef<CGImageRef> cgimage( | 
| 177     SkCreateCGImageRefWithColorspace(skiaBitmap, colorSpace); | 180       SkCreateCGImageRefWithColorspace(skiaBitmap, colorSpace)); | 
| 178 | 181 | 
| 179   // Now convert to NSImage. | 182   // Now convert to NSImage. | 
| 180   NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] | 183   scoped_nsobject<NSBitmapImageRep> bitmap( | 
| 181                                    initWithCGImage:cgimage] autorelease]; | 184       [[NSBitmapImageRep alloc] initWithCGImage:cgimage]); | 
| 182   CFRelease(cgimage); |  | 
| 183   NSImage* image = [[[NSImage alloc] init] autorelease]; | 185   NSImage* image = [[[NSImage alloc] init] autorelease]; | 
| 184   [image addRepresentation:bitmap]; | 186   [image addRepresentation:bitmap]; | 
| 185   [image setSize:NSMakeSize(skiaBitmap.width(), skiaBitmap.height())]; | 187   [image setSize:NSMakeSize(skiaBitmap.width(), skiaBitmap.height())]; | 
| 186   return image; | 188   return image; | 
| 187 } | 189 } | 
| 188 | 190 | 
| 189 NSImage* SkBitmapToNSImage(const SkBitmap& skiaBitmap) { | 191 NSImage* SkBitmapToNSImage(const SkBitmap& skiaBitmap) { | 
| 190   base::mac::ScopedCFTypeRef<CGColorSpaceRef> colorSpace( | 192   base::mac::ScopedCFTypeRef<CGColorSpaceRef> colorSpace( | 
| 191       CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | 193       CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | 
| 192   return SkBitmapToNSImageWithColorSpace(skiaBitmap, colorSpace.get()); | 194   return SkBitmapToNSImageWithColorSpace(skiaBitmap, colorSpace.get()); | 
| 193 } | 195 } | 
| 194 | 196 | 
|  | 197 NSImage* SkBitmapsToNSImage(const std::vector<const SkBitmap*>& bitmaps) { | 
|  | 198   if (bitmaps.empty()) | 
|  | 199     return nil; | 
|  | 200 | 
|  | 201   base::mac::ScopedCFTypeRef<CGColorSpaceRef> color_space( | 
|  | 202       CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | 
|  | 203   NSImage* image = [[[NSImage alloc] init] autorelease]; | 
|  | 204   NSSize min_size = NSZeroSize; | 
|  | 205 | 
|  | 206   for (std::vector<const SkBitmap*>::const_iterator it = bitmaps.begin(); | 
|  | 207        it != bitmaps.end(); ++it) { | 
|  | 208     const SkBitmap& skiaBitmap = **it; | 
|  | 209     // First convert SkBitmap to CGImageRef. | 
|  | 210     base::mac::ScopedCFTypeRef<CGImageRef> cgimage( | 
|  | 211         SkCreateCGImageRefWithColorspace(skiaBitmap, color_space)); | 
|  | 212 | 
|  | 213     // Now convert to NSImage. | 
|  | 214     scoped_nsobject<NSBitmapImageRep> bitmap( | 
|  | 215         [[NSBitmapImageRep alloc] initWithCGImage:cgimage]); | 
|  | 216     [image addRepresentation:bitmap]; | 
|  | 217 | 
|  | 218     if (min_size.width == 0 || min_size.width > skiaBitmap.width()) { | 
|  | 219       min_size.width = skiaBitmap.width(); | 
|  | 220       min_size.height = skiaBitmap.height(); | 
|  | 221     } | 
|  | 222   } | 
|  | 223 | 
|  | 224   [image setSize:min_size]; | 
|  | 225   return image; | 
|  | 226 } | 
|  | 227 | 
| 195 SkBitmap AppplicationIconAtSize(int size) { | 228 SkBitmap AppplicationIconAtSize(int size) { | 
| 196   NSImage* image = [NSImage imageNamed:@"NSApplicationIcon"]; | 229   NSImage* image = [NSImage imageNamed:@"NSApplicationIcon"]; | 
| 197   return NSImageToSkBitmap(image, NSMakeSize(size, size), /* is_opaque=*/true); | 230   return NSImageToSkBitmap(image, NSMakeSize(size, size), /* is_opaque=*/true); | 
| 198 } | 231 } | 
| 199 | 232 | 
| 200 }  // namespace gfx | 233 }  // namespace gfx | 
| OLD | NEW | 
|---|