<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
  <!ENTITY version SYSTEM "version.xml">
]>
<chapter id="fonts-and-faces">
  <title>Fonts, faces, and output</title>
    <para>
      In the previous chapter, we saw how to set up a buffer and fill
      it with text as Unicode code points. In order to shape this
      buffer text with HarfBuzz, you will need also need a font
      object.
    </para>
    <para>
      HarfBuzz provides abstractions to help you cache and reuse the
      heavier parts of working with binary fonts, so we will look at
      how to do that. We will also look at how to work with the
      FreeType font-rendering library and at how you can customize
      HarfBuzz to work with other libraries.
    </para>
    <para>
      Finally, we will look at how to work with OpenType variable
      fonts, the latest update to the OpenType font format, and at
      some other recent additions to OpenType.
    </para>

  <section id="fonts-and-faces-objects">
    <title>Font and face objects</title>
    <para>
      The outcome of shaping a run of text depends on the contents of
      a specific font file (such as the substitutions and positioning
      moves in the 'GSUB' and 'GPOS' tables), so HarfBuzz makes
      accessing those internals fast.
    </para>
    <para>
      An <type>hb_face_t</type> represents a <emphasis>face</emphasis>
      in HarfBuzz. This data type is a wrapper around an
      <type>hb_blob_t</type> blob that holds the contents of a binary
      font file. Since HarfBuzz supports TrueType Collections and
      OpenType Collections (each of which can include multiple
      typefaces), a HarfBuzz face also requires an index number
      specifying which typeface in the file you want to use. Most of
      the font files you will encounter in the wild include just a
      single face, however, so most of the time you would pass in
      <literal>0</literal> as the index when you create a face:
    </para>
    <programlisting language="C">
      hb_blob_t* blob = hb_blob_create_from_file(file);
      ...
      hb_face_t* face = hb_face_create(blob, 0);
    </programlisting>
    <para>
      On its own, a face object is not quite ready to use for
      shaping. The typeface must be set to a specific point size in
      order for some details (such as hinting) to work. In addition,
      if the font file in question is an OpenType Variable Font, then
      you may need to specify one or variation-axis settings (or a
      named instance) in order to get the output you need.
    </para>
    <para>
      In HarfBuzz, you do this by creating a <emphasis>font</emphasis>
      object from your face.
    </para>
    <para>
      Font objects also have the advantage of being considerably
      lighter-weight than face objects (remember that a face contains
      the contents of a binary font file mapped into memory). As a
      result, you can cache and reuse a font object, but you could
      also create a new one for each additional size you needed.
      Creating new fonts incurs some additional overhead, of course,
      but whether or not it is excessive is your call in the end. In
      contrast, face objects are substantially larger, and you really
      should cache them and reuse them whenever possible.
    </para>
    <para>
      You can create a font object from a face object:
    </para>
    <programlisting language="C">
      hb_font_t* hb_font = hb_font_create(hb_face);
    </programlisting>
    <para>
      After creating a font, there are a few properties you should
      set. Many fonts enable and disable hints based on the size it
      is used at, so setting this is important for font
      objects. <function>hb_font_set_ppem(font, x_ppem,
      y_ppem)</function> sets the pixels-per-EM value of the font. You
      can also set the point size of the font with
      <function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the
      industry standard 72 points per inch.
    </para>
    <para>
      HarfBuzz lets you specify the degree subpixel precision you want
      through a scaling factor. You can set horizontal and
      vertical scaling factors on the
      font by calling <function>hb_font_set_scale(font, x_scale,
      y_scale)</function>. 
    </para>
    <para>
      There may be times when you are handed a font object and need to
      access the face object that it comes from. For that, you can call
    </para>
    <programlisting language="C">
      hb_face = hb_font_get_face(hb_font);
    </programlisting>
    <para>
      You can also create a font object from an existing font object
      using the <function>hb_font_create_sub_font()</function>
      function. This creates a child font object that is initiated
      with the same attributes as its parent; it can be used to
      quickly set up a new font for the purpose of overriding a specific
      font-functions method.
    </para>
    <para>
      All face objects and font objects are lifecycle-managed by
      HarfBuzz. After creating a face, you increase its reference
      count with <function>hb_face_reference(face)</function> and
      decrease it with
      <function>hb_face_destroy(face)</function>. Likewise, you
      increase the reference count on a font with
      <function>hb_font_reference(font)</function> and decrease it
      with <function>hb_font_destroy(font)</function>.
    </para>
    <para>
      You can also attach user data to face objects and font objects.
    </para>
  </section>

 <section id="fonts-and-faces-custom-functions">
    <title>Customizing font functions</title>
    <para>
      During shaping, HarfBuzz frequently needs to query font objects
      to get at the contents and parameters of the glyphs in a font
      file. It includes a built-in set of functions that is tailored
      to working with OpenType fonts. However, as was the case with
      Unicode functions in the buffers chapter, HarfBuzz also wants to
      make it easy for you to assign a substitute set of font
      functions if you are developing a program to work with a library
      or platform that provides its own font functions. 
    </para>
    <para>
      Therefore, the HarfBuzz API defines a set of virtual
      methods for accessing font-object properties, and you can
      replace the defaults with your own selections without
      interfering with the shaping process. Each font object in
      HarfBuzz includes a structure called
      <literal>font_funcs</literal> that serves as a vtable for the
      font object. The virtual methods in
      <literal>font_funcs</literal> are:
    </para>
    <itemizedlist>
      <listitem>
    <para>
      <function>hb_font_get_font_h_extents_func_t</function>: returns
      the extents of the font for horizontal text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_font_v_extents_func_t</function>: returns
      the extents of the font for vertical text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_nominal_glyph_func_t</function>: returns
      the font's nominal glyph for a given code point.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_variation_glyph_func_t</function>: returns
      the font's glyph for a given code point when it is followed by a
      given Variation Selector.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_nominal_glyphs_func_t</function>: returns
      the font's nominal glyphs for a series of code points.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_advance_func_t</function>: returns
      the advance for a glyph.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_h_advance_func_t</function>: returns
      the advance for a glyph for horizontal text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_v_advance_func_t</function>:returns
      the advance for a glyph for vertical text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_advances_func_t</function>: returns
      the advances for a series of glyphs.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_h_advances_func_t</function>: returns
      the advances for a series of glyphs for horizontal text .
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_v_advances_func_t</function>: returns
      the advances for a series of glyphs for vertical text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_origin_func_t</function>: returns
      the origin coordinates of a glyph.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_h_origin_func_t</function>: returns
      the origin coordinates of a glyph for horizontal text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_v_origin_func_t</function>: returns
      the origin coordinates of a glyph for vertical text.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_extents_func_t</function>: returns
      the extents for a glyph.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_contour_point_func_t</function>:
      returns the coordinates of a specific contour point from a glyph.
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_name_func_t</function>: returns the
      name of a glyph (from its glyph index).
    </para>
      </listitem>
      <listitem>
    <para>
      <function>hb_font_get_glyph_from_name_func_t</function>: returns
      the glyph index that corresponds to a given glyph name.
    </para>
      </listitem>
    </itemizedlist>
    <para>
      You can fetch the font-functions configuration for a font object
      by calling <function>hb_font_get_font_funcs()</function>:
    </para>
    <programlisting language="C">
      hb_font_funcs_t *ffunctions;
      ffunctions = hb_font_get_font_funcs (font);
    </programlisting>
    <para>
      The individual methods can each be replaced with their own setter
      function, such as
      <function>hb_font_funcs_set_nominal_glyph_func(*ffunctions,
      func, *user_data, destroy)</function>. 
    </para>
    <para>
      Font-functions structures can be reused for multiple font
      objects, and can be reference counted with
      <function>hb_font_funcs_reference()</function> and
      <function>hb_font_funcs_destroy()</function>. Just like other
      objects in HarfBuzz, you can set user-data for each
      font-functions structure and assign a destroy callback for
      it.
    </para>
    <para>
      You can also mark a font-functions structure as immutable,
      with <function>hb_font_funcs_make_immutable()</function>. This
      is especially useful if your code is a library or framework that
      will have its own client programs. By marking your
      font-functions structures as immutable, you prevent your client
      programs from changing the configuration and introducing
      inconsistencies and errors downstream.
    </para>
  </section>

  <section id="fonts-and-faces-native-opentype">
    <title>Font objects and HarfBuzz's native OpenType implementation</title>
    <para>
      By default, whenever HarfBuzz creates a font object, it will
      configure the font to use a built-in set of font functions that
      supports contemporary OpenType font internals. If you want to
      work with OpenType or TrueType fonts, you should be able to use
      these functions without difficulty.
    </para>
    <para>
      Many of the methods in the font-functions structure deal with
      the fundamental properties of glyphs that are required for
      shaping text: extents (the maximums and minimums on each axis),
      origins (the <literal>(0,0)</literal> coordinate point which
      glyphs are drawn in reference to), and advances (the amount that
      the cursor needs to be moved after drawing each glyph, including
      any empty space for the glyph's side bearings).
    </para>
    <para>
      As you can see in the list of functions, there are separate "horizontal"
      and "vertical" variants depending on whether the text is set in
      the horizontal or vertical direction. For some scripts, fonts
      that are designed to support text set horizontally or vertically (for
      example, in Japanese) may include metrics for both text
      directions. When fonts don't include this information, HarfBuzz
      does its best to transform what the font provides.
    </para>
    <para>
      In addition to the direction-specific functions, HarfBuzz
      provides some higher-level functions for fetching information
      like extents and advances for a glyph. If you call
    </para>
    <programlisting language="C">
      hb_font_get_glyph_advance_for_direction(font, direction, extents);
    </programlisting>
    <para>
      then you can provide any <type>hb_direction_t</type> as the
      <parameter>direction</parameter> parameter, and HarfBuzz will
      use the correct function variant for the text direction. There
      are similar higher-level versions of the functions for fetching
      extents, origin coordinates, and contour-point
      coordinates. There are also addition and subtraction functions
      for moving points with respect to the origin.
    </para>
    <para>
      There are also methods for fetching the glyph ID that
      corresponds to a Unicode code point (possibly when followed by a
      variation-selector code point), fetching the glyph name from the
      font, and fetching the glyph ID that corresponds to a glyph name
      you already have.
    </para>
    <para>
      HarfBuzz also provides functions for converting between glyph
      names and string
      variables. <function>hb_font_glyph_to_string(font, glyph, s,
      size)</function> retrieves the name for the glyph ID
      <parameter>glyph</parameter> from the font object. It generates a
      generic name of the form <literal>gidDDD</literal> (where DDD is
      the glyph index) if there is no name for the glyph in the
      font. The <function>hb_font_glyph_from_string(font, s, len,
      glyph)</function> takes an input string <parameter>s</parameter>
      and looks for a glyph with that name in the font, returning its
      glyph ID in the <parameter>glyph</parameter>
      output parameter. It automatically parses
      <literal>gidDDD</literal> and <literal>uniUUUU</literal> strings.
    </para>
  </section>


  <!-- Commenting out FreeType integration section-holder for now. May move
       to the full-blown Integration Chapter. -->
  
  <!--   <section id="fonts-and-faces-freetype">
    <title>Using FreeType</title>
    <para>

    </para>
    <para>
      
    </para>
  </section> -->

  <section id="fonts-and-faces-variable">
    <title>Working with OpenType Variable Fonts</title>
    <para>
      If you are working with OpenType Variable Fonts, there are a few
      additional functions you should use to specify the
      variation-axis settings of your font object. Without doing so,
      your variable font's font object can still be used, but only at
      the default setting for every axis (which, of course, is
      sometimes what you want, but does not cover general usage).
    </para>
    <para>
      HarfBuzz manages variation settings in the
      <type>hb_variation_t</type> data type, which holds a <property>tag</property> for the
      variation-axis identifier tag and a <property>value</property> for its
      setting. You can retrieve the list of variation axes in a font
      binary from the face object (not from a font object, notably) by
      calling <function>hb_ot_var_get_axis_count(face)</function> to
      find the number of axes, then using
      <function>hb_ot_var_get_axis_infos()</function> to collect the 
      axis structures:
    </para>
    <programlisting language="C">
      axes = hb_ot_var_get_axis_count(face);
      ...
      hb_ot_var_get_axis_infos(face, 0, axes, axes_array);
    </programlisting>
    <para>
      For each axis returned in the array, you can can access the
      identifier in its <property>tag</property>. HarfBuzz also has
      tag definitions predefined for the five standard axes specified
      in OpenType (<literal>ital</literal> for italic,
      <literal>opsz</literal> for optical size,
      <literal>slnt</literal> for slant, <literal>wdth</literal> for
      width, and <literal>wght</literal> for weight). Each axis also
      has a <property>min_value</property>, a
      <property>default_value</property>, and a <property>max_value</property>.
    </para>
    <para>
      To set your font object's variation settings, you call the
      <function>hb_font_set_variations()</function> function with an
      array of <type>hb_variation_t</type> variation settings. Let's
      say our font has weight and width axes. We need to specify each
      of the axes by tag and assign a value on the axis:
    </para>
    <programlisting language="C">
      unsigned int variation_count = 2;
      hb_variation_t variation_data[variation_count];
      variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH;
      variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT;
      variation_data[0].value = 80;
      variation_data[1].value = 750;
      ...
      hb_font_set_variations(font, variation_data, variation_count);
    </programlisting>
    <para>
      That should give us a slightly condensed font ("normal" on the
      <literal>wdth</literal> axis is 100) at a noticeably bolder
      weight ("regular" is 400 on the <literal>wght</literal> axis).
    </para>
    <para>
      In practice, though, you should always check that the value you
      want to set on the axis is within the
      [<property>min_value</property>,<property>max_value</property>]
      range actually implemented in the font's variation axis. After
      all, a font might only provide lighter-than-regular weights, and
      setting a heavier value on the <literal>wght</literal> axis will
      not change that. 
    </para>
    <para>
      Once your variation settings are specified on your font object,
      however, shaping with a variable font is just like shaping a
      static font.
    </para>
  </section>

 </chapter>
