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="fonts-and-faces"> 8 <title>Fonts, faces, and output</title> 9 <para> 10 In the previous chapter, we saw how to set up a buffer and fill 11 it with text as Unicode code points. In order to shape this 12 buffer text with HarfBuzz, you will need also need a font 13 object. 14 </para> 15 <para> 16 HarfBuzz provides abstractions to help you cache and reuse the 17 heavier parts of working with binary fonts, so we will look at 18 how to do that. We will also look at how to work with the 19 FreeType font-rendering library and at how you can customize 20 HarfBuzz to work with other libraries. 21 </para> 22 <para> 23 Finally, we will look at how to work with OpenType variable 24 fonts, the latest update to the OpenType font format, and at 25 some other recent additions to OpenType. 26 </para> 27 28 <section id="fonts-and-faces-objects"> 29 <title>Font and face objects</title> 30 <para> 31 The outcome of shaping a run of text depends on the contents of 32 a specific font file (such as the substitutions and positioning 33 moves in the 'GSUB' and 'GPOS' tables), so HarfBuzz makes 34 accessing those internals fast. 35 </para> 36 <para> 37 An <type>hb_face_t</type> represents a <emphasis>face</emphasis> 38 in HarfBuzz. This data type is a wrapper around an 39 <type>hb_blob_t</type> blob that holds the contents of a binary 40 font file. Since HarfBuzz supports TrueType Collections and 41 OpenType Collections (each of which can include multiple 42 typefaces), a HarfBuzz face also requires an index number 43 specifying which typeface in the file you want to use. Most of 44 the font files you will encounter in the wild include just a 45 single face, however, so most of the time you would pass in 46 <literal>0</literal> as the index when you create a face: 47 </para> 48 <programlisting language="C"> 49 hb_blob_t* blob = hb_blob_create_from_file(file); 50 ... 51 hb_face_t* face = hb_face_create(blob, 0); 52 </programlisting> 53 <para> 54 On its own, a face object is not quite ready to use for 55 shaping. The typeface must be set to a specific point size in 56 order for some details (such as hinting) to work. In addition, 57 if the font file in question is an OpenType Variable Font, then 58 you may need to specify one or more variation-axis settings (or a 59 named instance) in order to get the output you need. 60 </para> 61 <para> 62 In HarfBuzz, you do this by creating a <emphasis>font</emphasis> 63 object from your face. 64 </para> 65 <para> 66 Font objects also have the advantage of being considerably 67 lighter-weight than face objects (remember that a face contains 68 the contents of a binary font file mapped into memory). As a 69 result, you can cache and reuse a font object, but you could 70 also create a new one for each additional size you needed. 71 Creating new fonts incurs some additional overhead, of course, 72 but whether or not it is excessive is your call in the end. In 73 contrast, face objects are substantially larger, and you really 74 should cache them and reuse them whenever possible. 75 </para> 76 <para> 77 You can create a font object from a face object: 78 </para> 79 <programlisting language="C"> 80 hb_font_t* hb_font = hb_font_create(hb_face); 81 </programlisting> 82 <para> 83 After creating a font, there are a few properties you should 84 set. Many fonts enable and disable hints based on the size it 85 is used at, so setting this is important for font 86 objects. <function>hb_font_set_ppem(font, x_ppem, 87 y_ppem)</function> sets the pixels-per-EM value of the font. You 88 can also set the point size of the font with 89 <function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the 90 industry standard 72 points per inch. 91 </para> 92 <para> 93 HarfBuzz lets you specify the degree subpixel precision you want 94 through a scaling factor. You can set horizontal and 95 vertical scaling factors on the 96 font by calling <function>hb_font_set_scale(font, x_scale, 97 y_scale)</function>. 98 </para> 99 <para> 100 There may be times when you are handed a font object and need to 101 access the face object that it comes from. For that, you can call 102 </para> 103 <programlisting language="C"> 104 hb_face = hb_font_get_face(hb_font); 105 </programlisting> 106 <para> 107 You can also create a font object from an existing font object 108 using the <function>hb_font_create_sub_font()</function> 109 function. This creates a child font object that is initiated 110 with the same attributes as its parent; it can be used to 111 quickly set up a new font for the purpose of overriding a specific 112 font-functions method. 113 </para> 114 <para> 115 All face objects and font objects are lifecycle-managed by 116 HarfBuzz. After creating a face, you increase its reference 117 count with <function>hb_face_reference(face)</function> and 118 decrease it with 119 <function>hb_face_destroy(face)</function>. Likewise, you 120 increase the reference count on a font with 121 <function>hb_font_reference(font)</function> and decrease it 122 with <function>hb_font_destroy(font)</function>. 123 </para> 124 <para> 125 You can also attach user data to face objects and font objects. 126 </para> 127 </section> 128 129 <section id="fonts-and-faces-custom-functions"> 130 <title>Customizing font functions</title> 131 <para> 132 During shaping, HarfBuzz frequently needs to query font objects 133 to get at the contents and parameters of the glyphs in a font 134 file. It includes a built-in set of functions that is tailored 135 to working with OpenType fonts. However, as was the case with 136 Unicode functions in the buffers chapter, HarfBuzz also wants to 137 make it easy for you to assign a substitute set of font 138 functions if you are developing a program to work with a library 139 or platform that provides its own font functions. 140 </para> 141 <para> 142 Therefore, the HarfBuzz API defines a set of virtual 143 methods for accessing font-object properties, and you can 144 replace the defaults with your own selections without 145 interfering with the shaping process. Each font object in 146 HarfBuzz includes a structure called 147 <literal>font_funcs</literal> that serves as a vtable for the 148 font object. The virtual methods in 149 <literal>font_funcs</literal> are: 150 </para> 151 <itemizedlist> 152 <listitem> 153 <para> 154 <function>hb_font_get_font_h_extents_func_t</function>: returns 155 the extents of the font for horizontal text. 156 </para> 157 </listitem> 158 <listitem> 159 <para> 160 <function>hb_font_get_font_v_extents_func_t</function>: returns 161 the extents of the font for vertical text. 162 </para> 163 </listitem> 164 <listitem> 165 <para> 166 <function>hb_font_get_nominal_glyph_func_t</function>: returns 167 the font's nominal glyph for a given code point. 168 </para> 169 </listitem> 170 <listitem> 171 <para> 172 <function>hb_font_get_variation_glyph_func_t</function>: returns 173 the font's glyph for a given code point when it is followed by a 174 given Variation Selector. 175 </para> 176 </listitem> 177 <listitem> 178 <para> 179 <function>hb_font_get_nominal_glyphs_func_t</function>: returns 180 the font's nominal glyphs for a series of code points. 181 </para> 182 </listitem> 183 <listitem> 184 <para> 185 <function>hb_font_get_glyph_advance_func_t</function>: returns 186 the advance for a glyph. 187 </para> 188 </listitem> 189 <listitem> 190 <para> 191 <function>hb_font_get_glyph_h_advance_func_t</function>: returns 192 the advance for a glyph for horizontal text. 193 </para> 194 </listitem> 195 <listitem> 196 <para> 197 <function>hb_font_get_glyph_v_advance_func_t</function>:returns 198 the advance for a glyph for vertical text. 199 </para> 200 </listitem> 201 <listitem> 202 <para> 203 <function>hb_font_get_glyph_advances_func_t</function>: returns 204 the advances for a series of glyphs. 205 </para> 206 </listitem> 207 <listitem> 208 <para> 209 <function>hb_font_get_glyph_h_advances_func_t</function>: returns 210 the advances for a series of glyphs for horizontal text . 211 </para> 212 </listitem> 213 <listitem> 214 <para> 215 <function>hb_font_get_glyph_v_advances_func_t</function>: returns 216 the advances for a series of glyphs for vertical text. 217 </para> 218 </listitem> 219 <listitem> 220 <para> 221 <function>hb_font_get_glyph_origin_func_t</function>: returns 222 the origin coordinates of a glyph. 223 </para> 224 </listitem> 225 <listitem> 226 <para> 227 <function>hb_font_get_glyph_h_origin_func_t</function>: returns 228 the origin coordinates of a glyph for horizontal text. 229 </para> 230 </listitem> 231 <listitem> 232 <para> 233 <function>hb_font_get_glyph_v_origin_func_t</function>: returns 234 the origin coordinates of a glyph for vertical text. 235 </para> 236 </listitem> 237 <listitem> 238 <para> 239 <function>hb_font_get_glyph_extents_func_t</function>: returns 240 the extents for a glyph. 241 </para> 242 </listitem> 243 <listitem> 244 <para> 245 <function>hb_font_get_glyph_contour_point_func_t</function>: 246 returns the coordinates of a specific contour point from a glyph. 247 </para> 248 </listitem> 249 <listitem> 250 <para> 251 <function>hb_font_get_glyph_name_func_t</function>: returns the 252 name of a glyph (from its glyph index). 253 </para> 254 </listitem> 255 <listitem> 256 <para> 257 <function>hb_font_get_glyph_from_name_func_t</function>: returns 258 the glyph index that corresponds to a given glyph name. 259 </para> 260 </listitem> 261 <listitem> 262 <para> 263 <function>hb_font_draw_glyph_func_t</function>: gets the outlines 264 of a glyph (by calling #hb_draw_funcs_t callbacks). 265 </para> 266 </listitem> 267 <listitem> 268 <para> 269 <function>hb_font_paint_glyph_func_t</function>: paints a glyph 270 (by calling #hb_paint_funcs_t callbacks). 271 </para> 272 </listitem> 273 </itemizedlist> 274 <para> 275 You can create new font-functions by calling 276 <function>hb_font_funcs_create()</function>: 277 </para> 278 <programlisting language="C"> 279 hb_font_funcs_t *ffunctions = hb_font_funcs_create (); 280 hb_font_set_funcs (font, ffunctions, font_data, destroy); 281 </programlisting> 282 <para> 283 The individual methods can each be set with their own setter 284 function, such as 285 <function>hb_font_funcs_set_nominal_glyph_func(ffunctions, 286 func, user_data, destroy)</function>. 287 </para> 288 <para> 289 Font-functions structures can be reused for multiple font 290 objects, and can be reference counted with 291 <function>hb_font_funcs_reference()</function> and 292 <function>hb_font_funcs_destroy()</function>. Just like other 293 objects in HarfBuzz, you can set user-data for each 294 font-functions structure and assign a destroy callback for 295 it. 296 </para> 297 <para> 298 You can also mark a font-functions structure as immutable, 299 with <function>hb_font_funcs_make_immutable()</function>. This 300 is especially useful if your code is a library or framework that 301 will have its own client programs. By marking your 302 font-functions structures as immutable, you prevent your client 303 programs from changing the configuration and introducing 304 inconsistencies and errors downstream. 305 </para> 306 <para> 307 To override only some functions while using the default implementation 308 for the others, you will need to create a sub-font. By default, the 309 sub-font uses the font functions of its parent except for the functions 310 that were explicitly set. The following code will override only the 311 <function>hb_font_get_nominal_glyph_func_t</function> for the sub-font: 312 </para> 313 <programlisting language="C"> 314 hb_font_t *subfont = hb_font_create_sub_font (font) 315 hb_font_funcs_t *ffunctions = hb_font_funcs_create (); 316 hb_font_funcs_set_nominal_glyph_func (ffunctions, func, user_data, destroy); 317 hb_font_set_funcs (subfont, ffunctions, font_data, destroy); 318 hb_font_funcs_destroy (ffunctions); 319 </programlisting> 320 </section> 321 322 <section id="fonts-and-faces-native-opentype"> 323 <title>Font objects and HarfBuzz's native OpenType implementation</title> 324 <para> 325 By default, whenever HarfBuzz creates a font object, it will 326 configure the font to use a built-in set of font functions that 327 supports contemporary OpenType font internals. If you want to 328 work with OpenType or TrueType fonts, you should be able to use 329 these functions without difficulty. 330 </para> 331 <para> 332 Many of the methods in the font-functions structure deal with 333 the fundamental properties of glyphs that are required for 334 shaping text: extents (the maximums and minimums on each axis), 335 origins (the <literal>(0,0)</literal> coordinate point which 336 glyphs are drawn in reference to), and advances (the amount that 337 the cursor needs to be moved after drawing each glyph, including 338 any empty space for the glyph's side bearings). 339 </para> 340 <para> 341 As you can see in the list of functions, there are separate "horizontal" 342 and "vertical" variants depending on whether the text is set in 343 the horizontal or vertical direction. For some scripts, fonts 344 that are designed to support text set horizontally or vertically (for 345 example, in Japanese) may include metrics for both text 346 directions. When fonts don't include this information, HarfBuzz 347 does its best to transform what the font provides. 348 </para> 349 <para> 350 In addition to the direction-specific functions, HarfBuzz 351 provides some higher-level functions for fetching information 352 like extents and advances for a glyph. If you call 353 </para> 354 <programlisting language="C"> 355 hb_font_get_glyph_advance_for_direction(font, direction, extents); 356 </programlisting> 357 <para> 358 then you can provide any <type>hb_direction_t</type> as the 359 <parameter>direction</parameter> parameter, and HarfBuzz will 360 use the correct function variant for the text direction. There 361 are similar higher-level versions of the functions for fetching 362 extents, origin coordinates, and contour-point 363 coordinates. There are also addition and subtraction functions 364 for moving points with respect to the origin. 365 </para> 366 <para> 367 There are also methods for fetching the glyph ID that 368 corresponds to a Unicode code point (possibly when followed by a 369 variation-selector code point), fetching the glyph name from the 370 font, and fetching the glyph ID that corresponds to a glyph name 371 you already have. 372 </para> 373 <para> 374 HarfBuzz also provides functions for converting between glyph 375 names and string 376 variables. <function>hb_font_glyph_to_string(font, glyph, s, 377 size)</function> retrieves the name for the glyph ID 378 <parameter>glyph</parameter> from the font object. It generates a 379 generic name of the form <literal>gidDDD</literal> (where DDD is 380 the glyph index) if there is no name for the glyph in the 381 font. The <function>hb_font_glyph_from_string(font, s, len, 382 glyph)</function> takes an input string <parameter>s</parameter> 383 and looks for a glyph with that name in the font, returning its 384 glyph ID in the <parameter>glyph</parameter> 385 output parameter. It automatically parses 386 <literal>gidDDD</literal> and <literal>uniUUUU</literal> strings. 387 </para> 388 </section> 389 390 <section id="fonts-and-faces-variable"> 391 <title>Working with OpenType Variable Fonts</title> 392 <para> 393 If you are working with OpenType Variable Fonts, there are a few 394 additional functions you should use to specify the 395 variation-axis settings of your font object. Without doing so, 396 your variable font's font object can still be used, but only at 397 the default setting for every axis (which, of course, is 398 sometimes what you want, but does not cover general usage). 399 </para> 400 <para> 401 HarfBuzz manages variation settings in the 402 <type>hb_variation_t</type> data type, which holds a <property>tag</property> for the 403 variation-axis identifier tag and a <property>value</property> for its 404 setting. You can retrieve the list of variation axes in a font 405 binary from the face object (not from a font object, notably) by 406 calling <function>hb_ot_var_get_axis_count(face)</function> to 407 find the number of axes, then using 408 <function>hb_ot_var_get_axis_infos()</function> to collect the 409 axis structures: 410 </para> 411 <programlisting language="C"> 412 axes = hb_ot_var_get_axis_count(face); 413 ... 414 hb_ot_var_get_axis_infos(face, 0, axes, axes_array); 415 </programlisting> 416 <para> 417 For each axis returned in the array, you can can access the 418 identifier in its <property>tag</property>. HarfBuzz also has 419 tag definitions predefined for the five standard axes specified 420 in OpenType (<literal>ital</literal> for italic, 421 <literal>opsz</literal> for optical size, 422 <literal>slnt</literal> for slant, <literal>wdth</literal> for 423 width, and <literal>wght</literal> for weight). Each axis also 424 has a <property>min_value</property>, a 425 <property>default_value</property>, and a <property>max_value</property>. 426 </para> 427 <para> 428 To set your font object's variation settings, you call the 429 <function>hb_font_set_variations()</function> function with an 430 array of <type>hb_variation_t</type> variation settings. Let's 431 say our font has weight and width axes. We need to specify each 432 of the axes by tag and assign a value on the axis: 433 </para> 434 <programlisting language="C"> 435 unsigned int variation_count = 2; 436 hb_variation_t variation_data[variation_count]; 437 variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH; 438 variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT; 439 variation_data[0].value = 80; 440 variation_data[1].value = 750; 441 ... 442 hb_font_set_variations(font, variation_data, variation_count); 443 </programlisting> 444 <para> 445 That should give us a slightly condensed font ("normal" on the 446 <literal>wdth</literal> axis is 100) at a noticeably bolder 447 weight ("regular" is 400 on the <literal>wght</literal> axis). 448 </para> 449 <para> 450 In practice, though, you should always check that the value you 451 want to set on the axis is within the 452 [<property>min_value</property>,<property>max_value</property>] 453 range actually implemented in the font's variation axis. After 454 all, a font might only provide lighter-than-regular weights, and 455 setting a heavier value on the <literal>wght</literal> axis will 456 not change that. 457 </para> 458 <para> 459 Once your variation settings are specified on your font object, 460 however, shaping with a variable font is just like shaping a 461 static font. 462 </para> 463 <para> 464 In addition to providing the variation axes themselves, fonts may also 465 pre-define certain variation coordinates as named instances. HarfBuzz 466 makes these coordinates (and their associated names) available via 467 <function>hb_ot_var_named_instance_get_design_coords()</function> and 468 <function>hb_ot_var_named_instance_get_subfamily_name_id()</function>. 469 </para> 470 <para> 471 Applications should treat named instances like multiple independent, 472 static fonts. 473 </para> 474 </section> 475 476 <section id="glyphs-and-rendering"> 477 <title>Glyphs and rendering</title> 478 479 <para> 480 The main purpose of HarfBuzz is shaping, which creates a list of positioned 481 glyphs as output. The remaining task for text layout is to convert this list 482 into rendered output. While HarfBuzz does not handle rasterization of glyphs 483 per se, it does have APIs that provide access to the font data that is needed 484 to perform this task. 485 </para> 486 <para> 487 Traditionally, the shapes of glyphs in scalable fonts are provided as quadratic 488 or cubic Beziér curves defining outlines to be filled. To obtain the outlines 489 for a glyph, call <function>hb_font_draw_glyph()</function> and pass a 490 <type>hb_draw_funcs_t</type> struct. The callbacks in that struct will be called 491 for each segment of the outline. Note that this API provides access to outlines 492 as they are defined in the font, without applying hinting to fit the curves 493 to the pixel grid. 494 </para> 495 <para> 496 Fonts may provide pre-rendered images for glyphs instead of or in addition to 497 outlines. This is most common for fonts that contain colored glyphs, such as 498 Emoji. To access these images, use <function>hb_ot_color_reference_png()</function> 499 or <function>hb_ot_color_reference_svg()</function>. 500 </para> 501 <para> 502 Another way in which fonts provide colored glyphs is via paint graphs that 503 combine glyph outlines with gradients and allow for transformations and 504 compositing. In its simplest form, this can be presented as a series of 505 layers that are rendered on top of each other, each with its own color. 506 HarfBuzz has the <function>hb_ot_color_glyph_get_layers()</function> to 507 access glyph data in this form. 508 </para> 509 <para> 510 In the general case, you have to use <function>hb_font_paint_glyph()</function> 511 and pass a <type>hb_paint_funcs_t</type> struct with callbacks to obtain paint 512 graphs for glyphs that have them. The <function>hb_font_paint_glyph()</function> 513 API can handle outline and image glyphs as well, so it provides a unified API for 514 access to glyph rendering information. 515 </para> 516 </section> 517 518 </chapter> 519