How to make a single letter bold within a word?
Is it possible to bold out specific letters within a word in iText?
Consider this sentence, "this is a word". Could I make all the "i" within that sentence bold? I want the output to be like this: "this is a word"
So to get the first word right (this), do I really have to create three chunks for one word and than add all the chunks together? Or is there another approach?
With three chunks I mean something like this:
Chunk chunk1 = new Chunk("th"); Chunk chunk2 = new Chunk("i", bold); Chunk chunk3 = new Chunk("s"); Paragraph p = new Paragraph(); p.add(chunk1); p.add(chunk2); p.add(chunk3)
Posted on StackOverflow on Nov 22, 2014 by user3711421
Take a look at the following example: ColoredLetters
I've written this method that automates what you describe:
private Text returnCorrectColor(char letter) throws IOException {
if (letter == 'b') {
return new Text("b")
.setFontColor(Color.BLUE)
.setFont(PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD));
} else if (letter == 'g') {
return new Text("g")
.setFontColor(Color.GREEN)
.setFont(PdfFontFactory.createFont(FontConstants. HELVETICA_OBLIQUE));
} else {
return new Text(String.valueOf(letter))
.setFontColor(Color.RED)
.setFont(PdfFontFactory.createFont(FontConstants.HELVETICA));
}
}
Note that I used some constants:
public static final Font RED_NORMAL =
new Font(FontFamily.HELVETICA, 12, Font.NORMAL, BaseColor.RED);
public static final Font BLUE_BOLD =
new Font(FontFamily.HELVETICA, 12, Font.BOLD, BaseColor.BLUE);
public static final Font GREEN_ITALIC =
new Font(FontFamily.HELVETICA, 12, Font.ITALIC, BaseColor.GREEN);
public static final Chunk B = new Chunk("b", BLUE_BOLD);
public static final Chunk G = new Chunk("g", GREEN_ITALIC);
It returns a Text
instance (iText 7 does not have Chunk
s anymore). Now I can construct a Paragraph
like this:
Paragraph p = new Paragraph();
String s = "all text is written in red, except the letters b and g; they are written in blue and green.";
for (int i = 0; i
The result looks like this: colored_letters.pdf
Color applied to text
Updates based on additional questions in the comments
Could i specify the color as a HEX. for example something like BaseColor(#ffcd03);
I understand that you can specify it like new BaseColor(0, 0, 255)
, however HEX would be more useful.
iText7 has a WebColors
class that offers a getRGBColor()
method. Now it takes a few seconds to create a color from a HEX value:
DeviceRgb color = WebColors.getRGBColor("#" + "ffcd03");
Text text = new Text("a").setFontColor(color);
is there a way to just define the color and leave the font to the default. Something like this: public static final Font RED_NORMAL = new Font(BaseColor.RED);
In iText 7 you could create a Text
instance and set only color value. When you add it to the Paragraph
, it should take the font defined at the level of the Paragraph.
Text tt = new Text("new strange text").setFontColor(Color.ORANGE);
Paragraph pp = new Paragraph(tt).setFont(PdfFontFactory.createFont(FontConstants.TIMES_ROMAN));
My goal is to write a program that colorizes existing PDF files without changing the structure of the PDF. Do you think this approach will work for this purpose (performance etc)?
No, this will not work. PDF is not a format that was created for editing. The internal syntax for the sentence shown in the screen shot looks like this:
BT
36 806 Td
0 -16 Td
/F1 12 Tf
1 0 0 rg
(all text is written in red, except the letters ) Tj
0 g
/F2 12 Tf
0 0 1 rg
(b) Tj
0 g
/F1 12 Tf
1 0 0 rg
( and ) Tj
0 g
/F3 12 Tf
0 1 0 rg
(g) Tj
0 g
/F1 12 Tf
1 0 0 rg
(; they are written in ) Tj
0 g
/F2 12 Tf
0 0 1 rg
(b) Tj
0 g
/F1 12 Tf
1 0 0 rg
(lue and ) Tj
0 g
/F3 12 Tf
0 1 0 rg
(g) Tj
0 g
/F1 12 Tf
1 0 0 rg
(reen.) Tj
0 g
0 0 Td
ET
As you can see, the Tf
operator changes the font:
/F1
is the regular font,/F2
is the bold font,/F3
is the italic font.
These names refer to fonts in the /Resources
dictionary of the page, where you'll find the references to the actual font descriptors.
The rg
operator changes the color. As we use red, green and blue, you recognize the operande 1 0 0
, 0 1 0
and 0 0 1
.
This looks fairly simple, because we used WINANSI encoding. One could parse the content stream, look for all the PDF string (between (
and )
or between and
>
), and introduce Tf
and rg
operators.
However: the content stream won't always be as trivial as here. Custom encodings can be used, Unicode can be used,... Take a look at the second screen shot in my answer to the following question: How to use Cyrillic characters in a PDF?. You'll understand that your plan to change colors in an existing PDF is a non-trivial task. We have done such a project in the past for one of our customers. It was a project that took several weeks.
Click How to make a single letter bold within a word? if you want to see how to answer this question in iText 5.