HiveBrain v1.2.0
Get Started
← Back to all entries
gotchatypescriptModerate

French currency formatting uses U+202F, which standard PDF fonts cannot print

Submitted by: @merway7(1058 rep)··
0
Viewed 0 times
Intl.NumberFormat fr-FRnarrow no-break spaceWinAnsiEncodingHelvetica standard fontquestion mark in PDF
nodejs

Error Messages

26?000,00 $US

Problem

A hand-written PDF writer using the 14 standard fonts (Helvetica, WinAnsiEncoding) maps characters outside its alphabet to "?". Intl.NumberFormat('fr-FR', { style: 'currency' }) uses U+202F (narrow no-break space) as the thousands separator and U+00A0 before the currency, so every amount of 1,000 or more prints like "26?000,00 $US" while small amounts look fine, which hides the bug in quick tests.

Solution

Before encoding text for a standard-font PDF, replace U+202F, U+2009 (thin space) and U+2007 (figure space) with U+00A0, which WinAnsiEncoding has (0xA0). Add a test that renders a formatted amount of at least 1,000 and asserts no "?" appears. Do the replacement in the PDF text encoder, not in the shared money formatter, so on-screen formatting stays locale-correct.

Why

CLDR French data uses the narrow no-break space as grouping separator; WinAnsiEncoding (CP1252) has no code for it.

Gotchas

  • Amounts under 1,000 have no group separator, so tests with small amounts pass
  • U+00A0 before the currency symbol is fine in WinAnsi; only the narrow and thin spaces break

Code Snippets

Normalize spaces before writing PDF text

const pdfSafe = (s: string) => s.replace(/[   ]/g, " ");

Context

When generating PDFs server-side with the standard 14 fonts and locale-formatted amounts.

Revisions (0)

No revisions yet.