How to tell iText how to clip text to fit in a cell?
Can I control this clipping algorithm? For example:
- Print a suffix of the string rather than a prefix.
- Mark a substring of the string as not to be removed. This is with footnote references. If I add text saying "Hello World [1]", the [1] is a reference to a footnote and should not be removed. It's okay to remove the other characters of the string, like "World".
- When there are multiple words in the string, iText seems to eliminate a word that doesn't fit, while I would like it partially printed. That is, if the string is "Hello World", and the cell has room only for "Hello Wo...", I would like that to be printed, rather than just "Hello", as iText prints.
- Rather than printing characters in their entirety, print only part of them. Imagine printing the text to a PNG and chopping off the top and/or bottom part of the PNG to fit it in the space available. For example, notice that the top line and the bottom line are partially clipped here:
Are any of these possible? Does iText give me any control over how text is clipped? Thanks.
Posted on StackOverflow on Feb 28, 2014 by Kartick Vaddadi
I have written a proof of concept, ClipCenterCellContent, where we try to fit the text "D2 is a cell with more content than we can fit into the cell."
in a cell that is too small.
We add the content using a CellRenderer
and overriding the draw()
method.
In iText 7 you would need to manipulate with table renderer a bit:
IRenderer pr = content.createRendererSubTree().setParent(this);
LayoutResult textArea = pr.layout(new LayoutContext(
new LayoutArea(0, new Rectangle(getOccupiedAreaBBox().getWidth(), 1000))));
A renderer is created, and layout()
is called for an area which is clearly big enough to fit the cell, afterwards you can get the actual occupied area of a cell:
float spaceneeded = textArea.getOccupiedArea().getBBox().getHeight();
System.out.println(String.format("The content requires %s pt whereas the height is %s pt.",
spaceneeded, getOccupiedAreaBBox().getHeight()));
We now know the needed height and we can add the content using an offset:
float offset = (getOccupiedAreaBBox().getHeight() - textArea.getOccupiedArea().getBBox().getHeight()) / 2;
System.out.println(String.format("The difference is %s pt; we'll need an offset of %s pt.",
-2f * offset, offset));
PdfFormXObject xObject = new PdfFormXObject(new Rectangle(getOccupiedAreaBBox().getWidth(),
getOccupiedAreaBBox().getHeight()));
Canvas layoutCanvas = new Canvas(new PdfCanvas(xObject, drawContext.getDocument()), drawContext.getDocument(),
new Rectangle(0, offset, getOccupiedAreaBBox().getWidth(), spaceneeded));
layoutCanvas.add(content);
drawContext.getCanvas().addXObject(xObject, occupiedArea.getBBox().getLeft(), occupiedArea.getBBox().getBottom());
In this case, I used a PdfFormXObject
to clip the content.
Click How to tell iText how to clip text to fit in a cell? if you want to see how to answer this question in iText 5.