use of com.lowagie.text.pdf.draw.DrawInterface in project OpenPDF by LibrePDF.
the class PdfDocument method add.
/**
* Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
*
* @param element the element to add
* @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
* @throws DocumentException when a document isn't open yet, or has been closed
*/
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:
info.addProducer(((Meta) element).getContent());
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.ury(indentTop() - currentHeight - 20), annot.urx(indentRight() - line.widthLeft() + 20), annot.lly(indentTop() - currentHeight));
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.getSpacingBefore(), 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();
// fixes bug with nested tables not shown
// Paragraph#getChunks() doesn't contain the nested table element
PdfPTable table = createInOneCell(paragraph);
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.getSpacingAfter(), 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.getSpacingBefore(), 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.getSpacingAfter(), 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())
// nothing to do
break;
// 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())
// nothing to do
break;
// 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())
// nothing to do
break;
// 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.JBIG2:
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);
}
}
use of com.lowagie.text.pdf.draw.DrawInterface in project OpenPDF by LibrePDF.
the class PdfDocument method writeLineToContent.
/**
* Writes a text line to the document. It takes care of all the attributes.
* <P>
* Before entering the line position must have been established and the
* <CODE>text</CODE> argument must be in text object scope (<CODE>beginText()</CODE>).
* @param line the line to be written
* @param text the <CODE>PdfContentByte</CODE> where the text will be written to
* @param graphics the <CODE>PdfContentByte</CODE> where the graphics will be written to
* @param currentValues the current font and extra spacing values
* @param ratio
* @throws DocumentException on error
*/
void writeLineToContent(PdfLine line, PdfContentByte text, PdfContentByte graphics, Object[] currentValues, float ratio) throws DocumentException {
PdfFont currentFont = (PdfFont) (currentValues[0]);
float lastBaseFactor = (Float) (currentValues[1]);
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() || (LayoutProcessor.isEnabled() && LayoutProcessor.isSet(LAYOUT_RIGHT_TO_LEFT))) {
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;
}
}
// if there's a single word on the line and we are using NO_SPACE_CHAR_RATIO,
// we don't want any character spacing
float baseFactor = (numberOfSpaces == 0 && ratio == PdfWriter.NO_SPACE_CHAR_RATIO) ? 0f : 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) {
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] + (Float) tab[3];
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)) {
graphics.saveState();
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);
graphics.restoreState();
}
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 (Object[] obj : unders) {
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], 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;
text.setTextMatrix(hScale, b, c, 1, xMarker, yMarker);
}
if (chunk.isAttribute(Chunk.CHAR_SPACING)) {
Float cs = (Float) chunk.getAttribute(Chunk.CHAR_SPACING);
text.setCharacterSpacing(cs);
}
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] & 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];
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;
if (color != null)
text.setColorFill(color);
if (rise != 0)
text.setTextRise(rise);
if (chunk.isImage()) {
adjustMatrix = true;
} else if (chunk.isVerticalSeparator()) {
// Did nothing here to avoid printing out OBJECT_REPLACEMENT_CHARACTER
} 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);
} else // space adjustment.
if (isJustified && numberOfSpaces > 0 && chunk.isSpecialEncoding()) {
if (hScale != lastHScale) {
lastHScale = hScale;
text.setWordSpacing(baseWordSpacing / hScale);
text.setCharacterSpacing(baseCharacterSpacing / hScale + text.getCharacterSpacing());
}
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();
if (LayoutProcessor.isEnabled() && LayoutProcessor.isSet(LAYOUT_RIGHT_TO_LEFT)) {
textArray.setRTL(true);
}
textArray.add(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.getCharacterSpacing());
}
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 (chunk.isAttribute(Chunk.CHAR_SPACING)) {
text.setCharacterSpacing(baseCharacterSpacing);
}
}
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] = lastBaseFactor;
}
use of com.lowagie.text.pdf.draw.DrawInterface in project OpenPDF by LibrePDF.
the class ColumnText method goComposite.
protected int goComposite(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 = adjustFirstLine;
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.setUseAscender(firstPass && useAscender);
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(para.getRunDirection() == PdfWriter.RUN_DIRECTION_DEFAULT ? runDirection : para.getRunDirection());
compositeColumn.setArabicOptions(arabicOptions);
compositeColumn.setSpaceCharRatio(spaceCharRatio);
compositeColumn.addText(para);
if (!firstPass) {
yLine -= para.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 = (para.getKeepTogether() && createHere && !firstPass);
status = compositeColumn.go(simulate || (keepCandidate && keep == 0));
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;
if (compositeColumn != null) {
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.lowagie.text.List list = (com.lowagie.text.List) element;
java.util.List<Element> items = list.getItems();
ListItem item = null;
float listIndentation = list.getIndentationLeft();
int count = 0;
Stack<Object[]> stack = new Stack<>();
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.lowagie.text.List) {
stack.push(new Object[] { list, k, listIndentation });
list = (com.lowagie.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.lowagie.text.List) objs[0];
items = list.getItems();
k = (Integer) objs[1];
listIndentation = (Float) objs[2];
}
}
}
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 && useAscender);
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) {
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 != null && item.getKeepTogether() && createHere && !firstPass);
status = compositeColumn.go(simulate || (keepCandidate && keep == 0));
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 && item != null) {
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;
if (item != null) {
yLine -= item.getSpacingAfter();
}
}
if ((status & NO_MORE_COLUMN) != 0)
return NO_MORE_COLUMN;
} else if (element.type() == Element.PTABLE) {
// don't write anything in the current column if there's no more space available
if (yLine < minY || yLine > maxY)
return NO_MORE_COLUMN;
// get the PdfPTable element
PdfPTable table = (PdfPTable) element;
// we ignore tables without a body
if (table.size() <= table.getHeaderRows()) {
compositeElements.removeFirst();
continue;
}
// offsets
float yTemp = yLine;
if (!firstPass && listIdx == 0)
yTemp -= table.spacingBefore();
float yLineWrite = yTemp;
// don't write anything in the current column if there's no more space available
if (yTemp < minY || yTemp > maxY)
return NO_MORE_COLUMN;
// coordinates
currentLeading = 0;
float x1 = leftX;
float tableWidth;
if (table.isLockedWidth()) {
tableWidth = table.getTotalWidth();
updateFilledWidth(tableWidth);
} else {
tableWidth = rectangularWidth * table.getWidthPercentage() / 100f;
table.setTotalWidth(tableWidth);
}
// how many header rows are real header rows; how many are footer rows?
int headerRows = table.getHeaderRows();
int footerRows = table.getFooterRows();
if (footerRows > headerRows)
footerRows = headerRows;
int realHeaderRows = headerRows - footerRows;
float headerHeight = table.getHeaderHeight();
float footerHeight = table.getFooterHeight();
// make sure the header and footer fit on the page
boolean skipHeader = (!firstPass && table.isSkipFirstHeader() && listIdx <= headerRows);
if (!skipHeader) {
yTemp -= headerHeight;
if (yTemp < minY || yTemp > maxY) {
if (firstPass) {
compositeElements.removeFirst();
continue;
}
return NO_MORE_COLUMN;
}
}
// how many real rows (not header or footer rows) fit on a page?
int k;
if (listIdx < headerRows)
listIdx = headerRows;
if (!table.isComplete())
yTemp -= footerHeight;
for (k = listIdx; k < table.size(); ++k) {
float rowHeight = table.getRowHeight(k);
if (yTemp - rowHeight < minY)
break;
yTemp -= rowHeight;
}
if (!table.isComplete())
yTemp += footerHeight;
// either k is the first row that doesn't fit on the page (break);
if (k < table.size()) {
if (table.isSplitRows() && (!table.isSplitLate() || (k == listIdx && firstPass))) {
if (!splittedRow) {
splittedRow = true;
table = new PdfPTable(table);
compositeElements.set(0, table);
List<PdfPRow> rows = table.getRows();
for (int i = headerRows; i < listIdx; ++i) rows.set(i, null);
}
float h = yTemp - minY;
PdfPRow newRow = table.getRow(k).splitRow(table, k, h);
if (newRow == null) {
if (k == listIdx)
return NO_MORE_COLUMN;
} else {
yTemp = minY;
table.getRows().add(++k, newRow);
}
} else if (!table.isSplitRows() && k == listIdx && firstPass) {
return NO_MORE_COLUMN;
} else if (k == listIdx && !firstPass && (!table.isSplitRows() || table.isSplitLate()) && (table.getFooterRows() == 0 || table.isComplete()))
return NO_MORE_COLUMN;
}
// or k is the number of rows in the table (for loop was done).
firstPass = false;
// we draw the table (for real now)
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);
List<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(listIdx, k));
// if k < table.size(), we must indicate that the new table is complete;
// otherwise no footers will be added (because iText thinks the table continues on the same page)
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)
for (int j = 0; j < footerRows && nt.isComplete() && showFooter; ++j) sub.add(table.getRow(j + realHeaderRows));
// we need a correction if the last row needs to be extended
float rowHeight = 0;
int index = sub.size() - 1;
if (showFooter)
index -= footerRows;
PdfPRow last = sub.get(index);
if (table.isExtendLastRow(newPageFollows)) {
rowHeight = last.getMaxHeights();
last.setMaxHeights(yTemp - minY + rowHeight);
yTemp = minY;
}
// now we render the rows of the new table
if (canvases != null)
nt.writeSelectedRows(0, -1, x1, yLineWrite, canvases);
else
nt.writeSelectedRows(0, -1, x1, yLineWrite, canvas);
if (table.isExtendLastRow(newPageFollows)) {
last.setMaxHeights(rowHeight);
}
} else if (table.isExtendLastRow() && minY > PdfPRow.BOTTOM_LIMIT)
yTemp = minY;
yLine = yTemp;
if (!(skipHeader || table.isComplete()))
yLine += footerHeight;
if (k >= table.size()) {
yLine -= table.spacingAfter();
compositeElements.removeFirst();
splittedRow = false;
listIdx = 0;
} else {
if (splittedRow) {
List<PdfPRow> rows = table.getRows();
for (int i = listIdx; i < k; ++i) rows.set(i, null);
}
listIdx = 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();
}
}
use of com.lowagie.text.pdf.draw.DrawInterface in project itext2 by albfernandez.
the class ColumnText method goComposite.
protected int goComposite(boolean simulate) throws DocumentException {
if (!rectangularMode)
throw new DocumentException("Irregular columns are not supported in composite mode.");
linesWritten = 0;
descender = 0;
boolean firstPass = adjustFirstLine;
main_loop: while (true) {
if (compositeElements.isEmpty())
return NO_MORE_TEXT;
Element 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.setUseAscender(firstPass ? useAscender : false);
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) {
yLine -= para.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 = (para.getKeepTogether() && createHere && !firstPass);
status = compositeColumn.go(simulate || (keepCandidate && keep == 0));
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.lowagie.text.List list = (com.lowagie.text.List) element;
ArrayList items = list.getItems();
ListItem item = null;
float listIndentation = list.getIndentationLeft();
int count = 0;
Stack stack = new Stack();
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.lowagie.text.List) {
stack.push(new Object[] { list, Integer.valueOf(k), new Float(listIndentation) });
list = (com.lowagie.text.List) obj;
items = list.getItems();
listIndentation += list.getIndentationLeft();
k = -1;
continue;
}
if (k == items.size() - 1) {
if (!stack.isEmpty()) {
Object[] objs = (Object[]) stack.pop();
list = (com.lowagie.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 ? 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) {
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);
status = compositeColumn.go(simulate || (keepCandidate && keep == 0));
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) {
// don't write anything in the current column if there's no more space available
if (yLine < minY || yLine > maxY)
return NO_MORE_COLUMN;
// get the PdfPTable element
PdfPTable table = (PdfPTable) element;
// we ignore tables without a body
if (table.size() <= table.getHeaderRows()) {
compositeElements.removeFirst();
continue;
}
// offsets
float yTemp = yLine;
if (!firstPass && listIdx == 0)
yTemp -= table.spacingBefore();
float yLineWrite = yTemp;
// don't write anything in the current column if there's no more space available
if (yTemp < minY || yTemp > maxY)
return NO_MORE_COLUMN;
// coordinates
currentLeading = 0;
float x1 = leftX;
float tableWidth;
if (table.isLockedWidth()) {
tableWidth = table.getTotalWidth();
updateFilledWidth(tableWidth);
} else {
tableWidth = rectangularWidth * table.getWidthPercentage() / 100f;
table.setTotalWidth(tableWidth);
}
// how many header rows are real header rows; how many are footer rows?
int headerRows = table.getHeaderRows();
int footerRows = table.getFooterRows();
if (footerRows > headerRows)
footerRows = headerRows;
int realHeaderRows = headerRows - footerRows;
float headerHeight = table.getHeaderHeight();
float footerHeight = table.getFooterHeight();
// make sure the header and footer fit on the page
boolean skipHeader = (!firstPass && table.isSkipFirstHeader() && listIdx <= headerRows);
if (!skipHeader) {
yTemp -= headerHeight;
if (yTemp < minY || yTemp > maxY) {
if (firstPass) {
compositeElements.removeFirst();
continue;
}
return NO_MORE_COLUMN;
}
}
// how many real rows (not header or footer rows) fit on a page?
int k;
if (listIdx < headerRows)
listIdx = headerRows;
if (!table.isComplete())
yTemp -= footerHeight;
for (k = listIdx; k < table.size(); ++k) {
float rowHeight = table.getRowHeight(k);
if (yTemp - rowHeight < minY)
break;
yTemp -= rowHeight;
}
if (!table.isComplete())
yTemp += footerHeight;
// either k is the first row that doesn't fit on the page (break);
if (k < table.size()) {
if (table.isSplitRows() && (!table.isSplitLate() || (k == listIdx && firstPass))) {
if (!splittedRow) {
splittedRow = true;
table = new PdfPTable(table);
compositeElements.set(0, table);
ArrayList rows = table.getRows();
for (int i = headerRows; i < listIdx; ++i) rows.set(i, null);
}
float h = yTemp - minY;
PdfPRow newRow = table.getRow(k).splitRow(table, k, h);
if (newRow == null) {
if (k == listIdx)
return NO_MORE_COLUMN;
} else {
yTemp = minY;
table.getRows().add(++k, newRow);
}
} else if (!table.isSplitRows() && k == listIdx && firstPass) {
compositeElements.removeFirst();
splittedRow = false;
continue;
} else if (k == listIdx && !firstPass && (!table.isSplitRows() || table.isSplitLate()) && (table.getFooterRows() == 0 || table.isComplete()))
return NO_MORE_COLUMN;
}
// or k is the number of rows in the table (for loop was done).
firstPass = false;
// we draw the table (for real now)
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 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(listIdx, k));
// if k < table.size(), we must indicate that the new table is complete;
// otherwise no footers will be added (because iText thinks the table continues on the same page)
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)
for (int j = 0; j < footerRows && nt.isComplete() && showFooter; ++j) sub.add(table.getRow(j + realHeaderRows));
// we need a correction if the last row needs to be extended
float rowHeight = 0;
PdfPRow last = (PdfPRow) sub.get(sub.size() - 1 - footerRows);
if (table.isExtendLastRow(newPageFollows)) {
rowHeight = last.getMaxHeights();
last.setMaxHeights(yTemp - minY + rowHeight);
yTemp = minY;
}
// now we render the rows of the new table
if (canvases != null)
nt.writeSelectedRows(0, -1, x1, yLineWrite, canvases);
else
nt.writeSelectedRows(0, -1, x1, yLineWrite, canvas);
if (table.isExtendLastRow(newPageFollows)) {
last.setMaxHeights(rowHeight);
}
} else if (table.isExtendLastRow() && minY > PdfPRow.BOTTOM_LIMIT)
yTemp = minY;
yLine = yTemp;
if (!(skipHeader || table.isComplete()))
yLine += footerHeight;
if (k >= table.size()) {
yLine -= table.spacingAfter();
compositeElements.removeFirst();
splittedRow = false;
listIdx = 0;
} else {
if (splittedRow) {
ArrayList rows = table.getRows();
for (int i = listIdx; i < k; ++i) rows.set(i, null);
}
listIdx = 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();
}
}
use of com.lowagie.text.pdf.draw.DrawInterface in project itext2 by albfernandez.
the class PdfDocument method writeLineToContent.
/**
* Writes a text line to the document. It takes care of all the attributes.
* <P>
* Before entering the line position must have been established and the
* <CODE>text</CODE> argument must be in text object scope (<CODE>beginText()</CODE>).
* @param line the line to be written
* @param text the <CODE>PdfContentByte</CODE> where the text will be written to
* @param graphics the <CODE>PdfContentByte</CODE> where the graphics will be written to
* @param currentValues the current font and extra spacing values
* @param ratio
* @throws DocumentException on error
*/
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;
}
}
// if there's a single word on the line and we are using NO_SPACE_CHAR_RATIO,
// we don't want any character spacing
float baseFactor = (numberOfSpaces == 0 && ratio == PdfWriter.NO_SPACE_CHAR_RATIO) ? 0f : 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)) {
@SuppressWarnings("unused") 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);
} else // space adjustment.
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);
}
Aggregations