iText — How do I get the rendered dimensions of te

2019-03-05 07:15发布

问题:

I would like to find out information about the layout of text in a PdfPCell. I'm aware of BaseFont.getWidthPointKerned(), but I'm looking for more detailed information like:

  1. How many lines would a string need if rendered in a cell of a given width (say, 30pt)? What would the height in points of the PdfPCell be?

  2. Give me the prefix or suffix of a string that fits in a cell of a given width and height. That is, if I have to render the text "Today is a good day to die" in a specific font in a PdfPCell of width 12pt and height 20pt, what portion of the string would fit in the available space?

  3. Where does iText break a given string when asked to render it in a cell of a given width?

This is with regard to iText 2.1.6. Thanks.

回答1:

iText uses the ColumnText class to render content to a cell. This is explained in my book on page 98-99. This means that, just like with ColumnText, you need to make the distinction between text mode and composite mode.

In any case, ColumnText measures the width of the characters and tests if they fit the available width. If not, the text is split. You can change the split behavior in different ways: by introducing hyphenation or by defining a custom split character.

I've written a small proof of concept to show how you could implement custom "truncation" behavior. See the TruncateTextInCell example.

Instead of adding the content to the cell, I have an empty cell for which I define a cell event. I pass the long text "D2 is a cell with more content than we can fit into the cell." to this event.

In the event, I use a fancy algorithm: I want the text to be truncated in the middle and insert "..." at the place where I truncated the text.

BaseFont bf = BaseFont.createFont();
Font font = new Font(bf, 12);
float availableWidth = position.getWidth();
int contentLength = content.length();
int leftChar = 0;
int rightChar = contentLength - 1;
availableWidth -= bf.getWidthPoint("...", 12);
while (leftChar < contentLength && rightChar != leftChar) {
    availableWidth -= bf.getWidthPoint(content.charAt(leftChar), 12);
    if (availableWidth > 0)
        leftChar++;
    else
        break;
    availableWidth -= bf.getWidthPoint(content.charAt(rightChar), 12);
    if (availableWidth > 0)
        rightChar--;
    else
        break;
    }
    String newContent = content.substring(0, leftChar) + "..." + content.substring(rightChar);
    PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS];
    ColumnText ct = new ColumnText(canvas);
    ct.setSimpleColumn(position);
    ct.addElement(new Paragraph(newContent, font));
    ct.go();

As you can see, we get the available width from the position parameter and we check how many characters match, alternating between a character at the start and a character at the end of the content.

The result is shown in the resulting PDF: the content is truncated like this: "D2 is a c... the cell."

Your question about "how many lines" can be solved in a similar way. The ColumnText class has a getLinesWritten() method that gives you that information. You can find more info about positioning a ColumnText object in my answer to your other question: Can I tell iText how to clip text to fit in a cell



标签: itext