diff --git a/engine/src/core-plugins/com/jme3/cursors/plugins/CursorLoader.java b/engine/src/core-plugins/com/jme3/cursors/plugins/CursorLoader.java index 36fbbecd4..c69d087c8 100644 --- a/engine/src/core-plugins/com/jme3/cursors/plugins/CursorLoader.java +++ b/engine/src/core-plugins/com/jme3/cursors/plugins/CursorLoader.java @@ -36,6 +36,9 @@ public class CursorLoader implements AssetLoader { */ public JmeCursor load(AssetInfo info) throws IOException { + isIco = false; + isAni = false; + isIco = ((AssetKey) info.getKey()).getExtension().equals("ico"); if (!isIco) { isIco = ((AssetKey) info.getKey()).getExtension().equals("cur"); @@ -125,7 +128,7 @@ public class CursorLoader implements AssetLoader { nextInt = leIn.readInt(); if (nextInt == 0x4f464e49) { // Got an INFO, skip its length // this part consist of Author, title, etc -// int skipped = leIn.skipBytes(length - 4); + leIn.skipBytes(length - 4); // System.out.println(" Discarding INFO (skipped = " + skipped + ")"); nextInt = leIn.readInt(); } else if (nextInt == 0x6d617266) { // found a 'fram' for animation @@ -144,6 +147,12 @@ public class CursorLoader implements AssetLoader { } byte[] data = new byte[icoLength]; ((InputStream) leIn).read(data, 0, icoLength); + // in case the header didn't have width or height + // get it from first image. + if (width == 0 || height == 0 && i == 1) { + width = data[6]; + height = data[7]; + } icons.add(data); } // at this point we have the icons, rates (either @@ -155,7 +164,7 @@ public class CursorLoader implements AssetLoader { nextInt = leIn.readInt(); // if for some reason there's JUNK (nextInt > -1) // bail out. - nextInt = nextInt > -1 ? -1 : nextInt; + nextInt = nextInt > -1 ? -1 : nextInt; } } } @@ -180,7 +189,7 @@ public class CursorLoader implements AssetLoader { } BufferedImage bi[] = parseICOImage(icoimages); - CursorImageData cid = new CursorImageData(bi, 0, 0, 0); + CursorImageData cid = new CursorImageData(bi, 0, 0, 0, 0); cid.completeCursor(); return setJmeCursor(cid); @@ -513,23 +522,22 @@ public class CursorLoader implements AssetLoader { public CursorImageData() { } - CursorImageData(BufferedImage[] bi, int delay, int hsX, int hsY) { + CursorImageData(BufferedImage[] bi, int delay, int hsX, int hsY, int curType) { + // cursor type + // 0 - Undefined (an array of images inside an ICO) + // 1 - ICO + // 2 - CUR IntBuffer singleCursor = null; ArrayList cursors = new ArrayList(); int bwidth = 0; int bheight = 0; - // cursor type - // 1 - ICO - // 2 - CUR - // Anything else is invalid. - int curType = 0; + boolean multIcons = false; // make the cursor image for (int i = 0; i < bi.length; i++) { BufferedImage img = bi[i]; bwidth = img.getWidth(); bheight = img.getHeight(); - curType = img.getType(); if (curType == 1) { hsX = 0; hsY = bheight - 1; @@ -539,8 +547,19 @@ public class CursorLoader implements AssetLoader { hsY = bheight - 1; } } else { - throw new IllegalArgumentException( - "An image contained is not of the right type! Only proper ICO and CUR formats are valid."); + // We force to choose 32x32 icon from + // the array of icons in that ICO file. + if (bwidth != 32 && bheight != 32) { + multIcons = true; + continue; + } else { + if (img.getType() != 2) { + continue; + } else { + // force hotspot + hsY = bheight - 1; + } + } } // We flip our image because .ICO and .CUR will always be reversed. @@ -555,10 +574,18 @@ public class CursorLoader implements AssetLoader { cursors.add(singleCursor); } + int count; + if (multIcons) { + bwidth = 32; + bheight = 32; + count = 1; + } else { + count = cursors.size(); + } // put the image in the IntBuffer data = BufferUtils.createIntBuffer(bwidth * bheight); imgDelay = BufferUtils.createIntBuffer(bi.length); - for (int i = 0; i < cursors.size(); i++) { + for (int i = 0; i < count; i++) { data.put(cursors.get(i)); if (delay > 0) { imgDelay.put(delay); @@ -568,14 +595,14 @@ public class CursorLoader implements AssetLoader { height = bheight; xHotSpot = hsX; yHotSpot = hsY; - numImages = cursors.size(); + numImages = count; data.rewind(); if (imgDelay != null) { imgDelay.rewind(); } } - private void addFrame(byte[] imgData, int rate, int jiffy, int width, int height) throws IOException { + private void addFrame(byte[] imgData, int rate, int jiffy, int width, int height, int numSeq) throws IOException { BufferedImage bi[] = parseICOImage(imgData); int hotspotx = 0; int hotspoty = 0; @@ -585,15 +612,16 @@ public class CursorLoader implements AssetLoader { hotspotx = imgData[10] | imgData[11]; hotspoty = imgData[12] | imgData[13]; } else if (type == 1) { - // ICO type, hotspot not stored. Leave at 0; + // ICO type, hotspot not stored. Put at 0, height - 1 + // because it's flipped. hotspotx = 0; - hotspoty = 0; + hotspoty = height - 1; } // System.out.println("Image type = " + (type == 1 ? "CUR" : "ICO")); if (rate == 0) { rate = jiffy; } - CursorImageData cid = new CursorImageData(bi, rate, hotspotx, hotspoty); + CursorImageData cid = new CursorImageData(bi, rate, hotspotx, hotspoty, type); if (width == 0) { this.width = cid.width; } else { @@ -605,13 +633,21 @@ public class CursorLoader implements AssetLoader { this.height = height; } if (data == null) { - data = BufferUtils.createIntBuffer(this.width * this.height * numImages); + if (numSeq > numImages) { + data = BufferUtils.createIntBuffer(this.width * this.height * numSeq); + } else { + data = BufferUtils.createIntBuffer(this.width * this.height * numImages); + } data.put(cid.data); } else { data.put(cid.data); } - if (imgDelay == null && numImages > 1) { - imgDelay = BufferUtils.createIntBuffer(numImages); + if (imgDelay == null && (numImages > 1 || numSeq > 1)) { + if (numSeq > numImages) { + imgDelay = BufferUtils.createIntBuffer(numSeq); + } else { + imgDelay = BufferUtils.createIntBuffer(numImages); + } imgDelay.put(cid.imgDelay); } else if (imgData != null) { imgDelay.put(cid.imgDelay); @@ -631,8 +667,8 @@ public class CursorLoader implements AssetLoader { // since the sequence can be larger than the number // of images in the ani if it reuses one or more of those // images. - if (animSeq != null) { - for (int i = 0 ; i < animSeq.length ; i++) { + if (animSeq != null && animSeq.length > 0) { + for (int i = 0; i < animSeq.length; i++) { if (rate != null) { frRate = rate[i] * MULT; } else { @@ -640,18 +676,18 @@ public class CursorLoader implements AssetLoader { } // the frame # is the one in the animation sequence frame = icons.get(animSeq[i]); - addFrame(frame, frRate, jiffy, width, height); + addFrame(frame, frRate, jiffy, width, height, animSeq.length); // System.out.println("delay of " + frRate); } } else { - for (int i = 0 ; i < icons.size() ; i++) { + for (int i = 0; i < icons.size(); i++) { frame = icons.get(i); if (rate == null) { frRate = jiffy * MULT; } else { frRate = rate[i] * MULT; } - addFrame(frame, frRate, jiffy, width, height); + addFrame(frame, frRate, jiffy, width, height, 0); // System.out.println("delay of " + frRate); } }