Code with Finding: |
class ColumnText {
protected int goComposite(final boolean simulate) throws DocumentException {
if (!rectangularMode)
throw new DocumentException(MessageLocalization.getComposedMessage("irregular.columns.are.not.supported.in.composite.mode"));
linesWritten = 0;
descender = 0;
boolean firstPass = true;
main_loop:
while (true) {
if (compositeElements.isEmpty())
return NO_MORE_TEXT;
Element element = compositeElements.getFirst();
if (element.type() == Element.PARAGRAPH) {
Paragraph para = (Paragraph)element;
int status = 0;
for (int keep = 0; keep < 2; ++keep) {
float lastY = yLine;
boolean createHere = false;
if (compositeColumn == null) {
compositeColumn = new ColumnText(canvas);
compositeColumn.setAlignment(para.getAlignment());
compositeColumn.setIndent(para.getIndentationLeft() + para.getFirstLineIndent());
compositeColumn.setExtraParagraphSpace(para.getExtraParagraphSpace());
compositeColumn.setFollowingIndent(para.getIndentationLeft());
compositeColumn.setRightIndent(para.getIndentationRight());
compositeColumn.setLeading(para.getLeading(), para.getMultipliedLeading());
compositeColumn.setRunDirection(runDirection);
compositeColumn.setArabicOptions(arabicOptions);
compositeColumn.setSpaceCharRatio(spaceCharRatio);
compositeColumn.addText(para);
if (!(firstPass && adjustFirstLine)) {
yLine -= para.getSpacingBefore();
}
createHere = true;
}
compositeColumn.setUseAscender(firstPass && adjustFirstLine ? useAscender : false);
compositeColumn.leftX = leftX;
compositeColumn.rightX = rightX;
compositeColumn.yLine = yLine;
compositeColumn.rectangularWidth = rectangularWidth;
compositeColumn.rectangularMode = rectangularMode;
compositeColumn.minY = minY;
compositeColumn.maxY = maxY;
boolean keepCandidate = para.getKeepTogether() && createHere && !(firstPass && adjustFirstLine);
status = compositeColumn.go(simulate || keepCandidate && keep == 0);
lastX = compositeColumn.getLastX();
updateFilledWidth(compositeColumn.filledWidth);
if ((status & NO_MORE_TEXT) == 0 && keepCandidate) {
compositeColumn = null;
yLine = lastY;
return NO_MORE_COLUMN;
}
if (simulate || !keepCandidate)
break;
if (keep == 0) {
compositeColumn = null;
yLine = lastY;
}
}
firstPass = false;
yLine = compositeColumn.yLine;
linesWritten += compositeColumn.linesWritten;
descender = compositeColumn.descender;
if ((status & NO_MORE_TEXT) != 0) {
compositeColumn = null;
compositeElements.removeFirst();
yLine -= para.getSpacingAfter();
}
if ((status & NO_MORE_COLUMN) != 0) {
return NO_MORE_COLUMN;
}
}
else if (element.type() == Element.LIST) {
com.itextpdf.text.List list = (com.itextpdf.text.List)element;
ArrayList<Element> items = list.getItems();
ListItem item = null;
float listIndentation = list.getIndentationLeft();
int count = 0;
Stack<Object[]> stack = new Stack<Object[]>();
for (int k = 0; k < items.size(); ++k) {
Object obj = items.get(k);
if (obj instanceof ListItem) {
if (count == listIdx) {
item = (ListItem)obj;
break;
}
else ++count;
}
else if (obj instanceof com.itextpdf.text.List) {
stack.push(new Object[]{list, Integer.valueOf(k), new Float(listIndentation)});
list = (com.itextpdf.text.List)obj;
items = list.getItems();
listIndentation += list.getIndentationLeft();
k = -1;
continue;
}
if (k == items.size() - 1) {
if (!stack.isEmpty()) {
Object objs[] = stack.pop();
list = (com.itextpdf.text.List)objs[0];
items = list.getItems();
k = ((Integer)objs[1]).intValue();
listIndentation = ((Float)objs[2]).floatValue();
}
}
}
int status = 0;
for (int keep = 0; keep < 2; ++keep) {
float lastY = yLine;
boolean createHere = false;
if (compositeColumn == null) {
if (item == null) {
listIdx = 0;
compositeElements.removeFirst();
continue main_loop;
}
compositeColumn = new ColumnText(canvas);
compositeColumn.setUseAscender(firstPass && adjustFirstLine ? useAscender : false);
compositeColumn.setAlignment(item.getAlignment());
compositeColumn.setIndent(item.getIndentationLeft() + listIndentation + item.getFirstLineIndent());
compositeColumn.setExtraParagraphSpace(item.getExtraParagraphSpace());
compositeColumn.setFollowingIndent(compositeColumn.getIndent());
compositeColumn.setRightIndent(item.getIndentationRight() + list.getIndentationRight());
compositeColumn.setLeading(item.getLeading(), item.getMultipliedLeading());
compositeColumn.setRunDirection(runDirection);
compositeColumn.setArabicOptions(arabicOptions);
compositeColumn.setSpaceCharRatio(spaceCharRatio);
compositeColumn.addText(item);
if (!(firstPass && adjustFirstLine)) {
yLine -= item.getSpacingBefore();
}
createHere = true;
}
compositeColumn.leftX = leftX;
compositeColumn.rightX = rightX;
compositeColumn.yLine = yLine;
compositeColumn.rectangularWidth = rectangularWidth;
compositeColumn.rectangularMode = rectangularMode;
compositeColumn.minY = minY;
compositeColumn.maxY = maxY;
boolean keepCandidate = item.getKeepTogether() && createHere && !(firstPass && adjustFirstLine);
status = compositeColumn.go(simulate || keepCandidate && keep == 0);
lastX = compositeColumn.getLastX();
updateFilledWidth(compositeColumn.filledWidth);
if ((status & NO_MORE_TEXT) == 0 && keepCandidate) {
compositeColumn = null;
yLine = lastY;
return NO_MORE_COLUMN;
}
if (simulate || !keepCandidate)
break;
if (keep == 0) {
compositeColumn = null;
yLine = lastY;
}
}
firstPass = false;
yLine = compositeColumn.yLine;
linesWritten += compositeColumn.linesWritten;
descender = compositeColumn.descender;
if (!Float.isNaN(compositeColumn.firstLineY) && !compositeColumn.firstLineYDone) {
if (!simulate)
showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(item.getListSymbol()), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0);
compositeColumn.firstLineYDone = true;
}
if ((status & NO_MORE_TEXT) != 0) {
compositeColumn = null;
++listIdx;
yLine -= item.getSpacingAfter();
}
if ((status & NO_MORE_COLUMN) != 0)
return NO_MORE_COLUMN;
}
else if (element.type() == Element.PTABLE) {
// INITIALISATIONS
// get the PdfPTable element
PdfPTable table = (PdfPTable)element;
// tables without a body are dismissed
if (table.size() <= table.getHeaderRows()) {
compositeElements.removeFirst();
continue;
}
// Y-offset
float yTemp = yLine;
if (rowIdx == 0 && adjustFirstLine)
yTemp -= table.spacingBefore();
// if there's no space left, ask for new column
if (yTemp < minY || yTemp > maxY)
return NO_MORE_COLUMN;
// mark start of table
float yLineWrite = yTemp;
float x1 = leftX;
currentLeading = 0;
// get the width of the table
float tableWidth;
if (table.isLockedWidth()) {
tableWidth = table.getTotalWidth();
updateFilledWidth(tableWidth);
}
else {
tableWidth = rectangularWidth * table.getWidthPercentage() / 100f;
table.setTotalWidth(tableWidth);
}
// HEADERS / FOOTERS
// how many header rows are real header rows; how many are footer rows?
table.normalizeHeadersFooters();
int headerRows = table.getHeaderRows();
int footerRows = table.getFooterRows();
int realHeaderRows = headerRows - footerRows;
float headerHeight = table.getHeaderHeight();
float footerHeight = table.getFooterHeight();
// do we need to skip the header?
boolean skipHeader = table.isSkipFirstHeader() && rowIdx <= realHeaderRows;
// if not, we wan't to be able to add more than just a header and a footer
if (!skipHeader) {
yTemp -= headerHeight;
if (yTemp < minY || yTemp > maxY) {
return NO_MORE_COLUMN;
}
}
// MEASURE NECESSARY SPACE
// how many real rows (not header or footer rows) fit on a page?
int k = 0;
if (rowIdx < headerRows)
rowIdx = headerRows;
// if the table isn't complete, we need to be able to add a footer
if (!table.isComplete())
yTemp -= footerHeight;
// k will be the first row that doesn't fit
for (k = rowIdx; k < table.size(); ++k) {
float rowHeight = table.getRowHeight(k);
if (yTemp - rowHeight < minY)
break;
yTemp -= rowHeight;
}
// only for incomplete tables:
if (!table.isComplete())
yTemp += footerHeight;
// IF ROWS MAY NOT BE SPLIT
if (!table.isSplitRows()) {
splittedRow = -1;
if (k == rowIdx) {
// drop the whole table
if (k == table.size()) {
compositeElements.removeFirst();
continue;
}
// or drop the row
else {
table.getRows().remove(k);
return NO_MORE_COLUMN;
}
}
}
// IF ROWS SHOULD NOT BE SPLIT
else if (table.isSplitLate() && !table.hasRowspan(k) && rowIdx < k) {
splittedRow = -1;
}
// SPLIT ROWS (IF WANTED AND NECESSARY)
else if (k < table.size()) {
// if the row hasn't been split before, we duplicate (part of) the table
if (k != splittedRow) {
splittedRow = k + 1;
table = new PdfPTable(table);
compositeElements.set(0, table);
ArrayList<PdfPRow> rows = table.getRows();
for (int i = headerRows; i < rowIdx; ++i)
rows.set(i, null);
}
// we calculate the remaining vertical space
float h = yTemp - minY;
// we create a new row with the remaining content
PdfPRow newRow = table.getRow(k).splitRow(table, k, h);
// if the row isn't null add it as an extra row
if (newRow == null) {
splittedRow = -1;
if (rowIdx == k)
return NO_MORE_COLUMN;
}
else {
yTemp = minY;
table.getRows().add(++k, newRow);
}
}
// We're no longer in the first pass
firstPass = false;
// if not in simulation mode, draw the table
if (!simulate) {
// set the alignment
switch (table.getHorizontalAlignment()) {
case Element.ALIGN_LEFT:
break;
case Element.ALIGN_RIGHT:
x1 += rectangularWidth - tableWidth;
break;
default:
x1 += (rectangularWidth - tableWidth) / 2f;
}
// copy the rows that fit on the page in a new table nt
PdfPTable nt = PdfPTable.shallowCopy(table);
ArrayList<PdfPRow> sub = nt.getRows();
// first we add the real header rows (if necessary)
if (!skipHeader && realHeaderRows > 0) {
sub.addAll(table.getRows(0, realHeaderRows));
}
else
nt.setHeaderRows(footerRows);
// then we add the real content
sub.addAll(table.getRows(rowIdx, k));
// do we need to show a footer?
boolean showFooter = !table.isSkipLastFooter();
boolean newPageFollows = false;
if (k < table.size()) {
nt.setComplete(true);
showFooter = true;
newPageFollows = true;
}
// we add the footer rows if necessary (not for incomplete tables)
if (footerRows > 0 && nt.isComplete() && showFooter) {
sub.addAll(table.getRows(realHeaderRows, realHeaderRows + footerRows));
}
else {
footerRows = 0;
}
// we need a correction if the last row needs to be extended
float rowHeight = 0;
int lastIdx = sub.size() - 1 - footerRows;
PdfPRow last = sub.get(lastIdx);
if (table.isExtendLastRow(newPageFollows)) {
rowHeight = last.getMaxHeights();
last.setMaxHeights(yTemp - minY + rowHeight);
yTemp = minY;
}
// newPageFollows indicates that this table is being split
if (newPageFollows) {
PdfPTableEvent tableEvent = table.getTableEvent();
if (tableEvent instanceof PdfPTableEventSplit) {
((PdfPTableEventSplit)tableEvent).splitTable(table);
}
}
// now we render the rows of the new table
if (canvases != null)
nt.writeSelectedRows(0, -1, 0, -1, x1, yLineWrite, canvases, false);
else
nt.writeSelectedRows(0, -1, 0, -1, x1, yLineWrite, canvas, false);
// if the row was split, we copy the content of the last row
// that was consumed into the first row shown on the next page
if (splittedRow == k && k < table.size()) {
PdfPRow splitted = table.getRows().get(k);
splitted.copyRowContent(nt, lastIdx);
}
// reset the row height of the last row
if (table.isExtendLastRow(newPageFollows)) {
last.setMaxHeights(rowHeight);
}
}
// in simulation mode, we need to take extendLastRow into account
else if (table.isExtendLastRow() && minY > PdfPRow.BOTTOM_LIMIT) {
yTemp = minY;
}
yLine = yTemp;
if (!(skipHeader || table.isComplete()))
yLine += footerHeight;
if (k >= table.size()) {
// Use up space no more than left
if(yLine - table.spacingAfter() < minY) {
yLine = minY;
}
else {
yLine -= table.spacingAfter();
}
compositeElements.removeFirst();
splittedRow = -1;
rowIdx = 0;
}
else {
if (splittedRow != -1) {
ArrayList<PdfPRow> rows = table.getRows();
for (int i = rowIdx; i < k; ++i)
rows.set(i, null);
}
rowIdx = k;
return NO_MORE_COLUMN;
}
}
else if (element.type() == Element.YMARK) {
if (!simulate) {
DrawInterface zh = (DrawInterface)element;
zh.draw(canvas, leftX, minY, rightX, maxY, yLine);
}
compositeElements.removeFirst();
}
else
compositeElements.removeFirst();
}
}
}
|