I have written a guide on how to use CJK fonts with English in Entity Print

Created on 6 August 2021, almost 3 years ago
Updated 19 January 2024, 5 months ago

Here’s how to make Chinese and English work in Entity Print (and Commerce Invoice) with dompdf.

I spent a few days researching this and trying various things. This guide will save time for people who are in the same situation.

-Situation:

TLDR: Font fallback works great in HTML with browsers. CJK scrips and Latin scrips are displayed properly and managed by the browser. This is not the case with dompdf and consequently Entity Print or Commerce Invoice.

There seems to be a problem with dompdf not respecting the font fallbacks, at least CJK fonts (I assume this isn’t an issue for other non-Asian Unicode fonts).

Example:

CSS settings:
* {font-family: DejaVu Sans, Firefly Sung, sans-serif;}

PDF with English and Chinese elements.
Expected behavior:
English font being the main one, Chinese font being the fallback for characters that are not covered by the English font.
Actual behavior:
Everything is shown using the DejaVu Sans font. Chinese characters are squares/empty spaces/question marks.

If I reverse the settings:
* {font-family: Firefly Sung, DejaVu Sans, sans-serif;}
Expected behavior:
Chinese font being the main one… well, Chinese font has Latin script so there is no sense for a fallback.
Result:
Whole PDF rendered using the Chinese font.

Ofc, I can specify a font per element, but most elements will have mixed English and Chinese anyway. Not to mention that Chinese language uses pinyin which is based on Latin script, and that pinyin can be useful in some website situations as well.

My Workaround:

I. What to keep in mind.

- make sure you’re using an updated version of dompdf library. As per this issue: related issue →
- as fallback doesn’t work, you are limited to only one font for most of the PDF.

There is an exception: You can style certain elements to use a different font, if you’re sure they don’t use mixed Latin and Chinese characters.

- The font we will use is a large file. You need to enable subsetting unless you want to make PDF files that won’t even fit an email attachment. [how to enable subsetting] →

II. Which font to choose?

It has to be a font that’s a full CJK font that includes Latin script as well.
There’s a list on Wikipedia: CJK Fonts List

Note on DroidFallback font: It won’t be useful as the one that has both CJK and Latin scripts is a .tcc format which isn’t supported by dompdf. The .tff DroidFallbackFull does not contain Latin script, so you end up having squares/spaces/question marks on Latin part.

Note on Noto Sans: It does not have a .tff version. Just .tcc. Once again, useless.

This narrows down the choices for us, at least if we want to use Chinese. (will be different for the Japanese and Korean).

Firefly Sung which is a small file and recommended by the dompdf in their discussion.
+ works
+ small file (not that it matters tho)
- A very ugly Latin script that resembles Times New Roman.
ArialUnicodeMS.
+ Good looking Latin script.
+ Wide coverage of scripts.
- Large font file.

III. Configuration.

CSS file should have these rules included:

@font-face {
  font-family: 'cjkfont';
  font-style: normal;
  font-weight: 400;
  src: url(../fontspdf/[cjkfont_name_here].ttf) format('truetype');
}

* {
  font-family: 'cjkfont', DejaVu Sans, Courier, sans-serif;
}

Your_template_name.libraries.yml part:

print-styling:
  css:
    theme:
      css/print-style.css: { }

Your_template_name.info.yml part:

libraries-extend: (optional, only needed if you’re using Commerce Invoice)
  commerce_invoice/entity-print-styling:
    - Your_template_name /print-styling

entity_print:
  node:
all: Your_template_name /print-styling'

IV. The Bottom Line.

In the end you will have one big font. That gets cached by dompdf in your tmp location. The first run (the first time you use print) will be the most taxing on your system.

Thankfully with versions of dompdf other than 0.8.0 (which ends up filling up whole memory) and other than 0.8.6 (which for some reason keeps making new temp file and never completes). Using dompdf versions like 0.8.4 and 1.0.2 work, as I have tested them.

And after the font is cached, it will be smooth sailing from then on.

You will have as a result PDFs that look like this one. (attached pdf)
Note, that some elements like the header link still show question marks. That’s because it’s selected to use a specific font (Arial), one that doesn’t have CJK support. So you need to override that CSS with yet another rule pointing to your CJK.

Maybe one day it will work like in browsers. That we can have English and CJK script alongside in every element without any of this work. But for now this seems to be the best way of getting to having both English and CJK script in your PDFs. And with ArialUnicodeMS it won’t even look that bad.

📌 Task
Status

Active

Version

2.2

Component

Documentation

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇨🇳China lawxen

    I found some font-weight settings of css will make corresponding Chinese can't display (ps: I don't know why)
    So I add font-weight: normal !important; to * {}, Then everything works

      @font-face {
        font-family: 'Firefly Sung';
        font-style: normal;
        src: url(/themes/custom/mytheme/fonts/fireflysung.ttf) format('truetype');
      }
      * {
        font-family: 'Firefly Sung', DejaVu Sans, Courier, sans-serif;
        font-weight: normal !important;
      }
  • 🇨🇳China lawxen

    Issue summury has mentioned of the cache, I say something in detail to help people who get stuck in this problem:

    Above css will install the newly font farmily to the site's temporary folder:

Production build 0.69.0 2024