Skip to content

Commit c9148df

Browse files
Use OS.CreateIconIndirect for colored cursors with source and mask
Previously, the Cursor constructor that accepted both source and mask used OS.CreateCursor, which only supports monochrome cursors. As a result, any color information in the source was ignored and the cursor always appeared black. This change updates the constructor to use OS.CreateIconIndirect, allowing full-color cursors while still respecting the mask for transparency. DPI scaling of the source and mask now works correctly with colored cursors.
1 parent 8444ec7 commit c9148df

File tree

1 file changed

+22
-28
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+22
-28
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -154,25 +154,6 @@ public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int
154154
this.device.registerResourceWithZoomSupport(this);
155155
}
156156

157-
private static CursorHandle setupCursorFromImageData(ImageData source, ImageData mask, int hotspotX, int hotspotY) {
158-
if (mask == null) {
159-
mask = source.getTransparencyMask();
160-
}
161-
/* Convert depth to 1 */
162-
mask = ImageData.convertMask(mask);
163-
source = ImageData.convertMask(source);
164-
165-
/* Make sure source and mask scanline pad is 2 */
166-
byte[] sourceData = ImageData.convertPad(source.data, source.width, source.height, source.depth, source.scanlinePad, 2);
167-
byte[] maskData = ImageData.convertPad(mask.data, mask.width, mask.height, mask.depth, mask.scanlinePad, 2);
168-
169-
/* Create the cursor */
170-
long hInst = OS.GetModuleHandle(null);
171-
long handle = OS.CreateCursor(hInst, hotspotX, hotspotY, source.width, source.height, sourceData, maskData);
172-
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
173-
return new CustomCursorHandle(handle);
174-
}
175-
176157
/**
177158
* Constructs a new cursor given a device, image data describing
178159
* the desired cursor appearance, and the x and y coordinates of
@@ -209,7 +190,7 @@ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
209190
this.device.registerResourceWithZoomSupport(this);
210191
}
211192

212-
private static CursorHandle setupCursorFromImageData(Device device, ImageData source, int hotspotX, int hotspotY) {
193+
private static CursorHandle setupCursorFromImageData(Device device, ImageData source, ImageData mask, int hotspotX, int hotspotY) {
213194
if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
214195
long hBitmap = 0;
215196
long hMask = 0;
@@ -258,8 +239,13 @@ private static CursorHandle setupCursorFromImageData(Device device, ImageData so
258239
hMask = OS.CreateBitmap(source.width, source.height, 1, 1, new byte[(((source.width + 7) / 8) + 3) / 4 * 4 * source.height]);
259240
if (hMask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
260241
} else {
261-
ImageData mask = source.getTransparencyMask();
262-
long [] result = Image.initIcon(device, source, mask);
242+
ImageData effectiveMask;
243+
if (mask != null) {
244+
effectiveMask = mask;
245+
} else {
246+
effectiveMask = source.getTransparencyMask();
247+
}
248+
long [] result = Image.initIcon(device, source, effectiveMask);
263249
hBitmap = result[0];
264250
hMask = result[1];
265251
}
@@ -649,7 +635,7 @@ public CursorHandle createHandle(Device device, int zoom) {
649635
source = tempImage.getImageData(zoom);
650636
tempImage.dispose();
651637
}
652-
return setupCursorFromImageData(device, source, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
638+
return setupCursorFromImageData(device, source, null, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
653639
}
654640
}
655641

@@ -667,7 +653,7 @@ public ImageDataCursorHandleProvider(ImageData source, int hotspotX, int hotspot
667653
public CursorHandle createHandle(Device device, int zoom) {
668654
int accessibilityFactor = getPointerSizeScaleFactor();
669655
ImageData scaledSource = DPIUtil.scaleImageData(device, this.source, zoom * accessibilityFactor, DEFAULT_ZOOM);
670-
return setupCursorFromImageData(device, scaledSource, getHotpotXInPixels(zoom),
656+
return setupCursorFromImageData(device, scaledSource, null, getHotpotXInPixels(zoom),
671657
getHotpotYInPixels(zoom));
672658
}
673659
}
@@ -697,10 +683,18 @@ private void validateMask(ImageData source, ImageData mask) {
697683

698684
@Override
699685
public CursorHandle createHandle(Device device, int zoom) {
700-
ImageData scaledSource = DPIUtil.scaleImageData(device, this.source, zoom, DEFAULT_ZOOM);
701-
ImageData scaledMask = this.mask != null ? DPIUtil.scaleImageData(device, mask, zoom, DEFAULT_ZOOM)
702-
: null;
703-
return setupCursorFromImageData(scaledSource, scaledMask, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
686+
float zoomFactor = getPointerSizeScaleFactor() * zoom / 100f;
687+
int scaledSourceWidth = Math.round(this.source.width * zoomFactor);
688+
int scaledSourceHeight = Math.round(this.source.height * zoomFactor);
689+
ImageData scaledSource = this.source.scaledTo(scaledSourceWidth, scaledSourceHeight);
690+
ImageData scaledMask = null;
691+
if (this.mask != null) {
692+
int scaledMaskWidth = Math.round(this.mask.width * zoomFactor);
693+
int scaledMaskHeight = Math.round(this.mask.height * zoomFactor);
694+
scaledMask = this.mask.scaledTo(scaledMaskWidth, scaledMaskHeight);
695+
}
696+
return setupCursorFromImageData(device, scaledSource, scaledMask, getHotpotXInPixels(zoom),
697+
getHotpotYInPixels(zoom));
704698
}
705699
}
706700

0 commit comments

Comments
 (0)