OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/glue/webcursor.h" | 5 #include "webkit/glue/webcursor.h" |
6 | 6 |
7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
8 #include <Carbon/Carbon.h> | 8 #include <Carbon/Carbon.h> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
12 #include "base/mac/scoped_cftyperef.h" | 12 #include "base/mac/scoped_cftyperef.h" |
13 #include "base/memory/scoped_nsobject.h" | 13 #include "base/memory/scoped_nsobject.h" |
| 14 #include "skia/ext/skia_utils_mac.h" |
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" |
15 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h" |
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" |
17 #include "ui/gfx/mac/nsimage_cache.h" | 18 #include "ui/gfx/mac/nsimage_cache.h" |
18 | 19 |
19 #if WEBKIT_USING_SKIA | |
20 #include "skia/ext/skia_utils_mac.h" | |
21 #endif | |
22 | |
23 using WebKit::WebCursorInfo; | 20 using WebKit::WebCursorInfo; |
24 using WebKit::WebImage; | 21 using WebKit::WebImage; |
25 using WebKit::WebSize; | 22 using WebKit::WebSize; |
26 | 23 |
27 // Declare symbols that are part of the 10.6 SDK. | 24 // Declare symbols that are part of the 10.6 SDK. |
28 #if !defined(MAC_OS_X_VERSION_10_6) || \ | 25 #if !defined(MAC_OS_X_VERSION_10_6) || \ |
29 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | 26 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 |
30 | 27 |
31 @interface NSCursor (SnowLeopardSDKDeclarations) | 28 @interface NSCursor (SnowLeopardSDKDeclarations) |
32 + (NSCursor*)contextualMenuCursor; | 29 + (NSCursor*)contextualMenuCursor; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 size.width()*4, | 86 size.width()*4, |
90 cg_color.get(), | 87 cg_color.get(), |
91 kCGImageAlphaPremultipliedLast | | 88 kCGImageAlphaPremultipliedLast | |
92 kCGBitmapByteOrder32Big)); | 89 kCGBitmapByteOrder32Big)); |
93 return CGBitmapContextCreateImage(context.get()); | 90 return CGBitmapContextCreateImage(context.get()); |
94 } | 91 } |
95 | 92 |
96 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, | 93 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, |
97 const gfx::Size& custom_size, | 94 const gfx::Size& custom_size, |
98 const gfx::Point& hotspot) { | 95 const gfx::Point& hotspot) { |
99 #if WEBKIT_USING_SKIA | |
100 // If the data is missing, leave the backing transparent. | 96 // If the data is missing, leave the backing transparent. |
101 void* data = NULL; | 97 void* data = NULL; |
102 size_t data_size = 0; | 98 size_t data_size = 0; |
103 if (!custom_data.empty()) { | 99 if (!custom_data.empty()) { |
104 // This is safe since we're not going to draw into the context we're | 100 // This is safe since we're not going to draw into the context we're |
105 // creating. | 101 // creating. |
106 data = const_cast<char*>(&custom_data[0]); | 102 data = const_cast<char*>(&custom_data[0]); |
107 data_size = custom_data.size(); | 103 data_size = custom_data.size(); |
108 } | 104 } |
109 | 105 |
110 // If the size is empty, use a 1x1 transparent image. | 106 // If the size is empty, use a 1x1 transparent image. |
111 gfx::Size size = custom_size; | 107 gfx::Size size = custom_size; |
112 if (size.IsEmpty()) { | 108 if (size.IsEmpty()) { |
113 size.SetSize(1, 1); | 109 size.SetSize(1, 1); |
114 data = NULL; | 110 data = NULL; |
115 } | 111 } |
116 | 112 |
117 SkBitmap bitmap; | 113 SkBitmap bitmap; |
118 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); | 114 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); |
119 bitmap.allocPixels(); | 115 bitmap.allocPixels(); |
120 if (data) | 116 if (data) |
121 memcpy(bitmap.getAddr32(0, 0), data, data_size); | 117 memcpy(bitmap.getAddr32(0, 0), data, data_size); |
122 else | 118 else |
123 bitmap.eraseARGB(0, 0, 0, 0); | 119 bitmap.eraseARGB(0, 0, 0, 0); |
124 NSImage* cursor_image = gfx::SkBitmapToNSImage(bitmap); | 120 NSImage* cursor_image = gfx::SkBitmapToNSImage(bitmap); |
125 #else | |
126 base::mac::ScopedCFTypeRef<CGImageRef> cg_image( | |
127 CreateCGImageFromCustomData(custom_data, custom_size)); | |
128 | |
129 scoped_nsobject<NSBitmapImageRep> ns_bitmap( | |
130 [[NSBitmapImageRep alloc] initWithCGImage:cg_image.get()]); | |
131 scoped_nsobject<NSImage> cursor_image([[NSImage alloc] init]); | |
132 DCHECK(cursor_image); | |
133 [cursor_image addRepresentation:ns_bitmap]; | |
134 #endif // WEBKIT_USING_SKIA | |
135 | 121 |
136 NSCursor* cursor = [[NSCursor alloc] initWithImage:cursor_image | 122 NSCursor* cursor = [[NSCursor alloc] initWithImage:cursor_image |
137 hotSpot:NSMakePoint(hotspot.x(), | 123 hotSpot:NSMakePoint(hotspot.x(), |
138 hotspot.y())]; | 124 hotspot.y())]; |
139 | 125 |
140 return [cursor autorelease]; | 126 return [cursor autorelease]; |
141 } | 127 } |
142 | 128 |
143 } // namespace | 129 } // namespace |
144 | 130 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 mask <<= 1; | 342 mask <<= 1; |
357 } | 343 } |
358 } | 344 } |
359 | 345 |
360 base::mac::ScopedCFTypeRef<CGImageRef> cg_image( | 346 base::mac::ScopedCFTypeRef<CGImageRef> cg_image( |
361 CreateCGImageFromCustomData(raw_data, custom_size)); | 347 CreateCGImageFromCustomData(raw_data, custom_size)); |
362 | 348 |
363 WebKit::WebCursorInfo cursor_info; | 349 WebKit::WebCursorInfo cursor_info; |
364 cursor_info.type = WebCursorInfo::TypeCustom; | 350 cursor_info.type = WebCursorInfo::TypeCustom; |
365 cursor_info.hotSpot = WebKit::WebPoint(cursor->hotSpot.h, cursor->hotSpot.v); | 351 cursor_info.hotSpot = WebKit::WebPoint(cursor->hotSpot.h, cursor->hotSpot.v); |
366 #if WEBKIT_USING_SKIA | |
367 // TODO(avi): build the cursor image in Skia directly rather than going via | 352 // TODO(avi): build the cursor image in Skia directly rather than going via |
368 // this roundabout path. | 353 // this roundabout path. |
369 cursor_info.customImage = gfx::CGImageToSkBitmap(cg_image.get()); | 354 cursor_info.customImage = gfx::CGImageToSkBitmap(cg_image.get()); |
370 #else | |
371 cursor_info.customImage = cg_image.get(); | |
372 #endif | |
373 | 355 |
374 InitFromCursorInfo(cursor_info); | 356 InitFromCursorInfo(cursor_info); |
375 } | 357 } |
376 | 358 |
377 void WebCursor::InitFromNSCursor(NSCursor* cursor) { | 359 void WebCursor::InitFromNSCursor(NSCursor* cursor) { |
378 WebKit::WebCursorInfo cursor_info; | 360 WebKit::WebCursorInfo cursor_info; |
379 | 361 |
380 if ([cursor isEqual:[NSCursor arrowCursor]]) { | 362 if ([cursor isEqual:[NSCursor arrowCursor]]) { |
381 cursor_info.type = WebCursorInfo::TypePointer; | 363 cursor_info.type = WebCursorInfo::TypePointer; |
382 } else if ([cursor isEqual:[NSCursor IBeamCursor]]) { | 364 } else if ([cursor isEqual:[NSCursor IBeamCursor]]) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 if ([rep isKindOfClass:[NSBitmapImageRep class]]) { | 404 if ([rep isKindOfClass:[NSBitmapImageRep class]]) { |
423 cg_image = [rep CGImage]; | 405 cg_image = [rep CGImage]; |
424 break; | 406 break; |
425 } | 407 } |
426 } | 408 } |
427 | 409 |
428 if (cg_image) { | 410 if (cg_image) { |
429 cursor_info.type = WebCursorInfo::TypeCustom; | 411 cursor_info.type = WebCursorInfo::TypeCustom; |
430 NSPoint hot_spot = [cursor hotSpot]; | 412 NSPoint hot_spot = [cursor hotSpot]; |
431 cursor_info.hotSpot = WebKit::WebPoint(hot_spot.x, hot_spot.y); | 413 cursor_info.hotSpot = WebKit::WebPoint(hot_spot.x, hot_spot.y); |
432 #if WEBKIT_USING_SKIA | |
433 cursor_info.customImage = gfx::CGImageToSkBitmap(cg_image); | 414 cursor_info.customImage = gfx::CGImageToSkBitmap(cg_image); |
434 #else | |
435 cursor_info.customImage = cg_image; | |
436 #endif | |
437 } else { | 415 } else { |
438 cursor_info.type = WebCursorInfo::TypePointer; | 416 cursor_info.type = WebCursorInfo::TypePointer; |
439 } | 417 } |
440 } | 418 } |
441 | 419 |
442 InitFromCursorInfo(cursor_info); | 420 InitFromCursorInfo(cursor_info); |
443 } | 421 } |
444 | 422 |
445 #if !WEBKIT_USING_SKIA | |
446 void WebCursor::SetCustomData(const WebImage& image) { | |
447 if (image.isNull()) | |
448 return; | |
449 | |
450 base::mac::ScopedCFTypeRef<CGColorSpaceRef> cg_color( | |
451 CGColorSpaceCreateDeviceRGB()); | |
452 | |
453 const WebSize& image_dimensions = image.size(); | |
454 int image_width = image_dimensions.width; | |
455 int image_height = image_dimensions.height; | |
456 | |
457 size_t size = image_height * image_width * 4; | |
458 custom_data_.resize(size); | |
459 custom_size_.set_width(image_width); | |
460 custom_size_.set_height(image_height); | |
461 | |
462 // These settings match up with the code in CreateCustomCursor() above; keep | |
463 // them in sync. | |
464 // TODO(avi): test to ensure that the flags here are correct for RGBA | |
465 base::mac::ScopedCFTypeRef<CGContextRef> context( | |
466 CGBitmapContextCreate(&custom_data_[0], | |
467 image_width, | |
468 image_height, | |
469 8, | |
470 image_width * 4, | |
471 cg_color.get(), | |
472 kCGImageAlphaPremultipliedLast | | |
473 kCGBitmapByteOrder32Big)); | |
474 CGRect rect = CGRectMake(0, 0, image_width, image_height); | |
475 CGContextDrawImage(context.get(), rect, image.getCGImageRef()); | |
476 } | |
477 | |
478 void WebCursor::ImageFromCustomData(WebImage* image) const { | |
479 if (custom_data_.empty()) | |
480 return; | |
481 | |
482 base::mac::ScopedCFTypeRef<CGImageRef> cg_image( | |
483 CreateCGImageFromCustomData(custom_data_, custom_size_)); | |
484 *image = cg_image.get(); | |
485 } | |
486 #endif // !WEBKIT_USING_SKIA | |
487 | |
488 void WebCursor::InitPlatformData() { | 423 void WebCursor::InitPlatformData() { |
489 return; | 424 return; |
490 } | 425 } |
491 | 426 |
492 bool WebCursor::SerializePlatformData(Pickle* pickle) const { | 427 bool WebCursor::SerializePlatformData(Pickle* pickle) const { |
493 return true; | 428 return true; |
494 } | 429 } |
495 | 430 |
496 bool WebCursor::DeserializePlatformData(PickleIterator* iter) { | 431 bool WebCursor::DeserializePlatformData(PickleIterator* iter) { |
497 return true; | 432 return true; |
498 } | 433 } |
499 | 434 |
500 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const { | 435 bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const { |
501 return true; | 436 return true; |
502 } | 437 } |
503 | 438 |
504 void WebCursor::CleanupPlatformData() { | 439 void WebCursor::CleanupPlatformData() { |
505 return; | 440 return; |
506 } | 441 } |
507 | 442 |
508 void WebCursor::CopyPlatformData(const WebCursor& other) { | 443 void WebCursor::CopyPlatformData(const WebCursor& other) { |
509 return; | 444 return; |
510 } | 445 } |
OLD | NEW |