0

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.

Kartick Vaddadi
  • 4,818
  • 6
  • 39
  • 55
  • Is there a policy that limits the rate at which one can ask questions? I have been using iText for many months now, BTW. It's just that I decided to ask my questions at once rather than dribbling them out. I looked through the other methods in BaseFont to see if there are methods that give me this information, but there weren't any. – Kartick Vaddadi Feb 28 '14 at 14:42
  • For other questions, I've showed what I tried (for example: http://stackoverflow.com/questions/22093993/itext-whats-an-easy-to-print-first-right-then-down ). That one describes the problem, how I partially solved it so far, and makes a proposal as to what I can do next. In this case, I could not think of what else to try, because there's no suitable API method I can see to try. I'm not asking to be taught or to "please do my homework". Regarding your request for code, I can give you the code for splitting columns, but that's going to confuse more than help. – Kartick Vaddadi Feb 28 '14 at 14:55
  • Splitting columnns doesn't apply to this question but to http://stackoverflow.com/questions/22093993/itext-whats-an-easy-to-print-first-right-then-down . Does your comment apply to this question or to the linked one? Thanks. – Kartick Vaddadi Feb 28 '14 at 15:02
  • Thanks for the tip about PdfTemplate. I will try it out. Regarding your other point, I have tried my best to ask specific, detailed questions. Not "how do I set the row height?" (which would be a homework / newbie question) but "how do setMinimumHeight() and setFixedHeight() interact?" I have used iText, read the API docs, tried things out, etc. But you were in a hurry to blame me for not reading the book without realizing that the book does NOT answer the question asked. If you don't want to help me, that's up to you :) – Kartick Vaddadi Feb 28 '14 at 15:17
  • Oh, and thanks for building iText, which I've benefitted from :) And, just as a general note, if you find a specific question confusing, please let me know what aspect of it is confusing, and I can post code to illustrate that aspect. Simply posting code to cover everything would go to pages and confuse rather than clarify. – Kartick Vaddadi Feb 28 '14 at 15:19
  • You should also understand that some of your questions take plenty of time to answer; for instance: the "first right, then down" question would take an hour. When you post 5 questions at once, you're asking for a serious time-investment. – Bruno Lowagie Feb 28 '14 at 16:19
  • Bruno, to be clear, I do not expect an answer immediately. Since you are under no obligation to help me at all, there's no way I can expect you to answer all five questions immediately. You are again jumping to conclusions when you call me cheap for using an old version of iText. I am doing so because this project has a tight deadline and I did not have time (until now) to work on the iText upgrade. I was using a version that was already checked in to the internal repository in my company. Do you see that you're jumping to conclusions again by calling me cheap? – Kartick Vaddadi Feb 28 '14 at 16:42
  • It's fine if you don't respond to the questions, and it's also fine if you respond by saying, "Sorry, this is an old version, and we have a policy to not provide support for such old versions." But let's not have a blame game here, call the other person cheap, blame them for not reading the book when it doesn't answer the question asked, etc. – Kartick Vaddadi Feb 28 '14 at 16:46
  • OK, I'll remove my comments, but please inform your employer that he shouldn't impose a tight deadline on his employees, when he can save plenty of time by getting support from the source. If only your employer had a support contract, we wouldn't be wasting time arguing about technical issues that can be easily solved. – Bruno Lowagie Feb 28 '14 at 16:52
  • The iText agreement we're working will include support. Thanks. – Kartick Vaddadi Feb 28 '14 at 16:54

1 Answers1

0

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

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thanks, Bruno. I will read through your three answers soon and get back to you. – Kartick Vaddadi Mar 01 '14 at 15:35
  • Part of this answer has been duplicated [here](http://stackoverflow.com/q/22093745/679449). – Kermit Mar 01 '14 at 15:58
  • @KartickVaddadi Answering questions is a thing of honor for me. It proves over and over again that the people at iText really know their stuff. Unfortunately, some people at your company have made me false promises in the past. Not keeping promises is not something I consider honorable, so I hope your company will finally do the right thing after all the years they've been stalling. – Bruno Lowagie Mar 01 '14 at 19:08
  • I am not aware of what other people at my company have or have not promised, and in what context, and so forth, so I am not interested in rehashing those. Let's stay focused on the technical discussion, okay? – Kartick Vaddadi Mar 02 '14 at 02:32
  • No, that's not okay. You, as a developer have the responsibility to do the right thing. You should have waited until the support contract was in place. I've been waiting for 5 years for your company to become a customer, surely you should be able to wait until a contract is signed. I am waiting for your company to make that step, it's not the other way round! – Bruno Lowagie Mar 02 '14 at 08:03
  • Stack Overflow is a place to discuss technical questions, and is open to everyone -- not just people with a support contract. You can't blame me for posting questions. You are free to ignore them. – Kartick Vaddadi Mar 03 '14 at 09:59