1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "Cursor.h" 28 29#include "Image.h" 30#include <wtf/Assertions.h> 31 32namespace WebCore { 33 34IntPoint determineHotSpot(Image* image, const IntPoint& specifiedHotSpot) 35{ 36 if (image->isNull()) 37 return IntPoint(); 38 39 // Hot spot must be inside cursor rectangle. 40 IntRect imageRect = image->rect(); 41 if (imageRect.contains(specifiedHotSpot)) 42 return specifiedHotSpot; 43 44 // If hot spot is not specified externally, it can be extracted from some image formats (e.g. .cur). 45 IntPoint intrinsicHotSpot; 46 bool imageHasIntrinsicHotSpot = image->getHotSpot(intrinsicHotSpot); 47 if (imageHasIntrinsicHotSpot && imageRect.contains(intrinsicHotSpot)) 48 return intrinsicHotSpot; 49 50 return IntPoint(); 51} 52 53const Cursor& Cursor::fromType(Cursor::Type type) 54{ 55 switch (type) { 56 case Cursor::Pointer: 57 return pointerCursor(); 58 case Cursor::Cross: 59 return crossCursor(); 60 case Cursor::Hand: 61 return handCursor(); 62 case Cursor::IBeam: 63 return iBeamCursor(); 64 case Cursor::Wait: 65 return waitCursor(); 66 case Cursor::Help: 67 return helpCursor(); 68 case Cursor::EastResize: 69 return eastResizeCursor(); 70 case Cursor::NorthResize: 71 return northResizeCursor(); 72 case Cursor::NorthEastResize: 73 return northEastResizeCursor(); 74 case Cursor::NorthWestResize: 75 return northWestResizeCursor(); 76 case Cursor::SouthResize: 77 return southResizeCursor(); 78 case Cursor::SouthEastResize: 79 return southEastResizeCursor(); 80 case Cursor::SouthWestResize: 81 return southWestResizeCursor(); 82 case Cursor::WestResize: 83 return westResizeCursor(); 84 case Cursor::NorthSouthResize: 85 return northSouthResizeCursor(); 86 case Cursor::EastWestResize: 87 return eastWestResizeCursor(); 88 case Cursor::NorthEastSouthWestResize: 89 return northEastSouthWestResizeCursor(); 90 case Cursor::NorthWestSouthEastResize: 91 return northWestSouthEastResizeCursor(); 92 case Cursor::ColumnResize: 93 return columnResizeCursor(); 94 case Cursor::RowResize: 95 return rowResizeCursor(); 96 case Cursor::MiddlePanning: 97 return middlePanningCursor(); 98 case Cursor::EastPanning: 99 return eastPanningCursor(); 100 case Cursor::NorthPanning: 101 return northPanningCursor(); 102 case Cursor::NorthEastPanning: 103 return northEastPanningCursor(); 104 case Cursor::NorthWestPanning: 105 return northWestPanningCursor(); 106 case Cursor::SouthPanning: 107 return southPanningCursor(); 108 case Cursor::SouthEastPanning: 109 return southEastPanningCursor(); 110 case Cursor::SouthWestPanning: 111 return southWestPanningCursor(); 112 case Cursor::WestPanning: 113 return westPanningCursor(); 114 case Cursor::Move: 115 return moveCursor(); 116 case Cursor::VerticalText: 117 return verticalTextCursor(); 118 case Cursor::Cell: 119 return cellCursor(); 120 case Cursor::ContextMenu: 121 return contextMenuCursor(); 122 case Cursor::Alias: 123 return aliasCursor(); 124 case Cursor::Progress: 125 return progressCursor(); 126 case Cursor::NoDrop: 127 return noDropCursor(); 128 case Cursor::Copy: 129 return copyCursor(); 130 case Cursor::None: 131 return noneCursor(); 132 case Cursor::NotAllowed: 133 return notAllowedCursor(); 134 case Cursor::ZoomIn: 135 return zoomInCursor(); 136 case Cursor::ZoomOut: 137 return zoomOutCursor(); 138 case Cursor::Grab: 139 return grabCursor(); 140 case Cursor::Grabbing: 141 return grabbingCursor(); 142 case Cursor::Custom: 143 ASSERT_NOT_REACHED(); 144 } 145 return pointerCursor(); 146} 147 148#if USE(LAZY_NATIVE_CURSOR) 149 150Cursor::Cursor(Image* image, const IntPoint& hotSpot) 151 : m_type(Custom) 152 , m_image(image) 153 , m_hotSpot(determineHotSpot(image, hotSpot)) 154#if ENABLE(MOUSE_CURSOR_SCALE) 155 , m_imageScaleFactor(1) 156#endif 157 , m_platformCursor(0) 158{ 159} 160 161#if ENABLE(MOUSE_CURSOR_SCALE) 162Cursor::Cursor(Image* image, const IntPoint& hotSpot, float scale) 163 : m_type(Custom) 164 , m_image(image) 165 , m_hotSpot(determineHotSpot(image, hotSpot)) 166 , m_imageScaleFactor(scale) 167 , m_platformCursor(0) 168{ 169} 170#endif 171 172Cursor::Cursor(Type type) 173 : m_type(type) 174#if ENABLE(MOUSE_CURSOR_SCALE) 175 , m_imageScaleFactor(1) 176#endif 177 , m_platformCursor(0) 178{ 179} 180 181#if !PLATFORM(MAC) 182 183PlatformCursor Cursor::platformCursor() const 184{ 185 ensurePlatformCursor(); 186 return m_platformCursor; 187} 188 189#endif 190 191const Cursor& pointerCursor() 192{ 193 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Pointer)); 194 return c; 195} 196 197const Cursor& crossCursor() 198{ 199 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cross)); 200 return c; 201} 202 203const Cursor& handCursor() 204{ 205 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Hand)); 206 return c; 207} 208 209const Cursor& moveCursor() 210{ 211 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Move)); 212 return c; 213} 214 215const Cursor& verticalTextCursor() 216{ 217 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::VerticalText)); 218 return c; 219} 220 221const Cursor& cellCursor() 222{ 223 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cell)); 224 return c; 225} 226 227const Cursor& contextMenuCursor() 228{ 229 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ContextMenu)); 230 return c; 231} 232 233const Cursor& aliasCursor() 234{ 235 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Alias)); 236 return c; 237} 238 239const Cursor& zoomInCursor() 240{ 241 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomIn)); 242 return c; 243} 244 245const Cursor& zoomOutCursor() 246{ 247 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomOut)); 248 return c; 249} 250 251const Cursor& copyCursor() 252{ 253 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Copy)); 254 return c; 255} 256 257const Cursor& noneCursor() 258{ 259 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::None)); 260 return c; 261} 262 263const Cursor& progressCursor() 264{ 265 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Progress)); 266 return c; 267} 268 269const Cursor& noDropCursor() 270{ 271 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NoDrop)); 272 return c; 273} 274 275const Cursor& notAllowedCursor() 276{ 277 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NotAllowed)); 278 return c; 279} 280 281const Cursor& iBeamCursor() 282{ 283 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::IBeam)); 284 return c; 285} 286 287const Cursor& waitCursor() 288{ 289 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Wait)); 290 return c; 291} 292 293const Cursor& helpCursor() 294{ 295 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Help)); 296 return c; 297} 298 299const Cursor& eastResizeCursor() 300{ 301 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastResize)); 302 return c; 303} 304 305const Cursor& northResizeCursor() 306{ 307 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthResize)); 308 return c; 309} 310 311const Cursor& northEastResizeCursor() 312{ 313 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastResize)); 314 return c; 315} 316 317const Cursor& northWestResizeCursor() 318{ 319 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestResize)); 320 return c; 321} 322 323const Cursor& southResizeCursor() 324{ 325 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthResize)); 326 return c; 327} 328 329const Cursor& southEastResizeCursor() 330{ 331 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastResize)); 332 return c; 333} 334 335const Cursor& southWestResizeCursor() 336{ 337 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestResize)); 338 return c; 339} 340 341const Cursor& westResizeCursor() 342{ 343 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestResize)); 344 return c; 345} 346 347const Cursor& northSouthResizeCursor() 348{ 349 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthSouthResize)); 350 return c; 351} 352 353const Cursor& eastWestResizeCursor() 354{ 355 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastWestResize)); 356 return c; 357} 358 359const Cursor& northEastSouthWestResizeCursor() 360{ 361 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastSouthWestResize)); 362 return c; 363} 364 365const Cursor& northWestSouthEastResizeCursor() 366{ 367 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestSouthEastResize)); 368 return c; 369} 370 371const Cursor& columnResizeCursor() 372{ 373 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ColumnResize)); 374 return c; 375} 376 377const Cursor& rowResizeCursor() 378{ 379 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::RowResize)); 380 return c; 381} 382 383const Cursor& middlePanningCursor() 384{ 385 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::MiddlePanning)); 386 return c; 387} 388 389const Cursor& eastPanningCursor() 390{ 391 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastPanning)); 392 return c; 393} 394 395const Cursor& northPanningCursor() 396{ 397 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthPanning)); 398 return c; 399} 400 401const Cursor& northEastPanningCursor() 402{ 403 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastPanning)); 404 return c; 405} 406 407const Cursor& northWestPanningCursor() 408{ 409 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestPanning)); 410 return c; 411} 412 413const Cursor& southPanningCursor() 414{ 415 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthPanning)); 416 return c; 417} 418 419const Cursor& southEastPanningCursor() 420{ 421 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastPanning)); 422 return c; 423} 424 425const Cursor& southWestPanningCursor() 426{ 427 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestPanning)); 428 return c; 429} 430 431const Cursor& westPanningCursor() 432{ 433 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestPanning)); 434 return c; 435} 436 437const Cursor& grabCursor() 438{ 439 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grab)); 440 return c; 441} 442 443const Cursor& grabbingCursor() 444{ 445 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grabbing)); 446 return c; 447} 448 449#endif 450 451} // namespace WebCore 452