 Chromium Code Reviews
 Chromium Code Reviews Issue 6849030:
  Add support for multi resolution icons   (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 6849030:
  Add support for multi resolution icons   (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| 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> colorSpace( | |
| 
Robert Sesek
2011/04/18 22:48:13
nit: use under_scores in C++, so this should be co
 
sail
2011/04/19 00:21:53
Done.
 | |
| 202 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | |
| 203 NSImage* image = [[[NSImage alloc] init] autorelease]; | |
| 204 NSSize minSize = NSZeroSize; | |
| 
Robert Sesek
2011/04/18 22:48:13
nit: min_size
 
sail
2011/04/19 00:21:53
Done.
 | |
| 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, colorSpace)); | |
| 212 | |
| 213 // Now convert to NSImage. | |
| 214 scoped_nsobject<NSBitmapImageRep> bitmap( | |
| 215 [[NSBitmapImageRep alloc] initWithCGImage:cgimage]); | |
| 216 [image addRepresentation:bitmap]; | |
| 217 | |
| 218 if (minSize.width == 0 || minSize.width > skiaBitmap.width()) { | |
| 219 minSize.width = skiaBitmap.width(); | |
| 220 minSize.height = skiaBitmap.height(); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 [image setSize:minSize]; | |
| 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 |