Fonts and Languages | |
HTML is rendered by a Chromium engine, which takes the fonts a page asks for from the computer it runs on, and text the library draws itself (headers, footers) uses fonts from the same place. On Windows and macOS that just works: both come with fonts for every major script. A Linux server, and almost every Linux container image, comes with few fonts or none.
SelectPdf brings three things to deal with that, from the smallest to the most complete: fonts built into the library, the SelectPdf.Universal.Fonts package, and your application's own fonts folder.
The library carries the Liberation fonts (Sans, Serif and Mono, regular, bold and italic), which have the same measurements as Arial, Times New Roman and Courier New. When the computer has no font for one of those families, or for the generic families sans-serif, serif and monospace, these are used, so a page in a Western European language prints correctly on any Linux host, even one with no fonts at all.
They cover Latin, Greek and Cyrillic text only. Without other fonts, every other script prints as empty boxes.
The SelectPdf.Universal.Fonts package contains Google's Noto fonts (SIL Open Font License 1.1): Sans, Serif and Mono for every script Noto covers - Latin, Greek, Cyrillic, Arabic, Hebrew, the Indic and Southeast Asian scripts, Georgian, Armenian, Ethiopic, Tibetan and more - plus Noto Sans CJK for Chinese, Japanese and Korean (regular and bold) and Noto Color Emoji. About 270 files and 92 MB.
Reference it next to the other two packages:
<ItemGroup> <PackageReference Include="SelectPdf.HtmlToPdf.Universal" Version="26.4.0" /> <PackageReference Include="SelectPdf.Universal.Native.linux-x64" Version="26.4.0" /> <PackageReference Include="SelectPdf.Universal.Fonts" Version="26.4.0" /> </ItemGroup>
On build and publish the fonts are copied to fonts/noto next to the application, where the Chromium engine and the library find them; nothing has to be installed on the server and no setting is needed. They are used only for text the computer has no font for: fonts installed on the computer still win.
Use it for every deployment to Linux - containers, AWS Lambda, Azure App Service for Linux, Google Cloud Run - unless you know the target has the fonts your pages need.
The fonts are not copied when the application is built for a Windows runtime identifier (win-x64, win-x86), because Windows has these scripts already. To leave them out of any other build, set the SelectPdfFonts property to false.
When your HTML asks for a font by name - a corporate font, for example - that the server does not have, put the font files (.ttf, .otf, .ttc) in a fonts folder of your project and have them copied to the output:
<ItemGroup> <None Include="fonts\**" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" /> </ItemGroup>
The folder ends up next to the application, and SelectPdf uses its fonts on every platform, with or without the fonts package (whose files go to the noto subfolder of the same folder):
Linux - the Chromium engine is pointed at the folder, so the fonts behave exactly like installed fonts.
Windows and macOS - Chromium looks only at the fonts installed on the computer there, so SelectPdf offers each font of the folder (outside noto) to the page as a web font. A page asking for the family by name gets it. Fonts over 16 MB, and fonts past 32 MB in total, are not offered.
Text the library draws - CreateFromSystemFont(String, Single) and PdfSystemFonts find the families of the folder too, after the fonts installed on the computer.
With the font in place, nothing else changes in the code:
// fonts/LobsterTwo-Regular.otf is copied next to the application HtmlToPdf converter = new HtmlToPdf(); // text drawn by the library finds the font too converter.Options.DisplayHeader = true; converter.Header.Height = 40; PdfFont font = PdfFont.CreateFromSystemFont("Lobster Two", 14); converter.Header.Add(new PdfTextSection(0, 10, "Monthly report", font)); // and so does the page PdfDocument doc = converter.ConvertHtmlString( "<p style=\"font-family: 'Lobster Two'\">Hello</p>"); doc.Save("report.pdf"); doc.Close();
Check that the license of each font allows you to distribute it with your application. |
Fonts installed in a Linux image the usual way (apt-get install fonts-noto-core fonts-noto-cjk on Debian and Ubuntu, dnf install google-noto-cjk-fonts on Amazon Linux) are used too, even on minimal images that do not include fontconfig's own configuration. The fonts package does the same without a package manager, which also covers platforms where the image cannot be changed, such as Azure App Service for Linux.