FreeType integration

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.