1414package org .eclipse .swt .graphics ;
1515
1616
17+ import java .util .*;
18+
1719import org .eclipse .swt .*;
20+ import org .eclipse .swt .internal .*;
1821import org .eclipse .swt .internal .win32 .*;
1922
2023/**
@@ -59,9 +62,18 @@ public final class Cursor extends Resource {
5962 * @noreference This field is not intended to be referenced by clients.
6063 */
6164 public long handle ;
65+ /**
66+ * Attribute to cache current native zoom level
67+ */
68+ private static int DEFAULT_ZOOM = 100 ;
6269
63- boolean isIcon ;
70+ private HashMap < Integer , Long > zoomLevelToHandle = new HashMap <>() ;
6471
72+ boolean isIcon ;
73+ private ImageData source ;
74+ private ImageData mask ;
75+ private int hotspotX ;
76+ private int hotspotY ;
6577/**
6678 * Prevents uninitialized instances from being created outside the package.
6779 */
@@ -184,6 +196,10 @@ public Cursor(Device device, int style) {
184196 */
185197public Cursor (Device device , ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
186198 super (device );
199+ this .source = source ;
200+ this .mask = mask ;
201+ this .hotspotX = hotspotX ;
202+ this .hotspotY = hotspotY ;
187203 if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
188204 if (mask == null ) {
189205 if (source .getTransparencyType () != SWT .TRANSPARENCY_MASK ) {
@@ -246,6 +262,9 @@ public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int
246262 */
247263public Cursor (Device device , ImageData source , int hotspotX , int hotspotY ) {
248264 super (device );
265+ this .source = source ;
266+ this .hotspotX = hotspotX ;
267+ this .hotspotY = hotspotY ;
249268 if (source == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
250269 /* Check the hotspots */
251270 if (hotspotX >= source .width || hotspotX < 0 ||
@@ -319,6 +338,55 @@ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
319338 init ();
320339}
321340
341+ /**
342+ * <b>IMPORTANT:</b> This method is not part of the public
343+ * API for Image. It is marked public only so that it
344+ * can be shared within the packages provided by SWT. It is not
345+ * available on all platforms, and should never be called from
346+ * application code.
347+ *
348+ * Updates zoom and refresh the Cursor based on the native zoom level, if required.
349+ *
350+ * @param cursor the cursor to get the handle of
351+ * @param zoom device zoom in % of the monitor on which the image is painted
352+ *
353+ * @return true if cursor is refreshed
354+ *
355+ * @noreference This method is not intended to be referenced by clients.
356+ */
357+ public static Long win32_getHandle (Cursor cursor , int zoom ) {
358+ if (cursor .isDisposed ()) {
359+ return cursor .handle ;
360+ }
361+ if (cursor .zoomLevelToHandle .get (zoom ) != null ) {
362+ return cursor .zoomLevelToHandle .get (zoom );
363+ }
364+
365+ if (cursor .source == null ) {
366+ cursor .setHandleForZoomLevel (cursor .handle , zoom );
367+ } else {
368+ ImageData source = DPIUtil .scaleImageData (cursor .device , cursor .source , zoom , DEFAULT_ZOOM );
369+ if (cursor .isIcon ) {
370+ Cursor newCursor = new Cursor (cursor .device , source , cursor .hotspotX , cursor .hotspotY );
371+ cursor .setHandleForZoomLevel (newCursor .handle , zoom );
372+ } else {
373+ ImageData mask = DPIUtil .scaleImageData (cursor .device , cursor .mask , zoom , DEFAULT_ZOOM );
374+ Cursor newCursor = new Cursor (cursor .device , source , mask , cursor .hotspotX , cursor .hotspotY );
375+ cursor .setHandleForZoomLevel (newCursor .handle , zoom );
376+ }
377+ }
378+ return cursor .zoomLevelToHandle .get (zoom );
379+ }
380+
381+ private void setHandleForZoomLevel (long handle , Integer zoom ) {
382+ if (this .handle == 0 ) {
383+ this .handle = handle ; // Set handle for default zoom level
384+ }
385+ if (zoom != null && !zoomLevelToHandle .containsKey (zoom )) {
386+ zoomLevelToHandle .put (zoom , handle );
387+ }
388+ }
389+
322390@ Override
323391void destroy () {
324392 /*
@@ -333,7 +401,18 @@ void destroy () {
333401// if (OS.GetCursor() == handle) {
334402// OS.SetCursor(OS.LoadCursor(0, OS.IDC_ARROW));
335403// }
404+ destroyHandle ();
405+ }
406+
407+ private void destroyHandle () {
408+ for (Long handle : zoomLevelToHandle .values ()) {
409+ destroyHandle (handle );
410+ }
411+ zoomLevelToHandle .clear ();
412+ handle = 0 ;
413+ }
336414
415+ private void destroyHandle (long handle ) {
337416 if (isIcon ) {
338417 OS .DestroyIcon (handle );
339418 } else {
@@ -347,7 +426,6 @@ void destroy () {
347426 */
348427 OS .DestroyCursor (handle );
349428 }
350- handle = 0 ;
351429}
352430
353431/**
0 commit comments