Each object type in HarfBuzz provides a
create()
method. Some object types provide
additional variants of create()
to handle
special cases or to speed up common tasks; those variants are
documented in the API reference. For example,
hb_blob_create_from_file()
constructs a new
blob directly from the contents of a file.
All objects are created with an initial reference count of
1
. Client programs can increase the reference
count on an object by calling its
reference()
method. Whenever a client
program is finished with an object, it should call its
corresponding destroy()
method. The destroy
method will decrease the reference count on the object and,
whenever the reference count reaches zero, it will also destroy
the object and free all of the associated memory.
All of HarfBuzz's object-lifecycle-management APIs are
thread-safe (unless you compiled HarfBuzz from source with the
HB_NO_MT
configuration flag), even when the
object as a whole is not thread-safe.
It is also permissible to reference()
or to
destroy()
the NULL
value.
Some objects are thread-safe after they have been constructed
and set up. The general pattern is to
create()
the object, make a few
set_*()
calls to set up the
object, and then use it without further modification.
To ensure that such an object is not modified, client programs
can explicitly mark an object as immutable. HarfBuzz provides
make_immutable()
methods to mark an object
as immutable and is_immutable()
methods to
test whether or not an object is immutable. Attempts to use
setter functions on immutable objects will fail silently; see the API
Reference manual for specifics.
Note also that there are no "make mutable" methods. If client programs need to alter an object previously marked as immutable, they will need to make a duplicate of the original.
Finally, object constructors (and, indeed, as much of the
shaping API as possible) will never return
NULL
. Instead, if there is an allocation
error, each constructor will return an “empty” object
singleton.
These empty-object singletons are inert and safe (although
typically useless) to pass around. This design choice avoids
having to check for NULL
pointers all
throughout the code.
In addition, this “empty” object singleton can also be accessed
using the get_empty()
method of the object
type in question.