• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. To use the
178      FreeType-integration API, include the
179      <filename>hb-ft.h</filename> header.
180    </para>
181    <para>
182      In a typical client program, you will create your
183      <type>hb_face_t</type> face object and <type>hb_font_t</type>
184      font object from a FreeType <type>FT_Face</type>. HarfBuzz
185      provides a suite of functions for doing this.
186    </para>
187    <para>
188      In the most common case, you will want to use
189      <function>hb_ft_font_create_referenced()</function>, which
190      creates both an <type>hb_face_t</type> face object and
191      <type>hb_font_t</type> font object (linked to that face object),
192      and provides lifecycle management.
193    </para>
194    <para>
195      It is important to note,
196      though, that while HarfBuzz makes a distinction between its face and
197      font objects, FreeType's <type>FT_Face</type> does not. After
198      you create your <type>FT_Face</type>, you must set its size
199      parameter using <function>FT_Set_Char_Size()</function>, because
200      an <type>hb_font_t</type> is defined as an instance of an
201      <type>hb_face_t</type> with size specified.
202    </para>
203    <programlisting language="C">
204      #include &lt;hb-ft.h&gt;
205      ...
206      FT_New_Face(ft_library, font_path, index, &amp;face);
207      FT_Set_Char_Size(face, 0, 1000, 0, 0);
208      hb_font_t *font = hb_ft_font_create(face);
209    </programlisting>
210    <para>
211      <function>hb_ft_font_create_referenced()</function> is
212      the recommended function for creating an <type>hb_face_t</type> face
213      object. This function calls <function>FT_Reference_Face()</function>
214      before using the <type>FT_Face</type> and calls
215      <function>FT_Done_Face()</function> when it is finished using the
216      <type>FT_Face</type>. Consequently, your client program does not need
217      to worry about destroying the <type>FT_Face</type> while HarfBuzz
218      is still using it.
219    </para>
220    <para>
221      Although <function>hb_ft_font_create_referenced()</function> is
222      the recommended function, there is another variant for client code
223      where special circumstances make it necessary. The simpler
224      version of the function is <function>hb_ft_font_create()</function>,
225      which takes an <type>FT_Face</type> and an optional destroy callback
226      as its arguments. Because <function>hb_ft_font_create()</function>
227      does not offer lifecycle management, however, your client code will
228      be responsible for tracking references to the <type>FT_Face</type>
229      objects and destroying them when they are no longer needed. If you
230      do not have a valid reason for doing this, use
231      <function>hb_ft_font_create_referenced()</function>.
232    </para>
233    <para>
234      After you have created your font object from your
235      <type>FT_Face</type>, you can set or retrieve the
236      <structfield>load_flags</structfield> of the
237      <type>FT_Face</type> through the <type>hb_font_t</type>
238      object. HarfBuzz provides
239      <function>hb_ft_font_set_load_flags()</function> and
240      <function>hb_ft_font_get_load_flags()</function> for this
241      purpose. The ability to set the
242      <structfield>load_flags</structfield> through the font object
243      could be useful for enabling or disabling hinting, for example,
244      or to activate vertical layout.
245    </para>
246    <para>
247      HarfBuzz also provides a utility function called
248      <function>hb_ft_font_has_changed()</function> that you should
249      call whenever you have altered the properties of your underlying
250      <type>FT_Face</type>, as well as a
251      <function>hb_ft_get_face()</function> that you can call on an
252      <type>hb_font_t</type> font object to fetch its underlying <type>FT_Face</type>.
253    </para>
254    <para>
255      With an <type>hb_face_t</type> and <type>hb_font_t</type> both linked
256      to your <type>FT_Face</type>, you will typically also want to
257      use FreeType for the <structfield>font_funcs</structfield>
258      vtable of your <type>hb_font_t</type>. As a reminder, this
259      font-functions structure is the set of methods that HarfBuzz
260      will use to fetch important information from the font, such as
261      the advances and extents of individual glyphs.
262    </para>
263    <para>
264      All you need to do is call
265    </para>
266    <programlisting language="C">
267      hb_ft_font_set_funcs(font);
268    </programlisting>
269    <para>
270      and HarfBuzz will use FreeType for the font-functions in
271      <literal>font</literal>.
272    </para>
273    <para>
274      As we noted above, an <type>hb_font_t</type> is derived from an
275      <type>hb_face_t</type> with size (and, perhaps, other
276      parameters, such as variation-axis coordinates)
277      specified. Consequently, you can reuse an <type>hb_face_t</type>
278      with several <type>hb_font_t</type> objects, and HarfBuzz
279      provides functions to simplify this.
280    </para>
281    <para>
282      The <function>hb_ft_face_create_referenced()</function>
283      function creates just an <type>hb_face_t</type> from a FreeType
284      <type>FT_Face</type> and, as with
285      <function>hb_ft_font_create_referenced()</function> above,
286      provides lifecycle management for the <type>FT_Face</type>.
287    </para>
288    <para>
289      Similarly, there is an <function>hb_ft_face_create()</function>
290      function variant that does not provide the lifecycle-management
291      feature. As with the font-object case, if you use this version
292      of the function, it will be your client code's respsonsibility
293      to track usage of the <type>FT_Face</type> objects.
294    </para>
295    <para>
296      A third variant of this function is
297      <function>hb_ft_face_create_cached()</function>, which is the
298      same as <function>hb_ft_face_create()</function> except that it
299      also uses the <structfield>generic</structfield> field of the
300      <type>FT_Face</type> structure to save a pointer to the newly
301      created <type>hb_face_t</type>. Subsequently, function calls
302      that pass the same <type>FT_Face</type> will get the same
303      <type>hb_face_t</type> returned &mdash; and the
304      <type>hb_face_t</type> will be correctly reference
305      counted. Still, as with
306      <function>hb_ft_face_create()</function>, your client code must
307      track references to the <type>FT_Face</type> itself, and destroy
308      it when it is unneeded.
309    </para>
310  </section>
311
312  <section id="integration-uniscribe">
313    <title>Uniscribe integration</title>
314    <para>
315      If your client program is running on Windows, HarfBuzz offers
316      an additional API that can help integrate with Microsoft's
317      Uniscribe engine and the Windows GDI.
318    </para>
319    <para>
320      Overall, the Uniscribe API covers a broader set of typographic
321      layout functions than HarfBuzz implements, but HarfBuzz's
322      shaping API can serve as a drop-in replacement for Uniscribe's shaping
323      functionality. In fact, one of HarfBuzz's design goals is to
324      accurately reproduce the same output for shaping a given text
325      segment that Uniscribe produces &mdash; even to the point of
326      duplicating known shaping bugs or deviations from the
327      specification &mdash; so you can be confident that your users'
328      documents with their existing fonts will not be affected adversely by
329      switching to HarfBuzz.
330    </para>
331    <para>
332      At a basic level, HarfBuzz's <function>hb_shape()</function>
333      function replaces both the <ulink url=""><function>ScriptShape()</function></ulink>
334      and <ulink
335      url="https://docs.microsoft.com/en-us/windows/desktop/api/Usp10/nf-usp10-scriptplace"><function>ScriptPlace()</function></ulink>
336      functions from Uniscribe.
337    </para>
338    <para>
339      However, whereas <function>ScriptShape()</function> returns the
340      glyphs and clusters for a shaped sequence and
341      <function>ScriptPlace()</function> returns the advances and
342      offsets for those glyphs, <function>hb_shape()</function>
343      handles both. After <function>hb_shape()</function> shapes a
344      buffer, the output glyph IDs and cluster IDs are returned as
345      an array of <structname>hb_glyph_info_t</structname> structures, and the
346      glyph advances and offsets are returned as an array of
347      <structname>hb_glyph_position_t</structname> structures.
348    </para>
349    <para>
350      Your client program only needs to ensure that it coverts
351      correctly between HarfBuzz's low-level data types (such as
352      <type>hb_position_t</type>) and Windows's corresponding types
353      (such as <type>GOFFSET</type> and <type>ABC</type>). Be sure you
354      read the <xref linkend="buffers-language-script-and-direction"
355      />
356      chapter for a full explanation of how HarfBuzz input buffers are
357      used, and see <xref linkend="shaping-buffer-output" /> for the
358      details of what <function>hb_shape()</function> returns in the
359      output buffer when shaping is complete.
360    </para>
361    <para>
362      Although <function>hb_shape()</function> itself is functionally
363      equivalent to Uniscribe's shaping routines, there are two
364      additional HarfBuzz functions you may want to use to integrate
365      the libraries in your code. Both are used to link HarfBuzz font
366      objects to the equivalent Windows structures.
367    </para>
368    <para>
369      The <function>hb_uniscribe_font_get_logfontw()</function>
370      function takes a <type>hb_font_t</type> font object and returns
371      a pointer to the <ulink
372      url="https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-logfontw"><type>LOGFONTW</type></ulink>
373      "logical font" that corresponds to it. A <type>LOGFONTW</type>
374      structure holds font-wide attributes, including metrics, size,
375      and style information.
376    </para>
377<!--
378     <para>
379       In Uniscribe's model, the <type>SCRIPT_CACHE</type> holds the
380       device context, including the logical font that the shaping
381       functions apply.
382       https://docs.microsoft.com/en-us/windows/desktop/Intl/script-cache
383    </para>
384-->
385    <para>
386      The <function>hb_uniscribe_font_get_hfont()</function> function
387      also takes a <type>hb_font_t</type> font object, but it returns
388      an <type>HFONT</type> &mdash; a handle to the underlying logical
389      font &mdash; instead.
390    </para>
391    <para>
392      <type>LOGFONTW</type>s and <type>HFONT</type>s are both needed
393      by other Uniscribe functions.
394    </para>
395    <para>
396      As a final note, you may notice a reference to an optional
397      <literal>uniscribe</literal> shaper back-end in the <xref
398      linkend="configuration" /> section of the HarfBuzz manual. This
399      option is not a Uniscribe-integration facility.
400    </para>
401    <para>
402      Instead, it is a internal code path used in the
403      <command>hb-shape</command> command-line utility, which hands
404      shaping functionality over to Uniscribe entirely, when run on a
405      Windows system. That allows testing HarfBuzz's native output
406      against the Uniscribe engine, for tracking compatibility and
407      debugging.
408    </para>
409    <para>
410      Because this back-end is only used when testing HarfBuzz
411      functionality, it is disabled by default when building the
412      HarfBuzz binaries.
413    </para>
414  </section>
415
416  <section id="integration-coretext">
417    <title>Core Text integration</title>
418    <para>
419      If your client program is running on macOS or iOS, HarfBuzz offers
420      an additional API that can help integrate with Apple's
421      Core Text engine and the underlying Core Graphics
422      framework. HarfBuzz does not attempt to offer the same
423      drop-in-replacement functionality for Core Text that it strives
424      for with Uniscribe on Windows, but you can still use HarfBuzz
425      to perform text shaping in native macOS and iOS applications.
426    </para>
427    <para>
428      Note, though, that if your interest is just in using fonts that
429      contain Apple Advanced Typography (AAT) features, then you do
430      not need to add Core Text integration. HarfBuzz natively
431      supports AAT features and will shape AAT fonts (on any platform)
432      automatically, without requiring additional work on your
433      part. This includes support for AAT-specific TrueType tables
434      such as <literal>mort</literal>, <literal>morx</literal>, and
435      <literal>kerx</literal>, which AAT fonts use instead of
436      <literal>GSUB</literal> and <literal>GPOS</literal>.
437    </para>
438    <para>
439      On a macOS or iOS system, the primary integration points offered
440      by HarfBuzz are for face objects and font objects.
441    </para>
442    <para>
443      The Apple APIs offer a pair of data structures that map well to
444      HarfBuzz's face and font objects. The Core Graphics API, which
445      is slightly lower-level than Core Text, provides
446      <ulink url="https://developer.apple.com/documentation/coregraphics/cgfontref"><type>CGFontRef</type></ulink>, which enables access to typeface
447      properties, but does not include size information. Core Text's
448      <ulink url="https://developer.apple.com/documentation/coretext/ctfont-q6r"><type>CTFontRef</type></ulink> is analagous to a HarfBuzz font object,
449      with all of the properties required to render text at a specific
450      size and configuration.
451      Consequently, a HarfBuzz <type>hb_font_t</type> font object can
452      be hooked up to a Core Text <type>CTFontRef</type>, and a HarfBuzz
453      <type>hb_face_t</type> face object can be hooked up to a
454      <type>CGFontRef</type>.
455    </para>
456    <para>
457      You can create a <type>hb_face_t</type> from a
458      <type>CGFontRef</type> by using the
459      <function>hb_coretext_face_create()</function>. Subsequently,
460      you can retrieve the <type>CGFontRef</type> from a
461      <type>hb_face_t</type> with <function>hb_coretext_face_get_cg_font()</function>.
462    </para>
463    <para>
464      Likewise, you create a <type>hb_font_t</type> from a
465      <type>CTFontRef</type> by calling
466      <function>hb_coretext_font_create()</function>, and you can
467      fetch the associated <type>CTFontRef</type> from a
468      <type>hb_font_t</type> font object with
469      <function>hb_coretext_face_get_ct_font()</function>.
470    </para>
471    <para>
472      HarfBuzz also offers a <function>hb_font_set_ptem()</function>
473      that you an use to set the nominal point size on any
474      <type>hb_font_t</type> font object. Core Text uses this value to
475      implement optical scaling.
476    </para>
477    <para>
478      When integrating your client code with Core Text, it is
479      important to recognize that Core Text <literal>points</literal>
480      are not typographic points (standardized at 72 per inch) as the
481      term is used elsewhere in OpenType. Instead, Core Text points
482      are CSS points, which are standardized at 96 per inch.
483    </para>
484    <para>
485      HarfBuzz's font functions take this distinction into account,
486      but it can be an easy detail to miss in cross-platform
487      code.
488    </para>
489    <para>
490      As a final note, you may notice a reference to an optional
491      <literal>coretext</literal> shaper back-end in the <xref
492      linkend="configuration" /> section of the HarfBuzz manual. This
493      option is not a Core Text-integration facility.
494    </para>
495    <para>
496      Instead, it is a internal code path used in the
497      <command>hb-shape</command> command-line utility, which hands
498      shaping functionality over to Core Text entirely, when run on a
499      macOS system. That allows testing HarfBuzz's native output
500      against the Core Text engine, for tracking compatibility and debugging.
501    </para>
502    <para>
503      Because this back-end is only used when testing HarfBuzz
504      functionality, it is disabled by default when building the
505      HarfBuzz binaries.
506    </para>
507  </section>
508
509  <section id="integration-icu">
510    <title>ICU integration</title>
511    <para>
512      Although HarfBuzz includes its own Unicode-data functions, it
513      also provides integration APIs for using the International
514      Components for Unicode (ICU) library as a source of Unicode data
515      on any supported platform.
516    </para>
517    <para>
518      The principal integration point with ICU is the
519      <type>hb_unicode_funcs_t</type> Unicode-functions structure
520      attached to a buffer. This structure holds the virtual methods
521      used for retrieving Unicode character properties, such as
522      General Category, Script, Combining Class, decomposition
523      mappings, and mirroring information.
524    </para>
525    <para>
526      To use ICU in your client program, you need to call
527      <function>hb_icu_get_unicode_funcs()</function>, which creates a
528      Unicode-functions structure populated with the ICU function for
529      each included method. Subsequently, you can attach the
530      Unicode-functions structure to your buffer:
531    </para>
532    <programlisting language="C">
533      hb_unicode_funcs_t *icufunctions;
534      icufunctions = hb_icu_get_unicode_funcs();
535      hb_buffer_set_unicode_funcs(buf, icufunctions);
536    </programlisting>
537    <para>
538      and ICU will be used for Unicode-data access.
539    </para>
540    <para>
541      HarfBuzz also supplies a pair of functions
542      (<function>hb_icu_script_from_script()</function> and
543      <function>hb_icu_script_to_script()</function>) for converting
544      between ICU's and HarfBuzz's internal enumerations of Unicode
545      scripts. The <function>hb_icu_script_from_script()</function>
546      function converts from a HarfBuzz <type>hb_script_t</type> to an
547      ICU <type>UScriptCode</type>. The
548      <function>hb_icu_script_to_script()</function> function does the
549      reverse: converting from a <type>UScriptCode</type> identifier
550      to a <type>hb_script_t</type>.
551    </para>
552    <para>
553      By default, HarfBuzz's ICU support is built as a separate shared
554      library (<filename class="libraryfile">libharfbuzz-icu.so</filename>)
555      when compiling HarfBuzz from source. This allows client programs
556      that do not need ICU to link against HarfBuzz without unnecessarily
557      adding ICU as a dependency. You can also build HarfBuzz with ICU
558      support built directly into the main HarfBuzz shared library
559      (<filename class="libraryfile">libharfbuzz.so</filename>),
560      by specifying the <literal>--with-icu=builtin</literal>
561      compile-time option.
562    </para>
563
564  </section>
565
566  <section id="integration-python">
567    <title>Python bindings</title>
568    <para>
569      As noted in the <xref linkend="integration-glib" /> section,
570      HarfBuzz uses a feature called <ulink
571      url="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject
572      Introspection</ulink> (GI) to provide bindings for Python.
573    </para>
574    <para>
575      At compile time, the GI scanner analyzes the HarfBuzz C source
576      and builds metadata objects connecting the language bindings to
577      the C library. Your Python code can then use the HarfBuzz binary
578      through its Python interface.
579    </para>
580    <para>
581      HarfBuzz's Python bindings support Python 2 and Python 3. To use
582      them, you will need to have the <literal>pygobject</literal>
583      package installed. Then you should import
584      <literal>HarfBuzz</literal> from
585      <literal>gi.repository</literal>:
586    </para>
587    <programlisting language="Python">
588      from gi.repository import HarfBuzz
589    </programlisting>
590    <para>
591      and you can call HarfBuzz functions from Python. Sample code can
592      be found in the <filename>sample.py</filename> script in the
593      HarfBuzz <filename>src</filename> directory.
594    </para>
595    <para>
596      Do note, however, that the Python API is subject to change
597      without advance notice. GI allows the bindings to be
598      automatically updated, which is one of its advantages, but you
599      may need to update your Python code.
600    </para>
601  </section>
602
603</chapter>
604