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="object-model">
8  <title>The HarfBuzz object model</title>
9  <section id="object-model-intro">
10    <title>An overview of data types in HarfBuzz</title>
11    <para>
12      HarfBuzz features two kinds of data types: non-opaque,
13      pass-by-value types and opaque, heap-allocated types.  This kind
14      of separation is common in C libraries that have to provide
15      API/ABI compatibility (almost) indefinitely.
16    </para>
17    <para>
18      <emphasis>Value types:</emphasis> The non-opaque, pass-by-value
19      types include integer types, enums, and small structs.  Exposing
20      a struct in the public API makes it impossible to expand the
21      struct in the future. As such, exposing structs is reserved for
22      cases where it’s extremely inefficient to do otherwise.
23    </para>
24    <para>
25      In HarfBuzz, several structs, like <literal>hb_glyph_info_t</literal> and
26      <literal>hb_glyph_position_t</literal>, fall into that efficiency-sensitive
27      category and are non-opaque.
28    </para>
29    <para>
30      For all non-opaque structs where future extensibility may be
31      necessary, reserved members are included to hold space for
32      possible future members.  As such, it’s important to provide
33      <function>equal()</function>, and <function>hash()</function>
34      methods for such structs, allowing users of the API do
35      effectively deal with the type without having to
36      adapt their code to future changes.
37    </para>
38    <para>
39      Important value types provided by HarfBuzz include the structs
40      for working with Unicode code points, glyphs, and tags for font
41      tables and features, as well as the enums for many Unicode and
42      OpenType properties.
43    </para>
44  </section>
45
46  <section id="object-model-object-types">
47    <title>Objects in HarfBuzz</title>
48    <para>
49      <emphasis>Object types:</emphasis> Opaque struct types are used
50      for what HarfBuzz loosely calls "objects."  This doesn’t have
51      much to do with the terminology from object-oriented programming
52      (OOP), although some of the concepts are similar.
53    </para>
54    <para>
55      In HarfBuzz, all object types provide certain
56      lifecycle-management APIs.  Objects are reference-counted, and
57      constructed with various <function>create()</function> methods, referenced via
58      <function>reference()</function> and dereferenced using
59      <function>destroy()</function>.
60    </para>
61    <para>
62      For example,
63      the <literal>hb_buffer_t</literal> object has
64      <function>hb_buffer_create()</function> as its constructor,
65      <function>hb_buffer_reference()</function> to reference, and
66      <function>hb_buffer_destroy()</function> to dereference.
67    </para>
68    <para>
69      After construction, each object's properties are accessible only
70      through the setter and getter functions described in the API
71      Reference manual.
72    </para>
73    <para>
74      Key object types provided by HarfBuzz include:
75    </para>
76    <itemizedlist spacing="compact">
77      <listitem>
78	<para>
79	  <emphasis>blobs</emphasis>, which act as low-level wrappers around binary
80	  data. Blobs are typically used to hold the contents of a
81	  binary font file.
82	</para>
83      </listitem>
84      <listitem>
85	<para>
86	  <emphasis>faces</emphasis>, which represent typefaces from a
87	  font file, but without specific parameters (such as size) set.
88	</para>
89      </listitem>
90      <listitem>
91	<para>
92	  <emphasis>fonts</emphasis>, which represent instances of a
93	  face with all of their parameters specified.
94	</para>
95      </listitem>
96      <listitem>
97	<para>
98	  <emphasis>buffers</emphasis>, which hold Unicode code points
99	  for characters (before shaping) and the shaped glyph output
100	  (after shaping).
101	</para>
102      </listitem>
103      <listitem>
104	<para>
105	  <emphasis>shape plans</emphasis>, which store the settings
106	  that HarfBuzz will use when shaping a particular text
107	  segment. Shape plans are not generally used by client
108	  programs directly, but as we will see in a later chapter,
109	  they are still valuable to understand.
110	</para>
111      </listitem>
112    </itemizedlist>
113
114  </section>
115
116
117
118  <section id="object-model-lifecycle">
119    <title>Object lifecycle management</title>
120    <para>
121      Each object type in HarfBuzz provides a
122      <function>create()</function> method. Some object types provide
123      additional variants of <function>create()</function> to handle
124      special cases or to speed up common tasks; those variants are
125      documented in the API reference. For example,
126      <function>hb_blob_create_from_file()</function> constructs a new
127      blob directly from the contents of a file.
128    </para>
129    <para>
130      All objects are created with an initial reference count of
131      <literal>1</literal>. Client programs can increase the reference
132      count on an object by calling its
133      <function>reference()</function> method. Whenever a client
134      program is finished with an object, it should call its
135      corresponding <function>destroy()</function> method. The destroy
136      method will decrease the reference count on the object and,
137      whenever the reference count reaches zero, it will also destroy
138      the object and free all of the associated memory.
139    </para>
140    <para>
141      All of HarfBuzz's object-lifecycle-management APIs are
142      thread-safe (unless you compiled HarfBuzz from source with the
143      <literal>HB_NO_MT</literal> configuration flag), even when the
144      object as a whole is not thread-safe.
145      It is also permissible to <function>reference()</function> or to
146      <function>destroy()</function> the <literal>NULL</literal>
147      value.
148    </para>
149    <para>
150      Some objects are thread-safe after they have been constructed
151      and set up. The general pattern is to
152      <function>create()</function> the object, make a few
153      <function>set_*()</function> calls to set up the
154      object, and then use it without further modification.
155    </para>
156    <para>
157      To ensure that such an object is not modified, client programs
158      can explicitly mark an object as immutable. HarfBuzz provides
159      <function>make_immutable()</function> methods to mark an object
160      as immutable and <function>is_immutable()</function> methods to
161      test whether or not an object is immutable. Attempts to use
162      setter functions on immutable objects will fail silently; see the API
163      Reference manual for specifics.
164    </para>
165    <para>
166      Note also that there are no "make mutable" methods. If client
167      programs need to alter an object previously marked as immutable,
168      they will need to make a duplicate of the original.
169    </para>
170    <para>
171      Finally, object constructors (and, indeed, as much of the
172      shaping API as possible) will never return
173      <literal>NULL</literal>.  Instead, if there is an allocation
174      error, each constructor will return an “empty” object
175      singleton.
176    </para>
177    <para>
178      These empty-object singletons are inert and safe (although
179      typically useless) to pass around.  This design choice avoids
180      having to check for <literal>NULL</literal> pointers all
181      throughout the code.
182    </para>
183    <para>
184      In addition, this “empty” object singleton can also be accessed
185      using the <function>get_empty()</function> method of the object
186      type in question.
187    </para>
188  </section>
189
190
191  <section id="object-model-user-data">
192    <title>User data</title>
193    <para>
194      To better integrate with client programs, HarfBuzz's objects
195      offer a "user data" mechanism that can be used to attach
196      arbitrary data to the object.  User-data attachment can be
197      useful for tying the lifecycles of various pieces of data
198      together, or for creating language bindings.
199    </para>
200    <para>
201      Each object type has a <function>set_user_data()</function>
202      method and a <function>get_user_data()</function> method. The
203      <function>set_user_data()</function> methods take a client-provided
204      <literal>key</literal> and a pointer,
205      <literal>user_data</literal>, pointing to the data itself. Once
206      the key-data pair has been attached to the object, the
207      <function>get_user_data()</function> method can be called with
208      the key, returning the <function>user_data</function> pointer.
209    </para>
210    <para>
211      The <function>set_user_data()</function> methods also support an
212      optional <function>destroy</function> callback. Client programs
213      can set the <function>destroy</function> callback and receive
214      notification from HarfBuzz whenever the object is destructed.
215    </para>
216    <para>
217      Finally, each <function>set_user_data()</function> method allows
218      the client program to set a <literal>replace</literal> Boolean
219      indicating whether or not the function call should replace any
220      existing <literal>user_data</literal>
221      associated with the specified key.
222    </para>
223  </section>
224
225
226
227  <section id="object-model-blobs">
228    <title>Blobs</title>
229    <para>
230      While most of HarfBuzz's object types are specific to the
231      shaping process, <emphasis>blobs</emphasis> are somewhat
232      different.
233    </para>
234    <para>
235      Blobs are an abstraction desgined to negotiate lifecycle and
236      permissions for raw pieces of data.  For example, when you load
237      the raw font data into memory and want to pass it to HarfBuzz,
238      you do so in a <literal>hb_blob_t</literal> wrapper.
239    </para>
240    <para>
241      This allows you to take advantage of HarffBuzz's
242      reference-counting and <function>destroy</function>
243      callbacks. If you allocated the memory for the data using
244      <function>malloc()</function>, you would create the blob using
245    </para>
246    <programlisting language="C">
247      hb_blob_create (data, length, HB_MEMORY_MODE_WRITABLE, NULL, free)
248    </programlisting>
249    <para>
250      That way, HarfBuzz will call <function>free()</function> on the
251      allocated memory whenever the blob drops its last reference and
252      is deconstructed.  Consequently, the user code can stop worrying
253      about freeing memory and let the reference-counting machinery
254      take care of that.
255    </para>
256  </section>
257
258</chapter>
259