Most of the functionality in systemfonts is intended to be used from
compiled code to help e.g. graphic devices to resolve font
specifications to a font file prior to rendering. systemfonts provide
key functionality to get called at the C level by putting systemfonts in
the LinkingTo
field in the description and adding
#include <systemfonts.h>
to your C code. Make sure
systemfonts is loaded before using it, e.g. by having
match_font()
imported into your package namespace. The
different functionality will be discussed below
The C equivalent of the match_font()
R function is
locate_font()
with the following signature:
It takes a UTF-8 encoded string with the font family name, an int setting both italic and bold styles along with a char pointer to be filled with the located path and the maximum length it can hold. The return value is an int giving the index of the font in the font file.
With the advent of systemfonts 0.3.0 fonts can now also have OpenType
features attached to them through the use of
register_font()
or register_variant()
. If you
wish to support such features you can use an alternative to the
above:
The returned FontSettings
struct will contain both the
font location and index along with any OpenType feature settings. The
struct (along with its FontFeature
struct dependency) is
shown below and is pretty self-documenting.
Do not cache the FontSettings
struct as the
features
array may be cleared at any time after the call
has ended. systemfonts itself takes care of caching so this is not
something you should be concerned with in your code.
The C equivalent of glyph_info()
is
glyph_metrics()
with the following signature:
int glyph_metrics(
uint32_t code,
const char* fontfile,
int index,
double size,
double res,
double* ascent,
double* descent,
double* width
)
It takes the glyph to measure as an int giving the UTF code of the
glyph, along with a fontfile and index to identify the font to measure
with. Further it takes a size in pt and a resolution in ppi. It will
write the ascent, descent, and width in pts to the pointers passed in,
and return 0
if the operation was successful.
The C equivalent of the string_width()
R function is
also called string_width()
with the following
signature:
string_width(
const char* string,
const char* fontfile,
int index,
double size,
double res,
int include_bearing,
double* width
)
This function calculates the width of a string, ignoring any newlines (these are automatically being handled by the graphic engine). It takes a UTF-8 encoded string, along with a fontfile and index identifying the font to use for the calculation. It also take a size in pt and a res in ppi for setting the size. In addition it takes an include_bearing flag to control whether the bearings of the first and last character should be taken into account (this is recommended by the graphic engine). It will write the width in pts to the passed in pointer and return 0 if successful.
A parred down version of shape_string()
is accessible at
the C level with string_shape()
. It behaves more or less
like string_width()
above, but instead returns the location
to write each glyph at relative to a (0, 0) origin.
string_shape(
const char* string,
const char* fontfile,
int index,
double size,
double res,
double* x,
double* y,
unsigned int max_length
)
string_shape()
behaves more or less like
string_width()
above, but instead returns the location to
write each glyph at relative to a (0, 0) origin. It takes a UTF-8
encoded string, along with a fontfile and index identifying the font to
use for the calculation. It also take a size in pt and a res in ppi for
setting the size. In addition it takes an include_bearing flag to
control whether the bearings of the first and last character should be
taken into account (this is recommended by the graphic engine). It will
write the x and y location of each glyph in pts to the passed in arrays,
stopping before the provided max_length and return 0 if successful.
A heavy part of text layouting is reading and parsing font files.
systemfonts contains its own cache to make sure that parsing is kept at
a minimum. If you want to use this cache to load and cache freetype face
object (FT_Face) you can use get_cached_face()
. This
resides in a separate header (systemfonts-ft.h
) because it
requires FreeType to be linked in your package, which the rest of the C
api does not. It will look in the cache for a face and size that matches
your request and return that if found. If not, it will load it for you
and add it to the cache, before returning it to you.
get_cached_face()
sets the passed in error pointer to 0 if
successful.
Freetype uses reference counting to keep track of objects and the
count is increased by a call to get_cached_face()
. It is
the responsiblity of the caller to decrease it once the face is no
longer needed using FT_Done_Face()
.
When rendering text it is not given that all the requested characters have a glyph in the given font. While one can elect to render a “missing glyph” glyph (often either an empty square or a questionmark in a tilted square) a better approach is often to find a font substitute that does contain the character and use that for rendering it. This function allows you to find a fallback font for a given string and font. The string should be stripped of characters that you already know how to render. The fallback font is returned as a FontSettings object, though features are always empty.
When encoding text with CSS it may be necessary to know the exact weight of the font given by a file so that it may be reflected in the style sheet. This function takes a path and an index and returns the weight (100-900 in steps of 100) or 0 if it is undefined by the font.
It may be beneficial to know the family name from a given path and
index into a font. This can be obtained with
get_font_family()
which will write the name to the provided
char*
argument. It will return 0 if it was somehow
unsuccessful.
Figuring out which character in a string should be treated as an emoji is non-trivial due to the existence of emojis with text representation default etc. systemfonts allow you to get the embedding of emojis in a string based on the correct rules.