From d8a2348c7712a69ac368335417a8f6616e535b1b Mon Sep 17 00:00:00 2001 From: megacz Date: Fri, 30 Jan 2004 07:40:06 +0000 Subject: [PATCH] 2003/10/28 10:10:17 darcs-hash:20040130074006-2ba56-30624f81d2ea0ade984feda8738d317dcece1064.gz --- src/org/xwt/Box.java.pp | 34 +++++++++++++++------------------- src/org/xwt/Glyph.java | 4 +++- src/org/xwt/Main.java | 10 +++++----- src/org/xwt/Picture.java | 8 +++++--- src/org/xwt/PixelBuffer.java | 7 +++---- src/org/xwt/Platform.java | 5 ++--- src/org/xwt/Res.java | 8 +++++++- src/org/xwt/Surface.java | 39 +++++++++++++++++++++------------------ src/org/xwt/ThreadMessage.java | 4 ++++ src/org/xwt/XWT.java | 2 ++ 10 files changed, 67 insertions(+), 54 deletions(-) diff --git a/src/org/xwt/Box.java.pp b/src/org/xwt/Box.java.pp index 2df28b0..81439f7 100644 --- a/src/org/xwt/Box.java.pp +++ b/src/org/xwt/Box.java.pp @@ -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) { diff --git a/src/org/xwt/Glyph.java b/src/org/xwt/Glyph.java index 6088717..425cfd2 100644 --- a/src/org/xwt/Glyph.java +++ b/src/org/xwt/Glyph.java @@ -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; diff --git a/src/org/xwt/Main.java b/src/org/xwt/Main.java index 4f1c6ac..e771585 100644 --- a/src/org/xwt/Main.java +++ b/src/org/xwt/Main.java @@ -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 /] source-location [initial-template]"); @@ -60,9 +62,6 @@ public class Main { Platform.forceLoad(); if (Log.on) for(int i=0; i 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; } diff --git a/src/org/xwt/Picture.java b/src/org/xwt/Picture.java index 29e3184..da65368 100644 --- a/src/org/xwt/Picture.java +++ b/src/org/xwt/Picture.java @@ -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(); diff --git a/src/org/xwt/PixelBuffer.java b/src/org/xwt/PixelBuffer.java index 9bb41be..eb8425a 100644 --- a/src/org/xwt/PixelBuffer.java +++ b/src/org/xwt/PixelBuffer.java @@ -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 w; note that the coordinates here are post-transform */ diff --git a/src/org/xwt/Platform.java b/src/org/xwt/Platform.java index aa8be35..c06bb8a 100644 --- a/src/org/xwt/Platform.java +++ b/src/org/xwt/Platform.java @@ -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(); diff --git a/src/org/xwt/Res.java b/src/org/xwt/Res.java index 3f34f82..54bebcb 100644 --- a/src/org/xwt/Res.java +++ b/src/org/xwt/Res.java @@ -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) { diff --git a/src/org/xwt/Surface.java b/src/org/xwt/Surface.java index 3f29808..c30a34b 100644 --- a/src/org/xwt/Surface.java +++ b/src/org/xwt/Surface.java @@ -73,13 +73,21 @@ public abstract class Surface extends PixelBuffer { public abstract void setInvisible(boolean b); ///< If b, make window invisible; otherwise, make it non-invisible. protected abstract void _setMaximized(boolean b); ///< If b, maximize the surface; otherwise, un-maximize it. protected abstract void _setMinimized(boolean b); ///< If b, 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); diff --git a/src/org/xwt/ThreadMessage.java b/src/org/xwt/ThreadMessage.java index d028642..cfd6cb7 100644 --- a/src/org/xwt/ThreadMessage.java +++ b/src/org/xwt/ThreadMessage.java @@ -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); diff --git a/src/org/xwt/XWT.java b/src/org/xwt/XWT.java index 9738c06..2d4ef45 100644 --- a/src/org/xwt/XWT.java +++ b/src/org/xwt/XWT.java @@ -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(); -- 1.7.10.4