OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. |
| 4 |
| 5 #include "webkit/glue/webcursor.h" |
| 6 |
| 7 #include "config.h" |
| 8 #include "PlatformCursor.h" |
| 9 #include "RetainPtr.h" |
| 10 |
| 11 #undef LOG |
| 12 #include "base/logging.h" |
| 13 |
| 14 using WebCore::PlatformCursor; |
| 15 |
| 16 namespace { |
| 17 |
| 18 // TODO(avi): Is loading resources what we want to do here? |
| 19 NSCursor* LoadCursor(const char* name, int x, int y) { |
| 20 NSString* file_name = [NSString stringWithUTF8String:name]; |
| 21 DCHECK(file_name); |
| 22 NSImage* cursor_image = [NSImage imageNamed:file_name]; |
| 23 DCHECK(cursor_image); |
| 24 return [[[NSCursor alloc] initWithImage:cursor_image |
| 25 hotSpot:NSMakePoint(x, y)] autorelease]; |
| 26 } |
| 27 |
| 28 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, |
| 29 const gfx::Size& custom_size, |
| 30 const gfx::Point& hotspot) { |
| 31 RetainPtr<CGColorSpace> cg_color(AdoptCF, CGColorSpaceCreateDeviceRGB()); |
| 32 // this is safe since we're not going to draw into the context we're creating |
| 33 void* data = const_cast<void *>(static_cast<const void*>(&custom_data[0])); |
| 34 // settings here match SetCustomData() below; keep in sync |
| 35 RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate( |
| 36 data, |
| 37 custom_size.width(), |
| 38 custom_size.height(), |
| 39 8, |
| 40 custom_size.width()*4, |
| 41 cg_color.get(), |
| 42 kCGImageAlphaPremultipliedLast | |
| 43 kCGBitmapByteOrder32Big)); |
| 44 RetainPtr<CGImage> cg_image(AdoptCF, |
| 45 CGBitmapContextCreateImage(context.get())); |
| 46 |
| 47 RetainPtr<NSBitmapImageRep> ns_bitmap( |
| 48 AdoptNS, [[NSBitmapImageRep alloc] initWithCGImage:cg_image.get()]); |
| 49 RetainPtr<NSImage> cursor_image([[NSImage alloc] init]); |
| 50 [cursor_image.get() addRepresentation:ns_bitmap.get()]; |
| 51 DCHECK(cursor_image); |
| 52 return [[[NSCursor alloc] initWithImage:cursor_image.get() |
| 53 hotSpot:NSMakePoint(hotspot.x(), |
| 54 hotspot.y())] |
| 55 autorelease]; |
| 56 } |
| 57 |
| 58 } |
| 59 |
| 60 // We're matching Safari's cursor choices; see platform/mac/CursorMac.mm |
| 61 NSCursor* WebCursor::GetCursor() const { |
| 62 switch (type_) { |
| 63 case PlatformCursor::typePointer: |
| 64 return [NSCursor arrowCursor]; |
| 65 case PlatformCursor::typeCross: |
| 66 return LoadCursor("crossHairCursor", 11, 11); |
| 67 case PlatformCursor::typeHand: |
| 68 return LoadCursor("linkCursor", 6, 1); |
| 69 case PlatformCursor::typeIBeam: |
| 70 return [NSCursor IBeamCursor]; |
| 71 case PlatformCursor::typeWait: |
| 72 return LoadCursor("waitCursor", 7, 7); |
| 73 case PlatformCursor::typeHelp: |
| 74 return LoadCursor("helpCursor", 8, 8); |
| 75 case PlatformCursor::typeEastResize: |
| 76 case PlatformCursor::typeEastPanning: |
| 77 return LoadCursor("eastResizeCursor", 14, 7); |
| 78 case PlatformCursor::typeNorthResize: |
| 79 case PlatformCursor::typeNorthPanning: |
| 80 return LoadCursor("northResizeCursor", 7, 1); |
| 81 case PlatformCursor::typeNorthEastResize: |
| 82 case PlatformCursor::typeNorthEastPanning: |
| 83 return LoadCursor("northEastResizeCursor", 14, 1); |
| 84 case PlatformCursor::typeNorthWestResize: |
| 85 case PlatformCursor::typeNorthWestPanning: |
| 86 return LoadCursor("northWestResizeCursor", 0, 0); |
| 87 case PlatformCursor::typeSouthResize: |
| 88 case PlatformCursor::typeSouthPanning: |
| 89 return LoadCursor("southResizeCursor", 7, 14); |
| 90 case PlatformCursor::typeSouthEastResize: |
| 91 case PlatformCursor::typeSouthEastPanning: |
| 92 return LoadCursor("southEastResizeCursor", 14, 14); |
| 93 case PlatformCursor::typeSouthWestResize: |
| 94 case PlatformCursor::typeSouthWestPanning: |
| 95 return LoadCursor("southWestResizeCursor", 1, 14); |
| 96 case PlatformCursor::typeWestResize: |
| 97 case PlatformCursor::typeWestPanning: |
| 98 return LoadCursor("westResizeCursor", 1, 7); |
| 99 case PlatformCursor::typeNorthSouthResize: |
| 100 return LoadCursor("northSouthResizeCursor", 7, 7); |
| 101 case PlatformCursor::typeEastWestResize: |
| 102 return LoadCursor("eastWestResizeCursor", 7, 7); |
| 103 case PlatformCursor::typeNorthEastSouthWestResize: |
| 104 return LoadCursor("northEastSouthWestResizeCursor", 7, 7); |
| 105 case PlatformCursor::typeNorthWestSouthEastResize: |
| 106 return LoadCursor("northWestSouthEastResizeCursor", 7, 7); |
| 107 case PlatformCursor::typeColumnResize: |
| 108 return [NSCursor resizeLeftRightCursor]; |
| 109 case PlatformCursor::typeRowResize: |
| 110 return [NSCursor resizeUpDownCursor]; |
| 111 case PlatformCursor::typeMiddlePanning: |
| 112 case PlatformCursor::typeMove: |
| 113 return LoadCursor("moveCursor", 7, 7); |
| 114 case PlatformCursor::typeVerticalText: |
| 115 return LoadCursor("verticalTextCursor", 7, 7); |
| 116 case PlatformCursor::typeCell: |
| 117 return LoadCursor("cellCursor", 7, 7); |
| 118 case PlatformCursor::typeContextMenu: |
| 119 return LoadCursor("contextMenuCursor", 3, 2); |
| 120 case PlatformCursor::typeAlias: |
| 121 return LoadCursor("aliasCursor", 11, 3); |
| 122 case PlatformCursor::typeProgress: |
| 123 return LoadCursor("progressCursor", 3, 2); |
| 124 case PlatformCursor::typeNoDrop: |
| 125 return LoadCursor("noDropCursor", 3, 1); |
| 126 case PlatformCursor::typeCopy: |
| 127 return LoadCursor("copyCursor", 3, 2); |
| 128 case PlatformCursor::typeNone: |
| 129 return LoadCursor("noneCursor", 7, 7); |
| 130 case PlatformCursor::typeNotAllowed: |
| 131 return LoadCursor("notAllowedCursor", 11, 11); |
| 132 case PlatformCursor::typeZoomIn: |
| 133 return LoadCursor("zoomInCursor", 7, 7); |
| 134 case PlatformCursor::typeZoomOut: |
| 135 return LoadCursor("zoomOutCursor", 7, 7); |
| 136 case PlatformCursor::typeCustom: |
| 137 return CreateCustomCursor(custom_data_, custom_size_, hotspot_); |
| 138 } |
| 139 NOTREACHED(); |
| 140 return nil; |
| 141 } |
| 142 |
| 143 void WebCursor::SetCustomData(WebCore::Image* image) { |
| 144 WebCore::NativeImagePtr image_ptr = image->nativeImageForCurrentFrame(); |
| 145 if (!image_ptr) |
| 146 return; |
| 147 |
| 148 RetainPtr<CGColorSpace> cg_color(AdoptCF, CGColorSpaceCreateDeviceRGB()); |
| 149 |
| 150 size_t size = CGImageGetHeight(image_ptr)*CGImageGetWidth(image_ptr)*4; |
| 151 custom_data_.resize(size); |
| 152 custom_size_.set_width(CGImageGetWidth(image_ptr)); |
| 153 custom_size_.set_height(CGImageGetHeight(image_ptr)); |
| 154 |
| 155 // These settings match up with the code in CreateCustomCursor() above; keep |
| 156 // them in sync. |
| 157 // TODO(avi): test to ensure that the flags here are correct for RGBA |
| 158 RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate( |
| 159 &custom_data_[0], |
| 160 CGImageGetWidth(image_ptr), |
| 161 CGImageGetHeight(image_ptr), |
| 162 8, |
| 163 CGImageGetWidth(image_ptr)*4, |
| 164 cg_color.get(), |
| 165 kCGImageAlphaPremultipliedLast | |
| 166 kCGBitmapByteOrder32Big)); |
| 167 CGRect rect = CGRectMake(0, 0, |
| 168 CGImageGetWidth(image_ptr), |
| 169 CGImageGetHeight(image_ptr)); |
| 170 CGContextDrawImage(context.get(), rect, image_ptr); |
| 171 } |
| 172 |
OLD | NEW |