UNDO: fixed bug 555
[org.ibex.core.git] / src / org / ibex / core / Box.java
index f333abb..2fb9fe6 100644 (file)
@@ -65,8 +65,8 @@ public final class Box extends JSScope implements Task {
     static final int MOUSEINSIDE  = 0x00000001;
     static final int VISIBLE      = 0x00000002;
     static final int PACKED       = 0x00000004;
-    static final int HSHRINK      = 0x00000008;
-    static final int VSHRINK      = 0x00000010;
+    public static final int HSHRINK      = 0x00000008;
+    public static final int VSHRINK      = 0x00000010;
     static final int BLACK        = 0x00000020;  // for red-black code
 
     static final int FIXED        = 0x00000040;
@@ -123,18 +123,16 @@ public final class Box extends JSScope implements Task {
     public int ay = 0;   // FEATURE: roll these into x/y; requires lots of changes; perhaps y()?
     public int width = 0;
     public int height = 0;
-    private int contentwidth = 0;      // == max(minwidth, textwidth, sum(child.contentwidth))
-    private int contentheight = 0;
+    public int contentwidth = 0;      // == max(minwidth, textwidth, sum(child.contentwidth))
+    public int contentheight = 0;
 
+    private Path path = null;
     /*
-    private VectorGraphics.VectorPath path = null;
     private Affine transform = null;
     private VectorGraphics.RasterPath rpath = null;
     private Affine rtransform = null;
     */
 
-    //#define DIRTY dirty()
-
     // Instance Methods /////////////////////////////////////////////////////////////////////
 
     public final int fontSize() { return font == null ? DEFAULT_FONT.pointsize : font.pointsize; }
@@ -143,9 +141,9 @@ public final class Box extends JSScope implements Task {
     public void perform() throws JSExn {
         if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return; }
         if (texture.isLoaded) {
-            setWidth(max(texture.width, maxwidth), maxwidth); 
-            setHeight(max(texture.height, maxheight), maxheight); 
-            DIRTY; }
+            setWidth(max(texture.width, minwidth), maxwidth); 
+            setHeight(max(texture.height, minheight), maxheight); 
+            dirty(); }
         else { JS res = texture.stream; texture = null; throw new JSExn("image not found: "+res.unclone()); }
     }
 
@@ -172,8 +170,14 @@ public final class Box extends JSScope implements Task {
     // Reflow ////////////////////////////////////////////////////////////////////////////////////////
 
     /** should only be invoked on the root box */
-    public void reflow() { pack(); resize(x, y, maxwidth, maxheight); place(); }
-
+    public void reflow() {
+        pack();
+        resize(x, y,
+               test(HSHRINK) ? contentwidth : maxwidth,
+               test(VSHRINK) ? contentheight : maxheight);
+        place();
+    }
+    
     private static Box[] frontier = new Box[65535];
     /** pack the boxes into rows and columns, compute contentwidth */
     public void pack() {
@@ -242,7 +246,7 @@ public final class Box extends JSScope implements Task {
         } else {
             who.dirty(thisx, thisy, this.width, this.height);
             this.width = width; this.height = height; this.x = x; this.y = y;
-            DIRTY;
+            dirty();
         }
         if (sizechange) putAndTriggerTrapsAndCatchExceptions("SizeChange", T);
     }
@@ -420,6 +424,8 @@ public final class Box extends JSScope implements Task {
             font.rasterizeGlyphs(text, buf, strokecolor, text_x, text_y, cx1, cy1, cx2, cy2);
         }
 
+        if (path != null) path.realize(Affine.translate(globalx, globaly)).stroke(buf, 1, strokecolor);
+
         for(Box b = getChild(0); b != null; b = b.nextSibling())
             b.render(globalx, globaly, cx1, cy1, cx2, cy2, buf, null);
     }
@@ -538,13 +544,14 @@ public final class Box extends JSScope implements Task {
         if (name instanceof Number) { put(toInt(name), value); return; }
         //#switch(name)
         case "thisbox":     if (value == null) removeSelf();
-        case "text":        if (value == null) value = ""; CHECKSET_STRING(text); RECONSTRAIN(); DIRTY;
-        case "strokecolor": value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); DIRTY;
-        case "textcolor":   value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); DIRTY;
-        case "strokewidth": CHECKSET_SHORT(strokewidth); DIRTY;
+        case "text":        if (value == null) value = ""; CHECKSET_STRING(text); RECONSTRAIN(); dirty();
+        case "strokecolor": value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); dirty();
+        case "textcolor":   value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); dirty();
+        case "strokewidth": CHECKSET_SHORT(strokewidth); dirty();
         case "shrink":      CHECKSET_FLAG(HSHRINK | VSHRINK); RECONSTRAIN();
         case "hshrink":     CHECKSET_FLAG(HSHRINK); RECONSTRAIN();
         case "vshrink":     CHECKSET_FLAG(VSHRINK); RECONSTRAIN();
+        case "path":        path = Path.parse(toString(value)); dirty();
         case "width":       setWidth(toInt(value), toInt(value));
         case "height":      setHeight(toInt(value), toInt(value));
         case "maxwidth":    setWidth(minwidth, toInt(value));
@@ -553,12 +560,12 @@ public final class Box extends JSScope implements Task {
         case "minheight":   setHeight(toInt(value), maxheight);
         case "colspan":     if (toInt(value) > 0) { CHECKSET_SHORT(colspan); if (parent != null) parent.REPACK(); }
         case "rowspan":     if (toInt(value) > 0) { CHECKSET_SHORT(rowspan); if (parent != null) parent.REPACK(); }
-        case "visible":     CHECKSET_FLAG(VISIBLE); RECONSTRAIN(); DIRTY;
+        case "visible":     CHECKSET_FLAG(VISIBLE); RECONSTRAIN(); dirty();
         case "packed":      CHECKSET_FLAG(PACKED); if (parent != null) { parent.REPACK(); } else { REPACK(); }
         case "align":       clear(ALIGNS); setAlign(value == null ? "center" : value); REPLACE();
         case "cursor":      setCursor(value);
         case "fill":        setFill(value);
-        case "clip":        CHECKSET_FLAG(CLIP); if (parent == null) DIRTY; else parent.DIRTY;
+        case "clip":        CHECKSET_FLAG(CLIP); if (parent == null) dirty(); else parent.dirty();
         case "rows": CHECKSET_SHORT(rows); if (rows==0){set(FIXED, COLS);if(cols==0)cols=1;} else set(FIXED, ROWS); REPACK();
         case "cols": CHECKSET_SHORT(cols); if (cols==0){set(FIXED, ROWS);if(rows==0)rows=1;} else set(FIXED, COLS); REPACK();
 
@@ -576,13 +583,13 @@ public final class Box extends JSScope implements Task {
             for(Box cur = (Box)value; cur != null || cur == redirect; cur = cur.parent)
                 if (cur == redirect) { redirect = (Box)value; return; }
             JS.error("redirect can only be set to a descendant of its current value");
-        case "fontsize": font = Font.getFont(font == null ? null : font.stream, toInt(value)); RECONSTRAIN(); DIRTY;
+        case "fontsize": font = Font.getFont(font == null ? null : font.stream, toInt(value)); RECONSTRAIN(); dirty();
         case "font":
             if(!(value instanceof Stream)) throw new JSExn("You can only put streams to the font property");
             if (font == value) return;  // FIXME: unclone()
             font = value == null ? null : Font.getFont((Stream)value, font == null ? 10 : font.pointsize);
             RECONSTRAIN();
-            DIRTY;
+            dirty();
         case "x": if (parent==null && Surface.fromBox(this)!=null) {
             CHECKSET_INT(x);
         } else {
@@ -708,7 +715,7 @@ public final class Box extends JSScope implements Task {
         } else {
             throw new JSExn("fill must be null, a String, or a stream, not a " + value.getClass());
         }
-        DIRTY;
+        dirty();
     }
 
     /**
@@ -818,7 +825,7 @@ public final class Box extends JSScope implements Task {
     void set(int mask) { flags |= mask; }
     void set(int mask, boolean setclear) { if (setclear) set(mask); else clear(mask); }
     void clear(int mask) { flags &= ~mask; }
-    boolean test(int mask) { return ((flags & mask) == mask); }
+    public boolean test(int mask) { return ((flags & mask) == mask); }
     
 
     // Tree Handling //////////////////////////////////////////////////////////////////////
@@ -844,11 +851,11 @@ public final class Box extends JSScope implements Task {
     public void removeChild(int i) {
         Box b = getChild(i);
         b.RECONSTRAIN();
-        b.DIRTY;
+        b.dirty();
         b.clear(MOUSEINSIDE);
         deleteNode(i);
         b.parent = null;
-        RECONSTRAIN();
+        REPACK();
         putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
     }
     
@@ -901,10 +908,10 @@ public final class Box extends JSScope implements Task {
             b.parent = this;
             
             // need both of these in case child was already uncalc'ed
-            b.RECONSTRAIN();
-            RECONSTRAIN();
+            b.REPACK();
+            REPACK();
             
-            b.DIRTY; 
+            b.dirty(); 
             putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
         }
     }