How to restrict the number of characters on a single line?

Category: 
Tags: fontsmeasure textfont widthiText 7

I am using iText to generate PDFs. In these PDFs, I need to add two Strings on one line.

The first String (string1) length is between 1 and 10. The length of the second String (string2) is unknown, but the combined length of string1 and string2 should not exceed 10 characters.

How can I add these strings to a single line that is underlined?

Posted on StackOverflow on Dec 22, 2013 by Rajkumar Chilukuri

Please take a look at the UnderlineParagraphWithTwoParts example and allow me to explain which problems are solved in this example.

First problem: you want to make sure that 100 characters fit on one line. I've made this 101 characters because I assume that you want some space between string1 and string2 (if not, it should be easy to adapt the example).

As you don't know the content of string1 and string2 in advance, I've chosen a font of which all the glyphs have the same width: Courier (this is a fixed width or monospaced font). If you want to use a proportional font (such as Arial), you will have a very hard time calculating the font size, in the sense that you will have to calculate the font size separately for every string1 and string2 combination. This will result in a very odd-looking document where each line has a different font size.

This is the code to calculate the font size, based on the width of a single character in the font COURIER, the fact that we want to add 101 characters on one line that has a width equal to the space available between the right and left margin of the page:

PdfFont font = PdfFontFactory.createFont(FontConstants.COURIER, PdfEncodings.WINANSI, false);
float charWidth = font.getWidth(" ");
int charactersPerLine = 101;
float pageWidth = pdfDoc.getPage(1).getPageSize().getWidth() - doc.getLeftMargin() - doc.getRightMargin();
float fontSize = (1000 * (pageWidth / (charWidth * charactersPerLine)));
fontSize = ((int) (fontSize * 100)) / 100f;

Note that I round the value of the float. If you don't do this, you may experience problems due to rounding errors inherent to using float values.

Problem2: Now we want to add two string to a single line and underline them. From your question, it isn't clear how you want to align these strings.

This is the simple situation, where string1 and string2 are separated by a single space:

public void addParagraphWithTwoParts2(Document doc, PdfFont font, String string1, String string2, float fontSize) {
    if (string1 == null) string1 = "";
    if (string1.length() > 10)
        string1 = string1.substring(0, 10);
    if (string2 == null) string2 = "";
    if (string1.length() + string2.length() > 100)
        string2 = string2.substring(0, 100 - string1.length());
    Paragraph p = new Paragraph(string1 + " " + string2).setFont(font).setFontSize(fontSize);
    doc.add(p);
    doc.add(new LineSeparator(new SolidLine(1)).setMarginTop(-6));
}

This is a more complex situation, where you right-align string2:

public void addParagraphWithTwoParts1(Document doc, PdfFont font, String string1, String string2, float fontSize) {
    if (string1 == null) string1 = "";
    if (string1.length() > 10)
        string1 = string1.substring(0, 10);
    Text chunk1 = new Text(string1).setFont(font).setFontSize(fontSize);
    if (string2 == null) string2 = "";
    if (string1.length() + string2.length() > 100)
        string2 = string2.substring(0, 100 - string1.length());
    Text chunk2 = new Text(string2).setFont(font).setFontSize(fontSize);
    Paragraph p = new Paragraph();
    p.add(chunk1);
    p.addTabStops(new TabStop(1000, TabAlignment.RIGHT));
    p.add(new Tab());
    p.add(chunk2);
    doc.add(p);
    doc.add(new LineSeparator(new SolidLine(1)).setMarginTop(-6));
}

As you can see, we do not have to add any spaces, we just use TabStops:

p.addTabStops(new TabStop(1000, TabAlignment.RIGHT));
p.add(new Tab());

I've created an example where string1 and string2 consist of numbers. This is what the result looks like:

Underlined paragraphs
Underlined paragraphs

In this screen shot, you see examples where string2 is right aligned as well as examples where string2 is added right after string1 (but separated from it with a single space character).

Click this link if you want to see how to answer this question in iText 5.