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 CellRenderer
to render content to a cell. We measure 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.
I pass the long text "D2 is a cell with more content than we can fit into the cell."
to the renderer of the cell.
In the renderer, 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.
PdfFont bf = getPropertyAsFont(Property.FONT);
float availableWidth = layoutContext.getArea().getBBox().getWidth() - paddingLeft - paddingRight - borderLeft - borderRight;
int contentLength = content.length();
int leftChar = 0;
int rightChar = contentLength - 1;
availableWidth -= bf.getWidth("...", 12);
while (leftChar 0)
leftChar++;
else {
leftChar--;
break;
}
availableWidth -= bf.getWidth(content.charAt(rightChar), 12);
if (availableWidth > 0)
rightChar--;
else{
rightChar++;
break;
}
}
String newContent = content.substring(0, leftChar) + "..." + content.substring(rightChar);
Paragraph p = new Paragraph(newContent);
IRenderer pr = p.createRendererSubTree().setParent(this);
this.childRenderers.add(pr);
return super.layout(layoutContext);
As you can see, we get the available width 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 CellRenderer will also help you with this. You can find more info about positioning in my answer to your other question: How to tell iText how to clip text to fit in a cell?"
Click How to get the rendered dimensions of text? if you want to see how to answer this question in iText 5.