2003/09/17 07:12:23
[org.ibex.core.git] / src / org / xwt / Box.java.pp
index 50ef309..2c60161 100644 (file)
@@ -7,8 +7,8 @@ package org.xwt;
 // upper-left hand corner of <tt>this</tt>
 
 // FIXME: align
-// FIXME use bitfields
-// FIXME fixedaspect
+// FIXME: use bitfields
+// FIXME: fixedaspect
 // FIXME: reflow before allowing js to read from width/height 
 // FIXME: due to font inheritance, we must dirty and mark all null-font descendents of a node if its font changes
 // FEATURE: fastpath for rows=1/cols=1
@@ -20,6 +20,7 @@ import java.net.*;
 import java.util.*;
 import org.xwt.js.*;
 import org.xwt.util.*;
+import org.xwt.imp.*;
 
 /**
  *  <p>
@@ -117,9 +118,9 @@ public final class Box extends JS.Scope {
     LENGTH y = 0;
     public LENGTH width = 0;
     public LENGTH height = 0;
-    private int row = 0;  // FIXME short
-    private int col = 0;  // FIXME short
-    private LENGTH contentwidth = 0;             // == max(minwidth, textwidth, sum(child.contentwidth) + pad)
+    private int row = 0;  // FIXME use a short
+    private int col = 0;  // FIXME use a short
+    private LENGTH contentwidth = 0;             // == max(minwidth, textwidth+pad, sum(child.contentwidth) + pad)
     private LENGTH contentheight = 0;
 
 
@@ -136,11 +137,12 @@ public final class Box extends JS.Scope {
     private String cursor = null;                // the cursor for this box
 
     //FIXME make private
-    public boolean invisible = false;           // true iff the Box is invisible
+    public boolean invisible = false;            // true iff the Box is invisible
     private boolean absolute = false;            // If true, the box will be positioned absolutely
     private boolean vshrink = false;             // If true, the box will shrink to the smallest vertical size possible
     private boolean hshrink = false;             // If true, the box will shrink to the smallest horizontal size possible
-    private boolean tile = false; // FIXME: drop this?
+    private boolean tile = false;                // FIXME: drop this?
+
 
     // Instance Methods /////////////////////////////////////////////////////////////////////
 
@@ -204,7 +206,11 @@ public final class Box extends JS.Scope {
     /** Checks if the Box's size has changed, dirties it if necessary, and makes sure childrens' sizes are up to date */
     void repack() {
         if (!needs_reflow) return;
-        if (numChildren() == 0) { contentwidth = minwidth; contentheight = minheight; return; }
+        if (numChildren() == 0) {
+           contentwidth = max(textwidth + 2 * hpad, minwidth);
+           contentheight = max(textheight + 2 * vpad, minheight);
+           return;
+       }
 
         // --- Phase 0 ----------------------------------------------------------------------
         // recurse
@@ -393,7 +399,7 @@ public final class Box extends JS.Scope {
             if (tile) renderTiledImage(globalx, globaly, clipx, clipy, clipw, cliph, buf);
             else renderStretchedImage(globalx, globaly, clipx, clipy, clipw, cliph, buf);
 
-        //if (text != null && !text.equals("")) renderText(x, y, w, h, buf);
+       if (text != null && !text.equals("")) renderText(x, y, clipx, clipy, clipw, cliph, buf);
 
         // now subtract the pad region from the clip region before proceeding
         clipw = min(max(clipx, globalx + hpad) + clipw, globalx + width - hpad) - clipx;
@@ -401,7 +407,8 @@ public final class Box extends JS.Scope {
         clipx = max(clipx, globalx + hpad);
         clipy = max(clipy, globaly + vpad);
 
-        for(Box b = getChild(0); b != null; b = b.nextSibling()) b.render(globalx, globaly, clipx, clipy, clipw, cliph, buf);   
+        for(Box b = getChild(0); b != null; b = b.nextSibling())
+            b.render(globalx, globaly, clipx, clipy, clipw, cliph, buf);   
     }
 
     void renderStretchedImage(int globalx, int globaly, int x, int y, int w, int h, DoubleBuffer buf) {
@@ -445,29 +452,21 @@ public final class Box extends JS.Scope {
         }
     }
 
-    void renderText(int x, int y, int w, int h, DoubleBuffer buf) {
-        /*
-        if ((textcolor & 0xFF000000) == 0x00000000) return;
-        buf.setClip(x, y, w + x, h + y);
+    void renderText(int x, int y, int clipx, int clipy, int clipw, int cliph, DoubleBuffer buf) {
+        //buf.setClip(clipx, clipy, clipw, cliph);
+
+       try {
+           ImageDecoder id = org.xwt.imp.Font.render(new FileInputStream("COMIC.TTF"), 24, text, false);
+           Picture p = Platform.createPicture(id);
+            // FIXME: color
+            // FIXME: underline (dotted?)
+           buf.drawPicture(p, x + hpad, y + vpad);
+           buf.setClip(0, 0, buf.getWidth(), buf.getHeight());
+       } catch (Exception e) {
+           Log.log(this, e);
+       }
 
-        buf.drawString(font(), text, x + hpad, y + vpad + Platform.getMaxAscent(font()) - 1, textcolor);
         buf.setClip(0, 0, buf.getWidth(), buf.getHeight());
-        int i=0; while(i<font().length() && !Character.isDigit(font().charAt(i))) i++;
-
-        if (font().lastIndexOf('d') > i) {
-            for(int j = x + hpad; j < x + hpad + textdim(0); j += 2)
-                buf.fillRect(j, y + vpad + (xwf == null ? Platform.getMaxAscent(font()) : xwf.getMaxAscent()) + 2,
-                             j + 1, y + vpad + (xwf == null ? Platform.getMaxAscent(font()) : xwf.getMaxAscent()) + 2 + 1,
-                             textcolor);
-
-        } else if (font().lastIndexOf('u') > i) {
-            buf.fillRect(x + hpad,
-                        y + vpad + (xwf == null ? Platform.getMaxAscent(font()) : xwf.getMaxAscent()) + 2,
-                        x + hpad + textdim(0),
-                        y + vpad + (xwf == null ? Platform.getMaxAscent(font()) : xwf.getMaxAscent()) + 2 + 1,
-                        textcolor);
-        }
-        */
     }
 
 
@@ -948,7 +947,6 @@ public final class Box extends JS.Scope {
                             }
                         else if (SVG.colors.get(s) != null)
                             newcolor = 0xFF000000 | ((Integer)SVG.colors.get(s)).intValue();
-                        // FIXME put named colors back in
                         if (newcolor == b.fillcolor) return;
                         b.fillcolor = newcolor;
                         b.dirty();
@@ -960,6 +958,7 @@ public final class Box extends JS.Scope {
                     public Object get(Box b) { return b.get("fillcolor"); }
                     public void put(Box b, Object value) { b.put("fillcolor", value); }
                 });
+
             specialBoxProperties.put("textcolor", new SpecialBoxProperty() {
                     public Object get(Box b) { return b.get("strokecolor"); }
                     public void put(Box b, Object value) { b.put("strokecolor", value); }
@@ -970,13 +969,29 @@ public final class Box extends JS.Scope {
                     public void put(Box b, Object value) {
                         String t = value == null ? "null" : value.toString();
                         if (t.equals(b.text)) return;
-                        // FIXME text is broken
+                       b.text = t;
+                       if (t == null) {
+                            if (b.textwidth != 0 || b.textheight != 0) MARK_FOR_REFLOW_b;
+                           b.textwidth = b.textheight = 0;
+                       } else {
+                           try {
+                               ImageDecoder id = org.xwt.imp.Font.render(new FileInputStream("COMIC.TTF"), 24, b.text, true);
+                                if (id.getWidth() != b.textwidth || id.getHeight() != b.textheight) MARK_FOR_REFLOW_b;
+                               b.textwidth = id.getWidth();
+                               b.textheight = id.getHeight();
+                           } catch (Exception e) {
+                               Log.log(this, e);
+                           }
+                       }
+                       b.dirty();
                     } });
+
             specialBoxProperties.put("font", new SpecialBoxProperty() {
                     public Object get(Box b) { return b.font; }
                     public void put(Box b, Object value) {
                         b.font = value == null ? null : value.toString();
-                        //b.fontChanged();
+                        // FIXME: need a resource stream to hand off to MIPS
+                        // FIXME: MARK_FOR_REFLOW here
                         b.dirty();
                     } });
         
@@ -991,6 +1006,7 @@ public final class Box extends JS.Scope {
 
             specialBoxProperties.put("orient", new SpecialBoxProperty() {
                     public Object get(Box b) {
+                        Log.log(this, "warning: the orient property is deprecated");
                         if (b.redirect == null) return "horizontal";
                         else if (b.redirect != b) return get(b.redirect);
                         else if (b.cols == 1) return "vertical";
@@ -998,6 +1014,7 @@ public final class Box extends JS.Scope {
                         else return "grid";
                     }
                     public void put(Box b, Object value) {
+                        Log.log(this, "warning: the orient property is deprecated");
                         if (value == null) return;
                         if (b.redirect == null) return;
                         if (b.redirect != b) { put(b.redirect, value); return; }
@@ -1056,8 +1073,7 @@ public final class Box extends JS.Scope {
                         b.dirty();
                         b.x = x;
                         if (b.parent == null && b.surface != null) {
-                            // FIXME this gets hosed by the #repeat
-                            //b.surface.setLocation(b.x, b.y);
+                            b.surface.setLocation();
                             b.surface.centerSurfaceOnRender = false;
                         }
                         MARK_FOR_REFLOW_b;
@@ -1075,6 +1091,7 @@ public final class Box extends JS.Scope {
                             b.surface.setSize();
                             MARK_FOR_REFLOW_b;
                         } else {
+                            if (b.minwidth == b.width && b.maxwidth == b.width) return;
                             b.minwidth = b.maxwidth = b.width;
                             MARK_FOR_REFLOW_b;
                         }
@@ -1085,6 +1102,7 @@ public final class Box extends JS.Scope {
             specialBoxProperties.put("cols", new SpecialBoxProperty() {
                     public Object get(Box b) { return new Double(b.cols); }
                     public void put(Box b, Object value) {
+                        if (b.cols == stoi(value)) return;
                         b.cols = stoi(value);
                         if (b.cols == 0 && b.rows == 0) b.rows = 1;
                         if (b.cols != 0 && b.rows != 0) b.rows = 0;
@@ -1095,16 +1113,19 @@ public final class Box extends JS.Scope {
             //#repeat colspan/rowspan
             specialBoxProperties.put("colspan", new SpecialBoxProperty() {
                     public Object get(Box b) { return new Double(b.colspan); }
-                    public void put(Box b, Object value) { b.colspan = stoi(value); MARK_FOR_REFLOW_b; }
+                    public void put(Box b, Object value) {
+                        if (b.colspan == stoi(value)) return;
+                        b.colspan = stoi(value);
+                        MARK_FOR_REFLOW_b;
+                    }
                 });
             //#end
         
             specialBoxProperties.put("tile", new SpecialBoxProperty() {
                     public Object get(Box b) { return b.tile ? Boolean.TRUE : Boolean.FALSE; }
                     public void put(Box b, Object value) {
-                        boolean newtile = stob(value);
-                        if (newtile == b.tile) return;
-                        b.tile = newtile;
+                        if (b.tile == stob(value)) return;
+                        b.tile = stob(value);
                         b.dirty();
                     } });
         
@@ -1114,11 +1135,10 @@ public final class Box extends JS.Scope {
                         return Boolean.FALSE;
                     }
                     public void put(Box b, Object value) {
-                        boolean newinvisible = stob(value);
-                        if (newinvisible == b.invisible) return;
-                        b.invisible = newinvisible;
+                        if (stob(value) == b.invisible) return;
+                        b.invisible = stob(value);
                         if (b.parent == null) {
-                            if (b.surface != null) b.surface.setInvisible(newinvisible);
+                            if (b.surface != null) b.surface.setInvisible(b.invisible);
                         } else {
                             b.dirty();
                             MARK_FOR_REFLOW_b_parent;
@@ -1129,9 +1149,8 @@ public final class Box extends JS.Scope {
             specialBoxProperties.put("absolute", new SpecialBoxProperty() {
                     public Object get(Box b) { return b.absolute ? Boolean.TRUE : Boolean.FALSE; }
                     public void put(Box b, Object value) {
-                        boolean newabsolute = stob(value);
-                        if (newabsolute == b.absolute) return;
-                        b.absolute = newabsolute;
+                        if (stob(value) == b.absolute) return;
+                        b.absolute = stob(value);
                         if (b.absolute) { b.x = 0; b.y = 0; }
                         if (b.parent != null) MARK_FOR_REFLOW_b_parent;
                     } });
@@ -1371,28 +1390,26 @@ public final class Box extends JS.Scope {
                 });
             */
         }
+    }
 
-        
-        /** helper that converts a String to a boolean according to JavaScript coercion rules */
-        public static boolean stob(Object o) {
-            if (o == null) return false;
-            return Boolean.TRUE.equals(o) || "true".equals(o);
-        }
+    /** helper that converts a String to a boolean according to JavaScript coercion rules */
+    public static boolean stob(Object o) {
+        if (o == null) return false;
+        return Boolean.TRUE.equals(o) || "true".equals(o);
+    }
 
+    /** helper that converts a String to an int according to JavaScript coercion rules */
+    public static int stoi(Object o) {
+        if (o == null) return 0;
+        if (o instanceof Integer) return ((Integer)o).intValue();
+        
+        String s;
+        if (!(o instanceof String)) s = o.toString();
+        else s = (String)o;
         
+        try { return Integer.parseInt(s.indexOf('.') == -1 ? s : s.substring(0, s.indexOf('.'))); }
+        catch (NumberFormatException e) { return 0; }
     }
-        /** helper that converts a String to an int according to JavaScript coercion rules */
-        public static int stoi(Object o) {
-            if (o == null) return 0;
-            if (o instanceof Integer) return ((Integer)o).intValue();
-
-            String s;
-            if (!(o instanceof String)) s = o.toString();
-            else s = (String)o;
-
-            try { return Integer.parseInt(s.indexOf('.') == -1 ? s : s.substring(0, s.indexOf('.'))); }
-            catch (NumberFormatException e) { return 0; }
-        }
 }