Imported Upstream version 2.6.4
[platform/upstream/harfbuzz.git] / docs / usermanual-fonts-and-faces.xml
index 01fcdc9..1258bec 100644 (file)
+<?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 and faces</title>
-  <section id="using-freetype">
-    <title>Using FreeType</title>
+  <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="using-harfbuzzs-native-opentype-implementation">
-    <title>Using Harfbuzz's native OpenType implementation</title>
+
+ <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="using-your-own-font-functions">
-    <title>Using your own font functions</title>
+
+  <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>
\ No newline at end of file
+
+ </chapter>