About this tool
Most Khmer users today work in Unicode — it is the encoding phones, browsers and modern design tools render correctly. But a real slice of professional work in Cambodia still runs on legacy Khmer fonts: print shops typesetting in Adobe InDesign CS6, sign cutters whose software only reads Limon bytes, government templates authored in Khek, publishers reprinting pre-2010 books laid out in ABC-Zwsp. Those workflows cannot open a Unicode file at all — they need the text as legacy bytes. This Unicode to Khmer legacy font converter bridges that gap: paste your modern Khmer text, pick Limon, ABC-Zwsp or Khek, and copy the encoded output or download it as a Windows-1252 .txt file the legacy tool can import. A Unicode to Limon conversion, a Unicode to Khek conversion and a Unicode to ABC-Zwsp conversion are three different byte outputs from the same input — the Khmer legacy font converter applies the exact table for whichever target you select, so the file you hand to the print shop draws correctly in their font. One honest note before you start: the output looks like gibberish Latin characters until it is opened inside the matching legacy font — that is normal, it is exactly how the legacy encoding works, not a bug.
How it works
Pressing Convert runs convertUnicodeToLegacy from lib/khmer-legacy-converter/converter.ts in your browser, under the encoding you picked — there is no auto-detect here because the input is already Unicode and the question is which table to emit, not which to decode. Each Unicode Khmer codepoint has a mapped byte in the target table, but the pass cannot simply swap one for one: Khmer subscripts are two codepoints in Unicode — U+17D2 (coeng) followed by a base consonant — while the legacy font stores the subscript as a single byte drawn below its base. The converter therefore reorders every cluster into the font's visual order first (reorder.ts: legacyReorder, which also inserts U+17EA position marks the emission pass consumes), so when it meets U+17D2 it looks ahead, consumes the following consonant codepoint, and emits the one subscript byte — this is where naïve implementations silently lose characters. Anything without a table entry passes through unchanged and is counted in the unmapped chip; spacing and line breaks pass through untouched. Inputs over 10 KB convert inside a Web Worker; smaller text runs on the main thread, entirely client-side — only size counters ever appear in anonymous telemetry. The output renders correctly only inside the matching legacy font, which is why the download writes literal Windows-1252 bytes rather than UTF-8.
Use cases
- A designer preparing a leaflet in Adobe InDesign CS6 where the Khmer font is Limon-only and the copy was written in modern Unicode.
- A print shop producing a wedding invitation on a legacy workflow that still runs on Limon fonts.
- A government officer formatting a document in an older template that requires Khek-encoded text to render on an unreplaced legacy printer.
- A publisher reissuing a classic Khmer book whose typesetting is in ABC-Zwsp and whose new material was written in Unicode.
- A software developer generating fallback Limon exports for users on older Windows systems without a Unicode Khmer font installed.
- A signwriter whose cutting software only accepts Limon byte input.
- An archivist preparing a legacy-font facsimile of a Unicode document for a publication that must match an original 1990s edition.
Verified conversion examples
| Encoding | Legacy text | Unicode Khmer |
|---|---|---|
| limon | sYsþI bgb¥Ún | សួស្តី បងប្អូន |
| limon | sMNYr nigcemøIy GMBI PasaExµr | សំណួរ និងចម្លើយ អំពី ភាសាខ្មែរ |
| abc-zwsp | sYsþI.bgbðÚn | សួស្តី បងប្អូន |
| abc-zwsp | qñaM.2026.Ex.11 | ឆ្នាំ ២០២៦ ខែ ១១ |
| khek | sYs¶I bgbíèn | សួស្តី បងប្អូន |
| khek | ekµg@kMBugeronGk§rExµr enAsalaeron | ក្មេងៗកំពុងរៀនអក្សរខ្មែរ នៅសាលារៀន |
Frequently asked questions
Why would I ever go FROM Unicode TO legacy?
Because the receiving end still runs on a legacy font. Print shops with Limon-licensed DTP templates, sign-cutting software that only reads Limon bytes, government forms authored in Khek, and reprints of pre-2010 publications laid out in ABC-Zwsp cannot open Unicode Khmer at all — the glyphs come out as Latin gibberish. If the workflow you are feeding is legacy, the file you hand over must be legacy too.
Which legacy encoding should I pick — Limon, ABC-Zwsp or Khek?
Pick the font the receiving tool actually has installed. Limon is the usual answer for older Windows-era DTP workflows and print shops; ABC-Zwsp suits pipelines that expect the ABC family with zero-width-space-style word markers; Khek is mostly government and administrative templates. If you do not know, ask the print shop or check which font appears in the document font list — converting under the wrong table produces output that is gibberish even inside their font.
Will my output open in Adobe InDesign CS6 or Microsoft Publisher 2003?
Yes, provided the machine has the matching legacy font installed and you hand it bytes, not UTF-8. The download button writes a Windows-1252 .txt file — the literal byte values those applications read — so InDesign or Publisher interprets them through its Limon, ABC-Zwsp or Khek font exactly like a document typed there in the first place. Saving as UTF-8 instead would double-encode the high bytes and break the file.
Why do some characters come back blank in the output?
The legacy fonts predate parts of the Unicode Khmer block, so some characters — rare signs, newer letters, symbols — have no byte to map to. Unmapped characters pass through unchanged rather than being guessed at, and the chip under the output counts each distinct one with its code point. Inside the legacy font such characters usually render as blanks or boxes; editing them by hand in the target application is the correct fix.
Will the tool preserve my spacing and line breaks?
Yes — spaces, tabs and line breaks are not glyph slots in these tables, so they pass through untouched and your paragraph structure survives the conversion intact. One deliberate exception is ABC-Zwsp, whose format marks word boundaries with its own separator byte; that is part of the encoding itself, not lost whitespace, and the target application expects it.
What about Khmer digits — do they get converted too?
Yes. Khmer digits U+17E0–U+17E9 map to the ASCII digit bytes 0–9, which is how the legacy fonts draw them — ២០២៦ comes out as 2026, and the font paints the Khmer digit shapes. Mixed text like a year next to a Khmer word converts in one pass, so a line such as ឆ្នាំ ២០២៦ ខែ ១១ needs no separate handling.
Is this a one-way conversion? Can I round-trip?
For characters inside the table it round-trips exactly — converting Unicode to Limon and back returns the same Khmer string, which the test corpus verifies on every build. A handful of rare structures are documented as lossy in the font data itself (the legacy font never represented them faithfully), and characters outside the table pass through unchanged rather than being approximated.
Why does the output look like gibberish in my browser?
Because it is meant to. The output is not text any modern renderer understands — it is a bag of legacy byte codes that only draws Khmer inside the matching font, which is precisely what the receiving workflow needs. Pasting it into a Unicode editor will always show Latin-1 gibberish; to see Khmer you open it where the Limon, ABC-Zwsp or Khek font is installed.
Can I preview the output in the legacy font here?
Not yet — the preview panel ships collapsed with an explicit note because the legacy font files have licensing terms we have not finished reviewing. Showing the bytes without the font is honest but useless, so for now the check is: does the unmapped chip report zero, and does the downloaded .txt open correctly in the target application.
Does my text leave the browser?
No. The mapping tables ship with the page and the conversion is pure local computation — large inputs run in a Web Worker, never on a server. The only telemetry is an anonymous event carrying counters like input length and unmapped count; the text you paste and the bytes produced are never transmitted or stored.
Data and accuracy
The three mapping tables live in lib/khmer-legacy-converter/mappings/ and are resolved from fontdata.xml in the KhmerConverter project — the open-source converter the Khmer Software Initiative (KhmerOS) has maintained since 2006 for Limon, ABC, Khek and other legacy Khmer fonts. The page converts entirely in your browser; the only promise about the output is the table itself, which is why the round-trip corpus in the same library regression-tests every shipped pair. A wrong result means the selected encoding does not match the receiving font — the fix is choosing the right table, not stale data.
Sources
- Khmer — Unicode code chart U+1780–U+17FF — Unicode Consortium
- KhmerConverter — Khmer Software Initiative legacy-font converter (fontdata.xml tables) — Khmer Software Initiative / KhmerOS (GitHub)
- This tool’s own page — InKhmer
Content last reviewed 8 November 2026