xref: /aosp_15_r20/external/harfbuzz_ng/docs/usermanual-fonts-and-faces.xml (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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