How to get the rendered dimensions of text?
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:
- 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? - 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? - 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. 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 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?"