iText

Using simulated fonts in iText when a font variant is unavailable

This article explains how to use iText Core's font style simulation, simulateBold() (Java/.NET) and simulateItalic() (Java/.NET), to approximate a bold or italic style when a document requests a font variant that does not exist as a separate physical font file.

It also covers the Text (Java/.NET), Paragraph (Java/.NET), Canvas (Java/.NET), and PdfCanvas (Java/.NET) building blocks used to apply and wrap that styling.

Overview

A source document may request a font family together with a style that does not exist as a separate physical font face.

For example, a document may specify:

Font family: Calibri Light
Bold: true

However, the available font collection may contain Calibri Light without a corresponding Calibri Light Bold font file.

This situation commonly occurs when processing:

  • SVG Content

  • HTML or CSS

  • XML-based document formats

  • Office documents (e.g. content authored in Word or PowerPoint and converted to PDF)

When the requested font variant is unavailable, the rendering application must decide how to represent the requested formatting.

iText provides simulateBold() and simulateItalic() through its Layout API to let an application preserve the available base font while approximating a missing bold or italic style. They are available through iText layout elements such as Text and Paragraph.

This article demonstrates two ways to use these methods:

  1. Apply the style directly to a Text or Paragraph.

  2. Use the Layout API in an existing PdfCanvas workflow by wrapping the PdfCanvas with a Layout Canvas.

The problem addressed by this article is:

How can an application preserve an available base font and approximate a requested bold or italic style when the corresponding physical font variant does not exist?

Font simulation should be used as part of an explicit fallback strategy.

Use the following order:

  1. Use the exact requested font face when it exists.

  2. When the exact styled face is unavailable, check whether the base font exists.

  3. If the base font exists, use it with simulateBold() or simulateItalic().

For example:

Calibri Light + Bold requested
              |
Calibri Light Bold available?
              |
             No
              |
Calibri Light available?
              |
             Yes
              |
Use Calibri Light with simulateBold()

Apply styles directly with the Layout API

When an application already uses iText’s Layout API, the style can be applied directly to a Text element.

Simulated Bold:

Java
Text text = new Text("Simulated bold")
        .setFont(font)
        .setFontSize(12)
        .simulateBold();

Simulated Italic:

Java
Text text = new Text("Simulated italic")
        .setFont(font)
        .setFontSize(12)
        .simulateItalic();

Simulated Bold and Italic:

Java
Text text = new Text("Simulated bold and italic")
        .setFont(font)
        .setFontSize(12)
        .simulateBold()
        .simulateItalic();

Underline:

Java
Text text = new Text("Underlined text")
        .setFont(font)
        .setFontSize(12)
        .setUnderline();

Line-through:

Java
Text text = new Text("Line-through text")
        .setFont(font)
        .setFontSize(12)
        .setLineThrough();

Text and Paragraph elements can also take setUnderline() (Java/.NET) and setLineThrough() (Java/.NET), and are applied the same way. They are shown here for completeness as they can be combined with simulateBold()/simulateItalic().

However, unlike font style simulation, these are not approximations of a missing style: they draw an actual vector line in the content stream regardless of which font is in use, so there is no "real" underline being approximated.

Screenshot 2026-08-10 130658.png
A demonstration of simulated bold and italic styles, as well as underline/line-through using the Layout API.


🔹 A simulated style can also be applied to a Paragraph when the entire paragraph should inherit the same formatting.

Java
Paragraph paragraph = new Paragraph("Simulated bold paragraph")
        .setFont(font)
        .setFontSize(12)
        .simulateBold();

🔹 For mixed formatting, apply the properties to individual Text elements:

Java
Paragraph paragraph = new Paragraph()
        .setFont(font)
        .setFontSize(12)
        .add(new Text("Normal text, "))
        .add(new Text("simulated bold").simulateBold())
        .add(new Text(", simulated italic").simulateItalic())
        .add(new Text(", and both")
                .simulateBold()
                .simulateItalic());
Screenshot 2026-08-10 130707.png
Simulated fonts in a Paragraph.

Use styles in an existing PdfCanvas workflow

PdfCanvas does not directly expose simulateBold() or simulateItalic() because those methods belong to the higher-level Layout API rather than the low-level kernel API.

An application does not need to replace its entire rendering pipeline to use them. Instead, it can wrap the existing PdfCanvas with a Layout Canvas and use the wrapper only for text requiring layout-level simulated styling.

For example:

Java
PdfCanvas pdfCanvas = new PdfCanvas(page);

try (Canvas textCanvas =
             new Canvas(pdfCanvas, page.getPageSize())) {
    Text text = new Text(value)
            .setFont(font)
            .setFontSize(fontSize);
    if (bold) {
        text.simulateBold();
    }
    if (italic) {
        text.simulateItalic();
    }
    textCanvas.showTextAligned(
            new Paragraph(text)
                    .setMargin(0)
                    .setPadding(0),
            x,
            y,
            TextAlignment.LEFT,
            VerticalAlignment.BOTTOM
    );
}

The Layout Canvas is designed for adding layout content directly to a specified PdfCanvas. The constructor accepts the low-level canvas and the rectangular area available for layout.

Mixing PdfCanvas and Layout Canvas

A rendering pipeline may draw table geometry using PdfCanvas:

Java
PdfCanvas pdfCanvas = new PdfCanvas(page);

pdfCanvas.rectangle(x, y, width, height)
        .stroke();

It can then use the same underlying content stream to render styled text:

Java
try (Canvas textCanvas =
             new Canvas(pdfCanvas, page.getPageSize())) {

    Text text = new Text(value)
            .setFont(font)
            .setFontSize(fontSize)
            .simulateBold();
    textCanvas.showTextAligned(
            new Paragraph(text)
                    .setMargin(0)
                    .setPadding(0),
            textX,
            textY,
            TextAlignment.LEFT,
            VerticalAlignment.BOTTOM
    );
}

This allows an application to introduce simulated styles without redesigning the rest of its graphics rendering architecture.

Screenshot 2026-08-10 130728.png
Bold and italic simulation using PdfCanvas.

Example

The screenshots above were taken from this example document:

simulated-styles-example.pdf

Notes and Limitations

  • Where possible, you should use a genuine bold or italic font file. Simulation exists for cases where no such file exists - it should not be a substitute for genuine font styles.

  • Simulated styles are most noticeable at small font sizes, in print, and viewing at high zoom levels.

  • Simulation reuses the original glyph outlines, so operations such as copy-paste and text extraction behave normally. This is an advantage over alternatives such as rasterizing text.