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