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 — 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 <hb-glib.h> 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 <hb-ft.h> 205 ... 206 FT_New_Face(ft_library, font_path, index, &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 — 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 — even to the point of 326 duplicating known shaping bugs or deviations from the 327 specification — 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> — a handle to the underlying logical 389 font — 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