private boolean iterateOnLeft( Iterator<AtomicIncreaseResult> iterator, int currentIndex, SplitResult currentResult, float elementTop, float elementHeight) { currentResult .setLeftColumnHeight(leftCTB.getCurrentHeight()) .setLeftElementSplitHeight(elementTop - leftCTB.getYLine(), elementHeight); if (currentResult.leftElementSplitHeight > 0) { considerAddingToRight(currentIndex + 1, true); } while (iterator.hasNext()) { AtomicIncreaseResult r = iterator.next(); currentResult .setLeftColumnHeight(leftCTB.getCurrentHeight()) .setLeftElementSplitHeight(elementTop - leftCTB.getYLine(), elementHeight); switch (r.type) { case PAGE_OVERFLOW: return true; case NORMAL: considerAddingToRight(currentIndex + 1, true); break; case NO_MORE_CONTENT: // don't consider adding to right as this case must be checked in the main loop // considerAddingToRight(currentIndex + 1, false); break; } } return false; }
private BalancingResult _go() { if (b.drawBorders) { b.getCanvasBuilder().drawGrayRectangle(origRectangle.get(), BaseColor.LIGHT_GRAY); } currentLeftResult.totalElementCount = currentRightResult.totalElementCount = bestResult.totalElementCount = sequence.size(); // try adding into a single infinite column to calc height final float hCenter = horCenter(); referenceHeight = calcReferenceHeight(hCenter); currentLeftResult.referenceHeight = currentRightResult.referenceHeight = bestResult.referenceHeight = referenceHeight; leftCTB = setColumn( (float) referenceHeight, hCenter, true, true, singleColumnRect, b.newColumnTextBuilder()); rightCTB = setColumn( (float) referenceHeight, hCenter, false, true, singleColumnRect, b.newColumnTextBuilder()); minimalLeftColumnHeight = MINIMAL_HEIGHT_COEFFICIENT * referenceHeight / 2; int i; List<Element> elements = sequence.getElements(); final DirectContentAdder.Result quickResult = new DirectContentAdder(leftCTB) .setStartWith(initialLeftCTB) .setStartAtIndex(startAtElement) .setQuickHeight(minimalLeftColumnHeight) .setSimulate(true) .go(); i = quickResult.index; bestResult.assignIfWorseThan( currentLeftResult .setElementsAddedCount(i) .setLeftElementSplitHeight(0, 0) .setLeftColumnHeight(leftCTB.getCurrentHeight()) .setPageSplit(i, quickResult.hasContentLeft(elements.size()))); boolean pageOverFlow = false; // the only situation possible is the content left from initialContent if (quickResult.contentLeft != null) { leftCTB.copyContentFrom(quickResult.contentLeft); pageOverFlow = iterateOnLeft( leftCTB.newAtomicIteratorFor(), i - 1, currentLeftResult, leftCTB.getTop(), sequence.initialContentHeight); } if (i == elements.size()) { bestResult.assignIfWorseThan( currentLeftResult .setLeftElementSplitHeight(0, 0) .setLeftColumnHeight(leftCTB.getCurrentHeight()) .setElementsAddedCount(i) .setPageSplit(i, leftCTB.hasMoreText())); } if (pageOverFlow) { return applyBestResult(); } elementsCycle: for (; i < elements.size(); i++) { Element el = elements.get(i); final SplitResult currentResult = currentLeftResult; currentResult .setLeftElementSplitHeight(0, 0) .setElementsAddedCount(i) .setLeftColumnHeight(leftCTB.getCurrentHeight()); considerAddingOnRightAtWholeElement(i); if (el instanceof SpaceElement) { SpaceElement space = (SpaceElement) el; currentResult.setElementsAddedCount(i); considerAddingToRight(i + 1, false); if (space.fits(leftCTB, origRectangle.getBottom())) { space.add(leftCTB, true); } else { if (leftCTB.getSimpleColumnRectangle().getBottom() - space.getHeight() < b.getDocument().bottom()) { break; } leftCTB.growBottom(space.getHeight()).setYLine(leftCTB.getYLine() - space.getHeight()); } } else { float elementTop = leftCTB.getYLine(); final Iterator<AtomicIncreaseResult> iterator = leftCTB.newAtomicIteratorFor(el); if (iterateOnLeft(iterator, i, currentResult, elementTop, sequence.getHeight(i))) { break elementsCycle; } // leftCTB.restoreState(); } currentResult.setLeftColumnHeight(leftCTB.getCurrentHeight()).setElementsAddedCount(i + 1); } considerAddingOnRightAtWholeElement(i); // here we have bestResult, so let's add our content with no simulation! // setColumn(bestResult, b.newColumnTextBuilder()) return applyBestResult(); }