Which fonts survive "print to PDF" as real fonts, and which ones turn into drawing instructions? That decides what a PDF-to-HTML converter can later hand back to a browser as a web font. The fsType flag in the font's OS/2 table is the obvious suspect. In the one test below, it explained two of three fonts and nothing for the third.
Three fonts, six fsType values each
The test is small. I took Pacifico and Liberation Sans (both TrueType outlines) and Noto Serif SC (CFF outlines in an .otf), all open-licensed. For each one I made six local copies with fsType set to 0, 2, 4, 8, 256 and 512, and printed one page of mixed English and Chinese text to PDF with Chromium 149. Then I read the font objects out of each PDF. The modified copies never left my machine.
For the TrueType fonts the flag mattered. Values 4 and 8 gave a normal embedded subset. Values 2 and 512 gave no embedded font at all, and the glyphs were written as Type 3 outlines instead. Value 256, the "no subsetting" bit, made Chromium embed the whole font: the Liberation Sans PDF went from 85,024 to 502,702 bytes.
Noto Serif SC ignored all of that. At 0, 2, 4, 8, 256 and 512 the PDF contained Type 3 fonts only. Value 0 is "installable embedding", the most permissive setting there is, so in this test the flag was not what pushed this font out of the embedded path.
python3 - NotoSerifSC-fsType0.pdf NotoSerifSC-fsType512.pdf Pacifico-fsType0.pdf Pacifico-fsType512.pdf <<'P'
import sys, fitz
from collections import Counter
for p in sys.argv[1:]:
d = fitz.open(p)
ids = {f[0]: f[2] for pg in d for f in pg.get_fonts(full=True)}
print(p, dict(Counter(ids.values())))
P
NotoSerifSC-fsType0.pdf {'Type3': 29}
NotoSerifSC-fsType512.pdf {'Type3': 29}
Pacifico-fsType0.pdf {'Type3': 24, 'Type0': 2}
Pacifico-fsType512.pdf {'Type3': 28}
The counts are PyMuPDF's view of one page. I do not know why it is 29 and not 1, and I did not dig into it. The Pacifico row is a useful contrast: at fsType 0 there are two Type0 objects, which are the embedded TrueType subset of Pacifico, and at 512 there are none. The Type 3 objects next to them come from the Chinese line, which fell back to a system font I did not identify.
What I know and what I am guessing
What I know is narrow. In this one test, with one CFF font, on Chromium 149 on one Mac, every fsType value ended in Type 3, and the two TrueType fonts did not behave that way.
The explanation I find most plausible is that Chromium's PDF writer has an embedding path for TrueType outlines and no equivalent for CFF outlines inside an OpenType wrapper, so those fonts get drawn glyph by glyph as Type 3. That is a guess. I did not read the Chromium or Skia source, I did not test a second CFF font, and I did not try another Chromium version. If Noto Serif SC is odd for some other reason, such as its size or its CJK coverage, my test cannot tell. So the "always" I was tempted to put in the title is really "every time in this test".
What it did to the PDF-to-HTML step
I ran these PDFs through ImgIng (https://imging.ai/), a browser-based PDF-to-HTML tool that is in Beta, runs in desktop browsers and processes the file locally. The outputs matched the font types in the PDF. The TrueType subsets became inline woff fonts holding only the glyphs the page used. The six Noto Serif SC PDFs got no inline font at all: every glyph became a path, with a transparent text layer on top set in Arial, sans-serif so the text can still be selected. In the fsType 2 case, the Pacifico text still looked like Pacifico, because paths do not need the font.
Paths keep the shape, but they give you no font file to reuse. A subset is not a reusable font either way, since it holds only the used characters. The takeaway from this one test is small: for the CFF font I tried, the outline flavor of the file mattered, and the license flag did not.
If you hit Type 3 where you expected a real font, it may be worth checking whether the file is TrueType or CFF before you look at fsType; that is my suggestion from one font, not something I verified more widely. On the PDFs you already have, the snippet above shows how many font objects are Type 3 and how many are embedded.
Top comments (0)