2003/11/13 07:46:41
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:41:15 +0000 (07:41 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:41:15 +0000 (07:41 +0000)
darcs-hash:20040130074115-2ba56-d0eacf6b706142fe8bef4d50fef7e36c5a62c4df.gz

18 files changed:
src/org/xwt/Box.java
src/org/xwt/BoxTree.java
src/org/xwt/HTTP.java
src/org/xwt/Picture.java
src/org/xwt/Platform.java
src/org/xwt/Res.java
src/org/xwt/SOAP.java
src/org/xwt/Surface.java
src/org/xwt/Template.java
src/org/xwt/XMLRPC.java
src/org/xwt/XWT.java
src/org/xwt/js/JS.java
src/org/xwt/js/JSContext.java
src/org/xwt/js/JSFunction.java
src/org/xwt/js/JSScope.java
src/org/xwt/js/JSTrap.java
src/org/xwt/translators/Freetype.java
src/org/xwt/translators/MSPack.java

index 475b380..a76c25d 100644 (file)
@@ -152,8 +152,7 @@ public abstract class Box extends JSScope implements JSTrap.JSTrappable {
         }
     }
 
-    public void putAndTriggerTraps(Object key, Object value) {
-        // FIXME
+    public void putAndTriggerJSTraps(Object key, Object value) {
     }
 
     /** update MOUSEINSIDE, check for Enter/Leave/Move */
@@ -164,7 +163,7 @@ public abstract class Box extends JSScope implements JSTrap.JSTrappable {
         if (isinside) set(MOUSEINSIDE); else clear(MOUSEINSIDE);
         if (!wasinside && !isinside) return;
         
-        if (isinside && test(CURSOR)) getRoot().cursor = (String)boxToCursor.get(this);
+        if (isinside && test(CURSOR)) Surface.fromBox(getRoot()).cursor = (String)boxToCursor.get(this);
         if (!wasinside && isinside && getTrap("Enter") != null) putAndTriggerJSTraps("Enter", T);
         else if (wasinside && !isinside && getTrap("Leave") != null) putAndTriggerJSTraps("Leave", T);
         else if (wasinside && isinside && (mousex != oldmousex || mousey != oldmousey) && getTrap("Move")!= null)
@@ -240,7 +239,7 @@ public abstract class Box extends JSScope implements JSTrap.JSTrappable {
             dirty();
             try { if (sizechange) putAndTriggerJSTraps("SizeChange", T); Surface.abort = true; }
             catch (Exception e) { Log.log(this, e); }
-            try { if (poschange) pputAndTriggerJSTraps("PosChange", T); Surface.abort = true; }
+            try { if (poschange) putAndTriggerJSTraps("PosChange", T); Surface.abort = true; }
             catch (Exception e) { Log.log(this, e); }
             /*
         }
@@ -533,8 +532,8 @@ public abstract class Box extends JSScope implements JSTrap.JSTrappable {
         int mousex = globalToLocalX(surface.mousex);
         int mousey = globalToLocalY(surface.mousey);
         for(Box c = prevSibling(); c != null; c = c.prevSibling())
-            if (c.inside(mousex - c.x, mousey - c.y)) { JSTrap.putAndTriggerJSTraps(c, name, value); return; }
-        if (parent != null) JSTrap.putAndTriggerJSTraps(parent, name, value);
+            if (c.inside(mousex - c.x, mousey - c.y)) { c.putAndTriggerJSTraps(name, value); return; }
+        if (parent != null) parent.putAndTriggerJSTraps(name, value);
     }
 
     private static int stringToColor(String s) {
@@ -613,14 +612,17 @@ public abstract class Box extends JSScope implements JSTrap.JSTrappable {
     
     protected Box left = null;
     protected Box right = null;
-    protected Box parent_ = null;    // not to be confused with Box.parent_!
     protected Box rootChild = null;
+    protected Box peerTree_parent = null;
+    public abstract Box peerTree_leftmost();
+    public abstract Box peerTree_rightmost();
+    public abstract Box insertBeforeMe(Box cell);
+    public abstract Box insertAfterMe(Box cell);
     protected abstract Box fixAfterInsertion();
     protected abstract Box fixAfterDeletion();
-    protected abstract Box rightmost();
-    protected abstract Box leftmost();
     protected abstract Box rotateLeft();
     protected abstract Box rotateRight();
+    protected abstract int numPeerChildren();
 }
 
 
index ef84541..9f89ece 100644 (file)
@@ -330,7 +330,7 @@ public final class BoxTree extends Box {
         removeNode();
         parent = null;
         if (oldparent != null) { Box b = oldparent; MARK_REFLOW_b; }
-        if (oldparent != null) oldparent.putAndInvokeTraps("childremoved", this);
+        if (oldparent != null) oldparent.putAndTriggerJSTraps("childremoved", this);
     }
 
     /** Returns ith child */
@@ -372,22 +372,22 @@ public final class BoxTree extends Box {
         }
 
         if (redirect == null) {
-            if (value == null) putAndTriggerTraps("childremoved", getChild(i));
+            if (value == null) putAndTriggerJSTraps("childremoved", getChild(i));
             else Log.logJS(this, "attempt to add/remove children to/from a node with a null redirect");
 
         } else if (redirect != this) {
-            if (value != null) putAndTriggerTraps("childadded", b);
+            if (value != null) putAndTriggerJSTraps("childadded", value);
             redirect.put(i, value);
             if (value == null) {
-                Box b = (Box)redirect.get(new Integer(i)) : (Box)value;
-                if (b != null) putAndTriggerTraps("childremoved", b);
+                Box b = (Box)redirect.get(new Integer(i));
+                if (b != null) putAndTriggerJSTraps("childremoved", b);
             }
 
         } else if (value == null) {
-            if (i < 0 || i > numChildren()) return;
+            if (i < 0 || i > numchildren) return;
             Box b = getChild(i);
             b.remove();
-            putAndTriggerTraps("childremoved", b);
+            putAndTriggerJSTraps("childremoved", b);
 
         } else {
             Box b = (Box)value;
@@ -412,15 +412,15 @@ public final class BoxTree extends Box {
             numchildren++;
 
             Box before = getChild(i);
-            if (before == null) root.peerTree_rightmost().insertAfterMe(b);
+            if (before == null) rootChild.peerTree_rightmost().insertAfterMe(b);
             else before.insertBeforeMe(b);
             
             // need both of these in case child was already uncalc'ed
             MARK_REFLOW_b;
             MARK_REFLOW;
             
-            b.dirty();
-            putAndTriggerTraps("childadded", b);
+            b.dirty(); 
+            putAndTriggerJSTraps("childadded", b);
         }
     }
 }
index 84e5abb..2b42f97 100644 (file)
@@ -283,7 +283,7 @@ public class HTTP {
             org.xwt.js.JSArray args = new org.xwt.js.JSArray();
             args.addElement(url.toString());
             args.addElement(url.getHost());
-            Object obj = pacFunc.call(args);
+            Object obj = pacFunc.call(null, args);
             if (Log.verbose) Log.log(this, "  PAC script returned \"" + obj + "\"");
             pac = obj.toString();
         } catch (Throwable e) {
@@ -779,7 +779,7 @@ public class HTTP {
                 }
 
                 JSFunction scr = JS.parse("PAC script at " + url, 0, new StringReader(script));
-                scr.cloneWithNewJSScope(proxyAutoConfigRootJSScope).call(new JSArray());
+                scr.cloneWithNewParentJSScope(proxyAutoConfigRootJSScope).call(null, new JSArray());
                 return (JSCallable)proxyAutoConfigRootJSScope.get("FindProxyForURL");
             } catch (Exception e) {
                 if (Log.on) {
index 942bf03..3168390 100644 (file)
@@ -30,7 +30,7 @@ public abstract class Picture {
     public abstract int getWidth();
 
     /** Pictures, cache keyed by Res instance */
-    private static Cache cache = new Cache();
+    private static Cache cache = new Cache(100);
     private static GIF gif = new GIF();
     
     /** turns a resource into a Picture.Source and passes it to the callback */
@@ -45,9 +45,9 @@ public abstract class Picture {
                         try {
                             Picture ret = null;
                             InputStream pbis = new ByteArrayInputStream(b);
-                            if ((b[0] & 0xff) == 'G') ret = gif.fromInputStream(pbis, r.getDescriptiveName());
-                            else if ((b[0] & 0xff) == 137) ret = new PNG().fromInputStream(pbis, r.getDescriptiveName());
-                            else if ((b[0] & 0xff) == 0xff) ret = Platform.decodeJPEG(pbis, r.getDescriptiveName());
+                            if ((b[0] & 0xff) == 'G') ret = gif.fromInputStream(pbis, "some picture");
+                            else if ((b[0] & 0xff) == 137) ret = new PNG().fromInputStream(pbis, "some picture");
+                            else if ((b[0] & 0xff) == 0xff) ret = Platform.decodeJPEG(pbis, "some picture");
                             else throw new JS.Exn("couldn't figure out image type from first byte");
                             ret.res = r;
                             cache.put(r, ret);
index 1640779..9c1d429 100644 (file)
@@ -226,7 +226,7 @@ public class Platform {
 
     /** displays a platform-specific "open file" dialog and returns the chosen filename, or null if the user hit cancel */
     protected String _fileDialog(String suggestedFileName, boolean write) { return null; }
-    public static void fileDialog(String suggestedFileName, boolean write) throws JS.Exn {
+    public static String fileDialog(String suggestedFileName, boolean write) throws org.xwt.js.JS.Exn {
         return platform._fileDialog(suggestedFileName, write);
     }
 
index b2ae73b..df0813f 100644 (file)
@@ -19,8 +19,8 @@ public abstract class Res extends JS {
     public static Res fromString(String url) {
         if (url.startsWith("http://")) return new HTTP(url);
         else if (url.startsWith("https://")) return new HTTP(url);
-        else if (url.startsWith("data:")) return new ByteArray(Base64.decode(url.substring(5)));
-        else if (url.startsWith("utf8:")) return new ByteArray(url.substring(5).getBytes());
+        else if (url.startsWith("data:")) return new ByteArray(Base64.decode(url.substring(5)), null);
+        else if (url.startsWith("utf8:")) return new ByteArray(url.substring(5).getBytes(), null);
         throw new JS.Exn("invalid resource specifier " + url);
     }
 
@@ -57,8 +57,8 @@ public abstract class Res extends JS {
 
     // Caching //////////////////////////////////////////////////////////////////////
 
-    private static class NotCacheableException extends Exception { }
-    private static NotCacheableException notCacheable = new NotCacheableException();
+    public static class NotCacheableException extends Exception { }
+    public static NotCacheableException notCacheable = new NotCacheableException();
 
     /** if it makes sense to cache a resource, the resource must return a unique key */
     public String getCacheKey() throws NotCacheableException { throw notCacheable; }
@@ -68,9 +68,12 @@ public abstract class Res extends JS {
     public static class CachedRes extends Res {
         private Res parent;
         private boolean disk = false;
-        public String getCacheKey() throws NotCacheableException { return parent.getCacheKey(); }
+        private String key;
+        public String getCacheKey() throws NotCacheableException { return key; }
         private Hash cachedInputStreams = new Hash();
-        public CachedRes(Res p, String s, boolean d) { this.parent = p; this.disk = d; }
+        public CachedRes(Res p, String s, boolean d) throws NotCacheableException {
+            this.parent = p; this.disk = d; this.key = p.getCacheKey();
+        }
         public InputStream getInputStream(String path) throws IOException {
             CachedInputStream cis = (CachedInputStream)cachedInputStreams.get(path);
             if (cis == null) {
@@ -80,7 +83,7 @@ public abstract class Res extends JS {
                                          java.io.File.separatorChar + ".xwt" +
                                          java.io.File.separatorChar + "caches" +
                                          java.io.File.separatorChar +
-                                         new String(Base64.encode(parent.getCacheKey().getBytes())));
+                                         new String(Base64.encode(key.getBytes())));
                     Log.log(this, "caching resource in " + f);
                     new java.io.File(f.getParent()).mkdirs();
                     if (f.exists()) return new FileInputStream(f);
@@ -98,7 +101,7 @@ public abstract class Res extends JS {
     /** HTTP or HTTPS resource */
     public static class HTTP extends Res {
         private String url;
-        HTTP(String url) { while (url.endsWith('/')) url = url.substring(0, url.length() - 1); this.url = url; }
+        HTTP(String url) { while (url.endsWith("/")) url = url.substring(0, url.length() - 1); this.url = url; }
         public String getCacheKey() throws NotCacheableException { return url; }
         public InputStream getInputStream(String path) throws IOException { return new org.xwt.HTTP(url + path).GET(); }
     }
@@ -107,7 +110,7 @@ public abstract class Res extends JS {
     public static class ByteArray extends Res {
         private byte[] bytes;
         private String cacheKey = null;
-        ByteArray(byte[] bytes, String cacheKey) { this.bytes = bytes; this.cacheKey = cacheKey; }}
+        ByteArray(byte[] bytes, String cacheKey) { this.bytes = bytes; this.cacheKey = cacheKey; }
         public String getCacheKey() throws NotCacheableException { return cacheKey; }
         public InputStream getInputStream(String path) throws IOException {
             if (!"".equals(path)) throw new JS.Exn("can't get subresources of a byte[] resource");
@@ -119,7 +122,7 @@ public abstract class Res extends JS {
     public static class File extends Res {
         private String path;
         File(String path) {
-            while (path.endsWith(java.io.File.separatorChar)) path = path.substring(0, path.length() - 1);
+            while (path.endsWith(java.io.File.separatorChar + "")) path = path.substring(0, path.length() - 1);
             this.path = path;
         }
         public String getCacheKey() throws NotCacheableException { throw notCacheable; }  // already on the disk!
index 59fc5c0..4ffb8a0 100644 (file)
@@ -92,7 +92,7 @@ class SOAP extends XMLRPC {
 
             } else if (me instanceof byte[]) {
                 objects.removeElementAt(objects.size() - 1);
-                objects.addElement(new Res.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size()))));
+                objects.addElement(new Res.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size())), null));
                 content.reset();                
 
             } else if (me instanceof Integer) {
@@ -233,7 +233,7 @@ class SOAP extends XMLRPC {
             Enumeration e = j.keys();
             while(e.hasMoreElements()) {
                 Object key = e.nextElement();
-                appendObject(key, j.get(key), sb);
+                appendObject((String)key, j.get(key), sb);
             }
             sb.append("</" + name + ">\r\n");
 
@@ -259,7 +259,7 @@ class SOAP extends XMLRPC {
             Enumeration e = ((JS)args.elementAt(0)).keys();
             while(e.hasMoreElements()) {
                 Object key = e.nextElement();
-                appendObject(key, ((JS)args.elementAt(0)).get(key), content);
+                appendObject((String)key, ((JS)args.elementAt(0)).get(key), content);
             }
         }
         content.append("    </" + methodname + "></SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n");
index a187981..b0b8df1 100644 (file)
@@ -232,7 +232,7 @@ public abstract class Surface extends PixelBuffer {
     protected final void SizeChange(final int width, final int height) {
         Scheduler.add(new Message() { public void perform() {
             if (width == root.width && height == root.height) return;
-            root.set(REFLOW);
+            root.set(root.REFLOW);
             do { abort = false; root.reflow(width, height); } while(abort);
         }});
         abort = true;
index 6956027..9a324d2 100644 (file)
@@ -97,7 +97,7 @@ public class Template {
         if (staticscript == null) return staticJSScope;
         JSFunction temp = staticscript;
         staticscript = null;
-        JSContext.invoke(temp.cloneWithNewParentJSSCope(staticJSScope));
+        temp.cloneWithNewParentJSScope(staticJSScope).call(new JSArray());
         return staticJSScope;
     }
     
@@ -121,15 +121,15 @@ public class Template {
         for (int i=0; children != null && i<children.size(); i++) {
             Box kid = new BoxTree();
             ((Template)children.elementAt(i)).apply(kid, xwt, pis);
-            b.putAndTriggerTraps(b.numChildren(), kid);
+            b.putAndTriggerJSTraps(JSObj.N(b.numchildren), kid);
         }
 
-        if (script != null) JSContext.invoke(script.cloneWithNewParentJSScope(pis));
+        if (script != null) script.cloneWithNewParentJSScope(pis).call(new JSArray());
 
         for(int i=0; keys != null && i<keys.length; i++)
-            if (vals[i] instanceof String && ((String)vals[i]).charAt(0) == '$') b.putAndTriggerTraps(keys[i], pis.get(vals[i]));
-            else if ("image".equals(keys[i])) b.putAndTriggerTraps("image", resolveStringToResource((String)vals[i], xwt, true));
-            else if (keys[i] != null) b.putAndTriggerTraps(keys[i], vals[i]);
+            if (vals[i] instanceof String && ((String)vals[i]).charAt(0) == '$') b.putAndTriggerJSTraps(keys[i], pis.get(vals[i]));
+            else if ("image".equals(keys[i])) b.putAndTriggerJSTraps("image", resolveStringToResource((String)vals[i], xwt, true));
+            else if (keys[i] != null) b.putAndTriggerJSTraps(keys[i], vals[i]);
     }
 
 
index 8368bf7..43654c7 100644 (file)
@@ -102,7 +102,7 @@ class XMLRPC extends JSCallable {
                 objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
             
             else if (c.localName.equals("base64"))
-                objects.setElementAt(new Res.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size()))), objects.size() - 1);
+                objects.setElementAt(new Res.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size())), null), objects.size() - 1);
 
             else if (c.localName.equals("name"))
                 objects.addElement(new String(content.getBuf(), 0, content.size()));
index 99bd691..f8b9c6d 100644 (file)
@@ -22,7 +22,7 @@ public final class XWT extends JSCallable {
         Sub(String key) { this.key = key; }
         public void put(Object key, Object val) { XWT.this.put(this.key + "." + key, val); }
         public Object get(Object key) { return XWT.this.get(this.key + "." + key); }
-        public Object call(Object method, JSArray args) { return XWT.call(method == null ? key : this.key + "." + method, args); }
+        public Object call(Object method, JSArray args) { return XWT.this.call(method == null ? key : this.key + "." + method, args); }
     }
 
     public Object get(Object name) {
@@ -32,28 +32,28 @@ public final class XWT extends JSCallable {
         case "date": return new JSDate();
         case "origin": return Main.origin;
         case "box": return new BoxTree();
-        case "ui": return sub("ui");
-        case "ui.key": return sub("ui.key");
+        case "ui": return new Sub("ui");
+        case "ui.key": return new Sub("ui.key");
         case "ui.key.alt": return Surface.alt ? Boolean.TRUE : Boolean.FALSE;
         case "ui.key.control": return Surface.control ? Boolean.TRUE : Boolean.FALSE;
         case "ui.key.shift": return Surface.shift ? Boolean.TRUE : Boolean.FALSE;
         case "ui.clipboard": return Platform.getClipBoard();
         case "ui.maxdim": return new Integer(Short.MAX_VALUE);
-        case "ui.key.name": return sub("ui.key.name");
+        case "ui.key.name": return new Sub("ui.key.name");
         case "ui.key.name.alt": return Platform.altKeyName();
-        case "ui.screen": return sub("ui.screen");
+        case "ui.screen": return new Sub("ui.screen");
         case "ui.screen.width": return new Integer(Platform.getScreenWidth());
         case "ui.screen.height": return new Integer(Platform.getScreenHeight());
         case "fs.home": return System.getProperty("user.home");
         case "fs.temp": return System.getProperty("java.io.tempdir");
-        case "ui.mouse": return sub("ui.mouse");
+        case "ui.mouse": return new Sub("ui.mouse");
         case "ui.mouse.button":
             if (Surface.button1 && !Surface.button2 && !Surface.button3) return new Integer(1);
             else if (!Surface.button1 && Surface.button2 && !Surface.button3) return new Integer(2);
             else if (!Surface.button1 && !Surface.button2 && Surface.button3) return new Integer(3);
             else return new Integer(0);
-        case "undocumented": return sub("undocumented");
-        case "undocumented.internal": return sub("undocumented.internal");
+        case "undocumented": return new Sub("undocumented");
+        case "undocumented.internal": return new Sub("undocumented.internal");
         //#end
         return rr.get(name);
     }
@@ -61,7 +61,7 @@ public final class XWT extends JSCallable {
     public void put(Object name, final Object value) {
         //#switch(name)
         case "thread":
-            Scheduler.add(new Scheduler.Task() { public void perform() { JSContext.newJSContext((JSFunction)value, null); } });
+            Scheduler.add(new Scheduler.Task() { public void perform() { JSContext.invokePauseable((JSFunction)value); } });
         case "ui.clipboard": Platform.setClipBoard((String)value);
         case "ui.frame": Platform.createSurface((Box)value, true, true);
         case "ui.window": Platform.createSurface((Box)value, false, true);
@@ -101,11 +101,12 @@ public final class XWT extends JSCallable {
             case "clone": return new XWT((Res)a);
             case "res.unzip": return new Res.Zip((Res)a);
             case "res.uncab": return new Res.Cab((Res)a);
-            case "res.cache": return new Res.CachedRes((Res)a, "resources", true);
+            case "res.cache": try { return new Res.CachedRes((Res)a, "resources", true); }
+                              catch (Res.NotCacheableException e) { throw new JS.Exn("this resource cannot be cached"); }
             case "res.fromURL": return Res.fromString((String)a);
             case "thread.sleep": sleep(JS.toInt(a)); return null;
             case "log.println": Log.logJS(this, a== null ? "**null**" : a.toString()); return null;
-            case "log.dump": JS.recurse("", "", a); return null;
+            case "log.dump": Log.recursiveLog("","",a); return null;
             case "regexp": return new JSRegexp(a, null);
             case "rpc.xml": return new XMLRPC((String)a, "");
             case "rpc.soap": return new SOAP((String)a, "", null, null);
@@ -169,9 +170,9 @@ public final class XWT extends JSCallable {
         public XMLHelper() { super(BUFFER_SIZE); }
         public void startElement(XML.Element c) throws XML.SchemaException {
             JS o = new JSObj();
-            o.put("$name", c.localName, null);
+            o.put("$name", c.localName);
             for(int i=0; i<c.len; i++) o.put(c.keys[i], c.vals[i]);
-            o.put("$numchildren", new Integer(0), null);
+            o.put("$numchildren", new Integer(0));
             obStack.addElement(o);
         }
         public void endElement(XML.Element c) throws XML.SchemaException {
@@ -180,8 +181,8 @@ public final class XWT extends JSCallable {
             obStack.setSize(obStack.size() - 1);
             JS parent = (JS)obStack.lastElement();
             int numchildren = ((Integer)parent.get("$numchildren")).intValue();
-            parent.put("$numchildren", new Integer(numchildren + 1), null);
-            parent.put(new Integer(numchildren), me, null);
+            parent.put("$numchildren", new Integer(numchildren + 1));
+            parent.put(new Integer(numchildren), me);
         }
         public void characters(char[] ch, int start, int length) throws XML.SchemaException {
             String s = new String(ch, start, length);
@@ -189,16 +190,15 @@ public final class XWT extends JSCallable {
             int numchildren = ((Integer)parent.get("$numchildren")).intValue();
             Object lastChild = parent.get(new Integer(numchildren - 1));
             if (lastChild instanceof String) {
-                parent.put(new Integer(numchildren - 1), lastChild + s, null);
+                parent.put(new Integer(numchildren - 1), lastChild + s);
             } else {
-                parent.put("$numchildren", new Integer(numchildren + 1), null);
-                parent.put(new Integer(numchildren), s, null);
+                parent.put("$numchildren", new Integer(numchildren + 1));
+                parent.put(new Integer(numchildren), s);
             }
         }
         public void whitespace(char[] ch, int start, int length) {}
-        public JS doParse() throws JS.Exn {
+        public JS doParse(InputStream is) throws JS.Exn {
             try { 
-                InputStream is = getInputStream();
                 BufferedReader r = new BufferedReader(new InputStreamReader(is));
                 parse(r);
             } catch (XML.XMLException e) {
index 6d964ea..f1f6726 100644 (file)
@@ -114,9 +114,9 @@ public abstract class JS {
         public int hashCode() { return graftee.hashCode(); }
         public Object get(Object key) { return replaced_key.equals(key) ? replaced_val : graftee.get(key); }
         public void put(Object key, Object val) { graftee.put(key, val); }
-        public void call(Object method, JSArray args) {
+        public Object call(Object method, JSArray args) {
             if (replaced_key.equals(method)) return ((JSCallable)replaced_val).call(null, args);
-            else if (graftee instanceof JSCallable) return graftee.call(method, args);
+            else if (graftee instanceof JSCallable) return ((JSCallable)graftee).call(method, args);
             else throw new JS.Exn("cannot call this value");
         }
         public Number coerceToNumber() { return graftee.coerceToNumber(); }
index 4eaf9b2..4e2d0b0 100644 (file)
@@ -30,16 +30,16 @@ public class JSContext {
     int pc = 0;                   ///< the program counter
     boolean pauseable;
 
-    public static void invokePauseable(JSFunction function) { new JSContext(f, true).invoke(new JSArray()); }
+    public static void invokePauseable(JSFunction function) { new JSContext(function, true).invoke(new JSArray()); }
 
     JSContext(JSFunction f, boolean pauseable) {
         this.pauseable = pauseable;
         this.f = f;
-        scope = new JSScope(function.parentJSScope);
+        scope = new JSScope(f.parentJSScope);
     }
 
     void invoke(JSArray args) {
-        stack.push(new JSFunction.CallMarker(cx));
+        stack.push(new JSFunction.CallMarker(this));
         stack.push(args);
         resume();
     }
@@ -50,7 +50,6 @@ public class JSContext {
         if (!pauseable) return null;
         pausecount++;
         return new Callback() { public Object call(Object o) {
-            paused = false;
             stack.push(o);
             resume();
             return null;
index 1d068e9..66b2e72 100644 (file)
@@ -2,6 +2,7 @@
 package org.xwt.js;
 
 import org.xwt.util.*;
+import java.util.*;
 import java.io.*;
 
 /** A JavaScript function, compiled into bytecode */
@@ -9,7 +10,7 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
 
     /** Note: code gets run in an <i>unpauseable</i> context. */
     public Object call(JSArray args) {
-        Context cx = new JSContext(this, false);
+        JSContext cx = new JSContext(this, false);
         cx.invoke(args);
         return cx.stack.pop();
     }
@@ -89,7 +90,7 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
 
     /** returns false if the thread has been paused */
     static Object eval(final JSContext cx) throws JS.Exn {
-        final initialPauseCount = cx.pausecount;
+        final int initialPauseCount = cx.pausecount;
         OUTER: for(;; cx.pc++) {
         try {
             if (cx.f == null || cx.pc >= cx.f.size) return cx.stack.pop();
@@ -193,22 +194,22 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
                         cx.pc = ((TryMarker)o).finallyLoc - 1;
                         continue OUTER;
                     } else if (o instanceof CallMarker) {
-                        if (cx.scope instanceof JSTrapScope) {
-                            JSTrapScope ts = (JSTrapScope)cx.scope;
+                        if (cx.scope instanceof JSTrap.JSTrapScope) {
+                            JSTrap.JSTrapScope ts = (JSTrap.JSTrapScope)cx.scope;
                             if (!ts.cascadeHappened) {
                                 ts.cascadeHappened = true;
                                 JSTrap t = ts.t.next;
                                 while (t != null && t.f.numFormalArgs == 0) t = t.next;
                                 if (t == null) {
-                                    ts.trappee.put(key, val);
-                                    if (cx.pausecount > initialPauseCount) return;   // we were paused
+                                    ((JS)ts.t.trapee).put(t.name, ts.val);
+                                    if (cx.pausecount > initialPauseCount) return null;   // we were paused
                                 } else {
                                     cx.stack.push(o);
                                     JSArray args = new JSArray();
                                     args.addElement(ts.val);
-                                    cx.stack.push(ta);
+                                    cx.stack.push(args);
                                     cx.f = t.f;
-                                    cx.scope = new JSTrap.JSTrapScope(cx.f.parentJSScope, ts.val);
+                                    cx.scope = new JSTrap.JSTrapScope(cx.f.parentJSScope, t, ts.val);
                                     cx.pc = -1;
                                     break;
                                 }
@@ -235,28 +236,28 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
                 if (key == null)
                     throw je("tried to assign \"" + (val==null?"(null)":val.toString()) + "\" to the null key");
                 JSTrap t = null;
-                if (o instanceof JSTrap.JSTrappable) {
-                    t = ((JSTrap.JSTrappable)o).getTrap(v);
+                if (target instanceof JSTrap.JSTrappable) {
+                    t = ((JSTrap.JSTrappable)target).getTrap(val);
                     while (t != null && t.f.numFormalArgs == 0) t = t.next;
-                } else if (o instanceof JSTrap.JSTrapScope && key.equals("cascade")) {
-                    JSTrap.JSTrapScope ts = (JSTrap.JSTrapScope)o;
+                } else if (target instanceof JSTrap.JSTrapScope && key.equals("cascade")) {
+                    JSTrap.JSTrapScope ts = (JSTrap.JSTrapScope)target;
                     t = ts.t.next;
                     ts.cascadeHappened = true;
                     while (t != null && t.f.numFormalArgs == 0) t = t.next;
-                    if (t == null) o = ts.t.trappee;
+                    if (t == null) target = ts.t.trapee;
                 }
                 if (t != null) {
                     cx.stack.push(new CallMarker(cx));
                     JSArray args = new JSArray();
                     args.addElement(val);
-                    cx.stack.push(ta);
+                    cx.stack.push(args);
                     cx.f = t.f;
-                    cx.scope = new JSTrap.JSTrapScope(cx.f.parentJSScope, val);
+                    cx.scope = new JSTrap.JSTrapScope(cx.f.parentJSScope, t, val);
                     cx.pc = -1;
                     break;
                 }
                 ((JS)target).put(key, val);
-                if (cx.pausecount > initialPauseCount) return;   // we were paused
+                if (cx.pausecount > initialPauseCount) return null;   // we were paused
                 cx.stack.push(val);
                 break;
             }
@@ -284,23 +285,23 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
                     if (o instanceof JSTrap.JSTrappable) {
                         t = ((JSTrap.JSTrappable)o).getTrap(v);
                         while (t != null && t.f.numFormalArgs != 0) t = t.next;
-                    } else if (o instanceof JSTrap.JSTrapScope && key.equals("cascade")) {
+                    } else if (o instanceof JSTrap.JSTrapScope && v.equals("cascade")) {
                         t = ((JSTrap.JSTrapScope)o).t.next;
                         while (t != null && t.f.numFormalArgs != 0) t = t.next;
-                        if (t == null) o = ((JSTrap.JSTrapScope)o).t.trappee;
+                        if (t == null) o = ((JSTrap.JSTrapScope)o).t.trapee;
                     }
                     if (t != null) {
                         cx.stack.push(new CallMarker(cx));
                         JSArray args = new JSArray();
-                        cx.stack.push(ta);
+                        cx.stack.push(args);
                         cx.f = t.f;
-                        cx.scope = new JSTrap.JSTrapScope(cx.f.parentJSScope, null);
+                        cx.scope = new JSTrap.JSTrapScope(cx.f.parentJSScope, t, null);
                         ((JSTrap.JSTrapScope)cx.scope).cascadeHappened = true;
                         cx.pc = -1;
                         break;
                     }
                     ret = ((JS)o).get(v);
-                    if (cx.pausecount > initialPauseCount) return;   // we were paused
+                    if (cx.pausecount > initialPauseCount) return null;   // we were paused
                     cx.stack.push(ret);
                     break;
                 }
@@ -354,7 +355,7 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens {
                         JSArray arguments = new JSArray();
                         for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j);
                         ret = c.call(method, arguments);
-                        if (cx.pausecount > initialPauseCount) return;   // we were paused
+                        if (cx.pausecount > initialPauseCount) return null;   // we were paused
                         break;
                     }
                 }
index bdf8233..8327ea1 100644 (file)
@@ -44,18 +44,22 @@ public class JSScope extends JSCallable {
             return super.get(key);
         }
 
+        public Object call(Object method, JSArray args) {
+            if (method.equals("stringFromCharCode")) return stringFromCharCode(args);
+            else throw new JS.Exn("method not found");
+        }
+
         public Object call1(Object method, Object arg0) {
             //#switch(method)
-            case "parseInt": return parseInt(arg0, 0);
+            case "parseInt": return parseInt(arg0, N(0));
             case "isNaN": { double d = toDouble(arg0); return d == d ? F : T; }
-            case "isFinite": { double d = toDouble(arg0); return (d == d && !Double.isFinite(d)) ? T : F; }
+            case "isFinite": { double d = toDouble(arg0); return (d == d && !Double.isInfinite(d)) ? T : F; }
             case "decodeURI": throw new JS.Exn("unimplemented");
             case "decodeURIComponent": throw new JS.Exn("unimplemented");
             case "encodeURI": throw new JS.Exn("unimplemented");
             case "encodeURIComponent": throw new JS.Exn("unimplemented");
             case "escape": throw new JS.Exn("unimplemented");
             case "unescape": throw new JS.Exn("unimplemented");
-            case "stringFromCharCode": return stringFromCharCode(arg0);
             //#end
             return null;
         }
@@ -65,13 +69,14 @@ public class JSScope extends JSCallable {
             return null;
         }
 
-        private Object stringFromCharCode(Object arg) {
+        private Object stringFromCharCode(JSArray args) {
             char buf[] = new char[args.length()];
-            for(int i=0;i<args.length();i++) buf[i] = (char)(JS.toInt(arg) & 0xffff);
+            for(int i=0;i<args.length();i++) buf[i] = (char)(JS.toInt(args.elementAt(i)) & 0xffff);
             return new String(buf);
         }
 
-        private Object parseInt(Object arg, int radix) {
+        private Object parseInt(Object arg, Object r) {
+            int radix = JS.toInt(r);
             String s = (String)arg;
             int start = 0;
             int length = s.length();
index baa02ef..3eefe14 100644 (file)
@@ -13,10 +13,10 @@ import java.io.*;
  */
 public class JSTrap {
 
-    private JSTrappable trapee = null;   ///< the box on which this trap was placed
+    JSTrappable trapee = null;   ///< the box on which this trap was placed
     JSFunction f = null;                 ///< the function for this trap
-    private JSTrap next = null;          ///< the next trap down the trap stack
-    private Object name = null;          ///< the property that the trap was placed on
+    JSTrap next = null;          ///< the next trap down the trap stack
+    Object name = null;          ///< the property that the trap was placed on
 
     private JSTrap(JSTrappable b, String n, JSFunction f, JSTrap nx) { trapee = b; name = n; this.f = f; this.next = nx; }
 
@@ -40,7 +40,7 @@ public class JSTrap {
         public abstract void putTrap(Object key, JSTrap trap);
 
         /** puts to this value using an unpauseable context, triggering any traps */
-        public abstract void putAndTriggerTraps(Object key, Object value);
+        public abstract void putAndTriggerJSTraps(Object key, Object value);
     }
 
     // FIXME: cascadeHappened gets set, but autocascade does not happen
@@ -48,7 +48,7 @@ public class JSTrap {
         JSTrap t;
         Object val = null;
         boolean cascadeHappened = false;
-        public JSTrapScope(JSTrap t, Object val) { this.t = t; this.val = val; }
+        public JSTrapScope(JSScope parent, JSTrap t, Object val) { super(parent); this.t = t; this.val = val; }
         public Object get(Object key) {
             if (key.equals("trapee")) return t.trapee;
             if (key.equals("trapname")) return t.name;
index 18934c9..ed52857 100644 (file)
@@ -21,7 +21,7 @@ public class Freetype {
 
     public void loadFontByteStream(Res res) {
         try {
-            Log.log(this, "loading font " + res.getDescriptiveName());
+            Log.log(this, "loading font " + res);
             loadedStream = res;
             InputStream is = res.getInputStream();
             byte[] fontstream = InputStreamToByteArray.convert(is);
@@ -42,17 +42,22 @@ public class Freetype {
         int width = 0;
         int height = 0;
         byte[] data = null;
-        String key = glyph.font.res.getDescriptiveName() + ":" + glyph.c;
-        key = new String(Base64.encode(key.getBytes()));
-        File cacheFile = new java.io.File(System.getProperty("user.home") +
-                                          java.io.File.separatorChar + ".xwt" +
-                                          java.io.File.separatorChar + "caches" +
-                                          java.io.File.separatorChar + "glyphs" +
-                                          java.io.File.separatorChar +
-                                          key);
-        new java.io.File(cacheFile.getParent()).mkdirs();
+        File cacheFile = null;
+        try {
+            String key = glyph.font.res.getCacheKey() + ":" + glyph.c;
+            key = new String(Base64.encode(key.getBytes()));
+            cacheFile = new java.io.File(System.getProperty("user.home") +
+                                         java.io.File.separatorChar + ".xwt" +
+                                         java.io.File.separatorChar + "caches" +
+                                         java.io.File.separatorChar + "glyphs" +
+                                         java.io.File.separatorChar +
+                                         key);
+            new java.io.File(cacheFile.getParent()).mkdirs();
+        } catch (Res.NotCacheableException e) {
+            Log.log(Freetype.class, "note: glyph not cacheable");
+        }
 
-        if (cacheFile.exists()) {
+        if (cacheFile != null && cacheFile.exists()) {
             DataInputStream dis = new DataInputStream(new FileInputStream(cacheFile));
             width = dis.readInt();
             height = dis.readInt();
index b34231c..2af26e8 100644 (file)
@@ -67,7 +67,7 @@ public class MSPack {
     public String[] getFileNames() { return fileNames; }
     public int[] getLengths() { return lengths; }
     public InputStream getInputStream(int index) {
-        return new KnownLength.KnownLengthInputStream(ByteArrayInputStream(data[index]), data[index].length);
+        return new KnownLength.KnownLengthInputStream(new ByteArrayInputStream(data[index]), data[index].length);
     }
     public InputStream getInputStream(String fileName) {
         for(int i=0;i<fileNames.length;i++) {