diff options
-rw-r--r-- | chrome/browser/dom_ui/fileicon_source.cc | 7 | ||||
-rw-r--r-- | chrome/browser/icon_loader_mac.mm | 19 | ||||
-rw-r--r-- | chrome/browser/icon_manager_mac.mm | 4 | ||||
-rw-r--r-- | skia/ext/skia_utils_mac.cc | 83 | ||||
-rw-r--r-- | skia/ext/skia_utils_mac.h | 15 | ||||
-rw-r--r-- | skia/ext/skia_utils_mac.mm | 159 | ||||
-rwxr-xr-x | skia/skia.gyp | 13 | ||||
-rw-r--r-- | webkit/glue/image_decoder.cc | 40 |
8 files changed, 207 insertions, 133 deletions
diff --git a/chrome/browser/dom_ui/fileicon_source.cc b/chrome/browser/dom_ui/fileicon_source.cc index e35d49c..daf9a43 100644 --- a/chrome/browser/dom_ui/fileicon_source.cc +++ b/chrome/browser/dom_ui/fileicon_source.cc @@ -25,13 +25,12 @@ void FileIconSource::StartDataRequest(const std::string& path, int request_id) { IconManager* im = g_browser_process->icon_manager(); - // The path we receive has the wrong slashes and escaping for what we need; - // this only appears to matter for getting icons from .exe files. std::string escaped_path = UnescapeURLComponent(path, UnescapeRule::SPACES); - std::replace(escaped_path.begin(), escaped_path.end(), '/', '\\'); - // Fast look up. #if defined(OS_WIN) + // The path we receive has the wrong slashes and escaping for what we need; + // this only appears to matter for getting icons from .exe files. + std::replace(escaped_path.begin(), escaped_path.end(), '/', '\\'); FilePath escaped_filepath(UTF8ToWide(escaped_path)); #elif defined(OS_POSIX) // The correct encoding on Linux may not actually be UTF8. diff --git a/chrome/browser/icon_loader_mac.mm b/chrome/browser/icon_loader_mac.mm index 83a8305..028edf7 100644 --- a/chrome/browser/icon_loader_mac.mm +++ b/chrome/browser/icon_loader_mac.mm @@ -4,11 +4,28 @@ #include "chrome/browser/icon_loader.h" +#import <AppKit/AppKit.h> + #include "base/message_loop.h" #include "base/thread.h" +#include "base/sys_string_conversions.h" +#include "skia/ext/skia_utils_mac.h" +#include "third_party/skia/include/core/SkBitmap.h" void IconLoader::ReadIcon() { - NOTIMPLEMENTED(); + NSString* group = base::SysUTF8ToNSString(group_); + NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; + NSImage* icon = [workspace iconForFileType:group]; + + NSSize size; + if (icon_size_ == NORMAL) + size = NSMakeSize(32, 32); + else if (icon_size_ == SMALL) + size = NSMakeSize(16, 16); + else + return; + + bitmap_ = new SkBitmap(gfx::NSImageToSkBitmap(icon, size, false)); target_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &IconLoader::NotifyDelegate)); diff --git a/chrome/browser/icon_manager_mac.mm b/chrome/browser/icon_manager_mac.mm index 3e5d8be..9f13218 100644 --- a/chrome/browser/icon_manager_mac.mm +++ b/chrome/browser/icon_manager_mac.mm @@ -5,8 +5,8 @@ #include "chrome/browser/icon_manager.h" #include "base/file_path.h" +#include "base/sys_string_conversions.h" IconGroupID IconManager::GetGroupIDFromFilepath(const FilePath& filepath) { - NOTIMPLEMENTED(); - return std::string(); + return filepath.Extension(); } diff --git a/skia/ext/skia_utils_mac.cc b/skia/ext/skia_utils_mac.cc deleted file mode 100644 index fbad62d..0000000 --- a/skia/ext/skia_utils_mac.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "skia/ext/skia_utils_mac.h" - -#include "base/logging.h" -#include "third_party/skia/include/core/SkMatrix.h" -#include "third_party/skia/include/core/SkRect.h" - -namespace gfx { - -CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix) { - // CGAffineTransforms don't support perspective transforms, so make sure - // we don't get those. - DCHECK(matrix[SkMatrix::kMPersp0] == 0.0f); - DCHECK(matrix[SkMatrix::kMPersp1] == 0.0f); - DCHECK(matrix[SkMatrix::kMPersp2] == 1.0f); - - return CGAffineTransformMake(matrix[SkMatrix::kMScaleX], - matrix[SkMatrix::kMSkewY], - matrix[SkMatrix::kMSkewX], - matrix[SkMatrix::kMScaleY], - matrix[SkMatrix::kMTransX], - matrix[SkMatrix::kMTransY]); -} - -SkIRect CGRectToSkIRect(const CGRect& rect) { - SkIRect sk_rect = { - SkScalarRound(rect.origin.x), - SkScalarRound(rect.origin.y), - SkScalarRound(rect.origin.x + rect.size.width), - SkScalarRound(rect.origin.y + rect.size.height) - }; - return sk_rect; -} - -SkRect CGRectToSkRect(const CGRect& rect) { - SkRect sk_rect = { - rect.origin.x, - rect.origin.y, - rect.origin.x + rect.size.width, - rect.origin.y + rect.size.height, - }; - return sk_rect; -} - -CGRect SkIRectToCGRect(const SkIRect& rect) { - CGRect cg_rect = { - { rect.fLeft, rect.fTop }, - { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop } - }; - return cg_rect; -} - -CGRect SkRectToCGRect(const SkRect& rect) { - CGRect cg_rect = { - { rect.fLeft, rect.fTop }, - { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop } - }; - return cg_rect; -} - -// Converts CGColorRef to the ARGB layout Skia expects. -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 -} - -// Converts ARGB to CGColorRef. -CGColorRef SkColorToCGColorRef(SkColor color) { - return CGColorCreateGenericRGB(SkColorGetR(color) / 255.0, - SkColorGetG(color) / 255.0, - SkColorGetB(color) / 255.0, - SkColorGetA(color) / 255.0); -} - -} // namespace gfx - diff --git a/skia/ext/skia_utils_mac.h b/skia/ext/skia_utils_mac.h index b678abb..14cd17f 100644 --- a/skia/ext/skia_utils_mac.h +++ b/skia/ext/skia_utils_mac.h @@ -13,6 +13,12 @@ struct SkMatrix; struct SkIRect; struct SkPoint; struct SkRect; +class SkBitmap; +typedef struct _NSSize NSSize; + +#ifdef __OBJC__ +@class NSImage; +#endif namespace gfx { @@ -45,7 +51,14 @@ SkColor CGColorRefToSkColor(CGColorRef color); // Converts ARGB to CGColorRef. CGColorRef SkColorToCGColorRef(SkColor color); +// Converts a CGImage to a SkBitmap. +SkBitmap CGImageToSkBitmap(CGImageRef image); + +#ifdef __OBJC__ +// Draws an NSImage with a given size into a SkBitmap. +SkBitmap NSImageToSkBitmap(NSImage* image, NSSize size, bool is_opaque); +#endif + } // namespace gfx #endif // SKIA_EXT_SKIA_UTILS_MAC_H_ - diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm new file mode 100644 index 0000000..6880ea8 --- /dev/null +++ b/skia/ext/skia_utils_mac.mm @@ -0,0 +1,159 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "skia/ext/skia_utils_mac.h" + +#import <AppKit/AppKit.h> + +#include "base/logging.h" +#include "base/scoped_cftyperef.h" +#include "base/scoped_ptr.h" +#include "skia/ext/bitmap_platform_device_mac.h" + +namespace gfx { + +CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix) { + // CGAffineTransforms don't support perspective transforms, so make sure + // we don't get those. + DCHECK(matrix[SkMatrix::kMPersp0] == 0.0f); + DCHECK(matrix[SkMatrix::kMPersp1] == 0.0f); + DCHECK(matrix[SkMatrix::kMPersp2] == 1.0f); + + return CGAffineTransformMake(matrix[SkMatrix::kMScaleX], + matrix[SkMatrix::kMSkewY], + matrix[SkMatrix::kMSkewX], + matrix[SkMatrix::kMScaleY], + matrix[SkMatrix::kMTransX], + matrix[SkMatrix::kMTransY]); +} + +SkIRect CGRectToSkIRect(const CGRect& rect) { + SkIRect sk_rect = { + SkScalarRound(rect.origin.x), + SkScalarRound(rect.origin.y), + SkScalarRound(rect.origin.x + rect.size.width), + SkScalarRound(rect.origin.y + rect.size.height) + }; + return sk_rect; +} + +SkRect CGRectToSkRect(const CGRect& rect) { + SkRect sk_rect = { + rect.origin.x, + rect.origin.y, + rect.origin.x + rect.size.width, + rect.origin.y + rect.size.height, + }; + return sk_rect; +} + +CGRect SkIRectToCGRect(const SkIRect& rect) { + CGRect cg_rect = { + { rect.fLeft, rect.fTop }, + { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop } + }; + return cg_rect; +} + +CGRect SkRectToCGRect(const SkRect& rect) { + CGRect cg_rect = { + { rect.fLeft, rect.fTop }, + { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop } + }; + return cg_rect; +} + +// Converts CGColorRef to the ARGB layout Skia expects. +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 +} + +// Converts ARGB to CGColorRef. +CGColorRef SkColorToCGColorRef(SkColor color) { + return CGColorCreateGenericRGB(SkColorGetR(color) / 255.0, + SkColorGetG(color) / 255.0, + SkColorGetB(color) / 255.0, + SkColorGetA(color) / 255.0); +} + +SkBitmap CGImageToSkBitmap(CGImageRef image) { + DCHECK(image != NULL); + + int width = CGImageGetWidth(image); + int height = CGImageGetHeight(image); + + scoped_ptr<skia::BitmapPlatformDevice> device( + skia::BitmapPlatformDevice::Create(NULL, width, height, false)); + + CGContextRef context = device->GetBitmapContext(); + + // We need to invert the y-axis of the canvas so that Core Graphics drawing + // happens right-side up. Skia has an upper-left origin and CG has a lower- + // left one. + CGContextScaleCTM(context, 1.0, -1.0); + CGContextTranslateCTM(context, 1, -height); + + // We want to copy transparent pixels from |image|, instead of blending it + // onto uninitialized pixels. + CGContextSetBlendMode(context, kCGBlendModeCopy); + + CGRect rect = CGRectMake(0, 0, width, height); + CGContextDrawImage(context, rect, image); + + // Because |device| will be cleaned up and will take its pixels with it, we + // copy it to the stack and return it. + SkBitmap bitmap = device->accessBitmap(false); + + return bitmap; +} + +SkBitmap NSImageToSkBitmap(NSImage* image, NSSize size, bool is_opaque) { + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width, size.height); + if (bitmap.allocPixels() != true) + return bitmap; // Return |bitmap| which should respond true to isNull(). + + bitmap.setIsOpaque(is_opaque); + + scoped_cftyperef<CGColorSpaceRef> color_space( + CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); + void* data = bitmap.getPixels(); + + // Allocate a bitmap context with 4 components per pixel (BGRA). Apple + // recommends these flags for improved CG performance. + scoped_cftyperef<CGContextRef> context( + CGBitmapContextCreate(data, size.width, size.height, 8, size.width*4, + color_space, + kCGImageAlphaPremultipliedFirst | + kCGBitmapByteOrder32Host)); + + // Something went really wrong. Best guess is that the bitmap data is invalid. + DCHECK(context != NULL); + + // Save the current graphics context so that we can restore it later. + NSGraphicsContext* current_context = [NSGraphicsContext currentContext]; + + // Dummy context that we will draw into. + NSGraphicsContext* context_cocoa = + [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:NO]; + [NSGraphicsContext setCurrentContext:context_cocoa]; + + // This will stretch any images to |size| if it does not fit or is non-square. + [image drawInRect:NSMakeRect(0, 0, size.width, size.height) + fromRect:NSZeroRect + operation:NSCompositeCopy + fraction:1.0]; + + // Done drawing, restore context. + [NSGraphicsContext setCurrentContext:current_context]; + + return bitmap; +} + +} // namespace gfx diff --git a/skia/skia.gyp b/skia/skia.gyp index 912e80a..a3e55b2 100755 --- a/skia/skia.gyp +++ b/skia/skia.gyp @@ -525,7 +525,7 @@ 'ext/SkTypeface_fake.cpp', 'ext/skia_utils.cc', 'ext/skia_utils.h', - 'ext/skia_utils_mac.cc', + 'ext/skia_utils_mac.mm', 'ext/skia_utils_mac.h', 'ext/skia_utils_win.cc', 'ext/skia_utils_win.h', @@ -608,9 +608,14 @@ 'defines': [ 'SK_BUILD_FOR_MAC', ], - 'include_dirs': [ - '../third_party/skia/include/utils/mac', - ], + 'include_dirs': [ + '../third_party/skia/include/utils/mac', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', + ], + }, }], [ 'OS == "win"', { 'sources!': [ diff --git a/webkit/glue/image_decoder.cc b/webkit/glue/image_decoder.cc index 8f138ca..73c3f9b 100644 --- a/webkit/glue/image_decoder.cc +++ b/webkit/glue/image_decoder.cc @@ -15,6 +15,7 @@ MSVC_PUSH_WARNING_LEVEL(0); #elif defined(OS_MACOSX) #include "ImageSource.h" #include "RetainPtr.h" +#include "skia/ext/skia_utils_mac.h" #endif #include "IntSize.h" #include "RefPtr.h" @@ -73,44 +74,7 @@ SkBitmap ImageDecoder::Decode(const unsigned char* data, size_t size) const { // BitmapImage releases automatically, but we're bypassing it so we'll need // to do the releasing. RetainPtr<CGImageRef> image(AdoptCF, frame0); - - SkBitmap result; - result.setConfig(SkBitmap::kARGB_8888_Config, CGImageGetWidth(image.get()), - CGImageGetHeight(image.get())); - - // TODO(port): - // This line is a waste, but is needed when the renderer sends a - // ViewHostMsg_DidDownloadImage and tries to pickle the SkBitmap. - // Presumably this will be removed when we (ImageDecoder::Decode()) - // are changed to not return a fake SkBitmap. - result.allocPixels(); - - RetainPtr<CGColorSpace> cg_color(AdoptCF, CGColorSpaceCreateDeviceRGB()); - // The last parameter is a total guess. Feel free to adjust it if images draw - // incorrectly. TODO(avi): Verify byte ordering; it should be possible to - // swizzle bytes with various combinations of the byte order and alpha - // constants. - RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate( - result.getPixels(), - result.width(), - result.height(), - result.bytesPerPixel() * 8 / 4, - result.rowBytes(), - cg_color.get(), - kCGImageAlphaPremultipliedFirst | - kCGBitmapByteOrder32Host)); - CGRect rect = CGRectMake(0, 0, - CGImageGetWidth(image.get()), - CGImageGetHeight(image.get())); - - // We want to copy transparent pixels from |image| over to |result|, instead - // of blending |image| onto the uninitialized pixels of |result|. Since - // |context| is used only locally, there's no need to restore the blend mode. - CGContextSetBlendMode(context.get(), kCGBlendModeCopy); - - CGContextDrawImage(context.get(), rect, image.get()); - - return result; + return gfx::CGImageToSkBitmap(image.get()); #endif } |