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