Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/harfbuzz/docs/usermanual-integration.xml @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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 converts | |
| 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 analogous 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> |
