usermanual-getting-started.xml 7.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<chapter id="getting-started">
  <title>Getting started with HarfBuzz</title>
  <section>
    <title>An overview of the HarfBuzz shaping API</title>
    <para>
      The core of the HarfBuzz shaping API is the function
      <function>hb_shape()</function>. This function takes a font, a
      buffer containing a string of Unicode codepoints and
      (optionally) a list of font features as its input. It replaces
      the codepoints in the buffer with the corresponding glyphs from
      the font, correctly ordered and positioned, and with any of the
      optional font features applied.
    </para>
    <para>
      In addition to holding the pre-shaping input (the Unicode
      codepoints that comprise the input string) and the post-shaping
      output (the glyphs and positions), a HarfBuzz buffer has several
      properties that affect shaping. The most important are the
      text-flow direction (e.g., left-to-right, right-to-left,
      top-to-bottom, or bottom-to-top), the script tag, and the
      language tag. HarfBuzz can attempt to guess the correct values
      for the buffer based on its contents if you do not set them
      explicitly.
    </para>
25

26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
    <para>
      For input string buffers, flags are available to denote when the
      buffer represents the beginning or end of a paragraph, to
      indicate whether or not to visibly render Unicode <literal>Default
      Ignorable</literal> codepoints, and to modify the cluster-merging
      behavior for the buffer. For shaped output buffers, the
      individual X and Y offsets and widths of each glyph are
      accessible. HarfBuzz also flags glyphs as
      <literal>UNSAFE_TO_BREAK</literal> if breaking the string at
      that glyph (e.g., in a line-breaking or hyphenation process)
      would alter the shaping output for the buffer.
    </para>
    
    <para>
      HarfBuzz also provides methods to compare the contents of
      buffers, join buffers, normalize buffer contents, and handle
      invalid codepoints, as well as to determine the state of a
      buffer (e.g., input codepoints or output glyphs). Buffer
      lifecycles are managed and all buffers are reference-counted.
    </para>

    <para>
      Although the default <function>hb_shape()</function> function is
      sufficient for most use cases, a variant is also provide that
      lets you specify which of HarfBuzz's shapers to use on a buffer. 
    </para>

    <para>
      HarfBuzz can read TrueType fonts, TrueType collections, OpenType
      fonts, and OpenType collections. Functions are provided to query
      font objects about metrics, Unicode coverage, available tables and
      features, and variation selectors. Individual glyphs can also be
      queried for metrics, variations, and glyph names. OpenType
      variable fonts are supported, and HarfBuzz allows you to set
      variation-axis coordinates on font objects.
    </para>
    
    <para>
      HarfBuzz provides glue code to integrate with FreeType, GObject,
      Uniscribe, and CoreText. Support for integrating with
      DirectWrite is experimental at present.
    </para>
  </section>

  <section>
    <title>Terminology</title>
      <variablelist>
	<varlistentry>
	  <term>shaper</term>
	  <listitem>
	    <para>
	      In HarfBuzz, a <emphasis>shaper</emphasis> is a
	      handler for a specific script shaping model. HarfBuzz
	      implements separate shapers for Indic, Arabic, Thai and
	      Lao, Khmer, Myanmar, Tibetan, Hangul, Hebrew, the
	      Universal Shaping Engine (USE), and a default shaper for
	      non-complex scripts. 
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>cluster</term>
	  <listitem>
	    <para>
	      In text shaping, a <emphasis>cluster</emphasis> is a
	      sequence of codepoints that must be handled as an
	      indivisible unit. Clusters can include codepoint
	      sequences that form a ligature or base-and-mark
	      sequences. Tracking and preserving clusters is important
	      when shaping operations might separate or reorder
	      codepoints.
	    </para>
	    <para>
	      HarfBuzz provides three cluster
	      <emphasis>levels</emphasis> that implement different
	      approaches to the problem of preserving clusters during
	      shaping operations.
	    </para>
	  </listitem>
	</varlistentry>
	

      </variablelist>
    
  </section>


  <section>
    <title>A simple shaping example</title>

    <para>
      Below is the simplest HarfBuzz shaping example possible.
    </para>
    <orderedlist numeration="arabic">
      <listitem>
	<para>
          Create a buffer and put your text in it.
	</para>
      </listitem>
    </orderedlist>
    <programlisting language="C">
      #include &lt;hb.h&gt;
      hb_buffer_t *buf;
      buf = hb_buffer_create();
      hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text));
    </programlisting>
    <orderedlist numeration="arabic">
      <listitem override="2">
	<para>
          Guess the script, language and direction of the buffer.
	</para>
      </listitem>
    </orderedlist>
    <programlisting language="C">
      hb_buffer_guess_segment_properties(buf);
    </programlisting>
    <orderedlist numeration="arabic">
      <listitem override="3">
	<para>
          Create a face and a font, using FreeType for now.
	</para>
      </listitem>
    </orderedlist>
    <programlisting language="C">
      #include &lt;hb-ft.h&gt;
      FT_New_Face(ft_library, font_path, index, &amp;face)
      hb_font_t *font = hb_ft_font_create(face);
    </programlisting>
    <orderedlist numeration="arabic">
      <listitem override="4">
	<para>
          Shape!
	</para>
      </listitem>
    </orderedlist>
    <programlisting>
      hb_shape(font, buf, NULL, 0);
    </programlisting>
    <orderedlist numeration="arabic">
      <listitem override="5">
	<para>
          Get the glyph and position information.
	</para>
      </listitem>
    </orderedlist>
    <programlisting language="C">
      hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &amp;glyph_count);
      hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &amp;glyph_count);
    </programlisting>
    <orderedlist numeration="arabic">
      <listitem override="6">
	<para>
          Iterate over each glyph.
	</para>
      </listitem>
    </orderedlist>
    <programlisting language="C">
      for (i = 0; i &lt; glyph_count; ++i) {
      glyphid = glyph_info[i].codepoint;
      x_offset = glyph_pos[i].x_offset / 64.0;
      y_offset = glyph_pos[i].y_offset / 64.0;
      x_advance = glyph_pos[i].x_advance / 64.0;
      y_advance = glyph_pos[i].y_advance / 64.0;
      draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset);
      cursor_x += x_advance;
      cursor_y += y_advance;
      }
    </programlisting>
    <orderedlist numeration="arabic">
      <listitem override="7">
	<para>
          Tidy up.
	</para>
      </listitem>
    </orderedlist>
    <programlisting language="C">
      hb_buffer_destroy(buf);
      hb_font_destroy(hb_ft_font);
    </programlisting>
    
    <para>
      This example shows enough to get us started using HarfBuzz. In
      the sections that follow, we will use the remainder of
      HarfBuzz's API to refine and extend the example and improve its
      text-shaping capabilities.
    </para>
  </section>
214
</chapter>