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