Invonest Logo
Invonest

Why Arabic and Kurdish Text Breaks in PDF Invoices (and How to Fix It)

6 min read
RTL
PDF
Kurdish
Arabic
Technical
I

Invonest Team

The Invonest team builds invoicing tools from Duhok, Kurdistan Region of Iraq, with a focus on Arabic and Kurdish language support.

A technical explanation of the three separate problems that mangle right-to-left text in generated PDFs: bidirectional ordering, letter shaping, and font embedding, plus what actually solves each one.

If you have ever generated a PDF invoice containing Arabic or Kurdish and received back a jumble of disconnected letters in reverse order, you have run into one of three distinct technical problems. They have different causes and different fixes, and diagnosing which one you have saves a lot of wasted effort.

This is a technical article. If you just want invoices that work, the short version is at the end.

The Three Problems

Text that looks correct in your browser and breaks in the PDF has usually hit one of these:

  1. Bidirectional ordering — the characters are correct but arranged in the wrong visual order
  2. Letter shaping — the characters are in the right order but not joined into words
  3. Font embedding — the glyphs are not in the PDF at all

They can occur together, which is why the output sometimes looks catastrophically wrong rather than subtly off.

Problem 1: Bidirectional Ordering

Text has two orders: logical (the sequence characters are stored in) and visual (the sequence they are drawn in). For English these are identical. For Arabic and Kurdish they are not.

The Unicode Bidirectional Algorithm resolves logical order into visual order. It handles the hard cases: an Arabic sentence containing an English word, a phone number inside Arabic text, punctuation at a direction boundary.

Browsers implement this algorithm. Most PDF generation libraries do not. They draw characters in storage order, left to right, which produces reversed Arabic.

The tell: the letters are individually correct and correctly shaped, but the word reads backwards.

The fix is to run text through a bidi implementation before handing it to the PDF library, so you pass already-reordered visual-order text. You cannot skip this by setting an alignment property — alignment moves the text block, it does not reorder characters within it.

A subtlety worth knowing: numbers embedded in RTL text stay left-to-right. A naive "just reverse the string" fix breaks every account number and amount on the invoice. This is why string reversal is not a solution, only a different bug.

Problem 2: Letter Shaping

Arabic script is cursive. Every letter has up to four forms depending on its position: isolated, initial, medial, and final. Correct text joins these into connected words.

Unicode stores the abstract letter, not the positional form. Something has to select the right shape based on neighbours — normally the font's OpenType shaping tables, executed by a shaping engine.

Browsers ship a shaping engine. PDF libraries generally do not. You get isolated letter forms sitting next to each other, unconnected.

The tell: text runs in the right direction but looks like separated letters rather than words.

There are two routes to fixing this. Either use a rendering path that includes a shaping engine, or pre-shape the text by substituting the correct positional forms before drawing. Pre-shaping is fiddly and has edge cases around ligatures — the lam-alef combination in particular is a mandatory ligature that has to be handled as a unit, not as two letters.

Kurdish adds its own characters

Kurdish written in Arabic script (Sorani) uses letters that Arabic does not:

  • ڕ — r with a V below
  • ڵ — l with a V above
  • ۆ — o
  • ێ — e
  • ک and ی — Kurdish uses the Persian-style keheh and yeh rather than the Arabic kaf and yeh

This matters practically: a font with complete Arabic coverage may still lack Kurdish letters. You get correct Arabic and missing boxes wherever a Kurdish-specific character appears. Anyone building for the Kurdistan Region needs to test with Kurdish text specifically, not assume Arabic support covers it.

Kurdish also has vowels written as full letters where Arabic uses optional diacritics, so Kurdish text tends to be longer than the equivalent Arabic and needs more horizontal room in table cells.

Problem 3: Font Embedding

PDF is not HTML. It does not fetch fonts at display time. Whatever glyphs the document needs must be inside the file, or the reader substitutes something else.

Standard PDF base fonts contain no Arabic glyphs at all. If you do not embed a font with Arabic and Kurdish coverage, the reader falls back — and the fallback varies by machine. Your invoice looks fine on your computer and arrives as empty boxes on the client's.

The tell: boxes, blank space, or question marks instead of characters. Or, more insidiously, correct rendering on your machine and broken rendering on theirs.

The fix is to embed a font that covers the full range you need. Subsetting keeps file size manageable, but the subset must include every character actually used — a subsetter that only walked your Latin text will drop the Arabic.

Fonts worth knowing for this region include Rabar, Speda and Rudaw, which were designed for Kurdish and carry the Kurdish-specific letters, alongside broader families like Noto Sans Arabic. Coverage varies, so verify rather than assume.

Why the HTML-to-Canvas Route Is Tempting and Imperfect

A common approach is to render the invoice as HTML, screenshot it with a canvas library, and place the image into a PDF. Since the browser handles bidi and shaping correctly, the text looks right.

It works, and for many cases it is the pragmatic choice. But understand the tradeoffs:

  • The text is no longer text. It cannot be selected, copied, or searched. A client cannot copy your IBAN out of the invoice.
  • It is not accessible. Screen readers get nothing.
  • File size grows substantially compared to a text-based PDF.
  • Resolution is fixed at capture time. Zooming reveals pixels.
  • Machine-readable extraction fails, which matters if the client's accounting system parses invoices.

For an invoice specifically, the copy-paste problem is the serious one. Payment details that cannot be copied get transcribed by hand, and hand-transcribed IBANs get typos.

How to Diagnose Your Own Output

Generate a test PDF containing one line of Arabic, one line of Kurdish including ڕ ڵ ۆ ێ, an IBAN, a date, and a decimal amount. Then:

  • Boxes or blanks? Font embedding problem.
  • Correct shapes, backwards words? Bidirectional ordering problem.
  • Right direction, disconnected letters? Shaping problem.
  • Arabic fine, Kurdish letters missing? Font lacks Kurdish coverage.
  • Numbers reversed? Something is naively reversing strings.
  • Fine on your machine, broken elsewhere? Font not embedded, only installed locally.
  • Cannot select the text? You are on the image-based path.

The Short Version

If you are choosing an invoicing tool rather than building one, test it before you trust it. Generate an invoice with real Arabic or Kurdish content, open it on a different computer, and try to select and copy the account number.

Most tools that claim multilingual support have only translated their interface labels. The invoice output is where it either works or does not, and that is the document your client actually receives.

If you are building this yourself: handle bidi ordering, handle shaping, embed a font with the coverage you need, and test with Kurdish rather than assuming Arabic support is sufficient. There is no single library switch that solves all three.

More Articles

How to Create Professional Invoices for Freelancers

A comprehensive guide on creating professional invoices, including essential elements, formatting tips, and best practices to get paid faster.

Top 5 Invoice Templates for Freelancers and Small Businesses

Discover the best invoice templates for different needs, including hourly and flat-rate options.