The issue is described here.
Prior discussion was here.
Files affected would be:
/trunk/engine/src/desktop/com/jme3/cursors/plugins/CursorLoader.java
and
/branches/gradle-restructure/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java
though the paths may change due to some recent moves. I will update before committing, of course.
Here are the diffs:
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -56,9 +56,11 @@
* @creation Jun 5, 2012 9:45:58 AM
*/
public class CursorLoader implements AssetLoader {
+ final private static int FDE_OFFSET = 6; // first directory entry offset
private boolean isIco;
private boolean isAni;
+ private boolean isCur; // .cur format if true
/**
* Loads and return a cursor file of one of the following format: .ani, .cur and .ico.
@@ -70,15 +72,16 @@
isIco = false;
isAni = false;
+ isCur = false;
isIco = ((AssetKey) info.getKey()).getExtension().equals("ico");
if (!isIco) {
- isIco = ((AssetKey) info.getKey()).getExtension().equals("cur");
- if (!isIco) {
+ isCur = ((AssetKey) info.getKey()).getExtension().equals("cur");
+ if (!isCur) {
isAni = ((AssetKey) info.getKey()).getExtension().equals("ani");
}
}
- if (!isAni && !isIco) {
+ if (!isAni && !isIco && !isCur) {
throw new IllegalArgumentException("Cursors supported are .ico, .cur or .ani");
}
@@ -209,7 +212,7 @@
} else {
throw new IllegalArgumentException("Unknown format.");
}
- } else if (isIco) {
+ } else if (isCur || isIco) {
DataInputStream in = new DataInputStream(inStream);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[16384];
@@ -221,7 +224,24 @@
}
BufferedImage bi[] = parseICOImage(icoimages);
- CursorImageData cid = new CursorImageData(bi, 0, 0, 0, 0);
+ int hotSpotX = 0;
+ int hotSpotY = 0;
+ CursorImageData cid = new CursorImageData(bi, 0, hotSpotX, hotSpotY, 0);
+ if (isCur) {
+ /*
+ * Per http://msdn.microsoft.com/en-us/library/ms997538.aspx
+ * every .cur file should provide hotspot coordinates.
+ */
+ hotSpotX = icoimages[FDE_OFFSET + 4]
+ + icoimages[FDE_OFFSET + 5] * 255;
+ hotSpotY = icoimages[FDE_OFFSET + 6]
+ + icoimages[FDE_OFFSET + 7] * 255;
+ cid.xHotSpot = hotSpotX;
+ /*
+ * Flip the Y-coordinate.
+ */
+ cid.yHotSpot = cid.height - 1 - hotSpotY;
+ }
cid.completeCursor();
return setJmeCursor(cid);
@@ -255,7 +275,6 @@
BufferedImage[] bi;
// Check resource type field.
- int FDE_OFFSET = 6; // first directory entry offset
int DE_LENGTH = 16; // directory entry length
int BMIH_LENGTH = 40; // BITMAPINFOHEADER length
This is a slightly cleaner solution than the patch proposed by @EmpirePhoenix – though someone with more complete understanding of the code could probably do a better job.
I’ve tested this fix on various assets.
May I commit this?