+ public float minWidth() { return Encode.longToFloat1(transform.rotateBox(minwidth, minheight)); }
+ public float minHeight() { return Encode.longToFloat2(transform.rotateBox(minwidth, minheight)); }
+ public float maxWidth() { return Encode.longToFloat1(transform.rotateBox(maxwidth, maxheight)); }
+ public float maxHeight() { return Encode.longToFloat2(transform.rotateBox(maxwidth, maxheight)); }
+ public float contentWidth() { return Encode.longToFloat1(transform.rotateBox(contentwidth, contentheight)); }
+ public float contentHeight() { return Encode.longToFloat2(transform.rotateBox(contentwidth, contentheight)); }
+
+ /** used (single-threadedly) in constrain() */
+ private static int xmin = 0, ymin = 0, xmax = 0, ymax = 0;
+
+ private static class BoundingBox {
+ public int xmin, ymin, xmax, ymax;
+ public boolean unbounded() {
+ return xmin==Integer.MAX_VALUE||xmax==Integer.MIN_VALUE||ymin==Integer.MAX_VALUE||ymax==Integer.MIN_VALUE; }
+ public void reset() {
+ xmin = Integer.MAX_VALUE; ymin = Integer.MAX_VALUE;
+ xmax = Integer.MIN_VALUE; ymax = Integer.MIN_VALUE;
+ }
+ public void include(Affine a, float cw, float ch) {
+ //#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
+ float z1 = a.multiply_px(0, 0);
+ float z2 = a.multiply_px(cw, ch);
+ float z3 = a.multiply_px(cw, 0);
+ float z4 = a.multiply_px(0, ch);
+ xmin = min(xmin, (int)min(min(z1, z2), min(z3, z4)));
+ xmax = max(xmax, (int)max(max(z1, z2), max(z3, z4)));
+ //#end
+ }
+ public void include(Affine a, Path path) {
+ //#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
+ long bounds = path.horizontalBounds(a);
+ float z1 = Encode.longToFloat2(bounds);
+ float z2 = Encode.longToFloat1(bounds);
+ float z3 = Encode.longToFloat2(bounds);
+ float z4 = Encode.longToFloat1(bounds);
+ xmin = min(xmin, (int)min(min(z1, z2), min(z3, z4)));
+ xmax = max(xmax, (int)max(max(z1, z2), max(z3, z4)));
+ //#end
+ }
+ }
+
+ /** expand the {x,y}{min,max} boundingbox in space <tt>a</tt> to include this box */
+ public void constrain(Box b, Affine a, BoundingBox bbox) {
+ contentwidth = 0;
+ contentheight = 0;
+ a = a.copy().premultiply(transform);
+
+ BoundingBox bbox2 = new BoundingBox();
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) {
+ child.constrain(this, Affine.identity(), bbox2);
+ if (bbox2.unbounded()) { /* FIXME: why? */ bbox2.reset(); continue; }
+ if (packed()) {
+ // packed boxes mush together their childrens' bounding boxes
+ if (test(XAXIS)) {
+ contentwidth = contentwidth + (bbox2.xmax-bbox2.xmin);
+ contentheight = max(bbox2.ymax-bbox2.ymin, contentheight);
+ } else {
+ contentwidth = max(bbox2.xmax-bbox2.xmin, contentwidth);
+ contentheight = contentheight + (bbox2.ymax-bbox2.ymin);
+ }
+ bbox2.reset();