Skip to content

Commit 491e76f

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 b5cfe6b commit 491e76f

File tree

1 file changed

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

1 file changed

+20
-28
lines changed

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

Lines changed: 20 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 maskData, int hotspotX, int hotspotY) {
213194
if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
214195
long hBitmap = 0;
215196
long hMask = 0;
@@ -255,10 +236,21 @@ private static CursorHandle setupCursorFromImageData(Device device, ImageData so
255236
}
256237
}
257238
OS.MoveMemory(dibBM.bmBits, srcData, srcData.length);
258-
hMask = OS.CreateBitmap(source.width, source.height, 1, 1, new byte[(((source.width + 7) / 8) + 3) / 4 * 4 * source.height]);
239+
if (maskData != null) {
240+
long[] maskResult = Image.initIcon(device, maskData, maskData);
241+
hMask = maskResult[1];
242+
} else {
243+
hMask = OS.CreateBitmap(source.width, source.height, 1, 1,
244+
new byte[(((source.width + 7) / 8) + 3) / 4 * 4 * source.height]);
245+
}
259246
if (hMask == 0) SWT.error(SWT.ERROR_NO_HANDLES);
260247
} else {
261-
ImageData mask = source.getTransparencyMask();
248+
ImageData mask;
249+
if(maskData != null) {
250+
mask = maskData;
251+
} else {
252+
mask = source.getTransparencyMask();
253+
}
262254
long [] result = Image.initIcon(device, source, mask);
263255
hBitmap = result[0];
264256
hMask = result[1];
@@ -653,7 +645,7 @@ public CursorHandle createHandle(Device device, int zoom) {
653645
source = tempImage.getImageData(zoom);
654646
tempImage.dispose();
655647
}
656-
return setupCursorFromImageData(device, source, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
648+
return setupCursorFromImageData(device, source, null, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
657649
}
658650
}
659651

@@ -671,7 +663,7 @@ public ImageDataCursorHandleProvider(ImageData source, int hotspotX, int hotspot
671663
public CursorHandle createHandle(Device device, int zoom) {
672664
int accessibilityFactor = getPointerSizeScaleFactor();
673665
ImageData scaledSource = DPIUtil.scaleImageData(device, this.source, zoom * accessibilityFactor, DEFAULT_ZOOM);
674-
return setupCursorFromImageData(device, scaledSource, getHotpotXInPixels(zoom),
666+
return setupCursorFromImageData(device, scaledSource, null, getHotpotXInPixels(zoom),
675667
getHotpotYInPixels(zoom));
676668
}
677669
}
@@ -701,10 +693,10 @@ private void validateMask(ImageData source, ImageData mask) {
701693

702694
@Override
703695
public CursorHandle createHandle(Device device, int zoom) {
704-
ImageData scaledSource = DPIUtil.scaleImageData(device, this.source, zoom, DEFAULT_ZOOM);
705-
ImageData scaledMask = this.mask != null ? DPIUtil.scaleImageData(device, mask, zoom, DEFAULT_ZOOM)
706-
: null;
707-
return setupCursorFromImageData(scaledSource, scaledMask, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
696+
float zoomFactor = (getPointerSizeScaleFactor() * zoom) / 100f;
697+
ImageData scaledSource = this.source.scaledTo((int) (this.source.width * zoomFactor), (int) (this.source.height * zoomFactor));
698+
ImageData scaledMask = this.mask!= null? this.mask.scaledTo((int) (this.mask.width * zoomFactor), (int) (this.mask.height * zoomFactor)) : null;
699+
return setupCursorFromImageData(device, scaledSource, scaledMask, getHotpotXInPixels(zoom), getHotpotYInPixels(zoom));
708700
}
709701
}
710702

0 commit comments

Comments
 (0)