protected void finishTableRowLevelBox(final RenderBox box) { try { box.setCachedX(nodeContext.getX()); box.setContentAreaX1(nodeContext.getX1()); box.setContentAreaX2(nodeContext.getX2()); if (box.getNodeType() != LayoutNodeTypes.TYPE_BOX_TABLE_CELL) { // break-marker boxes etc. box.setCachedWidth(resolveTableWidthOnFinish(box)); nodeContext.updateParentX2(box.getCachedX2()); } else { box.setCachedWidth( MinorAxisLayoutStepUtil.resolveNodeWidthOnFinish( box, nodeContext, isStrictLegacyMode())); final TableCellRenderBox cell = (TableCellRenderBox) box; final MinorAxisTableContext tableContext = getTableContext(); final TableRenderBox table = tableContext.getTable(); if (tableContext.isStructureValidated() == false) { table .getColumnModel() .updateCellSize( cell.getColumnIndex(), cell.getColSpan(), box.getCachedWidth() - box.getInsets()); } nodeContext.updateParentX2(box.getCachedX2()); } } finally { nodeContext = nodeContext.pop(); } }
protected void computeInlineBlock( final RenderBox box, final long position, final long itemElementWidth) { final StaticBoxLayoutProperties blp = box.getStaticBoxLayoutProperties(); box.setCachedX(position + blp.getMarginLeft()); final long width = itemElementWidth - blp.getMarginLeft() - blp.getMarginRight(); if (width == 0) { // ModelPrinter.printParents(box); throw new IllegalStateException( "A box without any width? " + Integer.toHexString(System.identityHashCode(box)) + ' ' + box.getClass()); } box.setCachedWidth(width); final BoxDefinition bdef = box.getBoxDefinition(); final long leftInsets = bdef.getPaddingLeft() + blp.getBorderLeft(); final long rightInsets = bdef.getPaddingRight() + blp.getBorderRight(); box.setContentAreaX1(box.getCachedX() + leftInsets); box.setContentAreaX2(box.getCachedX() + box.getCachedWidth() - rightInsets); // final InfiniteMinorAxisLayoutStep layoutStep = new InfiniteMinorAxisLayoutStep(metaData); // layoutStep.continueComputation(getPageGrid(), box); }
protected void finishTableSectionLevelBox(final RenderBox box) { try { box.setCachedX(nodeContext.getX()); box.setContentAreaX1(nodeContext.getX1()); box.setContentAreaX2(nodeContext.getX2()); box.setCachedWidth(resolveTableWidthOnFinish(box)); nodeContext.updateParentX2(box.getCachedX2()); } finally { nodeContext = nodeContext.pop(); } }
protected void finishTableLevelBox(final RenderBox box) { try { if (checkCacheValid(box)) { nodeContext.updateParentX2(box.getCachedX2()); return; } if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL_GROUP) { finishTableColGroup((TableColumnGroupNode) box); } else if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL) { finishTableCol((TableColumnNode) box); } else { box.setCachedX(nodeContext.getX()); box.setContentAreaX1(nodeContext.getX1()); box.setContentAreaX2(nodeContext.getX2()); box.setCachedWidth(resolveTableWidthOnFinish(box)); nodeContext.updateParentX2(box.getCachedX2()); } } finally { nodeContext = nodeContext.pop(); } }
protected void finishBlockLevelBox(final RenderBox box) { try { if (checkCacheValid(box)) { nodeContext.updateParentX2(box.getCachedX2()); return; } box.setCachedX(nodeContext.getX()); box.setContentAreaX1(nodeContext.getX1()); box.setContentAreaX2(nodeContext.getX2()); if (finishTableContext(box) == false) { box.setCachedWidth( MinorAxisLayoutStepUtil.resolveNodeWidthOnFinish( box, nodeContext, isStrictLegacyMode())); } nodeContext.updateParentX2(box.getCachedX2()); finishParagraphBox(box); } finally { nodeContext = nodeContext.pop(); } }
protected void finishCanvasLevelBox(final RenderBox box) { try { if (checkCacheValid(box)) { nodeContext.updateParentX2(box.getCachedX2()); return; } // make sure that the width takes all the borders and paddings into account. box.setCachedX(nodeContext.getX()); box.setContentAreaX1(nodeContext.getX1()); box.setContentAreaX2(nodeContext.getX2()); if (finishTableContext(box) == false) { box.setCachedWidth( MinorAxisLayoutStepUtil.resolveNodeWidthOnFinish( box, nodeContext, isStrictLegacyMode())); } nodeContext.updateParentX2(box.getCachedX2()); finishParagraphBox(box); } finally { nodeContext = nodeContext.pop(); } }
public void performLastLineAlignment() { if (pagebreakCount == 0) { throw new IllegalStateException("Alignment processor has not been initialized correctly."); } Arrays.fill(elementDimensions, 0); Arrays.fill(elementPositions, 0); int lastPosition = iterate(sequenceElements, sequenceFill); if (lastPosition == 0) { // This could evolve into an infinite loop. Thats evil. // We have two choices to prevent that: // (1) Try to break the element. // if (getBreakableIndex() >= 0) // { // // Todo: Breaking is not yet implemented .. // } if (getSkipIndex() >= 0) { // This causes an overflow .. performSkipAlignment(getSkipIndex()); lastPosition = getSkipIndex(); } else { // Skip the complete line. Oh, thats not good, really! lastPosition = sequenceFill; } } // the elements up to the 'lastPosition' are now aligned according to the alignment rules. // now, update the element's positions and dimensions .. if (lastPosition == sequenceFill || lastLineAlignment) { // First, the simple case: The line's content did fully fit into the linebox. No linebreaks // were necessary. RenderBox firstBox = null; for (int i = 0; i < lastPosition; i++) { final RenderNode node = nodes[i]; final InlineSequenceElement element = sequenceElements[i]; if (element instanceof EndSequenceElement) { final long boxX2 = (elementPositions[i] + elementDimensions[i]); final RenderBox box = (RenderBox) node; box.setCachedWidth(boxX2 - box.getCachedX()); continue; } if (element instanceof StartSequenceElement) { final RenderBox box = (RenderBox) node; box.setCachedX(elementPositions[i]); if (firstBox == null) { firstBox = box; } continue; } // Content element: Perform a deep-deriveForAdvance, so that we preserve the // possibly existing sub-nodes. node.setCachedX(elementPositions[i]); node.setCachedWidth(elementDimensions[i]); } return; } // The second case is more complicated. The text did not fit fully into the text-element. // Left align all elements after the layouted content .. if (leftAlignProcessor == null) { leftAlignProcessor = new LeftAlignmentProcessor(); } leftAlignProcessor.initializeForLastLineAlignment(this); leftAlignProcessor.performLastLineAlignment(); leftAlignProcessor.deinitialize(); }
public RenderBox next() { cleanFirstSpacers(); Arrays.fill(elementDimensions, 0); Arrays.fill(elementPositions, 0); int lastPosition = iterate(sequenceElements, sequenceFill); if (lastPosition == 0) { // This could evolve into an infinite loop. Thats evil. // We have two choices to prevent that: // (1) Try to break the element. // if (getBreakableIndex() >= 0) // { // // Todo: Breaking is not yet implemented .. // } if (getSkipIndex() >= 0) { // This causes an overflow .. performSkipAlignment(getSkipIndex()); lastPosition = getSkipIndex(); } else { // Skip the complete line. Oh, thats not good, really! lastPosition = sequenceFill; } } // now, build the line and update the array .. pendingElements.clear(); contexts.clear(); RenderBox firstBox = null; RenderBox box = null; for (int i = 0; i < lastPosition; i++) { final RenderNode node = nodes[i]; final InlineSequenceElement element = sequenceElements[i]; if (element instanceof EndSequenceElement) { contexts.pop(); final long boxX2 = (elementPositions[i] + elementDimensions[i]); box.setCachedWidth(boxX2 - box.getCachedX()); if (contexts.isEmpty()) { box = null; } else { final RenderNode tmpnode = box; box = contexts.peek(); box.addGeneratedChild(tmpnode); } continue; } if (element instanceof StartSequenceElement) { box = (RenderBox) node.derive(false); box.setCachedX(elementPositions[i]); contexts.push(box); if (firstBox == null) { firstBox = box; } continue; } if (box == null) { throw new IllegalStateException( "Invalid sequence: " + "Cannot have elements before we open the box context."); } // Content element: Perform a deep-deriveForAdvance, so that we preserve the // possibly existing sub-nodes. final RenderNode child = node.derive(true); child.setCachedX(elementPositions[i]); child.setCachedWidth(elementDimensions[i]); if (box.getStaticBoxLayoutProperties().isPreserveSpace() && box.getStyleSheet().getBooleanStyleProperty(TextStyleKeys.TRIM_TEXT_CONTENT) == false) { // Take a shortcut as we know that we will never have any pending elements if preserve is // true and // trim-content is false. box.addGeneratedChild(child); continue; } if (child.isIgnorableForRendering()) { pendingElements.add(child); } else { for (int j = 0; j < pendingElements.size(); j++) { final RenderNode pendingNode = pendingElements.get(j); box.addGeneratedChild(pendingNode); } pendingElements.clear(); box.addGeneratedChild(child); } } // Remove all spacers and other non printable content that might // look ugly at the beginning of a new line .. for (; lastPosition < sequenceFill; lastPosition++) { final RenderNode node = nodes[lastPosition]; final StyleSheet styleSheet = node.getStyleSheet(); if (WhitespaceCollapse.PRESERVE.equals( styleSheet.getStyleProperty(TextStyleKeys.WHITE_SPACE_COLLAPSE)) && styleSheet.getBooleanStyleProperty(TextStyleKeys.TRIM_TEXT_CONTENT) == false) { break; } if (node.isIgnorableForRendering() == false) { break; } } // If there are open contexts, then add the split-result to the new line // and update the width of the current line RenderBox previousContext = null; final int openContexts = contexts.size(); for (int i = 0; i < openContexts; i++) { final RenderBox renderBox = contexts.get(i); final long cachedWidth = getEndOfLine() - renderBox.getCachedX(); renderBox.setCachedWidth(cachedWidth); final InlineRenderBox rightBox = (InlineRenderBox) renderBox.split(RenderNode.HORIZONTAL_AXIS); sequenceElements[i] = StartSequenceElement.INSTANCE; nodes[i] = rightBox; if (previousContext != null) { previousContext.addGeneratedChild(renderBox); } previousContext = renderBox; } final int length = sequenceFill - lastPosition; System.arraycopy(sequenceElements, lastPosition, sequenceElements, openContexts, length); System.arraycopy(nodes, lastPosition, nodes, openContexts, length); sequenceFill = openContexts + length; Arrays.fill(sequenceElements, sequenceFill, sequenceElements.length, null); Arrays.fill(nodes, sequenceFill, nodes.length, null); return firstBox; }