Browse Source

- Removed a comment on a line that wasn't to be commented...
- Fixed import problem when RIFF header didn't have height/width (when it should). The loader will now use the first image's width/height. Since all images in an animation are supposed to be the same size this should not be a problem.
- Fixed import when an .ICO file contains more than one image (as it in in the case of "windows theme" files). The loader will default to a 32x32 icon in that list.
- Formatting.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9485 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

dan..om 13 years ago
parent
commit
0ade9ab80f
1 changed files with 62 additions and 26 deletions
  1. 62 26
      engine/src/core-plugins/com/jme3/cursors/plugins/CursorLoader.java

+ 62 - 26
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<IntBuffer> cursors = new ArrayList<IntBuffer>();
             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);
                 }
             }