fix bug that prevented scar image from loading
[org.ibex.core.git] / src / org / ibex / core / Box.java
index 7a332ea..5133251 100644 (file)
@@ -41,7 +41,7 @@ import org.ibex.graphics.*;
  *  trigger a Surface.abort; if rendering were done in the same pass,
  *  rendering work done prior to the Surface.abort would be wasted.
  */
-public final class Box extends JS.Obj implements Task {
+public final class Box extends JS.Obj implements Callable {
 
     private static final JS.Method METHOD = new JS.Method();
 
@@ -58,13 +58,9 @@ public final class Box extends JS.Obj implements Task {
     //#define CHECKSET_STRING(prop) if ((value==null&&prop==null)||(value!=null&&JSU.toString(value).equals(prop))) break; prop=JSU.toString(value);
 
     // FIXME memory leak
-    static Hash boxToCursor = new Hash(500, 3);
+    static Basket.Map boxToCursor = new Basket.Hash(500, 3);
 
-    static final Font DEFAULT_FONT;
-    static {
-        try { DEFAULT_FONT = Font.getFont((JS)Main.builtin.get(JSU.S("fonts/vera/Vera.ttf")), 10); }
-        catch(JSExn e) { throw new Error("Error loading default font: " + e); }
-    }
+    public static final Font DEFAULT_FONT = Font.getFont(Main.vera, 10);
 
 
     // Flags //////////////////////////////////////////////////////////////////////
@@ -118,6 +114,10 @@ public final class Box extends JS.Obj implements Task {
     public int maxwidth = Integer.MAX_VALUE;
     public int minheight = 0;
     public int maxheight = Integer.MAX_VALUE;
+    public int minwidth() { return minwidth; }
+    public int minheight() { return minheight; }
+    public int maxwidth() { return maxwidth; }
+    public int maxheight() { return maxheight; }
     private short rows = 1;
     private short cols = 0;
     private short rowspan = 1;
@@ -147,13 +147,14 @@ public final class Box extends JS.Obj implements Task {
     public final int fontSize() { return font == null ? DEFAULT_FONT.pointsize : font.pointsize; }
 
     /** invoked when a resource needed to render ourselves finishes loading */
-    public void perform() throws JSExn {
-        if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return; }
+    public Object run(Object o) throws JSExn {
+        if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return null; }
         if (texture.isLoaded) {
             setWidth(max(texture.width, minwidth), maxwidth); 
             setHeight(max(texture.height, minheight), maxheight); 
             dirty(); }
         else { JS res = texture.stream; texture = null; throw new JSExn("image not found: "+res.unclone()); }
+        return null;
     }
 
     // FEATURE: use cx2/cy2 format
@@ -243,7 +244,8 @@ public final class Box extends JS.Obj implements Task {
     
     void resize(int x, int y, int width, int height) {
         if (x == this.x && y == this.y && width == this.width && height == this.height) return;
-        boolean sizechange = (this.width != width || this.height != height) && hasTrap(SIZECHANGE);
+        boolean sizechange = (this.width != width || this.height != height);
+        try { sizechange = sizechange && getTrap(SIZECHANGE) != null; } catch (JSExn e) {}
         int thisx = parent == null ? 0 : this.x;
         int thisy = parent == null ? 0 : this.y;
         Box who = (parent == null ? this : parent);
@@ -259,7 +261,7 @@ public final class Box extends JS.Obj implements Task {
             this.width = width; this.height = height; this.x = x; this.y = y;
             dirty();
         }
-        if (sizechange) putAndTriggerTrapsAndCatchExceptions(SIZECHANGE, T);
+        if (sizechange) putAndTriggerTrapsAndCatchExceptions(SIZECHANGE, JSU.T);
     }
 
     private float targetColumnSize = (float)0.0;
@@ -435,7 +437,7 @@ public final class Box extends JS.Obj implements Task {
             font.rasterizeGlyphs(text, buf, strokecolor, text_x, text_y, cx1, cy1, cx2, cy2);
         }
 
-        if (path != null) path.realize(Affine.translate(globalx, globaly)).stroke(buf, 1, strokecolor);
+        if (path != null) new Polygon(path, Affine.translate(globalx, globaly)).stroke(buf, strokecolor);
 
         for(Box b = getChild(0); b != null; b = b.nextSibling())
             b.render(globalx, globaly, cx1, cy1, cx2, cy2, buf, null);
@@ -445,20 +447,19 @@ public final class Box extends JS.Obj implements Task {
     // Methods to implement org.ibex.js.JS //////////////////////////////////////
 
   
-    public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
-        switch (nargs) {
+    public JS call(JS method, JS[] args) throws JSExn {
+        switch (args.length) {
             case 1: {
                 //#switch(JSU.toString(method))
                 case "indexof":
-                    Box b = (Box)a0;
+                    Box b = (Box)args[0];
                     if (b.parent != this)
                         return (redirect == null || redirect == this) ?
-                            JSU.N(-1) :
-                            redirect.callMethod(method, a0, a1, a2, rest, nargs);
+                            JSU.N(-1) : redirect.call(method, args);
                     return JSU.N(b.getIndexInParent());
 
                 case "distanceto":
-                    Box b = (Box)a0;
+                    Box b = (Box)args[0];
                     JS ret = new JS.Obj();
                     ret.put(JSU.S("x"), JSU.N(b.localToGlobalX(0) - localToGlobalX(0)));
                     ret.put(JSU.S("y"), JSU.N(b.localToGlobalY(0) - localToGlobalY(0)));
@@ -467,7 +468,7 @@ public final class Box extends JS.Obj implements Task {
                 //#end
             }
         }
-        return super.callMethod(method, a0, a1, a2, rest, nargs);
+        return super.call(method, args);
     }
 
     public JS get(JS name) throws JSExn {
@@ -512,7 +513,7 @@ public final class Box extends JS.Obj implements Task {
         case "minheight": return JSU.N(minheight);
         case "maxheight": return JSU.N(maxheight);
         case "clip": return JSU.B(test(CLIP));
-        case "visible": return JSU.B(test(VISIBLE) && (parent == null || (parent.get(JSU.S("visible")) == T)));
+        case "visible": return JSU.B(test(VISIBLE) && (parent == null || (parent.get(JSU.S("visible")) == JSU.T)));
         case "packed": return JSU.B(test(PACKED));
         case "globalx": return JSU.N(localToGlobalX(0));
         case "globaly": return JSU.N(localToGlobalY(0));
@@ -523,14 +524,14 @@ public final class Box extends JS.Obj implements Task {
                 throw new JSExn("you cannot read from the box.mouse property in background thread context");
             return new Mouse();
         case "numchildren": return redirect == null ? JSU.N(0) : redirect == this ? JSU.N(treeSize()) : redirect.get(JSU.S("numchildren"));
-        case "redirect": return redirect == null ? null : redirect == this ? T : redirect.get(JSU.S("redirect"));
+        case "redirect": return redirect == null ? null : redirect == this ? JSU.T : redirect.get(JSU.S("redirect"));
         case "Minimized": if (parent == null && getSurface() != null) return JSU.B(getSurface().minimized);
         default: return super.get(name);
         //#end
         throw new Error("unreachable"); // unreachable
     }
 
-    private class Mouse extends JS implements JS.Cloneable {
+    private class Mouse extends JS.Immutable implements JS.Cloneable {
         public JS get(JS key) throws JSExn {
             //#switch(JSU.toString(key))
             case "x": return JSU.N(globalToLocalX(getSurface()._mousex));
@@ -539,7 +540,7 @@ public final class Box extends JS.Obj implements Task {
             // this might not get recomputed if we change mousex/mousey...
             case "inside": return JSU.B(test(MOUSEINSIDE));
             //#end
-            return null;
+            return super.get(key);
         }
     }
 
@@ -569,7 +570,7 @@ public final class Box extends JS.Obj implements Task {
         case "shrink":      CHECKSET_FLAG(HSHRINK | VSHRINK); RECONSTRAIN();
         case "hshrink":     CHECKSET_FLAG(HSHRINK); RECONSTRAIN();
         case "vshrink":     CHECKSET_FLAG(VSHRINK); RECONSTRAIN();
-        case "path":        path = Path.parse(JSU.toString(value)); RECONSTRAIN(); dirty();
+        case "path":        path = new Path(JSU.toString(value)); RECONSTRAIN(); dirty();
         case "width":       setWidth(JSU.toInt(value), JSU.toInt(value));
         case "height":      setHeight(JSU.toInt(value), JSU.toInt(value));
         case "maxwidth":    setWidth(minwidth, JSU.toInt(value));
@@ -603,9 +604,9 @@ public final class Box extends JS.Obj implements Task {
             JSU.error("redirect can only be set to a descendant of its current value");
         case "fontsize": font = Font.getFont(font == null ? null : font.stream, JSU.toInt(value)); RECONSTRAIN(); dirty();
         case "font":
-            if(!(value instanceof Stream)) throw new JSExn("You can only put streams to the font property");
+            if(!(value instanceof Fountain)) throw new JSExn("You can only put streams to the font property");
             //FIXME: if (font == value) return;  // FIXME: unclone()
-            font = value == null ? null : Font.getFont((Stream)value, font == null ? 10 : font.pointsize);
+            font = value == null ? null : Font.getFont((Fountain)value, font == null ? 10 : font.pointsize);
             RECONSTRAIN();
             dirty();
         case "x": if (parent==null && Surface.fromBox(this)!=null) {
@@ -698,7 +699,7 @@ public final class Box extends JS.Obj implements Task {
         case "bottom": set(ALIGN_BOTTOM);
         case "left": set(ALIGN_LEFT);
         case "right": set(ALIGN_RIGHT);
-        default: JSU.log("invalid alignment \"" + JSU.debugToString(value) + "\"");
+        default: JSU.log("invalid alignment \"" + JSU.str(value) + "\"");
         //#end
     }
     
@@ -729,7 +730,7 @@ public final class Box extends JS.Obj implements Task {
             if (texture == newtex) return;
             texture = newtex;
             fillcolor = 0;
-            if (texture != null && texture.isLoaded) perform();
+            if (texture != null && texture.isLoaded) run(null);
         }
         dirty();
     }
@@ -748,12 +749,12 @@ public final class Box extends JS.Obj implements Task {
         boolean isinside = test(VISIBLE) && inside(x, y) && !obscured;
         if (!wasinside && isinside) {
             set(MOUSEINSIDE);
-            putAndTriggerTrapsAndCatchExceptions(JSU.S("Enter"), T);
+            putAndTriggerTrapsAndCatchExceptions(JSU.S("Enter"), JSU.T);
         }
         if (isinside && test(CURSOR)) getSurface().cursor = (String)boxToCursor.get(this);
         if (wasinside && !isinside) {
             clear(MOUSEINSIDE);
-            putAndTriggerTrapsAndCatchExceptions(JSU.S("Leave"), T);
+            putAndTriggerTrapsAndCatchExceptions(JSU.S("Leave"), JSU.T);
         }
 
         boolean found = false;
@@ -936,10 +937,10 @@ public final class Box extends JS.Obj implements Task {
         try {
             putAndTriggerTraps(name, val);
         } catch (JSExn e) {
-            JSU.log("caught js exception while putting to trap \""+ JSU.debugToString(name)+"\"");
+            JSU.log("caught js exception while putting to trap \""+ JSU.str(name)+"\"");
             JSU.log(e);
         } catch (Exception e) {
-            JSU.log("caught exception while putting to trap \""+ JSU.debugToString(name)+"\"");
+            JSU.log("caught exception while putting to trap \""+ JSU.str(name)+"\"");
             JSU.log(e);
         }
     }