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 "core/platform/Cursor.h" 28 29 namespace WebCore { 30 31 IntPoint 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 50 const 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 145 Cursor::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 153 Cursor::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 161 Cursor::Cursor(Type type) 162 : m_type(type) 163 , m_imageScaleFactor(1) 164 { 165 } 166 167 Cursor::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 175 Cursor& 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 184 Cursor::~Cursor() 185 { 186 } 187 188 const Cursor& pointerCursor() 189 { 190 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Pointer)); 191 return c; 192 } 193 194 const Cursor& crossCursor() 195 { 196 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cross)); 197 return c; 198 } 199 200 const Cursor& handCursor() 201 { 202 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Hand)); 203 return c; 204 } 205 206 const Cursor& moveCursor() 207 { 208 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Move)); 209 return c; 210 } 211 212 const Cursor& verticalTextCursor() 213 { 214 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::VerticalText)); 215 return c; 216 } 217 218 const Cursor& cellCursor() 219 { 220 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cell)); 221 return c; 222 } 223 224 const Cursor& contextMenuCursor() 225 { 226 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ContextMenu)); 227 return c; 228 } 229 230 const Cursor& aliasCursor() 231 { 232 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Alias)); 233 return c; 234 } 235 236 const Cursor& zoomInCursor() 237 { 238 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomIn)); 239 return c; 240 } 241 242 const Cursor& zoomOutCursor() 243 { 244 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomOut)); 245 return c; 246 } 247 248 const Cursor& copyCursor() 249 { 250 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Copy)); 251 return c; 252 } 253 254 const Cursor& noneCursor() 255 { 256 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::None)); 257 return c; 258 } 259 260 const Cursor& progressCursor() 261 { 262 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Progress)); 263 return c; 264 } 265 266 const Cursor& noDropCursor() 267 { 268 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NoDrop)); 269 return c; 270 } 271 272 const Cursor& notAllowedCursor() 273 { 274 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NotAllowed)); 275 return c; 276 } 277 278 const Cursor& iBeamCursor() 279 { 280 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::IBeam)); 281 return c; 282 } 283 284 const Cursor& waitCursor() 285 { 286 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Wait)); 287 return c; 288 } 289 290 const Cursor& helpCursor() 291 { 292 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Help)); 293 return c; 294 } 295 296 const Cursor& eastResizeCursor() 297 { 298 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastResize)); 299 return c; 300 } 301 302 const Cursor& northResizeCursor() 303 { 304 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthResize)); 305 return c; 306 } 307 308 const Cursor& northEastResizeCursor() 309 { 310 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastResize)); 311 return c; 312 } 313 314 const Cursor& northWestResizeCursor() 315 { 316 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestResize)); 317 return c; 318 } 319 320 const Cursor& southResizeCursor() 321 { 322 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthResize)); 323 return c; 324 } 325 326 const Cursor& southEastResizeCursor() 327 { 328 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastResize)); 329 return c; 330 } 331 332 const Cursor& southWestResizeCursor() 333 { 334 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestResize)); 335 return c; 336 } 337 338 const Cursor& westResizeCursor() 339 { 340 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestResize)); 341 return c; 342 } 343 344 const Cursor& northSouthResizeCursor() 345 { 346 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthSouthResize)); 347 return c; 348 } 349 350 const Cursor& eastWestResizeCursor() 351 { 352 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastWestResize)); 353 return c; 354 } 355 356 const Cursor& northEastSouthWestResizeCursor() 357 { 358 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastSouthWestResize)); 359 return c; 360 } 361 362 const Cursor& northWestSouthEastResizeCursor() 363 { 364 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestSouthEastResize)); 365 return c; 366 } 367 368 const Cursor& columnResizeCursor() 369 { 370 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ColumnResize)); 371 return c; 372 } 373 374 const Cursor& rowResizeCursor() 375 { 376 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::RowResize)); 377 return c; 378 } 379 380 const Cursor& middlePanningCursor() 381 { 382 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::MiddlePanning)); 383 return c; 384 } 385 386 const Cursor& eastPanningCursor() 387 { 388 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastPanning)); 389 return c; 390 } 391 392 const Cursor& northPanningCursor() 393 { 394 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthPanning)); 395 return c; 396 } 397 398 const Cursor& northEastPanningCursor() 399 { 400 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastPanning)); 401 return c; 402 } 403 404 const Cursor& northWestPanningCursor() 405 { 406 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestPanning)); 407 return c; 408 } 409 410 const Cursor& southPanningCursor() 411 { 412 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthPanning)); 413 return c; 414 } 415 416 const Cursor& southEastPanningCursor() 417 { 418 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastPanning)); 419 return c; 420 } 421 422 const Cursor& southWestPanningCursor() 423 { 424 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestPanning)); 425 return c; 426 } 427 428 const Cursor& westPanningCursor() 429 { 430 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestPanning)); 431 return c; 432 } 433 434 const Cursor& grabCursor() 435 { 436 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grab)); 437 return c; 438 } 439 440 const Cursor& grabbingCursor() 441 { 442 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grabbing)); 443 return c; 444 } 445 446 } // namespace WebCore 447