Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: webkit/glue/webcursor_mac.mm

Issue 11567049: mac: Handle hidpi cursors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« skia/ext/skia_utils_mac.mm ('K') | « webkit/glue/webcursor.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h" 11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/memory/scoped_nsobject.h" 12 #include "base/memory/scoped_nsobject.h"
13 #include "grit/webkit_chromium_resources.h" 13 #include "grit/webkit_chromium_resources.h"
14 #include "skia/ext/skia_utils_mac.h" 14 #include "skia/ext/skia_utils_mac.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h" 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
18 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/point_conversions.h"
20 #include "ui/gfx/size_conversions.h"
19 21
20 22
21 using WebKit::WebCursorInfo; 23 using WebKit::WebCursorInfo;
22 using WebKit::WebImage; 24 using WebKit::WebImage;
23 using WebKit::WebSize; 25 using WebKit::WebSize;
24 26
25 // Declare symbols that are part of the 10.7 SDK. 27 // Declare symbols that are part of the 10.7 SDK.
26 #if !defined(MAC_OS_X_VERSION_10_7) || \ 28 #if !defined(MAC_OS_X_VERSION_10_7) || \
27 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 29 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
28 30
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 8, 170 8,
169 size.width()*4, 171 size.width()*4,
170 cg_color.get(), 172 cg_color.get(),
171 kCGImageAlphaPremultipliedLast | 173 kCGImageAlphaPremultipliedLast |
172 kCGBitmapByteOrder32Big)); 174 kCGBitmapByteOrder32Big));
173 return CGBitmapContextCreateImage(context.get()); 175 return CGBitmapContextCreateImage(context.get());
174 } 176 }
175 177
176 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, 178 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data,
177 const gfx::Size& custom_size, 179 const gfx::Size& custom_size,
180 float custom_scale,
178 const gfx::Point& hotspot) { 181 const gfx::Point& hotspot) {
179 // If the data is missing, leave the backing transparent. 182 // If the data is missing, leave the backing transparent.
180 void* data = NULL; 183 void* data = NULL;
181 size_t data_size = 0; 184 size_t data_size = 0;
182 if (!custom_data.empty()) { 185 if (!custom_data.empty()) {
183 // This is safe since we're not going to draw into the context we're 186 // This is safe since we're not going to draw into the context we're
184 // creating. 187 // creating.
185 data = const_cast<char*>(&custom_data[0]); 188 data = const_cast<char*>(&custom_data[0]);
186 data_size = custom_data.size(); 189 data_size = custom_data.size();
187 } 190 }
188 191
189 // If the size is empty, use a 1x1 transparent image. 192 // If the size is empty, use a 1x1 transparent image.
190 gfx::Size size = custom_size; 193 gfx::Size size = custom_size;
191 if (size.IsEmpty()) { 194 if (size.IsEmpty()) {
192 size.SetSize(1, 1); 195 size.SetSize(1, 1);
193 data = NULL; 196 data = NULL;
194 } 197 }
195 198
196 SkBitmap bitmap; 199 SkBitmap bitmap;
197 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); 200 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
198 bitmap.allocPixels(); 201 bitmap.allocPixels();
199 if (data) 202 if (data)
200 memcpy(bitmap.getAddr32(0, 0), data, data_size); 203 memcpy(bitmap.getAddr32(0, 0), data, data_size);
201 else 204 else
202 bitmap.eraseARGB(0, 0, 0, 0); 205 bitmap.eraseARGB(0, 0, 0, 0);
206
207 // Convert from pixels to view units.
208 if (custom_scale == 0)
209 custom_scale = 1;
210 NSSize dip_size = NSSizeFromCGSize(gfx::ToFlooredSize(
211 gfx::ScaleSize(custom_size, 1 / custom_scale)).ToCGSize());
212 NSPoint dip_hotspot = NSPointFromCGPoint(gfx::ToFlooredPoint(
213 gfx::ScalePoint(hotspot, 1 / custom_scale)).ToCGPoint());
214
203 NSImage* cursor_image = gfx::SkBitmapToNSImage(bitmap); 215 NSImage* cursor_image = gfx::SkBitmapToNSImage(bitmap);
216 [cursor_image setSize:dip_size];
204 217
205 NSCursor* cursor = [[NSCursor alloc] initWithImage:cursor_image 218 NSCursor* cursor = [[NSCursor alloc] initWithImage:cursor_image
206 hotSpot:NSMakePoint(hotspot.x(), 219 hotSpot:dip_hotspot];
207 hotspot.y())];
208 220
209 return [cursor autorelease]; 221 return [cursor autorelease];
210 } 222 }
211 223
212 } // namespace 224 } // namespace
213 225
214 // Match Safari's cursor choices; see platform/mac/CursorMac.mm . 226 // Match Safari's cursor choices; see platform/mac/CursorMac.mm .
215 gfx::NativeCursor WebCursor::GetNativeCursor() { 227 gfx::NativeCursor WebCursor::GetNativeCursor() {
216 switch (type_) { 228 switch (type_) {
217 case WebCursorInfo::TypePointer: 229 case WebCursorInfo::TypePointer:
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 case WebCursorInfo::TypeVerticalText: 302 case WebCursorInfo::TypeVerticalText:
291 // IBeamCursorForVerticalLayout is >= 10.7. 303 // IBeamCursorForVerticalLayout is >= 10.7.
292 if ([NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)]) 304 if ([NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)])
293 return [NSCursor IBeamCursorForVerticalLayout]; 305 return [NSCursor IBeamCursorForVerticalLayout];
294 else 306 else
295 return LoadCursor(IDR_VERTICALTEXT_CURSOR, 7, 7); 307 return LoadCursor(IDR_VERTICALTEXT_CURSOR, 7, 7);
296 case WebCursorInfo::TypeCell: 308 case WebCursorInfo::TypeCell:
297 return GetCoreCursorWithFallback(kCellCursor, 309 return GetCoreCursorWithFallback(kCellCursor,
298 IDR_CELL_CURSOR, 7, 7); 310 IDR_CELL_CURSOR, 7, 7);
299 case WebCursorInfo::TypeContextMenu: 311 case WebCursorInfo::TypeContextMenu:
300 // contextualMenuCursor is >= 10.6. 312 return [NSCursor contextualMenuCursor];
301 if ([NSCursor respondsToSelector:@selector(contextualMenuCursor)])
302 return [NSCursor contextualMenuCursor];
303 else
304 return LoadCursor(IDR_CONTEXTMENU_CURSOR, 3, 2);
Avi (use Gerrit) 2012/12/14 21:46:26 Are we dropping the bundling of the bitmaps we no
Nico 2012/12/14 21:49:37 Good question! It looks like IDR_CONTEXTMENU_CURSO
305 case WebCursorInfo::TypeAlias: 313 case WebCursorInfo::TypeAlias:
306 return GetCoreCursorWithFallback(kMakeAliasCursor, 314 return GetCoreCursorWithFallback(kMakeAliasCursor,
307 IDR_ALIAS_CURSOR, 11, 3); 315 IDR_ALIAS_CURSOR, 11, 3);
308 case WebCursorInfo::TypeProgress: 316 case WebCursorInfo::TypeProgress:
309 return GetCoreCursorWithFallback(kBusyButClickableCursor, 317 return GetCoreCursorWithFallback(kBusyButClickableCursor,
310 IDR_PROGRESS_CURSOR, 3, 2); 318 IDR_PROGRESS_CURSOR, 3, 2);
311 case WebCursorInfo::TypeNoDrop: 319 case WebCursorInfo::TypeNoDrop:
312 case WebCursorInfo::TypeNotAllowed: 320 case WebCursorInfo::TypeNotAllowed:
313 // Docs say that operationNotAllowedCursor is >= 10.6, and it's not in the
314 // 10.5 SDK, but later SDKs note that it really is available on 10.5.
315 return [NSCursor operationNotAllowedCursor]; 321 return [NSCursor operationNotAllowedCursor];
316 case WebCursorInfo::TypeCopy: 322 case WebCursorInfo::TypeCopy:
317 // dragCopyCursor is >= 10.6. 323 return [NSCursor dragCopyCursor];
318 if ([NSCursor respondsToSelector:@selector(dragCopyCursor)])
319 return [NSCursor dragCopyCursor];
320 else
321 return LoadCursor(IDR_COPY_CURSOR, 3, 2);
Avi (use Gerrit) 2012/12/14 21:52:15 And IDR_COPY_CURSOR too.
322 case WebCursorInfo::TypeNone: 324 case WebCursorInfo::TypeNone:
323 return LoadCursor(IDR_NONE_CURSOR, 7, 7); 325 return LoadCursor(IDR_NONE_CURSOR, 7, 7);
324 case WebCursorInfo::TypeZoomIn: 326 case WebCursorInfo::TypeZoomIn:
325 return GetCoreCursorWithFallback(kZoomInCursor, 327 return GetCoreCursorWithFallback(kZoomInCursor,
326 IDR_ZOOMIN_CURSOR, 7, 7); 328 IDR_ZOOMIN_CURSOR, 7, 7);
327 case WebCursorInfo::TypeZoomOut: 329 case WebCursorInfo::TypeZoomOut:
328 return GetCoreCursorWithFallback(kZoomOutCursor, 330 return GetCoreCursorWithFallback(kZoomOutCursor,
329 IDR_ZOOMOUT_CURSOR, 7, 7); 331 IDR_ZOOMOUT_CURSOR, 7, 7);
330 case WebCursorInfo::TypeGrab: 332 case WebCursorInfo::TypeGrab:
331 return [NSCursor openHandCursor]; 333 return [NSCursor openHandCursor];
332 case WebCursorInfo::TypeGrabbing: 334 case WebCursorInfo::TypeGrabbing:
333 return [NSCursor closedHandCursor]; 335 return [NSCursor closedHandCursor];
334 case WebCursorInfo::TypeCustom: 336 case WebCursorInfo::TypeCustom:
335 return CreateCustomCursor(custom_data_, custom_size_, hotspot_); 337 return CreateCustomCursor(
338 custom_data_, custom_size_, custom_scale_, hotspot_);
336 } 339 }
337 NOTREACHED(); 340 NOTREACHED();
338 return nil; 341 return nil;
339 } 342 }
340 343
341 void WebCursor::InitFromNSCursor(NSCursor* cursor) { 344 void WebCursor::InitFromNSCursor(NSCursor* cursor) {
342 WebKit::WebCursorInfo cursor_info; 345 WebKit::WebCursorInfo cursor_info;
343 346
344 if ([cursor isEqual:[NSCursor arrowCursor]]) { 347 if ([cursor isEqual:[NSCursor arrowCursor]]) {
345 cursor_info.type = WebCursorInfo::TypePointer; 348 cursor_info.type = WebCursorInfo::TypePointer;
(...skipping 14 matching lines...) Expand all
360 } else if ([cursor isEqual:[NSCursor resizeDownCursor]]) { 363 } else if ([cursor isEqual:[NSCursor resizeDownCursor]]) {
361 cursor_info.type = WebCursorInfo::TypeSouthResize; 364 cursor_info.type = WebCursorInfo::TypeSouthResize;
362 } else if ([cursor isEqual:[NSCursor resizeUpDownCursor]]) { 365 } else if ([cursor isEqual:[NSCursor resizeUpDownCursor]]) {
363 cursor_info.type = WebCursorInfo::TypeNorthSouthResize; 366 cursor_info.type = WebCursorInfo::TypeNorthSouthResize;
364 } else if ([cursor isEqual:[NSCursor openHandCursor]]) { 367 } else if ([cursor isEqual:[NSCursor openHandCursor]]) {
365 cursor_info.type = WebCursorInfo::TypeGrab; 368 cursor_info.type = WebCursorInfo::TypeGrab;
366 } else if ([cursor isEqual:[NSCursor closedHandCursor]]) { 369 } else if ([cursor isEqual:[NSCursor closedHandCursor]]) {
367 cursor_info.type = WebCursorInfo::TypeGrabbing; 370 cursor_info.type = WebCursorInfo::TypeGrabbing;
368 } else if ([cursor isEqual:[NSCursor operationNotAllowedCursor]]) { 371 } else if ([cursor isEqual:[NSCursor operationNotAllowedCursor]]) {
369 cursor_info.type = WebCursorInfo::TypeNotAllowed; 372 cursor_info.type = WebCursorInfo::TypeNotAllowed;
370 } else if ([NSCursor respondsToSelector:@selector(dragCopyCursor)] && 373 } else if ([cursor isEqual:[NSCursor dragCopyCursor]]) {
371 [cursor isEqual:[NSCursor dragCopyCursor]]) {
372 cursor_info.type = WebCursorInfo::TypeCopy; 374 cursor_info.type = WebCursorInfo::TypeCopy;
373 } else if ([NSCursor respondsToSelector:@selector(contextualMenuCursor)] && 375 } else if ([cursor isEqual:[NSCursor contextualMenuCursor]]) {
374 [cursor isEqual:[NSCursor contextualMenuCursor]]) {
375 cursor_info.type = WebCursorInfo::TypeContextMenu; 376 cursor_info.type = WebCursorInfo::TypeContextMenu;
376 } else if ( 377 } else if (
377 [NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)] && 378 [NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)] &&
378 [cursor isEqual:[NSCursor IBeamCursorForVerticalLayout]]) { 379 [cursor isEqual:[NSCursor IBeamCursorForVerticalLayout]]) {
379 cursor_info.type = WebCursorInfo::TypeVerticalText; 380 cursor_info.type = WebCursorInfo::TypeVerticalText;
380 } else { 381 } else {
381 // Also handles the [NSCursor disappearingItemCursor] case. Quick-and-dirty 382 // Also handles the [NSCursor disappearingItemCursor] case. Quick-and-dirty
382 // image conversion; TODO(avi): do better. 383 // image conversion; TODO(avi): do better.
383 CGImageRef cg_image = nil; 384 CGImageRef cg_image = nil;
384 NSImage* image = [cursor image]; 385 NSImage* image = [cursor image];
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 return true; 419 return true;
419 } 420 }
420 421
421 void WebCursor::CleanupPlatformData() { 422 void WebCursor::CleanupPlatformData() {
422 return; 423 return;
423 } 424 }
424 425
425 void WebCursor::CopyPlatformData(const WebCursor& other) { 426 void WebCursor::CopyPlatformData(const WebCursor& other) {
426 return; 427 return;
427 } 428 }
OLDNEW
« skia/ext/skia_utils_mac.mm ('K') | « webkit/glue/webcursor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698