📄 columntext.java
字号:
ratio = 0.001f; } float firstIndent = 0; int status = 0; if (rectangularMode) { for (;;) { firstIndent = (lastWasNewline ? indent : followingIndent); if (rectangularWidth <= firstIndent + rightIndent) { status = NO_MORE_COLUMN; if (bidiLine.isEmpty()) status |= NO_MORE_TEXT; break; } if (bidiLine.isEmpty()) { status = NO_MORE_TEXT; break; } PdfLine line = bidiLine.processLine(leftX, rectangularWidth - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions); if (line == null) { status = NO_MORE_TEXT; break; } float maxSize = line.getMaxSizeSimple(); if (isUseAscender() && Float.isNaN(firstLineY)) { currentLeading = line.getAscender(); } else { currentLeading = fixedLeading + maxSize * multipliedLeading; } if (yLine > maxY || yLine - currentLeading < minY ) { status = NO_MORE_COLUMN; bidiLine.restore(); break; } yLine -= currentLeading; if (!simulate && !dirty) { text.beginText(); dirty = true; } if (Float.isNaN(firstLineY)) { firstLineY = yLine; } updateFilledWidth(rectangularWidth - line.widthLeft()); if (!simulate) { currentValues[0] = currentFont; text.setTextMatrix(leftX + (line.isRTL() ? rightIndent : firstIndent) + line.indentLeft(), yLine); pdf.writeLineToContent(line, text, graphics, currentValues, ratio); currentFont = (PdfFont)currentValues[0]; } lastWasNewline = line.isNewlineSplit(); yLine -= line.isNewlineSplit() ? extraParagraphSpace : 0; ++linesWritten; descender = line.getDescender(); } } else { currentLeading = fixedLeading; for (;;) { firstIndent = (lastWasNewline ? indent : followingIndent); float yTemp = yLine; float xx[] = findLimitsTwoLines(); if (xx == null) { status = NO_MORE_COLUMN; if (bidiLine.isEmpty()) status |= NO_MORE_TEXT; yLine = yTemp; break; } if (bidiLine.isEmpty()) { status = NO_MORE_TEXT; yLine = yTemp; break; } float x1 = Math.max(xx[0], xx[2]); float x2 = Math.min(xx[1], xx[3]); if (x2 - x1 <= firstIndent + rightIndent) continue; if (!simulate && !dirty) { text.beginText(); dirty = true; } PdfLine line = bidiLine.processLine(x1, x2 - x1 - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions); if (line == null) { status = NO_MORE_TEXT; yLine = yTemp; break; } if (!simulate) { currentValues[0] = currentFont; text.setTextMatrix(x1 + (line.isRTL() ? rightIndent : firstIndent) + line.indentLeft(), yLine); pdf.writeLineToContent(line, text, graphics, currentValues, ratio); currentFont = (PdfFont)currentValues[0]; } lastWasNewline = line.isNewlineSplit(); yLine -= line.isNewlineSplit() ? extraParagraphSpace : 0; ++linesWritten; descender = line.getDescender(); } } if (dirty) { text.endText(); canvas.add(text); } return status; } /** * Sets the extra space between paragraphs. * @return the extra space between paragraphs */ public float getExtraParagraphSpace() { return extraParagraphSpace; } /** * Sets the extra space between paragraphs. * @param extraParagraphSpace the extra space between paragraphs */ public void setExtraParagraphSpace(float extraParagraphSpace) { this.extraParagraphSpace = extraParagraphSpace; } /** * Clears the chunk array. A call to <CODE>go()</CODE> will always return * NO_MORE_TEXT. */ public void clearChunks() { if (bidiLine != null) bidiLine.clearChunks(); } /** Gets the space/character extra spacing ratio for * fully justified text. * @return the space/character extra spacing ratio */ public float getSpaceCharRatio() { return spaceCharRatio; } /** Sets the ratio between the extra word spacing and the extra character spacing * when the text is fully justified. * Extra word spacing will grow <CODE>spaceCharRatio</CODE> times more than extra character spacing. * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> then the extra character spacing * will be zero. * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing */ public void setSpaceCharRatio(float spaceCharRatio) { this.spaceCharRatio = spaceCharRatio; } /** Sets the run direction. * @param runDirection the run direction */ public void setRunDirection(int runDirection) { if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) throw new RuntimeException("Invalid run direction: " + runDirection); this.runDirection = runDirection; } /** Gets the run direction. * @return the run direction */ public int getRunDirection() { return runDirection; } /** Gets the number of lines written. * @return the number of lines written */ public int getLinesWritten() { return this.linesWritten; } /** Gets the arabic shaping options. * @return the arabic shaping options */ public int getArabicOptions() { return this.arabicOptions; } /** Sets the arabic shaping options. The option can be AR_NOVOWEL, * AR_COMPOSEDTASHKEEL and AR_LIG. * @param arabicOptions the arabic shaping options */ public void setArabicOptions(int arabicOptions) { this.arabicOptions = arabicOptions; } /** Gets the biggest descender value of the last line written. * @return the biggest descender value of the last line written */ public float getDescender() { return descender; } /** Gets the width that the line will occupy after writing. * Only the width of the first line is returned. * @param phrase the <CODE>Phrase</CODE> containing the line * @param runDirection the run direction * @param arabicOptions the options for the arabic shaping * @return the width of the line */ public static float getWidth(Phrase phrase, int runDirection, int arabicOptions) { ColumnText ct = new ColumnText(null); ct.addText(phrase); ct.addWaitingPhrase(); PdfLine line = ct.bidiLine.processLine(0, 20000, Element.ALIGN_LEFT, runDirection, arabicOptions); if (line == null) return 0; else return 20000 - line.widthLeft(); } /** Gets the width that the line will occupy after writing. * Only the width of the first line is returned. * @param phrase the <CODE>Phrase</CODE> containing the line * @return the width of the line */ public static float getWidth(Phrase phrase) { return getWidth(phrase, PdfWriter.RUN_DIRECTION_NO_BIDI, 0); } /** Shows a line of text. Only the first line is written. * @param canvas where the text is to be written to * @param alignment the alignment. It is not influenced by the run direction * @param phrase the <CODE>Phrase</CODE> with the text * @param x the x reference position * @param y the y reference position * @param rotation the rotation to be applied in degrees counterclockwise * @param runDirection the run direction * @param arabicOptions the options for the arabic shaping */ public static void showTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation, int runDirection, int arabicOptions) { if (alignment != Element.ALIGN_LEFT && alignment != Element.ALIGN_CENTER && alignment != Element.ALIGN_RIGHT) alignment = Element.ALIGN_LEFT; canvas.saveState(); ColumnText ct = new ColumnText(canvas); if (rotation == 0) { if (alignment == Element.ALIGN_LEFT) ct.setSimpleColumn(phrase, x, y - 1, 20000 + x, y + 2, 2, alignment); else if (alignment == Element.ALIGN_RIGHT) ct.setSimpleColumn(phrase, x-20000, y-1, x, y+2, 2, alignment); else ct.setSimpleColumn(phrase, x-20000, y-1, x+20000, y+2, 2, alignment); } else { double alpha = rotation * Math.PI / 180.0; float cos = (float)Math.cos(alpha); float sin = (float)Math.sin(alpha); canvas.concatCTM(cos, sin, -sin, cos, x, y); if (alignment == Element.ALIGN_LEFT) ct.setSimpleColumn(phrase, 0, -1, 20000, 2, 2, alignment); else if (alignment == Element.ALIGN_RIGHT) ct.setSimpleColumn(phrase, -20000, -1, 0, 2, 2, alignment); else ct.setSimpleColumn(phrase, -20000, -1, 20000, 2, 2, alignment); } if (runDirection == PdfWriter.RUN_DIRECTION_RTL) { if (alignment == Element.ALIGN_LEFT) alignment = Element.ALIGN_RIGHT; else if (alignment == Element.ALIGN_RIGHT) alignment = Element.ALIGN_LEFT; } ct.setAlignment(alignment); ct.setArabicOptions(arabicOptions); ct.setRunDirection(runDirection); try { ct.go(); } catch (DocumentException e) { throw new ExceptionConverter(e); } canvas.restoreState(); } /** Shows a line of text. Only the first line is written. * @param canvas where the text is to be written to * @param alignment the alignment * @param phrase the <CODE>Phrase</CODE> with the text * @param x the x reference position * @param y the y reference position * @param rotation the rotation to be applied in degrees counterclockwise */ public static void showTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation) { showTextAligned(canvas, alignment, phrase, x, y, rotation, PdfWriter.RUN_DIRECTION_NO_BIDI, 0); } 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.spacingBefore(); } 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.spacingAfter(); } 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, new Integer(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -