Docs: usermanual, add API Overview to Hello HarfBuzz chapter. Start Terminology section.
This commit is contained in:
parent
3a27e8fb97
commit
9e7efa3f47
|
@ -1,99 +1,214 @@
|
|||
<chapter id="hello-harfbuzz">
|
||||
<title>Hello, HarfBuzz</title>
|
||||
<para>
|
||||
Here's the simplest HarfBuzz that can possibly work. We will improve
|
||||
it later.
|
||||
</para>
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem>
|
||||
<para>
|
||||
Create a buffer and put your text in it.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<programlisting language="C">
|
||||
#include <hb.h>
|
||||
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 <hb-ft.h>
|
||||
FT_New_Face(ft_library, font_path, index, &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, &glyph_count);
|
||||
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
|
||||
</programlisting>
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem override="6">
|
||||
<para>
|
||||
Iterate over each glyph.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<programlisting language="C">
|
||||
for (i = 0; i < 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>
|
||||
<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>
|
||||
|
||||
<para>
|
||||
This example shows enough to get us started using HarfBuzz. Now we
|
||||
are going to use the remainder of HarfBuzz's API to refine that
|
||||
example and improve our text shaping capabilities.
|
||||
</para>
|
||||
<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 <hb.h>
|
||||
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 <hb-ft.h>
|
||||
FT_New_Face(ft_library, font_path, index, &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, &glyph_count);
|
||||
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
|
||||
</programlisting>
|
||||
<orderedlist numeration="arabic">
|
||||
<listitem override="6">
|
||||
<para>
|
||||
Iterate over each glyph.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<programlisting language="C">
|
||||
for (i = 0; i < 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>
|
||||
</chapter>
|
||||
|
|
Loading…
Reference in New Issue