FreeType is the free-software font-rendering engine included in desktop Linux distributions, Android, ChromeOS, iOS, and multiple Unix operating systems, and used by cross-platform programs like Chrome, Java, and GhostScript. Used together, HarfBuzz can perform shaping on Unicode text segments, outputting the glyph IDs that FreeType should rasterize from the active font as well as the positions at which those glyphs should be drawn.
HarfBuzz provides integration points with FreeType at the
face-object and font-object level and for the font-functions
virtual-method structure of a font object. To use the
FreeType-integration API, include the
hb-ft.h
header.
In a typical client program, you will create your hb_face_t face object and hb_font_t font object from a FreeType FT_Face. HarfBuzz provides a suite of functions for doing this.
In the most common case, you will want to use
hb_ft_font_create_referenced()
, which
creates both an hb_face_t face object and
hb_font_t font object (linked to that face object),
and provides lifecycle management.
It is important to note,
though, that while HarfBuzz makes a distinction between its face and
font objects, FreeType's FT_Face does not. After
you create your FT_Face, you must set its size
parameter using FT_Set_Char_Size()
, because
an hb_font_t is defined as an instance of an
hb_face_t with size specified.
#include <hb-ft.h> ... FT_New_Face(ft_library, font_path, index, &face); FT_Set_Char_Size(face, 0, 1000, 0, 0); hb_font_t *font = hb_ft_font_create(face);
hb_ft_font_create_referenced()
is
the recommended function for creating an hb_face_t face
object. This function calls FT_Reference_Face()
before using the FT_Face and calls
FT_Done_Face()
when it is finished using the
FT_Face. Consequently, your client program does not need
to worry about destroying the FT_Face while HarfBuzz
is still using it.
Although hb_ft_font_create_referenced()
is
the recommended function, there is another variant for client code
where special circumstances make it necessary. The simpler
version of the function is hb_ft_font_create()
,
which takes an FT_Face and an optional destroy callback
as its arguments. Because hb_ft_font_create()
does not offer lifecycle management, however, your client code will
be responsible for tracking references to the FT_Face
objects and destroying them when they are no longer needed. If you
do not have a valid reason for doing this, use
hb_ft_font_create_referenced()
.
After you have created your font object from your
FT_Face, you can set or retrieve the
load_flags
of the
FT_Face through the hb_font_t
object. HarfBuzz provides
hb_ft_font_set_load_flags()
and
hb_ft_font_get_load_flags()
for this
purpose. The ability to set the
load_flags
through the font object
could be useful for enabling or disabling hinting, for example,
or to activate vertical layout.
HarfBuzz also provides a utility function called
hb_ft_font_has_changed()
that you should
call whenever you have altered the properties of your underlying
FT_Face, as well as a
hb_ft_get_face()
that you can call on an
hb_font_t font object to fetch its underlying FT_Face.
With an hb_face_t and hb_font_t both linked
to your FT_Face, you will typically also want to
use FreeType for the font_funcs
vtable of your hb_font_t. As a reminder, this
font-functions structure is the set of methods that HarfBuzz
will use to fetch important information from the font, such as
the advances and extents of individual glyphs.
All you need to do is call
hb_ft_font_set_funcs(font);
and HarfBuzz will use FreeType for the font-functions in
font
.
As we noted above, an hb_font_t is derived from an hb_face_t with size (and, perhaps, other parameters, such as variation-axis coordinates) specified. Consequently, you can reuse an hb_face_t with several hb_font_t objects, and HarfBuzz provides functions to simplify this.
The hb_ft_face_create_referenced()
function creates just an hb_face_t from a FreeType
FT_Face and, as with
hb_ft_font_create_referenced()
above,
provides lifecycle management for the FT_Face.
Similarly, there is an hb_ft_face_create()
function variant that does not provide the lifecycle-management
feature. As with the font-object case, if you use this version
of the function, it will be your client code's respsonsibility
to track usage of the FT_Face objects.
A third variant of this function is
hb_ft_face_create_cached()
, which is the
same as hb_ft_face_create()
except that it
also uses the generic
field of the
FT_Face structure to save a pointer to the newly
created hb_face_t. Subsequently, function calls
that pass the same FT_Face will get the same
hb_face_t returned — and the
hb_face_t will be correctly reference
counted. Still, as with
hb_ft_face_create()
, your client code must
track references to the FT_Face itself, and destroy
it when it is unneeded.