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