Skip to content

fix(pdf): Cyrillic in print templates renders as '#' - bundle DejaVu Sans for FOP#6124

Merged
delchev merged 1 commit into
masterfrom
feat/pdf-unicode-fonts
Jul 2, 2026
Merged

fix(pdf): Cyrillic in print templates renders as '#' - bundle DejaVu Sans for FOP#6124
delchev merged 1 commit into
masterfrom
feat/pdf-unicode-fonts

Conversation

@delchev

@delchev delchev commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Problem

Printing a document whose template contains non-Latin text (e.g. a Cyrillic title Фактура in the generated standard.print) produces a PDF where every non-Latin character renders as #.

Root cause: PDFFacade created a bare FopFactory with no font configuration, so Apache FOP only had its built-in base-14 fonts (Helvetica/Times/Courier). Those are metric-only, Latin-1 encoded fonts with no Cyrillic glyphs, and FOP substitutes # for every glyph the font lacks. XslFoRenderer additionally hard-coded font-family="Helvetica" at the fo:root.

Fix

  • api-pdf: bundle DejaVu Sans (regular/bold/oblique/bold-oblique + LICENSE, Bitstream Vera license - covers Latin, Cyrillic, Greek) under META-INF/fonts/dejavu and build the now-cached FopFactory from a font configuration that embeds them as subsets. The TTFs are extracted to a temp directory first because FOP cannot load fonts from inside a jar. If extraction fails, falls back to the unconfigured factory with a warning.
  • parsers-document: XslFoRenderer emits font-family="DejaVu Sans, Helvetica" so every generated print stylesheet picks up the Unicode font.
  • test: a Cyrillic XSL-FO template renders and the resulting PDF is asserted to embed a DejaVuSans subset.

Verification

mvn test -pl components/api/api-pdf,modules/parsers/document: 94 tests green, no FOP "glyph not available" warnings in the run.

🤖 Generated with Claude Code

…t with FOP

FOP's built-in base-14 fonts (Helvetica/Times/Courier) are metric-only and
Latin-1 encoded, and PDFFacade created a bare FopFactory with no font
configuration - so every non-Latin glyph in a print template (e.g. a
Cyrillic title in a Sales Invoice standard.print) rendered as '#'.

- api-pdf: bundle DejaVu Sans (regular/bold/oblique/bold-oblique, Bitstream
  Vera license) under META-INF/fonts/dejavu and build the (now cached)
  FopFactory from a font configuration that embeds them as subsets; the TTFs
  are extracted to a temp dir because FOP cannot read fonts from inside a
  jar. Falls back to the unconfigured factory with a warning if extraction
  fails.
- parsers-document: XslFoRenderer emits font-family="DejaVu Sans, Helvetica"
  so generated print templates pick up the Unicode font.
- test: Cyrillic template renders and the PDF embeds a DejaVuSans subset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev delchev merged commit d856634 into master Jul 2, 2026
12 checks passed
@delchev delchev deleted the feat/pdf-unicode-fonts branch July 2, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant