Home | History | Annotate | Download | only in docs
      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="getting-started">
      8   <title>Getting started with HarfBuzz</title>
      9   <section>
     10     <title>An overview of the HarfBuzz shaping API</title>
     11     <para>
     12       The core of the HarfBuzz shaping API is the function
     13       <function>hb_shape()</function>. This function takes a font, a
     14       buffer containing a string of Unicode codepoints and
     15       (optionally) a list of font features as its input. It replaces
     16       the codepoints in the buffer with the corresponding glyphs from
     17       the font, correctly ordered and positioned, and with any of the
     18       optional font features applied.
     19     </para>
     20     <para>
     21       In addition to holding the pre-shaping input (the Unicode
     22       codepoints that comprise the input string) and the post-shaping
     23       output (the glyphs and positions), a HarfBuzz buffer has several
     24       properties that affect shaping. The most important are the
     25       text-flow direction (e.g., left-to-right, right-to-left,
     26       top-to-bottom, or bottom-to-top), the script tag, and the
     27       language tag.
     28     </para>
     29 
     30     <para>
     31       For input string buffers, flags are available to denote when the
     32       buffer represents the beginning or end of a paragraph, to
     33       indicate whether or not to visibly render Unicode <literal>Default
     34       Ignorable</literal> codepoints, and to modify the cluster-merging
     35       behavior for the buffer. For shaped output buffers, the
     36       individual X and Y offsets and <literal>advances</literal>
     37       (the logical dimensions) of each glyph are 
     38       accessible. HarfBuzz also flags glyphs as
     39       <literal>UNSAFE_TO_BREAK</literal> if breaking the string at
     40       that glyph (e.g., in a line-breaking or hyphenation process)
     41       would require re-shaping the text.
     42     </para>
     43     
     44     <para>
     45       HarfBuzz also provides methods to compare the contents of
     46       buffers, join buffers, normalize buffer contents, and handle
     47       invalid codepoints, as well as to determine the state of a
     48       buffer (e.g., input codepoints or output glyphs). Buffer
     49       lifecycles are managed and all buffers are reference-counted.
     50     </para>
     51 
     52     <para>
     53       Although the default <function>hb_shape()</function> function is
     54       sufficient for most use cases, a variant is also provide that
     55       lets you specify which of HarfBuzz's shapers to use on a buffer. 
     56     </para>
     57 
     58     <para>
     59       HarfBuzz can read TrueType fonts, TrueType collections, OpenType
     60       fonts, and OpenType collections. Functions are provided to query
     61       font objects about metrics, Unicode coverage, available tables and
     62       features, and variation selectors. Individual glyphs can also be
     63       queried for metrics, variations, and glyph names. OpenType
     64       variable fonts are supported, and HarfBuzz allows you to set
     65       variation-axis coordinates on font objects.
     66     </para>
     67     
     68     <para>
     69       HarfBuzz provides glue code to integrate with various other
     70       libraries, including FreeType, GObject, and CoreText. Support
     71       for integrating with Uniscribe and DirectWrite is experimental
     72       at present.
     73     </para>
     74   </section>
     75 
     76   <section>
     77     <title>Terminology</title>
     78       <variablelist>
     79 	<varlistentry>
     80 	  <term>shaper</term>
     81 	  <listitem>
     82 	    <para>
     83 	      In HarfBuzz, a <emphasis>shaper</emphasis> is a
     84 	      handler for a specific script shaping model. HarfBuzz
     85 	      implements separate shapers for Indic, Arabic, Thai and
     86 	      Lao, Khmer, Myanmar, Tibetan, Hangul, Hebrew, the
     87 	      Universal Shaping Engine (USE), and a default shaper for
     88 	      non-complex scripts. 
     89 	    </para>
     90 	  </listitem>
     91 	</varlistentry>
     92 	
     93 	<varlistentry>
     94 	  <term>cluster</term>
     95 	  <listitem>
     96 	    <para>
     97 	      In text shaping, a <emphasis>cluster</emphasis> is a
     98 	      sequence of codepoints that must be handled as an
     99 	      indivisible unit. Clusters can include codepoint
    100 	      sequences that form a ligature or base-and-mark
    101 	      sequences. Tracking and preserving clusters is important
    102 	      when shaping operations might separate or reorder
    103 	      codepoints.
    104 	    </para>
    105 	    <para>
    106 	      HarfBuzz provides three cluster
    107 	      <emphasis>levels</emphasis> that implement different
    108 	      approaches to the problem of preserving clusters during
    109 	      shaping operations.
    110 	    </para>
    111 	  </listitem>
    112 	</varlistentry>
    113 	
    114 
    115       </variablelist>
    116     
    117   </section>
    118 
    119 
    120   <section>
    121     <title>A simple shaping example</title>
    122 
    123     <para>
    124       Below is the simplest HarfBuzz shaping example possible.
    125     </para>
    126     <orderedlist numeration="arabic">
    127       <listitem>
    128 	<para>
    129           Create a buffer and put your text in it.
    130 	</para>
    131       </listitem>
    132     </orderedlist>
    133     <programlisting language="C">
    134       #include &lt;hb.h&gt;
    135       hb_buffer_t *buf;
    136       buf = hb_buffer_create();
    137       hb_buffer_add_utf8(buf, text, -1, 0, -1);
    138     </programlisting>
    139     <orderedlist numeration="arabic">
    140       <listitem override="2">
    141 	<para>
    142           Guess the script, language and direction of the buffer.
    143 	</para>
    144       </listitem>
    145     </orderedlist>
    146     <programlisting language="C">
    147       hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
    148       hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
    149       hb_buffer_set_language(buf, hb_language_from_string("en", -1));
    150     </programlisting>
    151     <orderedlist numeration="arabic">
    152       <listitem override="3">
    153 	<para>
    154           Create a face and a font, using FreeType for now.
    155 	</para>
    156       </listitem>
    157     </orderedlist>
    158     <programlisting language="C">
    159       #include &lt;hb-ft.h&gt;
    160       FT_New_Face(ft_library, font_path, index, &amp;face);
    161       FT_Set_Char_Size(face, 0, 1000, 0, 0);
    162       hb_font_t *font = hb_ft_font_create(face);
    163     </programlisting>
    164     <orderedlist numeration="arabic">
    165       <listitem override="4">
    166 	<para>
    167           Shape!
    168 	</para>
    169       </listitem>
    170     </orderedlist>
    171     <programlisting>
    172       hb_shape(font, buf, NULL, 0);
    173     </programlisting>
    174     <orderedlist numeration="arabic">
    175       <listitem override="5">
    176 	<para>
    177           Get the glyph and position information.
    178 	</para>
    179       </listitem>
    180     </orderedlist>
    181     <programlisting language="C">
    182       hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &amp;glyph_count);
    183       hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &amp;glyph_count);
    184     </programlisting>
    185     <orderedlist numeration="arabic">
    186       <listitem override="6">
    187 	<para>
    188           Iterate over each glyph.
    189 	</para>
    190       </listitem>
    191     </orderedlist>
    192     <programlisting language="C">
    193       for (i = 0; i &lt; glyph_count; ++i) {
    194       glyphid = glyph_info[i].codepoint;
    195       x_offset = glyph_pos[i].x_offset / 64.0;
    196       y_offset = glyph_pos[i].y_offset / 64.0;
    197       x_advance = glyph_pos[i].x_advance / 64.0;
    198       y_advance = glyph_pos[i].y_advance / 64.0;
    199       draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset);
    200       cursor_x += x_advance;
    201       cursor_y += y_advance;
    202       }
    203     </programlisting>
    204     <orderedlist numeration="arabic">
    205       <listitem override="7">
    206 	<para>
    207           Tidy up.
    208 	</para>
    209       </listitem>
    210     </orderedlist>
    211     <programlisting language="C">
    212       hb_buffer_destroy(buf);
    213       hb_font_destroy(hb_ft_font);
    214     </programlisting>
    215     
    216     <para>
    217       This example shows enough to get us started using HarfBuzz. In
    218       the sections that follow, we will use the remainder of
    219       HarfBuzz's API to refine and extend the example and improve its
    220       text-shaping capabilities.
    221     </para>
    222   </section>
    223 </chapter>
    224