Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  1998-2004  David Turner and Werner Lemberg
      3  * Copyright  2004,2007,2009,2010  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 #include "hb-buffer-private.hh"
     31 #include "hb-utf-private.hh"
     32 
     33 
     34 /**
     35  * SECTION: hb-buffer
     36  * @title: Buffers
     37  * @short_description: Input and output buffers
     38  * @include: hb.h
     39  *
     40  * Buffers serve dual role in HarfBuzz; they hold the input characters that are
     41  * passed hb_shape(), and after shaping they hold the output glyphs.
     42  **/
     43 
     44 /**
     45  * hb_segment_properties_equal:
     46  * @a: first #hb_segment_properties_t to compare.
     47  * @b: second #hb_segment_properties_t to compare.
     48  *
     49  * Checks the equality of two #hb_segment_properties_t's.
     50  *
     51  * Return value:
     52  * %true if all properties of @a equal those of @b, false otherwise.
     53  *
     54  * Since: 0.9.7
     55  **/
     56 hb_bool_t
     57 hb_segment_properties_equal (const hb_segment_properties_t *a,
     58 			     const hb_segment_properties_t *b)
     59 {
     60   return a->direction == b->direction &&
     61 	 a->script    == b->script    &&
     62 	 a->language  == b->language  &&
     63 	 a->reserved1 == b->reserved1 &&
     64 	 a->reserved2 == b->reserved2;
     65 
     66 }
     67 
     68 /**
     69  * hb_segment_properties_hash:
     70  * @p: #hb_segment_properties_t to hash.
     71  *
     72  * Creates a hash representing @p.
     73  *
     74  * Return value:
     75  * A hash of @p.
     76  *
     77  * Since: 0.9.7
     78  **/
     79 unsigned int
     80 hb_segment_properties_hash (const hb_segment_properties_t *p)
     81 {
     82   return (unsigned int) p->direction ^
     83 	 (unsigned int) p->script ^
     84 	 (intptr_t) (p->language);
     85 }
     86 
     87 
     88 
     89 /* Here is how the buffer works internally:
     90  *
     91  * There are two info pointers: info and out_info.  They always have
     92  * the same allocated size, but different lengths.
     93  *
     94  * As an optimization, both info and out_info may point to the
     95  * same piece of memory, which is owned by info.  This remains the
     96  * case as long as out_len doesn't exceed i at any time.
     97  * In that case, swap_buffers() is no-op and the glyph operations operate
     98  * mostly in-place.
     99  *
    100  * As soon as out_info gets longer than info, out_info is moved over
    101  * to an alternate buffer (which we reuse the pos buffer for!), and its
    102  * current contents (out_len entries) are copied to the new place.
    103  * This should all remain transparent to the user.  swap_buffers() then
    104  * switches info and out_info.
    105  */
    106 
    107 
    108 
    109 /* Internal API */
    110 
    111 bool
    112 hb_buffer_t::enlarge (unsigned int size)
    113 {
    114   if (unlikely (in_error))
    115     return false;
    116   if (unlikely (size > max_len))
    117   {
    118     in_error = true;
    119     return false;
    120   }
    121 
    122   unsigned int new_allocated = allocated;
    123   hb_glyph_position_t *new_pos = nullptr;
    124   hb_glyph_info_t *new_info = nullptr;
    125   bool separate_out = out_info != info;
    126 
    127   if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
    128     goto done;
    129 
    130   while (size >= new_allocated)
    131     new_allocated += (new_allocated >> 1) + 32;
    132 
    133   static_assert ((sizeof (info[0]) == sizeof (pos[0])), "");
    134   if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
    135     goto done;
    136 
    137   new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
    138   new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
    139 
    140 done:
    141   if (unlikely (!new_pos || !new_info))
    142     in_error = true;
    143 
    144   if (likely (new_pos))
    145     pos = new_pos;
    146 
    147   if (likely (new_info))
    148     info = new_info;
    149 
    150   out_info = separate_out ? (hb_glyph_info_t *) pos : info;
    151   if (likely (!in_error))
    152     allocated = new_allocated;
    153 
    154   return likely (!in_error);
    155 }
    156 
    157 bool
    158 hb_buffer_t::make_room_for (unsigned int num_in,
    159 			    unsigned int num_out)
    160 {
    161   if (unlikely (!ensure (out_len + num_out))) return false;
    162 
    163   if (out_info == info &&
    164       out_len + num_out > idx + num_in)
    165   {
    166     assert (have_output);
    167 
    168     out_info = (hb_glyph_info_t *) pos;
    169     memcpy (out_info, info, out_len * sizeof (out_info[0]));
    170   }
    171 
    172   return true;
    173 }
    174 
    175 bool
    176 hb_buffer_t::shift_forward (unsigned int count)
    177 {
    178   assert (have_output);
    179   if (unlikely (!ensure (len + count))) return false;
    180 
    181   memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0]));
    182   if (idx + count > len)
    183   {
    184     /* Under memory failure we might expose this area.  At least
    185      * clean it up.  Oh well... */
    186     memset (info + len, 0, (idx + count - len) * sizeof (info[0]));
    187   }
    188   len += count;
    189   idx += count;
    190 
    191   return true;
    192 }
    193 
    194 hb_buffer_t::scratch_buffer_t *
    195 hb_buffer_t::get_scratch_buffer (unsigned int *size)
    196 {
    197   have_output = false;
    198   have_positions = false;
    199 
    200   out_len = 0;
    201   out_info = info;
    202 
    203   assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
    204   *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
    205   return (scratch_buffer_t *) (void *) pos;
    206 }
    207 
    208 
    209 
    210 /* HarfBuzz-Internal API */
    211 
    212 void
    213 hb_buffer_t::reset (void)
    214 {
    215   if (unlikely (hb_object_is_inert (this)))
    216     return;
    217 
    218   hb_unicode_funcs_destroy (unicode);
    219   unicode = hb_unicode_funcs_get_default ();
    220   flags = HB_BUFFER_FLAG_DEFAULT;
    221   replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
    222 
    223   clear ();
    224 }
    225 
    226 void
    227 hb_buffer_t::clear (void)
    228 {
    229   if (unlikely (hb_object_is_inert (this)))
    230     return;
    231 
    232   hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
    233   props = default_props;
    234   scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
    235 
    236   content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
    237   in_error = false;
    238   have_output = false;
    239   have_positions = false;
    240 
    241   idx = 0;
    242   len = 0;
    243   out_len = 0;
    244   out_info = info;
    245 
    246   serial = 0;
    247 
    248   memset (context, 0, sizeof context);
    249   memset (context_len, 0, sizeof context_len);
    250 
    251   deallocate_var_all ();
    252 }
    253 
    254 void
    255 hb_buffer_t::add (hb_codepoint_t  codepoint,
    256 		  unsigned int    cluster)
    257 {
    258   hb_glyph_info_t *glyph;
    259 
    260   if (unlikely (!ensure (len + 1))) return;
    261 
    262   glyph = &info[len];
    263 
    264   memset (glyph, 0, sizeof (*glyph));
    265   glyph->codepoint = codepoint;
    266   glyph->mask = 0;
    267   glyph->cluster = cluster;
    268 
    269   len++;
    270 }
    271 
    272 void
    273 hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info)
    274 {
    275   if (unlikely (!ensure (len + 1))) return;
    276 
    277   info[len] = glyph_info;
    278 
    279   len++;
    280 }
    281 
    282 
    283 void
    284 hb_buffer_t::remove_output (void)
    285 {
    286   if (unlikely (hb_object_is_inert (this)))
    287     return;
    288 
    289   have_output = false;
    290   have_positions = false;
    291 
    292   out_len = 0;
    293   out_info = info;
    294 }
    295 
    296 void
    297 hb_buffer_t::clear_output (void)
    298 {
    299   if (unlikely (hb_object_is_inert (this)))
    300     return;
    301 
    302   have_output = true;
    303   have_positions = false;
    304 
    305   out_len = 0;
    306   out_info = info;
    307 }
    308 
    309 void
    310 hb_buffer_t::clear_positions (void)
    311 {
    312   if (unlikely (hb_object_is_inert (this)))
    313     return;
    314 
    315   have_output = false;
    316   have_positions = true;
    317 
    318   out_len = 0;
    319   out_info = info;
    320 
    321   memset (pos, 0, sizeof (pos[0]) * len);
    322 }
    323 
    324 void
    325 hb_buffer_t::swap_buffers (void)
    326 {
    327   if (unlikely (in_error)) return;
    328 
    329   assert (have_output);
    330   have_output = false;
    331 
    332   if (out_info != info)
    333   {
    334     hb_glyph_info_t *tmp_string;
    335     tmp_string = info;
    336     info = out_info;
    337     out_info = tmp_string;
    338     pos = (hb_glyph_position_t *) out_info;
    339   }
    340 
    341   unsigned int tmp;
    342   tmp = len;
    343   len = out_len;
    344   out_len = tmp;
    345 
    346   idx = 0;
    347 }
    348 
    349 
    350 void
    351 hb_buffer_t::replace_glyphs (unsigned int num_in,
    352 			     unsigned int num_out,
    353 			     const uint32_t *glyph_data)
    354 {
    355   if (unlikely (!make_room_for (num_in, num_out))) return;
    356 
    357   merge_clusters (idx, idx + num_in);
    358 
    359   hb_glyph_info_t orig_info = info[idx];
    360   hb_glyph_info_t *pinfo = &out_info[out_len];
    361   for (unsigned int i = 0; i < num_out; i++)
    362   {
    363     *pinfo = orig_info;
    364     pinfo->codepoint = glyph_data[i];
    365     pinfo++;
    366   }
    367 
    368   idx  += num_in;
    369   out_len += num_out;
    370 }
    371 
    372 void
    373 hb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
    374 {
    375   if (unlikely (!make_room_for (0, 1))) return;
    376 
    377   out_info[out_len] = info[idx];
    378   out_info[out_len].codepoint = glyph_index;
    379 
    380   out_len++;
    381 }
    382 
    383 void
    384 hb_buffer_t::output_info (const hb_glyph_info_t &glyph_info)
    385 {
    386   if (unlikely (!make_room_for (0, 1))) return;
    387 
    388   out_info[out_len] = glyph_info;
    389 
    390   out_len++;
    391 }
    392 
    393 void
    394 hb_buffer_t::copy_glyph (void)
    395 {
    396   if (unlikely (!make_room_for (0, 1))) return;
    397 
    398   out_info[out_len] = info[idx];
    399 
    400   out_len++;
    401 }
    402 
    403 bool
    404 hb_buffer_t::move_to (unsigned int i)
    405 {
    406   if (!have_output)
    407   {
    408     assert (i <= len);
    409     idx = i;
    410     return true;
    411   }
    412   if (unlikely (in_error))
    413     return false;
    414 
    415   assert (i <= out_len + (len - idx));
    416 
    417   if (out_len < i)
    418   {
    419     unsigned int count = i - out_len;
    420     if (unlikely (!make_room_for (count, count))) return false;
    421 
    422     memmove (out_info + out_len, info + idx, count * sizeof (out_info[0]));
    423     idx += count;
    424     out_len += count;
    425   }
    426   else if (out_len > i)
    427   {
    428     /* Tricky part: rewinding... */
    429     unsigned int count = out_len - i;
    430 
    431     /* This will blow in our face if memory allocation fails later
    432      * in this same lookup... */
    433     if (unlikely (idx < count && !shift_forward (count + 32))) return false;
    434 
    435     assert (idx >= count);
    436 
    437     idx -= count;
    438     out_len -= count;
    439     memmove (info + idx, out_info + out_len, count * sizeof (out_info[0]));
    440   }
    441 
    442   return true;
    443 }
    444 
    445 void
    446 hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
    447 {
    448   if (unlikely (out_info != info || out_len != idx)) {
    449     if (unlikely (!make_room_for (1, 1))) return;
    450     out_info[out_len] = info[idx];
    451   }
    452   out_info[out_len].codepoint = glyph_index;
    453 
    454   idx++;
    455   out_len++;
    456 }
    457 
    458 
    459 void
    460 hb_buffer_t::set_masks (hb_mask_t    value,
    461 			hb_mask_t    mask,
    462 			unsigned int cluster_start,
    463 			unsigned int cluster_end)
    464 {
    465   hb_mask_t not_mask = ~mask;
    466   value &= mask;
    467 
    468   if (!mask)
    469     return;
    470 
    471   if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
    472     unsigned int count = len;
    473     for (unsigned int i = 0; i < count; i++)
    474       info[i].mask = (info[i].mask & not_mask) | value;
    475     return;
    476   }
    477 
    478   unsigned int count = len;
    479   for (unsigned int i = 0; i < count; i++)
    480     if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
    481       info[i].mask = (info[i].mask & not_mask) | value;
    482 }
    483 
    484 void
    485 hb_buffer_t::reverse_range (unsigned int start,
    486 			    unsigned int end)
    487 {
    488   unsigned int i, j;
    489 
    490   if (end - start < 2)
    491     return;
    492 
    493   for (i = start, j = end - 1; i < j; i++, j--) {
    494     hb_glyph_info_t t;
    495 
    496     t = info[i];
    497     info[i] = info[j];
    498     info[j] = t;
    499   }
    500 
    501   if (have_positions) {
    502     for (i = start, j = end - 1; i < j; i++, j--) {
    503       hb_glyph_position_t t;
    504 
    505       t = pos[i];
    506       pos[i] = pos[j];
    507       pos[j] = t;
    508     }
    509   }
    510 }
    511 
    512 void
    513 hb_buffer_t::reverse (void)
    514 {
    515   if (unlikely (!len))
    516     return;
    517 
    518   reverse_range (0, len);
    519 }
    520 
    521 void
    522 hb_buffer_t::reverse_clusters (void)
    523 {
    524   unsigned int i, start, count, last_cluster;
    525 
    526   if (unlikely (!len))
    527     return;
    528 
    529   reverse ();
    530 
    531   count = len;
    532   start = 0;
    533   last_cluster = info[0].cluster;
    534   for (i = 1; i < count; i++) {
    535     if (last_cluster != info[i].cluster) {
    536       reverse_range (start, i);
    537       start = i;
    538       last_cluster = info[i].cluster;
    539     }
    540   }
    541   reverse_range (start, i);
    542 }
    543 
    544 void
    545 hb_buffer_t::merge_clusters_impl (unsigned int start,
    546 				  unsigned int end)
    547 {
    548   if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
    549   {
    550     unsafe_to_break (start, end);
    551     return;
    552   }
    553 
    554   unsigned int cluster = info[start].cluster;
    555 
    556   for (unsigned int i = start + 1; i < end; i++)
    557     cluster = MIN<unsigned int> (cluster, info[i].cluster);
    558 
    559   /* Extend end */
    560   while (end < len && info[end - 1].cluster == info[end].cluster)
    561     end++;
    562 
    563   /* Extend start */
    564   while (idx < start && info[start - 1].cluster == info[start].cluster)
    565     start--;
    566 
    567   /* If we hit the start of buffer, continue in out-buffer. */
    568   if (idx == start)
    569     for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
    570       set_cluster (out_info[i - 1], cluster);
    571 
    572   for (unsigned int i = start; i < end; i++)
    573     set_cluster (info[i], cluster);
    574 }
    575 void
    576 hb_buffer_t::merge_out_clusters (unsigned int start,
    577 				 unsigned int end)
    578 {
    579   if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
    580     return;
    581 
    582   if (unlikely (end - start < 2))
    583     return;
    584 
    585   unsigned int cluster = out_info[start].cluster;
    586 
    587   for (unsigned int i = start + 1; i < end; i++)
    588     cluster = MIN<unsigned int> (cluster, out_info[i].cluster);
    589 
    590   /* Extend start */
    591   while (start && out_info[start - 1].cluster == out_info[start].cluster)
    592     start--;
    593 
    594   /* Extend end */
    595   while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
    596     end++;
    597 
    598   /* If we hit the end of out-buffer, continue in buffer. */
    599   if (end == out_len)
    600     for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
    601       set_cluster (info[i], cluster);
    602 
    603   for (unsigned int i = start; i < end; i++)
    604     set_cluster (out_info[i], cluster);
    605 }
    606 void
    607 hb_buffer_t::delete_glyph ()
    608 {
    609   /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */
    610 
    611   unsigned int cluster = info[idx].cluster;
    612   if (idx + 1 < len && cluster == info[idx + 1].cluster)
    613   {
    614     /* Cluster survives; do nothing. */
    615     goto done;
    616   }
    617 
    618   if (out_len)
    619   {
    620     /* Merge cluster backward. */
    621     if (cluster < out_info[out_len - 1].cluster)
    622     {
    623       unsigned int mask = info[idx].mask;
    624       unsigned int old_cluster = out_info[out_len - 1].cluster;
    625       for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--)
    626 	set_cluster (out_info[i - 1], cluster, mask);
    627     }
    628     goto done;
    629   }
    630 
    631   if (idx + 1 < len)
    632   {
    633     /* Merge cluster forward. */
    634     merge_clusters (idx, idx + 2);
    635     goto done;
    636   }
    637 
    638 done:
    639   skip_glyph ();
    640 }
    641 
    642 void
    643 hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
    644 {
    645   unsigned int cluster = (unsigned int) -1;
    646   cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster);
    647   _unsafe_to_break_set_mask (info, start, end, cluster);
    648 }
    649 void
    650 hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
    651 {
    652   if (!have_output)
    653   {
    654     unsafe_to_break_impl (start, end);
    655     return;
    656   }
    657 
    658   assert (start <= out_len);
    659   assert (idx <= end);
    660 
    661   unsigned int cluster = (unsigned int) -1;
    662   cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster);
    663   cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster);
    664   _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
    665   _unsafe_to_break_set_mask (info, idx, end, cluster);
    666 }
    667 
    668 void
    669 hb_buffer_t::guess_segment_properties (void)
    670 {
    671   assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
    672 	  (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
    673 
    674   /* If script is set to INVALID, guess from buffer contents */
    675   if (props.script == HB_SCRIPT_INVALID) {
    676     for (unsigned int i = 0; i < len; i++) {
    677       hb_script_t script = unicode->script (info[i].codepoint);
    678       if (likely (script != HB_SCRIPT_COMMON &&
    679 		  script != HB_SCRIPT_INHERITED &&
    680 		  script != HB_SCRIPT_UNKNOWN)) {
    681         props.script = script;
    682         break;
    683       }
    684     }
    685   }
    686 
    687   /* If direction is set to INVALID, guess from script */
    688   if (props.direction == HB_DIRECTION_INVALID) {
    689     props.direction = hb_script_get_horizontal_direction (props.script);
    690   }
    691 
    692   /* If language is not set, use default language from locale */
    693   if (props.language == HB_LANGUAGE_INVALID) {
    694     /* TODO get_default_for_script? using $LANGUAGE */
    695     props.language = hb_language_get_default ();
    696   }
    697 }
    698 
    699 
    700 /* Public API */
    701 
    702 /**
    703  * hb_buffer_create: (Xconstructor)
    704  *
    705  * Creates a new #hb_buffer_t with all properties to defaults.
    706  *
    707  * Return value: (transfer full):
    708  * A newly allocated #hb_buffer_t with a reference count of 1. The initial
    709  * reference count should be released with hb_buffer_destroy() when you are done
    710  * using the #hb_buffer_t. This function never returns %NULL. If memory cannot
    711  * be allocated, a special #hb_buffer_t object will be returned on which
    712  * hb_buffer_allocation_successful() returns %false.
    713  *
    714  * Since: 0.9.2
    715  **/
    716 hb_buffer_t *
    717 hb_buffer_create (void)
    718 {
    719   hb_buffer_t *buffer;
    720 
    721   if (!(buffer = hb_object_create<hb_buffer_t> ()))
    722     return hb_buffer_get_empty ();
    723 
    724   buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
    725   buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
    726 
    727   buffer->reset ();
    728 
    729   return buffer;
    730 }
    731 
    732 /**
    733  * hb_buffer_get_empty:
    734  *
    735  *
    736  *
    737  * Return value: (transfer full):
    738  *
    739  * Since: 0.9.2
    740  **/
    741 hb_buffer_t *
    742 hb_buffer_get_empty (void)
    743 {
    744   static const hb_buffer_t _hb_buffer_nil = {
    745     HB_OBJECT_HEADER_STATIC,
    746 
    747     const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
    748     HB_BUFFER_FLAG_DEFAULT,
    749     HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
    750     HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
    751     HB_BUFFER_SCRATCH_FLAG_DEFAULT,
    752     HB_BUFFER_MAX_LEN_DEFAULT,
    753     HB_BUFFER_MAX_OPS_DEFAULT,
    754 
    755     HB_BUFFER_CONTENT_TYPE_INVALID,
    756     HB_SEGMENT_PROPERTIES_DEFAULT,
    757     true, /* in_error */
    758     true, /* have_output */
    759     true  /* have_positions */
    760 
    761     /* Zero is good enough for everything else. */
    762   };
    763 
    764   return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
    765 }
    766 
    767 /**
    768  * hb_buffer_reference: (skip)
    769  * @buffer: an #hb_buffer_t.
    770  *
    771  * Increases the reference count on @buffer by one. This prevents @buffer from
    772  * being destroyed until a matching call to hb_buffer_destroy() is made.
    773  *
    774  * Return value: (transfer full):
    775  * The referenced #hb_buffer_t.
    776  *
    777  * Since: 0.9.2
    778  **/
    779 hb_buffer_t *
    780 hb_buffer_reference (hb_buffer_t *buffer)
    781 {
    782   return hb_object_reference (buffer);
    783 }
    784 
    785 /**
    786  * hb_buffer_destroy: (skip)
    787  * @buffer: an #hb_buffer_t.
    788  *
    789  * Deallocate the @buffer.
    790  * Decreases the reference count on @buffer by one. If the result is zero, then
    791  * @buffer and all associated resources are freed. See hb_buffer_reference().
    792  *
    793  * Since: 0.9.2
    794  **/
    795 void
    796 hb_buffer_destroy (hb_buffer_t *buffer)
    797 {
    798   if (!hb_object_destroy (buffer)) return;
    799 
    800   hb_unicode_funcs_destroy (buffer->unicode);
    801 
    802   free (buffer->info);
    803   free (buffer->pos);
    804   if (buffer->message_destroy)
    805     buffer->message_destroy (buffer->message_data);
    806 
    807   free (buffer);
    808 }
    809 
    810 /**
    811  * hb_buffer_set_user_data: (skip)
    812  * @buffer: an #hb_buffer_t.
    813  * @key:
    814  * @data:
    815  * @destroy:
    816  * @replace:
    817  *
    818  *
    819  *
    820  * Return value:
    821  *
    822  * Since: 0.9.2
    823  **/
    824 hb_bool_t
    825 hb_buffer_set_user_data (hb_buffer_t        *buffer,
    826 			 hb_user_data_key_t *key,
    827 			 void *              data,
    828 			 hb_destroy_func_t   destroy,
    829 			 hb_bool_t           replace)
    830 {
    831   return hb_object_set_user_data (buffer, key, data, destroy, replace);
    832 }
    833 
    834 /**
    835  * hb_buffer_get_user_data: (skip)
    836  * @buffer: an #hb_buffer_t.
    837  * @key:
    838  *
    839  *
    840  *
    841  * Return value:
    842  *
    843  * Since: 0.9.2
    844  **/
    845 void *
    846 hb_buffer_get_user_data (hb_buffer_t        *buffer,
    847 			 hb_user_data_key_t *key)
    848 {
    849   return hb_object_get_user_data (buffer, key);
    850 }
    851 
    852 
    853 /**
    854  * hb_buffer_set_content_type:
    855  * @buffer: an #hb_buffer_t.
    856  * @content_type: the type of buffer contents to set
    857  *
    858  * Sets the type of @buffer contents, buffers are either empty, contain
    859  * characters (before shaping) or glyphs (the result of shaping).
    860  *
    861  * Since: 0.9.5
    862  **/
    863 void
    864 hb_buffer_set_content_type (hb_buffer_t              *buffer,
    865 			    hb_buffer_content_type_t  content_type)
    866 {
    867   buffer->content_type = content_type;
    868 }
    869 
    870 /**
    871  * hb_buffer_get_content_type:
    872  * @buffer: an #hb_buffer_t.
    873  *
    874  * see hb_buffer_set_content_type().
    875  *
    876  * Return value:
    877  * The type of @buffer contents.
    878  *
    879  * Since: 0.9.5
    880  **/
    881 hb_buffer_content_type_t
    882 hb_buffer_get_content_type (hb_buffer_t *buffer)
    883 {
    884   return buffer->content_type;
    885 }
    886 
    887 
    888 /**
    889  * hb_buffer_set_unicode_funcs:
    890  * @buffer: an #hb_buffer_t.
    891  * @unicode_funcs:
    892  *
    893  *
    894  *
    895  * Since: 0.9.2
    896  **/
    897 void
    898 hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
    899 			     hb_unicode_funcs_t *unicode_funcs)
    900 {
    901   if (unlikely (hb_object_is_inert (buffer)))
    902     return;
    903 
    904   if (!unicode_funcs)
    905     unicode_funcs = hb_unicode_funcs_get_default ();
    906 
    907 
    908   hb_unicode_funcs_reference (unicode_funcs);
    909   hb_unicode_funcs_destroy (buffer->unicode);
    910   buffer->unicode = unicode_funcs;
    911 }
    912 
    913 /**
    914  * hb_buffer_get_unicode_funcs:
    915  * @buffer: an #hb_buffer_t.
    916  *
    917  *
    918  *
    919  * Return value:
    920  *
    921  * Since: 0.9.2
    922  **/
    923 hb_unicode_funcs_t *
    924 hb_buffer_get_unicode_funcs (hb_buffer_t        *buffer)
    925 {
    926   return buffer->unicode;
    927 }
    928 
    929 /**
    930  * hb_buffer_set_direction:
    931  * @buffer: an #hb_buffer_t.
    932  * @direction: the #hb_direction_t of the @buffer
    933  *
    934  * Set the text flow direction of the buffer. No shaping can happen without
    935  * setting @buffer direction, and it controls the visual direction for the
    936  * output glyphs; for RTL direction the glyphs will be reversed. Many layout
    937  * features depend on the proper setting of the direction, for example,
    938  * reversing RTL text before shaping, then shaping with LTR direction is not
    939  * the same as keeping the text in logical order and shaping with RTL
    940  * direction.
    941  *
    942  * Since: 0.9.2
    943  **/
    944 void
    945 hb_buffer_set_direction (hb_buffer_t    *buffer,
    946 			 hb_direction_t  direction)
    947 
    948 {
    949   if (unlikely (hb_object_is_inert (buffer)))
    950     return;
    951 
    952   buffer->props.direction = direction;
    953 }
    954 
    955 /**
    956  * hb_buffer_get_direction:
    957  * @buffer: an #hb_buffer_t.
    958  *
    959  * See hb_buffer_set_direction()
    960  *
    961  * Return value:
    962  * The direction of the @buffer.
    963  *
    964  * Since: 0.9.2
    965  **/
    966 hb_direction_t
    967 hb_buffer_get_direction (hb_buffer_t    *buffer)
    968 {
    969   return buffer->props.direction;
    970 }
    971 
    972 /**
    973  * hb_buffer_set_script:
    974  * @buffer: an #hb_buffer_t.
    975  * @script: an #hb_script_t to set.
    976  *
    977  * Sets the script of @buffer to @script.
    978  *
    979  * Script is crucial for choosing the proper shaping behaviour for scripts that
    980  * require it (e.g. Arabic) and the which OpenType features defined in the font
    981  * to be applied.
    982  *
    983  * You can pass one of the predefined #hb_script_t values, or use
    984  * hb_script_from_string() or hb_script_from_iso15924_tag() to get the
    985  * corresponding script from an ISO15924 script tag.
    986  *
    987  * Since: 0.9.2
    988  **/
    989 void
    990 hb_buffer_set_script (hb_buffer_t *buffer,
    991 		      hb_script_t  script)
    992 {
    993   if (unlikely (hb_object_is_inert (buffer)))
    994     return;
    995 
    996   buffer->props.script = script;
    997 }
    998 
    999 /**
   1000  * hb_buffer_get_script:
   1001  * @buffer: an #hb_buffer_t.
   1002  *
   1003  * See hb_buffer_set_script().
   1004  *
   1005  * Return value:
   1006  * The #hb_script_t of the @buffer.
   1007  *
   1008  * Since: 0.9.2
   1009  **/
   1010 hb_script_t
   1011 hb_buffer_get_script (hb_buffer_t *buffer)
   1012 {
   1013   return buffer->props.script;
   1014 }
   1015 
   1016 /**
   1017  * hb_buffer_set_language:
   1018  * @buffer: an #hb_buffer_t.
   1019  * @language: an hb_language_t to set.
   1020  *
   1021  * Sets the language of @buffer to @language.
   1022  *
   1023  * Languages are crucial for selecting which OpenType feature to apply to the
   1024  * buffer which can result in applying language-specific behaviour. Languages
   1025  * are orthogonal to the scripts, and though they are related, they are
   1026  * different concepts and should not be confused with each other.
   1027  *
   1028  * Use hb_language_from_string() to convert from ISO639 language codes to
   1029  * #hb_language_t.
   1030  *
   1031  * Since: 0.9.2
   1032  **/
   1033 void
   1034 hb_buffer_set_language (hb_buffer_t   *buffer,
   1035 			hb_language_t  language)
   1036 {
   1037   if (unlikely (hb_object_is_inert (buffer)))
   1038     return;
   1039 
   1040   buffer->props.language = language;
   1041 }
   1042 
   1043 /**
   1044  * hb_buffer_get_language:
   1045  * @buffer: an #hb_buffer_t.
   1046  *
   1047  * See hb_buffer_set_language().
   1048  *
   1049  * Return value: (transfer none):
   1050  * The #hb_language_t of the buffer. Must not be freed by the caller.
   1051  *
   1052  * Since: 0.9.2
   1053  **/
   1054 hb_language_t
   1055 hb_buffer_get_language (hb_buffer_t *buffer)
   1056 {
   1057   return buffer->props.language;
   1058 }
   1059 
   1060 /**
   1061  * hb_buffer_set_segment_properties:
   1062  * @buffer: an #hb_buffer_t.
   1063  * @props: an #hb_segment_properties_t to use.
   1064  *
   1065  * Sets the segment properties of the buffer, a shortcut for calling
   1066  * hb_buffer_set_direction(), hb_buffer_set_script() and
   1067  * hb_buffer_set_language() individually.
   1068  *
   1069  * Since: 0.9.7
   1070  **/
   1071 void
   1072 hb_buffer_set_segment_properties (hb_buffer_t *buffer,
   1073 				  const hb_segment_properties_t *props)
   1074 {
   1075   if (unlikely (hb_object_is_inert (buffer)))
   1076     return;
   1077 
   1078   buffer->props = *props;
   1079 }
   1080 
   1081 /**
   1082  * hb_buffer_get_segment_properties:
   1083  * @buffer: an #hb_buffer_t.
   1084  * @props: (out): the output #hb_segment_properties_t.
   1085  *
   1086  * Sets @props to the #hb_segment_properties_t of @buffer.
   1087  *
   1088  * Since: 0.9.7
   1089  **/
   1090 void
   1091 hb_buffer_get_segment_properties (hb_buffer_t *buffer,
   1092 				  hb_segment_properties_t *props)
   1093 {
   1094   *props = buffer->props;
   1095 }
   1096 
   1097 
   1098 /**
   1099  * hb_buffer_set_flags:
   1100  * @buffer: an #hb_buffer_t.
   1101  * @flags: the buffer flags to set.
   1102  *
   1103  * Sets @buffer flags to @flags. See #hb_buffer_flags_t.
   1104  *
   1105  * Since: 0.9.7
   1106  **/
   1107 void
   1108 hb_buffer_set_flags (hb_buffer_t       *buffer,
   1109 		     hb_buffer_flags_t  flags)
   1110 {
   1111   if (unlikely (hb_object_is_inert (buffer)))
   1112     return;
   1113 
   1114   buffer->flags = flags;
   1115 }
   1116 
   1117 /**
   1118  * hb_buffer_get_flags:
   1119  * @buffer: an #hb_buffer_t.
   1120  *
   1121  * See hb_buffer_set_flags().
   1122  *
   1123  * Return value:
   1124  * The @buffer flags.
   1125  *
   1126  * Since: 0.9.7
   1127  **/
   1128 hb_buffer_flags_t
   1129 hb_buffer_get_flags (hb_buffer_t *buffer)
   1130 {
   1131   return buffer->flags;
   1132 }
   1133 
   1134 /**
   1135  * hb_buffer_set_cluster_level:
   1136  * @buffer: an #hb_buffer_t.
   1137  * @cluster_level:
   1138  *
   1139  *
   1140  *
   1141  * Since: 0.9.42
   1142  **/
   1143 void
   1144 hb_buffer_set_cluster_level (hb_buffer_t       *buffer,
   1145 		     hb_buffer_cluster_level_t  cluster_level)
   1146 {
   1147   if (unlikely (hb_object_is_inert (buffer)))
   1148     return;
   1149 
   1150   buffer->cluster_level = cluster_level;
   1151 }
   1152 
   1153 /**
   1154  * hb_buffer_get_cluster_level:
   1155  * @buffer: an #hb_buffer_t.
   1156  *
   1157  *
   1158  *
   1159  * Return value:
   1160  *
   1161  * Since: 0.9.42
   1162  **/
   1163 hb_buffer_cluster_level_t
   1164 hb_buffer_get_cluster_level (hb_buffer_t *buffer)
   1165 {
   1166   return buffer->cluster_level;
   1167 }
   1168 
   1169 
   1170 /**
   1171  * hb_buffer_set_replacement_codepoint:
   1172  * @buffer: an #hb_buffer_t.
   1173  * @replacement: the replacement #hb_codepoint_t
   1174  *
   1175  * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
   1176  * when adding text to @buffer.
   1177  *
   1178  * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
   1179  *
   1180  * Since: 0.9.31
   1181  **/
   1182 void
   1183 hb_buffer_set_replacement_codepoint (hb_buffer_t    *buffer,
   1184 				     hb_codepoint_t  replacement)
   1185 {
   1186   if (unlikely (hb_object_is_inert (buffer)))
   1187     return;
   1188 
   1189   buffer->replacement = replacement;
   1190 }
   1191 
   1192 /**
   1193  * hb_buffer_get_replacement_codepoint:
   1194  * @buffer: an #hb_buffer_t.
   1195  *
   1196  * See hb_buffer_set_replacement_codepoint().
   1197  *
   1198  * Return value:
   1199  * The @buffer replacement #hb_codepoint_t.
   1200  *
   1201  * Since: 0.9.31
   1202  **/
   1203 hb_codepoint_t
   1204 hb_buffer_get_replacement_codepoint (hb_buffer_t    *buffer)
   1205 {
   1206   return buffer->replacement;
   1207 }
   1208 
   1209 
   1210 /**
   1211  * hb_buffer_reset:
   1212  * @buffer: an #hb_buffer_t.
   1213  *
   1214  * Resets the buffer to its initial status, as if it was just newly created
   1215  * with hb_buffer_create().
   1216  *
   1217  * Since: 0.9.2
   1218  **/
   1219 void
   1220 hb_buffer_reset (hb_buffer_t *buffer)
   1221 {
   1222   buffer->reset ();
   1223 }
   1224 
   1225 /**
   1226  * hb_buffer_clear_contents:
   1227  * @buffer: an #hb_buffer_t.
   1228  *
   1229  * Similar to hb_buffer_reset(), but does not clear the Unicode functions and
   1230  * the replacement code point.
   1231  *
   1232  * Since: 0.9.11
   1233  **/
   1234 void
   1235 hb_buffer_clear_contents (hb_buffer_t *buffer)
   1236 {
   1237   buffer->clear ();
   1238 }
   1239 
   1240 /**
   1241  * hb_buffer_pre_allocate:
   1242  * @buffer: an #hb_buffer_t.
   1243  * @size: number of items to pre allocate.
   1244  *
   1245  * Pre allocates memory for @buffer to fit at least @size number of items.
   1246  *
   1247  * Return value:
   1248  * %true if @buffer memory allocation succeeded, %false otherwise.
   1249  *
   1250  * Since: 0.9.2
   1251  **/
   1252 hb_bool_t
   1253 hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
   1254 {
   1255   return buffer->ensure (size);
   1256 }
   1257 
   1258 /**
   1259  * hb_buffer_allocation_successful:
   1260  * @buffer: an #hb_buffer_t.
   1261  *
   1262  * Check if allocating memory for the buffer succeeded.
   1263  *
   1264  * Return value:
   1265  * %true if @buffer memory allocation succeeded, %false otherwise.
   1266  *
   1267  * Since: 0.9.2
   1268  **/
   1269 hb_bool_t
   1270 hb_buffer_allocation_successful (hb_buffer_t  *buffer)
   1271 {
   1272   return !buffer->in_error;
   1273 }
   1274 
   1275 /**
   1276  * hb_buffer_add:
   1277  * @buffer: an #hb_buffer_t.
   1278  * @codepoint: a Unicode code point.
   1279  * @cluster: the cluster value of @codepoint.
   1280  *
   1281  * Appends a character with the Unicode value of @codepoint to @buffer, and
   1282  * gives it the initial cluster value of @cluster. Clusters can be any thing
   1283  * the client wants, they are usually used to refer to the index of the
   1284  * character in the input text stream and are output in
   1285  * #hb_glyph_info_t.cluster field.
   1286  *
   1287  * This function does not check the validity of @codepoint, it is up to the
   1288  * caller to ensure it is a valid Unicode code point.
   1289  *
   1290  * Since: 0.9.7
   1291  **/
   1292 void
   1293 hb_buffer_add (hb_buffer_t    *buffer,
   1294 	       hb_codepoint_t  codepoint,
   1295 	       unsigned int    cluster)
   1296 {
   1297   buffer->add (codepoint, cluster);
   1298   buffer->clear_context (1);
   1299 }
   1300 
   1301 /**
   1302  * hb_buffer_set_length:
   1303  * @buffer: an #hb_buffer_t.
   1304  * @length: the new length of @buffer.
   1305  *
   1306  * Similar to hb_buffer_pre_allocate(), but clears any new items added at the
   1307  * end.
   1308  *
   1309  * Return value:
   1310  * %true if @buffer memory allocation succeeded, %false otherwise.
   1311  *
   1312  * Since: 0.9.2
   1313  **/
   1314 hb_bool_t
   1315 hb_buffer_set_length (hb_buffer_t  *buffer,
   1316 		      unsigned int  length)
   1317 {
   1318   if (unlikely (hb_object_is_inert (buffer)))
   1319     return length == 0;
   1320 
   1321   if (!buffer->ensure (length))
   1322     return false;
   1323 
   1324   /* Wipe the new space */
   1325   if (length > buffer->len) {
   1326     memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
   1327     if (buffer->have_positions)
   1328       memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
   1329   }
   1330 
   1331   buffer->len = length;
   1332 
   1333   if (!length)
   1334   {
   1335     buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
   1336     buffer->clear_context (0);
   1337   }
   1338   buffer->clear_context (1);
   1339 
   1340   return true;
   1341 }
   1342 
   1343 /**
   1344  * hb_buffer_get_length:
   1345  * @buffer: an #hb_buffer_t.
   1346  *
   1347  * Returns the number of items in the buffer.
   1348  *
   1349  * Return value:
   1350  * The @buffer length.
   1351  * The value valid as long as buffer has not been modified.
   1352  *
   1353  * Since: 0.9.2
   1354  **/
   1355 unsigned int
   1356 hb_buffer_get_length (hb_buffer_t *buffer)
   1357 {
   1358   return buffer->len;
   1359 }
   1360 
   1361 /**
   1362  * hb_buffer_get_glyph_infos:
   1363  * @buffer: an #hb_buffer_t.
   1364  * @length: (out): output array length.
   1365  *
   1366  * Returns @buffer glyph information array.  Returned pointer
   1367  * is valid as long as @buffer contents are not modified.
   1368  *
   1369  * Return value: (transfer none) (array length=length):
   1370  * The @buffer glyph information array.
   1371  * The value valid as long as buffer has not been modified.
   1372  *
   1373  * Since: 0.9.2
   1374  **/
   1375 hb_glyph_info_t *
   1376 hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
   1377                            unsigned int *length)
   1378 {
   1379   if (length)
   1380     *length = buffer->len;
   1381 
   1382   return (hb_glyph_info_t *) buffer->info;
   1383 }
   1384 
   1385 /**
   1386  * hb_buffer_get_glyph_positions:
   1387  * @buffer: an #hb_buffer_t.
   1388  * @length: (out): output length.
   1389  *
   1390  * Returns @buffer glyph position array.  Returned pointer
   1391  * is valid as long as @buffer contents are not modified.
   1392  *
   1393  * Return value: (transfer none) (array length=length):
   1394  * The @buffer glyph position array.
   1395  * The value valid as long as buffer has not been modified.
   1396  *
   1397  * Since: 0.9.2
   1398  **/
   1399 hb_glyph_position_t *
   1400 hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
   1401                                unsigned int *length)
   1402 {
   1403   if (!buffer->have_positions)
   1404     buffer->clear_positions ();
   1405 
   1406   if (length)
   1407     *length = buffer->len;
   1408 
   1409   return (hb_glyph_position_t *) buffer->pos;
   1410 }
   1411 
   1412 /**
   1413  * hb_glyph_info_get_glyph_flags:
   1414  * @info: a #hb_glyph_info_t.
   1415  *
   1416  * Returns glyph flags encoded within a #hb_glyph_info_t.
   1417  *
   1418  * Return value:
   1419  * The #hb_glyph_flags_t encoded within @info.
   1420  *
   1421  * Since: 1.5.0
   1422  **/
   1423 hb_glyph_flags_t
   1424 (hb_glyph_info_get_glyph_flags) (const hb_glyph_info_t *info)
   1425 {
   1426   return hb_glyph_info_get_glyph_flags (info);
   1427 }
   1428 
   1429 /**
   1430  * hb_buffer_reverse:
   1431  * @buffer: an #hb_buffer_t.
   1432  *
   1433  * Reverses buffer contents.
   1434  *
   1435  * Since: 0.9.2
   1436  **/
   1437 void
   1438 hb_buffer_reverse (hb_buffer_t *buffer)
   1439 {
   1440   buffer->reverse ();
   1441 }
   1442 
   1443 /**
   1444  * hb_buffer_reverse_range:
   1445  * @buffer: an #hb_buffer_t.
   1446  * @start: start index.
   1447  * @end: end index.
   1448  *
   1449  * Reverses buffer contents between start to end.
   1450  *
   1451  * Since: 0.9.41
   1452  **/
   1453 void
   1454 hb_buffer_reverse_range (hb_buffer_t *buffer,
   1455 			 unsigned int start, unsigned int end)
   1456 {
   1457   buffer->reverse_range (start, end);
   1458 }
   1459 
   1460 /**
   1461  * hb_buffer_reverse_clusters:
   1462  * @buffer: an #hb_buffer_t.
   1463  *
   1464  * Reverses buffer clusters.  That is, the buffer contents are
   1465  * reversed, then each cluster (consecutive items having the
   1466  * same cluster number) are reversed again.
   1467  *
   1468  * Since: 0.9.2
   1469  **/
   1470 void
   1471 hb_buffer_reverse_clusters (hb_buffer_t *buffer)
   1472 {
   1473   buffer->reverse_clusters ();
   1474 }
   1475 
   1476 /**
   1477  * hb_buffer_guess_segment_properties:
   1478  * @buffer: an #hb_buffer_t.
   1479  *
   1480  * Sets unset buffer segment properties based on buffer Unicode
   1481  * contents.  If buffer is not empty, it must have content type
   1482  * %HB_BUFFER_CONTENT_TYPE_UNICODE.
   1483  *
   1484  * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
   1485  * will be set to the Unicode script of the first character in
   1486  * the buffer that has a script other than %HB_SCRIPT_COMMON,
   1487  * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
   1488  *
   1489  * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
   1490  * it will be set to the natural horizontal direction of the
   1491  * buffer script as returned by hb_script_get_horizontal_direction().
   1492  *
   1493  * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
   1494  * it will be set to the process's default language as returned by
   1495  * hb_language_get_default().  This may change in the future by
   1496  * taking buffer script into consideration when choosing a language.
   1497  *
   1498  * Since: 0.9.7
   1499  **/
   1500 void
   1501 hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
   1502 {
   1503   buffer->guess_segment_properties ();
   1504 }
   1505 
   1506 template <typename utf_t>
   1507 static inline void
   1508 hb_buffer_add_utf (hb_buffer_t  *buffer,
   1509 		   const typename utf_t::codepoint_t *text,
   1510 		   int           text_length,
   1511 		   unsigned int  item_offset,
   1512 		   int           item_length)
   1513 {
   1514   typedef typename utf_t::codepoint_t T;
   1515   const hb_codepoint_t replacement = buffer->replacement;
   1516 
   1517   assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
   1518 	  (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
   1519 
   1520   if (unlikely (hb_object_is_inert (buffer)))
   1521     return;
   1522 
   1523   if (text_length == -1)
   1524     text_length = utf_t::strlen (text);
   1525 
   1526   if (item_length == -1)
   1527     item_length = text_length - item_offset;
   1528 
   1529   buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
   1530 
   1531   /* If buffer is empty and pre-context provided, install it.
   1532    * This check is written this way, to make sure people can
   1533    * provide pre-context in one add_utf() call, then provide
   1534    * text in a follow-up call.  See:
   1535    *
   1536    * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
   1537    */
   1538   if (!buffer->len && item_offset > 0)
   1539   {
   1540     /* Add pre-context */
   1541     buffer->clear_context (0);
   1542     const T *prev = text + item_offset;
   1543     const T *start = text;
   1544     while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
   1545     {
   1546       hb_codepoint_t u;
   1547       prev = utf_t::prev (prev, start, &u, replacement);
   1548       buffer->context[0][buffer->context_len[0]++] = u;
   1549     }
   1550   }
   1551 
   1552   const T *next = text + item_offset;
   1553   const T *end = next + item_length;
   1554   while (next < end)
   1555   {
   1556     hb_codepoint_t u;
   1557     const T *old_next = next;
   1558     next = utf_t::next (next, end, &u, replacement);
   1559     buffer->add (u, old_next - (const T *) text);
   1560   }
   1561 
   1562   /* Add post-context */
   1563   buffer->clear_context (1);
   1564   end = text + text_length;
   1565   while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
   1566   {
   1567     hb_codepoint_t u;
   1568     next = utf_t::next (next, end, &u, replacement);
   1569     buffer->context[1][buffer->context_len[1]++] = u;
   1570   }
   1571 
   1572   buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
   1573 }
   1574 
   1575 /**
   1576  * hb_buffer_add_utf8:
   1577  * @buffer: an #hb_buffer_t.
   1578  * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
   1579  *               characters to append.
   1580  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
   1581  * @item_offset: the offset of the first character to add to the @buffer.
   1582  * @item_length: the number of characters to add to the @buffer, or -1 for the
   1583  *               end of @text (assuming it is %NULL terminated).
   1584  *
   1585  * See hb_buffer_add_codepoints().
   1586  *
   1587  * Replaces invalid UTF-8 characters with the @buffer replacement code point,
   1588  * see hb_buffer_set_replacement_codepoint().
   1589  *
   1590  * Since: 0.9.2
   1591  **/
   1592 void
   1593 hb_buffer_add_utf8 (hb_buffer_t  *buffer,
   1594 		    const char   *text,
   1595 		    int           text_length,
   1596 		    unsigned int  item_offset,
   1597 		    int           item_length)
   1598 {
   1599   hb_buffer_add_utf<hb_utf8_t> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
   1600 }
   1601 
   1602 /**
   1603  * hb_buffer_add_utf16:
   1604  * @buffer: an #hb_buffer_t.
   1605  * @text: (array length=text_length): an array of UTF-16 characters to append.
   1606  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
   1607  * @item_offset: the offset of the first character to add to the @buffer.
   1608  * @item_length: the number of characters to add to the @buffer, or -1 for the
   1609  *               end of @text (assuming it is %NULL terminated).
   1610  *
   1611  * See hb_buffer_add_codepoints().
   1612  *
   1613  * Replaces invalid UTF-16 characters with the @buffer replacement code point,
   1614  * see hb_buffer_set_replacement_codepoint().
   1615  *
   1616  * Since: 0.9.2
   1617  **/
   1618 void
   1619 hb_buffer_add_utf16 (hb_buffer_t    *buffer,
   1620 		     const uint16_t *text,
   1621 		     int             text_length,
   1622 		     unsigned int    item_offset,
   1623 		     int             item_length)
   1624 {
   1625   hb_buffer_add_utf<hb_utf16_t> (buffer, text, text_length, item_offset, item_length);
   1626 }
   1627 
   1628 /**
   1629  * hb_buffer_add_utf32:
   1630  * @buffer: an #hb_buffer_t.
   1631  * @text: (array length=text_length): an array of UTF-32 characters to append.
   1632  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
   1633  * @item_offset: the offset of the first character to add to the @buffer.
   1634  * @item_length: the number of characters to add to the @buffer, or -1 for the
   1635  *               end of @text (assuming it is %NULL terminated).
   1636  *
   1637  * See hb_buffer_add_codepoints().
   1638  *
   1639  * Replaces invalid UTF-32 characters with the @buffer replacement code point,
   1640  * see hb_buffer_set_replacement_codepoint().
   1641  *
   1642  * Since: 0.9.2
   1643  **/
   1644 void
   1645 hb_buffer_add_utf32 (hb_buffer_t    *buffer,
   1646 		     const uint32_t *text,
   1647 		     int             text_length,
   1648 		     unsigned int    item_offset,
   1649 		     int             item_length)
   1650 {
   1651   hb_buffer_add_utf<hb_utf32_t<> > (buffer, text, text_length, item_offset, item_length);
   1652 }
   1653 
   1654 /**
   1655  * hb_buffer_add_latin1:
   1656  * @buffer: an #hb_buffer_t.
   1657  * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
   1658  *               characters to append.
   1659  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
   1660  * @item_offset: the offset of the first character to add to the @buffer.
   1661  * @item_length: the number of characters to add to the @buffer, or -1 for the
   1662  *               end of @text (assuming it is %NULL terminated).
   1663  *
   1664  * Similar to hb_buffer_add_codepoints(), but allows only access to first 256
   1665  * Unicode code points that can fit in 8-bit strings.
   1666  *
   1667  * <note>Has nothing to do with non-Unicode Latin-1 encoding.</note>
   1668  *
   1669  * Since: 0.9.39
   1670  **/
   1671 void
   1672 hb_buffer_add_latin1 (hb_buffer_t   *buffer,
   1673 		      const uint8_t *text,
   1674 		      int            text_length,
   1675 		      unsigned int   item_offset,
   1676 		      int            item_length)
   1677 {
   1678   hb_buffer_add_utf<hb_latin1_t> (buffer, text, text_length, item_offset, item_length);
   1679 }
   1680 
   1681 /**
   1682  * hb_buffer_add_codepoints:
   1683  * @buffer: a #hb_buffer_t to append characters to.
   1684  * @text: (array length=text_length): an array of Unicode code points to append.
   1685  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
   1686  * @item_offset: the offset of the first code point to add to the @buffer.
   1687  * @item_length: the number of code points to add to the @buffer, or -1 for the
   1688  *               end of @text (assuming it is %NULL terminated).
   1689  *
   1690  * Appends characters from @text array to @buffer. The @item_offset is the
   1691  * position of the first character from @text that will be appended, and
   1692  * @item_length is the number of character. When shaping part of a larger text
   1693  * (e.g. a run of text from a paragraph), instead of passing just the substring
   1694  * corresponding to the run, it is preferable to pass the whole
   1695  * paragraph and specify the run start and length as @item_offset and
   1696  * @item_length, respectively, to give HarfBuzz the full context to be able,
   1697  * for example, to do cross-run Arabic shaping or properly handle combining
   1698  * marks at stat of run.
   1699  *
   1700  * This function does not check the validity of @text, it is up to the caller
   1701  * to ensure it contains a valid Unicode code points.
   1702  *
   1703  * Since: 0.9.31
   1704  **/
   1705 void
   1706 hb_buffer_add_codepoints (hb_buffer_t          *buffer,
   1707 			  const hb_codepoint_t *text,
   1708 			  int                   text_length,
   1709 			  unsigned int          item_offset,
   1710 			  int                   item_length)
   1711 {
   1712   hb_buffer_add_utf<hb_utf32_t<false> > (buffer, text, text_length, item_offset, item_length);
   1713 }
   1714 
   1715 
   1716 /**
   1717  * hb_buffer_append:
   1718  * @buffer: an #hb_buffer_t.
   1719  * @source: source #hb_buffer_t.
   1720  * @start: start index into source buffer to copy.  Use 0 to copy from start of buffer.
   1721  * @end: end index into source buffer to copy.  Use (unsigned int) -1 to copy to end of buffer.
   1722  *
   1723  * Append (part of) contents of another buffer to this buffer.
   1724  *
   1725  * Since: 1.5.0
   1726  **/
   1727 HB_EXTERN void
   1728 hb_buffer_append (hb_buffer_t *buffer,
   1729 		  hb_buffer_t *source,
   1730 		  unsigned int start,
   1731 		  unsigned int end)
   1732 {
   1733   assert (!buffer->have_output && !source->have_output);
   1734   assert (buffer->have_positions == source->have_positions ||
   1735 	  !buffer->len || !source->len);
   1736   assert (buffer->content_type == source->content_type ||
   1737 	  !buffer->len || !source->len);
   1738 
   1739   if (end > source->len)
   1740     end = source->len;
   1741   if (start > end)
   1742     start = end;
   1743   if (start == end)
   1744     return;
   1745 
   1746   if (!buffer->len)
   1747     buffer->content_type = source->content_type;
   1748   if (!buffer->have_positions && source->have_positions)
   1749     buffer->clear_positions ();
   1750 
   1751   if (buffer->len + (end - start) < buffer->len) /* Overflows. */
   1752   {
   1753     buffer->in_error = true;
   1754     return;
   1755   }
   1756 
   1757   unsigned int orig_len = buffer->len;
   1758   hb_buffer_set_length (buffer, buffer->len + (end - start));
   1759   if (buffer->in_error)
   1760     return;
   1761 
   1762   memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
   1763   if (buffer->have_positions)
   1764     memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
   1765 }
   1766 
   1767 
   1768 static int
   1769 compare_info_codepoint (const hb_glyph_info_t *pa,
   1770 			const hb_glyph_info_t *pb)
   1771 {
   1772   return (int) pb->codepoint - (int) pa->codepoint;
   1773 }
   1774 
   1775 static inline void
   1776 normalize_glyphs_cluster (hb_buffer_t *buffer,
   1777 			  unsigned int start,
   1778 			  unsigned int end,
   1779 			  bool backward)
   1780 {
   1781   hb_glyph_position_t *pos = buffer->pos;
   1782 
   1783   /* Total cluster advance */
   1784   hb_position_t total_x_advance = 0, total_y_advance = 0;
   1785   for (unsigned int i = start; i < end; i++)
   1786   {
   1787     total_x_advance += pos[i].x_advance;
   1788     total_y_advance += pos[i].y_advance;
   1789   }
   1790 
   1791   hb_position_t x_advance = 0, y_advance = 0;
   1792   for (unsigned int i = start; i < end; i++)
   1793   {
   1794     pos[i].x_offset += x_advance;
   1795     pos[i].y_offset += y_advance;
   1796 
   1797     x_advance += pos[i].x_advance;
   1798     y_advance += pos[i].y_advance;
   1799 
   1800     pos[i].x_advance = 0;
   1801     pos[i].y_advance = 0;
   1802   }
   1803 
   1804   if (backward)
   1805   {
   1806     /* Transfer all cluster advance to the last glyph. */
   1807     pos[end - 1].x_advance = total_x_advance;
   1808     pos[end - 1].y_advance = total_y_advance;
   1809 
   1810     hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
   1811   } else {
   1812     /* Transfer all cluster advance to the first glyph. */
   1813     pos[start].x_advance += total_x_advance;
   1814     pos[start].y_advance += total_y_advance;
   1815     for (unsigned int i = start + 1; i < end; i++) {
   1816       pos[i].x_offset -= total_x_advance;
   1817       pos[i].y_offset -= total_y_advance;
   1818     }
   1819     hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
   1820   }
   1821 }
   1822 
   1823 /**
   1824  * hb_buffer_normalize_glyphs:
   1825  * @buffer: an #hb_buffer_t.
   1826  *
   1827  * Reorders a glyph buffer to have canonical in-cluster glyph order / position.
   1828  * The resulting clusters should behave identical to pre-reordering clusters.
   1829  *
   1830  * <note>This has nothing to do with Unicode normalization.</note>
   1831  *
   1832  * Since: 0.9.2
   1833  **/
   1834 void
   1835 hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
   1836 {
   1837   assert (buffer->have_positions);
   1838   assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS ||
   1839 	  (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
   1840 
   1841   bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
   1842 
   1843   unsigned int count = buffer->len;
   1844   if (unlikely (!count)) return;
   1845   hb_glyph_info_t *info = buffer->info;
   1846 
   1847   unsigned int start = 0;
   1848   unsigned int end;
   1849   for (end = start + 1; end < count; end++)
   1850     if (info[start].cluster != info[end].cluster) {
   1851       normalize_glyphs_cluster (buffer, start, end, backward);
   1852       start = end;
   1853     }
   1854   normalize_glyphs_cluster (buffer, start, end, backward);
   1855 }
   1856 
   1857 void
   1858 hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *))
   1859 {
   1860   assert (!have_positions);
   1861   for (unsigned int i = start + 1; i < end; i++)
   1862   {
   1863     unsigned int j = i;
   1864     while (j > start && compar (&info[j - 1], &info[i]) > 0)
   1865       j--;
   1866     if (i == j)
   1867       continue;
   1868     /* Move item i to occupy place for item j, shift what's in between. */
   1869     merge_clusters (j, i + 1);
   1870     {
   1871       hb_glyph_info_t t = info[i];
   1872       memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t));
   1873       info[j] = t;
   1874     }
   1875   }
   1876 }
   1877 
   1878 
   1879 /*
   1880  * Comparing buffers.
   1881  */
   1882 
   1883 /**
   1884  * hb_buffer_diff:
   1885  *
   1886  * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
   1887  * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned.  This should be used by most
   1888  * callers if just comparing two buffers is needed.
   1889  *
   1890  * Since: 1.5.0
   1891  **/
   1892 hb_buffer_diff_flags_t
   1893 hb_buffer_diff (hb_buffer_t *buffer,
   1894 		hb_buffer_t *reference,
   1895 		hb_codepoint_t dottedcircle_glyph,
   1896 		unsigned int position_fuzz)
   1897 {
   1898   if (buffer->content_type != reference->content_type && buffer->len && reference->len)
   1899     return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH;
   1900 
   1901   hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL;
   1902   bool contains = dottedcircle_glyph != (hb_codepoint_t) -1;
   1903 
   1904   unsigned int count = reference->len;
   1905 
   1906   if (buffer->len != count)
   1907   {
   1908     /*
   1909      * we can't compare glyph-by-glyph, but we do want to know if there
   1910      * are .notdef or dottedcircle glyphs present in the reference buffer
   1911      */
   1912     const hb_glyph_info_t *info = reference->info;
   1913     unsigned int i;
   1914     for (i = 0; i < count; i++)
   1915     {
   1916       if (contains && info[i].codepoint == dottedcircle_glyph)
   1917         result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
   1918       if (contains && info[i].codepoint == 0)
   1919         result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
   1920     }
   1921     result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
   1922     return hb_buffer_diff_flags_t (result);
   1923   }
   1924 
   1925   if (!count)
   1926     return hb_buffer_diff_flags_t (result);
   1927 
   1928   const hb_glyph_info_t *buf_info = buffer->info;
   1929   const hb_glyph_info_t *ref_info = reference->info;
   1930   for (unsigned int i = 0; i < count; i++)
   1931   {
   1932     if (buf_info->codepoint != ref_info->codepoint)
   1933       result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
   1934     if (buf_info->cluster != ref_info->cluster)
   1935       result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
   1936     if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED))
   1937       result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH;
   1938     if (contains && ref_info->codepoint == dottedcircle_glyph)
   1939       result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
   1940     if (contains && ref_info->codepoint == 0)
   1941       result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
   1942     buf_info++;
   1943     ref_info++;
   1944   }
   1945 
   1946   if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS)
   1947   {
   1948     assert (buffer->have_positions);
   1949     const hb_glyph_position_t *buf_pos = buffer->pos;
   1950     const hb_glyph_position_t *ref_pos = reference->pos;
   1951     for (unsigned int i = 0; i < count; i++)
   1952     {
   1953       if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
   1954           (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
   1955           (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
   1956           (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
   1957       {
   1958         result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
   1959         break;
   1960       }
   1961       buf_pos++;
   1962       ref_pos++;
   1963     }
   1964   }
   1965 
   1966   return result;
   1967 }
   1968 
   1969 
   1970 /*
   1971  * Debugging.
   1972  */
   1973 
   1974 /**
   1975  * hb_buffer_set_message_func:
   1976  * @buffer: an #hb_buffer_t.
   1977  * @func: (closure user_data) (destroy destroy) (scope notified):
   1978  * @user_data:
   1979  * @destroy:
   1980  *
   1981  *
   1982  *
   1983  * Since: 1.1.3
   1984  **/
   1985 void
   1986 hb_buffer_set_message_func (hb_buffer_t *buffer,
   1987 			    hb_buffer_message_func_t func,
   1988 			    void *user_data, hb_destroy_func_t destroy)
   1989 {
   1990   if (buffer->message_destroy)
   1991     buffer->message_destroy (buffer->message_data);
   1992 
   1993   if (func) {
   1994     buffer->message_func = func;
   1995     buffer->message_data = user_data;
   1996     buffer->message_destroy = destroy;
   1997   } else {
   1998     buffer->message_func = nullptr;
   1999     buffer->message_data = nullptr;
   2000     buffer->message_destroy = nullptr;
   2001   }
   2002 }
   2003 
   2004 bool
   2005 hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
   2006 {
   2007   char buf[100];
   2008   vsnprintf (buf, sizeof (buf),  fmt, ap);
   2009   return (bool) this->message_func (this, font, buf, this->message_data);
   2010 }
   2011