Imported Upstream version 2.6.7
[platform/upstream/harfbuzz.git] / src / hb-buffer.cc
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   hb_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   unsigned int count = len;
442   for (unsigned int i = 0; i < count; i++)
443     if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
444       info[i].mask = (info[i].mask & not_mask) | value;
445 }
446
447 void
448 hb_buffer_t::reverse_range (unsigned int start,
449                             unsigned int end)
450 {
451   if (end - start < 2)
452     return;
453
454   hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end);
455
456   if (have_positions) {
457     hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end);
458   }
459 }
460
461 void
462 hb_buffer_t::reverse ()
463 {
464   if (unlikely (!len))
465     return;
466
467   reverse_range (0, len);
468 }
469
470 void
471 hb_buffer_t::reverse_clusters ()
472 {
473   unsigned int i, start, count, last_cluster;
474
475   if (unlikely (!len))
476     return;
477
478   reverse ();
479
480   count = len;
481   start = 0;
482   last_cluster = info[0].cluster;
483   for (i = 1; i < count; i++) {
484     if (last_cluster != info[i].cluster) {
485       reverse_range (start, i);
486       start = i;
487       last_cluster = info[i].cluster;
488     }
489   }
490   reverse_range (start, i);
491 }
492
493 void
494 hb_buffer_t::merge_clusters_impl (unsigned int start,
495                                   unsigned int end)
496 {
497   if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
498   {
499     unsafe_to_break (start, end);
500     return;
501   }
502
503   unsigned int cluster = info[start].cluster;
504
505   for (unsigned int i = start + 1; i < end; i++)
506     cluster = hb_min (cluster, info[i].cluster);
507
508   /* Extend end */
509   while (end < len && info[end - 1].cluster == info[end].cluster)
510     end++;
511
512   /* Extend start */
513   while (idx < start && info[start - 1].cluster == info[start].cluster)
514     start--;
515
516   /* If we hit the start of buffer, continue in out-buffer. */
517   if (idx == start)
518     for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
519       set_cluster (out_info[i - 1], cluster);
520
521   for (unsigned int i = start; i < end; i++)
522     set_cluster (info[i], cluster);
523 }
524 void
525 hb_buffer_t::merge_out_clusters (unsigned int start,
526                                  unsigned int end)
527 {
528   if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS)
529     return;
530
531   if (unlikely (end - start < 2))
532     return;
533
534   unsigned int cluster = out_info[start].cluster;
535
536   for (unsigned int i = start + 1; i < end; i++)
537     cluster = hb_min (cluster, out_info[i].cluster);
538
539   /* Extend start */
540   while (start && out_info[start - 1].cluster == out_info[start].cluster)
541     start--;
542
543   /* Extend end */
544   while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
545     end++;
546
547   /* If we hit the end of out-buffer, continue in buffer. */
548   if (end == out_len)
549     for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
550       set_cluster (info[i], cluster);
551
552   for (unsigned int i = start; i < end; i++)
553     set_cluster (out_info[i], cluster);
554 }
555 void
556 hb_buffer_t::delete_glyph ()
557 {
558   /* The logic here is duplicated in hb_ot_hide_default_ignorables(). */
559
560   unsigned int cluster = info[idx].cluster;
561   if (idx + 1 < len && cluster == info[idx + 1].cluster)
562   {
563     /* Cluster survives; do nothing. */
564     goto done;
565   }
566
567   if (out_len)
568   {
569     /* Merge cluster backward. */
570     if (cluster < out_info[out_len - 1].cluster)
571     {
572       unsigned int mask = info[idx].mask;
573       unsigned int old_cluster = out_info[out_len - 1].cluster;
574       for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--)
575         set_cluster (out_info[i - 1], cluster, mask);
576     }
577     goto done;
578   }
579
580   if (idx + 1 < len)
581   {
582     /* Merge cluster forward. */
583     merge_clusters (idx, idx + 2);
584     goto done;
585   }
586
587 done:
588   skip_glyph ();
589 }
590
591 void
592 hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
593 {
594   unsigned int cluster = UINT_MAX;
595   cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster);
596   _unsafe_to_break_set_mask (info, start, end, cluster);
597 }
598 void
599 hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
600 {
601   if (!have_output)
602   {
603     unsafe_to_break_impl (start, end);
604     return;
605   }
606
607   assert (start <= out_len);
608   assert (idx <= end);
609
610   unsigned int cluster = UINT_MAX;
611   cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster);
612   cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster);
613   _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
614   _unsafe_to_break_set_mask (info, idx, end, cluster);
615 }
616
617 void
618 hb_buffer_t::guess_segment_properties ()
619 {
620   assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
621           (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
622
623   /* If script is set to INVALID, guess from buffer contents */
624   if (props.script == HB_SCRIPT_INVALID) {
625     for (unsigned int i = 0; i < len; i++) {
626       hb_script_t script = unicode->script (info[i].codepoint);
627       if (likely (script != HB_SCRIPT_COMMON &&
628                   script != HB_SCRIPT_INHERITED &&
629                   script != HB_SCRIPT_UNKNOWN)) {
630         props.script = script;
631         break;
632       }
633     }
634   }
635
636   /* If direction is set to INVALID, guess from script */
637   if (props.direction == HB_DIRECTION_INVALID) {
638     props.direction = hb_script_get_horizontal_direction (props.script);
639     if (props.direction == HB_DIRECTION_INVALID)
640       props.direction = HB_DIRECTION_LTR;
641   }
642
643   /* If language is not set, use default language from locale */
644   if (props.language == HB_LANGUAGE_INVALID) {
645     /* TODO get_default_for_script? using $LANGUAGE */
646     props.language = hb_language_get_default ();
647   }
648 }
649
650
651 /* Public API */
652
653 DEFINE_NULL_INSTANCE (hb_buffer_t) =
654 {
655   HB_OBJECT_HEADER_STATIC,
656
657   const_cast<hb_unicode_funcs_t *> (&_hb_Null_hb_unicode_funcs_t),
658   HB_BUFFER_FLAG_DEFAULT,
659   HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
660   HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
661   0, /* invisible */
662   HB_BUFFER_SCRATCH_FLAG_DEFAULT,
663   HB_BUFFER_MAX_LEN_DEFAULT,
664   HB_BUFFER_MAX_OPS_DEFAULT,
665
666   HB_BUFFER_CONTENT_TYPE_INVALID,
667   HB_SEGMENT_PROPERTIES_DEFAULT,
668   false, /* successful */
669   true, /* have_output */
670   true  /* have_positions */
671
672   /* Zero is good enough for everything else. */
673 };
674
675
676 /**
677  * hb_buffer_create: (Xconstructor)
678  *
679  * Creates a new #hb_buffer_t with all properties to defaults.
680  *
681  * Return value: (transfer full):
682  * A newly allocated #hb_buffer_t with a reference count of 1. The initial
683  * reference count should be released with hb_buffer_destroy() when you are done
684  * using the #hb_buffer_t. This function never returns %NULL. If memory cannot
685  * be allocated, a special #hb_buffer_t object will be returned on which
686  * hb_buffer_allocation_successful() returns %false.
687  *
688  * Since: 0.9.2
689  **/
690 hb_buffer_t *
691 hb_buffer_create ()
692 {
693   hb_buffer_t *buffer;
694
695   if (!(buffer = hb_object_create<hb_buffer_t> ()))
696     return hb_buffer_get_empty ();
697
698   buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
699   buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
700
701   buffer->reset ();
702
703   return buffer;
704 }
705
706 /**
707  * hb_buffer_get_empty:
708  *
709  *
710  *
711  * Return value: (transfer full):
712  *
713  * Since: 0.9.2
714  **/
715 hb_buffer_t *
716 hb_buffer_get_empty ()
717 {
718   return const_cast<hb_buffer_t *> (&Null (hb_buffer_t));
719 }
720
721 /**
722  * hb_buffer_reference: (skip)
723  * @buffer: an #hb_buffer_t.
724  *
725  * Increases the reference count on @buffer by one. This prevents @buffer from
726  * being destroyed until a matching call to hb_buffer_destroy() is made.
727  *
728  * Return value: (transfer full):
729  * The referenced #hb_buffer_t.
730  *
731  * Since: 0.9.2
732  **/
733 hb_buffer_t *
734 hb_buffer_reference (hb_buffer_t *buffer)
735 {
736   return hb_object_reference (buffer);
737 }
738
739 /**
740  * hb_buffer_destroy: (skip)
741  * @buffer: an #hb_buffer_t.
742  *
743  * Deallocate the @buffer.
744  * Decreases the reference count on @buffer by one. If the result is zero, then
745  * @buffer and all associated resources are freed. See hb_buffer_reference().
746  *
747  * Since: 0.9.2
748  **/
749 void
750 hb_buffer_destroy (hb_buffer_t *buffer)
751 {
752   if (!hb_object_destroy (buffer)) return;
753
754   hb_unicode_funcs_destroy (buffer->unicode);
755
756   free (buffer->info);
757   free (buffer->pos);
758 #ifndef HB_NO_BUFFER_MESSAGE
759   if (buffer->message_destroy)
760     buffer->message_destroy (buffer->message_data);
761 #endif
762
763   free (buffer);
764 }
765
766 /**
767  * hb_buffer_set_user_data: (skip)
768  * @buffer: an #hb_buffer_t.
769  * @key:
770  * @data:
771  * @destroy:
772  * @replace:
773  *
774  *
775  *
776  * Return value:
777  *
778  * Since: 0.9.2
779  **/
780 hb_bool_t
781 hb_buffer_set_user_data (hb_buffer_t        *buffer,
782                          hb_user_data_key_t *key,
783                          void *              data,
784                          hb_destroy_func_t   destroy,
785                          hb_bool_t           replace)
786 {
787   return hb_object_set_user_data (buffer, key, data, destroy, replace);
788 }
789
790 /**
791  * hb_buffer_get_user_data: (skip)
792  * @buffer: an #hb_buffer_t.
793  * @key:
794  *
795  *
796  *
797  * Return value:
798  *
799  * Since: 0.9.2
800  **/
801 void *
802 hb_buffer_get_user_data (hb_buffer_t        *buffer,
803                          hb_user_data_key_t *key)
804 {
805   return hb_object_get_user_data (buffer, key);
806 }
807
808
809 /**
810  * hb_buffer_set_content_type:
811  * @buffer: an #hb_buffer_t.
812  * @content_type: the type of buffer contents to set
813  *
814  * Sets the type of @buffer contents, buffers are either empty, contain
815  * characters (before shaping) or glyphs (the result of shaping).
816  *
817  * Since: 0.9.5
818  **/
819 void
820 hb_buffer_set_content_type (hb_buffer_t              *buffer,
821                             hb_buffer_content_type_t  content_type)
822 {
823   buffer->content_type = content_type;
824 }
825
826 /**
827  * hb_buffer_get_content_type:
828  * @buffer: an #hb_buffer_t.
829  *
830  * see hb_buffer_set_content_type().
831  *
832  * Return value:
833  * The type of @buffer contents.
834  *
835  * Since: 0.9.5
836  **/
837 hb_buffer_content_type_t
838 hb_buffer_get_content_type (hb_buffer_t *buffer)
839 {
840   return buffer->content_type;
841 }
842
843
844 /**
845  * hb_buffer_set_unicode_funcs:
846  * @buffer: an #hb_buffer_t.
847  * @unicode_funcs:
848  *
849  *
850  *
851  * Since: 0.9.2
852  **/
853 void
854 hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
855                              hb_unicode_funcs_t *unicode_funcs)
856 {
857   if (unlikely (hb_object_is_immutable (buffer)))
858     return;
859
860   if (!unicode_funcs)
861     unicode_funcs = hb_unicode_funcs_get_default ();
862
863   hb_unicode_funcs_reference (unicode_funcs);
864   hb_unicode_funcs_destroy (buffer->unicode);
865   buffer->unicode = unicode_funcs;
866 }
867
868 /**
869  * hb_buffer_get_unicode_funcs:
870  * @buffer: an #hb_buffer_t.
871  *
872  *
873  *
874  * Return value:
875  *
876  * Since: 0.9.2
877  **/
878 hb_unicode_funcs_t *
879 hb_buffer_get_unicode_funcs (hb_buffer_t        *buffer)
880 {
881   return buffer->unicode;
882 }
883
884 /**
885  * hb_buffer_set_direction:
886  * @buffer: an #hb_buffer_t.
887  * @direction: the #hb_direction_t of the @buffer
888  *
889  * Set the text flow direction of the buffer. No shaping can happen without
890  * setting @buffer direction, and it controls the visual direction for the
891  * output glyphs; for RTL direction the glyphs will be reversed. Many layout
892  * features depend on the proper setting of the direction, for example,
893  * reversing RTL text before shaping, then shaping with LTR direction is not
894  * the same as keeping the text in logical order and shaping with RTL
895  * direction.
896  *
897  * Since: 0.9.2
898  **/
899 void
900 hb_buffer_set_direction (hb_buffer_t    *buffer,
901                          hb_direction_t  direction)
902
903 {
904   if (unlikely (hb_object_is_immutable (buffer)))
905     return;
906
907   buffer->props.direction = direction;
908 }
909
910 /**
911  * hb_buffer_get_direction:
912  * @buffer: an #hb_buffer_t.
913  *
914  * See hb_buffer_set_direction()
915  *
916  * Return value:
917  * The direction of the @buffer.
918  *
919  * Since: 0.9.2
920  **/
921 hb_direction_t
922 hb_buffer_get_direction (hb_buffer_t    *buffer)
923 {
924   return buffer->props.direction;
925 }
926
927 /**
928  * hb_buffer_set_script:
929  * @buffer: an #hb_buffer_t.
930  * @script: an #hb_script_t to set.
931  *
932  * Sets the script of @buffer to @script.
933  *
934  * Script is crucial for choosing the proper shaping behaviour for scripts that
935  * require it (e.g. Arabic) and the which OpenType features defined in the font
936  * to be applied.
937  *
938  * You can pass one of the predefined #hb_script_t values, or use
939  * hb_script_from_string() or hb_script_from_iso15924_tag() to get the
940  * corresponding script from an ISO 15924 script tag.
941  *
942  * Since: 0.9.2
943  **/
944 void
945 hb_buffer_set_script (hb_buffer_t *buffer,
946                       hb_script_t  script)
947 {
948   if (unlikely (hb_object_is_immutable (buffer)))
949     return;
950
951   buffer->props.script = script;
952 }
953
954 /**
955  * hb_buffer_get_script:
956  * @buffer: an #hb_buffer_t.
957  *
958  * See hb_buffer_set_script().
959  *
960  * Return value:
961  * The #hb_script_t of the @buffer.
962  *
963  * Since: 0.9.2
964  **/
965 hb_script_t
966 hb_buffer_get_script (hb_buffer_t *buffer)
967 {
968   return buffer->props.script;
969 }
970
971 /**
972  * hb_buffer_set_language:
973  * @buffer: an #hb_buffer_t.
974  * @language: an hb_language_t to set.
975  *
976  * Sets the language of @buffer to @language.
977  *
978  * Languages are crucial for selecting which OpenType feature to apply to the
979  * buffer which can result in applying language-specific behaviour. Languages
980  * are orthogonal to the scripts, and though they are related, they are
981  * different concepts and should not be confused with each other.
982  *
983  * Use hb_language_from_string() to convert from BCP 47 language tags to
984  * #hb_language_t.
985  *
986  * Since: 0.9.2
987  **/
988 void
989 hb_buffer_set_language (hb_buffer_t   *buffer,
990                         hb_language_t  language)
991 {
992   if (unlikely (hb_object_is_immutable (buffer)))
993     return;
994
995   buffer->props.language = language;
996 }
997
998 /**
999  * hb_buffer_get_language:
1000  * @buffer: an #hb_buffer_t.
1001  *
1002  * See hb_buffer_set_language().
1003  *
1004  * Return value: (transfer none):
1005  * The #hb_language_t of the buffer. Must not be freed by the caller.
1006  *
1007  * Since: 0.9.2
1008  **/
1009 hb_language_t
1010 hb_buffer_get_language (hb_buffer_t *buffer)
1011 {
1012   return buffer->props.language;
1013 }
1014
1015 /**
1016  * hb_buffer_set_segment_properties:
1017  * @buffer: an #hb_buffer_t.
1018  * @props: an #hb_segment_properties_t to use.
1019  *
1020  * Sets the segment properties of the buffer, a shortcut for calling
1021  * hb_buffer_set_direction(), hb_buffer_set_script() and
1022  * hb_buffer_set_language() individually.
1023  *
1024  * Since: 0.9.7
1025  **/
1026 void
1027 hb_buffer_set_segment_properties (hb_buffer_t *buffer,
1028                                   const hb_segment_properties_t *props)
1029 {
1030   if (unlikely (hb_object_is_immutable (buffer)))
1031     return;
1032
1033   buffer->props = *props;
1034 }
1035
1036 /**
1037  * hb_buffer_get_segment_properties:
1038  * @buffer: an #hb_buffer_t.
1039  * @props: (out): the output #hb_segment_properties_t.
1040  *
1041  * Sets @props to the #hb_segment_properties_t of @buffer.
1042  *
1043  * Since: 0.9.7
1044  **/
1045 void
1046 hb_buffer_get_segment_properties (hb_buffer_t *buffer,
1047                                   hb_segment_properties_t *props)
1048 {
1049   *props = buffer->props;
1050 }
1051
1052
1053 /**
1054  * hb_buffer_set_flags:
1055  * @buffer: an #hb_buffer_t.
1056  * @flags: the buffer flags to set.
1057  *
1058  * Sets @buffer flags to @flags. See #hb_buffer_flags_t.
1059  *
1060  * Since: 0.9.7
1061  **/
1062 void
1063 hb_buffer_set_flags (hb_buffer_t       *buffer,
1064                      hb_buffer_flags_t  flags)
1065 {
1066   if (unlikely (hb_object_is_immutable (buffer)))
1067     return;
1068
1069   buffer->flags = flags;
1070 }
1071
1072 /**
1073  * hb_buffer_get_flags:
1074  * @buffer: an #hb_buffer_t.
1075  *
1076  * See hb_buffer_set_flags().
1077  *
1078  * Return value:
1079  * The @buffer flags.
1080  *
1081  * Since: 0.9.7
1082  **/
1083 hb_buffer_flags_t
1084 hb_buffer_get_flags (hb_buffer_t *buffer)
1085 {
1086   return buffer->flags;
1087 }
1088
1089 /**
1090  * hb_buffer_set_cluster_level:
1091  * @buffer: an #hb_buffer_t.
1092  * @cluster_level:
1093  *
1094  *
1095  *
1096  * Since: 0.9.42
1097  **/
1098 void
1099 hb_buffer_set_cluster_level (hb_buffer_t       *buffer,
1100                      hb_buffer_cluster_level_t  cluster_level)
1101 {
1102   if (unlikely (hb_object_is_immutable (buffer)))
1103     return;
1104
1105   buffer->cluster_level = cluster_level;
1106 }
1107
1108 /**
1109  * hb_buffer_get_cluster_level:
1110  * @buffer: an #hb_buffer_t.
1111  *
1112  *
1113  *
1114  * Return value:
1115  *
1116  * Since: 0.9.42
1117  **/
1118 hb_buffer_cluster_level_t
1119 hb_buffer_get_cluster_level (hb_buffer_t *buffer)
1120 {
1121   return buffer->cluster_level;
1122 }
1123
1124
1125 /**
1126  * hb_buffer_set_replacement_codepoint:
1127  * @buffer: an #hb_buffer_t.
1128  * @replacement: the replacement #hb_codepoint_t
1129  *
1130  * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding
1131  * when adding text to @buffer.
1132  *
1133  * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT.
1134  *
1135  * Since: 0.9.31
1136  **/
1137 void
1138 hb_buffer_set_replacement_codepoint (hb_buffer_t    *buffer,
1139                                      hb_codepoint_t  replacement)
1140 {
1141   if (unlikely (hb_object_is_immutable (buffer)))
1142     return;
1143
1144   buffer->replacement = replacement;
1145 }
1146
1147 /**
1148  * hb_buffer_get_replacement_codepoint:
1149  * @buffer: an #hb_buffer_t.
1150  *
1151  * See hb_buffer_set_replacement_codepoint().
1152  *
1153  * Return value:
1154  * The @buffer replacement #hb_codepoint_t.
1155  *
1156  * Since: 0.9.31
1157  **/
1158 hb_codepoint_t
1159 hb_buffer_get_replacement_codepoint (hb_buffer_t    *buffer)
1160 {
1161   return buffer->replacement;
1162 }
1163
1164
1165 /**
1166  * hb_buffer_set_invisible_glyph:
1167  * @buffer: an #hb_buffer_t.
1168  * @invisible: the invisible #hb_codepoint_t
1169  *
1170  * Sets the #hb_codepoint_t that replaces invisible characters in
1171  * the shaping result.  If set to zero (default), the glyph for the
1172  * U+0020 SPACE character is used.  Otherwise, this value is used
1173  * verbatim.
1174  *
1175  * Since: 2.0.0
1176  **/
1177 void
1178 hb_buffer_set_invisible_glyph (hb_buffer_t    *buffer,
1179                                hb_codepoint_t  invisible)
1180 {
1181   if (unlikely (hb_object_is_immutable (buffer)))
1182     return;
1183
1184   buffer->invisible = invisible;
1185 }
1186
1187 /**
1188  * hb_buffer_get_invisible_glyph:
1189  * @buffer: an #hb_buffer_t.
1190  *
1191  * See hb_buffer_set_invisible_glyph().
1192  *
1193  * Return value:
1194  * The @buffer invisible #hb_codepoint_t.
1195  *
1196  * Since: 2.0.0
1197  **/
1198 hb_codepoint_t
1199 hb_buffer_get_invisible_glyph (hb_buffer_t    *buffer)
1200 {
1201   return buffer->invisible;
1202 }
1203
1204
1205 /**
1206  * hb_buffer_reset:
1207  * @buffer: an #hb_buffer_t.
1208  *
1209  * Resets the buffer to its initial status, as if it was just newly created
1210  * with hb_buffer_create().
1211  *
1212  * Since: 0.9.2
1213  **/
1214 void
1215 hb_buffer_reset (hb_buffer_t *buffer)
1216 {
1217   buffer->reset ();
1218 }
1219
1220 /**
1221  * hb_buffer_clear_contents:
1222  * @buffer: an #hb_buffer_t.
1223  *
1224  * Similar to hb_buffer_reset(), but does not clear the Unicode functions and
1225  * the replacement code point.
1226  *
1227  * Since: 0.9.11
1228  **/
1229 void
1230 hb_buffer_clear_contents (hb_buffer_t *buffer)
1231 {
1232   buffer->clear ();
1233 }
1234
1235 /**
1236  * hb_buffer_pre_allocate:
1237  * @buffer: an #hb_buffer_t.
1238  * @size: number of items to pre allocate.
1239  *
1240  * Pre allocates memory for @buffer to fit at least @size number of items.
1241  *
1242  * Return value:
1243  * %true if @buffer memory allocation succeeded, %false otherwise.
1244  *
1245  * Since: 0.9.2
1246  **/
1247 hb_bool_t
1248 hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
1249 {
1250   return buffer->ensure (size);
1251 }
1252
1253 /**
1254  * hb_buffer_allocation_successful:
1255  * @buffer: an #hb_buffer_t.
1256  *
1257  * Check if allocating memory for the buffer succeeded.
1258  *
1259  * Return value:
1260  * %true if @buffer memory allocation succeeded, %false otherwise.
1261  *
1262  * Since: 0.9.2
1263  **/
1264 hb_bool_t
1265 hb_buffer_allocation_successful (hb_buffer_t  *buffer)
1266 {
1267   return buffer->successful;
1268 }
1269
1270 /**
1271  * hb_buffer_add:
1272  * @buffer: an #hb_buffer_t.
1273  * @codepoint: a Unicode code point.
1274  * @cluster: the cluster value of @codepoint.
1275  *
1276  * Appends a character with the Unicode value of @codepoint to @buffer, and
1277  * gives it the initial cluster value of @cluster. Clusters can be any thing
1278  * the client wants, they are usually used to refer to the index of the
1279  * character in the input text stream and are output in
1280  * #hb_glyph_info_t.cluster field.
1281  *
1282  * This function does not check the validity of @codepoint, it is up to the
1283  * caller to ensure it is a valid Unicode code point.
1284  *
1285  * Since: 0.9.7
1286  **/
1287 void
1288 hb_buffer_add (hb_buffer_t    *buffer,
1289                hb_codepoint_t  codepoint,
1290                unsigned int    cluster)
1291 {
1292   buffer->add (codepoint, cluster);
1293   buffer->clear_context (1);
1294 }
1295
1296 /**
1297  * hb_buffer_set_length:
1298  * @buffer: an #hb_buffer_t.
1299  * @length: the new length of @buffer.
1300  *
1301  * Similar to hb_buffer_pre_allocate(), but clears any new items added at the
1302  * end.
1303  *
1304  * Return value:
1305  * %true if @buffer memory allocation succeeded, %false otherwise.
1306  *
1307  * Since: 0.9.2
1308  **/
1309 hb_bool_t
1310 hb_buffer_set_length (hb_buffer_t  *buffer,
1311                       unsigned int  length)
1312 {
1313   if (unlikely (hb_object_is_immutable (buffer)))
1314     return length == 0;
1315
1316   if (!buffer->ensure (length))
1317     return false;
1318
1319   /* Wipe the new space */
1320   if (length > buffer->len) {
1321     memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
1322     if (buffer->have_positions)
1323       memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
1324   }
1325
1326   buffer->len = length;
1327
1328   if (!length)
1329   {
1330     buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
1331     buffer->clear_context (0);
1332   }
1333   buffer->clear_context (1);
1334
1335   return true;
1336 }
1337
1338 /**
1339  * hb_buffer_get_length:
1340  * @buffer: an #hb_buffer_t.
1341  *
1342  * Returns the number of items in the buffer.
1343  *
1344  * Return value:
1345  * The @buffer length.
1346  * The value valid as long as buffer has not been modified.
1347  *
1348  * Since: 0.9.2
1349  **/
1350 unsigned int
1351 hb_buffer_get_length (hb_buffer_t *buffer)
1352 {
1353   return buffer->len;
1354 }
1355
1356 /**
1357  * hb_buffer_get_glyph_infos:
1358  * @buffer: an #hb_buffer_t.
1359  * @length: (out): output array length.
1360  *
1361  * Returns @buffer glyph information array.  Returned pointer
1362  * is valid as long as @buffer contents are not modified.
1363  *
1364  * Return value: (transfer none) (array length=length):
1365  * The @buffer glyph information array.
1366  * The value valid as long as buffer has not been modified.
1367  *
1368  * Since: 0.9.2
1369  **/
1370 hb_glyph_info_t *
1371 hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
1372                            unsigned int *length)
1373 {
1374   if (length)
1375     *length = buffer->len;
1376
1377   return (hb_glyph_info_t *) buffer->info;
1378 }
1379
1380 /**
1381  * hb_buffer_get_glyph_positions:
1382  * @buffer: an #hb_buffer_t.
1383  * @length: (out): output length.
1384  *
1385  * Returns @buffer glyph position array.  Returned pointer
1386  * is valid as long as @buffer contents are not modified.
1387  *
1388  * Return value: (transfer none) (array length=length):
1389  * The @buffer glyph position array.
1390  * The value valid as long as buffer has not been modified.
1391  *
1392  * Since: 0.9.2
1393  **/
1394 hb_glyph_position_t *
1395 hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
1396                                unsigned int *length)
1397 {
1398   if (!buffer->have_positions)
1399     buffer->clear_positions ();
1400
1401   if (length)
1402     *length = buffer->len;
1403
1404   return (hb_glyph_position_t *) buffer->pos;
1405 }
1406
1407 /**
1408  * hb_glyph_info_get_glyph_flags:
1409  * @info: a #hb_glyph_info_t.
1410  *
1411  * Returns glyph flags encoded within a #hb_glyph_info_t.
1412  *
1413  * Return value:
1414  * The #hb_glyph_flags_t encoded within @info.
1415  *
1416  * Since: 1.5.0
1417  **/
1418 hb_glyph_flags_t
1419 (hb_glyph_info_get_glyph_flags) (const hb_glyph_info_t *info)
1420 {
1421   return hb_glyph_info_get_glyph_flags (info);
1422 }
1423
1424 /**
1425  * hb_buffer_reverse:
1426  * @buffer: an #hb_buffer_t.
1427  *
1428  * Reverses buffer contents.
1429  *
1430  * Since: 0.9.2
1431  **/
1432 void
1433 hb_buffer_reverse (hb_buffer_t *buffer)
1434 {
1435   buffer->reverse ();
1436 }
1437
1438 /**
1439  * hb_buffer_reverse_range:
1440  * @buffer: an #hb_buffer_t.
1441  * @start: start index.
1442  * @end: end index.
1443  *
1444  * Reverses buffer contents between start to end.
1445  *
1446  * Since: 0.9.41
1447  **/
1448 void
1449 hb_buffer_reverse_range (hb_buffer_t *buffer,
1450                          unsigned int start, unsigned int end)
1451 {
1452   buffer->reverse_range (start, end);
1453 }
1454
1455 /**
1456  * hb_buffer_reverse_clusters:
1457  * @buffer: an #hb_buffer_t.
1458  *
1459  * Reverses buffer clusters.  That is, the buffer contents are
1460  * reversed, then each cluster (consecutive items having the
1461  * same cluster number) are reversed again.
1462  *
1463  * Since: 0.9.2
1464  **/
1465 void
1466 hb_buffer_reverse_clusters (hb_buffer_t *buffer)
1467 {
1468   buffer->reverse_clusters ();
1469 }
1470
1471 /**
1472  * hb_buffer_guess_segment_properties:
1473  * @buffer: an #hb_buffer_t.
1474  *
1475  * Sets unset buffer segment properties based on buffer Unicode
1476  * contents.  If buffer is not empty, it must have content type
1477  * %HB_BUFFER_CONTENT_TYPE_UNICODE.
1478  *
1479  * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
1480  * will be set to the Unicode script of the first character in
1481  * the buffer that has a script other than %HB_SCRIPT_COMMON,
1482  * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
1483  *
1484  * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
1485  * it will be set to the natural horizontal direction of the
1486  * buffer script as returned by hb_script_get_horizontal_direction().
1487  * If hb_script_get_horizontal_direction() returns %HB_DIRECTION_INVALID,
1488  * then %HB_DIRECTION_LTR is used.
1489  *
1490  * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
1491  * it will be set to the process's default language as returned by
1492  * hb_language_get_default().  This may change in the future by
1493  * taking buffer script into consideration when choosing a language.
1494  * Note that hb_language_get_default() is NOT threadsafe the first time
1495  * it is called.  See documentation for that function for details.
1496  *
1497  * Since: 0.9.7
1498  **/
1499 void
1500 hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
1501 {
1502   buffer->guess_segment_properties ();
1503 }
1504
1505 template <typename utf_t>
1506 static inline void
1507 hb_buffer_add_utf (hb_buffer_t  *buffer,
1508                    const typename utf_t::codepoint_t *text,
1509                    int           text_length,
1510                    unsigned int  item_offset,
1511                    int           item_length)
1512 {
1513   typedef typename utf_t::codepoint_t T;
1514   const hb_codepoint_t replacement = buffer->replacement;
1515
1516   assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
1517           (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
1518
1519   if (unlikely (hb_object_is_immutable (buffer)))
1520     return;
1521
1522   if (text_length == -1)
1523     text_length = utf_t::strlen (text);
1524
1525   if (item_length == -1)
1526     item_length = text_length - item_offset;
1527
1528   buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
1529
1530   /* If buffer is empty and pre-context provided, install it.
1531    * This check is written this way, to make sure people can
1532    * provide pre-context in one add_utf() call, then provide
1533    * text in a follow-up call.  See:
1534    *
1535    * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
1536    */
1537   if (!buffer->len && item_offset > 0)
1538   {
1539     /* Add pre-context */
1540     buffer->clear_context (0);
1541     const T *prev = text + item_offset;
1542     const T *start = text;
1543     while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
1544     {
1545       hb_codepoint_t u;
1546       prev = utf_t::prev (prev, start, &u, replacement);
1547       buffer->context[0][buffer->context_len[0]++] = u;
1548     }
1549   }
1550
1551   const T *next = text + item_offset;
1552   const T *end = next + item_length;
1553   while (next < end)
1554   {
1555     hb_codepoint_t u;
1556     const T *old_next = next;
1557     next = utf_t::next (next, end, &u, replacement);
1558     buffer->add (u, old_next - (const T *) text);
1559   }
1560
1561   /* Add post-context */
1562   buffer->clear_context (1);
1563   end = text + text_length;
1564   while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
1565   {
1566     hb_codepoint_t u;
1567     next = utf_t::next (next, end, &u, replacement);
1568     buffer->context[1][buffer->context_len[1]++] = u;
1569   }
1570
1571   buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
1572 }
1573
1574 /**
1575  * hb_buffer_add_utf8:
1576  * @buffer: an #hb_buffer_t.
1577  * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
1578  *               characters to append.
1579  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
1580  * @item_offset: the offset of the first character to add to the @buffer.
1581  * @item_length: the number of characters to add to the @buffer, or -1 for the
1582  *               end of @text (assuming it is %NULL terminated).
1583  *
1584  * See hb_buffer_add_codepoints().
1585  *
1586  * Replaces invalid UTF-8 characters with the @buffer replacement code point,
1587  * see hb_buffer_set_replacement_codepoint().
1588  *
1589  * Since: 0.9.2
1590  **/
1591 void
1592 hb_buffer_add_utf8 (hb_buffer_t  *buffer,
1593                     const char   *text,
1594                     int           text_length,
1595                     unsigned int  item_offset,
1596                     int           item_length)
1597 {
1598   hb_buffer_add_utf<hb_utf8_t> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
1599 }
1600
1601 /**
1602  * hb_buffer_add_utf16:
1603  * @buffer: an #hb_buffer_t.
1604  * @text: (array length=text_length): an array of UTF-16 characters to append.
1605  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
1606  * @item_offset: the offset of the first character to add to the @buffer.
1607  * @item_length: the number of characters to add to the @buffer, or -1 for the
1608  *               end of @text (assuming it is %NULL terminated).
1609  *
1610  * See hb_buffer_add_codepoints().
1611  *
1612  * Replaces invalid UTF-16 characters with the @buffer replacement code point,
1613  * see hb_buffer_set_replacement_codepoint().
1614  *
1615  * Since: 0.9.2
1616  **/
1617 void
1618 hb_buffer_add_utf16 (hb_buffer_t    *buffer,
1619                      const uint16_t *text,
1620                      int             text_length,
1621                      unsigned int    item_offset,
1622                      int             item_length)
1623 {
1624   hb_buffer_add_utf<hb_utf16_t> (buffer, text, text_length, item_offset, item_length);
1625 }
1626
1627 /**
1628  * hb_buffer_add_utf32:
1629  * @buffer: an #hb_buffer_t.
1630  * @text: (array length=text_length): an array of UTF-32 characters to append.
1631  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
1632  * @item_offset: the offset of the first character to add to the @buffer.
1633  * @item_length: the number of characters to add to the @buffer, or -1 for the
1634  *               end of @text (assuming it is %NULL terminated).
1635  *
1636  * See hb_buffer_add_codepoints().
1637  *
1638  * Replaces invalid UTF-32 characters with the @buffer replacement code point,
1639  * see hb_buffer_set_replacement_codepoint().
1640  *
1641  * Since: 0.9.2
1642  **/
1643 void
1644 hb_buffer_add_utf32 (hb_buffer_t    *buffer,
1645                      const uint32_t *text,
1646                      int             text_length,
1647                      unsigned int    item_offset,
1648                      int             item_length)
1649 {
1650   hb_buffer_add_utf<hb_utf32_t> (buffer, text, text_length, item_offset, item_length);
1651 }
1652
1653 /**
1654  * hb_buffer_add_latin1:
1655  * @buffer: an #hb_buffer_t.
1656  * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8
1657  *               characters to append.
1658  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
1659  * @item_offset: the offset of the first character to add to the @buffer.
1660  * @item_length: the number of characters to add to the @buffer, or -1 for the
1661  *               end of @text (assuming it is %NULL terminated).
1662  *
1663  * Similar to hb_buffer_add_codepoints(), but allows only access to first 256
1664  * Unicode code points that can fit in 8-bit strings.
1665  *
1666  * <note>Has nothing to do with non-Unicode Latin-1 encoding.</note>
1667  *
1668  * Since: 0.9.39
1669  **/
1670 void
1671 hb_buffer_add_latin1 (hb_buffer_t   *buffer,
1672                       const uint8_t *text,
1673                       int            text_length,
1674                       unsigned int   item_offset,
1675                       int            item_length)
1676 {
1677   hb_buffer_add_utf<hb_latin1_t> (buffer, text, text_length, item_offset, item_length);
1678 }
1679
1680 /**
1681  * hb_buffer_add_codepoints:
1682  * @buffer: a #hb_buffer_t to append characters to.
1683  * @text: (array length=text_length): an array of Unicode code points to append.
1684  * @text_length: the length of the @text, or -1 if it is %NULL terminated.
1685  * @item_offset: the offset of the first code point to add to the @buffer.
1686  * @item_length: the number of code points to add to the @buffer, or -1 for the
1687  *               end of @text (assuming it is %NULL terminated).
1688  *
1689  * Appends characters from @text array to @buffer. The @item_offset is the
1690  * position of the first character from @text that will be appended, and
1691  * @item_length is the number of character. When shaping part of a larger text
1692  * (e.g. a run of text from a paragraph), instead of passing just the substring
1693  * corresponding to the run, it is preferable to pass the whole
1694  * paragraph and specify the run start and length as @item_offset and
1695  * @item_length, respectively, to give HarfBuzz the full context to be able,
1696  * for example, to do cross-run Arabic shaping or properly handle combining
1697  * marks at stat of run.
1698  *
1699  * This function does not check the validity of @text, it is up to the caller
1700  * to ensure it contains a valid Unicode code points.
1701  *
1702  * Since: 0.9.31
1703  **/
1704 void
1705 hb_buffer_add_codepoints (hb_buffer_t          *buffer,
1706                           const hb_codepoint_t *text,
1707                           int                   text_length,
1708                           unsigned int          item_offset,
1709                           int                   item_length)
1710 {
1711   hb_buffer_add_utf<hb_utf32_novalidate_t> (buffer, text, text_length, item_offset, item_length);
1712 }
1713
1714
1715 /**
1716  * hb_buffer_append:
1717  * @buffer: an #hb_buffer_t.
1718  * @source: source #hb_buffer_t.
1719  * @start: start index into source buffer to copy.  Use 0 to copy from start of buffer.
1720  * @end: end index into source buffer to copy.  Use @HB_FEATURE_GLOBAL_END to copy to end of buffer.
1721  *
1722  * Append (part of) contents of another buffer to this buffer.
1723  *
1724  * Since: 1.5.0
1725  **/
1726 HB_EXTERN void
1727 hb_buffer_append (hb_buffer_t *buffer,
1728                   hb_buffer_t *source,
1729                   unsigned int start,
1730                   unsigned int end)
1731 {
1732   assert (!buffer->have_output && !source->have_output);
1733   assert (buffer->have_positions == source->have_positions ||
1734           !buffer->len || !source->len);
1735   assert (buffer->content_type == source->content_type ||
1736           !buffer->len || !source->len);
1737
1738   if (end > source->len)
1739     end = source->len;
1740   if (start > end)
1741     start = end;
1742   if (start == end)
1743     return;
1744
1745   if (!buffer->len)
1746     buffer->content_type = source->content_type;
1747   if (!buffer->have_positions && source->have_positions)
1748     buffer->clear_positions ();
1749
1750   if (buffer->len + (end - start) < buffer->len) /* Overflows. */
1751   {
1752     buffer->successful = false;
1753     return;
1754   }
1755
1756   unsigned int orig_len = buffer->len;
1757   hb_buffer_set_length (buffer, buffer->len + (end - start));
1758   if (unlikely (!buffer->successful))
1759     return;
1760
1761   memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
1762   if (buffer->have_positions)
1763     memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
1764 }
1765
1766
1767 static int
1768 compare_info_codepoint (const hb_glyph_info_t *pa,
1769                         const hb_glyph_info_t *pb)
1770 {
1771   return (int) pb->codepoint - (int) pa->codepoint;
1772 }
1773
1774 static inline void
1775 normalize_glyphs_cluster (hb_buffer_t *buffer,
1776                           unsigned int start,
1777                           unsigned int end,
1778                           bool backward)
1779 {
1780   hb_glyph_position_t *pos = buffer->pos;
1781
1782   /* Total cluster advance */
1783   hb_position_t total_x_advance = 0, total_y_advance = 0;
1784   for (unsigned int i = start; i < end; i++)
1785   {
1786     total_x_advance += pos[i].x_advance;
1787     total_y_advance += pos[i].y_advance;
1788   }
1789
1790   hb_position_t x_advance = 0, y_advance = 0;
1791   for (unsigned int i = start; i < end; i++)
1792   {
1793     pos[i].x_offset += x_advance;
1794     pos[i].y_offset += y_advance;
1795
1796     x_advance += pos[i].x_advance;
1797     y_advance += pos[i].y_advance;
1798
1799     pos[i].x_advance = 0;
1800     pos[i].y_advance = 0;
1801   }
1802
1803   if (backward)
1804   {
1805     /* Transfer all cluster advance to the last glyph. */
1806     pos[end - 1].x_advance = total_x_advance;
1807     pos[end - 1].y_advance = total_y_advance;
1808
1809     hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
1810   } else {
1811     /* Transfer all cluster advance to the first glyph. */
1812     pos[start].x_advance += total_x_advance;
1813     pos[start].y_advance += total_y_advance;
1814     for (unsigned int i = start + 1; i < end; i++) {
1815       pos[i].x_offset -= total_x_advance;
1816       pos[i].y_offset -= total_y_advance;
1817     }
1818     hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
1819   }
1820 }
1821
1822 /**
1823  * hb_buffer_normalize_glyphs:
1824  * @buffer: an #hb_buffer_t.
1825  *
1826  * Reorders a glyph buffer to have canonical in-cluster glyph order / position.
1827  * The resulting clusters should behave identical to pre-reordering clusters.
1828  *
1829  * <note>This has nothing to do with Unicode normalization.</note>
1830  *
1831  * Since: 0.9.2
1832  **/
1833 void
1834 hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
1835 {
1836   assert (buffer->have_positions);
1837   assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS ||
1838           (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
1839
1840   bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
1841
1842   foreach_cluster (buffer, start, end)
1843     normalize_glyphs_cluster (buffer, start, end, backward);
1844 }
1845
1846 void
1847 hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *))
1848 {
1849   assert (!have_positions);
1850   for (unsigned int i = start + 1; i < end; i++)
1851   {
1852     unsigned int j = i;
1853     while (j > start && compar (&info[j - 1], &info[i]) > 0)
1854       j--;
1855     if (i == j)
1856       continue;
1857     /* Move item i to occupy place for item j, shift what's in between. */
1858     merge_clusters (j, i + 1);
1859     {
1860       hb_glyph_info_t t = info[i];
1861       memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t));
1862       info[j] = t;
1863     }
1864   }
1865 }
1866
1867
1868 /*
1869  * Comparing buffers.
1870  */
1871
1872 /**
1873  * hb_buffer_diff:
1874  * @buffer: a buffer.
1875  * @reference: other buffer to compare to.
1876  * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
1877  * @position_fuzz: allowed absolute difference in position values.
1878  *
1879  * If dottedcircle_glyph is (hb_codepoint_t) -1 then %HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
1880  * and %HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT are never returned.  This should be used by most
1881  * callers if just comparing two buffers is needed.
1882  *
1883  * Since: 1.5.0
1884  **/
1885 hb_buffer_diff_flags_t
1886 hb_buffer_diff (hb_buffer_t *buffer,
1887                 hb_buffer_t *reference,
1888                 hb_codepoint_t dottedcircle_glyph,
1889                 unsigned int position_fuzz)
1890 {
1891   if (buffer->content_type != reference->content_type && buffer->len && reference->len)
1892     return HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH;
1893
1894   hb_buffer_diff_flags_t result = HB_BUFFER_DIFF_FLAG_EQUAL;
1895   bool contains = dottedcircle_glyph != (hb_codepoint_t) -1;
1896
1897   unsigned int count = reference->len;
1898
1899   if (buffer->len != count)
1900   {
1901     /*
1902      * we can't compare glyph-by-glyph, but we do want to know if there
1903      * are .notdef or dottedcircle glyphs present in the reference buffer
1904      */
1905     const hb_glyph_info_t *info = reference->info;
1906     unsigned int i;
1907     for (i = 0; i < count; i++)
1908     {
1909       if (contains && info[i].codepoint == dottedcircle_glyph)
1910         result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
1911       if (contains && info[i].codepoint == 0)
1912         result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
1913     }
1914     result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
1915     return hb_buffer_diff_flags_t (result);
1916   }
1917
1918   if (!count)
1919     return hb_buffer_diff_flags_t (result);
1920
1921   const hb_glyph_info_t *buf_info = buffer->info;
1922   const hb_glyph_info_t *ref_info = reference->info;
1923   for (unsigned int i = 0; i < count; i++)
1924   {
1925     if (buf_info->codepoint != ref_info->codepoint)
1926       result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH;
1927     if (buf_info->cluster != ref_info->cluster)
1928       result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH;
1929     if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED))
1930       result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH;
1931     if (contains && ref_info->codepoint == dottedcircle_glyph)
1932       result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
1933     if (contains && ref_info->codepoint == 0)
1934       result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
1935     buf_info++;
1936     ref_info++;
1937   }
1938
1939   if (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS)
1940   {
1941     assert (buffer->have_positions);
1942     const hb_glyph_position_t *buf_pos = buffer->pos;
1943     const hb_glyph_position_t *ref_pos = reference->pos;
1944     for (unsigned int i = 0; i < count; i++)
1945     {
1946       if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
1947           (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
1948           (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
1949           (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
1950       {
1951         result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
1952         break;
1953       }
1954       buf_pos++;
1955       ref_pos++;
1956     }
1957   }
1958
1959   return result;
1960 }
1961
1962
1963 /*
1964  * Debugging.
1965  */
1966
1967 #ifndef HB_NO_BUFFER_MESSAGE
1968 /**
1969  * hb_buffer_set_message_func:
1970  * @buffer: an #hb_buffer_t.
1971  * @func: (closure user_data) (destroy destroy) (scope notified):
1972  * @user_data:
1973  * @destroy:
1974  *
1975  *
1976  *
1977  * Since: 1.1.3
1978  **/
1979 void
1980 hb_buffer_set_message_func (hb_buffer_t *buffer,
1981                             hb_buffer_message_func_t func,
1982                             void *user_data, hb_destroy_func_t destroy)
1983 {
1984   if (buffer->message_destroy)
1985     buffer->message_destroy (buffer->message_data);
1986
1987   if (func) {
1988     buffer->message_func = func;
1989     buffer->message_data = user_data;
1990     buffer->message_destroy = destroy;
1991   } else {
1992     buffer->message_func = nullptr;
1993     buffer->message_data = nullptr;
1994     buffer->message_destroy = nullptr;
1995   }
1996 }
1997 bool
1998 hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
1999 {
2000   char buf[100];
2001   vsnprintf (buf, sizeof (buf), fmt, ap);
2002   return (bool) this->message_func (this, font, buf, this->message_data);
2003 }
2004 #endif