Nathan Willis | 9f4b375 | 2018-10-29 17:10:53 -0500 | [diff] [blame] | 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 | ]> |
Simon Cozens | 11a07c4 | 2015-08-31 10:39:10 +0100 | [diff] [blame] | 7 | <chapter id="fonts-and-faces"> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 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 |
Bruce Mitchener | da9d431 | 2019-05-28 21:50:17 +0700 | [diff] [blame] | 40 | font file. Since HarfBuzz supports TrueType Collections and |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 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 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 |
Simon Sapin | cf1a782 | 2019-07-04 21:06:59 +0200 | [diff] [blame] | 89 | <function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 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 | </itemizedlist> |
| 262 | <para> |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 263 | You can create new font-functions by calling |
| 264 | <function>hb_font_funcs_create()</function>: |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 265 | </para> |
| 266 | <programlisting language="C"> |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 267 | hb_font_funcs_t *ffunctions = hb_font_funcs_create (); |
| 268 | hb_font_set_funcs (font, ffunctions, font_data, destroy); |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 269 | </programlisting> |
| 270 | <para> |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 271 | The individual methods can each be set with their own setter |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 272 | function, such as |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 273 | <function>hb_font_funcs_set_nominal_glyph_func(ffunctions, |
| 274 | func, user_data, destroy)</function>. |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 275 | </para> |
| 276 | <para> |
| 277 | Font-functions structures can be reused for multiple font |
| 278 | objects, and can be reference counted with |
| 279 | <function>hb_font_funcs_reference()</function> and |
| 280 | <function>hb_font_funcs_destroy()</function>. Just like other |
| 281 | objects in HarfBuzz, you can set user-data for each |
| 282 | font-functions structure and assign a destroy callback for |
| 283 | it. |
| 284 | </para> |
| 285 | <para> |
| 286 | You can also mark a font-functions structure as immutable, |
| 287 | with <function>hb_font_funcs_make_immutable()</function>. This |
| 288 | is especially useful if your code is a library or framework that |
| 289 | will have its own client programs. By marking your |
| 290 | font-functions structures as immutable, you prevent your client |
| 291 | programs from changing the configuration and introducing |
| 292 | inconsistencies and errors downstream. |
| 293 | </para> |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 294 | <para> |
| 295 | To override only some functions while using the default implementation |
| 296 | for the others, you will need to create a sub-font. By default, the |
| 297 | sub-font uses the font functions of its parent except for the functions |
| 298 | that were explicitly set. The following code will override only the |
| 299 | <function>hb_font_get_nominal_glyph_func_t</function> for the sub-font: |
| 300 | </para> |
| 301 | <programlisting language="C"> |
| 302 | hb_font_t *subfont = hb_font_create_sub_font (font) |
| 303 | hb_font_funcs_t *ffunctions = hb_font_funcs_create (); |
Behdad Esfahbod | feeff59 | 2021-02-09 14:59:40 -0700 | [diff] [blame] | 304 | hb_font_funcs_set_nominal_glyph_func (ffunctions, func, user_data, destroy); |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 305 | hb_font_set_funcs (subfont, ffunctions, font_data, destroy); |
Behdad Esfahbod | feeff59 | 2021-02-09 14:59:40 -0700 | [diff] [blame] | 306 | hb_font_funcs_destroy (ffunctions); |
Khaled Hosny | 319e5b3 | 2021-01-01 01:31:19 +0200 | [diff] [blame] | 307 | </programlisting> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 308 | </section> |
| 309 | |
| 310 | <section id="fonts-and-faces-native-opentype"> |
| 311 | <title>Font objects and HarfBuzz's native OpenType implementation</title> |
| 312 | <para> |
| 313 | By default, whenever HarfBuzz creates a font object, it will |
| 314 | configure the font to use a built-in set of font functions that |
| 315 | supports contemporary OpenType font internals. If you want to |
| 316 | work with OpenType or TrueType fonts, you should be able to use |
| 317 | these functions without difficulty. |
| 318 | </para> |
| 319 | <para> |
| 320 | Many of the methods in the font-functions structure deal with |
| 321 | the fundamental properties of glyphs that are required for |
| 322 | shaping text: extents (the maximums and minimums on each axis), |
| 323 | origins (the <literal>(0,0)</literal> coordinate point which |
| 324 | glyphs are drawn in reference to), and advances (the amount that |
| 325 | the cursor needs to be moved after drawing each glyph, including |
| 326 | any empty space for the glyph's side bearings). |
| 327 | </para> |
| 328 | <para> |
| 329 | As you can see in the list of functions, there are separate "horizontal" |
| 330 | and "vertical" variants depending on whether the text is set in |
| 331 | the horizontal or vertical direction. For some scripts, fonts |
| 332 | that are designed to support text set horizontally or vertically (for |
| 333 | example, in Japanese) may include metrics for both text |
| 334 | directions. When fonts don't include this information, HarfBuzz |
| 335 | does its best to transform what the font provides. |
| 336 | </para> |
| 337 | <para> |
| 338 | In addition to the direction-specific functions, HarfBuzz |
| 339 | provides some higher-level functions for fetching information |
| 340 | like extents and advances for a glyph. If you call |
| 341 | </para> |
| 342 | <programlisting language="C"> |
| 343 | hb_font_get_glyph_advance_for_direction(font, direction, extents); |
| 344 | </programlisting> |
| 345 | <para> |
| 346 | then you can provide any <type>hb_direction_t</type> as the |
| 347 | <parameter>direction</parameter> parameter, and HarfBuzz will |
| 348 | use the correct function variant for the text direction. There |
| 349 | are similar higher-level versions of the functions for fetching |
| 350 | extents, origin coordinates, and contour-point |
| 351 | coordinates. There are also addition and subtraction functions |
| 352 | for moving points with respect to the origin. |
| 353 | </para> |
| 354 | <para> |
| 355 | There are also methods for fetching the glyph ID that |
| 356 | corresponds to a Unicode code point (possibly when followed by a |
| 357 | variation-selector code point), fetching the glyph name from the |
| 358 | font, and fetching the glyph ID that corresponds to a glyph name |
| 359 | you already have. |
| 360 | </para> |
| 361 | <para> |
| 362 | HarfBuzz also provides functions for converting between glyph |
| 363 | names and string |
| 364 | variables. <function>hb_font_glyph_to_string(font, glyph, s, |
| 365 | size)</function> retrieves the name for the glyph ID |
| 366 | <parameter>glyph</parameter> from the font object. It generates a |
| 367 | generic name of the form <literal>gidDDD</literal> (where DDD is |
| 368 | the glyph index) if there is no name for the glyph in the |
| 369 | font. The <function>hb_font_glyph_from_string(font, s, len, |
| 370 | glyph)</function> takes an input string <parameter>s</parameter> |
| 371 | and looks for a glyph with that name in the font, returning its |
| 372 | glyph ID in the <parameter>glyph</parameter> |
| 373 | output parameter. It automatically parses |
| 374 | <literal>gidDDD</literal> and <literal>uniUUUU</literal> strings. |
| 375 | </para> |
| 376 | </section> |
| 377 | |
| 378 | |
| 379 | <!-- Commenting out FreeType integration section-holder for now. May move |
| 380 | to the full-blown Integration Chapter. --> |
| 381 | |
| 382 | <!-- <section id="fonts-and-faces-freetype"> |
Simon Cozens | 5470e74 | 2015-08-29 08:21:18 +0100 | [diff] [blame] | 383 | <title>Using FreeType</title> |
| 384 | <para> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 385 | |
Simon Cozens | 5470e74 | 2015-08-29 08:21:18 +0100 | [diff] [blame] | 386 | </para> |
Simon Cozens | 5470e74 | 2015-08-29 08:21:18 +0100 | [diff] [blame] | 387 | <para> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 388 | |
Simon Cozens | 5470e74 | 2015-08-29 08:21:18 +0100 | [diff] [blame] | 389 | </para> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 390 | </section> --> |
| 391 | |
| 392 | <section id="fonts-and-faces-variable"> |
| 393 | <title>Working with OpenType Variable Fonts</title> |
Simon Cozens | 5470e74 | 2015-08-29 08:21:18 +0100 | [diff] [blame] | 394 | <para> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 395 | If you are working with OpenType Variable Fonts, there are a few |
| 396 | additional functions you should use to specify the |
| 397 | variation-axis settings of your font object. Without doing so, |
| 398 | your variable font's font object can still be used, but only at |
| 399 | the default setting for every axis (which, of course, is |
| 400 | sometimes what you want, but does not cover general usage). |
| 401 | </para> |
| 402 | <para> |
| 403 | HarfBuzz manages variation settings in the |
| 404 | <type>hb_variation_t</type> data type, which holds a <property>tag</property> for the |
| 405 | variation-axis identifier tag and a <property>value</property> for its |
| 406 | setting. You can retrieve the list of variation axes in a font |
| 407 | binary from the face object (not from a font object, notably) by |
| 408 | calling <function>hb_ot_var_get_axis_count(face)</function> to |
| 409 | find the number of axes, then using |
| 410 | <function>hb_ot_var_get_axis_infos()</function> to collect the |
| 411 | axis structures: |
| 412 | </para> |
| 413 | <programlisting language="C"> |
| 414 | axes = hb_ot_var_get_axis_count(face); |
| 415 | ... |
| 416 | hb_ot_var_get_axis_infos(face, 0, axes, axes_array); |
| 417 | </programlisting> |
| 418 | <para> |
| 419 | For each axis returned in the array, you can can access the |
| 420 | identifier in its <property>tag</property>. HarfBuzz also has |
| 421 | tag definitions predefined for the five standard axes specified |
| 422 | in OpenType (<literal>ital</literal> for italic, |
| 423 | <literal>opsz</literal> for optical size, |
| 424 | <literal>slnt</literal> for slant, <literal>wdth</literal> for |
| 425 | width, and <literal>wght</literal> for weight). Each axis also |
| 426 | has a <property>min_value</property>, a |
| 427 | <property>default_value</property>, and a <property>max_value</property>. |
| 428 | </para> |
| 429 | <para> |
| 430 | To set your font object's variation settings, you call the |
| 431 | <function>hb_font_set_variations()</function> function with an |
| 432 | array of <type>hb_variation_t</type> variation settings. Let's |
| 433 | say our font has weight and width axes. We need to specify each |
| 434 | of the axes by tag and assign a value on the axis: |
| 435 | </para> |
| 436 | <programlisting language="C"> |
| 437 | unsigned int variation_count = 2; |
| 438 | hb_variation_t variation_data[variation_count]; |
| 439 | variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH; |
| 440 | variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT; |
| 441 | variation_data[0].value = 80; |
| 442 | variation_data[1].value = 750; |
| 443 | ... |
| 444 | hb_font_set_variations(font, variation_data, variation_count); |
| 445 | </programlisting> |
| 446 | <para> |
| 447 | That should give us a slightly condensed font ("normal" on the |
| 448 | <literal>wdth</literal> axis is 100) at a noticeably bolder |
| 449 | weight ("regular" is 400 on the <literal>wght</literal> axis). |
| 450 | </para> |
| 451 | <para> |
| 452 | In practice, though, you should always check that the value you |
| 453 | want to set on the axis is within the |
| 454 | [<property>min_value</property>,<property>max_value</property>] |
| 455 | range actually implemented in the font's variation axis. After |
| 456 | all, a font might only provide lighter-than-regular weights, and |
| 457 | setting a heavier value on the <literal>wght</literal> axis will |
| 458 | not change that. |
| 459 | </para> |
| 460 | <para> |
| 461 | Once your variation settings are specified on your font object, |
| 462 | however, shaping with a variable font is just like shaping a |
| 463 | static font. |
Simon Cozens | 5470e74 | 2015-08-29 08:21:18 +0100 | [diff] [blame] | 464 | </para> |
Simon Cozens | 11a07c4 | 2015-08-31 10:39:10 +0100 | [diff] [blame] | 465 | </section> |
Nathan Willis | 8354c99 | 2019-04-30 17:22:08 +0100 | [diff] [blame] | 466 | |
| 467 | </chapter> |