@@ -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,163 @@ void destroyHandlesExcept(Set<Integer> zoomLevels) {
578501 });
579502}
580503
504+ private static final long createHandleFromImageData (Cursor cursor , int zoom , ImageData source , ImageData mask ,
505+ int hotspotX , int hotspotY ) {
506+ return cursor .isIcon ? setupCursorFromImageData (cursor .device , source , hotspotX , hotspotY )
507+ : setupCursorFromImageData (source , mask , hotspotX , hotspotY );
508+ }
509+
510+ private static interface CursorHandleProvider {
511+ long createHandle (Cursor cursor , int zoom );
512+ }
513+
514+ private static class StyleCursorHandleProvider implements CursorHandleProvider {
515+ private final int style ;
516+
517+ public StyleCursorHandleProvider (int style ) {
518+ this .style = style ;
519+ }
520+
521+ @ Override
522+ public long createHandle (Cursor cursor , int zoom ) {
523+ // zoom ignored, LoadCursor handles scaling internally
524+ return setupCursorFromStyle (this .style );
525+ }
526+
527+ private static final long setupCursorFromStyle (int style ) {
528+ long lpCursorName = 0 ;
529+ switch (style ) {
530+ case SWT .CURSOR_HAND :
531+ lpCursorName = OS .IDC_HAND ;
532+ break ;
533+ case SWT .CURSOR_ARROW :
534+ lpCursorName = OS .IDC_ARROW ;
535+ break ;
536+ case SWT .CURSOR_WAIT :
537+ lpCursorName = OS .IDC_WAIT ;
538+ break ;
539+ case SWT .CURSOR_CROSS :
540+ lpCursorName = OS .IDC_CROSS ;
541+ break ;
542+ case SWT .CURSOR_APPSTARTING :
543+ lpCursorName = OS .IDC_APPSTARTING ;
544+ break ;
545+ case SWT .CURSOR_HELP :
546+ lpCursorName = OS .IDC_HELP ;
547+ break ;
548+ case SWT .CURSOR_SIZEALL :
549+ lpCursorName = OS .IDC_SIZEALL ;
550+ break ;
551+ case SWT .CURSOR_SIZENESW :
552+ lpCursorName = OS .IDC_SIZENESW ;
553+ break ;
554+ case SWT .CURSOR_SIZENS :
555+ lpCursorName = OS .IDC_SIZENS ;
556+ break ;
557+ case SWT .CURSOR_SIZENWSE :
558+ lpCursorName = OS .IDC_SIZENWSE ;
559+ break ;
560+ case SWT .CURSOR_SIZEWE :
561+ lpCursorName = OS .IDC_SIZEWE ;
562+ break ;
563+ case SWT .CURSOR_SIZEN :
564+ lpCursorName = OS .IDC_SIZENS ;
565+ break ;
566+ case SWT .CURSOR_SIZES :
567+ lpCursorName = OS .IDC_SIZENS ;
568+ break ;
569+ case SWT .CURSOR_SIZEE :
570+ lpCursorName = OS .IDC_SIZEWE ;
571+ break ;
572+ case SWT .CURSOR_SIZEW :
573+ lpCursorName = OS .IDC_SIZEWE ;
574+ break ;
575+ case SWT .CURSOR_SIZENE :
576+ lpCursorName = OS .IDC_SIZENESW ;
577+ break ;
578+ case SWT .CURSOR_SIZESE :
579+ lpCursorName = OS .IDC_SIZENWSE ;
580+ break ;
581+ case SWT .CURSOR_SIZESW :
582+ lpCursorName = OS .IDC_SIZENESW ;
583+ break ;
584+ case SWT .CURSOR_SIZENW :
585+ lpCursorName = OS .IDC_SIZENWSE ;
586+ break ;
587+ case SWT .CURSOR_UPARROW :
588+ lpCursorName = OS .IDC_UPARROW ;
589+ break ;
590+ case SWT .CURSOR_IBEAM :
591+ lpCursorName = OS .IDC_IBEAM ;
592+ break ;
593+ case SWT .CURSOR_NO :
594+ lpCursorName = OS .IDC_NO ;
595+ break ;
596+ default :
597+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
598+ }
599+ long handle = OS .LoadCursor (0 , lpCursorName );
600+ if (handle == 0 ) {
601+ SWT .error (SWT .ERROR_NO_HANDLES );
602+ }
603+ return handle ;
604+ }
605+ }
606+
607+ private static class ImageDataProviderCursorHandleProvider implements CursorHandleProvider {
608+ private final ImageDataProvider provider ;
609+ private final int hotspotX ;
610+ private final int hotspotY ;
611+
612+ public ImageDataProviderCursorHandleProvider (ImageDataProvider provider , int hotspotX , int hotspotY ) {
613+ this .provider = provider ;
614+ this .hotspotX = hotspotX ;
615+ this .hotspotY = hotspotY ;
616+ }
617+
618+ @ Override
619+ public long createHandle (Cursor cursor , int zoom ) {
620+ ImageData source ;
621+ if (zoom == DEFAULT_ZOOM ) {
622+ source = this .provider .getImageData (DEFAULT_ZOOM );
623+ } else {
624+ Image tempImage = new Image (cursor .device , this .provider );
625+ source = tempImage .getImageData (zoom );
626+ tempImage .dispose ();
627+ }
628+ int hotspotXInPixels = Win32DPIUtils .pointToPixel (hotspotX , zoom );
629+ int hotspotYInPixels = Win32DPIUtils .pointToPixel (hotspotY , zoom );
630+ long handle = createHandleFromImageData (cursor , zoom , source , null , hotspotXInPixels , hotspotYInPixels );
631+
632+ return handle ;
633+ }
634+ }
635+
636+ private static class ImageDataCursorHandleProvider implements CursorHandleProvider {
637+ private final ImageData source ;
638+ private final ImageData mask ;
639+ private final int hotspotX ;
640+ private final int hotspotY ;
641+
642+ public ImageDataCursorHandleProvider (ImageData source , ImageData mask , int hotspotX , int hotspotY ) {
643+ this .source = source ;
644+ this .mask = mask ;
645+ this .hotspotX = hotspotX ;
646+ this .hotspotY = hotspotY ;
647+ }
648+
649+ @ Override
650+ public long createHandle (Cursor cursor , int zoom ) {
651+ ImageData scaledSource = DPIUtil .scaleImageData (cursor .device , this .source , zoom , DEFAULT_ZOOM );
652+ ImageData scaledMask = this .mask != null ? DPIUtil .scaleImageData (cursor .device , mask , zoom , DEFAULT_ZOOM )
653+ : null ;
654+ int hotspotXInPixels = Win32DPIUtils .pointToPixel (hotspotX , zoom );
655+ int hotspotYInPixels = Win32DPIUtils .pointToPixel (hotspotY , zoom );
656+ long handle = createHandleFromImageData (cursor , zoom , scaledSource , scaledMask , hotspotXInPixels ,
657+ hotspotYInPixels );
658+
659+ return handle ;
660+ }
661+ }
662+
581663}
0 commit comments