Adding custom fonts
PDF prescribes a set of standard fonts that are available to all PDF viewers and can be used without embedding them specifically. This allows to keep generated PDF file size to a minimum. ReportBro supports all Latin text typefaces (Courier, Helvetica and Times) of these standard fonts.
While a browser is able to display e.g. Chinese characters by default (it can use any available font from the computer as fallback) printing PDF is limited to the available typefaces of a specific font. That's why custom fonts have to be added to both ReportBro Designer and ReportBro Lib in order to embed the font itself into the generated PDF.
In this tutorial you will learn how to:1 Find suitable fonts to add
You can embed any TrueType Font (TTF) file into ReportBro - however, you must make sure
that the license of the font allows embedding.
The PyFPDF library (predecessor of the pyfpdf2 library used by ReportBro for PDF rendering) shares a collection of useful fonts,
e.g. the DejaVu font family (supporting more than 200 languages) or Firefly (
an open source Chinese font).
It can be downloaded from Github:
Free Unicode TrueType Font Pack
2 Include a custom font in ReportBro Designer
Now that we figured out which fonts we'd like to add (DejaVu and Firefly) we create a project folder
which contains:
- additional_fonts.html
Follow the instructions
to initialize ReportBro Designer
- dist the ReportBro Designer dist directory
- fonts directory including the font source files:
- fireflysung.ttf
- DejaVuSans.ttf
With this setup we are ready to configure ReportBro Designer. This is all done in the <head> of additional_fonts.html:
Specify the @font-face
By specifying the @font-face with inline CSS we let the browser know where to find the fonts for correct font rendering. There is no need to define font-weight or font-style here, font-family and src is all we require.
<style type="text/css">
@font-face {
font-family: "dejavusans";
src: url("fonts/DejaVuSans.ttf");
}
@font-face {
font-family: "firefly";
src: url("fonts/fireflysung.ttf");
}
</style>
Initialize the font as part of ReportBro
Because we'd like ReportBro Designer to add the fonts to its font dropdown selection list, we need to include them to the ReportBro initialization using the additionalFonts option. The value must match the value set for font-family in the @font-face definition! The name will be displayed to the user in the dropdown.<script type="text/javascript">
const rb = new ReportBro(document.getElementById('reportbro'), {
additionalFonts: [
{ name: 'DejaVu', value: 'dejavusans'},
{ name: 'Firefly', value: 'firefly'}
]
});
</script>
ReportBro PLUS: Add the font to rich text editor
Finally, we make the custom fonts available with the rich text editor. We create an inline CSS style for each font. The CSS class has to follow the scheme .ql-font-{font-family} whereas {font-family} must match the font-family value set in the @font-face definition again. The only CSS class parameter is - you guessed it - font-family with the same font-family value.<style type="text/css">
.ql-font-dejavusans {
font-family: "dejavusans";
}
.ql-font-firefly {
font-family: "firefly";
}
</style>
3 Add a custom font to ReportBro Lib
Custom fonts must be made available for ReportBro Lib so that their source can be embedded into the PDF file.
To generate reports for this tutorial we use our tornado report server. In case you have already a Python application running, you would use that already. If you are using the tornado report server install it into your project folder (follow these instructions).
Let's initialize the additional_fonts for the lib. Open the file reportbro_server.py in a text editor and find the line self.additional_fonts = []. That's the place to add the list of dicts with value (you are absolutely right - it needs to match the value set for font-family in the @font-face definition ;-) and filename holding the path to the TTF file. Find all configuration options for additional_fonts in the API documentation.
Note: In case a font variation (bold/italic) is not specified, ReportBro Lib uses the regular font as a fallback.
additional_fonts = [
dict(
value='firefly', filename='../fonts/fireflysung.ttf'
),
dict(
value='dejavusans',
filename='../fonts/DejaVuSans.ttf',
bold_filename='../fonts/DejaVuSans-Bold.ttf',
italic_filename='../fonts/DejaVuSans-Oblique.ttf',
bold_italic_filename='../fonts/DejaVuSans-BoldOblique.ttf'
)
]
Save the file and we are done!
If you look further into
reportbro_server.py you'll find that
additional_fonts is already referenced for
creating the reportbro.Report instance.
Now, it's time to run the tornado report server - if not sure, see how it is done
here.
Let's print it
The browser perfectly displays the text with Chinese characters when used with a standard font. Anyways, it only gets printed once we apply the appropriate font.
Try it yourself: Download the HTML file (additional_fonts.html) of this tutorial.
By the way, ReportBro is also available for everyone as open-source on github (see Download page). Star us on github if you like what you see!