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