blob: 78c9a0e38916cd0c938dbab4cbd7cee70352a2fc [file] [log] [blame]
Nathan Willis2da567e2019-05-24 11:13:53 +01001<?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
Nathan Willisdd1c7652019-05-24 14:30:15 +010022 external libraries like FreeType and International Components for
Nathan Willis2da567e2019-05-24 11:13:53 +010023 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
n8willisa29578c2020-04-13 15:30:18 +010034 properties like the active font, font style, and so on).
Nathan Willis2da567e2019-05-24 11:13:53 +010035 </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
n8willisc241e822020-04-13 15:28:42 +010043 objects. HarfBuzz can use FreeType's built-in functions for
Nathan Willis2da567e2019-05-24 11:13:53 +010044 <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
n8willis3a479212020-04-13 15:42:00 +010071 properties of a code point (such as its General Category (gc),
Nathan Willis2da567e2019-05-24 11:13:53 +010072 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 ...
Nathan Willisdd1c7652019-05-24 14:30:15 +0100206 FT_New_Face(ft_library, font_path, index, &amp;face);
Nathan Willis2da567e2019-05-24 11:13:53 +0100207 FT_Set_Char_Size(face, 0, 1000, 0, 0);
208 hb_font_t *font = hb_ft_font_create(face);
209 </programlisting>
210 <para>
n8willisd6edd9a2020-04-19 15:26:28 +0100211 <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>
Nathan Willis2da567e2019-05-24 11:13:53 +0100221 Although <function>hb_ft_font_create_referenced()</function> is
n8willisd6edd9a2020-04-19 15:26:28 +0100222 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
Nathan Willis2da567e2019-05-24 11:13:53 +0100231 <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>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100315 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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100318 </para>
319 <para>
Nathan Willisdd1c7652019-05-24 14:30:15 +0100320 Overall, the Uniscribe API covers a broader set of typographic
321 layout functions than HarfBuzz implements, but HarfBuzz's
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100322 shaping API can serve as a drop-in replacement for Uniscribe's shaping
Nathan Willisdd1c7652019-05-24 14:30:15 +0100323 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
n8willis9457b602020-04-13 17:01:15 +0100327 specification &mdash; so you can be confident that your users'
328 documents with their existing fonts will not be affected adversely by
Nathan Willisdd1c7652019-05-24 14:30:15 +0100329 switching to HarfBuzz.
Nathan Willis2da567e2019-05-24 11:13:53 +0100330 </para>
331 <para>
Nathan Willisdd1c7652019-05-24 14:30:15 +0100332 At a basic level, HarfBuzz's <function>hb_shape()</function>
333 function replaces both the <ulink url=""><function>ScriptShape()</function></ulink>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100334 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.
Nathan Willisdd1c7652019-05-24 14:30:15 +0100337 </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>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100377<!--
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-->
Nathan Willisdd1c7652019-05-24 14:30:15 +0100385 <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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100413 </para>
414 </section>
Nathan Willisdd1c7652019-05-24 14:30:15 +0100415
Nathan Willis2da567e2019-05-24 11:13:53 +0100416 <section id="integration-coretext">
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100417 <title>Core Text integration</title>
Nathan Willis2da567e2019-05-24 11:13:53 +0100418 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100419 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
n8willis17b60ef2020-04-13 16:51:58 +0100424 for with Uniscribe on Windows, but you can still use HarfBuzz
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100425 to perform text shaping in native macOS and iOS applications.
Nathan Willis2da567e2019-05-24 11:13:53 +0100426 </para>
427 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100428 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>.
Nathan Willis2da567e2019-05-24 11:13:53 +0100437 </para>
438 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100439 On a macOS or iOS system, the primary integration points offered
440 by HarfBuzz are for face objects and font objects.
Nathan Willis2da567e2019-05-24 11:13:53 +0100441 </para>
Nathan Willisdd1c7652019-05-24 14:30:15 +0100442 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100443 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>.
Nathan Willisdd1c7652019-05-24 14:30:15 +0100455 </para>
456 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100457 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>.
Nathan Willisdd1c7652019-05-24 14:30:15 +0100462 </para>
463 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100464 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>.
Nathan Willisdd1c7652019-05-24 14:30:15 +0100470 </para>
471 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100472 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.
Nathan Willisdd1c7652019-05-24 14:30:15 +0100476 </para>
477 <para>
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100478 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
n8willisf782d732020-04-13 16:57:36 +0100493 option is not a Core Text-integration facility.
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100494 </para>
495 <para>
496 Instead, it is a internal code path used in the
497 <command>hb-shape</command> command-line utility, which hands
n8willisf782d732020-04-13 16:57:36 +0100498 shaping functionality over to Core Text entirely, when run on a
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100499 macOS system. That allows testing HarfBuzz's native output
n8willisf782d732020-04-13 16:57:36 +0100500 against the Core Text engine, for tracking compatibility and debugging.
Nathan Willisc0bb66e2019-05-24 18:49:40 +0100501 </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.
Nathan Willisdd1c7652019-05-24 14:30:15 +0100506 </para>
Nathan Willis2da567e2019-05-24 11:13:53 +0100507 </section>
508
509 <section id="integration-icu">
510 <title>ICU integration</title>
511 <para>
Nathan Willis773c85f2019-05-24 19:23:19 +0100512 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>
n8willis05b7bdb2020-04-13 16:59:41 +0100518 The principal integration point with ICU is the
Nathan Willis773c85f2019-05-24 19:23:19 +0100519 <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>
n8willis1ed30512020-04-19 15:38:52 +0100553 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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100562 </para>
Nathan Willis773c85f2019-05-24 19:23:19 +0100563
Nathan Willis2da567e2019-05-24 11:13:53 +0100564 </section>
565
566 <section id="integration-python">
567 <title>Python bindings</title>
568 <para>
Nathan Willis322df802019-05-24 19:49:19 +0100569 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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100573 </para>
574 <para>
Nathan Willis322df802019-05-24 19:49:19 +0100575 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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100579 </para>
580 <para>
Nathan Willis322df802019-05-24 19:49:19 +0100581 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>:
Nathan Willis2da567e2019-05-24 11:13:53 +0100586 </para>
Nathan Willis322df802019-05-24 19:49:19 +0100587 <programlisting language="Python">
588 from gi.repository import HarfBuzz
589 </programlisting>
Nathan Willis2da567e2019-05-24 11:13:53 +0100590 <para>
Nathan Willis322df802019-05-24 19:49:19 +0100591 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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100594 </para>
595 <para>
Nathan Willis322df802019-05-24 19:49:19 +0100596 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.
Nathan Willis2da567e2019-05-24 11:13:53 +0100600 </para>
601 </section>
602
603</chapter>