Why Korean text vanishes when you convert an .ai file to PNG
The bug that doesn’t announce itself
While building our .ai to PNG converter, we ran a real client file through it — a Korean poster layout, several artboards, mixed Latin and Hangul type. The PNG came out looking correct at a glance. Shapes were right, the placed photos were right, the Latin headline was right. Every character of Korean was gone.
Not garbled. Not replaced with boxes. Not shifted. Simply absent, as if those text frames had never been drawn. No error appeared in the console, no warning surfaced in the UI, and the file itself was fine — Illustrator opened it normally.
That silence is what makes this failure worth writing about. Most conversion problems tell you something went wrong. This one hands you a clean-looking image with a hole in it, and if the person converting the file doesn’t read Korean, Japanese, or Chinese, there’s a good chance it ships that way.
What’s actually missing: the CMap
To understand the cause, it helps to know what an .ai file is underneath. Illustrator saves most files with “Create PDF Compatible File” enabled, which embeds a complete PDF version of the artwork inside the .ai container. That embedded PDF is what any non-Illustrator tool — including a browser — actually reads. (We cover that structure in more detail in how to open an .ai file without Illustrator.)
Inside a PDF, a Latin font is usually simple: one byte per character, and a built-in encoding table says byte 0x41 means the glyph for “A”. That mapping is small enough to live inside the PDF itself.
CJK fonts can’t work that way. A Korean font covers thousands of syllables, a Japanese font tens of thousands of glyphs, and a Chinese font more still. PDF handles this with CID-keyed fonts: instead of referring to glyphs by a single byte, the text stream refers to them by a numeric glyph ID within a character collection — Adobe-Korea1, Adobe-Japan1, Adobe-GB1, Adobe-CNS1. The bridge between the bytes in the file and those glyph IDs is a separate table called a CMap, named in the PDF by identifier rather than embedded in it: UniKS-UTF16-H for Korean, UniJIS-UCS2-H for Japanese, UniGB- and UniCNS- variants for simplified and traditional Chinese.
The PDF names the CMap. It does not carry it. The reader is expected to already have it.
So when the renderer is asked to draw a run of Hangul, it looks up a CMap it was never given, gets nothing back, resolves zero glyphs, and draws zero glyphs. From the renderer’s point of view nothing failed — there was simply nothing to paint. That’s the silence.
Why a browser tool is especially prone to it
pdf.js, the PDF engine browsers and browser-based tools use, ships those CMap tables as a separate directory of compact binary files rather than bundling them into the main script. That’s a sensible default: the tables are large, and a viewer showing English invoices should not download Korean, Japanese, and Chinese mapping data on every page load.
The consequence is that pdf.js does nothing with CMaps unless you explicitly point it at them. Our copy of that data is 168 .bcmap files, part of a 198-file bundle of PDF support assets served from the site as static files. Enabling it takes two lines in the document-open call:
const task = pdfjs.getDocument({
data: buffer,
cMapUrl: '/pdf-assets/cmaps/',
cMapPacked: true,
standardFontDataUrl: '/pdf-assets/standard_fonts/',
});
Leave those out and everything still builds, still runs, and still renders — right up until someone converts a file with CJK type in it. Nothing in a Latin-only test suite catches it. We only caught it because we tested with a real Korean design file rather than a synthetic one, and the fix is now pinned in place with a comment in our source explaining exactly why the parameter cannot be removed.
We hit the same wall a second time on a different code path. Our .ai to SVG export runs on an older pdf.js build, because the SVG output backend was removed from newer versions. That path needed its own cMapUrl for the same reason, plus a flag to keep translated font data available — without it, the SVG font-embedding pass throws instead of failing quietly. Same class of problem, two different renderers, both requiring the fix independently.
Three symptoms, three different causes
If text is behaving strangely after a conversion, the specific symptom narrows the cause down quickly:
All CJK text is missing, everything else is fine. Missing CMap data, as described above. Latin type in the same file renders normally because simple fonts carry their encoding inside the PDF. This is the fingerprint of the bug: the loss is selective by script, not by frame or layer.
Text is present but the letterforms are wrong. The font wasn’t embedded in the file, so the renderer substituted a similar one. Spacing shifts, line breaks move, the design drifts — but nothing disappears. This is a font problem, not a mapping problem, and no amount of CMap data fixes it. The sender needs to embed the fonts or outline them.
Nothing renders at all — a blank page or a notice. The .ai was saved without “Create PDF Compatible File”, so there’s no PDF stream to read. Only Illustrator can recover that artwork; the file has to be saved again with the option on.
Worth checking in that order, since the first is invisible unless you can read the script in question.
How to protect yourself when handing files off
A few habits make this whole category of problem go away:
- Outline the type before handing off a file for image conversion. Once text is converted to paths, there’s no font, no encoding, and no CMap in the equation — just shapes. Keep an editable copy for yourself, since outlined text can’t be revised.
- Open the exported image and look for the text, especially if you don’t read the script it’s in. A converter that silently drops glyphs produces an image that passes a casual glance.
- Test conversion tools with a file in the script you actually use. An English test file proves nothing about Korean handling, which is precisely why this bug survives in so many quick self-hosted setups.
- If a tool loses your CJK text, that’s usually a configuration gap in the tool, not damage to your file. The file is intact; the reader is under-equipped.
What our converter does about it
All four of our .ai tools — PNG, SVG, PDF, and the viewer — load the full CMap set on both rendering paths, so Korean, Japanese, and Chinese text renders rather than disappearing. They also load substitute data for standard fonts that aren’t embedded, which is the difference between “close enough letterforms” and “no letterforms”.
Two honest caveats remain. Fonts that aren’t embedded in the file are still substituted, so text can look different from the original design — that’s a limitation of the file, not something a renderer can solve. And CMYK colors are converted to RGB for on-screen display, so print-critical color needs a check in Illustrator.
The other bug we found in the same testing session is worth mentioning as an example of how much of this work is empirical: in the current pdf.js version, the background parameter is painted opaquely, so asking for a transparent background produces solid black. Transparency in our PNG export is recovered by rendering each artboard twice — once on white, once on black — deriving per-pixel alpha from the difference between them, and un-premultiplying the result. It’s more work than it should be, and it’s there because we compared our output against a reference render pixel by pixel and found the discrepancy.
Both fixes came from the same place: running real design files through the tool instead of trusting that a clean-looking output is a correct one. Everything happens inside your browser either way — the file is never sent to a server, so testing a confidential client file against the tool costs you nothing but the time.