예제 #1
0
 /**
  * Replaces the current text array with this <CODE>Phrase</CODE>.
  * Anything added previously with AddElement() is lost.
  * @param phrase the text
  */
 public void SetText(Phrase phrase)
 {
     bidiLine = null;
     composite = false;
     compositeColumn = null;
     compositeElements = null;
     listIdx = 0;
     splittedRow = false;
     waitPhrase = phrase;
 }
예제 #2
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);
     float lly = -1;
     float ury = 2;
     float llx;
     float urx;
     switch (alignment) {
     case Element.ALIGN_LEFT:
         llx = 0;
         urx = 20000;
         break;
     case Element.ALIGN_RIGHT:
         llx = -20000;
         urx = 0;
         break;
     default:
         llx = -20000;
         urx = 20000;
         break;
     }
     if (rotation == 0) {
     llx += x;
     lly += y;
     urx += x;
     ury += y;
     }
     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);
     }
     ct.SetSimpleColumn(phrase, llx, lly, urx, ury, 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.Alignment = alignment;
     ct.ArabicOptions = arabicOptions;
     ct.RunDirection = runDirection;
     ct.Go();
     canvas.RestoreState();
 }
예제 #3
0
 /** Makes this instance an independent copy of <CODE>org</CODE>.
  * @param org the original <CODE>ColumnText</CODE>
  * @return itself
  */
 public ColumnText SetACopy(ColumnText org)
 {
     SetSimpleVars(org);
     if (org.bidiLine != null)
     bidiLine = new BidiLine(org.bidiLine);
     return this;
 }
예제 #4
0
 /** Creates an independent duplicated of the instance <CODE>org</CODE>.
  * @param org the original <CODE>ColumnText</CODE>
  * @return the duplicated
  */
 public static ColumnText Duplicate(ColumnText org)
 {
     ColumnText ct = new ColumnText(null);
     ct.SetACopy(org);
     return ct;
 }
예제 #5
0
 /** 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;
 }
예제 #6
0
 protected internal void SetSimpleVars(ColumnText org)
 {
     maxY = org.maxY;
     minY = org.minY;
     alignment = org.alignment;
     leftWall = null;
     if (org.leftWall != null)
     leftWall = new ArrayList(org.leftWall);
     rightWall = null;
     if (org.rightWall != null)
     rightWall = new ArrayList(org.rightWall);
     yLine = org.yLine;
     currentLeading = org.currentLeading;
     fixedLeading = org.fixedLeading;
     multipliedLeading = org.multipliedLeading;
     canvas = org.canvas;
     canvases = org.canvases;
     lineStatus = org.lineStatus;
     indent = org.indent;
     followingIndent = org.followingIndent;
     rightIndent = org.rightIndent;
     extraParagraphSpace = org.extraParagraphSpace;
     rectangularWidth = org.rectangularWidth;
     rectangularMode = org.rectangularMode;
     spaceCharRatio = org.spaceCharRatio;
     lastWasNewline = org.lastWasNewline;
     linesWritten = org.linesWritten;
     arabicOptions = org.arabicOptions;
     runDirection = org.runDirection;
     descender = org.descender;
     composite = org.composite;
     splittedRow = org.splittedRow;
     if (org.composite) {
     compositeElements = new ArrayList(org.compositeElements);
     if (splittedRow) {
         PdfPTable table = (PdfPTable)compositeElements[0];
         compositeElements[0] = new PdfPTable(table);
     }
     if (org.compositeColumn != null)
         compositeColumn = Duplicate(org.compositeColumn);
     }
     listIdx = org.listIdx;
     firstLineY = org.firstLineY;
     leftX = org.leftX;
     rightX = org.rightX;
     firstLineYDone = org.firstLineYDone;
     waitPhrase = org.waitPhrase;
     useAscender = org.useAscender;
     filledWidth = org.filledWidth;
     adjustFirstLine = org.adjustFirstLine;
 }
예제 #7
0
        protected int GoComposite(bool simulate)
        {
            if (!rectangularMode)
            throw new DocumentException("Irregular columns are not supported in composite mode.");
            linesWritten = 0;
            descender = 0;
            bool firstPass = adjustFirstLine;
            main_loop:
            while (true) {
            if (compositeElements.Count == 0)
                return NO_MORE_TEXT;
            IElement element = (IElement)compositeElements[0];
            if (element.Type == Element.PARAGRAPH) {
                Paragraph para = (Paragraph)element;
                int status = 0;
                for (int keep = 0; keep < 2; ++keep) {
                    float lastY = yLine;
                    bool createHere = false;
                    if (compositeColumn == null) {
                        compositeColumn = new ColumnText(canvas);
                        compositeColumn.UseAscender = (firstPass ? useAscender : false);
                        compositeColumn.Alignment = para.Alignment;
                        compositeColumn.Indent = para.IndentationLeft + para.FirstLineIndent;
                        compositeColumn.ExtraParagraphSpace = para.ExtraParagraphSpace;
                        compositeColumn.FollowingIndent = para.IndentationLeft;
                        compositeColumn.RightIndent = para.IndentationRight;
                        compositeColumn.SetLeading(para.Leading, para.MultipliedLeading);
                        compositeColumn.RunDirection = runDirection;
                        compositeColumn.ArabicOptions = arabicOptions;
                        compositeColumn.SpaceCharRatio = 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;
                    bool keepCandidate = (para.KeepTogether && 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.RemoveAt(0);
                    yLine -= para.SpacingAfter;
                }
                if ((status & NO_MORE_COLUMN) != 0) {
                    return NO_MORE_COLUMN;
                }
            }
            else if (element.Type == Element.LIST) {
                List list = (List)element;
                ArrayList items = list.Items;
                ListItem item = null;
                float listIndentation = list.IndentationLeft;
                int count = 0;
                Stack stack = new Stack();
                for (int k = 0; k < items.Count; ++k) {
                    Object obj = items[k];
                    if (obj is ListItem) {
                        if (count == listIdx) {
                            item = (ListItem)obj;
                            break;
                        }
                        else ++count;
                    }
                    else if (obj is List) {
                        stack.Push(new Object[]{list, k, listIndentation});
                        list = (List)obj;
                        items = list.Items;
                        listIndentation += list.IndentationLeft;
                        k = -1;
                        continue;
                    }
                    if (k == items.Count - 1) {
                        if (stack.Count > 0) {
                            Object[] objs = (Object[])stack.Pop();
                            list = (List)objs[0];
                            items = list.Items;
                            k = (int)objs[1];
                            listIndentation = (float)objs[2];
                        }
                    }
                }
                int status = 0;
                for (int keep = 0; keep < 2; ++keep) {
                    float lastY = yLine;
                    bool createHere = false;
                    if (compositeColumn == null) {
                        if (item == null) {
                            listIdx = 0;
                            compositeElements.RemoveAt(0);
                            goto main_loop;
                        }
                        compositeColumn = new ColumnText(canvas);

                        compositeColumn.UseAscender = (firstPass ? useAscender : false);
                        compositeColumn.Alignment = item.Alignment;
                        compositeColumn.Indent = item.IndentationLeft + listIndentation + item.FirstLineIndent;
                        compositeColumn.ExtraParagraphSpace = item.ExtraParagraphSpace;
                        compositeColumn.FollowingIndent = compositeColumn.Indent;
                        compositeColumn.RightIndent = item.IndentationRight + list.IndentationRight;
                        compositeColumn.SetLeading(item.Leading, item.MultipliedLeading);
                        compositeColumn.RunDirection = runDirection;
                        compositeColumn.ArabicOptions = arabicOptions;
                        compositeColumn.SpaceCharRatio = spaceCharRatio;
                        compositeColumn.AddText(item);
                        if (!firstPass) {
                            yLine -= item.SpacingBefore;
                        }
                        createHere = true;
                    }
                    compositeColumn.leftX = leftX;
                    compositeColumn.rightX = rightX;
                    compositeColumn.yLine = yLine;
                    compositeColumn.rectangularWidth = rectangularWidth;
                    compositeColumn.rectangularMode = rectangularMode;
                    compositeColumn.minY = minY;
                    compositeColumn.maxY = maxY;
                    bool keepCandidate = (item.KeepTogether && 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.ListSymbol), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0);
                    compositeColumn.firstLineYDone = true;
                }
                if ((status & NO_MORE_TEXT) != 0) {
                    compositeColumn = null;
                    ++listIdx;
                    yLine -= item.SpacingAfter;
                }
                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.HeaderRows) {
                    compositeElements.RemoveAt(0);
                    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.LockedWidth) {
                    tableWidth = table.TotalWidth;
                    UpdateFilledWidth(tableWidth);
                }
                else {
                    tableWidth = rectangularWidth * table.WidthPercentage / 100f;
                    table.TotalWidth = tableWidth;
                }

                // how many header rows are real header rows; how many are footer rows?
                int headerRows = table.HeaderRows;
                int footerRows = table.FooterRows;
                if (footerRows > headerRows)
                    footerRows = headerRows;
                int realHeaderRows = headerRows - footerRows;
                float headerHeight = table.HeaderHeight;
                float footerHeight = table.FooterHeight;

                // make sure the header and footer fit on the page
                bool skipHeader = (!firstPass && table.SkipFirstHeader && listIdx <= headerRows);
                if (!skipHeader) {
                    yTemp -= headerHeight;
                    if (yTemp < minY || yTemp > maxY) {
                        if (firstPass) {
                            compositeElements.RemoveAt(0);
                            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.ElementComplete) {
                    yTemp -= footerHeight;
                }
                for (k = listIdx; k < table.Size; ++k) {
                    float rowHeight = table.GetRowHeight(k);
                    if (yTemp - rowHeight < minY)
                        break;
                    yTemp -= rowHeight;
                }
                if (!table.ElementComplete) {
                    yTemp += footerHeight;
                }
                // either k is the first row that doesn't fit on the page (break);
                if (k < table.Size) {
                    if (table.SplitRows && (!table.SplitLate || (k == listIdx && firstPass))) {
                        if (!splittedRow) {
                            splittedRow = true;
                            table = new PdfPTable(table);
                            compositeElements[0] = table;
                            ArrayList rows = table.Rows;
                            for (int i = headerRows; i < listIdx; ++i)
                                rows[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.Rows.Insert(++k, newRow);
                        }
                    }
                    else if (!table.SplitRows && k == listIdx && firstPass) {
                        compositeElements.RemoveAt(0);
                        splittedRow = false;
                        continue;
                    }
                    else if (k == listIdx && !firstPass && (!table.SplitRows || table.SplitLate) && (table.FooterRows == 0 || table.ElementComplete)) {
                        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.HorizontalAlignment) {
                        case Element.ALIGN_LEFT:
                            break;
                        case Element.ALIGN_RIGHT:
                            x1 += rectangularWidth - tableWidth;
                            break;
                        default:
                            x1 += (rectangularWidth - tableWidth) / 2f;
                            break;
                    }
                    // copy the rows that fit on the page in a new table nt
                    PdfPTable nt = PdfPTable.ShallowCopy(table);
                    ArrayList sub = nt.Rows;

                    // first we add the real header rows (if necessary)
                    if (!skipHeader) {
                        for (int j = 0; j < realHeaderRows; ++j) {
                            PdfPRow headerRow = table.GetRow(j);
                            sub.Add(headerRow);
                        }
                    }
                    else {
                        nt.HeaderRows = footerRows;
                    }
                    // then we add the real content
                    sub.AddRange(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)
                    bool showFooter = !table.SkipLastFooter;
                    if (k < table.Size) {
                        nt.ElementComplete = true;
                        showFooter = true;
                    }
                    // we add the footer rows if necessary (not for incomplete tables)
                    for (int j = 0; j < footerRows && nt.ElementComplete && 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[sub.Count - 1 - footerRows];
                    if (table.ExtendLastRow) {
                        rowHeight = last.MaxHeights;
                        last.MaxHeights = 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.ExtendLastRow) {
                        last.MaxHeights = rowHeight;
                    }
                }
                else if (table.ExtendLastRow && minY > PdfPRow.BOTTOM_LIMIT) {
                    yTemp = minY;
                }
                yLine = yTemp;
                if (!(skipHeader || table.ElementComplete)) {
                    yLine += footerHeight;
                }
                if (k >= table.Size) {
                    yLine -= table.SpacingAfter;
                    compositeElements.RemoveAt(0);
                    splittedRow = false;
                    listIdx = 0;
                }
                else {
                    if (splittedRow) {
                        ArrayList rows = table.Rows;
                        for (int i = listIdx; i < k; ++i)
                            rows[i] = null;
                    }
                    listIdx = k;
                    return NO_MORE_COLUMN;
                }
            }
            else if (element.Type == Element.YMARK) {
                if (!simulate) {
                    IDrawInterface zh = (IDrawInterface)element;
                    zh.Draw(canvas, leftX, minY, rightX, maxY, yLine);
                }
                compositeElements.RemoveAt(0);
            }
            else
                compositeElements.RemoveAt(0);
            }
        }
예제 #8
0
 /**
 * Get the <code>PdfAppearance</code> of a text or combo field
 * @throws IOException on error
 * @throws DocumentException on error
 * @return A <code>PdfAppearance</code>
 */
 public PdfAppearance GetAppearance()
 {
     PdfAppearance app = GetBorderAppearance();
     app.BeginVariableText();
     if (text == null || text.Length == 0) {
         app.EndVariableText();
         return app;
     }
     bool borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET;
     float h = box.Height - borderWidth * 2 - extraMarginTop;
     float bw2 = borderWidth;
     if (borderExtra) {
         h -= borderWidth * 2;
         bw2 *= 2;
     }
     float offsetX = Math.Max(bw2, 1);
     float offX = Math.Min(bw2, offsetX);
     app.SaveState();
     app.Rectangle(offX, offX, box.Width - 2 * offX, box.Height - 2 * offX);
     app.Clip();
     app.NewPath();
     String ptext;
     if ((options & PASSWORD) != 0)
         ptext = ObfuscatePassword(text);
     else if ((options & MULTILINE) == 0)
         ptext = RemoveCRLF(text);
     else
         ptext = text; //fixed by Kazuya Ujihara (ujihara.jp)
     BaseFont ufont = RealFont;
     Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor;
     int rtl = CheckRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI;
     float usize = fontSize;
     Phrase phrase = ComposePhrase(ptext, ufont, fcolor, usize);
     if ((options & MULTILINE) != 0) {
         float width = box.Width - 4 * offsetX - extraMarginLeft;
         float factor = ufont.GetFontDescriptor(BaseFont.BBOXURY, 1) - ufont.GetFontDescriptor(BaseFont.BBOXLLY, 1);
         ColumnText ct = new ColumnText(null);
         if (usize == 0) {
             usize = h / factor;
             if (usize > 4) {
                 if (usize > 12)
                     usize = 12;
                 float step = Math.Max((usize - 4) / 10, 0.2f);
                 ct.SetSimpleColumn(0, -h, width, 0);
                 ct.Alignment = alignment;
                 ct.RunDirection = rtl;
                 for (; usize > 4; usize -= step) {
                     ct.YLine = 0;
                     ChangeFontSize(phrase, usize);
                     ct.SetText(phrase);
                     ct.Leading = factor * usize;
                     int status = ct.Go(true);
                     if ((status & ColumnText.NO_MORE_COLUMN) == 0)
                         break;
                 }
             }
             if (usize < 4) {
                 usize = 4;
             }
         }
         ChangeFontSize(phrase, usize);
         ct.Canvas = app;
         float leading = usize * factor;
         float offsetY = offsetX + h - ufont.GetFontDescriptor(BaseFont.BBOXURY, usize);
         ct.SetSimpleColumn(extraMarginLeft + 2 * offsetX, -20000, box.Width - 2 * offsetX, offsetY + leading);
         ct.Leading = leading;
         ct.Alignment = alignment;
         ct.RunDirection = rtl;
         ct.SetText(phrase);
         ct.Go();
     }
     else {
         if (usize == 0) {
             float maxCalculatedSize = h / (ufont.GetFontDescriptor(BaseFont.BBOXURX, 1) - ufont.GetFontDescriptor(BaseFont.BBOXLLY, 1));
             ChangeFontSize(phrase, 1);
             float wd = ColumnText.GetWidth(phrase, rtl, 0);
             if (wd == 0)
                 usize = maxCalculatedSize;
             else
                 usize = Math.Min(maxCalculatedSize, (box.Width - extraMarginLeft - 4 * offsetX) / wd);
             if (usize < 4)
                 usize = 4;
         }
         ChangeFontSize(phrase, usize);
         float offsetY = offX + ((box.Height - 2*offX) - ufont.GetFontDescriptor(BaseFont.ASCENT, usize)) / 2;
         if (offsetY < offX)
             offsetY = offX;
         if (offsetY - offX < -ufont.GetFontDescriptor(BaseFont.DESCENT, usize)) {
             float ny = -ufont.GetFontDescriptor(BaseFont.DESCENT, usize) + offX;
             float dy = box.Height - offX - ufont.GetFontDescriptor(BaseFont.ASCENT, usize);
             offsetY = Math.Min(ny, Math.Max(offsetY, dy));
         }
         if ((options & COMB) != 0 && maxCharacterLength > 0) {
             int textLen = Math.Min(maxCharacterLength, ptext.Length);
             int position = 0;
             if (alignment == Element.ALIGN_RIGHT) {
                 position = maxCharacterLength - textLen;
             }
             else if (alignment == Element.ALIGN_CENTER) {
                 position = (maxCharacterLength - textLen) / 2;
             }
             float step = (box.Width - extraMarginLeft) / maxCharacterLength;
             float start = step / 2 + position * step;
             if (textColor == null)
                 app.SetGrayFill(0);
             else
                 app.SetColorFill(textColor);
             app.BeginText();
             foreach (Chunk ck in phrase) {
                 BaseFont bf = ck.Font.BaseFont;
                 app.SetFontAndSize(bf, usize);
                 StringBuilder sb = ck.Append("");
                 for (int j = 0; j < sb.Length; ++j) {
                     String c = sb.ToString(j, 1);
                     float wd = bf.GetWidthPoint(c, usize);
                     app.SetTextMatrix(extraMarginLeft + start - wd / 2, offsetY - extraMarginTop);
                     app.ShowText(c);
                     start += step;
                 }
             }
             app.EndText();
         }
         else {
             float x;
             switch (alignment) {
                 case Element.ALIGN_RIGHT:
                     x = extraMarginLeft + box.Width - (2 * offsetX);
                     break;
                 case Element.ALIGN_CENTER:
                     x = extraMarginLeft + (box.Width / 2);
                     break;
                 default:
                     x = extraMarginLeft + (2 * offsetX);
                     break;
             }
             ColumnText.ShowTextAligned(app, alignment, phrase, x, offsetY - extraMarginTop, 0, rtl, 0);
         }
     }
     app.RestoreState();
     app.EndVariableText();
     return app;
 }
예제 #9
0
 /** Constructs a deep copy of a <CODE>PdfPCell</CODE>.
 * @param cell the <CODE>PdfPCell</CODE> to duplicate
 */
 public PdfPCell(PdfPCell cell)
     : base(cell.llx, cell.lly, cell.urx, cell.ury)
 {
     CloneNonPositionParameters(cell);
     verticalAlignment = cell.verticalAlignment;
     paddingLeft = cell.paddingLeft;
     paddingRight = cell.paddingRight;
     paddingTop = cell.paddingTop;
     paddingBottom = cell.paddingBottom;
     phrase = cell.phrase;
     fixedHeight = cell.fixedHeight;
     minimumHeight = cell.minimumHeight;
     noWrap = cell.noWrap;
     colspan = cell.colspan;
     rowspan = cell.rowspan;
     if (cell.table != null)
         table = new PdfPTable(cell.table);
     image = Image.GetInstance(cell.image);
     cellEvent = cell.cellEvent;
     useDescender = cell.useDescender;
     column = ColumnText.Duplicate(cell.column);
     useBorderPadding = cell.useBorderPadding;
     rotation = cell.rotation;
 }
예제 #10
0
 /**
 * Fits the text to some rectangle adjusting the font size as needed.
 * @param font the font to use
 * @param text the text
 * @param rect the rectangle where the text must fit
 * @param maxFontSize the maximum font size
 * @param runDirection the run direction
 * @return the calculated font size that makes the text fit
 */
 public static float FitText(Font font, String text, Rectangle rect, float maxFontSize, int runDirection)
 {
     ColumnText ct = null;
     int status = 0;
     if (maxFontSize <= 0) {
         int cr = 0;
         int lf = 0;
         char[] t = text.ToCharArray();
         for (int k = 0; k < t.Length; ++k) {
             if (t[k] == '\n')
                 ++lf;
             else if (t[k] == '\r')
                 ++cr;
         }
         int minLines = Math.Max(cr, lf) + 1;
         maxFontSize = Math.Abs(rect.Height) / minLines - 0.001f;
     }
     font.Size = maxFontSize;
     Phrase ph = new Phrase(text, font);
     ct = new ColumnText(null);
     ct.SetSimpleColumn(ph, rect.Left, rect.Bottom, rect.Right, rect.Top, maxFontSize, Element.ALIGN_LEFT);
     ct.RunDirection = runDirection;
     status = ct.Go(true);
     if ((status & ColumnText.NO_MORE_TEXT) != 0)
         return maxFontSize;
     float precision = 0.1f;
     float min = 0;
     float max = maxFontSize;
     float size = maxFontSize;
     for (int k = 0; k < 50; ++k) { //just in case it doesn't converge
         size = (min + max) / 2;
         ct = new ColumnText(null);
         font.Size = size;
         ct.SetSimpleColumn(new Phrase(text, font), rect.Left, rect.Bottom, rect.Right, rect.Top, size, Element.ALIGN_LEFT);
         ct.RunDirection = runDirection;
         status = ct.Go(true);
         if ((status & ColumnText.NO_MORE_TEXT) != 0) {
             if (max - min < size * precision)
                 return size;
             min = size;
         }
         else
             max = size;
     }
     return size;
 }
예제 #11
0
        /**
        * Gets the main appearance layer.
        * <p>
        * Consult <A HREF="http://partners.adobe.com/asn/developer/pdfs/tn/PPKAppearances.pdf">PPKAppearances.pdf</A>
        * for further details.
        * @return the main appearance layer
        * @throws DocumentException on error
        * @throws IOException on error
        */
        public PdfTemplate GetAppearance()
        {
            if (IsInvisible()) {
                PdfTemplate t = new PdfTemplate(writer);
                t.BoundingBox = new Rectangle(0, 0);
                writer.AddDirectTemplateSimple(t, null);
                return t;
            }
            if (app[0] == null) {
                PdfTemplate t = app[0] = new PdfTemplate(writer);
                t.BoundingBox = new Rectangle(100, 100);
                writer.AddDirectTemplateSimple(t, new PdfName("n0"));
                t.SetLiteral("% DSBlank\n");
            }
            if (app[1] == null && !acro6Layers) {
                PdfTemplate t = app[1] = new PdfTemplate(writer);
                t.BoundingBox = new Rectangle(100, 100);
                writer.AddDirectTemplateSimple(t, new PdfName("n1"));
                t.SetLiteral(questionMark);
            }
            if (app[2] == null) {
                String text;
                if (layer2Text == null) {
                    StringBuilder buf = new StringBuilder();
                    buf.Append("Digitally signed by ").Append(PdfPKCS7.GetSubjectFields((X509Certificate)certChain[0]).GetField("CN")).Append('\n');
                    buf.Append("Date: ").Append(signDate.ToString("yyyy.MM.dd HH:mm:ss zzz"));
                    if (reason != null)
                        buf.Append('\n').Append("Reason: ").Append(reason);
                    if (location != null)
                        buf.Append('\n').Append("Location: ").Append(location);
                    text = buf.ToString();
                }
                else
                    text = layer2Text;
                PdfTemplate t = app[2] = new PdfTemplate(writer);
                t.BoundingBox = rect;
                writer.AddDirectTemplateSimple(t, new PdfName("n2"));
                if (image != null) {
                    if (imageScale == 0) {
                        t.AddImage(image, rect.Width, 0, 0, rect.Height, 0, 0);
                    }
                    else {
                        float usableScale = imageScale;
                        if (imageScale < 0)
                            usableScale = Math.Min(rect.Width / image.Width, rect.Height / image.Height);
                        float w = image.Width * usableScale;
                        float h = image.Height * usableScale;
                        float x = (rect.Width - w) / 2;
                        float y = (rect.Height - h) / 2;
                        t.AddImage(image, w, 0, 0, h, x, y);
                    }
                }
                Font font;
                if (layer2Font == null)
                    font = new Font();
                else
                    font = new Font(layer2Font);
                float size = font.Size;

                Rectangle dataRect = null;
                Rectangle signatureRect = null;

                if (Render == SignatureRender.NameAndDescription ||
                    (Render == SignatureRender.GraphicAndDescription && this.SignatureGraphic != null)) {
                    // origin is the bottom-left
                    signatureRect = new Rectangle(
                        MARGIN,
                        MARGIN,
                        rect.Width / 2 - MARGIN,
                        rect.Height - MARGIN);
                    dataRect = new Rectangle(
                        rect.Width / 2 +  MARGIN / 2,
                        MARGIN,
                        rect.Width - MARGIN / 2,
                        rect.Height - MARGIN);

                    if (rect.Height > rect.Width) {
                        signatureRect = new Rectangle(
                            MARGIN,
                            rect.Height / 2,
                            rect.Width - MARGIN,
                            rect.Height);
                        dataRect = new Rectangle(
                            MARGIN,
                            MARGIN,
                            rect.Width - MARGIN,
                            rect.Height / 2 - MARGIN);
                    }
                }
                else {
                    dataRect = new Rectangle(
                        MARGIN,
                        MARGIN,
                        rect.Width - MARGIN,
                        rect.Height * (1 - TOP_SECTION) - MARGIN);
                }

                if (Render == SignatureRender.NameAndDescription) {
                    string signedBy = Legacy.Text.Pdf.PdfPKCS7.GetSubjectFields(this.certChain[0]).GetField("CN");
                    Rectangle sr2 = new Rectangle(signatureRect.Width - MARGIN, signatureRect.Height - MARGIN );
                    float signedSize = FitText(font, signedBy, sr2, -1, runDirection);

                    ColumnText ct2 = new ColumnText(t);
                    ct2.RunDirection = runDirection;
                    ct2.SetSimpleColumn(new Phrase(signedBy, font), signatureRect.Left, signatureRect.Bottom, signatureRect.Right, signatureRect.Top, signedSize, Element.ALIGN_LEFT);

                    ct2.Go();
                }
                else if (Render == SignatureRender.GraphicAndDescription) {
                    ColumnText ct2 = new ColumnText(t);
                    ct2.RunDirection = runDirection;
                    ct2.SetSimpleColumn(signatureRect.Left, signatureRect.Bottom, signatureRect.Right, signatureRect.Top, 0, Element.ALIGN_RIGHT);

                    Image im = Image.GetInstance(SignatureGraphic);
                    im.ScaleToFit(signatureRect.Width, signatureRect.Height);

                    Paragraph p = new Paragraph();
                    // must calculate the point to draw from to make image appear in middle of column
                    float x = 0;
                    // experimentation found this magic number to counteract Adobe's signature graphic, which
                    // offsets the y co-ordinate by 15 units
                    float y = -im.ScaledHeight + 15;

                    x = x + (signatureRect.Width - im.ScaledWidth) / 2;
                    y = y - (signatureRect.Height - im.ScaledHeight) / 2;
                    p.Add(new Chunk(im, x + (signatureRect.Width - im.ScaledWidth) / 2, y, false));
                    ct2.AddElement(p);
                    ct2.Go();
                }

                if (size <= 0) {
                    Rectangle sr = new Rectangle(dataRect.Width, dataRect.Height);
                    size = FitText(font, text, sr, 12, runDirection);
                }
                ColumnText ct = new ColumnText(t);
                ct.RunDirection = runDirection;
                ct.SetSimpleColumn(new Phrase(text, font), dataRect.Left, dataRect.Bottom, dataRect.Right, dataRect.Top, size, Element.ALIGN_LEFT);
                ct.Go();

            }
            if (app[3] == null && !acro6Layers) {
                PdfTemplate t = app[3] = new PdfTemplate(writer);
                t.BoundingBox = new Rectangle(100, 100);
                writer.AddDirectTemplateSimple(t, new PdfName("n3"));
                t.SetLiteral("% DSBlank\n");
            }
            if (app[4] == null && !acro6Layers) {
                PdfTemplate t = app[4] = new PdfTemplate(writer);
                t.BoundingBox = new Rectangle(0, rect.Height * (1 - TOP_SECTION), rect.Right, rect.Top);
                writer.AddDirectTemplateSimple(t, new PdfName("n4"));
                Font font;
                if (layer2Font == null)
                    font = new Font();
                else
                    font = new Font(layer2Font);
                float size = font.Size;
                String text = "Signature Not Verified";
                if (layer4Text != null)
                    text = layer4Text;
                Rectangle sr = new Rectangle(rect.Width - 2 * MARGIN, rect.Height * TOP_SECTION - 2 * MARGIN);
                size = FitText(font, text, sr, 15, runDirection);
                ColumnText ct = new ColumnText(t);
                ct.RunDirection = runDirection;
                ct.SetSimpleColumn(new Phrase(text, font), MARGIN, 0, rect.Width - MARGIN, rect.Height - MARGIN, size, Element.ALIGN_LEFT);
                ct.Go();
            }
            int rotation = writer.reader.GetPageRotation(page);
            Rectangle rotated = new Rectangle(rect);
            int n = rotation;
            while (n > 0) {
                rotated = rotated.Rotate();
                n -= 90;
            }
            if (frm == null) {
                frm = new PdfTemplate(writer);
                frm.BoundingBox = rotated;
                writer.AddDirectTemplateSimple(frm, new PdfName("FRM"));
                float scale = Math.Min(rect.Width, rect.Height) * 0.9f;
                float x = (rect.Width - scale) / 2;
                float y = (rect.Height - scale) / 2;
                scale /= 100;
                if (rotation == 90)
                    frm.ConcatCTM(0, 1, -1, 0, rect.Height, 0);
                else if (rotation == 180)
                    frm.ConcatCTM(-1, 0, 0, -1, rect.Width, rect.Height);
                else if (rotation == 270)
                    frm.ConcatCTM(0, -1, 1, 0, 0, rect.Width);
                frm.AddTemplate(app[0], 0, 0);
                if (!acro6Layers)
                    frm.AddTemplate(app[1], scale, 0, 0, scale, x, y);
                frm.AddTemplate(app[2], 0, 0);
                if (!acro6Layers) {
                    frm.AddTemplate(app[3], scale, 0, 0, scale, x, y);
                    frm.AddTemplate(app[4], 0, 0);
                }
            }
            PdfTemplate napp = new PdfTemplate(writer);
            napp.BoundingBox = rotated;
            writer.AddDirectTemplateSimple(napp, null);
            napp.AddTemplate(frm, 0, 0);
            return napp;
        }
예제 #12
0
 /**
 * Copy the parameters from the specified ColumnText to use
 * when rendering.  Parameters like <CODE>setArabicOptions</CODE>
 * must be set in this way.
 *
 * @param sourceColumn
 */
 public void UseColumnParams(ColumnText sourceColumn)
 {
     // note that canvas will be overwritten later
     columnText.SetSimpleVars(sourceColumn);
 }
예제 #13
0
 /**
 * Construct a MultiColumnText container of the specified height
 * starting at the specified Y position.
 *
 * @param height
 * @param top
 */
 public MultiColumnText(float top, float height)
 {
     columnDefs = new ArrayList();
     desiredHeight = height;
     this.top = top;
     nextY = top;
     // canvas will be set later
     columnText = new ColumnText(null);
     totalHeight = 0f;
 }
예제 #14
0
 /**
 * Construct a MultiColumnText container of the specified height.
 * If height is <CODE>AUTOMATIC</CODE>, fill complete pages until done.
 * If a specific height is used, it may span one or more pages.
 *
 * @param height
 */
 public MultiColumnText(float height)
 {
     columnDefs = new ArrayList();
     desiredHeight = height;
     top = AUTOMATIC;
     // canvas will be set later
     columnText = new ColumnText(null);
     totalHeight = 0f;
 }
예제 #15
0
 /**
 * @since	3.0.0 protected is now public static
 */
 public static float SetColumn(ColumnText ct, float left, float bottom, float right, float top)
 {
     if (left > right)
         right = left;
     if (bottom > top)
         top = bottom;
     ct.SetSimpleColumn(left, bottom, right, top);
     return top;
 }
예제 #16
0
 //    [M4] Adding a PdfPTable
 /** Adds a <CODE>PdfPTable</CODE> to the document.
 * @param ptable the <CODE>PdfPTable</CODE> to be added to the document.
 * @throws DocumentException on error
 */
 internal void AddPTable(PdfPTable ptable)
 {
     ColumnText ct = new ColumnText(writer.DirectContent);
     // 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.KeepTogether && !FitsPage(ptable, 0f) && currentHeight > 0)  {
         NewPage();
     }
     // add dummy paragraph if we aren't at the top of a page, so that
     // spacingBefore will be taken into account by ColumnText
     if (currentHeight > 0) {
         Paragraph p = new Paragraph();
         p.Leading = 0;
         ct.AddElement(p);
     }
     ct.AddElement(ptable);
     bool he = ptable.HeadersInEvent;
     ptable.HeadersInEvent = 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.YLine - IndentTop + currentHeight);
             currentHeight = IndentTop - ct.YLine;
             break;
         }
         if (IndentTop - currentHeight == ct.YLine)
             ++loop;
         else
             loop = 0;
         if (loop == 3) {
             Add(new Paragraph("ERROR: Infinite table loop"));
             break;
         }
         NewPage();
     }
     ptable.HeadersInEvent = he;
 }