// save positions
int saveIP = currentIPPosition;
int saveBP = currentBPPosition;
CTM ctm = bv.getCTM();
int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
float x, y;
x = (float) (bv.getXOffset() + containingIPPosition) / 1000f;
y = (float) (bv.getYOffset() + containingBPPosition) / 1000f;
if (bv.getPositioning() == Block.ABSOLUTE
|| bv.getPositioning() == Block.FIXED) {
// TODO not tested yet
// For FIXED, we need to break out of the current viewports to the
// one established by the page. We save the state stack for
// restoration
// after the block-container has been painted. See below.
List breakOutList = null;
if (bv.getPositioning() == Block.FIXED) {
log.debug("Block.FIXED --> break out");
breakOutList = new java.util.ArrayList();
Graphics2D graph;
while (true) {
graph = state.getGraph();
if (state.pop() == null) {
break;
}
breakOutList.add(0, graph); // Insert because of
// stack-popping
log.debug("Adding to break out list: " + graph);
}
}
CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
ctm = tempctm.multiply(ctm);
// This is the content-rect
float width = (float) bv.getIPD() / 1000f;
float height = (float) bv.getBPD() / 1000f;
// Adjust for spaces (from margin or indirectly by start-indent etc.
Integer spaceStart = (Integer) bv.getTrait(Trait.SPACE_START);
if (spaceStart != null) {
x += spaceStart.floatValue() / 1000;
}
Integer spaceBefore = (Integer) bv.getTrait(Trait.SPACE_BEFORE);
if (spaceBefore != null) {
y += spaceBefore.floatValue() / 1000;
}
float bpwidth = (borderPaddingStart + bv
.getBorderAndPaddingWidthEnd()) / 1000f;
float bpheight = (borderPaddingBefore + bv
.getBorderAndPaddingWidthAfter()) / 1000f;
drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
// Now adjust for border/padding
x += borderPaddingStart / 1000f;
y += borderPaddingBefore / 1000f;
if (bv.getClip()) {
// saves the graphics state in a stack
state.push();
clip(x, y, width, height);
}
startVParea(ctm);
renderBlocks(bv, children);
endVParea();
if (bv.getClip()) {
// restores the last graphics state from the stack
state.pop();
}
// clip if necessary
if (breakOutList != null) {
log.debug(
"Block.FIXED --> restoring context after break-out");
Graphics2D graph;
Iterator i = breakOutList.iterator();
while (i.hasNext()) {
graph = (Graphics2D) i.next();
log.debug("Restoring: " + graph);
state.push();
}
}
currentIPPosition = saveIP;
currentBPPosition = saveBP;
} else { // orientation = Block.STACK or RELATIVE
Integer spaceBefore = (Integer) bv.getTrait(Trait.SPACE_BEFORE);
if (spaceBefore != null) {
currentBPPosition += spaceBefore.intValue();
}
// borders and background in the old coordinate system
handleBlockTraits(bv);
CTM tempctm = new CTM(containingIPPosition, currentBPPosition
+ containingBPPosition);
ctm = tempctm.multiply(ctm);
// Now adjust for border/padding
x += borderPaddingStart / 1000f;
y += borderPaddingBefore / 1000f;