Skip to content

Revise the Cursor class to support scaling #2271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,9 @@ void createNSCursor(int hotspotX, int hotspotY, byte[] buffer, int width, int he
*/
public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
super(device);
setupCursorFromImageData(source, hotspotX, hotspotY);
}
private void setupCursorFromImageData(ImageData source, int hotspotX, int hotspotY) {
if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (hotspotX >= source.width || hotspotX < 0 ||
hotspotY >= source.height || hotspotY < 0) {
Expand Down Expand Up @@ -448,6 +451,41 @@ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
}
}

/**
* Constructs a new cursor given a device, image describing
* the desired cursor appearance, and the x and y coordinates of
* the <em>hotspot</em> (that is, the point within the area
* covered by the cursor which is considered to be where the
* on-screen pointer is "pointing").
* <p>
* You must dispose the cursor when it is no longer required.
* </p>
*
* @param device the device on which to allocate the cursor
* @param image the image for the cursor
* @param hotspotX the x coordinate of the cursor's hotspot
* @param hotspotY the y coordinate of the cursor's hotspot
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
* <li>ERROR_NULL_ARGUMENT - if the image is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the hotspot is outside the bounds of the
* image</li>
* </ul>
* @exception SWTError <ul>
* <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li>
* </ul>
*
* @see #dispose()
*
* @since 3.131
*/
public Cursor(Device device, Image image, int hotspotX, int hotspotY) {
super(device);
if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
setupCursorFromImageData(image.getImageData(), hotspotX, hotspotY);
}

@Override
void destroy() {
handle.release();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int
*/
public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
super(device);
setupCursorFromImageData(source, hotspotX, hotspotY);

}

private void setupCursorFromImageData(ImageData source, int hotspotX, int hotspotY) {
if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (hotspotX >= source.width || hotspotX < 0 ||
hotspotY >= source.height || hotspotY < 0) {
Expand Down Expand Up @@ -355,6 +360,41 @@ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
init();
}

/**
* Constructs a new cursor given a device, image describing
* the desired cursor appearance, and the x and y coordinates of
* the <em>hotspot</em> (that is, the point within the area
* covered by the cursor which is considered to be where the
* on-screen pointer is "pointing").
* <p>
* You must dispose the cursor when it is no longer required.
* </p>
*
* @param device the device on which to allocate the cursor
* @param image the image for the cursor
* @param hotspotX the x coordinate of the cursor's hotspot
* @param hotspotY the y coordinate of the cursor's hotspot
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
* <li>ERROR_NULL_ARGUMENT - if the image is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the hotspot is outside the bounds of the
* image</li>
* </ul>
* @exception SWTError <ul>
* <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li>
* </ul>
*
* @see #dispose()
*
* @since 3.131
*/
public Cursor(Device device, Image image, int hotspotX, int hotspotY) {
super(device);
if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
setupCursorFromImageData(image.getImageData(), hotspotX, hotspotY);
}

long createCursor(byte[] sourceData, byte[] maskData, int width, int height, int hotspotX, int hotspotY, boolean reverse) {
for (int i = 0; i < sourceData.length; i++) {
byte s = sourceData[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public final class Cursor extends Resource {
private HashMap<Integer, Long> zoomLevelToHandle = new HashMap<>();

boolean isIcon;
private final Image backingImage;
private final ImageData source;
private final ImageData mask;
private final int hotspotX;
Expand All @@ -79,6 +80,7 @@ public final class Cursor extends Resource {
Cursor(Device device) {
super(device);
this.source = null;
this.backingImage = null;
this.mask = null;
this.hotspotX = -1;
this.hotspotY = -1;
Expand Down Expand Up @@ -204,6 +206,7 @@ public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int
this.mask = mask;
this.hotspotX = hotspotX;
this.hotspotY = hotspotY;
this.backingImage = null;
if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
if (mask == null) {
if (source.getTransparencyType() != SWT.TRANSPARENCY_MASK) {
Expand Down Expand Up @@ -271,6 +274,11 @@ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
this.mask = null;
this.hotspotX = hotspotX;
this.hotspotY = hotspotY;
this.backingImage = null;
setupCursorFromImageData(source);
}

private void setupCursorFromImageData(ImageData source) {
if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
/* Check the hotspots */
if (hotspotX >= source.width || hotspotX < 0 ||
Expand Down Expand Up @@ -345,6 +353,46 @@ public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) {
this.device.registerResourceWithZoomSupport(this);
}

/**
* Constructs a new cursor given a device, image describing
* the desired cursor appearance, and the x and y coordinates of
* the <em>hotspot</em> (that is, the point within the area
* covered by the cursor which is considered to be where the
* on-screen pointer is "pointing").
* <p>
* You must dispose the cursor when it is no longer required.
* </p>
*
* @param device the device on which to allocate the cursor
* @param image the image for the cursor
* @param hotspotX the x coordinate of the cursor's hotspot
* @param hotspotY the y coordinate of the cursor's hotspot
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
* <li>ERROR_NULL_ARGUMENT - if the image is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the hotspot is outside the bounds of the
* image</li>
* </ul>
* @exception SWTError <ul>
* <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li>
* </ul>
*
* @see #dispose()
*
* @since 3.131
*/
public Cursor(Device device, Image image, int hotspotX, int hotspotY) {
super(device);
if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
this.backingImage = image;
this.source = image.getImageData();
this.mask = null;
this.hotspotX = hotspotX;
this.hotspotY = hotspotY;
setupCursorFromImageData(image.getImageData());
}

/**
* <b>IMPORTANT:</b> This method is not part of the public
* API for Image. It is marked public only so that it
Expand All @@ -371,7 +419,13 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
if (cursor.source == null) {
cursor.setHandleForZoomLevel(cursor.handle, zoom);
} else {
ImageData source = DPIUtil.scaleImageData(cursor.device, cursor.source, zoom, DEFAULT_ZOOM);
ImageData source;
if (cursor.backingImage != null) {
source = cursor.backingImage.getImageData(zoom);
}
else {
source = DPIUtil.scaleImageData(cursor.device, cursor.source, zoom, DEFAULT_ZOOM);
}
if (cursor.isIcon) {
Cursor newCursor = new Cursor(cursor.device, source, cursor.hotspotX, cursor.hotspotY);
cursor.setHandleForZoomLevel(newCursor.handle, zoom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
Expand Down Expand Up @@ -153,6 +154,15 @@ public void test_ConstructorLorg_eclipse_swt_graphics_DeviceLorg_eclipse_swt_gra
}
}

@Test
public void test_ConstructorLorg_eclipse_swt_graphics_DeviceLorg_eclipse_swt_graphics_ImageData() {
// Test new Cursor(Device device, ImageData source, ImageData mask, int
// hotspotX, int hotspotY)
Image sourceImage = new Image(display, 10, 10);
Cursor cursor = new Cursor(display, sourceImage, 0, 0);
cursor.dispose();
}

@Test
public void test_equalsLjava_lang_Object() {
/* Note: Two cursors are only considered equal if their handles are equal.
Expand Down
Loading