Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/harfbuzz/docs/usermanual-object-model.xml @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 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> |
