| Method from com.lowagie.text.pdf.PdfDocument Detail: |
public boolean add(Element element) throws DocumentException {
if (writer != null && writer.isPaused()) {
return false;
}
try {
switch(element.type()) {
// Information (headers)
case Element.HEADER:
info.addkey(((Meta)element).getName(), ((Meta)element).getContent());
break;
case Element.TITLE:
info.addTitle(((Meta)element).getContent());
break;
case Element.SUBJECT:
info.addSubject(((Meta)element).getContent());
break;
case Element.KEYWORDS:
info.addKeywords(((Meta)element).getContent());
break;
case Element.AUTHOR:
info.addAuthor(((Meta)element).getContent());
break;
case Element.CREATOR:
info.addCreator(((Meta)element).getContent());
break;
case Element.PRODUCER:
// you can not change the name of the producer
info.addProducer();
break;
case Element.CREATIONDATE:
// you can not set the creation date, only reset it
info.addCreationDate();
break;
// content (text)
case Element.CHUNK: {
// if there isn't a current line available, we make one
if (line == null) {
carriageReturn();
}
// we cast the element to a chunk
PdfChunk chunk = new PdfChunk((Chunk) element, anchorAction);
// we try to add the chunk to the line, until we succeed
{
PdfChunk overflow;
while ((overflow = line.add(chunk)) != null) {
carriageReturn();
chunk = overflow;
chunk.trimFirstSpace();
}
}
pageEmpty = false;
if (chunk.isAttribute(Chunk.NEWPAGE)) {
newPage();
}
break;
}
case Element.ANCHOR: {
leadingCount++;
Anchor anchor = (Anchor) element;
String url = anchor.getReference();
leading = anchor.getLeading();
if (url != null) {
anchorAction = new PdfAction(url);
}
// we process the element
element.process(this);
anchorAction = null;
leadingCount--;
break;
}
case Element.ANNOTATION: {
if (line == null) {
carriageReturn();
}
Annotation annot = (Annotation) element;
Rectangle rect = new Rectangle(0, 0);
if (line != null)
rect = new Rectangle(annot.llx(indentRight() - line.widthLeft()), annot.lly(indentTop() - currentHeight), annot.urx(indentRight() - line.widthLeft() + 20), annot.ury(indentTop() - currentHeight - 20));
PdfAnnotation an = PdfAnnotationsImp.convertAnnotation(writer, annot, rect);
annotationsImp.addPlainAnnotation(an);
pageEmpty = false;
break;
}
case Element.PHRASE: {
leadingCount++;
// we cast the element to a phrase and set the leading of the document
leading = ((Phrase) element).getLeading();
// we process the element
element.process(this);
leadingCount--;
break;
}
case Element.PARAGRAPH: {
leadingCount++;
// we cast the element to a paragraph
Paragraph paragraph = (Paragraph) element;
addSpacing(paragraph.spacingBefore(), leading, paragraph.getFont());
// we adjust the parameters of the document
alignment = paragraph.getAlignment();
leading = paragraph.getTotalLeading();
carriageReturn();
// we don't want to make orphans/widows
if (currentHeight + line.height() + leading > indentTop() - indentBottom()) {
newPage();
}
indentation.indentLeft += paragraph.getIndentationLeft();
indentation.indentRight += paragraph.getIndentationRight();
carriageReturn();
PdfPageEvent pageEvent = writer.getPageEvent();
if (pageEvent != null && !isSectionTitle)
pageEvent.onParagraph(writer, this, indentTop() - currentHeight);
// if a paragraph has to be kept together, we wrap it in a table object
if (paragraph.getKeepTogether()) {
carriageReturn();
PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100f);
PdfPCell cell = new PdfPCell();
cell.addElement(paragraph);
cell.setBorder(Table.NO_BORDER);
cell.setPadding(0);
table.addCell(cell);
indentation.indentLeft -= paragraph.getIndentationLeft();
indentation.indentRight -= paragraph.getIndentationRight();
this.add(table);
indentation.indentLeft += paragraph.getIndentationLeft();
indentation.indentRight += paragraph.getIndentationRight();
}
else {
line.setExtraIndent(paragraph.getFirstLineIndent());
element.process(this);
carriageReturn();
addSpacing(paragraph.spacingAfter(), paragraph.getTotalLeading(), paragraph.getFont());
}
if (pageEvent != null && !isSectionTitle)
pageEvent.onParagraphEnd(writer, this, indentTop() - currentHeight);
alignment = Element.ALIGN_LEFT;
indentation.indentLeft -= paragraph.getIndentationLeft();
indentation.indentRight -= paragraph.getIndentationRight();
carriageReturn();
leadingCount--;
break;
}
case Element.SECTION:
case Element.CHAPTER: {
// Chapters and Sections only differ in their constructor
// so we cast both to a Section
Section section = (Section) element;
PdfPageEvent pageEvent = writer.getPageEvent();
boolean hasTitle = section.isNotAddedYet()
&& section.getTitle() != null;
// if the section is a chapter, we begin a new page
if (section.isTriggerNewPage()) {
newPage();
}
if (hasTitle) {
float fith = indentTop() - currentHeight;
int rotation = pageSize.getRotation();
if (rotation == 90 || rotation == 180)
fith = pageSize.getHeight() - fith;
PdfDestination destination = new PdfDestination(PdfDestination.FITH, fith);
while (currentOutline.level() >= section.getDepth()) {
currentOutline = currentOutline.parent();
}
PdfOutline outline = new PdfOutline(currentOutline, destination, section.getBookmarkTitle(), section.isBookmarkOpen());
currentOutline = outline;
}
// some values are set
carriageReturn();
indentation.sectionIndentLeft += section.getIndentationLeft();
indentation.sectionIndentRight += section.getIndentationRight();
if (section.isNotAddedYet() && pageEvent != null)
if (element.type() == Element.CHAPTER)
pageEvent.onChapter(writer, this, indentTop() - currentHeight, section.getTitle());
else
pageEvent.onSection(writer, this, indentTop() - currentHeight, section.getDepth(), section.getTitle());
// the title of the section (if any has to be printed)
if (hasTitle) {
isSectionTitle = true;
add(section.getTitle());
isSectionTitle = false;
}
indentation.sectionIndentLeft += section.getIndentation();
// we process the section
element.process(this);
flushLines();
// some parameters are set back to normal again
indentation.sectionIndentLeft -= (section.getIndentationLeft() + section.getIndentation());
indentation.sectionIndentRight -= section.getIndentationRight();
if (section.isComplete() && pageEvent != null)
if (element.type() == Element.CHAPTER)
pageEvent.onChapterEnd(writer, this, indentTop() - currentHeight);
else
pageEvent.onSectionEnd(writer, this, indentTop() - currentHeight);
break;
}
case Element.LIST: {
// we cast the element to a List
List list = (List) element;
if (list.isAlignindent()) {
list.normalizeIndentation();
}
// we adjust the document
indentation.listIndentLeft += list.getIndentationLeft();
indentation.indentRight += list.getIndentationRight();
// we process the items in the list
element.process(this);
// some parameters are set back to normal again
indentation.listIndentLeft -= list.getIndentationLeft();
indentation.indentRight -= list.getIndentationRight();
carriageReturn();
break;
}
case Element.LISTITEM: {
leadingCount++;
// we cast the element to a ListItem
ListItem listItem = (ListItem) element;
addSpacing(listItem.spacingBefore(), leading, listItem.getFont());
// we adjust the document
alignment = listItem.getAlignment();
indentation.listIndentLeft += listItem.getIndentationLeft();
indentation.indentRight += listItem.getIndentationRight();
leading = listItem.getTotalLeading();
carriageReturn();
// we prepare the current line to be able to show us the listsymbol
line.setListItem(listItem);
// we process the item
element.process(this);
addSpacing(listItem.spacingAfter(), listItem.getTotalLeading(), listItem.getFont());
// if the last line is justified, it should be aligned to the left
if (line.hasToBeJustified()) {
line.resetAlignment();
}
// some parameters are set back to normal again
carriageReturn();
indentation.listIndentLeft -= listItem.getIndentationLeft();
indentation.indentRight -= listItem.getIndentationRight();
leadingCount--;
break;
}
case Element.RECTANGLE: {
Rectangle rectangle = (Rectangle) element;
graphics.rectangle(rectangle);
pageEmpty = false;
break;
}
case Element.PTABLE: {
PdfPTable ptable = (PdfPTable)element;
if (ptable.size() < = ptable.getHeaderRows())
break; //nothing to do
// before every table, we add a new line and flush all lines
ensureNewLine();
flushLines();
addPTable(ptable);
pageEmpty = false;
newLine();
break;
}
case Element.MULTI_COLUMN_TEXT: {
ensureNewLine();
flushLines();
MultiColumnText multiText = (MultiColumnText) element;
float height = multiText.write(writer.getDirectContent(), this, indentTop() - currentHeight);
currentHeight += height;
text.moveText(0, -1f* height);
pageEmpty = false;
break;
}
case Element.TABLE : {
if (element instanceof SimpleTable) {
PdfPTable ptable = ((SimpleTable)element).createPdfPTable();
if (ptable.size() < = ptable.getHeaderRows())
break; //nothing to do
// before every table, we add a new line and flush all lines
ensureNewLine();
flushLines();
addPTable(ptable);
pageEmpty = false;
break;
} else if (element instanceof Table) {
try {
PdfPTable ptable = ((Table)element).createPdfPTable();
if (ptable.size() < = ptable.getHeaderRows())
break; //nothing to do
// before every table, we add a new line and flush all lines
ensureNewLine();
flushLines();
addPTable(ptable);
pageEmpty = false;
break;
}
catch(BadElementException bee) {
// constructing the PdfTable
// Before the table, add a blank line using offset or default leading
float offset = ((Table)element).getOffset();
if (Float.isNaN(offset))
offset = leading;
carriageReturn();
lines.add(new PdfLine(indentLeft(), indentRight(), alignment, offset));
currentHeight += offset;
addPdfTable((Table)element);
}
} else {
return false;
}
break;
}
case Element.JPEG:
case Element.JPEG2000:
case Element.IMGRAW:
case Element.IMGTEMPLATE: {
//carriageReturn(); suggestion by Marc Campforts
add((Image) element);
break;
}
case Element.YMARK: {
DrawInterface zh = (DrawInterface)element;
zh.draw(graphics, indentLeft(), indentBottom(), indentRight(), indentTop(), indentTop() - currentHeight - (leadingCount > 0 ? leading : 0));
pageEmpty = false;
break;
}
case Element.MARKED: {
MarkedObject mo;
if (element instanceof MarkedSection) {
mo = ((MarkedSection)element).getTitle();
if (mo != null) {
mo.process(this);
}
}
mo = (MarkedObject)element;
mo.process(this);
break;
}
default:
return false;
}
lastElementType = element.type();
return true;
}
catch(Exception e) {
throw new DocumentException(e);
}
}
Signals that an Element was added to the Document. |
protected void add(Image image) throws PdfException, DocumentException {
if (image.hasAbsoluteY()) {
graphics.addImage(image);
pageEmpty = false;
return;
}
// if there isn't enough room for the image on this page, save it for the next page
if (currentHeight != 0 && indentTop() - currentHeight - image.getScaledHeight() < indentBottom()) {
if (!strictImageSequence && imageWait == null) {
imageWait = image;
return;
}
newPage();
if (currentHeight != 0 && indentTop() - currentHeight - image.getScaledHeight() < indentBottom()) {
imageWait = image;
return;
}
}
pageEmpty = false;
// avoid endless loops
if (image == imageWait)
imageWait = null;
boolean textwrap = (image.getAlignment() & Image.TEXTWRAP) == Image.TEXTWRAP
&& !((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE);
boolean underlying = (image.getAlignment() & Image.UNDERLYING) == Image.UNDERLYING;
float diff = leading / 2;
if (textwrap) {
diff += leading;
}
float lowerleft = indentTop() - currentHeight - image.getScaledHeight() -diff;
float mt[] = image.matrix();
float startPosition = indentLeft() - mt[4];
if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) startPosition = indentRight() - image.getScaledWidth() - mt[4];
if ((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE) startPosition = indentLeft() + ((indentRight() - indentLeft() - image.getScaledWidth()) / 2) - mt[4];
if (image.hasAbsoluteX()) startPosition = image.getAbsoluteX();
if (textwrap) {
if (imageEnd < 0 || imageEnd < currentHeight + image.getScaledHeight() + diff) {
imageEnd = currentHeight + image.getScaledHeight() + diff;
}
if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) {
// indentation suggested by Pelikan Stephan
indentation.imageIndentRight += image.getScaledWidth() + image.getIndentationLeft();
}
else {
// indentation suggested by Pelikan Stephan
indentation.imageIndentLeft += image.getScaledWidth() + image.getIndentationRight();
}
}
else {
if ((image.getAlignment() & Image.RIGHT) == Image.RIGHT) startPosition -= image.getIndentationRight();
else if ((image.getAlignment() & Image.MIDDLE) == Image.MIDDLE) startPosition += image.getIndentationLeft() - image.getIndentationRight();
else startPosition += image.getIndentationLeft();
}
graphics.addImage(image, mt[0], mt[1], mt[2], mt[3], startPosition, lowerleft - mt[5]);
if (!(textwrap || underlying)) {
currentHeight += image.getScaledHeight() + diff;
flushLines();
text.moveText(0, - (image.getScaledHeight() + diff));
newLine();
}
}
Adds an image to the document. |
void addAdditionalAction(PdfName actionType,
PdfAction action) {
if (additionalActions == null) {
additionalActions = new PdfDictionary();
}
if (action == null)
additionalActions.remove(actionType);
else
additionalActions.put(actionType, action);
if (additionalActions.size() == 0)
additionalActions = null;
}
|
void addAnnotation(PdfAnnotation annot) {
pageEmpty = false;
annotationsImp.addAnnotation(annot);
}
|
void addCalculationOrder(PdfFormField formField) {
annotationsImp.addCalculationOrder(formField);
}
|
void addFileAttachment(String description,
PdfFileSpecification fs) throws IOException {
if (description == null) {
PdfString desc = (PdfString)fs.get(PdfName.DESC);
if (desc == null) {
description = "";
}
else {
description = PdfEncodings.convertToString(desc.getBytes(), null);
}
}
fs.addDescription(description, true);
if (description.length() == 0)
description = "Unnamed";
String fn = PdfEncodings.convertToString(new PdfString(description, PdfObject.TEXT_UNICODE).getBytes(), null);
int k = 0;
while (documentFileAttachment.containsKey(fn)) {
++k;
fn = PdfEncodings.convertToString(new PdfString(description + " " + k, PdfObject.TEXT_UNICODE).getBytes(), null);
}
documentFileAttachment.put(fn, fs.getReference());
}
|
void addJavaScript(PdfAction js) {
if (js.get(PdfName.JS) == null)
throw new RuntimeException("Only JavaScript actions are allowed.");
try {
documentLevelJS.put(SIXTEEN_DIGITS.format(jsCounter++), writer.addToBody(js).getIndirectReference());
}
catch (IOException e) {
throw new ExceptionConverter(e);
}
}
|
void addJavaScript(String name,
PdfAction js) {
if (js.get(PdfName.JS) == null)
throw new RuntimeException("Only JavaScript actions are allowed.");
try {
documentLevelJS.put(name, writer.addToBody(js).getIndirectReference());
}
catch (IOException e) {
throw new ExceptionConverter(e);
}
}
|
void addOutline(PdfOutline outline,
String name) {
localDestination(name, outline.getPdfDestination());
}
Adds a named outline to the document . |
void addPTable(PdfPTable ptable) throws DocumentException {
ColumnText ct = new ColumnText(writer.getDirectContent());
if (currentHeight > 0) {
Paragraph p = new Paragraph();
p.setLeading(0);
ct.addElement(p);
// if the table prefers to be on a single page, and it wouldn't
//fit on the current page, start a new page.
if (ptable.getKeepTogether() && !fitsPage(ptable, 0f)) {
newPage();
}
}
ct.addElement(ptable);
boolean he = ptable.isHeadersInEvent();
ptable.setHeadersInEvent(true);
int loop = 0;
while (true) {
ct.setSimpleColumn(indentLeft(), indentBottom(), indentRight(), indentTop() - currentHeight);
int status = ct.go();
if ((status & ColumnText.NO_MORE_TEXT) != 0) {
text.moveText(0, ct.getYLine() - indentTop() + currentHeight);
currentHeight = indentTop() - ct.getYLine();
break;
}
if (indentTop() - currentHeight == ct.getYLine())
++loop;
else
loop = 0;
if (loop == 3) {
add(new Paragraph("ERROR: Infinite table loop"));
break;
}
newPage();
}
ptable.setHeadersInEvent(he);
}
Adds a PdfPTable to the document. |
protected void addSpacing(float extraspace,
float oldleading,
Font f) {
if (extraspace == 0) return;
if (pageEmpty) return;
if (currentHeight + line.height() + leading > indentTop() - indentBottom()) return;
leading = extraspace;
carriageReturn();
if (f.isUnderlined() || f.isStrikethru()) {
f = new Font(f);
int style = f.getStyle();
style &= ~Font.UNDERLINE;
style &= ~Font.STRIKETHRU;
f.setStyle(Font.UNDEFINED);
f.setStyle(style);
}
Chunk space = new Chunk(" ", f);
space.process(this);
carriageReturn();
leading = oldleading;
}
Adds extra space.
This method should probably be rewritten. |
void addViewerPreference(PdfName key,
PdfObject value) {
this.viewerPreferences.addViewerPreference(key, value);
}
|
public void addWriter(PdfWriter writer) throws DocumentException {
if (this.writer == null) {
this.writer = writer;
annotationsImp = new PdfAnnotationsImp(writer);
return;
}
throw new DocumentException("You can only add a writer to a PdfDocument once.");
}
Adds a PdfWriter to the PdfDocument. |
protected void analyzeRow(ArrayList rows,
PdfDocument.RenderingContext ctx) {
ctx.maxCellBottom = indentBottom();
// determine whether row(index) is in a rowspan
int rowIndex = 0;
ArrayList row = (ArrayList) rows.get(rowIndex);
int maxRowspan = 1;
Iterator iterator = row.iterator();
while (iterator.hasNext()) {
PdfCell cell = (PdfCell) iterator.next();
maxRowspan = Math.max(ctx.currentRowspan(cell), maxRowspan);
}
rowIndex += maxRowspan;
boolean useTop = true;
if (rowIndex == rows.size()) {
rowIndex = rows.size() - 1;
useTop = false;
}
if (rowIndex < 0 || rowIndex >= rows.size()) return;
row = (ArrayList) rows.get(rowIndex);
iterator = row.iterator();
while (iterator.hasNext()) {
PdfCell cell = (PdfCell) iterator.next();
Rectangle cellRect = cell.rectangle(ctx.pagetop, indentBottom());
if (useTop) {
ctx.maxCellBottom = Math.max(ctx.maxCellBottom, cellRect.getTop());
} else {
if (ctx.currentRowspan(cell) == 1) {
ctx.maxCellBottom = Math.max(ctx.maxCellBottom, cellRect.getBottom());
}
}
}
}
|
float bottom(Table table) {
// constructing a PdfTable
PdfTable tmp = new PdfTable(table, indentLeft(), indentRight(), indentTop() - currentHeight);
return tmp.getBottom();
}
Returns the bottomvalue of a Table if it were added to this document. |
void calculateOutlineCount() {
if (rootOutline.getKids().size() == 0)
return;
traverseOutlineCount(rootOutline);
}
Updates the count in the outlines. |
protected void carriageReturn() {
// the arraylist with lines may not be null
if (lines == null) {
lines = new ArrayList();
}
// If the current line is not null
if (line != null) {
// we check if the end of the page is reached (bugfix by Francois Gravel)
if (currentHeight + line.height() + leading < indentTop() - indentBottom()) {
// if so nonempty lines are added and the height is augmented
if (line.size() > 0) {
currentHeight += line.height();
lines.add(line);
pageEmpty = false;
}
}
// if the end of the line is reached, we start a new page
else {
newPage();
}
}
if (imageEnd > -1 && currentHeight > imageEnd) {
imageEnd = -1;
indentation.imageIndentRight = 0;
indentation.imageIndentLeft = 0;
}
// a new current line is constructed
line = new PdfLine(indentLeft(), indentRight(), alignment, leading);
}
If the current line is not empty or null, it is added to the arraylist
of lines and a new empty line is added. |
public void clearTextWrap() {
float tmpHeight = imageEnd - currentHeight;
if (line != null) {
tmpHeight += line.height();
}
if ((imageEnd > -1) && (tmpHeight > 0)) {
carriageReturn();
currentHeight += tmpHeight;
}
}
Method added by Pelikan Stephan |
public void close() {
if (close) {
return;
}
try {
boolean wasImage = (imageWait != null);
newPage();
if (imageWait != null || wasImage) newPage();
if (annotationsImp.hasUnusedAnnotations())
throw new RuntimeException("Not all annotations could be added to the document (the document doesn't have enough pages).");
PdfPageEvent pageEvent = writer.getPageEvent();
if (pageEvent != null)
pageEvent.onCloseDocument(writer, this);
super.close();
writer.addLocalDestinations(localDestinations);
calculateOutlineCount();
writeOutlines();
}
catch(Exception e) {
throw new ExceptionConverter(e);
}
writer.close();
}
Closes the document.
Once all the content has been written in the body, you have to close
the body. After that nothing can be written to the body anymore. |
protected void consumeRowspan(ArrayList row,
PdfDocument.RenderingContext ctx) {
Iterator iterator = row.iterator();
while (iterator.hasNext()) {
PdfCell c = (PdfCell) iterator.next();
ctx.consumeRowspan(c);
}
}
|
protected void doFooter() throws DocumentException {
if (footer == null) return;
// Begin added by Edgar Leonardo Prieto Perilla
// Avoid footer indentation
float tmpIndentLeft = indentation.indentLeft;
float tmpIndentRight = indentation.indentRight;
// Begin added: Bonf (Marc Schneider) 2003-07-29
float tmpListIndentLeft = indentation.listIndentLeft;
float tmpImageIndentLeft = indentation.imageIndentLeft;
float tmpImageIndentRight = indentation.imageIndentRight;
// End added: Bonf (Marc Schneider) 2003-07-29
indentation.indentLeft = indentation.indentRight = 0;
// Begin added: Bonf (Marc Schneider) 2003-07-29
indentation.listIndentLeft = 0;
indentation.imageIndentLeft = 0;
indentation.imageIndentRight = 0;
// End added: Bonf (Marc Schneider) 2003-07-29
// End Added by Edgar Leonardo Prieto Perilla
footer.setPageNumber(pageN);
leading = footer.paragraph().getTotalLeading();
add(footer.paragraph());
// adding the footer limits the height
indentation.indentBottom = currentHeight;
text.moveText(left(), indentBottom());
flushLines();
text.moveText(-left(), -bottom());
footer.setTop(bottom(currentHeight));
footer.setBottom(bottom() - (0.75f * leading));
footer.setLeft(left());
footer.setRight(right());
graphics.rectangle(footer);
indentation.indentBottom = currentHeight + leading * 2;
currentHeight = 0;
// Begin added by Edgar Leonardo Prieto Perilla
indentation.indentLeft = tmpIndentLeft;
indentation.indentRight = tmpIndentRight;
// Begin added: Bonf (Marc Schneider) 2003-07-29
indentation.listIndentLeft = tmpListIndentLeft;
indentation.imageIndentLeft = tmpImageIndentLeft;
indentation.imageIndentRight = tmpImageIndentRight;
// End added: Bonf (Marc Schneider) 2003-07-29
// End added by Edgar Leonardo Prieto Perilla
}
|
protected void doHeader() throws DocumentException {
// if there is a header, the header = added
if (header == null) return;
// Begin added by Edgar Leonardo Prieto Perilla
// Avoid header indentation
float tmpIndentLeft = indentation.indentLeft;
float tmpIndentRight = indentation.indentRight;
// Begin added: Bonf (Marc Schneider) 2003-07-29
float tmpListIndentLeft = indentation.listIndentLeft;
float tmpImageIndentLeft = indentation.imageIndentLeft;
float tmpImageIndentRight = indentation.imageIndentRight;
// End added: Bonf (Marc Schneider) 2003-07-29
indentation.indentLeft = indentation.indentRight = 0;
// Added: Bonf
indentation.listIndentLeft = 0;
indentation.imageIndentLeft = 0;
indentation.imageIndentRight = 0;
// End added: Bonf
// Begin added by Edgar Leonardo Prieto Perilla
header.setPageNumber(pageN);
leading = header.paragraph().getTotalLeading();
text.moveText(0, leading);
add(header.paragraph());
newLine();
indentation.indentTop = currentHeight - leading;
header.setTop(top() + leading);
header.setBottom(indentTop() + leading * 2 / 3);
header.setLeft(left());
header.setRight(right());
graphics.rectangle(header);
flushLines();
currentHeight = 0;
// Begin added by Edgar Leonardo Prieto Perilla
// Restore indentation
indentation.indentLeft = tmpIndentLeft;
indentation.indentRight = tmpIndentRight;
// Begin added: Bonf (Marc Schneider) 2003-07-29
indentation.listIndentLeft = tmpListIndentLeft;
indentation.imageIndentLeft = tmpImageIndentLeft;
indentation.imageIndentRight = tmpImageIndentRight;
// End added: Bonf (Marc Schneider) 2003-07-29
// End Added by Edgar Leonardo Prieto Perilla
}
|
protected void ensureNewLine() {
try {
if ((lastElementType == Element.PHRASE) ||
(lastElementType == Element.CHUNK)) {
newLine();
flushLines();
}
} catch (DocumentException ex) {
throw new ExceptionConverter(ex);
}
}
Ensures that a new line has been started. |
protected ArrayList extractRows(ArrayList cells,
PdfDocument.RenderingContext ctx) {
PdfCell cell;
PdfCell previousCell = null;
ArrayList rows = new ArrayList();
java.util.List rowCells = new ArrayList();
Iterator iterator = cells.iterator();
while (iterator.hasNext()) {
cell = (PdfCell) iterator.next();
boolean isAdded = false;
boolean isEndOfRow = !iterator.hasNext();
boolean isCurrentCellPartOfRow = !iterator.hasNext();
if (previousCell != null) {
if (cell.getLeft() < = previousCell.getLeft()) {
isEndOfRow = true;
isCurrentCellPartOfRow = false;
}
}
if (isCurrentCellPartOfRow) {
rowCells.add(cell);
isAdded = true;
}
if (isEndOfRow) {
if (!rowCells.isEmpty()) {
// add to rowlist
rows.add(rowCells);
}
// start a new list for next line
rowCells = new ArrayList();
}
if (!isAdded) {
rowCells.add(cell);
}
previousCell = cell;
}
if (!rowCells.isEmpty()) {
rows.add(rowCells);
}
// fill row information with rowspan cells to get complete "scan lines"
for (int i = rows.size() - 1; i >= 0; i--) {
ArrayList row = (ArrayList) rows.get(i);
// iterator through row
for (int j = 0; j < row.size(); j++) {
PdfCell c = (PdfCell) row.get(j);
int rowspan = c.rowspan();
// fill in missing rowspan cells to complete "scan line"
for (int k = 1; k < rowspan && rows.size() < i+k; k++) {
ArrayList spannedRow = ((ArrayList) rows.get(i + k));
if (spannedRow.size() > j)
spannedRow.add(j, c);
}
}
}
return rows;
}
|
boolean fitsPage(PdfPTable table,
float margin) {
if (!table.isLockedWidth()) {
float totalWidth = (indentRight() - indentLeft()) * table.getWidthPercentage() / 100;
table.setTotalWidth(totalWidth);
}
// ensuring that a new line has been started.
ensureNewLine();
return table.getTotalHeight() < = indentTop() - currentHeight - indentBottom() - margin;
}
Checks if a PdfPTable fits the current page of the PdfDocument. |
protected float flushLines() throws DocumentException {
// checks if the ArrayList with the lines is not null
if (lines == null) {
return 0;
}
// checks if a new Line has to be made.
if (line != null && line.size() > 0) {
lines.add(line);
line = new PdfLine(indentLeft(), indentRight(), alignment, leading);
}
// checks if the ArrayList with the lines is empty
if (lines.isEmpty()) {
return 0;
}
// initialization of some parameters
Object currentValues[] = new Object[2];
PdfFont currentFont = null;
float displacement = 0;
PdfLine l;
Float lastBaseFactor = new Float(0);
currentValues[1] = lastBaseFactor;
// looping over all the lines
for (Iterator i = lines.iterator(); i.hasNext(); ) {
// this is a line in the loop
l = (PdfLine) i.next();
float moveTextX = l.indentLeft() - indentLeft() + indentation.indentLeft + indentation.listIndentLeft + indentation.sectionIndentLeft;
text.moveText(moveTextX, -l.height());
// is the line preceded by a symbol?
if (l.listSymbol() != null) {
ColumnText.showTextAligned(graphics, Element.ALIGN_LEFT, new Phrase(l.listSymbol()), text.getXTLM() - l.listIndent(), text.getYTLM(), 0);
}
currentValues[0] = currentFont;
writeLineToContent(l, text, graphics, currentValues, writer.getSpaceCharRatio());
currentFont = (PdfFont)currentValues[0];
displacement += l.height();
text.moveText(-moveTextX, 0);
}
lines = new ArrayList();
return displacement;
}
Writes all the lines to the text-object. |
PdfAcroForm getAcroForm() {
return annotationsImp.getAcroForm();
}
Gets the AcroForm object. |
Rectangle getBoxSize(String boxName) {
PdfRectangle r = (PdfRectangle)thisBoxSize.get(boxName);
if (r != null) return r.getRectangle();
return null;
}
Gives the size of a trim, art, crop or bleed box, or null if not defined. |
PdfDocument.PdfCatalog getCatalog(PdfIndirectReference pages) {
PdfCatalog catalog = new PdfCatalog(pages, writer);
// [C1] outlines
if (rootOutline.getKids().size() > 0) {
catalog.put(PdfName.PAGEMODE, PdfName.USEOUTLINES);
catalog.put(PdfName.OUTLINES, rootOutline.indirectReference());
}
// [C2] version
writer.getPdfVersion().addToCatalog(catalog);
// [C3] preferences
viewerPreferences.addToCatalog(catalog);
// [C4] pagelabels
if (pageLabels != null) {
catalog.put(PdfName.PAGELABELS, pageLabels.getDictionary(writer));
}
// [C5] named objects
catalog.addNames(localDestinations, getDocumentLevelJS(), documentFileAttachment, writer);
// [C6] actions
if (openActionName != null) {
PdfAction action = getLocalGotoAction(openActionName);
catalog.setOpenAction(action);
}
else if (openActionAction != null)
catalog.setOpenAction(openActionAction);
if (additionalActions != null) {
catalog.setAdditionalActions(additionalActions);
}
// [C7] portable collections
if (collection != null) {
catalog.put(PdfName.COLLECTION, collection);
}
// [C8] AcroForm
if (annotationsImp.hasValidAcroForm()) {
try {
catalog.put(PdfName.ACROFORM, writer.addToBody(annotationsImp.getAcroForm()).getIndirectReference());
}
catch (IOException e) {
throw new ExceptionConverter(e);
}
}
return catalog;
}
Gets the PdfCatalog-object. |
HashMap getDocumentFileAttachment() {
return documentFileAttachment;
}
|
HashMap getDocumentLevelJS() {
return documentLevelJS;
}
|
PdfDocument.PdfInfo getInfo() {
return info;
}
|
public float getLeading() {
return leading;
}
Getter for the current leading. |
PdfAction getLocalGotoAction(String name) {
PdfAction action;
Object obj[] = (Object[])localDestinations.get(name);
if (obj == null)
obj = new Object[3];
if (obj[0] == null) {
if (obj[1] == null) {
obj[1] = writer.getPdfIndirectReference();
}
action = new PdfAction((PdfIndirectReference)obj[1]);
obj[0] = action;
localDestinations.put(name, obj);
}
else {
action = (PdfAction)obj[0];
}
return action;
}
|
int getMarkPoint() {
return markPoint;
}
|
PageResources getPageResources() {
return pageResources;
}
|
public PdfOutline getRootOutline() {
return rootOutline;
}
Gets the root outline. All the outlines must be created with a parent.
The first level is created with this outline. |
public float getVerticalPosition(boolean ensureNewLine) {
// ensuring that a new line has been started.
if (ensureNewLine) {
ensureNewLine();
}
return top() - currentHeight - indentation.indentTop;
}
Gets the current vertical page position. |
void incMarkPoint() {
++markPoint;
}
|
float indentBottom() {
return bottom(indentation.indentBottom);
}
Gets the indentation on the bottom side. |
protected float indentLeft() {
return left(indentation.indentLeft + indentation.listIndentLeft + indentation.imageIndentLeft + indentation.sectionIndentLeft);
}
Gets the indentation on the left side. |
protected float indentRight() {
return right(indentation.indentRight + indentation.sectionIndentRight + indentation.imageIndentRight);
}
Gets the indentation on the right side. |
protected float indentTop() {
return top(indentation.indentTop);
}
Gets the indentation on the top side. |
protected void initPage() throws DocumentException {
// the pagenumber is incremented
pageN++;
// initialization of some page objects
annotationsImp.resetAnnotations();
pageResources = new PageResources();
writer.resetContent();
graphics = new PdfContentByte(writer);
text = new PdfContentByte(writer);
text.reset();
text.beginText();
textEmptySize = text.size();
markPoint = 0;
setNewPageSizeAndMargins();
imageEnd = -1;
indentation.imageIndentRight = 0;
indentation.imageIndentLeft = 0;
indentation.indentBottom = 0;
indentation.indentTop = 0;
currentHeight = 0;
// backgroundcolors, etc...
thisBoxSize = new HashMap(boxSize);
if (pageSize.getBackgroundColor() != null
|| pageSize.hasBorders()
|| pageSize.getBorderColor() != null) {
add(pageSize);
}
float oldleading = leading;
int oldAlignment = alignment;
// if there is a footer, the footer is added
doFooter();
// we move to the left/top position of the page
text.moveText(left(), top());
doHeader();
pageEmpty = true;
// if there is an image waiting to be drawn, draw it
try {
if (imageWait != null) {
add(imageWait);
imageWait = null;
}
}
catch(Exception e) {
throw new ExceptionConverter(e);
}
leading = oldleading;
alignment = oldAlignment;
carriageReturn();
PdfPageEvent pageEvent = writer.getPageEvent();
if (pageEvent != null) {
if (firstPageEvent) {
pageEvent.onOpenDocument(writer, this);
}
pageEvent.onStartPage(writer, this);
}
firstPageEvent = false;
}
Initializes a page.
If the footer/header is set, it is printed. |
boolean isStrictImageSequence() {
return this.strictImageSequence;
}
Getter for property strictImageSequence. |
boolean localDestination(String name,
PdfDestination destination) {
Object obj[] = (Object[])localDestinations.get(name);
if (obj == null)
obj = new Object[3];
if (obj[2] != null)
return false;
obj[2] = destination;
localDestinations.put(name, obj);
destination.addPage(writer.getCurrentPage());
return true;
}
The local destination to where a local goto with the same
name will jump to. |
void localGoto(String name,
float llx,
float lly,
float urx,
float ury) {
PdfAction action = getLocalGotoAction(name);
annotationsImp.addPlainAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action));
}
Implements a link to other part of the document. The jump will
be made to a local destination with the same name, that must exist. |
protected boolean mayBeRemoved(ArrayList row) {
Iterator iterator = row.iterator();
boolean mayBeRemoved = true;
while (iterator.hasNext()) {
PdfCell cell = (PdfCell) iterator.next();
mayBeRemoved &= cell.mayBeRemoved();
}
return mayBeRemoved;
}
|
protected void newLine() throws DocumentException {
lastElementType = -1;
carriageReturn();
if (lines != null && !lines.isEmpty()) {
lines.add(line);
currentHeight += line.height();
}
line = new PdfLine(indentLeft(), indentRight(), alignment, leading);
}
Adds the current line to the list of lines and also adds an empty line. |
public boolean newPage() {
lastElementType = -1;
if (writer == null || (writer.getDirectContent().size() == 0 && writer.getDirectContentUnder().size() == 0 && (pageEmpty || writer.isPaused()))) {
setNewPageSizeAndMargins();
return false;
}
if (!open || close) {
throw new RuntimeException("The document isn't open.");
}
PdfPageEvent pageEvent = writer.getPageEvent();
if (pageEvent != null)
pageEvent.onEndPage(writer, this);
//Added to inform any listeners that we are moving to a new page (added by David Freels)
super.newPage();
// the following 2 lines were added by Pelikan Stephan
indentation.imageIndentLeft = 0;
indentation.imageIndentRight = 0;
try {
// we flush the arraylist with recently written lines
flushLines();
// we prepare the elements of the page dictionary
// [U1] page size and rotation
int rotation = pageSize.getRotation();
// [C10]
if (writer.isPdfX()) {
if (thisBoxSize.containsKey("art") && thisBoxSize.containsKey("trim"))
throw new PdfXConformanceException("Only one of ArtBox or TrimBox can exist in the page.");
if (!thisBoxSize.containsKey("art") && !thisBoxSize.containsKey("trim")) {
if (thisBoxSize.containsKey("crop"))
thisBoxSize.put("trim", thisBoxSize.get("crop"));
else
thisBoxSize.put("trim", new PdfRectangle(pageSize, pageSize.getRotation()));
}
}
// [M1]
pageResources.addDefaultColorDiff(writer.getDefaultColorspace());
if (writer.isRgbTransparencyBlending()) {
PdfDictionary dcs = new PdfDictionary();
dcs.put(PdfName.CS, PdfName.DEVICERGB);
pageResources.addDefaultColorDiff(dcs);
}
PdfDictionary resources = pageResources.getResources();
// we create the page dictionary
PdfPage page = new PdfPage(new PdfRectangle(pageSize, rotation), thisBoxSize, resources, rotation);
// we complete the page dictionary
// [C9] if there is XMP data to add: add it
if (xmpMetadata != null) {
PdfStream xmp = new PdfStream(xmpMetadata);
xmp.put(PdfName.TYPE, PdfName.METADATA);
xmp.put(PdfName.SUBTYPE, PdfName.XML);
PdfEncryption crypto = writer.getEncryption();
if (crypto != null && !crypto.isMetadataEncrypted()) {
PdfArray ar = new PdfArray();
ar.add(PdfName.CRYPT);
xmp.put(PdfName.FILTER, ar);
}
page.put(PdfName.METADATA, writer.addToBody(xmp).getIndirectReference());
}
// [U3] page actions: transition, duration, additional actions
if (this.transition!=null) {
page.put(PdfName.TRANS, this.transition.getTransitionDictionary());
transition = null;
}
if (this.duration >0) {
page.put(PdfName.DUR,new PdfNumber(this.duration));
duration = 0;
}
if (pageAA != null) {
page.put(PdfName.AA, writer.addToBody(pageAA).getIndirectReference());
pageAA = null;
}
// [U4] we add the thumbs
if (thumb != null) {
page.put(PdfName.THUMB, thumb);
thumb = null;
}
// [U8] we check if the userunit is defined
if (writer.getUserunit() > 0f) {
page.put(PdfName.USERUNIT, new PdfNumber(writer.getUserunit()));
}
// [C5] and [C8] we add the annotations
if (annotationsImp.hasUnusedAnnotations()) {
PdfArray array = annotationsImp.rotateAnnotations(writer, pageSize);
if (array.size() != 0)
page.put(PdfName.ANNOTS, array);
}
// [F12] we add tag info
if (writer.isTagged())
page.put(PdfName.STRUCTPARENTS, new PdfNumber(writer.getCurrentPageNumber() - 1));
if (text.size() > textEmptySize)
text.endText();
else
text = null;
writer.add(page, new PdfContents(writer.getDirectContentUnder(), graphics, text, writer.getDirectContent(), pageSize));
// we initialize the new page
initPage();
}
catch(DocumentException de) {
// maybe this never happens, but it's better to check.
throw new ExceptionConverter(de);
}
catch (IOException ioe) {
throw new ExceptionConverter(ioe);
}
return true;
}
Makes a new page and sends it to the PdfWriter. |
public void open() {
if (!open) {
super.open();
writer.open();
rootOutline = new PdfOutline(writer);
currentOutline = rootOutline;
}
try {
initPage();
}
catch(DocumentException de) {
throw new ExceptionConverter(de);
}
}
|
void outlineTree(PdfOutline outline) throws IOException {
outline.setIndirectReference(writer.getPdfIndirectReference());
if (outline.parent() != null)
outline.put(PdfName.PARENT, outline.parent().indirectReference());
ArrayList kids = outline.getKids();
int size = kids.size();
for (int k = 0; k < size; ++k)
outlineTree((PdfOutline)kids.get(k));
for (int k = 0; k < size; ++k) {
if (k > 0)
((PdfOutline)kids.get(k)).put(PdfName.PREV, ((PdfOutline)kids.get(k - 1)).indirectReference());
if (k < size - 1)
((PdfOutline)kids.get(k)).put(PdfName.NEXT, ((PdfOutline)kids.get(k + 1)).indirectReference());
}
if (size > 0) {
outline.put(PdfName.FIRST, ((PdfOutline)kids.get(0)).indirectReference());
outline.put(PdfName.LAST, ((PdfOutline)kids.get(size - 1)).indirectReference());
}
for (int k = 0; k < size; ++k) {
PdfOutline kid = (PdfOutline)kids.get(k);
writer.addToBody(kid, kid.indirectReference());
}
}
Recursive method used to write outlines. |
void remoteGoto(String filename,
String name,
float llx,
float lly,
float urx,
float ury) {
annotationsImp.addPlainAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, name)));
}
Implements a link to another document. |
void remoteGoto(String filename,
int page,
float llx,
float lly,
float urx,
float ury) {
addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, page)));
}
Implements a link to another document. |
protected void renderCells(PdfDocument.RenderingContext ctx,
List cells,
boolean hasToFit) throws DocumentException {
PdfCell cell;
Iterator iterator;
if (hasToFit) {
iterator = cells.iterator();
while (iterator.hasNext()) {
cell = (PdfCell) iterator.next();
if (!cell.isHeader()) {
if (cell.getBottom() < indentBottom()) return;
}
}
}
iterator = cells.iterator();
while (iterator.hasNext()) {
cell = (PdfCell) iterator.next();
if (!ctx.isCellRenderedOnPage(cell, getPageNumber())) {
float correction = 0;
if (ctx.numCellRendered(cell) >= 1) {
correction = 1.0f;
}
lines = cell.getLines(ctx.pagetop, indentBottom() - correction);
// if there is still text to render we render it
if (lines != null && !lines.isEmpty()) {
// we write the text
float cellTop = cell.getTop(ctx.pagetop - ctx.oldHeight);
text.moveText(0, cellTop);
float cellDisplacement = flushLines() - cellTop;
text.moveText(0, cellDisplacement);
if (ctx.oldHeight + cellDisplacement > currentHeight) {
currentHeight = ctx.oldHeight + cellDisplacement;
}
ctx.cellRendered(cell, getPageNumber());
}
float indentBottom = Math.max(cell.getBottom(), indentBottom());
Rectangle tableRect = ctx.table.rectangle(ctx.pagetop, indentBottom());
indentBottom = Math.max(tableRect.getBottom(), indentBottom);
// we paint the borders of the cells
Rectangle cellRect = cell.rectangle(tableRect.getTop(), indentBottom);
//cellRect.setBottom(cellRect.bottom());
if (cellRect.getHeight() > 0) {
ctx.lostTableBottom = indentBottom;
ctx.cellGraphics.rectangle(cellRect);
}
// and additional graphics
ArrayList images = cell.getImages(ctx.pagetop, indentBottom());
for (Iterator i = images.iterator(); i.hasNext();) {
Image image = (Image) i.next();
graphics.addImage(image);
}
}
}
}
|
public void resetFooter() {
if (writer != null && writer.isPaused()) {
return;
}
super.resetFooter();
}
Resets the footer of this document. |
public void resetHeader() {
if (writer != null && writer.isPaused()) {
return;
}
super.resetHeader();
}
Resets the header of this document. |
public void resetPageCount() {
if (writer != null && writer.isPaused()) {
return;
}
super.resetPageCount();
}
Sets the page number to 0. |
void setAction(PdfAction action,
float llx,
float lly,
float urx,
float ury) {
addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action));
}
Implements an action in an area. |
void setBoxSize(String boxName,
Rectangle size) {
if (size == null)
boxSize.remove(boxName);
else
boxSize.put(boxName, new PdfRectangle(size));
}
|
public void setCollection(PdfCollection collection) {
this.collection = collection;
}
Sets the collection dictionary. |
void setCropBoxSize(Rectangle crop) {
setBoxSize("crop", crop);
}
|
void setDuration(int seconds) {
if (seconds > 0)
this.duration=seconds;
else
this.duration=-1;
}
Sets the display duration for the page (for presentations) |
public void setFooter(HeaderFooter footer) {
if (writer != null && writer.isPaused()) {
return;
}
super.setFooter(footer);
}
Changes the footer of this document. |
public void setHeader(HeaderFooter header) {
if (writer != null && writer.isPaused()) {
return;
}
super.setHeader(header);
}
Changes the header of this document. |
public boolean setMarginMirroring(boolean MarginMirroring) {
if (writer != null && writer.isPaused()) {
return false;
}
return super.setMarginMirroring(MarginMirroring);
}
|
public boolean setMargins(float marginLeft,
float marginRight,
float marginTop,
float marginBottom) {
if (writer != null && writer.isPaused()) {
return false;
}
nextMarginLeft = marginLeft;
nextMarginRight = marginRight;
nextMarginTop = marginTop;
nextMarginBottom = marginBottom;
return true;
}
|
protected void setNewPageSizeAndMargins() {
pageSize = nextPageSize;
if (marginMirroring && (getPageNumber() & 1) == 0) {
marginRight = nextMarginLeft;
marginLeft = nextMarginRight;
}
else {
marginLeft = nextMarginLeft;
marginRight = nextMarginRight;
}
marginTop = nextMarginTop;
marginBottom = nextMarginBottom;
}
|
void setOpenAction(String name) {
openActionName = name;
openActionAction = null;
}
|
void setOpenAction(PdfAction action) {
openActionAction = action;
openActionName = null;
}
|
void setPageAction(PdfName actionType,
PdfAction action) {
if (pageAA == null) {
pageAA = new PdfDictionary();
}
pageAA.put(actionType, action);
}
|
public void setPageCount(int pageN) {
if (writer != null && writer.isPaused()) {
return;
}
super.setPageCount(pageN);
}
|
void setPageEmpty(boolean pageEmpty) {
this.pageEmpty = pageEmpty;
}
|
void setPageLabels(PdfPageLabels pageLabels) {
this.pageLabels = pageLabels;
}
|
public boolean setPageSize(Rectangle pageSize) {
if (writer != null && writer.isPaused()) {
return false;
}
nextPageSize = new Rectangle(pageSize);
return true;
}
|
void setSigFlags(int f) {
annotationsImp.setSigFlags(f);
}
|
void setStrictImageSequence(boolean strictImageSequence) {
this.strictImageSequence = strictImageSequence;
}
Setter for property strictImageSequence. |
void setThumbnail(Image image) throws PdfException, DocumentException {
thumb = writer.getImageReference(writer.addDirectImageSimple(image));
}
|
void setTransition(PdfTransition transition) {
this.transition=transition;
}
Sets the transition for the page |
void setViewerPreferences(int preferences) {
this.viewerPreferences.setViewerPreferences(preferences);
}
|
public void setXmpMetadata(byte[] xmpMetadata) {
this.xmpMetadata = xmpMetadata;
}
Use this method to set the XMP Metadata. |
void traverseOutlineCount(PdfOutline outline) {
ArrayList kids = outline.getKids();
PdfOutline parent = outline.parent();
if (kids.isEmpty()) {
if (parent != null) {
parent.setCount(parent.getCount() + 1);
}
}
else {
for (int k = 0; k < kids.size(); ++k) {
traverseOutlineCount((PdfOutline)kids.get(k));
}
if (parent != null) {
if (outline.isOpen()) {
parent.setCount(outline.getCount() + parent.getCount() + 1);
}
else {
parent.setCount(parent.getCount() + 1);
outline.setCount(-outline.getCount());
}
}
}
}
Recursive method to update the count in the outlines. |
void writeLineToContent(PdfLine line,
PdfContentByte text,
PdfContentByte graphics,
Object[] currentValues,
float ratio) throws DocumentException {
PdfFont currentFont = (PdfFont)(currentValues[0]);
float lastBaseFactor = ((Float)(currentValues[1])).floatValue();
PdfChunk chunk;
int numberOfSpaces;
int lineLen;
boolean isJustified;
float hangingCorrection = 0;
float hScale = 1;
float lastHScale = Float.NaN;
float baseWordSpacing = 0;
float baseCharacterSpacing = 0;
float glueWidth = 0;
numberOfSpaces = line.numberOfSpaces();
lineLen = line.GetLineLengthUtf32();
// does the line need to be justified?
isJustified = line.hasToBeJustified() && (numberOfSpaces != 0 || lineLen > 1);
int separatorCount = line.getSeparatorCount();
if (separatorCount > 0) {
glueWidth = line.widthLeft() / separatorCount;
}
else if (isJustified) {
if (line.isNewlineSplit() && line.widthLeft() >= (lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1))) {
if (line.isRTL()) {
text.moveText(line.widthLeft() - lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1), 0);
}
baseWordSpacing = ratio * lastBaseFactor;
baseCharacterSpacing = lastBaseFactor;
}
else {
float width = line.widthLeft();
PdfChunk last = line.getChunk(line.size() - 1);
if (last != null) {
String s = last.toString();
char c;
if (s.length() > 0 && hangingPunctuation.indexOf((c = s.charAt(s.length() - 1))) >= 0) {
float oldWidth = width;
width += last.font().width(c) * 0.4f;
hangingCorrection = width - oldWidth;
}
}
float baseFactor = width / (ratio * numberOfSpaces + lineLen - 1);
baseWordSpacing = ratio * baseFactor;
baseCharacterSpacing = baseFactor;
lastBaseFactor = baseFactor;
}
}
int lastChunkStroke = line.getLastStrokeChunk();
int chunkStrokeIdx = 0;
float xMarker = text.getXTLM();
float baseXMarker = xMarker;
float yMarker = text.getYTLM();
boolean adjustMatrix = false;
float tabPosition = 0;
// looping over all the chunks in 1 line
for (Iterator j = line.iterator(); j.hasNext(); ) {
chunk = (PdfChunk) j.next();
Color color = chunk.color();
hScale = 1;
if (chunkStrokeIdx < = lastChunkStroke) {
float width;
if (isJustified) {
width = chunk.getWidthCorrected(baseCharacterSpacing, baseWordSpacing);
}
else {
width = chunk.width();
}
if (chunk.isStroked()) {
PdfChunk nextChunk = line.getChunk(chunkStrokeIdx + 1);
if (chunk.isSeparator()) {
width = glueWidth;
Object[] sep = (Object[])chunk.getAttribute(Chunk.SEPARATOR);
DrawInterface di = (DrawInterface)sep[0];
Boolean vertical = (Boolean)sep[1];
float fontSize = chunk.font().size();
float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize);
float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize);
if (vertical.booleanValue()) {
di.draw(graphics, baseXMarker, yMarker + descender, baseXMarker + line.getOriginalWidth(), ascender - descender, yMarker);
}
else {
di.draw(graphics, xMarker, yMarker + descender, xMarker + width, ascender - descender, yMarker);
}
}
if (chunk.isTab()) {
Object[] tab = (Object[])chunk.getAttribute(Chunk.TAB);
DrawInterface di = (DrawInterface)tab[0];
tabPosition = ((Float)tab[1]).floatValue() + ((Float)tab[3]).floatValue();
float fontSize = chunk.font().size();
float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize);
float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize);
if (tabPosition > xMarker) {
di.draw(graphics, xMarker, yMarker + descender, tabPosition, ascender - descender, yMarker);
}
float tmp = xMarker;
xMarker = tabPosition;
tabPosition = tmp;
}
if (chunk.isAttribute(Chunk.BACKGROUND)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.BACKGROUND))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
float fontSize = chunk.font().size();
float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize);
float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize);
Object bgr[] = (Object[])chunk.getAttribute(Chunk.BACKGROUND);
graphics.setColorFill((Color)bgr[0]);
float extra[] = (float[])bgr[1];
graphics.rectangle(xMarker - extra[0],
yMarker + descender - extra[1] + chunk.getTextRise(),
width - subtract + extra[0] + extra[2],
ascender - descender + extra[1] + extra[3]);
graphics.fill();
graphics.setGrayFill(0);
}
if (chunk.isAttribute(Chunk.UNDERLINE)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.UNDERLINE))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
Object unders[][] = (Object[][])chunk.getAttribute(Chunk.UNDERLINE);
Color scolor = null;
for (int k = 0; k < unders.length; ++k) {
Object obj[] = unders[k];
scolor = (Color)obj[0];
float ps[] = (float[])obj[1];
if (scolor == null)
scolor = color;
if (scolor != null)
graphics.setColorStroke(scolor);
float fsize = chunk.font().size();
graphics.setLineWidth(ps[0] + fsize * ps[1]);
float shift = ps[2] + fsize * ps[3];
int cap2 = (int)ps[4];
if (cap2 != 0)
graphics.setLineCap(cap2);
graphics.moveTo(xMarker, yMarker + shift);
graphics.lineTo(xMarker + width - subtract, yMarker + shift);
graphics.stroke();
if (scolor != null)
graphics.resetGrayStroke();
if (cap2 != 0)
graphics.setLineCap(0);
}
graphics.setLineWidth(1);
}
if (chunk.isAttribute(Chunk.ACTION)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.ACTION))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
text.addAnnotation(new PdfAnnotation(writer, xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size(), (PdfAction)chunk.getAttribute(Chunk.ACTION)));
}
if (chunk.isAttribute(Chunk.REMOTEGOTO)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.REMOTEGOTO))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
Object obj[] = (Object[])chunk.getAttribute(Chunk.REMOTEGOTO);
String filename = (String)obj[0];
if (obj[1] instanceof String)
remoteGoto(filename, (String)obj[1], xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size());
else
remoteGoto(filename, ((Integer)obj[1]).intValue(), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size());
}
if (chunk.isAttribute(Chunk.LOCALGOTO)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALGOTO))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
localGoto((String)chunk.getAttribute(Chunk.LOCALGOTO), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size());
}
if (chunk.isAttribute(Chunk.LOCALDESTINATION)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALDESTINATION))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
localDestination((String)chunk.getAttribute(Chunk.LOCALDESTINATION), new PdfDestination(PdfDestination.XYZ, xMarker, yMarker + chunk.font().size(), 0));
}
if (chunk.isAttribute(Chunk.GENERICTAG)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.GENERICTAG))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
Rectangle rect = new Rectangle(xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size());
PdfPageEvent pev = writer.getPageEvent();
if (pev != null)
pev.onGenericTag(writer, this, rect, (String)chunk.getAttribute(Chunk.GENERICTAG));
}
if (chunk.isAttribute(Chunk.PDFANNOTATION)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.PDFANNOTATION))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
float fontSize = chunk.font().size();
float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize);
float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize);
PdfAnnotation annot = PdfFormField.shallowDuplicate((PdfAnnotation)chunk.getAttribute(Chunk.PDFANNOTATION));
annot.put(PdfName.RECT, new PdfRectangle(xMarker, yMarker + descender, xMarker + width - subtract, yMarker + ascender));
text.addAnnotation(annot);
}
float params[] = (float[])chunk.getAttribute(Chunk.SKEW);
Float hs = (Float)chunk.getAttribute(Chunk.HSCALE);
if (params != null || hs != null) {
float b = 0, c = 0;
if (params != null) {
b = params[0];
c = params[1];
}
if (hs != null)
hScale = hs.floatValue();
text.setTextMatrix(hScale, b, c, 1, xMarker, yMarker);
}
if (chunk.isImage()) {
Image image = chunk.getImage();
float matrix[] = image.matrix();
matrix[Image.CX] = xMarker + chunk.getImageOffsetX() - matrix[Image.CX];
matrix[Image.CY] = yMarker + chunk.getImageOffsetY() - matrix[Image.CY];
graphics.addImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
text.moveText(xMarker + lastBaseFactor + image.getScaledWidth() - text.getXTLM(), 0);
}
}
xMarker += width;
++chunkStrokeIdx;
}
if (chunk.font().compareTo(currentFont) != 0) {
currentFont = chunk.font();
text.setFontAndSize(currentFont.getFont(), currentFont.size());
}
float rise = 0;
Object textRender[] = (Object[])chunk.getAttribute(Chunk.TEXTRENDERMODE);
int tr = 0;
float strokeWidth = 1;
Color strokeColor = null;
Float fr = (Float)chunk.getAttribute(Chunk.SUBSUPSCRIPT);
if (textRender != null) {
tr = ((Integer)textRender[0]).intValue() & 3;
if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL)
text.setTextRenderingMode(tr);
if (tr == PdfContentByte.TEXT_RENDER_MODE_STROKE || tr == PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE) {
strokeWidth = ((Float)textRender[1]).floatValue();
if (strokeWidth != 1)
text.setLineWidth(strokeWidth);
strokeColor = (Color)textRender[2];
if (strokeColor == null)
strokeColor = color;
if (strokeColor != null)
text.setColorStroke(strokeColor);
}
}
if (fr != null)
rise = fr.floatValue();
if (color != null)
text.setColorFill(color);
if (rise != 0)
text.setTextRise(rise);
if (chunk.isImage()) {
adjustMatrix = true;
}
else if (chunk.isHorizontalSeparator()) {
PdfTextArray array = new PdfTextArray();
array.add(-glueWidth * 1000f / chunk.font.size() / hScale);
text.showText(array);
}
else if (chunk.isTab()) {
PdfTextArray array = new PdfTextArray();
array.add((tabPosition - xMarker) * 1000f / chunk.font.size() / hScale);
text.showText(array);
}
// If it is a CJK chunk or Unicode TTF we will have to simulate the
// space adjustment.
else if (isJustified && numberOfSpaces > 0 && chunk.isSpecialEncoding()) {
if (hScale != lastHScale) {
lastHScale = hScale;
text.setWordSpacing(baseWordSpacing / hScale);
text.setCharacterSpacing(baseCharacterSpacing / hScale);
}
String s = chunk.toString();
int idx = s.indexOf(' ");
if (idx < 0)
text.showText(s);
else {
float spaceCorrection = - baseWordSpacing * 1000f / chunk.font.size() / hScale;
PdfTextArray textArray = new PdfTextArray(s.substring(0, idx));
int lastIdx = idx;
while ((idx = s.indexOf(' ", lastIdx + 1)) >= 0) {
textArray.add(spaceCorrection);
textArray.add(s.substring(lastIdx, idx));
lastIdx = idx;
}
textArray.add(spaceCorrection);
textArray.add(s.substring(lastIdx));
text.showText(textArray);
}
}
else {
if (isJustified && hScale != lastHScale) {
lastHScale = hScale;
text.setWordSpacing(baseWordSpacing / hScale);
text.setCharacterSpacing(baseCharacterSpacing / hScale);
}
text.showText(chunk.toString());
}
if (rise != 0)
text.setTextRise(0);
if (color != null)
text.resetRGBColorFill();
if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL)
text.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
if (strokeColor != null)
text.resetRGBColorStroke();
if (strokeWidth != 1)
text.setLineWidth(1);
if (chunk.isAttribute(Chunk.SKEW) || chunk.isAttribute(Chunk.HSCALE)) {
adjustMatrix = true;
text.setTextMatrix(xMarker, yMarker);
}
}
if (isJustified) {
text.setWordSpacing(0);
text.setCharacterSpacing(0);
if (line.isNewlineSplit())
lastBaseFactor = 0;
}
if (adjustMatrix)
text.moveText(baseXMarker - text.getXTLM(), 0);
currentValues[0] = currentFont;
currentValues[1] = new Float(lastBaseFactor);
}
Writes a text line to the document. It takes care of all the attributes.
Before entering the line position must have been established and the
text argument must be in text object scope (beginText()). |
void writeOutlines() throws IOException {
if (rootOutline.getKids().size() == 0)
return;
outlineTree(rootOutline);
writer.addToBody(rootOutline, rootOutline.indirectReference());
}
Writes the outline tree to the body of the PDF document. |