@@ -68,24 +68,8 @@ public final class Cursor extends Resource {
6868
6969 private HashMap <Integer , Long > zoomLevelToHandle = new HashMap <>();
7070
71+ private final CursorHandleProvider cursorHandleProvider ;
7172 boolean isIcon ;
72- private final ImageDataProvider imageDataProvider ;
73- private final ImageData source ;
74- private final ImageData mask ;
75- private final int hotspotX ;
76- private final int hotspotY ;
77- /**
78- * Prevents uninitialized instances from being created outside the package.
79- */
80- Cursor (Device device ) {
81- super (device );
82- this .source = null ;
83- this .imageDataProvider = null ;
84- this .mask = null ;
85- this .hotspotX = -1 ;
86- this .hotspotY = -1 ;
87- this .device .registerResourceWithZoomSupport (this );
88- }
8973
9074/**
9175 * Constructs a new cursor given a device and a style
@@ -134,42 +118,11 @@ public final class Cursor extends Resource {
134118 * @see #dispose()
135119 */
136120public Cursor (Device device , int style ) {
137- this (device );
138- this .handle = setupCursorFromStyle (style );
121+ super (device );
122+ this .cursorHandleProvider = new StyleCursorHandleProvider (style );
123+ this .handle = this .cursorHandleProvider .createHandle (this , DEFAULT_ZOOM );
139124 init ();
140- }
141-
142- private static long setupCursorFromStyle (int style ) {
143- long lpCursorName = 0 ;
144- switch (style ) {
145- case SWT .CURSOR_HAND : lpCursorName = OS .IDC_HAND ; break ;
146- case SWT .CURSOR_ARROW : lpCursorName = OS .IDC_ARROW ; break ;
147- case SWT .CURSOR_WAIT : lpCursorName = OS .IDC_WAIT ; break ;
148- case SWT .CURSOR_CROSS : lpCursorName = OS .IDC_CROSS ; break ;
149- case SWT .CURSOR_APPSTARTING : lpCursorName = OS .IDC_APPSTARTING ; break ;
150- case SWT .CURSOR_HELP : lpCursorName = OS .IDC_HELP ; break ;
151- case SWT .CURSOR_SIZEALL : lpCursorName = OS .IDC_SIZEALL ; break ;
152- case SWT .CURSOR_SIZENESW : lpCursorName = OS .IDC_SIZENESW ; break ;
153- case SWT .CURSOR_SIZENS : lpCursorName = OS .IDC_SIZENS ; break ;
154- case SWT .CURSOR_SIZENWSE : lpCursorName = OS .IDC_SIZENWSE ; break ;
155- case SWT .CURSOR_SIZEWE : lpCursorName = OS .IDC_SIZEWE ; break ;
156- case SWT .CURSOR_SIZEN : lpCursorName = OS .IDC_SIZENS ; break ;
157- case SWT .CURSOR_SIZES : lpCursorName = OS .IDC_SIZENS ; break ;
158- case SWT .CURSOR_SIZEE : lpCursorName = OS .IDC_SIZEWE ; break ;
159- case SWT .CURSOR_SIZEW : lpCursorName = OS .IDC_SIZEWE ; break ;
160- case SWT .CURSOR_SIZENE : lpCursorName = OS .IDC_SIZENESW ; break ;
161- case SWT .CURSOR_SIZESE : lpCursorName = OS .IDC_SIZENWSE ; break ;
162- case SWT .CURSOR_SIZESW : lpCursorName = OS .IDC_SIZENESW ; break ;
163- case SWT .CURSOR_SIZENW : lpCursorName = OS .IDC_SIZENWSE ; break ;
164- case SWT .CURSOR_UPARROW : lpCursorName = OS .IDC_UPARROW ; break ;
165- case SWT .CURSOR_IBEAM : lpCursorName = OS .IDC_IBEAM ; break ;
166- case SWT .CURSOR_NO : lpCursorName = OS .IDC_NO ; break ;
167- default :
168- SWT .error (SWT .ERROR_INVALID_ARGUMENT );
169- }
170- long handle = OS .LoadCursor (0 , lpCursorName );
171- if (handle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
172- return handle ;
125+ this .device .registerResourceWithZoomSupport (this );
173126}
174127
175128/**
@@ -207,12 +160,8 @@ private static long setupCursorFromStyle(int style) {
207160 */
208161public Cursor (Device device , ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
209162 super (device );
210- this .source = source ;
211- this .mask = mask ;
212- this .hotspotX = hotspotX ;
213- this .hotspotY = hotspotY ;
214- this .imageDataProvider = null ;
215- this .handle = setupCursorFromImageData (source , mask , hotspotX , hotspotY );
163+ this .cursorHandleProvider = new ImageDataCursorHandleProvider (source , mask , hotspotX , hotspotY );
164+ this .handle = this .cursorHandleProvider .createHandle (this , DEFAULT_ZOOM );
216165 init ();
217166 this .device .registerResourceWithZoomSupport (this );
218167}
@@ -280,13 +229,9 @@ private static long setupCursorFromImageData(ImageData source, ImageData mask, i
280229 */
281230public Cursor (Device device , ImageData source , int hotspotX , int hotspotY ) {
282231 super (device );
283- this .source = source ;
284- this .mask = null ;
285- this .hotspotX = hotspotX ;
286- this .hotspotY = hotspotY ;
287- this .imageDataProvider = null ;
288- this .handle = setupCursorFromImageData (device , source , hotspotX , hotspotY );
232+ this .cursorHandleProvider = new ImageDataCursorHandleProvider (source , null , hotspotX , hotspotY );
289233 isIcon = true ;
234+ this .handle = this .cursorHandleProvider .createHandle (this , DEFAULT_ZOOM );
290235 init ();
291236 this .device .registerResourceWithZoomSupport (this );
292237}
@@ -397,13 +342,9 @@ private static long setupCursorFromImageData(Device device, ImageData source, in
397342public Cursor (Device device , ImageDataProvider imageDataProvider , int hotspotX , int hotspotY ) {
398343 super (device );
399344 if (imageDataProvider == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
400- this .imageDataProvider = imageDataProvider ;
401- this .source = imageDataProvider .getImageData (100 );
402- this .mask = null ;
403- this .hotspotX = hotspotX ;
404- this .hotspotY = hotspotY ;
405- this .handle = setupCursorFromImageData (device , this .source , hotspotX , hotspotY );
345+ this .cursorHandleProvider = new ImageDataProviderCursorHandleProvider (imageDataProvider , hotspotX , hotspotY );
406346 isIcon = true ;
347+ this .handle = this .cursorHandleProvider .createHandle (this , DEFAULT_ZOOM );
407348 init ();
408349 this .device .registerResourceWithZoomSupport (this );
409350}
@@ -431,27 +372,9 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
431372 return cursor .zoomLevelToHandle .get (zoom );
432373 }
433374
434- if (cursor .source == null ) {
435- cursor .setHandleForZoomLevel (cursor .handle , zoom );
436- } else {
437- ImageData source ;
438- if (cursor .imageDataProvider != null ) {
439- Image tempImage = new Image (cursor .getDevice (), cursor .imageDataProvider );
440- source = tempImage .getImageData (zoom );
441- tempImage .dispose ();
442- }
443- else {
444- source = DPIUtil .scaleImageData (cursor .device , cursor .source , zoom , DEFAULT_ZOOM );
445- }
446- if (cursor .isIcon ) {
447- long handle = setupCursorFromImageData (cursor .getDevice (), source , Win32DPIUtils .pointToPixel (cursor .hotspotX , zoom ), Win32DPIUtils .pointToPixel (cursor .hotspotY , zoom ));
448- cursor .setHandleForZoomLevel (handle , zoom );
449- } else {
450- ImageData mask = DPIUtil .scaleImageData (cursor .getDevice (), cursor .mask , zoom , DEFAULT_ZOOM );
451- long handle = setupCursorFromImageData (source , mask , Win32DPIUtils .pointToPixel (cursor .hotspotX , zoom ), Win32DPIUtils .pointToPixel (cursor .hotspotY , zoom ));
452- cursor .setHandleForZoomLevel (handle , zoom );
453- }
454- }
375+ long handle = cursor .cursorHandleProvider .createHandle (cursor , zoom );
376+ cursor .setHandleForZoomLevel (handle , zoom );
377+
455378 return cursor .zoomLevelToHandle .get (zoom );
456379}
457380
@@ -578,4 +501,156 @@ void destroyHandlesExcept(Set<Integer> zoomLevels) {
578501 });
579502}
580503
504+ private static interface CursorHandleProvider {
505+ long createHandle (Cursor cursor , int zoom );
506+ }
507+
508+ private static class StyleCursorHandleProvider implements CursorHandleProvider {
509+ private final int style ;
510+
511+ public StyleCursorHandleProvider (int style ) {
512+ this .style = style ;
513+ }
514+
515+ @ Override
516+ public long createHandle (Cursor cursor , int zoom ) {
517+ // zoom ignored, LoadCursor handles scaling internally
518+ return setupCursorFromStyle (this .style );
519+ }
520+
521+ private static final long setupCursorFromStyle (int style ) {
522+ long lpCursorName = 0 ;
523+ switch (style ) {
524+ case SWT .CURSOR_HAND :
525+ lpCursorName = OS .IDC_HAND ;
526+ break ;
527+ case SWT .CURSOR_ARROW :
528+ lpCursorName = OS .IDC_ARROW ;
529+ break ;
530+ case SWT .CURSOR_WAIT :
531+ lpCursorName = OS .IDC_WAIT ;
532+ break ;
533+ case SWT .CURSOR_CROSS :
534+ lpCursorName = OS .IDC_CROSS ;
535+ break ;
536+ case SWT .CURSOR_APPSTARTING :
537+ lpCursorName = OS .IDC_APPSTARTING ;
538+ break ;
539+ case SWT .CURSOR_HELP :
540+ lpCursorName = OS .IDC_HELP ;
541+ break ;
542+ case SWT .CURSOR_SIZEALL :
543+ lpCursorName = OS .IDC_SIZEALL ;
544+ break ;
545+ case SWT .CURSOR_SIZENESW :
546+ lpCursorName = OS .IDC_SIZENESW ;
547+ break ;
548+ case SWT .CURSOR_SIZENS :
549+ lpCursorName = OS .IDC_SIZENS ;
550+ break ;
551+ case SWT .CURSOR_SIZENWSE :
552+ lpCursorName = OS .IDC_SIZENWSE ;
553+ break ;
554+ case SWT .CURSOR_SIZEWE :
555+ lpCursorName = OS .IDC_SIZEWE ;
556+ break ;
557+ case SWT .CURSOR_SIZEN :
558+ lpCursorName = OS .IDC_SIZENS ;
559+ break ;
560+ case SWT .CURSOR_SIZES :
561+ lpCursorName = OS .IDC_SIZENS ;
562+ break ;
563+ case SWT .CURSOR_SIZEE :
564+ lpCursorName = OS .IDC_SIZEWE ;
565+ break ;
566+ case SWT .CURSOR_SIZEW :
567+ lpCursorName = OS .IDC_SIZEWE ;
568+ break ;
569+ case SWT .CURSOR_SIZENE :
570+ lpCursorName = OS .IDC_SIZENESW ;
571+ break ;
572+ case SWT .CURSOR_SIZESE :
573+ lpCursorName = OS .IDC_SIZENWSE ;
574+ break ;
575+ case SWT .CURSOR_SIZESW :
576+ lpCursorName = OS .IDC_SIZENESW ;
577+ break ;
578+ case SWT .CURSOR_SIZENW :
579+ lpCursorName = OS .IDC_SIZENWSE ;
580+ break ;
581+ case SWT .CURSOR_UPARROW :
582+ lpCursorName = OS .IDC_UPARROW ;
583+ break ;
584+ case SWT .CURSOR_IBEAM :
585+ lpCursorName = OS .IDC_IBEAM ;
586+ break ;
587+ case SWT .CURSOR_NO :
588+ lpCursorName = OS .IDC_NO ;
589+ break ;
590+ default :
591+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
592+ }
593+ long handle = OS .LoadCursor (0 , lpCursorName );
594+ if (handle == 0 ) {
595+ SWT .error (SWT .ERROR_NO_HANDLES );
596+ }
597+ return handle ;
598+ }
599+ }
600+
601+ private static class ImageDataProviderCursorHandleProvider implements CursorHandleProvider {
602+ private final ImageDataProvider provider ;
603+ private final int hotspotX ;
604+ private final int hotspotY ;
605+
606+ public ImageDataProviderCursorHandleProvider (ImageDataProvider provider , int hotspotX , int hotspotY ) {
607+ this .provider = provider ;
608+ this .hotspotX = hotspotX ;
609+ this .hotspotY = hotspotY ;
610+ }
611+
612+ @ Override
613+ public long createHandle (Cursor cursor , int zoom ) {
614+ ImageData source ;
615+ if (zoom == DEFAULT_ZOOM ) {
616+ source = this .provider .getImageData (DEFAULT_ZOOM );
617+ } else {
618+ Image tempImage = new Image (cursor .device , this .provider );
619+ source = tempImage .getImageData (zoom );
620+ tempImage .dispose ();
621+ }
622+ int hotspotXInPixels = Win32DPIUtils .pointToPixel (hotspotX , zoom );
623+ int hotspotYInPixels = Win32DPIUtils .pointToPixel (hotspotY , zoom );
624+ return setupCursorFromImageData (cursor .device , source , hotspotXInPixels , hotspotYInPixels );
625+ }
626+ }
627+
628+ private static class ImageDataCursorHandleProvider implements CursorHandleProvider {
629+ private final ImageData source ;
630+ private final ImageData mask ;
631+ private final int hotspotX ;
632+ private final int hotspotY ;
633+
634+ public ImageDataCursorHandleProvider (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
635+ this .source = source ;
636+ this .mask = mask ;
637+ this .hotspotX = hotspotX ;
638+ this .hotspotY = hotspotY ;
639+ }
640+
641+ @ Override
642+ public long createHandle (Cursor cursor , int zoom ) {
643+ ImageData scaledSource = DPIUtil .scaleImageData (cursor .device , this .source , zoom , DEFAULT_ZOOM );
644+ int hotspotXInPixels = Win32DPIUtils .pointToPixel (hotspotX , zoom );
645+ int hotspotYInPixels = Win32DPIUtils .pointToPixel (hotspotY , zoom );
646+ if (cursor .isIcon ) {
647+ return setupCursorFromImageData (cursor .device , scaledSource , hotspotXInPixels , hotspotYInPixels );
648+ } else {
649+ ImageData scaledMask = this .mask != null ? DPIUtil .scaleImageData (cursor .device , mask , zoom , DEFAULT_ZOOM )
650+ : null ;
651+ return setupCursorFromImageData (scaledSource , scaledMask , hotspotXInPixels , hotspotYInPixels );
652+ }
653+ }
654+ }
655+
581656}
0 commit comments