printpdf
printpdf copied to clipboard
TTC and OTC font files cause Rusttype(IllFormed)
Reading opentype fonts(.otf) or truetype collection files (.ttc) causes panic!
let mut font_reader = std::io::Cursor::new(include_bytes!("../assets/fonts/Cantarell-Bold.otf").as_ref());
let font = doc.add_external_font(&mut font_reader).unwrap();
The second line caused panic, and retrun Rusttype(IllFormed). I tried .ttc file and this also failed.
Yes, rusttype doesn't support TTC and OTF files, only TTF (and OTF fonts that are a direct wrapper of a TTF font). The question is whether I'd want to go back to using freetype because it caused compliation problems on Windows.
Perhaps it would work to use https://github.com/pcwalton/font-kit?
No, font-kit is for finding fonts on the computer, not decoding them (it uses freetype for that). It's a completely different tool, it has nothing to do with decoding fonts.
font-kit let's you get the metrics for fonts using the system font libraries. i.e. CoreText on Mac and DirectWrite on Windows. By default it will only use FreeType on Linux.
Is there information that printpdf needs to get from the fonts that font-kit doesn't provide?
I wonder if we could replace rusttype with the allsorts crate.
It seems rusttype
is going to support OTF in a future release by using ttf-parser
.
According to the changelog :
Unreleased
- Major rework to use crates ttf-parser & ab_glyph_rasterizer to respectively read and render OpenType .oft [sic] format fonts.
rusttype
now supports OTF (from release 0.9.0). From the changelog:
Major rework to use crates ttf-parser & ab_glyph_rasterizer to respectively read and render OpenType .oft format fonts.
So this issue should be resolved by just updating rusttype to 0.9, shouldn't it?
It's good to hear that rusttype now supports OTF, but at some point I have to refactor it with something like a FontMetricsProvider
trait - so that you can add a font from both freetype AND rusttype. Right now rusttype still doesn't do any font shaping, which might be an issue.
Any updates on this? I'll take a stab at it myself. It's holding up the hack to get around #2, too.
I tried updating to rusttype 0.9, but ran into some refactoring errors. You just need to update the crate and fix the resulting compilation errors.
I think I've got it mostly sorted, just have to fix a few glyph size issues. Seems the rusttype guys ditched some key 0.8 apis that don't have direct equivalents.
It now handles .ttf
s just as it used to. It's fine in that regard.
~~It now too can embed and use .otf
glyphs, but there's no spacing and it appears that what text I give it and what text it outputs is (char + 44)
, (i.e., -
-> q
) for some reason.~~ This happens when loading Zilla Slab TTFs too.
I've only modified a small portion of the code, so I know what part is breaking it, but I'll have to work at it a little more.
I'll get a PR open ASAP.
I'm a little stumped right now. The font embeds fine, but glyphs are mapped wrong, and what they're mapped to depends on the font.
For Zilla Slab Highlight Bold, the PDF contains "O" (0x004F
) but displays Ć (0x0106
).
Furthermore, there's a complete lack of spacing. Characters simply stack on top of each other (though I can see this being a totally different problem).
Again, these only apply to external fonts, both OTF and TTF.
My changes are at eitasuka/printpdf and the above broken pdf in this gist.
@eitasuka It's likely because the Subtype
of the font in the font descriptor is wrong.
See: https://github.com/fschutt/printpdf/commit/209bb910a19dc37fd7eac2d6c60c14f6387b84fb - you have to use the correct Subtype
, since it's now OTF (CidFontType0C
) instead of TTF (CidFontType2
). I'll have to look up what the correct type is, the PDF spec has more info.