Using Custom Fonts
Scenic ships standard with support for the Roboto and Roboto_Mono fonts. The Roboto_Slab font is no longer standard in Scenic.
You can, however, add the RobotoSlab font, and most any other TrueType font you want to use into Scenic.
To do this you will need do the following steps.
- Download the font you want to use and add it to the static files of your
priv/folder in your application. Please be aware of font licenses and make good choices. - Use the truetype_metrics hex package to generate a
*.metricsfile, which you also add to yourpriv/folder. This tool will also change the name of your font so that a hash of the data is included in the file name. - Load the
*.metricsfile into theScenic.Cache.Static.FontMetricscache. - Refer to the font by the key to the metrics file in the graph where you want to use it.
These steps are descried in detail below
Add the custom font file
Download your custom font and place it into your static assets folder. A typical static assets layout would look like this...
priv/
static/
fonts/
Roboto_Slab/
LICENSE.txt
RobotoSlab-Regular.ttf
Generate the \*.metrics file
Use the truetype_metrics tool to generate a font metrics file. This tool is not included in Scenic because this code is complicated (don't get me started on the TrueType format) and only needs to be used once when you set up your project.
This tool will do two things. It will create a \*.metrics file and decorate the name of the font itself with a hash of its contents.
You may need to install the tool as an archive first
mix archive.install hex truetype_metricsThen you can run the tool, pointing at your font directory
mix truetype_metrics -d priv/static/fonts/Roboto_SlabWhen you are done, static folder will look something like this
priv/
static/
fonts/
Roboto_Slab/
LICENSE.txt
RobotoSlab-Regular.ttf.0IXAWqFTtjn6MKSgQOzxUgxNKGrmyhqz1e2d90PVHck
RobotoSlab-Regular.ttf.metricsRead the truetype_metrics documentation to learn how to recurse font folders, control the font name decoration and force the file to be re-generated.
Load the \*.metrics file and the font into the cache
In your scene, you need to make load both the \*.metrics file into the Scenic.Cache.Static.FontMetrics cache and the font itself into the Scenic.Cache.Static.Font cache.
@custom_font_hash "0IXAWqFTtjn6MKSgQOzxUgxNKGrmyhqz1e2d90PVHck"
@custom_metrics_path :code.priv_dir(:scenic_example)
|> Path.join("/static/fonts/Roboto_Slab/RobotoSlab-Regular.ttf.metrics")
@custom_metrics_hash Scenic.Cache.Support.Hash.file!(@custom_metrics_path, :sha)
def init(_, _opts) do
# load the custom font
font_folder = :code.priv_dir(:my_app) |> Path.join("/static/fonts")
custom_metrics_path = :code.priv_dir(:scenic_example)
|> Path.join("/static/fonts/Roboto_Slab/RobotoSlab-Regular.ttf.metrics")
Cache.Static.Font.load(font_folder, @custom_font_hash)
Cache.Static.FontMetrics.load(custom_metrics_path, @custom_metrics_hash)
# no need to put the graph into state as we won't be using it again
{:ok, nil, push: @graph}
endNote that if you use this font everywhere, you may want to load it once during app startup with the :global scope. Then you can just refer to it without having to load it in every scene.
Cache.Static.Font.load(@font_folder, @custom_font_hash, scope: :global)
Cache.Static.FontMetrics.load(@custom_metrics_path, @custom_metrics_hash, scope: :global)Refer to the font by the metrics key
Finally, you use the key to refer to the font metrics in the graph. The font itself will be loaded and used automatically as needed. The metrics file already contains the hash of the font itself.
text_spec("Font Test", translate: {0, 40}, font_size: 60, font: @custom_metrics_hash)