How to get the rendered dimensions of text?

Category: 
Tags: measure textfontsColumnTextiText 5

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?

Posted on StackOverflow on Feb 28, 2014 by Kartick Vaddadi

iText uses the ColumnText class to render content to a cell. TColumnText 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: How to tell iText how to clip text to fit in a cell?"