X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fcore%2FBox.java;h=ffec434e18da5b796e3b68d2ac3cd171ff7d12ee;hb=531e31402f74fa636b2d9a2a367305bfd0777cdc;hp=76871cf50a8f898f31a6ba30dde33fccba893b67;hpb=026feed5d3ffb670533197a4ec733d1d03578c63;p=org.ibex.core.git diff --git a/src/org/ibex/core/Box.java b/src/org/ibex/core/Box.java index 76871cf..ffec434 100644 --- a/src/org/ibex/core/Box.java +++ b/src/org/ibex/core/Box.java @@ -9,9 +9,15 @@ package org.ibex.core; // FIXME: mouse move/release still needs to propagate to boxen in which the mouse was pressed and is still held down // FEATURE: reintroduce surface.abort +// Broken: +// - textures +// - align/origin +// - clipping (all forms) + import java.util.*; import org.ibex.js.*; import org.ibex.util.*; +import org.ibex.plat.*; import org.ibex.graphics.*; /** @@ -33,7 +39,11 @@ import org.ibex.graphics.*; * trigger a Surface.abort; if rendering were done in the same pass, * rendering work done prior to the Surface.abort would be wasted. */ -public final class Box extends JS.Obj implements Callable { +public final class Box extends JS.Obj implements Callable, Mesh.Chain { + + public Mesh.Chain getMeshChainParent() { return parent; } + public Mesh getMesh() { return mesh; } + public Affine getAffine() { return transform; } // Macros ////////////////////////////////////////////////////////////////////// @@ -59,10 +69,12 @@ public final class Box extends JS.Obj implements Callable { private int strokecolor = 0xFF000000; public float flex = 1; private Path path = null; + private Path clippath = null; private Affine transform = Affine.identity(); // FEATURE: polygon caching - private Polygon polygon = null; + private Mesh polygon = null; + private Mesh mesh = null; // specified directly by user public int minwidth = 0; @@ -121,8 +133,8 @@ public final class Box extends JS.Obj implements Callable { void place() { if (!packed()) { for(Box child = getChild(0); child != null; child = child.nextSibling()) { - child.width = max(child.minwidth, child.test(HSHRINK) ? child.contentwidth : child.maxwidth); - child.height = max(child.minheight, child.test(VSHRINK) ? child.contentheight : child.maxheight); + child.width = max(child.minwidth, min(child.test(HSHRINK) ? child.contentwidth : width, child.maxwidth)); + child.height = max(child.minheight, min(child.test(VSHRINK) ? child.contentheight : height, child.maxheight)); child.place(); } return; @@ -165,7 +177,8 @@ public final class Box extends JS.Obj implements Callable { transform.f = 0; a = a.copy().premultiply(transform); - boolean relevant = packed() || ((fillcolor&0xff000000)!=0x0) || path!=null; + //boolean relevant = packed() || ((fillcolor&0xff000000)!=0x0) || path!=null; + boolean relevant = true; int save_xmin = xmin, save_ymin = ymin, save_xmax = xmax, save_ymax = ymax; if (!relevant) { for(Box child = getChild(0); child != null; child = child.nextSibling()) { @@ -191,10 +204,8 @@ public final class Box extends JS.Obj implements Callable { xmax = save_xmax; ymax = save_ymax; - contentwidth = bound(minwidth, contentwidth, maxwidth); - contentheight = bound(minheight, contentheight, maxheight); - - int cw = bound(minwidth, contentwidth, maxwidth), ch = bound(minheight, contentheight, maxheight); + int cw = contentwidth = bound(minwidth, contentwidth, maxwidth); + int ch = contentheight = bound(minheight, contentheight, maxheight); //#repeat contentwidth/contentheight contentheight/contentwidth minwidth/minheight row/col col/row \ // textwidth/textheight maxwidth/maxheight bounds/boundsy x1/y1 x2/y2 z1/q1 z2/q2 z3/q3 z4/q4 \ // horizontalBounds/verticalBounds e/f multiply_px/multiply_py xmin/ymin xmax/ymax @@ -214,35 +225,34 @@ public final class Box extends JS.Obj implements Callable { private static final boolean OPTIMIZE = false; /** Renders self and children within the specified region. All rendering operations are clipped to xIn,yIn,wIn,hIn */ - public void render(int cx1, int cy1, int cx2, int cy2, PixelBuffer buf, Affine a) { + public void render(PixelBuffer buf, Affine a, Mesh clipFrom) { render(buf, a, clipFrom, Affine.identity()); } + public void render(PixelBuffer buf, Affine a, Mesh clipFrom, Affine clipa) { if (!test(VISIBLE)) return; - a = a.copy().premultiply(transform); - - // FIXME: clipping - if (path == null) { - if (((fillcolor & 0xFF000000) != 0x00000000 || parent == null)) { - if (OPTIMIZE && a.doesNotRotate()) { - int x = (int)a.multiply_px(0, 0); - int y = (int)a.multiply_py(0, 0); - int x2 = (int)a.multiply_px(contentwidth, contentheight); - int y2 = (int)a.multiply_py(contentwidth, contentheight); - buf.fillTrapezoid(x, x, y, x2, x2, y2, (fillcolor & 0xFF000000) == 0 ? 0xffffffff : fillcolor); - } else { - new Polygon().addrect(0, 0, contentwidth, contentheight, a).fill(buf, new Paint.SingleColorPaint(fillcolor)); - } + a = a.copy().multiply(transform); + clipa = clipa.copy().multiply(transform); + + if (mesh == null) + if (path != null) mesh = new Mesh(path, true); + else { + if (((fillcolor & 0xFF000000) != 0x00000000 || parent == null) && (text==null||"".equals(text))) + mesh = new Mesh().addRect(0, 0, contentwidth, contentheight); + // long ret = font.rasterizeGlyphs(text, buf, a, null, 0x777777, 0); + // minwidth = maxwidth = font.textwidth(text); + // minheight = maxheight = font.textwidth(text); + // if (ret == 0) Platform.Scheduler.add(this); + // FIXME: texture } - // FIXME: text - // FIXME: texture - } else { - Polygon p = new Polygon(path, a); - p.fill(buf, new Paint.SingleColorPaint(fillcolor)); - p.stroke(buf, strokecolor); + if (mesh==null) { + for(Box b = getChild(0); b != null; b = b.nextSibling()) b.render(buf, a, clipFrom, clipa); + return; } - for(Box b = getChild(0); b != null; b = b.nextSibling()) b.render(cx1, cy1, cx2, cy2, buf, a); + if (clipFrom != null) clipFrom.subtract(mesh, clipa); + Mesh mesh = treeSize() > 0 ? this.mesh.copy() : this.mesh; + for(Box b = getChild(0); b != null; b = b.nextSibling()) b.render(buf, a, mesh, Affine.identity()); + mesh.fill(buf, a, null, fillcolor, true); } - // Methods to implement org.ibex.js.JS ////////////////////////////////////// public JS call(JS method, JS[] args) throws JSExn { @@ -252,8 +262,7 @@ public final class Box extends JS.Obj implements Callable { case "indexof": Box b = (Box)args[0]; if (b.parent != this) - return (redirect == null || redirect == this) ? - JSU.N(-1) : redirect.call(method, args); + return (redirect == null || redirect == this) ? JSU.N(-1) : redirect.call(method, args); return JSU.N(b.getIndexInParent()); case "distanceto": @@ -353,13 +362,23 @@ public final class Box extends JS.Obj implements Callable { if (JSU.isInt(name)) { put(JSU.toInt(name), value); return; } //#switch(JSU.toString(name)) case "thisbox": if (value == null) removeSelf(); - case "text": { String s = value==null ? "" : JSU.toString(value); CHECKSET_STRING(text); RECONSTRAIN(); dirty(); } + case "text": { + String s = value==null ? "" : JSU.toString(value); + text = s; + minwidth = maxwidth = font.textwidth(text); + System.out.println("width=" + width); + minheight = maxheight = font.textheight(text); + System.out.println("height=" + height); + RECONSTRAIN(); + dirty(); + } case "strokecolor": value = JSU.N(Color.stringToColor(JSU.toString(value))); CHECKSET_INT(strokecolor); dirty(); case "textcolor": value = JSU.N(Color.stringToColor(JSU.toString(value))); CHECKSET_INT(strokecolor); dirty(); case "shrink": CHECKSET_FLAG(HSHRINK | VSHRINK); RECONSTRAIN(); case "hshrink": CHECKSET_FLAG(HSHRINK); RECONSTRAIN(); case "vshrink": CHECKSET_FLAG(VSHRINK); RECONSTRAIN(); case "path": { + mesh = null; path = new Path(JSU.toString(value)); float tx = -1 * Encode.longToFloat2(path.horizontalBounds(Affine.identity())); float ty = -1 * Encode.longToFloat2(path.verticalBounds(Affine.identity())); @@ -369,11 +388,22 @@ public final class Box extends JS.Obj implements Callable { dirty(); polygon = null; } + case "clippath": { + clippath = new Path(JSU.toString(value)); + //float tx = -1 * Encode.longToFloat2(clippath.horizontalBounds(Affine.identity())); + //float ty = -1 * Encode.longToFloat2(clippath.verticalBounds(Affine.identity())); + //clippath.transform(Affine.translate(tx, ty), true); + REPLACE(); + RECONSTRAIN(); + dirty(); + polygon = null; + } case "transform": { transform = Affine.parse(JSU.toString(value)); transform.e = 0; transform.f = 0; - if (getSurface() != null) getSurface().dirty(0, 0, 500, 500); // FIXME + if (getSurface() != null) // FIXME + getSurface().dirty(0, 0, getSurface().root.contentwidth, getSurface().root.contentheight); REPLACE(); RECONSTRAIN(); dirty(); polygon = null; }