usermanual-integration.xml 28 KB

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