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 "platform/Cursor.h" 28 29namespace blink { 30 31IntPoint determineHotSpot(Image* image, const IntPoint& specifiedHotSpot) 32{ 33 if (image->isNull()) 34 return IntPoint(); 35 36 // Hot spot must be inside cursor rectangle. 37 IntRect imageRect = image->rect(); 38 if (imageRect.contains(specifiedHotSpot)) 39 return specifiedHotSpot; 40 41 // If hot spot is not specified externally, it can be extracted from some image formats (e.g. .cur). 42 IntPoint intrinsicHotSpot; 43 bool imageHasIntrinsicHotSpot = image->getHotSpot(intrinsicHotSpot); 44 if (imageHasIntrinsicHotSpot && imageRect.contains(intrinsicHotSpot)) 45 return intrinsicHotSpot; 46 47 return IntPoint(); 48} 49 50const Cursor& Cursor::fromType(Cursor::Type type) 51{ 52 switch (type) { 53 case Cursor::Pointer: 54 return pointerCursor(); 55 case Cursor::Cross: 56 return crossCursor(); 57 case Cursor::Hand: 58 return handCursor(); 59 case Cursor::IBeam: 60 return iBeamCursor(); 61 case Cursor::Wait: 62 return waitCursor(); 63 case Cursor::Help: 64 return helpCursor(); 65 case Cursor::EastResize: 66 return eastResizeCursor(); 67 case Cursor::NorthResize: 68 return northResizeCursor(); 69 case Cursor::NorthEastResize: 70 return northEastResizeCursor(); 71 case Cursor::NorthWestResize: 72 return northWestResizeCursor(); 73 case Cursor::SouthResize: 74 return southResizeCursor(); 75 case Cursor::SouthEastResize: 76 return southEastResizeCursor(); 77 case Cursor::SouthWestResize: 78 return southWestResizeCursor(); 79 case Cursor::WestResize: 80 return westResizeCursor(); 81 case Cursor::NorthSouthResize: 82 return northSouthResizeCursor(); 83 case Cursor::EastWestResize: 84 return eastWestResizeCursor(); 85 case Cursor::NorthEastSouthWestResize: 86 return northEastSouthWestResizeCursor(); 87 case Cursor::NorthWestSouthEastResize: 88 return northWestSouthEastResizeCursor(); 89 case Cursor::ColumnResize: 90 return columnResizeCursor(); 91 case Cursor::RowResize: 92 return rowResizeCursor(); 93 case Cursor::MiddlePanning: 94 return middlePanningCursor(); 95 case Cursor::EastPanning: 96 return eastPanningCursor(); 97 case Cursor::NorthPanning: 98 return northPanningCursor(); 99 case Cursor::NorthEastPanning: 100 return northEastPanningCursor(); 101 case Cursor::NorthWestPanning: 102 return northWestPanningCursor(); 103 case Cursor::SouthPanning: 104 return southPanningCursor(); 105 case Cursor::SouthEastPanning: 106 return southEastPanningCursor(); 107 case Cursor::SouthWestPanning: 108 return southWestPanningCursor(); 109 case Cursor::WestPanning: 110 return westPanningCursor(); 111 case Cursor::Move: 112 return moveCursor(); 113 case Cursor::VerticalText: 114 return verticalTextCursor(); 115 case Cursor::Cell: 116 return cellCursor(); 117 case Cursor::ContextMenu: 118 return contextMenuCursor(); 119 case Cursor::Alias: 120 return aliasCursor(); 121 case Cursor::Progress: 122 return progressCursor(); 123 case Cursor::NoDrop: 124 return noDropCursor(); 125 case Cursor::Copy: 126 return copyCursor(); 127 case Cursor::None: 128 return noneCursor(); 129 case Cursor::NotAllowed: 130 return notAllowedCursor(); 131 case Cursor::ZoomIn: 132 return zoomInCursor(); 133 case Cursor::ZoomOut: 134 return zoomOutCursor(); 135 case Cursor::Grab: 136 return grabCursor(); 137 case Cursor::Grabbing: 138 return grabbingCursor(); 139 case Cursor::Custom: 140 ASSERT_NOT_REACHED(); 141 } 142 return pointerCursor(); 143} 144 145Cursor::Cursor(Image* image, const IntPoint& hotSpot) 146 : m_type(Custom) 147 , m_image(image) 148 , m_hotSpot(determineHotSpot(image, hotSpot)) 149 , m_imageScaleFactor(1) 150{ 151} 152 153Cursor::Cursor(Image* image, const IntPoint& hotSpot, float scale) 154 : m_type(Custom) 155 , m_image(image) 156 , m_hotSpot(determineHotSpot(image, hotSpot)) 157 , m_imageScaleFactor(scale) 158{ 159} 160 161Cursor::Cursor(Type type) 162 : m_type(type) 163 , m_imageScaleFactor(1) 164{ 165} 166 167Cursor::Cursor(const Cursor& other) 168 : m_type(other.m_type) 169 , m_image(other.m_image) 170 , m_hotSpot(other.m_hotSpot) 171 , m_imageScaleFactor(other.m_imageScaleFactor) 172{ 173} 174 175Cursor& Cursor::operator=(const Cursor& other) 176{ 177 m_type = other.m_type; 178 m_image = other.m_image; 179 m_hotSpot = other.m_hotSpot; 180 m_imageScaleFactor = other.m_imageScaleFactor; 181 return *this; 182} 183 184Cursor::~Cursor() 185{ 186} 187 188const Cursor& pointerCursor() 189{ 190 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Pointer)); 191 return c; 192} 193 194const Cursor& crossCursor() 195{ 196 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cross)); 197 return c; 198} 199 200const Cursor& handCursor() 201{ 202 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Hand)); 203 return c; 204} 205 206const Cursor& moveCursor() 207{ 208 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Move)); 209 return c; 210} 211 212const Cursor& verticalTextCursor() 213{ 214 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::VerticalText)); 215 return c; 216} 217 218const Cursor& cellCursor() 219{ 220 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cell)); 221 return c; 222} 223 224const Cursor& contextMenuCursor() 225{ 226 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ContextMenu)); 227 return c; 228} 229 230const Cursor& aliasCursor() 231{ 232 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Alias)); 233 return c; 234} 235 236const Cursor& zoomInCursor() 237{ 238 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomIn)); 239 return c; 240} 241 242const Cursor& zoomOutCursor() 243{ 244 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomOut)); 245 return c; 246} 247 248const Cursor& copyCursor() 249{ 250 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Copy)); 251 return c; 252} 253 254const Cursor& noneCursor() 255{ 256 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::None)); 257 return c; 258} 259 260const Cursor& progressCursor() 261{ 262 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Progress)); 263 return c; 264} 265 266const Cursor& noDropCursor() 267{ 268 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NoDrop)); 269 return c; 270} 271 272const Cursor& notAllowedCursor() 273{ 274 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NotAllowed)); 275 return c; 276} 277 278const Cursor& iBeamCursor() 279{ 280 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::IBeam)); 281 return c; 282} 283 284const Cursor& waitCursor() 285{ 286 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Wait)); 287 return c; 288} 289 290const Cursor& helpCursor() 291{ 292 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Help)); 293 return c; 294} 295 296const Cursor& eastResizeCursor() 297{ 298 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastResize)); 299 return c; 300} 301 302const Cursor& northResizeCursor() 303{ 304 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthResize)); 305 return c; 306} 307 308const Cursor& northEastResizeCursor() 309{ 310 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastResize)); 311 return c; 312} 313 314const Cursor& northWestResizeCursor() 315{ 316 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestResize)); 317 return c; 318} 319 320const Cursor& southResizeCursor() 321{ 322 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthResize)); 323 return c; 324} 325 326const Cursor& southEastResizeCursor() 327{ 328 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastResize)); 329 return c; 330} 331 332const Cursor& southWestResizeCursor() 333{ 334 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestResize)); 335 return c; 336} 337 338const Cursor& westResizeCursor() 339{ 340 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestResize)); 341 return c; 342} 343 344const Cursor& northSouthResizeCursor() 345{ 346 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthSouthResize)); 347 return c; 348} 349 350const Cursor& eastWestResizeCursor() 351{ 352 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastWestResize)); 353 return c; 354} 355 356const Cursor& northEastSouthWestResizeCursor() 357{ 358 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastSouthWestResize)); 359 return c; 360} 361 362const Cursor& northWestSouthEastResizeCursor() 363{ 364 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestSouthEastResize)); 365 return c; 366} 367 368const Cursor& columnResizeCursor() 369{ 370 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ColumnResize)); 371 return c; 372} 373 374const Cursor& rowResizeCursor() 375{ 376 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::RowResize)); 377 return c; 378} 379 380const Cursor& middlePanningCursor() 381{ 382 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::MiddlePanning)); 383 return c; 384} 385 386const Cursor& eastPanningCursor() 387{ 388 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastPanning)); 389 return c; 390} 391 392const Cursor& northPanningCursor() 393{ 394 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthPanning)); 395 return c; 396} 397 398const Cursor& northEastPanningCursor() 399{ 400 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastPanning)); 401 return c; 402} 403 404const Cursor& northWestPanningCursor() 405{ 406 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestPanning)); 407 return c; 408} 409 410const Cursor& southPanningCursor() 411{ 412 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthPanning)); 413 return c; 414} 415 416const Cursor& southEastPanningCursor() 417{ 418 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastPanning)); 419 return c; 420} 421 422const Cursor& southWestPanningCursor() 423{ 424 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestPanning)); 425 return c; 426} 427 428const Cursor& westPanningCursor() 429{ 430 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestPanning)); 431 return c; 432} 433 434const Cursor& grabCursor() 435{ 436 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grab)); 437 return c; 438} 439 440const Cursor& grabbingCursor() 441{ 442 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grabbing)); 443 return c; 444} 445 446} // namespace blink 447