1 /* 2 * Copyright 1998-2004 David Turner and Werner Lemberg 3 * Copyright 2004,2007,2009 Red Hat, Inc. 4 * Copyright 2011,2012 Google, Inc. 5 * 6 * This is part of HarfBuzz, a text shaping library. 7 * 8 * Permission is hereby granted, without written agreement and without 9 * license or royalty fees, to use, copy, modify, and distribute this 10 * software and its documentation for any purpose, provided that the 11 * above copyright notice and the following two paragraphs appear in 12 * all copies of this software. 13 * 14 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 15 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 16 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 17 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 18 * DAMAGE. 19 * 20 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 21 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 22 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 24 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 * 26 * Red Hat Author(s): Owen Taylor, Behdad Esfahbod 27 * Google Author(s): Behdad Esfahbod 28 */ 29 30 #ifndef HB_H_IN 31 #error "Include <hb.h> instead." 32 #endif 33 34 #ifndef HB_BUFFER_H 35 #define HB_BUFFER_H 36 37 #include "hb-common.h" 38 #include "hb-unicode.h" 39 #include "hb-font.h" 40 41 HB_BEGIN_DECLS 42 43 /** 44 * hb_glyph_info_t: 45 * @codepoint: either a Unicode code point (before shaping) or a glyph index 46 * (after shaping). 47 * @cluster: the index of the character in the original text that corresponds 48 * to this #hb_glyph_info_t, or whatever the client passes to 49 * hb_buffer_add(). More than one #hb_glyph_info_t can have the same 50 * @cluster value, if they resulted from the same character (e.g. one 51 * to many glyph substitution), and when more than one character gets 52 * merged in the same glyph (e.g. many to one glyph substitution) the 53 * #hb_glyph_info_t will have the smallest cluster value of them. 54 * By default some characters are merged into the same cluster 55 * (e.g. combining marks have the same cluster as their bases) 56 * even if they are separate glyphs, hb_buffer_set_cluster_level() 57 * allow selecting more fine-grained cluster handling. 58 * 59 * The #hb_glyph_info_t is the structure that holds information about the 60 * glyphs and their relation to input text. 61 */ 62 typedef struct hb_glyph_info_t 63 { 64 hb_codepoint_t codepoint; 65 /*< private >*/ 66 hb_mask_t mask; 67 /*< public >*/ 68 uint32_t cluster; 69 70 /*< private >*/ 71 hb_var_int_t var1; 72 hb_var_int_t var2; 73 } hb_glyph_info_t; 74 75 /** 76 * hb_glyph_flags_t: 77 * @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the 78 * beginning of the cluster this glyph is part of, 79 * then both sides need to be re-shaped, as the 80 * result might be different. On the flip side, 81 * it means that when this flag is not present, 82 * then it's safe to break the glyph-run at the 83 * beginning of this cluster, and the two sides 84 * represent the exact same result one would get 85 * if breaking input text at the beginning of 86 * this cluster and shaping the two sides 87 * separately. This can be used to optimize 88 * paragraph layout, by avoiding re-shaping 89 * of each line after line-breaking, or limiting 90 * the reshaping to a small piece around the 91 * breaking point only. 92 * @HB_GLYPH_FLAG_DEFINED: All the currently defined flags. 93 * 94 * Since: 1.5.0 95 */ 96 typedef enum { /*< flags >*/ 97 HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, 98 99 HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */ 100 } hb_glyph_flags_t; 101 102 HB_EXTERN hb_glyph_flags_t 103 hb_glyph_info_get_glyph_flags (const hb_glyph_info_t *info); 104 105 #define hb_glyph_info_get_glyph_flags(info) \ 106 ((hb_glyph_flags_t) ((unsigned int) (info)->mask & HB_GLYPH_FLAG_DEFINED)) 107 108 109 /** 110 * hb_glyph_position_t: 111 * @x_advance: how much the line advances after drawing this glyph when setting 112 * text in horizontal direction. 113 * @y_advance: how much the line advances after drawing this glyph when setting 114 * text in vertical direction. 115 * @x_offset: how much the glyph moves on the X-axis before drawing it, this 116 * should not affect how much the line advances. 117 * @y_offset: how much the glyph moves on the Y-axis before drawing it, this 118 * should not affect how much the line advances. 119 * 120 * The #hb_glyph_position_t is the structure that holds the positions of the 121 * glyph in both horizontal and vertical directions. All positions in 122 * #hb_glyph_position_t are relative to the current point. 123 * 124 */ 125 typedef struct hb_glyph_position_t { 126 hb_position_t x_advance; 127 hb_position_t y_advance; 128 hb_position_t x_offset; 129 hb_position_t y_offset; 130 131 /*< private >*/ 132 hb_var_int_t var; 133 } hb_glyph_position_t; 134 135 /** 136 * hb_segment_properties_t: 137 * @direction: the #hb_direction_t of the buffer, see hb_buffer_set_direction(). 138 * @script: the #hb_script_t of the buffer, see hb_buffer_set_script(). 139 * @language: the #hb_language_t of the buffer, see hb_buffer_set_language(). 140 * 141 * The structure that holds various text properties of an #hb_buffer_t. Can be 142 * set and retrieved using hb_buffer_set_segment_properties() and 143 * hb_buffer_get_segment_properties(), respectively. 144 */ 145 typedef struct hb_segment_properties_t { 146 hb_direction_t direction; 147 hb_script_t script; 148 hb_language_t language; 149 /*< private >*/ 150 void *reserved1; 151 void *reserved2; 152 } hb_segment_properties_t; 153 154 #define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \ 155 HB_SCRIPT_INVALID, \ 156 HB_LANGUAGE_INVALID, \ 157 (void *) 0, \ 158 (void *) 0} 159 160 HB_EXTERN hb_bool_t 161 hb_segment_properties_equal (const hb_segment_properties_t *a, 162 const hb_segment_properties_t *b); 163 164 HB_EXTERN unsigned int 165 hb_segment_properties_hash (const hb_segment_properties_t *p); 166 167 168 169 /** 170 * hb_buffer_t: 171 * 172 * The main structure holding the input text and its properties before shaping, 173 * and output glyphs and their information after shaping. 174 */ 175 176 typedef struct hb_buffer_t hb_buffer_t; 177 178 HB_EXTERN hb_buffer_t * 179 hb_buffer_create (void); 180 181 HB_EXTERN hb_buffer_t * 182 hb_buffer_get_empty (void); 183 184 HB_EXTERN hb_buffer_t * 185 hb_buffer_reference (hb_buffer_t *buffer); 186 187 HB_EXTERN void 188 hb_buffer_destroy (hb_buffer_t *buffer); 189 190 HB_EXTERN hb_bool_t 191 hb_buffer_set_user_data (hb_buffer_t *buffer, 192 hb_user_data_key_t *key, 193 void * data, 194 hb_destroy_func_t destroy, 195 hb_bool_t replace); 196 197 HB_EXTERN void * 198 hb_buffer_get_user_data (hb_buffer_t *buffer, 199 hb_user_data_key_t *key); 200 201 202 /** 203 * hb_buffer_content_type_t: 204 * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. 205 * @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping). 206 * @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping). 207 */ 208 typedef enum { 209 HB_BUFFER_CONTENT_TYPE_INVALID = 0, 210 HB_BUFFER_CONTENT_TYPE_UNICODE, 211 HB_BUFFER_CONTENT_TYPE_GLYPHS 212 } hb_buffer_content_type_t; 213 214 HB_EXTERN void 215 hb_buffer_set_content_type (hb_buffer_t *buffer, 216 hb_buffer_content_type_t content_type); 217 218 HB_EXTERN hb_buffer_content_type_t 219 hb_buffer_get_content_type (hb_buffer_t *buffer); 220 221 222 HB_EXTERN void 223 hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, 224 hb_unicode_funcs_t *unicode_funcs); 225 226 HB_EXTERN hb_unicode_funcs_t * 227 hb_buffer_get_unicode_funcs (hb_buffer_t *buffer); 228 229 HB_EXTERN void 230 hb_buffer_set_direction (hb_buffer_t *buffer, 231 hb_direction_t direction); 232 233 HB_EXTERN hb_direction_t 234 hb_buffer_get_direction (hb_buffer_t *buffer); 235 236 HB_EXTERN void 237 hb_buffer_set_script (hb_buffer_t *buffer, 238 hb_script_t script); 239 240 HB_EXTERN hb_script_t 241 hb_buffer_get_script (hb_buffer_t *buffer); 242 243 HB_EXTERN void 244 hb_buffer_set_language (hb_buffer_t *buffer, 245 hb_language_t language); 246 247 248 HB_EXTERN hb_language_t 249 hb_buffer_get_language (hb_buffer_t *buffer); 250 251 HB_EXTERN void 252 hb_buffer_set_segment_properties (hb_buffer_t *buffer, 253 const hb_segment_properties_t *props); 254 255 HB_EXTERN void 256 hb_buffer_get_segment_properties (hb_buffer_t *buffer, 257 hb_segment_properties_t *props); 258 259 HB_EXTERN void 260 hb_buffer_guess_segment_properties (hb_buffer_t *buffer); 261 262 263 /** 264 * hb_buffer_flags_t: 265 * @HB_BUFFER_FLAG_DEFAULT: the default buffer flag. 266 * @HB_BUFFER_FLAG_BOT: flag indicating that special handling of the beginning 267 * of text paragraph can be applied to this buffer. Should usually 268 * be set, unless you are passing to the buffer only part 269 * of the text without the full context. 270 * @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text 271 * paragraph can be applied to this buffer, similar to 272 * @HB_BUFFER_FLAG_BOT. 273 * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES: 274 * flag indication that character with Default_Ignorable 275 * Unicode property should use the corresponding glyph 276 * from the font, instead of hiding them (done by 277 * replacing them with the space glyph and zeroing the 278 * advance width.) This flag takes precedence over 279 * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES. 280 * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES: 281 * flag indication that character with Default_Ignorable 282 * Unicode property should be removed from glyph string 283 * instead of hiding them (done by replacing them with the 284 * space glyph and zeroing the advance width.) 285 * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES takes 286 * precedence over this flag. Since: 1.8.0 287 * 288 * Since: 0.9.20 289 */ 290 typedef enum { /*< flags >*/ 291 HB_BUFFER_FLAG_DEFAULT = 0x00000000u, 292 HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */ 293 HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */ 294 HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u, 295 HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u 296 } hb_buffer_flags_t; 297 298 HB_EXTERN void 299 hb_buffer_set_flags (hb_buffer_t *buffer, 300 hb_buffer_flags_t flags); 301 302 HB_EXTERN hb_buffer_flags_t 303 hb_buffer_get_flags (hb_buffer_t *buffer); 304 305 /** 306 * hb_buffer_cluster_level_t: 307 * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES: Return cluster values grouped by graphemes into 308 * monotone order. 309 * @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS: Return cluster values grouped into monotone order. 310 * @HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: Don't group cluster values. 311 * @HB_BUFFER_CLUSTER_LEVEL_DEFAULT: Default cluster level, 312 * equal to @HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES. 313 * 314 * Since: 0.9.42 315 */ 316 typedef enum { 317 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, 318 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, 319 HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, 320 HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES 321 } hb_buffer_cluster_level_t; 322 323 HB_EXTERN void 324 hb_buffer_set_cluster_level (hb_buffer_t *buffer, 325 hb_buffer_cluster_level_t cluster_level); 326 327 HB_EXTERN hb_buffer_cluster_level_t 328 hb_buffer_get_cluster_level (hb_buffer_t *buffer); 329 330 /** 331 * HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT: 332 * 333 * The default code point for replacing invalid characters in a given encoding. 334 * Set to U+FFFD REPLACEMENT CHARACTER. 335 * 336 * Since: 0.9.31 337 */ 338 #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu 339 340 HB_EXTERN void 341 hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, 342 hb_codepoint_t replacement); 343 344 HB_EXTERN hb_codepoint_t 345 hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); 346 347 HB_EXTERN void 348 hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, 349 hb_codepoint_t invisible); 350 351 HB_EXTERN hb_codepoint_t 352 hb_buffer_get_invisible_glyph (hb_buffer_t *buffer); 353 354 355 HB_EXTERN void 356 hb_buffer_reset (hb_buffer_t *buffer); 357 358 HB_EXTERN void 359 hb_buffer_clear_contents (hb_buffer_t *buffer); 360 361 HB_EXTERN hb_bool_t 362 hb_buffer_pre_allocate (hb_buffer_t *buffer, 363 unsigned int size); 364 365 366 HB_EXTERN hb_bool_t 367 hb_buffer_allocation_successful (hb_buffer_t *buffer); 368 369 HB_EXTERN void 370 hb_buffer_reverse (hb_buffer_t *buffer); 371 372 HB_EXTERN void 373 hb_buffer_reverse_range (hb_buffer_t *buffer, 374 unsigned int start, unsigned int end); 375 376 HB_EXTERN void 377 hb_buffer_reverse_clusters (hb_buffer_t *buffer); 378 379 380 /* Filling the buffer in */ 381 382 HB_EXTERN void 383 hb_buffer_add (hb_buffer_t *buffer, 384 hb_codepoint_t codepoint, 385 unsigned int cluster); 386 387 HB_EXTERN void 388 hb_buffer_add_utf8 (hb_buffer_t *buffer, 389 const char *text, 390 int text_length, 391 unsigned int item_offset, 392 int item_length); 393 394 HB_EXTERN void 395 hb_buffer_add_utf16 (hb_buffer_t *buffer, 396 const uint16_t *text, 397 int text_length, 398 unsigned int item_offset, 399 int item_length); 400 401 HB_EXTERN void 402 hb_buffer_add_utf32 (hb_buffer_t *buffer, 403 const uint32_t *text, 404 int text_length, 405 unsigned int item_offset, 406 int item_length); 407 408 HB_EXTERN void 409 hb_buffer_add_latin1 (hb_buffer_t *buffer, 410 const uint8_t *text, 411 int text_length, 412 unsigned int item_offset, 413 int item_length); 414 415 HB_EXTERN void 416 hb_buffer_add_codepoints (hb_buffer_t *buffer, 417 const hb_codepoint_t *text, 418 int text_length, 419 unsigned int item_offset, 420 int item_length); 421 422 HB_EXTERN void 423 hb_buffer_append (hb_buffer_t *buffer, 424 hb_buffer_t *source, 425 unsigned int start, 426 unsigned int end); 427 428 HB_EXTERN hb_bool_t 429 hb_buffer_set_length (hb_buffer_t *buffer, 430 unsigned int length); 431 432 HB_EXTERN unsigned int 433 hb_buffer_get_length (hb_buffer_t *buffer); 434 435 /* Getting glyphs out of the buffer */ 436 437 HB_EXTERN hb_glyph_info_t * 438 hb_buffer_get_glyph_infos (hb_buffer_t *buffer, 439 unsigned int *length); 440 441 HB_EXTERN hb_glyph_position_t * 442 hb_buffer_get_glyph_positions (hb_buffer_t *buffer, 443 unsigned int *length); 444 445 446 HB_EXTERN void 447 hb_buffer_normalize_glyphs (hb_buffer_t *buffer); 448 449 450 /* 451 * Serialize 452 */ 453 454 /** 455 * hb_buffer_serialize_flags_t: 456 * @HB_BUFFER_SERIALIZE_FLAG_DEFAULT: serialize glyph names, clusters and positions. 457 * @HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS: do not serialize glyph cluster. 458 * @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information. 459 * @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name. 460 * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents. 461 * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0 462 * @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances, 463 * glyph offsets will reflect absolute glyph positions. Since: 1.8.0 464 * 465 * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs(). 466 * 467 * Since: 0.9.20 468 */ 469 typedef enum { /*< flags >*/ 470 HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000u, 471 HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u, 472 HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u, 473 HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, 474 HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u, 475 HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u, 476 HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u 477 } hb_buffer_serialize_flags_t; 478 479 /** 480 * hb_buffer_serialize_format_t: 481 * @HB_BUFFER_SERIALIZE_FORMAT_TEXT: a human-readable, plain text format. 482 * @HB_BUFFER_SERIALIZE_FORMAT_JSON: a machine-readable JSON format. 483 * @HB_BUFFER_SERIALIZE_FORMAT_INVALID: invalid format. 484 * 485 * The buffer serialization and de-serialization format used in 486 * hb_buffer_serialize_glyphs() and hb_buffer_deserialize_glyphs(). 487 * 488 * Since: 0.9.2 489 */ 490 typedef enum { 491 HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'), 492 HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'), 493 HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE 494 } hb_buffer_serialize_format_t; 495 496 HB_EXTERN hb_buffer_serialize_format_t 497 hb_buffer_serialize_format_from_string (const char *str, int len); 498 499 HB_EXTERN const char * 500 hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format); 501 502 HB_EXTERN const char ** 503 hb_buffer_serialize_list_formats (void); 504 505 HB_EXTERN unsigned int 506 hb_buffer_serialize_glyphs (hb_buffer_t *buffer, 507 unsigned int start, 508 unsigned int end, 509 char *buf, 510 unsigned int buf_size, 511 unsigned int *buf_consumed, 512 hb_font_t *font, 513 hb_buffer_serialize_format_t format, 514 hb_buffer_serialize_flags_t flags); 515 516 HB_EXTERN hb_bool_t 517 hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, 518 const char *buf, 519 int buf_len, 520 const char **end_ptr, 521 hb_font_t *font, 522 hb_buffer_serialize_format_t format); 523 524 525 /* 526 * Compare buffers 527 */ 528 529 typedef enum { /*< flags >*/ 530 HB_BUFFER_DIFF_FLAG_EQUAL = 0x0000, 531 532 /* Buffers with different content_type cannot be meaningfully compared 533 * in any further detail. */ 534 HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH = 0x0001, 535 536 /* For buffers with differing length, the per-glyph comparison is not 537 * attempted, though we do still scan reference for dottedcircle / .notdef 538 * glyphs. */ 539 HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH = 0x0002, 540 541 /* We want to know if dottedcircle / .notdef glyphs are present in the 542 * reference, as we may not care so much about other differences in this 543 * case. */ 544 HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT = 0x0004, 545 HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT = 0x0008, 546 547 /* If the buffers have the same length, we compare them glyph-by-glyph 548 * and report which aspect(s) of the glyph info/position are different. */ 549 HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH = 0x0010, 550 HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH = 0x0020, 551 HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH = 0x0040, 552 HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH = 0x0080 553 554 } hb_buffer_diff_flags_t; 555 556 /* Compare the contents of two buffers, report types of differences. */ 557 HB_EXTERN hb_buffer_diff_flags_t 558 hb_buffer_diff (hb_buffer_t *buffer, 559 hb_buffer_t *reference, 560 hb_codepoint_t dottedcircle_glyph, 561 unsigned int position_fuzz); 562 563 564 /* 565 * Debugging. 566 */ 567 568 typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer, 569 hb_font_t *font, 570 const char *message, 571 void *user_data); 572 573 HB_EXTERN void 574 hb_buffer_set_message_func (hb_buffer_t *buffer, 575 hb_buffer_message_func_t func, 576 void *user_data, hb_destroy_func_t destroy); 577 578 579 HB_END_DECLS 580 581 #endif /* HB_BUFFER_H */ 582