RAWA Engineering

Arabic on ESC/POS thermal printers: a reference for reliable receipts and kitchen tickets

فريق هندسة RAWA · 2026-11-09

ملخص بالعربية: ورقة مرجعية بالإنجليزية عن حل مشكلة الطباعة العربية على الطابعات الحرارية: أربعة أسباب برمجية (جدول حروف، تشكيل، ترتيب يمين-يسار، تجاوز الذاكرة) والحل: رسم الإيصال كصورة بعرض الورق وإرساله شرائح من 128 سطراً باتصال قصير على المنفذ 9100.

Whitepaper · RAWA Engineering · rawaerp.com · runnable example: github.com/rawaerp/arabic-thermal-printer-escpos-guide

Problem

Arabic receipts that print as ?????, as disconnected letters, in reversed word order, or that start well and degrade halfway are the most common hardware complaint in Arabic-market POS deployments. They look like printer faults; they are four distinct software problems.

Root causes

  1. No Arabic code page on the printer model, or none selected.
  2. No shaping. Arabic letters take different forms depending on their neighbours; printers do not join them.
  3. No bidirectional reordering. Right-to-left text with embedded numbers needs the Unicode bidi algorithm.
  4. Receive-buffer overrun. A cheap network printer has a small buffer; one large job can overflow it.

Fixing 1–3 in text mode means different handling for every printer brand supported.

Architecture: render on the host, send raster in bands

  1. Shape and reorder the text on the host (arabic-reshaper + python-bidi, or the browser's own text engine).
  2. Draw the receipt onto a canvas exactly as wide as the paper in dots — 576 for an 80 mm head, 384 for 58 mm, always a multiple of 8.
  3. Binarise and encode as ESC/POS raster GS v 0, in bands of 128 rows, each band self-contained.
  4. Network printers: one short TCP connection per band to port 9100, ~50 ms pause. Idle sockets to cheap printers drop; per-job connections are boring and reliable.
  5. Frame the job: ESC @ first; optional drawer pulse ESC p 0 25 250; LF LF LF then GS V 66 0 (feed and partial cut).

The host decides what is on the paper, so the same bytes print the same on every printer. The trade-offs are real and stated: more bytes per receipt (tens of KB) and slower Bluetooth links — hence compact receipts.

Operational rules

Reference implementation

A symptoms → causes → fixes table, a network checklist and a runnable example that works without a printer (--out receipt.bin --png preview.png) are open source: github.com/rawaerp/arabic-thermal-printer-escpos-guide. RAWA prints receipts and kitchen tickets this way over network, USB and Bluetooth on standard 80 mm ESC/POS printers. Hardware: https://rawaerp.com/guide/pos-hardware-jordan

Common questions

Why do Arabic receipts print as question marks or disconnected letters?
Four distinct causes: no Arabic code page on the printer, no letter shaping, no bidirectional reordering, and receive-buffer overrun on cheap network printers.

What image width should I use?
The printable width in dots as a multiple of 8: 576 for an 80 mm head and 384 for a 58 mm head.

Why send the image in bands?
A cheap network printer has a small receive buffer; sending 128-row bands, one short connection per band to port 9100 with a short pause, avoids overruns and half-printed receipts.