xref: /aosp_15_r20/external/harfbuzz_ng/docs/usermanual-object-model.xml (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
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      Note that many object types can be marked as read-only or immutable,
75      facilitating their use in multi-threaded environments.
76    </para>
77    <para>
78      Key object types provided by HarfBuzz include:
79    </para>
80    <itemizedlist spacing="compact">
81      <listitem>
82	<para>
83	  <emphasis>blobs</emphasis>, which act as low-level wrappers around binary
84	  data. Blobs are typically used to hold the contents of a
85	  binary font file.
86	</para>
87      </listitem>
88      <listitem>
89	<para>
90	  <emphasis>faces</emphasis>, which represent typefaces from a
91	  font file, but without specific parameters (such as size) set.
92	</para>
93      </listitem>
94      <listitem>
95	<para>
96	  <emphasis>fonts</emphasis>, which represent instances of a
97	  face with all of their parameters specified.
98	</para>
99      </listitem>
100      <listitem>
101	<para>
102	  <emphasis>buffers</emphasis>, which hold Unicode code points
103	  for characters (before shaping) and the shaped glyph output
104	  (after shaping).
105	</para>
106      </listitem>
107      <listitem>
108	<para>
109	  <emphasis>shape plans</emphasis>, which store the settings
110	  that HarfBuzz will use when shaping a particular text
111	  segment. Shape plans are not generally used by client
112	  programs directly, but as we will see in a later chapter,
113	  they are still valuable to understand.
114	</para>
115      </listitem>
116    </itemizedlist>
117
118  </section>
119
120
121
122  <section id="object-model-lifecycle">
123    <title>Object lifecycle management</title>
124    <para>
125      Each object type in HarfBuzz provides a
126      <function>create()</function> method. Some object types provide
127      additional variants of <function>create()</function> to handle
128      special cases or to speed up common tasks; those variants are
129      documented in the API reference. For example,
130      <function>hb_blob_create_from_file()</function> constructs a new
131      blob directly from the contents of a file.
132    </para>
133    <para>
134      All objects are created with an initial reference count of
135      <literal>1</literal>. Client programs can increase the reference
136      count on an object by calling its
137      <function>reference()</function> method. Whenever a client
138      program is finished with an object, it should call its
139      corresponding <function>destroy()</function> method. The destroy
140      method will decrease the reference count on the object and,
141      whenever the reference count reaches zero, it will also destroy
142      the object and free all of the associated memory.
143    </para>
144    <para>
145      All of HarfBuzz's object-lifecycle-management APIs are
146      thread-safe (unless you compiled HarfBuzz from source with the
147      <literal>HB_NO_MT</literal> configuration flag), even when the
148      object as a whole is not thread-safe.
149      It is also permissible to <function>reference()</function> or to
150      <function>destroy()</function> the <literal>NULL</literal>
151      value.
152    </para>
153    <para>
154      Some objects are thread-safe after they have been constructed
155      and set up. The general pattern is to
156      <function>create()</function> the object, make a few
157      <function>set_*()</function> calls to set up the
158      object, and then use it without further modification.
159    </para>
160    <para>
161      To ensure that such an object is not modified, client programs
162      can explicitly mark an object as immutable. HarfBuzz provides
163      <function>make_immutable()</function> methods to mark an object
164      as immutable and <function>is_immutable()</function> methods to
165      test whether or not an object is immutable. Attempts to use
166      setter functions on immutable objects will fail silently; see the API
167      Reference manual for specifics.
168    </para>
169    <para>
170      Note also that there are no "make mutable" methods. If client
171      programs need to alter an object previously marked as immutable,
172      they will need to make a duplicate of the original.
173    </para>
174    <para>
175      Finally, object constructors (and, indeed, as much of the
176      shaping API as possible) will never return
177      <literal>NULL</literal>.  Instead, if there is an allocation
178      error, each constructor will return an “empty” object
179      singleton.
180    </para>
181    <para>
182      These empty-object singletons are inert and safe (although
183      typically useless) to pass around.  This design choice avoids
184      having to check for <literal>NULL</literal> pointers all
185      throughout the code.
186    </para>
187    <para>
188      In addition, this “empty” object singleton can also be accessed
189      using the <function>get_empty()</function> method of the object
190      type in question.
191    </para>
192  </section>
193
194
195  <section id="object-model-user-data">
196    <title>User data</title>
197    <para>
198      To better integrate with client programs, HarfBuzz's objects
199      offer a "user data" mechanism that can be used to attach
200      arbitrary data to the object.  User-data attachment can be
201      useful for tying the lifecycles of various pieces of data
202      together, or for creating language bindings.
203    </para>
204    <para>
205      Each object type has a <function>set_user_data()</function>
206      method and a <function>get_user_data()</function> method. The
207      <function>set_user_data()</function> methods take a client-provided
208      <literal>key</literal> and a pointer,
209      <literal>user_data</literal>, pointing to the data itself. Once
210      the key-data pair has been attached to the object, the
211      <function>get_user_data()</function> method can be called with
212      the key, returning the <function>user_data</function> pointer.
213    </para>
214    <para>
215      The <function>set_user_data()</function> methods also support an
216      optional <function>destroy</function> callback. Client programs
217      can set the <function>destroy</function> callback and receive
218      notification from HarfBuzz whenever the object is destructed.
219    </para>
220    <para>
221      Finally, each <function>set_user_data()</function> method allows
222      the client program to set a <literal>replace</literal> Boolean
223      indicating whether or not the function call should replace any
224      existing <literal>user_data</literal>
225      associated with the specified key.
226    </para>
227  </section>
228
229
230
231  <section id="object-model-blobs">
232    <title>Blobs</title>
233    <para>
234      While most of HarfBuzz's object types are specific to the
235      shaping process, <emphasis>blobs</emphasis> are somewhat
236      different.
237    </para>
238    <para>
239      Blobs are an abstraction designed to negotiate lifecycle and
240      permissions for raw pieces of data.  For example, when you load
241      the raw font data into memory and want to pass it to HarfBuzz,
242      you do so in a <literal>hb_blob_t</literal> wrapper.
243    </para>
244    <para>
245      This allows you to take advantage of HarfBuzz's
246      reference-counting and <function>destroy</function>
247      callbacks. If you allocated the memory for the data using
248      <function>malloc()</function>, you would create the blob using
249    </para>
250    <programlisting language="C">
251      hb_blob_create (data, length, HB_MEMORY_MODE_WRITABLE, data, free)
252    </programlisting>
253    <para>
254      That way, HarfBuzz will call <function>free()</function> on the
255      allocated memory whenever the blob drops its last reference and
256      is deconstructed.  Consequently, the user code can stop worrying
257      about freeing memory and let the reference-counting machinery
258      take care of that.
259    </para>
260    <para>
261      Most of the time, blobs are read-only, facilitating their use in
262      immutable objects.
263    </para>
264  </section>
265
266</chapter>
267