FRM← back to projects02 / 10

02 / CASE STUDY

ENGINEERING CASE

Invoice Renderer.

Five scripts in oneinvoice that stays readable.

Guestpedia's PMS serves hotels with international guests. Group invoices and reports are exported as PDF, and guest names arrive in Arabic, Chinese, Japanese, Korean, and Cyrillic.

STATUS
PRODUCTION
INPUT
GUEST NAMES
OUTPUT
PDF

BUILT WITH

  • jsPDF
  • Canvas API

Guest names in five scripts have to stay readable in a PDF that reaches real hotel guests.

01 / PROBLEM

The built-in PDF fontsstop at Latin.

jsPDF ships only the 14 standard PDF fonts, all of them Latin. Embedding full CJK font files adds megabytes to every export, while Arabic needs right-to-left layout with contextual letter shaping. jsPDF's text API does not do that. The naive result: invoices full of empty boxes, sent to real hotel guests.

02 / APPROACH

Draw the textin the browser first.

Instead of fighting font embedding, text rendering moved into the browser itself. A canvas-based renderer draws each text run using the browser's own text engine, which already handles bidirectional layout, Arabic shaping, and CJK glyphs through system fonts. The rasterised output is then composited into the PDF via jsPDF's image API.

DETECTIONOne regex per run decides the path.
RESOLUTION2× supersampling keeps print sharp.
CALIBRATIONA 0.82 factor matches canvas to vector sizing.

03 / TRADE-OFF

What that resultactually costs.

Canvas-drawn text becomes an image: not selectable, not searchable inside the PDF, and dependent on the browser's system fonts. That is acceptable for guest names but not for body text. Latin runs stay on jsPDF's crisp, selectable vector path for exactly that reason. The same renderer serves group invoices, the Sales Additional Charges report, and Excel exports.

DECISIONS

Why it is builtthis way.

  1. 01
    Non-Latin scripts drawn on canvas

    The browser's text engine already handles bidi layout, Arabic shaping, and CJK glyphs. Embedding full CJK fonts would add megabytes to every export.

  2. 02
    Latin stays on the vector path

    Canvas text becomes an image that cannot be selected or searched. That is fine for guest names and wrong for body text.

  3. 03
    One renderer for every export

    Group invoices, the Sales Additional Charges report, and Excel exports all share the same renderer.

NEXT PROJECT

PLTS Solar Monitoring03 ↗