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