2003/10/29 00:53:07
authorxwt <xwt@xwt.org>
Fri, 30 Jan 2004 07:40:26 +0000 (07:40 +0000)
committerxwt <xwt@xwt.org>
Fri, 30 Jan 2004 07:40:26 +0000 (07:40 +0000)
darcs-hash:20040130074026-3ac31-c45e854d06efdddb4a7f354209e498066590cfc3.gz

src/org/xwt/Box.java.pp
src/org/xwt/Glyph.java
src/org/xwt/Main.java
src/org/xwt/Platform.java
src/org/xwt/Res.java
src/org/xwt/ThreadMessage.java

index 81439f7..7cae9dd 100644 (file)
@@ -507,19 +507,27 @@ public final class Box extends JS.Scope {
 
     void renderText(int x, int y, int clipx, int clipy, int clipw, int cliph, PixelBuffer buf) {
         for(int i=0; i<text.length(); i++) {
-            // FIXME: clipping
-            char c = text.charAt(i);
-            Glyph g = Glyph.getGlyph(font, fontsize, c);
-            if (g.p != null)
-                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(),
-                                         textcolor);
-            x += g.advance;
+            final char c = text.charAt(i);
+           Glyph g = Glyph.getCachedGlyph(font, fontsize, c);
+           if (g != null) {
+               int top = y + g.max_ascent - g.baseline + g.max_descent;
+               if (g.p != null)
+                   buf.drawPictureAlphaOnly(g.p, x, top,
+                                            clipx, clipy, clipx + clipw, clipy + cliph, textcolor);
+               x += g.advance;
+           } else {
+               final int fontsize_final = fontsize;
+               final Res font_final = font;
+                ThreadMessage.newthread(new JS.Callable() {
+                        public Object call(JS.Array args) {
+                           Glyph.renderGlyph(font_final, fontsize_final, c);   
+                           recompute_font();
+                           Box b = Box.this; MARK_FOR_REFLOW_b;
+                           dirty();
+                           return null;
+                       } });
+               return;
+           }
         }
     }
 
@@ -848,9 +856,23 @@ public final class Box extends JS.Scope {
             textheight = 0;
             if (text == null) return;
             for(int i=0; i<text.length(); i++) {
-                Glyph g = Glyph.getGlyph(font, fontsize, text.charAt(i));
-                textwidth += g.advance;
-                textheight = g.max_ascent;
+                Glyph g = Glyph.getCachedGlyph(font, fontsize, text.charAt(i));
+               if (g == null) {
+                   final int fontsize_final = fontsize;
+                   final Res font_final = font;
+                   final char c = text.charAt(i);
+                   ThreadMessage.newthread(new JS.Callable() {
+                           public Object call(JS.Array args) {
+                               Glyph.renderGlyph(font_final, fontsize_final, c);       
+                               recompute_font();
+                               Box b = Box.this; MARK_FOR_REFLOW_b;
+                               dirty();
+                               return null;
+                           } });
+               } else {
+                   textwidth += g.advance;
+                   textheight = g.max_ascent;
+               }
             }
         } catch (Exception e) {
             Log.log(this, e);
index 425cfd2..0cb1b29 100644 (file)
@@ -15,18 +15,21 @@ public class Glyph {
     // k1=font.res k2=(c << 16 | pointsize)
     private static Cache glyphCache = new Cache();
 
-    public static Glyph getGlyph(Res res, int pointsize, char c) {
-        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 >= 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;
-        throw new JS.Exn("error rendering glyph " + c + "; glyph is null");
+    public static Glyph getCachedGlyph(Res res, int pointsize, char c) {
+        return (Glyph)glyphCache.get(res, new Integer((((int)c) << 16) | pointsize));
+    }
+    public static void renderGlyph(Res res, int pointsize, char c) {
+       if (!ThreadMessage.suspendThread())
+           throw new RuntimeException("attempt to perform background-only operation in a foreground thread");
+       synchronized(res) {
+           // FEATURE: be smarter here
+           if ((Glyph)glyphCache.get(res, new Integer((((int)c) << 16) | pointsize)) != null) return;
+           Log.log(Freetype.class, "rendering glyphs for font " + res.getDescriptiveName());
+           if (c >= 32 && c < 127) Freetype.renderGlyphs(res, pointsize, 32, 126, glyphCache);
+           else Freetype.renderGlyphs(res, pointsize, (int)c, (int)c, glyphCache);
+           if ((Glyph)glyphCache.get(res, new Integer((((int)c) << 16) | pointsize)) == null)
+               throw new JS.Exn("error rendering glyph " + c + "; glyph is null");
+       }
+       ThreadMessage.resumeThread();
     }
 }
index e771585..f102939 100644 (file)
@@ -25,8 +25,7 @@ public class Main {
     public static String originHost = null;
     public static String origin = null;
     
-    public static final Res builtin = new Res.Zip(new Res() {
-            public InputStream getInputStream(String path) { return Platform.getBuiltinInputStream(); } });
+    public static final Res builtin = new Res.Builtin();
     public static Picture scarImage = null;
 
     public static void printUsage() {
index c06bb8a..8e77b87 100644 (file)
@@ -34,7 +34,7 @@ public class Platform {
     static boolean alreadyDetectedProxy = false;
 
     /** the result of proxy autodetection */
-    static HTTP.Proxy cachedProxyInfo = null;
+    static org.xwt.HTTP.Proxy cachedProxyInfo = null;
 
     /** the current build */
     public static String build = "unknown";
@@ -301,15 +301,15 @@ public class Platform {
     }
 
     /** detects proxy settings */
-    protected synchronized HTTP.Proxy _detectProxy() { return null; }
-    public static synchronized HTTP.Proxy detectProxy() {
+    protected synchronized org.xwt.HTTP.Proxy _detectProxy() { return null; }
+    public static synchronized org.xwt.HTTP.Proxy detectProxy() {
 
         if (cachedProxyInfo != null) return cachedProxyInfo;
         if (alreadyDetectedProxy) return null;
         alreadyDetectedProxy = true;
 
         if (Log.on) Log.log(Platform.class, "attempting environment-variable DNS proxy detection");
-        cachedProxyInfo = HTTP.Proxy.detectProxyViaManual();
+        cachedProxyInfo = org.xwt.HTTP.Proxy.detectProxyViaManual();
         if (cachedProxyInfo != null) return cachedProxyInfo;
 
         if (Log.on) Log.log(Platform.class, "attempting " + platform.getClass().getName() + " proxy detection");
index 54bebcb..6bf79a3 100644 (file)
@@ -142,6 +142,16 @@ public abstract class Res extends JS {
         }
     }
 
+    /** the Builtin resource */
+    public static class Builtin extends Res {
+       public Builtin() { };
+       public String getDescriptiveName() { return "[builtin]"; }
+       public InputStream getInputStream(String path) throws IOException {
+           if (!path.equals("")) throw new IOException("the builtin resource has no subresources");
+           return Platform.getBuiltinInputStream();
+       }
+    }
+
     /** what you get when you reference a subresource */
     public static class Ref extends Res {
         Res parent;
@@ -149,7 +159,9 @@ public abstract class Res extends JS {
         Ref(Res parent, Object key) { this.parent = parent; this.key = key; }
         public String getDescriptiveName() {
             String pdn = parent.getDescriptiveName();
-            return pdn.equals("") ? key.toString() : (pdn + "." + key.toString());
+           if (pdn.equals("")) return key.toString();
+           if (!pdn.endsWith("!")) pdn += ".";
+           return pdn + key.toString();
         }
         public Res addExtension(String extension) {
             return (key instanceof String && ((String)key).endsWith(extension)) ? this : new Ref(parent, key + extension);
index cfd6cb7..0eeefef 100644 (file)
@@ -17,8 +17,6 @@ import org.xwt.js.*;
  */
 public class ThreadMessage extends Thread implements Message {
 
-    public static boolean fakeBackground = false;
-    
     private volatile static int threadcount = 0;
 
     /** the JavaScript function that we are executing */
@@ -55,7 +53,6 @@ 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)) {
@@ -70,7 +67,6 @@ 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);