• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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