xref: /aosp_15_r20/external/harfbuzz_ng/docs/usermanual-integration.xml (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1<?xml version="1.0"?>
2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
4  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
5  <!ENTITY version SYSTEM "version.xml">
6]>
7<chapter id="integration">
8  <title>Platform Integration Guide</title>
9  <para>
10    HarfBuzz was first developed for use with the GNOME and GTK
11    software stack commonly found in desktop Linux
12    distributions. Nevertheless, it can be used on other operating
13    systems and platforms, from iOS and macOS to Windows. It can also
14    be used with other application frameworks and components, such as
15    Android, Qt, or application-specific widget libraries.
16  </para>
17  <para>
18    This chapter will look at how HarfBuzz fits into a typical
19    text-rendering pipeline, and will discuss the APIs available to
20    integrate HarfBuzz with contemporary Linux, Mac, and Windows
21    software. It will also show how HarfBuzz integrates with popular
22    external libraries like FreeType and International Components for
23    Unicode (ICU) and describe the HarfBuzz language bindings for
24    Python.
25  </para>
26  <para>
27    On a GNOME system, HarfBuzz is designed to tie in with several
28    other common system libraries. The most common architecture uses
29    Pango at the layer directly "above" HarfBuzz; Pango is responsible
30    for text segmentation and for ensuring that each input
31    <type>hb_buffer_t</type> passed to HarfBuzz for shaping contains
32    Unicode code points that share the same segment properties
33    (namely, direction, language, and script, but also higher-level
34    properties like the active font, font style, and so on).
35  </para>
36  <para>
37    The layer directly "below" HarfBuzz is typically FreeType, which
38    is used to rasterize glyph outlines at the necessary optical size,
39    hinting settings, and pixel resolution. FreeType provides APIs for
40    accessing font and face information, so HarfBuzz includes
41    functions to create <type>hb_face_t</type> and
42    <type>hb_font_t</type> objects directly from FreeType
43    objects. HarfBuzz can use FreeType's built-in functions for
44    <structfield>font_funcs</structfield> vtable in an <type>hb_font_t</type>.
45  </para>
46  <para>
47    FreeType's output is bitmaps of the rasterized glyphs; on a
48    typical Linux system these will then be drawn by a graphics
49    library like Cairo, but those details are beyond HarfBuzz's
50    control. On the other hand, at the top end of the stack, Pango is
51    part of the larger GNOME framework, and HarfBuzz does include APIs
52    for working with key components of GNOME's higher-level libraries
53    &mdash; most notably GLib.
54  </para>
55  <para>
56    For other operating systems or application frameworks, the
57    critical integration points are where HarfBuzz gets font and face
58    information about the font used for shaping and where HarfBuzz
59    gets Unicode data about the input-buffer code points.
60  </para>
61  <para>
62    The font and face information is necessary for text shaping
63    because HarfBuzz needs to retrieve the glyph indices for
64    particular code points, and to know the extents and advances of
65    glyphs. Note that, in an OpenType variable font, both of those
66    types of information can change with different variation-axis
67    settings.
68  </para>
69  <para>
70    The Unicode information is necessary for shaping because the
71    properties of a code point (such as its General Category (gc),
72    Canonical Combining Class (ccc), and decomposition) can directly
73    impact the shaping moves that HarfBuzz performs.
74  </para>
75
76  <section id="integration-glib">
77    <title>GNOME integration, GLib, and GObject</title>
78    <para>
79      As mentioned in the preceding section, HarfBuzz offers
80      integration APIs to help client programs using the
81      GNOME and GTK framework commonly found in desktop Linux
82      distributions.
83    </para>
84    <para>
85      GLib is the main utility library for GNOME applications. It
86      provides basic data types and conversions, file abstractions,
87      string manipulation, and macros, as well as facilities like
88      memory allocation and the main event loop.
89    </para>
90    <para>
91      Where text shaping is concerned, GLib provides several utilities
92      that HarfBuzz can take advantage of, including a set of
93      Unicode-data functions and a data type for script
94      information. Both are useful when working with HarfBuzz
95      buffers. To make use of them, you will need to include the
96      <filename>hb-glib.h</filename> header file.
97    </para>
98    <para>
99      GLib's <ulink
100      url="https://developer.gnome.org/glib/stable/glib-Unicode-Manipulation.html">Unicode
101      manipulation API</ulink> includes all the functionality
102      necessary to retrieve Unicode data for the
103      <structfield>unicode_funcs</structfield> structure of a HarfBuzz
104      <type>hb_buffer_t</type>.
105    </para>
106    <para>
107      The function <function>hb_glib_get_unicode_funcs()</function>
108      sets up a <type>hb_unicode_funcs_t</type> structure configured
109      with the GLib Unicode functions and returns a pointer to it.
110    </para>
111    <para>
112      You can attach this Unicode-functions structure to your buffer,
113      and it will be ready for use with GLib:
114    </para>
115    <programlisting language="C">
116      #include &lt;hb-glib.h&gt;
117      ...
118      hb_unicode_funcs_t *glibufunctions;
119      glibufunctions = hb_glib_get_unicode_funcs();
120      hb_buffer_set_unicode_funcs(buf, glibufunctions);
121    </programlisting>
122    <para>
123      For script information, GLib uses the
124      <type>GUnicodeScript</type> type. Like HarfBuzz's own
125      <type>hb_script_t</type>, this data type is an enumeration
126      of Unicode scripts, but text segments passed in from GLib code
127      will be tagged with a <type>GUnicodeScript</type>. Therefore,
128      when setting the script property on a <type>hb_buffer_t</type>,
129      you will need to convert between the <type>GUnicodeScript</type>
130      of the input provided by GLib and HarfBuzz's
131      <type>hb_script_t</type> type.
132    </para>
133    <para>
134      The <function>hb_glib_script_to_script()</function> function
135      takes an <type>GUnicodeScript</type> script identifier as its
136      sole argument and returns the corresponding <type>hb_script_t</type>.
137      The <function>hb_glib_script_from_script()</function> does the
138      reverse, taking an <type>hb_script_t</type> and returning the
139      <type>GUnicodeScript</type> identifier for GLib.
140    </para>
141    <para>
142      Finally, GLib also provides a reference-counted object type called <ulink
143      url="https://developer.gnome.org/glib/stable/glib-Byte-Arrays.html#GBytes"><type>GBytes</type></ulink>
144      that is used for accessing raw memory segments with the benefits
145      of GLib's lifecycle management. HarfBuzz provides a
146      <function>hb_glib_blob_create()</function> function that lets
147      you create an <type>hb_blob_t</type> directly from a
148      <type>GBytes</type> object. This function takes only the
149      <type>GBytes</type> object as its input; HarfBuzz registers the
150      GLib <function>destroy</function> callback automatically.
151    </para>
152    <para>
153      The GNOME platform also features an object system called
154      GObject. For HarfBuzz, the main advantage of GObject is a
155      feature called <ulink
156      url="https://gi.readthedocs.io/en/latest/">GObject
157      Introspection</ulink>. This is a middleware facility that can be
158      used to generate language bindings for C libraries. HarfBuzz uses it
159      to build its Python bindings, which we will look at in a separate section.
160    </para>
161  </section>
162
163  <section id="integration-freetype">
164    <title>FreeType integration</title>
165    <para>
166      FreeType is the free-software font-rendering engine included in
167      desktop Linux distributions, Android, ChromeOS, iOS, and multiple Unix
168      operating systems, and used by cross-platform programs like
169      Chrome, Java, and GhostScript. Used together, HarfBuzz can
170      perform shaping on Unicode text segments, outputting the glyph
171      IDs that FreeType should rasterize from the active font as well
172      as the positions at which those glyphs should be drawn.
173    </para>
174    <para>
175      HarfBuzz provides integration points with FreeType at the
176      face-object and font-object level and for the font-functions
177      virtual-method structure of a font object. These functions
178      make it easy for clients that use FreeType for rasterization
179      or font-loading, to use HarfBuzz for shaping. To use the
180      FreeType-integration API, include the
181      <filename>hb-ft.h</filename> header.
182    </para>
183    <para>
184      In a typical client program, you will create your
185      <type>hb_face_t</type> face object and <type>hb_font_t</type>
186      font object from a FreeType <type>FT_Face</type>. HarfBuzz
187      provides a suite of functions for doing this.
188    </para>
189    <para>
190      In the most common case, you will want to use
191      <function>hb_ft_font_create_referenced()</function>, which
192      creates both an <type>hb_face_t</type> face object and
193      <type>hb_font_t</type> font object (linked to that face object),
194      and provides lifecycle management.
195    </para>
196    <para>
197      It is important to note,
198      though, that while HarfBuzz makes a distinction between its face and
199      font objects, FreeType's <type>FT_Face</type> does not. After
200      you create your <type>FT_Face</type>, you must set its size
201      parameter using <function>FT_Set_Char_Size()</function>, because
202      an <type>hb_font_t</type> is defined as an instance of an
203      <type>hb_face_t</type> with size specified.
204    </para>
205    <programlisting language="C">
206      #include &lt;hb-ft.h&gt;
207      ...
208      FT_New_Face(ft_library, font_path, index, &amp;face);
209      FT_Set_Char_Size(face, 0, 1000, 0, 0);
210      hb_font_t *font = hb_ft_font_create(face);
211    </programlisting>
212    <para>
213      <function>hb_ft_font_create_referenced()</function> is
214      the recommended function for creating an <type>hb_face_t</type> face
215      object. This function calls <function>FT_Reference_Face()</function>
216      before using the <type>FT_Face</type> and calls
217      <function>FT_Done_Face()</function> when it is finished using the
218      <type>FT_Face</type>. Consequently, your client program does not need
219      to worry about destroying the <type>FT_Face</type> while HarfBuzz
220      is still using it.
221    </para>
222    <para>
223      Although <function>hb_ft_font_create_referenced()</function> is
224      the recommended function, there is another variant for client code
225      where special circumstances make it necessary. The simpler
226      version of the function is <function>hb_ft_font_create()</function>,
227      which takes an <type>FT_Face</type> and an optional destroy callback
228      as its arguments. Because <function>hb_ft_font_create()</function>
229      does not offer lifecycle management, however, your client code will
230      be responsible for tracking references to the <type>FT_Face</type>
231      objects and destroying them when they are no longer needed. If you
232      do not have a valid reason for doing this, use
233      <function>hb_ft_font_create_referenced()</function>.
234    </para>
235    <para>
236      After you have created your font object from your
237      <type>FT_Face</type>, you can set or retrieve the
238      <structfield>load_flags</structfield> of the
239      <type>FT_Face</type> through the <type>hb_font_t</type>
240      object. HarfBuzz provides
241      <function>hb_ft_font_set_load_flags()</function> and
242      <function>hb_ft_font_get_load_flags()</function> for this
243      purpose. The ability to set the
244      <structfield>load_flags</structfield> through the font object
245      could be useful for enabling or disabling hinting, for example,
246      or to activate vertical layout.
247    </para>
248    <para>
249      HarfBuzz also provides a utility function called
250      <function>hb_ft_font_changed()</function> that you should
251      call whenever you have altered the properties of your underlying
252      <type>FT_Face</type>, as well as a
253      <function>hb_ft_get_face()</function> that you can call on an
254      <type>hb_font_t</type> font object to fetch its underlying <type>FT_Face</type>.
255    </para>
256    <para>
257      With an <type>hb_face_t</type> and <type>hb_font_t</type> both linked
258      to your <type>FT_Face</type>, you will typically also want to
259      use FreeType for the <structfield>font_funcs</structfield>
260      vtable of your <type>hb_font_t</type>. As a reminder, this
261      font-functions structure is the set of methods that HarfBuzz
262      will use to fetch important information from the font, such as
263      the advances and extents of individual glyphs.
264    </para>
265    <para>
266      All you need to do is call
267    </para>
268    <programlisting language="C">
269      hb_ft_font_set_funcs(font);
270    </programlisting>
271    <para>
272      and HarfBuzz will use FreeType for the font-functions in
273      <literal>font</literal>.
274    </para>
275    <para>
276      As we noted above, an <type>hb_font_t</type> is derived from an
277      <type>hb_face_t</type> with size (and, perhaps, other
278      parameters, such as variation-axis coordinates)
279      specified. Consequently, you can reuse an <type>hb_face_t</type>
280      with several <type>hb_font_t</type> objects, and HarfBuzz
281      provides functions to simplify this.
282    </para>
283    <para>
284      The <function>hb_ft_face_create_referenced()</function>
285      function creates just an <type>hb_face_t</type> from a FreeType
286      <type>FT_Face</type> and, as with
287      <function>hb_ft_font_create_referenced()</function> above,
288      provides lifecycle management for the <type>FT_Face</type>.
289    </para>
290    <para>
291      Similarly, there is an <function>hb_ft_face_create()</function>
292      function variant that does not provide the lifecycle-management
293      feature. As with the font-object case, if you use this version
294      of the function, it will be your client code's respsonsibility
295      to track usage of the <type>FT_Face</type> objects.
296    </para>
297    <para>
298      A third variant of this function is
299      <function>hb_ft_face_create_cached()</function>, which is the
300      same as <function>hb_ft_face_create()</function> except that it
301      also uses the <structfield>generic</structfield> field of the
302      <type>FT_Face</type> structure to save a pointer to the newly
303      created <type>hb_face_t</type>. Subsequently, function calls
304      that pass the same <type>FT_Face</type> will get the same
305      <type>hb_face_t</type> returned &mdash; and the
306      <type>hb_face_t</type> will be correctly reference
307      counted. Still, as with
308      <function>hb_ft_face_create()</function>, your client code must
309      track references to the <type>FT_Face</type> itself, and destroy
310      it when it is unneeded.
311    </para>
312  </section>
313
314  <section id="integration-cairo">
315    <title>Cairo integration</title>
316
317    <para>
318      Cairo is a 2D graphics library that is frequently used together
319      with GTK and Pango. Cairo supports rendering text using FreeType, or
320      by using callback-based 'user fonts'.
321    </para>
322    <para>
323      HarfBuzz provides integration points with cairo for fonts as well as
324      for buffers. To use the Cairo-integration API, link against libharfbuzz-cairo,
325      and include the <filename>hb-cairo.h</filename> header. For easy buildsystem
326      integration, HarfBuzz comes with a <filename>harfbuzz-cairo.pc</filename>
327      pkg-config file.
328    </para>
329    <para>
330      To create a <type>cairo_scaled_font_t</type> font from a HarfBuzz
331      <type>hb_font_t</type>, you can use <function>hb_cairo_font_face_create_for_font()</function>
332      or <function>hb_cairo_font_face_create_for_face()</function>. The former API
333      applies variations and synthetic slant from the <type>hb_font_t</type> when
334      rendering, the latter takes them from the <type>cairo_font_options_t</type>
335      that were passed when creating the <type>cairo_scaled_font_t</type>.
336    </para>
337    <para>
338      The Cairo fonts created in this way make use of Cairo's user-font facilities.
339      They can be used to render on any Cairo context, and provide full support for
340      font rendering features, including color. One current limitation of the
341      implementation is that it does not support hinting for glyph outlines.
342    </para>
343    <para>
344      When using color fonts with this API, the color palette index is taken from
345      the <type>cairo_font_options_t</type> (with new enough Cairo), and the foreground
346      color is extracted from the source of the Cairo context.
347    </para>
348    <para>
349      To render the results of shaping a piece of text, use
350      <function>hb_cairo_glyphs_from_buffer()</function> to obtain the glyphs in
351      a form that can be passed to <function>cairo_show_text_glyphs()</function> or
352      <function>cairo_show_glyphs()</function>.
353    </para>
354  </section>
355
356  <section id="integration-uniscribe">
357    <title>Uniscribe integration</title>
358    <para>
359      If your client program is running on Windows, HarfBuzz offers
360      an additional API that can help integrate with Microsoft's
361      Uniscribe engine and the Windows GDI.
362    </para>
363    <para>
364      Overall, the Uniscribe API covers a broader set of typographic
365      layout functions than HarfBuzz implements, but HarfBuzz's
366      shaping API can serve as a drop-in replacement for Uniscribe's shaping
367      functionality. In fact, one of HarfBuzz's design goals is to
368      accurately reproduce the same output for shaping a given text
369      segment that Uniscribe produces &mdash; even to the point of
370      duplicating known shaping bugs or deviations from the
371      specification &mdash; so you can be confident that your users'
372      documents with their existing fonts will not be affected adversely by
373      switching to HarfBuzz.
374    </para>
375    <para>
376      At a basic level, HarfBuzz's <function>hb_shape()</function>
377      function replaces both the <ulink url=""><function>ScriptShape()</function></ulink>
378      and <ulink
379      url="https://docs.microsoft.com/en-us/windows/desktop/api/Usp10/nf-usp10-scriptplace"><function>ScriptPlace()</function></ulink>
380      functions from Uniscribe.
381    </para>
382    <para>
383      However, whereas <function>ScriptShape()</function> returns the
384      glyphs and clusters for a shaped sequence and
385      <function>ScriptPlace()</function> returns the advances and
386      offsets for those glyphs, <function>hb_shape()</function>
387      handles both. After <function>hb_shape()</function> shapes a
388      buffer, the output glyph IDs and cluster IDs are returned as
389      an array of <structname>hb_glyph_info_t</structname> structures, and the
390      glyph advances and offsets are returned as an array of
391      <structname>hb_glyph_position_t</structname> structures.
392    </para>
393    <para>
394      Your client program only needs to ensure that it converts
395      correctly between HarfBuzz's low-level data types (such as
396      <type>hb_position_t</type>) and Windows's corresponding types
397      (such as <type>GOFFSET</type> and <type>ABC</type>). Be sure you
398      read the <xref linkend="buffers-language-script-and-direction"
399      />
400      chapter for a full explanation of how HarfBuzz input buffers are
401      used, and see <xref linkend="shaping-buffer-output" /> for the
402      details of what <function>hb_shape()</function> returns in the
403      output buffer when shaping is complete.
404    </para>
405    <para>
406      Although <function>hb_shape()</function> itself is functionally
407      equivalent to Uniscribe's shaping routines, there are two
408      additional HarfBuzz functions you may want to use to integrate
409      the libraries in your code. Both are used to link HarfBuzz font
410      objects to the equivalent Windows structures.
411    </para>
412    <para>
413      The <function>hb_uniscribe_font_get_logfontw()</function>
414      function takes a <type>hb_font_t</type> font object and returns
415      a pointer to the <ulink
416      url="https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-logfontw"><type>LOGFONTW</type></ulink>
417      "logical font" that corresponds to it. A <type>LOGFONTW</type>
418      structure holds font-wide attributes, including metrics, size,
419      and style information.
420    </para>
421<!--
422     <para>
423       In Uniscribe's model, the <type>SCRIPT_CACHE</type> holds the
424       device context, including the logical font that the shaping
425       functions apply.
426       https://docs.microsoft.com/en-us/windows/desktop/Intl/script-cache
427    </para>
428-->
429    <para>
430      The <function>hb_uniscribe_font_get_hfont()</function> function
431      also takes a <type>hb_font_t</type> font object, but it returns
432      an <type>HFONT</type> &mdash; a handle to the underlying logical
433      font &mdash; instead.
434    </para>
435    <para>
436      <type>LOGFONTW</type>s and <type>HFONT</type>s are both needed
437      by other Uniscribe functions.
438    </para>
439    <para>
440      As a final note, you may notice a reference to an optional
441      <literal>uniscribe</literal> shaper back-end in the <xref
442      linkend="configuration" /> section of the HarfBuzz manual. This
443      option is not a Uniscribe-integration facility.
444    </para>
445    <para>
446      Instead, it is a internal code path used in the
447      <command>hb-shape</command> command-line utility, which hands
448      shaping functionality over to Uniscribe entirely, when run on a
449      Windows system. That allows testing HarfBuzz's native output
450      against the Uniscribe engine, for tracking compatibility and
451      debugging.
452    </para>
453    <para>
454      Because this back-end is only used when testing HarfBuzz
455      functionality, it is disabled by default when building the
456      HarfBuzz binaries.
457    </para>
458  </section>
459
460  <section id="integration-coretext">
461    <title>Core Text integration</title>
462    <para>
463      If your client program is running on macOS or iOS, HarfBuzz offers
464      an additional API that can help integrate with Apple's
465      Core Text engine and the underlying Core Graphics
466      framework. HarfBuzz does not attempt to offer the same
467      drop-in-replacement functionality for Core Text that it strives
468      for with Uniscribe on Windows, but you can still use HarfBuzz
469      to perform text shaping in native macOS and iOS applications.
470    </para>
471    <para>
472      Note, though, that if your interest is just in using fonts that
473      contain Apple Advanced Typography (AAT) features, then you do
474      not need to add Core Text integration. HarfBuzz natively
475      supports AAT features and will shape AAT fonts (on any platform)
476      automatically, without requiring additional work on your
477      part. This includes support for AAT-specific TrueType tables
478      such as <literal>mort</literal>, <literal>morx</literal>, and
479      <literal>kerx</literal>, which AAT fonts use instead of
480      <literal>GSUB</literal> and <literal>GPOS</literal>.
481    </para>
482    <para>
483      On a macOS or iOS system, the primary integration points offered
484      by HarfBuzz are for face objects and font objects.
485    </para>
486    <para>
487      The Apple APIs offer a pair of data structures that map well to
488      HarfBuzz's face and font objects. The Core Graphics API, which
489      is slightly lower-level than Core Text, provides
490      <ulink url="https://developer.apple.com/documentation/coregraphics/cgfontref"><type>CGFontRef</type></ulink>, which enables access to typeface
491      properties, but does not include size information. Core Text's
492      <ulink url="https://developer.apple.com/documentation/coretext/ctfont-q6r"><type>CTFontRef</type></ulink> is analogous to a HarfBuzz font object,
493      with all of the properties required to render text at a specific
494      size and configuration.
495      Consequently, a HarfBuzz <type>hb_font_t</type> font object can
496      be hooked up to a Core Text <type>CTFontRef</type>, and a HarfBuzz
497      <type>hb_face_t</type> face object can be hooked up to a
498      <type>CGFontRef</type>.
499    </para>
500    <para>
501      You can create a <type>hb_face_t</type> from a
502      <type>CGFontRef</type> by using the
503      <function>hb_coretext_face_create()</function>. Subsequently,
504      you can retrieve the <type>CGFontRef</type> from a
505      <type>hb_face_t</type> with <function>hb_coretext_face_get_cg_font()</function>.
506    </para>
507    <para>
508      Likewise, you create a <type>hb_font_t</type> from a
509      <type>CTFontRef</type> by calling
510      <function>hb_coretext_font_create()</function>, and you can
511      fetch the associated <type>CTFontRef</type> from a
512      <type>hb_font_t</type> font object with
513      <function>hb_coretext_face_get_ct_font()</function>.
514    </para>
515    <para>
516      HarfBuzz also offers a <function>hb_font_set_ptem()</function>
517      that you an use to set the nominal point size on any
518      <type>hb_font_t</type> font object. Core Text uses this value to
519      implement optical scaling.
520    </para>
521    <para>
522      When integrating your client code with Core Text, it is
523      important to recognize that Core Text <literal>points</literal>
524      are not typographic points (standardized at 72 per inch) as the
525      term is used elsewhere in OpenType. Instead, Core Text points
526      are CSS points, which are standardized at 96 per inch.
527    </para>
528    <para>
529      HarfBuzz's font functions take this distinction into account,
530      but it can be an easy detail to miss in cross-platform
531      code.
532    </para>
533    <para>
534      As a final note, you may notice a reference to an optional
535      <literal>coretext</literal> shaper back-end in the <xref
536      linkend="configuration" /> section of the HarfBuzz manual. This
537      option is not a Core Text-integration facility.
538    </para>
539    <para>
540      Instead, it is a internal code path used in the
541      <command>hb-shape</command> command-line utility, which hands
542      shaping functionality over to Core Text entirely, when run on a
543      macOS system. That allows testing HarfBuzz's native output
544      against the Core Text engine, for tracking compatibility and debugging.
545    </para>
546    <para>
547      Because this back-end is only used when testing HarfBuzz
548      functionality, it is disabled by default when building the
549      HarfBuzz binaries.
550    </para>
551  </section>
552
553  <section id="integration-icu">
554    <title>ICU integration</title>
555    <para>
556      Although HarfBuzz includes its own Unicode-data functions, it
557      also provides integration APIs for using the International
558      Components for Unicode (ICU) library as a source of Unicode data
559      on any supported platform.
560    </para>
561    <para>
562      The principal integration point with ICU is the
563      <type>hb_unicode_funcs_t</type> Unicode-functions structure
564      attached to a buffer. This structure holds the virtual methods
565      used for retrieving Unicode character properties, such as
566      General Category, Script, Combining Class, decomposition
567      mappings, and mirroring information.
568    </para>
569    <para>
570      To use ICU in your client program, you need to call
571      <function>hb_icu_get_unicode_funcs()</function>, which creates a
572      Unicode-functions structure populated with the ICU function for
573      each included method. Subsequently, you can attach the
574      Unicode-functions structure to your buffer:
575    </para>
576    <programlisting language="C">
577      hb_unicode_funcs_t *icufunctions;
578      icufunctions = hb_icu_get_unicode_funcs();
579      hb_buffer_set_unicode_funcs(buf, icufunctions);
580    </programlisting>
581    <para>
582      and ICU will be used for Unicode-data access.
583    </para>
584    <para>
585      HarfBuzz also supplies a pair of functions
586      (<function>hb_icu_script_from_script()</function> and
587      <function>hb_icu_script_to_script()</function>) for converting
588      between ICU's and HarfBuzz's internal enumerations of Unicode
589      scripts. The <function>hb_icu_script_from_script()</function>
590      function converts from a HarfBuzz <type>hb_script_t</type> to an
591      ICU <type>UScriptCode</type>. The
592      <function>hb_icu_script_to_script()</function> function does the
593      reverse: converting from a <type>UScriptCode</type> identifier
594      to a <type>hb_script_t</type>.
595    </para>
596    <para>
597      By default, HarfBuzz's ICU support is built as a separate shared
598      library (<filename class="libraryfile">libharfbuzz-icu.so</filename>)
599      when compiling HarfBuzz from source. This allows client programs
600      that do not need ICU to link against HarfBuzz without unnecessarily
601      adding ICU as a dependency. You can also build HarfBuzz with ICU
602      support built directly into the main HarfBuzz shared library
603      (<filename class="libraryfile">libharfbuzz.so</filename>),
604      by specifying the <literal>--with-icu=builtin</literal>
605      compile-time option.
606    </para>
607
608  </section>
609
610  <section id="integration-python">
611    <title>Python bindings</title>
612    <para>
613      As noted in the <xref linkend="integration-glib" /> section,
614      HarfBuzz uses a feature called <ulink
615      url="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject
616      Introspection</ulink> (GI) to provide bindings for Python.
617    </para>
618    <para>
619      At compile time, the GI scanner analyzes the HarfBuzz C source
620      and builds metadata objects connecting the language bindings to
621      the C library. Your Python code can then use the HarfBuzz binary
622      through its Python interface.
623    </para>
624    <para>
625      HarfBuzz's Python bindings support Python 2 and Python 3. To use
626      them, you will need to have the <literal>pygobject</literal>
627      package installed. Then you should import
628      <literal>HarfBuzz</literal> from
629      <literal>gi.repository</literal>:
630    </para>
631    <programlisting language="Python">
632      from gi.repository import HarfBuzz
633    </programlisting>
634    <para>
635      and you can call HarfBuzz functions from Python. Sample code can
636      be found in the <filename>sample.py</filename> script in the
637      HarfBuzz <filename>src</filename> directory.
638    </para>
639    <para>
640      Do note, however, that the Python API is subject to change
641      without advance notice. GI allows the bindings to be
642      automatically updated, which is one of its advantages, but you
643      may need to update your Python code.
644    </para>
645  </section>
646
647</chapter>
648