2003/10/28 10:10:17
authormegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:40:06 +0000 (07:40 +0000)
committermegacz <megacz@xwt.org>
Fri, 30 Jan 2004 07:40:06 +0000 (07:40 +0000)
darcs-hash:20040130074006-2ba56-30624f81d2ea0ade984feda8738d317dcece1064.gz

src/org/xwt/Box.java.pp
src/org/xwt/Glyph.java
src/org/xwt/Main.java
src/org/xwt/Picture.java
src/org/xwt/PixelBuffer.java
src/org/xwt/Platform.java
src/org/xwt/Res.java
src/org/xwt/Surface.java
src/org/xwt/ThreadMessage.java
src/org/xwt/XWT.java

index 2df28b0..81439f7 100644 (file)
@@ -451,7 +451,7 @@ public final class Box extends JS.Scope {
 
         if (image != null)
             if ((flags & TILE_FLAG) != 0) renderTiledImage(globalx, globaly, clipx, clipy, clipw, cliph, buf);
-            else renderStretchedImage(globalx, globaly, clipx, clipy, clipw, cliph, buf);
+            else buf.drawPicture(image, globalx, globaly, clipx, clipy, clipx + clipw, clipy + cliph);
 
        if (text != null && !text.equals(""))
             renderText(globalx, globaly, clipx, clipy, clipw, cliph, buf);
@@ -480,12 +480,9 @@ public final class Box extends JS.Scope {
         }
     }
 
-    void renderStretchedImage(int globalx, int globaly, int clipx, int clipy, int clipw, int cliph, PixelBuffer buf) {
-        // FIXME: wrong
-        buf.drawPicture(image, clipx, clipy, clipx + clipw, clipy + cliph, 0, 0, image.getWidth(), image.getHeight());
-    }
-
     void renderTiledImage(int globalx, int globaly, int x, int y, int w, int h, PixelBuffer buf) {
+        /*
+          FIXME
         int iw = image.getWidth();
         int ih = image.getHeight();
         for(int i=(x - x)/iw; i <= (x + w - x)/iw; i++) {
@@ -505,6 +502,7 @@ public final class Box extends JS.Scope {
                     buf.drawPicture(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
             }
         }
+        */
     }
 
     void renderText(int x, int y, int clipx, int clipy, int clipw, int cliph, PixelBuffer buf) {
@@ -516,10 +514,10 @@ public final class Box extends JS.Scope {
                 buf.drawPictureAlphaOnly(g.p,
                                          x,
                                          y + g.max_ascent - g.baseline + g.max_descent,
+                                         x,
+                                         y + g.max_ascent - g.baseline + g.max_descent,
                                          x + g.p.getWidth(),
                                          y + g.max_ascent - g.baseline + g.max_descent + g.p.getHeight(),
-                                         0, 0,
-                                         g.p.getWidth(), g.p.getHeight(),
                                          textcolor);
             x += g.advance;
         }
@@ -1111,7 +1109,6 @@ public final class Box extends JS.Scope {
                     public Object get(Box b) { return b; }
                     public void put(Box b, Object value) {
                         if (value == null) b.remove();
-                        else if (value.equals("window") || value.equals("frame")) Platform.createSurface(b, value.equals("frame"), true);
                         else if (Log.on) Log.log(this, "put invalid value to 'thisbox' property: " + value);
                     }
                 });
@@ -1178,18 +1175,20 @@ public final class Box extends JS.Scope {
                 });
             //#end
         
-            //#repeat width/height minwidth/minheight maxwidth/maxheight
+            //#repeat width/height height/width minwidth/minheight maxwidth/maxheight true/false
             specialBoxProperties.put("width", new SpecialBoxProperty() {
                     public Object get(Box b) { return new Integer(b.width); }
                     public void put(Box b, Object value) {
-                        int width = stoi(value);
+                        int newval = stoi(value);
                         if (b.parent == null && b.surface != null) {
-                            b.width = width;
-                            b.surface.setSize();
+                            // hack to circumvent #repeat
+                            int other = b.height;
+                            if (true) b.surface.setSize(newval, other);
+                            else b.surface.setSize(other, newval);
                             MARK_FOR_REFLOW_b;
                         } else {
-                            if (b.minwidth == width && b.maxwidth == width) return;
-                            b.minwidth = b.maxwidth = width;
+                            if (b.minwidth == newval && b.maxwidth == newval) return;
+                            b.minwidth = b.maxwidth = newval;
                             MARK_FOR_REFLOW_b;
                         }
                     } });
@@ -1263,11 +1262,8 @@ public final class Box extends JS.Scope {
                     } });
         
             specialBoxProperties.put("image", new SpecialBoxProperty() {
-                    /* FIXME
-                    public Object get(Box b) { return b.image == null ? null : ImageDecoder.imageToNameMap.get(b.image); }
-                    */
+                    public Object get(Box b) { return b.image == null ? null : b.image.res; }
                     public void put(Box b, Object value) {
-                        //if (image != null) System.out.println("hit");
                         if (value == null) {
                             b.image = null;
                         } else if (value instanceof Res) {
index 6088717..425cfd2 100644 (file)
@@ -19,9 +19,11 @@ public class Glyph {
         Glyph ret = (Glyph)glyphCache.get(res, new Integer((((int)c) << 16) | pointsize));
         if (ret != null) return ret;
 
+        ThreadMessage.fakeBackground = true;
         // FEATURE: be smarter here
-        if (c < 256) Freetype.renderGlyphs(res, pointsize, 0, 255, glyphCache);
+        if (c >= 32 && c < 127) Freetype.renderGlyphs(res, pointsize, 32, 126, glyphCache);
         else Freetype.renderGlyphs(res, pointsize, (int)c, (int)c, glyphCache);
+        ThreadMessage.fakeBackground = false;
 
         ret = (Glyph)glyphCache.get(res, new Integer((((int)c) << 16) | pointsize));
         if (ret != null) return ret;
index 4f1c6ac..e771585 100644 (file)
@@ -24,8 +24,10 @@ public class Main {
     public static java.net.InetAddress originAddr = null;
     public static String originHost = null;
     public static String origin = null;
-
-    public static Res builtin = null;
+    
+    public static final Res builtin = new Res.Zip(new Res() {
+            public InputStream getInputStream(String path) { return Platform.getBuiltinInputStream(); } });
+    public static Picture scarImage = null;
 
     public static void printUsage() {
         System.err.println("Usage: xwt [-s] [-v] [-l <port>/<url>] source-location [initial-template]");
@@ -60,9 +62,6 @@ public class Main {
         Platform.forceLoad();
         if (Log.on) for(int i=0; i<args.length; i++) Log.log(Main.class, "argument " + i + ": " + args[i]);
 
-        Res zip = new Res() { public InputStream getInputStream(String path) { return Platform.getBuiltinInputStream(); } };
-        builtin = new Res.Zip(zip);
-
         String initialTemplateName = args.length > startargs + 1 ? args[startargs + 1] : "main";
         initialTemplateName = initialTemplateName.replace('/', '.');
         origin = args[startargs];
@@ -95,6 +94,7 @@ public class Main {
                 Message.Q.startQ();
                 ThreadMessage.newthread(new JS.Callable() {
                         public Object call(JS.Array args) {
+                            scarImage = Picture.fromRes((Res)Main.builtin.get("org/xwt/builtin/scar.png"));
                             Template.getTemplate(((Res)final_rr.get(initialTemplate))).apply(new Box(), null, xwt);
                             return null;
                         }
index 29e3184..da65368 100644 (file)
@@ -24,11 +24,9 @@ public abstract class Picture {
     private static Cache cache = new Cache();
 
     private static GIF gif = new GIF();
-    private static PNG png = new PNG();
     
     /** turns a resource into a Picture.Source */
     public static Picture fromRes(Res r) {
-        // FIXME: put self in background thread if needed
         Picture ret = (Picture)cache.get(r);
         if (ret == null) {
             try {
@@ -36,10 +34,11 @@ public abstract class Picture {
                 int c = pbis.read();
                 pbis.unread(c);
                 if (c == 'G') ret = gif.fromInputStream(pbis, r.getDescriptiveName());
-                else if (c == 137) ret = png.fromInputStream(pbis, r.getDescriptiveName());
+                else if (c == 137) ret = new PNG().fromInputStream(pbis, r.getDescriptiveName());
                 else if (c == 0xff) ret = Platform.decodeJPEG(pbis, r.getDescriptiveName());
                 else throw new JS.Exn("couldn't figure out image type from first byte");
                 cache.put(r, ret);
+                ret.res = r;
             } catch (IOException e) {
                 Log.logJS(Picture.class, e);
                 return null;
@@ -48,6 +47,9 @@ public abstract class Picture {
         return ret;
     }
 
+    /** the resource that created this Picture */
+    public Res res = null;
+
     /** the height of the picture */
     public abstract int getHeight();
     
index 9bb41be..eb8425a 100644 (file)
@@ -21,8 +21,8 @@ package org.xwt;
  */
 public abstract class PixelBuffer {
 
-    /** Draw the region of source within s onto the region d on this PixelBuffer, scaling as needed */
-    public abstract void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2);
+    /** draw the picture at (dx1, dy1), cropping to (cx1, cy1, cx2, cy2) */
+    public abstract void drawPicture(Picture source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2);
 
     /** fill a trapezoid whose top and bottom edges are horizontal */
     public abstract void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
@@ -32,8 +32,7 @@ public abstract class PixelBuffer {
      *  channels of the Picture in the process.  This method may assume that the RGB channels of the image are all zero IFF it
      *  restores this invariant before returning.
      */
-    public abstract void drawPictureAlphaOnly(Picture source, int dx1, int dy1, int dx2, int dy2,
-                                              int sx1, int sy1, int sx2, int sy2, int rgb);
+    public abstract void drawPictureAlphaOnly(Picture source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2, int rgb);
 
     // FIXME: we want floats (inter-pixel spacing) for antialiasing, but this hoses the fastpath line drawing... argh!
     /** draws a line of width <tt>w</tt>; note that the coordinates here are <i>post-transform</i> */
index aa8be35..c06bb8a 100644 (file)
@@ -66,10 +66,9 @@ public class Platform {
             else if (!version.startsWith("1.0") && !version.startsWith("1.1")) platform_class = "Java2";
 
             /*
-        // Disable 2d hardware acceleration on Jaguar
-        if (os_name.equals("Mac OS X") && os_version.equals("10.2"))
+            // Disable 2d hardware acceleration on Jaguar
+            if (os_name.equals("Mac OS X") && os_version.startsWith("10.2")) System.setProperty("com.apple.hwaccel", "false");
             */
-        System.setProperty("com.apple.hwaccel", "false");
 
             if (platform_class != null) {
                 platform = (Platform)Class.forName("org.xwt.plat." + platform_class).newInstance();
index 3f34f82..54bebcb 100644 (file)
@@ -101,6 +101,7 @@ public abstract class Res extends JS {
     public static class HTTP extends CachedRes {
         private String url;
         HTTP(String url) { this.url = url; }
+        public String getDescriptiveName() { return url; }
         public InputStream _getInputStream(String path) throws IOException {
             return new org.xwt.HTTP(url + path).GET(); }
     }
@@ -109,6 +110,7 @@ public abstract class Res extends JS {
     public static class ByteArray extends Res {
         private byte[] bytes;
         ByteArray(byte[] bytes) { this.bytes = bytes; }
+        public String getDescriptiveName() { return "byte[]"; }
         public InputStream getInputStream(String path) throws IOException {
             if (!"".equals(path)) throw new JS.Exn("can't get subresources of a byte[] resource");
             return new ByteArrayInputStream(bytes);
@@ -119,6 +121,7 @@ public abstract class Res extends JS {
     public static class File extends Res {
         private String path;
         File(String path) { this.path = path; }
+        public String getDescriptiveName() { return "file://" + path; }
         public InputStream getInputStream(String rest) throws IOException {
             return new FileInputStream((path + rest).replace('/', java.io.File.separatorChar)); }
     }
@@ -127,9 +130,11 @@ public abstract class Res extends JS {
     public static class Zip extends Res {
         private Res parent;
         Zip(Res parent) { this.parent = parent; }
+        public String getDescriptiveName() { return parent.getDescriptiveName() + "!"; }
         public InputStream getInputStream(String path) throws IOException {
             if (path.startsWith("/")) path = path.substring(1);
-            ZipInputStream zis = new ZipInputStream(parent.getInputStream());
+            InputStream pis = parent.getInputStream();
+            ZipInputStream zis = new ZipInputStream(pis);
             ZipEntry ze = zis.getNextEntry();
             while(ze != null && !ze.getName().equals(path)) ze = zis.getNextEntry();
             if (ze == null) throw new JS.Exn("requested file (" + path + ") not found in archive");
@@ -186,6 +191,7 @@ public abstract class Res extends JS {
         final Res watchee;
         JS.Callable callback;
         ProgressWatcher(Res watchee, JS.Callable callback) { this.watchee = watchee; this.callback = callback; }
+        public String getDescriptiveName() { return watchee.getDescriptiveName(); }
         public InputStream getInputStream(String s) throws IOException {
             final InputStream is = watchee.getInputStream(s);
             return new FilterInputStream(is) {
index 3f29808..c30a34b 100644 (file)
@@ -73,13 +73,21 @@ public abstract class Surface extends PixelBuffer {
     public abstract void setInvisible(boolean b);      ///< If <tt>b</tt>, make window invisible; otherwise, make it non-invisible.
     protected abstract void _setMaximized(boolean b);  ///< If <tt>b</tt>, maximize the surface; otherwise, un-maximize it.
     protected abstract void _setMinimized(boolean b);  ///< If <tt>b</tt>, minimize the surface; otherwise, un-minimize it.
-    protected abstract void setSize(int width, int height);  ///< Sets the surface's width and height.
     public abstract void setLocation();                      ///< Set the surface's x/y position to that of the root box
     public abstract void setTitleBarText(String s);      ///< Sets the surface's title bar text, if applicable
     public abstract void setIcon(Picture i);      ///< Sets the surface's title bar text, if applicable
     public abstract void _dispose();      ///< Destroy the surface
     public void setLimits(int min_width, int min_height, int max_width, int max_height) { }
+    protected abstract void _setSize(int width, int height);  ///< Sets the surface's width and height.
 
+    protected final void setSize(int width, int height) {
+        if (root.width != width || root.height != height) {
+            root.dirty(0, root.height - Main.scarImage.getHeight(), Main.scarImage.getWidth(), Main.scarImage.getHeight());
+            root.width = Math.max(Main.scarImage.getWidth(), width);
+            root.height = Math.max(Main.scarImage.getHeight(), height);
+        }
+        _setSize(root.width, root.height);
+    }
 
     // Helper methods for subclasses ////////////////////////////////////////////////////////////
 
@@ -248,13 +256,6 @@ public abstract class Surface extends PixelBuffer {
 
     // Other Methods ///////////////////////////////////////////////////////////////////////////////
 
-    /** wrapper for setSize() which makes sure to dirty the place where the scar used to be */
-    void setSize() {
-        root.width = Math.max(root.width, 10);
-        root.height = Math.max(root.height, 10);
-        setSize(root.width, root.height);
-    }
-
     /** Indicates that the Surface is no longer needed */
     public final void dispose(boolean quitIfAllSurfacesGone) {
         if (Log.on) Log.log(this, "disposing " + this);
@@ -294,7 +295,7 @@ public abstract class Surface extends PixelBuffer {
         do {
             abort = false;
             root.reflow();
-            setSize();
+            setSize(root.width, root.height);
             // update mouseinside and trigger Enter/Leave as a result of box size/position changes
             String oldcursor = cursor;
             cursor = "default";
@@ -314,6 +315,9 @@ public abstract class Surface extends PixelBuffer {
             if (w <= 0 || h <= 0) continue;
 
             root.render(0, 0, x, y, w, h, this, identity);
+            drawPicture(Main.scarImage,
+                        0, root.height - Main.scarImage.getHeight(), 
+                        x, y, w, h);
             
             if (abort) {
 
@@ -360,16 +364,15 @@ public abstract class Surface extends PixelBuffer {
         PixelBuffer backbuffer = Platform.createPixelBuffer(Platform.getScreenWidth(), Platform.getScreenHeight(), this);
         DirtyList screenDirtyRegions = new DirtyList();
 
-        public void drawPicture(Picture source, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
-            screenDirtyRegions.dirty(dx1, dy1, dx2 - dx1, dy2 - dy1);
-            backbuffer.drawPicture(source, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2); }
+        public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+            screenDirtyRegions.dirty(cx1, cy1, cx2 - cx1, cy2 - cy1);
+            backbuffer.drawPicture(source, dx, dy, cx1, cy1, cx2, cy2);
+        }
 
-        public void drawPictureAlphaOnly(Picture source,
-                                         int dx1, int dy1, int dx2, int dy2,
-                                         int sx1, int sy1, int sx2, int sy2,
-                                         int argb) {
-            screenDirtyRegions.dirty(dx1, dy1, dx2 - dx1, dy2 - dy1);
-            backbuffer.drawPictureAlphaOnly(source, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, argb); }
+        public void drawPictureAlphaOnly(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int argb) {
+            screenDirtyRegions.dirty(cx1, cy1, cx2 - cx1, cy2 - cy1);
+            backbuffer.drawPictureAlphaOnly(source, dx, dy, cx1, cy1, cx2, cy2, argb);
+        }
 
         public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color) {
             screenDirtyRegions.dirty(Math.min(x1, x3), y1, Math.max(x2, x4) - Math.min(x1, x3), y2 - y1);
index d028642..cfd6cb7 100644 (file)
@@ -16,6 +16,8 @@ import org.xwt.js.*;
  *             this invariant.
  */
 public class ThreadMessage extends Thread implements Message {
+
+    public static boolean fakeBackground = false;
     
     private volatile static int threadcount = 0;
 
@@ -53,6 +55,7 @@ public class ThreadMessage extends Thread implements Message {
 
     /** attempts to put this thread into the background to perform a blocking operation; returns false if unable to do so */
     public static boolean suspendThread() {
+        if (fakeBackground) return true;
         // put ourselves in the background
         Thread thread = Thread.currentThread();
         if (!(thread instanceof ThreadMessage)) {
@@ -67,6 +70,7 @@ public class ThreadMessage extends Thread implements Message {
 
     /** re-enqueues this thread */
     public static void resumeThread() {
+        if (fakeBackground) return;
         ThreadMessage mythread = (ThreadMessage)Thread.currentThread();
         Message.Q.add(mythread);
         mythread.setPriority(Thread.NORM_PRIORITY);
index 9738c06..2d4ef45 100644 (file)
@@ -53,6 +53,8 @@ public final class XWT extends JS.Obj {
     public void put(Object name, Object value) {
         if (name.equals("thread") && value != null && value instanceof JS.Callable) ThreadMessage.newthread((JS.Callable)value);
         else if (name.equals("clipboard")) Platform.setClipBoard(value.toString());
+        else if (name.equals("frame")) Platform.createSurface((Box)value, true, true);
+        else if (name.equals("window")) Platform.createSurface((Box)value, false, true);
         else if (name.equals("proxyAuthorization")) {
             HTTP.Proxy.Authorization.authorization = value.toString();
             HTTP.Proxy.Authorization.waitingForUser.release();