diff --git a/docs/Makefile.am b/docs/Makefile.am index 0c76b2ed3..f8b38219d 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -82,6 +82,7 @@ content_files= \ usermanual-opentype-features.xml \ usermanual-clusters.xml \ usermanual-utilities.xml \ + usermanual-integration.xml \ version.xml # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index e3f314d92..7a175f357 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -43,6 +43,7 @@ + diff --git a/docs/usermanual-integration.xml b/docs/usermanual-integration.xml new file mode 100644 index 000000000..b8a52c9f7 --- /dev/null +++ b/docs/usermanual-integration.xml @@ -0,0 +1,365 @@ + + + +]> + + Platform Integration Guide + + HarfBuzz was first developed for use with the GNOME and GTK + software stack commonly found in desktop Linux + distributions. Nevertheless, it can be used on other operating + systems and platforms, from iOS and macOS to Windows. It can also + be used with other application frameworks and components, such as + Android, Qt, or application-specific widget libraries. + + + This chapter will look at how HarfBuzz fits into a typical + text-rendering pipeline, and will discuss the APIs available to + integrate HarfBuzz with contemporary Linux, Mac, and Windows + software. It will also show how HarfBuzz integrates with popular + external libaries like FreeType and International Components for + Unicode (ICU) and describe the HarfBuzz language bindings for + Python. + + + On a GNOME system, HarfBuzz is designed to tie in with several + other common system libraries. The most common architecture uses + Pango at the layer directly "above" HarfBuzz; Pango is responsible + for text segmentation and for ensuring that each input + hb_buffer_t passed to HarfBuzz for shaping contains + Unicode code points that share the same segment properties + (namely, direction, language, and script, but also higher-level + properties like the active font, font style, color, and so on). + + + The layer directly "below" HarfBuzz is typically FreeType, which + is used to rasterize glyph outlines at the necessary optical size, + hinting settings, and pixel resolution. FreeType provides APIs for + accessing font and face information, so HarfBuzz includes + functions to create hb_face_t and + hb_font_t objects directly from FreeType + objects. HarfBuzz will can use FreeType's built-in functions for + font_funcs vtable in an hb_font_t. + + + FreeType's output is bitmaps of the rasterized glyphs; on a + typical Linux system these will then be drawn by a graphics + library like Cairo, but those details are beyond HarfBuzz's + control. On the other hand, at the top end of the stack, Pango is + part of the larger GNOME framework, and HarfBuzz does include APIs + for working with key components of GNOME's higher-level libraries + — most notably GLib. + + + For other operating systems or application frameworks, the + critical integration points are where HarfBuzz gets font and face + information about the font used for shaping and where HarfBuzz + gets Unicode data about the input-buffer code points. + + + The font and face information is necessary for text shaping + because HarfBuzz needs to retrieve the glyph indices for + particular code points, and to know the extents and advances of + glyphs. Note that, in an OpenType variable font, both of those + types of information can change with different variation-axis + settings. + + + The Unicode information is necessary for shaping because the + properties of a code point (such as it's General Category (gc), + Canonical Combining Class (ccc), and decomposition) can directly + impact the shaping moves that HarfBuzz performs. + + +
+ GNOME integration, GLib, and GObject + + As mentioned in the preceding section, HarfBuzz offers + integration APIs to help client programs using the + GNOME and GTK framework commonly found in desktop Linux + distributions. + + + GLib is the main utility library for GNOME applications. It + provides basic data types and conversions, file abstractions, + string manipulation, and macros, as well as facilities like + memory allocation and the main event loop. + + + Where text shaping is concerned, GLib provides several utilities + that HarfBuzz can take advantage of, including a set of + Unicode-data functions and a data type for script + information. Both are useful when working with HarfBuzz + buffers. To make use of them, you will need to include the + hb-glib.h header file. + + + GLib's Unicode + manipulation API includes all the functionality + necessary to retrieve Unicode data for the + unicode_funcs structure of a HarfBuzz + hb_buffer_t. + + + The function hb_glib_get_unicode_funcs() + sets up a hb_unicode_funcs_t structure configured + with the GLib Unicode functions and returns a pointer to it. + + + You can attach this Unicode-functions structure to your buffer, + and it will be ready for use with GLib: + + + #include <hb-glib.h> + ... + hb_unicode_funcs_t *glibufunctions; + glibufunctions = hb_glib_get_unicode_funcs(); + hb_buffer_set_unicode_funcs(buf, glibufunctions); + + + For script information, GLib uses the + GUnicodeScript type. Like HarfBuzz's own + hb_script_t, this data type is an enumeration + of Unicode scripts, but text segments passed in from GLib code + will be tagged with a GUnicodeScript. Therefore, + when setting the script property on a hb_buffer_t, + you will need to convert between the GUnicodeScript + of the input provided by GLib and HarfBuzz's + hb_script_t type. + + + The hb_glib_script_to_script() function + takes an GUnicodeScript script identifier as its + sole argument and returns the corresponding hb_script_t. + The hb_glib_script_from_script() does the + reverse, taking an hb_script_t and returning the + GUnicodeScript identifier for GLib. + + + Finally, GLib also provides a reference-counted object type called GBytes + that is used for accessing raw memory segments with the benefits + of GLib's lifecycle management. HarfBuzz provides a + hb_glib_blob_create() function that lets + you create an hb_blob_t directly from a + GBytes object. This function takes only the + GBytes object as its input; HarfBuzz registers the + GLib destroy callback automatically. + + + The GNOME platform also features an object system called + GObject. For HarfBuzz, the main advantage of GObject is a + feature called GObject + Introspection. This is a middleware facility that can be + used to generate language bindings for C libraries. HarfBuzz uses it + to build its Python bindings, which we will look at in a separate section. + +
+ +
+ 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); + + + Although hb_ft_font_create_referenced() is + the recommended function, there is another variant. The simpler + version of the function is + hb_ft_font_create(), which takes an + FT_Face and an optional destroy callback as its + arguments. The critical difference between the two is that + hb_ft_font_create() does not offer the + lifecycle-management feature. 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, user + 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. + +
+ +
+ Uniscribe integration + + + + + + + + + +
+ +
+ CoreText integration + + + + + + + + + +
+ +
+ ICU integration + + + + + + + + + +
+ +
+ Python bindings + + + + + + + + + +
+ +
+ + + + + + + +
+ +