X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FBox.java.pp;h=c58eebc04b2d338634e0d78d782cfb01a7126ac8;hb=6a96430e10e27fc1de5754cb5add705f929dd109;hp=931171cedd6d186477d5dd1f15d593d6aaa75790;hpb=fed560ec17c824f4332919829f11899e48b52f4b;p=org.ibex.core.git diff --git a/src/org/xwt/Box.java.pp b/src/org/xwt/Box.java.pp index 931171c..c58eebc 100644 --- a/src/org/xwt/Box.java.pp +++ b/src/org/xwt/Box.java.pp @@ -84,15 +84,19 @@ public final class Box extends JS.Scope { // Flags /////////////////////////////////////////////////////////////////////////////// short flags = 0; - static int MOUSEINSIDE_FLAG = 0x00000001; - static int INVISIBLE_FLAG = 0x00000002; - static int ABSOLUTE_FLAG = 0x00000004; - static int HSHRINK_FLAG = 0x00000008; - static int VSHRINK_FLAG = 0x00000010; - static int TILE_FLAG = 0x00000020; - static int FONT_CHANGED_FLAG = 0x00000040; // set when font changes, cleared during repack - static int ISROOT_FLAG = 0x00000080; - static int NOCLIP_FLAG = 0x00000100; + static final int MOUSEINSIDE_FLAG = 0x00000001; + static final int INVISIBLE_FLAG = 0x00000002; + static final int NOTPACKED_FLAG = 0x00000004; + static final int HSHRINK_FLAG = 0x00000008; + static final int VSHRINK_FLAG = 0x00000010; + static final int FONT_CHANGED_FLAG = 0x00000040; // set when font changes, cleared during repack + static final int ISROOT_FLAG = 0x00000080; + static final int NOCLIP_FLAG = 0x00000100; + static final int ALIGN_TOP_FLAG = 0x00001000; + static final int ALIGN_BOTTOM_FLAG = 0x00002000; + static final int ALIGN_LEFT_FLAG = 0x00004000; + static final int ALIGN_RIGHT_FLAG = 0x00008000; + static final int ALIGN_FLAGS = 0x0000f000; // Geometry //////////////////////////////////////////////////////////////////////////// @@ -107,8 +111,6 @@ public final class Box extends JS.Scope { public LENGTH minheight = 0; public LENGTH maxwidth = MAX_LENGTH; public LENGTH maxheight = MAX_LENGTH; - private LENGTH hpad = 0; - private LENGTH vpad = 0; private String text = null; private Res font = null; private int fontsize = 10; @@ -128,14 +130,20 @@ public final class Box extends JS.Scope { public LENGTH height = 0; private int row = 0; // FEATURE use a short private int col = 0; // FEATURE use a short - private LENGTH contentwidth = 0; // == max(minwidth, textwidth+pad, sum(child.contentwidth) + pad) + private LENGTH contentwidth = 0; // == max(minwidth, textwidth, sum(child.contentwidth)) private LENGTH contentheight = 0; + private LENGTH offset_x = 0; + private LENGTH offset_y = 0; // Rendering Properties /////////////////////////////////////////////////////////// private VectorGraphics.VectorPath path = null; private VectorGraphics.Affine transform = null; + + private VectorGraphics.RasterPath rpath = null; + private VectorGraphics.Affine rtransform = null; + //private VectorGraphics.Paint fill = null; //private VectorGraphics.Paint stroke = null; int strokewidth = 1; @@ -194,7 +202,7 @@ public final class Box extends JS.Scope { if (isinside && cursor != null) getRoot().cursor = cursor; // if the mouse has moved into our padding region, it is considered 'outside' all our children - if (!(mousex >= hpad && mousey >= vpad && mousex < width - hpad && mousey < height + vpad)) forceleave = true; + if (!(mousex >= 0 && mousey >= 0 && mousex < width && mousey < height)) forceleave = true; for(Box b = getChild(numChildren() - 1); b != null; b = b.prevSibling()) { b.Move(oldmousex - b.x, oldmousey - b.y, mousex - b.x, mousey - b.y, forceleave); @@ -205,25 +213,23 @@ public final class Box extends JS.Scope { // Reflow //////////////////////////////////////////////////////////////////////////////////////// + /** only for use on the root box */ void reflow() { reflow(width, height); } void reflow(int new_width, int new_height) { repack(); if (Surface.abort) return; + //#repeat width/height new_width/new_height HSHRINK_FLAG/VSHRINK_FLAG contentwidth/contentheight minwidth/minheight maxwidth/maxheight + new_width = bound(max(contentwidth, minwidth), + new_width, + ((flags & HSHRINK_FLAG) != 0) ? max(contentwidth, minwidth) : maxwidth); + //#end resize(x, y, new_width, new_height); } /** 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 = max(textwidth + 2 * hpad, minwidth); - contentheight = max(textheight + 2 * vpad, minheight); - if (path != null) { - contentwidth = max(contentwidth, path.boundingBoxWidth()); - contentheight = max(contentheight, path.boundingBoxHeight()); - } - return; - } + contentwidth = contentheight = 0; // --- Phase 0 ---------------------------------------------------------------------- // recurse @@ -240,11 +246,11 @@ public final class Box extends JS.Scope { // --- Phase 1 ---------------------------------------------------------------------- // assign children to their row/column positions (assuming constrained columns) if ((rows == 0 && cols == 0) || (rows != 0 && cols != 0)) throw new Error("rows == " + rows + " cols == " + cols); - //#repeat x/y y/x width/height col/row row/col cols/rows rows/cols colspan/rowspan rowspan/colspan colWidth/rowHeight numRowsInCol/numColsInRow INNER/INNER2 maxwidth/maxheight minwidth/minheight contentwidth/contentheight colMaxWidth/rowMaxHeight OUTER/OUTER2 INNER/INNER2 - if (rows == 0) { + //#repeat x/y y/x width/height col/row row/col cols/rows rows/cols colspan/rowspan rowspan/colspan colWidth/rowHeight numRowsInCol/numColsInRow INNER/INNER2 maxwidth/maxheight minwidth/minheight colMaxWidth/rowMaxHeight OUTER/OUTER2 INNER/INNER2 + if (rows == 0 && numChildren() != 0) { int[] numRowsInCol = new int[cols]; // the number of cells occupied in each column Box child = getChild(0); - for(; child != null && (((child.flags & ABSOLUTE_FLAG) != 0) || ((child.flags & INVISIBLE_FLAG) != 0)); child = child.nextSibling()); + for(; child != null && (((child.flags & NOTPACKED_FLAG) != 0) || ((child.flags & INVISIBLE_FLAG) != 0)); child = child.nextSibling()); OUTER: for(int row=0; child != null; row++) { for(int col=0; child != null && col < cols;) { INNER: while(true) { // scan across the row, looking for an unoccupied gap at least as wide as the child @@ -259,7 +265,7 @@ public final class Box extends JS.Scope { child.row = row; col += min(cols, child.colspan); child = child.nextSibling(); - for(; child != null && (((child.flags & ABSOLUTE_FLAG) != 0) || ((child.flags & INVISIBLE_FLAG) != 0)); child = child.nextSibling()); + for(; child != null && (((child.flags & NOTPACKED_FLAG) != 0) || ((child.flags & INVISIBLE_FLAG) != 0)); child = child.nextSibling()); } } } @@ -267,26 +273,43 @@ public final class Box extends JS.Scope { // --- Phase 2 ---------------------------------------------------------------------- // compute the min/max sizes of the columns and rows and set our contentwidth - //#repeat x/y y/x width/height col/row cols/rows colspan/rowspan colWidth/rowHeight maxwidth/maxheight minwidth/minheight contentwidth/contentheight colMaxWidth/rowMaxHeight numCols/numRows hpad/vpad - contentwidth = 2 * hpad; - int numCols = cols; - if (numCols == 0) + //#repeat x/y y/x width/height col/row cols/rows colspan/rowspan colWidth/rowHeight maxwidth/maxheight minwidth/minheight contentwidth/contentheight colMaxWidth/rowMaxHeight numCols/numRows textwidth/textheight + if (numChildren() != 0) { + int numCols = cols; + if (numCols == 0) + for(Box child = getChild(0); child != null; child = child.nextSibling()) + numCols = max(numCols, child.col + child.colspan); + LENGTH[] colWidth = new LENGTH[numCols]; for(Box child = getChild(0); child != null; child = child.nextSibling()) - numCols = max(numCols, child.col + child.colspan); - LENGTH[] colWidth = new LENGTH[numCols]; - for(Box child = getChild(0); child != null; child = child.nextSibling()) - if (!(((child.flags & ABSOLUTE_FLAG) != 0) || ((child.flags & INVISIBLE_FLAG) != 0))) - colWidth[child.col] = max(colWidth[child.col], child.contentwidth / child.colspan); - for(int col=0; col 0) while(slack > 0) { @@ -377,17 +400,21 @@ public final class Box extends JS.Scope { for(Box child = getChild(0); child != null; child = child.nextSibling()) { if ((child.flags & INVISIBLE_FLAG) != 0) continue; int child_x = 0, child_y = 0, child_width = 0, child_height = 0; - if ((child.flags & ABSOLUTE_FLAG) != 0) { + if ((child.flags & NOTPACKED_FLAG) != 0) { child_x = child.x; child_y = child.y; - child_width = ((child.flags & HSHRINK_FLAG) != 0) ? child.contentwidth : min(child.maxwidth, width - child.x - hpad); - child_height = ((child.flags & VSHRINK_FLAG) != 0) ? child.contentheight : min(child.maxheight, height - child.y - vpad); + child_width = ((child.flags & HSHRINK_FLAG) != 0) ? child.contentwidth : min(child.maxwidth, width - child.x); + child_height = ((child.flags & VSHRINK_FLAG) != 0) ? child.contentheight : min(child.maxheight, height - child.y); } else { int diff; - //#repeat x/y y/x width/height col/row cols/rows colspan/rowspan colWidth/rowHeight maxwidth/maxheight minwidth/minheight contentwidth/contentheight colMaxWidth/rowMaxHeight HSHRINK_FLAG/VSHRINK_FLAG marginWidth/marginHeight hpad/vpad child_x/child_y child_width/child_height + //#repeat x/y y/x width/height col/row cols/rows colspan/rowspan colWidth/rowHeight maxwidth/maxheight minwidth/minheight contentwidth/contentheight colMaxWidth/rowMaxHeight HSHRINK_FLAG/VSHRINK_FLAG marginWidth/marginHeight child_x/child_y child_width/child_height ALIGN_LEFT_FLAG/ALIGN_TOP_FLAG ALIGN_RIGHT_FLAG/ALIGN_BOTTOM_FLAG child_width = 0; for(int i=child.col; i 0 && dy2 - dy1 > 0 && sx2 - sx1 > 0 && sy2 - sy1 > 0) - buf.drawPicture(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2); + if (rtransform == null) rpath = null; + else if (!rtransform.equalsIgnoringTranslation(a)) rpath = null; + else { + rpath.translate((int)(a.e - rtransform.e), (int)(a.f - rtransform.f)); + rtransform = a.copy(); + } + if (rpath == null) { + rtransform = a; + rpath = path.realize(a == null ? VectorGraphics.Affine.identity() : a); } + if ((strokecolor & 0xff000000) != 0) rpath.stroke(buf, 1, strokecolor); + if ((fillcolor & 0xff000000) != 0) rpath.fill(buf, new VectorGraphics.SingleColorPaint(fillcolor)); } - } - void renderText(int x, int y, int clipx, int clipy, int clipw, int cliph, PixelBuffer buf) { - for(int i=0; i= 0 && i < numChildren()) { Box b = getChild(i); b.remove(); - put("0", b); + if (t != null) t.perform(b); } } else { Box newnode = (Box)value; @@ -599,9 +600,7 @@ public final class Box extends JS.Scope { MARK_FOR_REFLOW_this; newnode.dirty(); - - // note that JavaScript box[0] will invoke put(int i), not put(String s) - put("0", newnode); + if (t != null) t.perform(b); } } @@ -661,9 +660,6 @@ public final class Box extends JS.Scope { } } - // don't want to really cascade down to the box on this one - if (name.equals("0")) return; - SpecialBoxProperty gph = (SpecialBoxProperty)SpecialBoxProperty.specialBoxProperties.get(name); if (gph != null) { gph.put(name, this, value); return; } @@ -731,7 +727,10 @@ public final class Box extends JS.Scope { if (oldparent != null) { Box b = oldparent; MARK_FOR_REFLOW_b; } // note that JavaScript box[0] will invoke put(int i), not put(String s) - if (oldparent != null) oldparent.put("0", this); + if (oldparent != null) { + Trap t = (Trap)oldparent.get("childremoved", Trap.class); + if (t != null) t.perform(this); + } } /** returns our next sibling (parent[ourindex + 1]) */ @@ -807,12 +806,31 @@ public final class Box extends JS.Scope { return parent.getRoot(); } + public void recompute_font() { + if (text == null) { textwidth = textheight = 0; return; } + if (font == null) { /* FIXME */ } + long widthheight = Glyph.rasterizeGlyphs(font, fontsize, text, null, textcolor, 0, 0, 0, 0, 0, 0, + new Callback() { public Object call(Object arg) { + Box b = Box.this; + recompute_font(); + MARK_FOR_REFLOW_b; + b.dirty(); + return null; + } }); + if (widthheight == -1) return; + textwidth = (int)((widthheight & 0xffff0000) >> 16); + textheight = (int)(widthheight & 0x0000ffff); + MARK_FOR_REFLOW_this; + } + - // Trivial Helper Methods (should be inlined) ///////////////////////////////////////// + // Trivial Helper Method s(should be inlined) ///////////////////////////////////////// static final int min(int a, int b) { if (ab) return a; else return b; } + static final float max(float a, float b) { if (a>b) return a; else return b; } static final int min(int a, int b, int c) { if (a<=b && a<=c) return a; else if (b<=c && b<=a) return b; else return c; } static final int max(int a, int b, int c) { if (a>=b && a>=c) return a; else if (b>=c && b>=a) return b; else return c; } static final int bound(int a, int b, int c) { if (c < b) return c; if (a > b) return a; return b; } @@ -877,6 +895,18 @@ public final class Box extends JS.Scope { static { specialBoxProperties.put("fill", new ColorBoxProperty() { + public void put(final Box b, final Object value) { + if (value == null || !(value instanceof Res)) super.put(b, value); + else Picture.fromRes((Res)value, new Callback() { public Object call(Object pic) { + if (pic == b.image) return null; + b.image = (Picture)pic; + b.minwidth = b.image.getWidth(); + b.minheight = b.image.getHeight(); + MARK_FOR_REFLOW_b; + b.dirty(); + return null; + } }); + } public int getColor(Box b) { return b.fillcolor; } public void putColor(Box b, int argb) { b.fillcolor = argb; } }); @@ -895,23 +925,8 @@ public final class Box extends JS.Scope { String t = value == null ? "null" : value.toString(); if (t.equals(b.text)) return; b.text = t; - if (t == null) { - if (b.textwidth != 0 || b.textheight != 0) MARK_FOR_REFLOW_b; - b.textwidth = b.textheight = 0; - } else { - try { - MARK_FOR_REFLOW_b; - b.textwidth = 0; - for(int i=0; i