hb-buffer.cc revision c54599ad269380c7aa28d885fcfd660fc2c10a7b
1a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 1998-2004  David Turner and Werner Lemberg
32409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod * Copyright © 2011,2012  Google, Inc.
59f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod *
68f0d7e0c3fd4b05c43ac449be4f374dc2dc56127Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
79f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod *
8a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Permission is hereby granted, without written agreement and without
9a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
10a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * software and its documentation for any purpose, provided that the
11a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
12a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * all copies of this software.
13a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod *
14a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * DAMAGE.
19a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod *
20a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
21a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
23a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod *
26a2a9a023f6472ba262f89e5327318996b8258d25Behdad Esfahbod * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
27c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod * Google Author(s): Behdad Esfahbod
289f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod */
299f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod
3022da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-buffer-private.hh"
317f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod#include "hb-utf-private.hh"
329f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod
33f1322e52d557726baa010be8d35a594748e8fa1aBehdad Esfahbod
34a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#ifndef HB_DEBUG_BUFFER
35a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#define HB_DEBUG_BUFFER (HB_DEBUG+0)
36a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod#endif
37a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod
38a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod/* Here is how the buffer works internally:
39a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod *
40910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * There are two info pointers: info and out_info.  They always have
41910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * the same allocated size, but different lengths.
42a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod *
439d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As an optimization, both info and out_info may point to the
447e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod * same piece of memory, which is owned by info.  This remains the
45cc1a8a938b4c13e76b58825a9e1951c4134e634aBehdad Esfahbod * case as long as out_len doesn't exceed i at any time.
46468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * In that case, swap_buffers() is no-op and the glyph operations operate
47910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * mostly in-place.
48a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod *
499d5e26df0877aa5b187764ba09bd7bf221e92968Behdad Esfahbod * As soon as out_info gets longer than info, out_info is moved over
50910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * to an alternate buffer (which we reuse the pos buffer for!), and its
51910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * current contents (out_len entries) are copied to the new place.
52468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod * This should all remain transparent to the user.  swap_buffers() then
53910a33fe8457a8e13f7eb77fc92fa59c31f5e8fdBehdad Esfahbod * switches info and out_info.
54a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod */
55a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod
56c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod
57468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
58468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* Internal API */
59468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
60468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool
61468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::enlarge (unsigned int size)
623567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{
63468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (in_error))
640594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return false;
653567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
66468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  unsigned int new_allocated = allocated;
67e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod  hb_glyph_position_t *new_pos = NULL;
68e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod  hb_glyph_info_t *new_info = NULL;
69468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  bool separate_out = out_info != info;
703567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
71468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
72e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod    goto done;
733567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
7438b015e57ffa75d3b078a368c23685beb7c3f946Behdad Esfahbod  while (size >= new_allocated)
7565e0063eae2f3adb25315b8bd7b0e7757aa960f3Behdad Esfahbod    new_allocated += (new_allocated >> 1) + 32;
763567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
77468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
78468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
79e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod    goto done;
80e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod
81468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
82468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
833567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
84e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahboddone:
853567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod  if (unlikely (!new_pos || !new_info))
860594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    in_error = true;
873567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
883567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod  if (likely (new_pos))
89468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    pos = new_pos;
903567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
913567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod  if (likely (new_info))
92468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    info = new_info;
93468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
94468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_info = separate_out ? (hb_glyph_info_t *) pos : info;
95468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (likely (!in_error))
96468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    allocated = new_allocated;
97468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
98468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  return likely (!in_error);
99468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
100468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
101468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodbool
102468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::make_room_for (unsigned int num_in,
103468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod			    unsigned int num_out)
104468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
1050594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  if (unlikely (!ensure (out_len + num_out))) return false;
106468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
107468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (out_info == info &&
108468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      out_len + num_out > idx + num_in)
109468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  {
110468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    assert (have_output);
111468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
112468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    out_info = (hb_glyph_info_t *) pos;
113468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    memcpy (out_info, info, out_len * sizeof (out_info[0]));
114468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  }
115468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
1160594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return true;
117468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
118468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
119e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbodvoid *
120e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbodhb_buffer_t::get_scratch_buffer (unsigned int *size)
121e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod{
1220594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_output = false;
1230594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_positions = false;
12447ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod
125e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod  out_len = 0;
12647ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod  out_info = info;
12747ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod
128e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod  *size = allocated * sizeof (pos[0]);
129e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod  return pos;
130e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod}
131e62df43649e31b7815c272f01808b3f726c7d07dBehdad Esfahbod
132468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
13369cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod
134468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod/* HarfBuzz-Internal API */
135468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
136468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
137468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reset (void)
138468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
139468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (hb_object_is_inert (this)))
140468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
141468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
142468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  hb_unicode_funcs_destroy (unicode);
143d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod  unicode = hb_unicode_funcs_get_default ();
144468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
14582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  clear ();
14682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod}
14782ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
14882ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodvoid
14982ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodhb_buffer_t::clear (void)
15082ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod{
15182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  if (unlikely (hb_object_is_inert (this)))
15282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod    return;
15382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
154f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
155f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  props = default_props;
1560c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  flags = HB_BUFFER_FLAGS_DEFAULT;
157468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
15896fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod  content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
1590594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  in_error = false;
1600594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_output = false;
1610594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_positions = false;
1623567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
163468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  idx = 0;
164468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  len = 0;
165468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_len = 0;
16647ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod  out_info = info;
1673567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
168468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  serial = 0;
169f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod  memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
170f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod  memset (allocated_var_owner, 0, sizeof allocated_var_owner);
17105207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod
17205207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  memset (context, 0, sizeof context);
17305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  memset (context_len, 0, sizeof context_len);
1743567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod}
1753567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
176468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
177468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::add (hb_codepoint_t  codepoint,
178468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod		  unsigned int    cluster)
1793567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod{
180468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  hb_glyph_info_t *glyph;
181468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
182468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (!ensure (len + 1))) return;
183468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
184468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  glyph = &info[len];
185468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
186468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  memset (glyph, 0, sizeof (*glyph));
187468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  glyph->codepoint = codepoint;
18866ac2ff32e24f0d5658ca172147613081a133847Behdad Esfahbod  glyph->mask = 1;
189468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  glyph->cluster = cluster;
190468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
191468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  len++;
1923567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod}
1936b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod
194468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
1950bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbodhb_buffer_t::remove_output (void)
1960bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod{
1970bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod  if (unlikely (hb_object_is_inert (this)))
1980bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod    return;
1990bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod
2000bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod  have_output = false;
2010bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod  have_positions = false;
2020bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod
2030bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod  out_len = 0;
2040bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod  out_info = info;
2050bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod}
2060bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbod
2070bc7a38463bfb37f12efeb1b8cb2024cf4a347bcBehdad Esfahbodvoid
208468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_output (void)
209c968fc2dc87cf85b53f60a40db59d5ee7b992edfBehdad Esfahbod{
210468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (hb_object_is_inert (this)))
211468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
212468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
2130594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_output = true;
2140594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_positions = false;
215a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbod
216468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_len = 0;
217468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_info = info;
218468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
219468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
220468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
221468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::clear_positions (void)
222468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
223468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (hb_object_is_inert (this)))
224468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
225468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
2260594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_output = false;
2270594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_positions = true;
228468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
22947ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod  out_len = 0;
23047ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod  out_info = info;
23147ef931f13778b894090139a64238a5ab9ac1154Behdad Esfahbod
232468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  memset (pos, 0, sizeof (pos[0]) * len);
233468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
234468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
235468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
236468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::swap_buffers (void)
237468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
238468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (in_error)) return;
239468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
240468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  assert (have_output);
2410594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  have_output = false;
242468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
243468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (out_info != info)
244e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod  {
245468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    hb_glyph_info_t *tmp_string;
246468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    tmp_string = info;
247468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    info = out_info;
248468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    out_info = tmp_string;
249468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    pos = (hb_glyph_position_t *) out_info;
250468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  }
251468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
252468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  unsigned int tmp;
253468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  tmp = len;
254468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  len = out_len;
255468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_len = tmp;
256468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
257468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  idx = 0;
258468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
259e35bbd570a5d914f86f1ea83941ee4328f268059Behdad Esfahbod
26069cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod
261468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
2629ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbodhb_buffer_t::replace_glyphs (unsigned int num_in,
2639ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod			     unsigned int num_out,
2648e3715f8a16b315c1c7dd4b256e7f68a36c53e7cBehdad Esfahbod			     const uint32_t *glyph_data)
2659ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod{
26669cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod  if (unlikely (!make_room_for (num_in, num_out))) return;
2679ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod
268e88e14421a33ca5bdfd76bc0b2f801fcb6e78911Behdad Esfahbod  merge_clusters (idx, idx + num_in);
2699ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod
270e88e14421a33ca5bdfd76bc0b2f801fcb6e78911Behdad Esfahbod  hb_glyph_info_t orig_info = info[idx];
2719ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod  hb_glyph_info_t *pinfo = &out_info[out_len];
2729ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod  for (unsigned int i = 0; i < num_out; i++)
2739ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod  {
2749ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod    *pinfo = orig_info;
2759ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod    pinfo->codepoint = glyph_data[i];
2769ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod    pinfo++;
2779ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod  }
2789ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod
2799ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod  idx  += num_in;
2809ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod  out_len += num_out;
2819ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod}
2829ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbod
2839ebe8c0286856d46430ae184ba7303bd34485883Behdad Esfahbodvoid
284468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
285468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
28669cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod  if (unlikely (!make_room_for (0, 1))) return;
287468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
288468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_info[out_len] = info[idx];
289468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_info[out_len].codepoint = glyph_index;
290468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
291468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_len++;
292468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
293468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
294468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
295b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbodhb_buffer_t::output_info (hb_glyph_info_t &glyph_info)
296b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod{
297b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod  if (unlikely (!make_room_for (0, 1))) return;
298b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod
299b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod  out_info[out_len] = glyph_info;
300b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod
301b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod  out_len++;
302b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod}
303b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbod
304b85800f9de8976a7418ef9df467d3080c6ab0199Behdad Esfahbodvoid
305468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::copy_glyph (void)
306468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
30769cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod  if (unlikely (!make_room_for (0, 1))) return;
308468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
309468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_info[out_len] = info[idx];
310468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
311468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_len++;
312468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
313468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
314468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
315468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
316468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
31769cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod  if (unlikely (out_info != info || out_len != idx)) {
31869cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod    if (unlikely (!make_room_for (1, 1))) return;
31969cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod    out_info[out_len] = info[idx];
32069cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod  }
321468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_info[out_len].codepoint = glyph_index;
322468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
323468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  idx++;
324468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  out_len++;
325468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
326468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
32769cc492dc120847ed00cae65ec958593ebf550c5Behdad Esfahbod
328468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
329468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::set_masks (hb_mask_t    value,
330468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod			hb_mask_t    mask,
331468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod			unsigned int cluster_start,
332468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod			unsigned int cluster_end)
333468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
334468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  hb_mask_t not_mask = ~mask;
335468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  value &= mask;
336468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
337468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (!mask)
338468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
339468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
340468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
341468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    unsigned int count = len;
342468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    for (unsigned int i = 0; i < count; i++)
343468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      info[i].mask = (info[i].mask & not_mask) | value;
344468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
345468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  }
346468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
347468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  unsigned int count = len;
348468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  for (unsigned int i = 0; i < count; i++)
349468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
350468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      info[i].mask = (info[i].mask & not_mask) | value;
351468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
352468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
353468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
354468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_range (unsigned int start,
355468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod			    unsigned int end)
356468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
357468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  unsigned int i, j;
358468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
359468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (start == end - 1)
360468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
361468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
362468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  for (i = start, j = end - 1; i < j; i++, j--) {
363468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    hb_glyph_info_t t;
364468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
365468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    t = info[i];
366468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    info[i] = info[j];
367468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    info[j] = t;
368468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  }
369468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
370468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (pos) {
371468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    for (i = start, j = end - 1; i < j; i++, j--) {
372468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      hb_glyph_position_t t;
373468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
374468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      t = pos[i];
375468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      pos[i] = pos[j];
376468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      pos[j] = t;
377468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    }
378468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  }
379468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
380468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
381468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
382468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse (void)
383468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
384468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (!len))
385468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
386468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
387468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  reverse_range (0, len);
388468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod}
389468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
390468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodvoid
391468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbodhb_buffer_t::reverse_clusters (void)
392468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod{
393468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  unsigned int i, start, count, last_cluster;
394468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
395468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (unlikely (!len))
396468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    return;
397468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
398468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  reverse ();
399468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod
400468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  count = len;
401468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  start = 0;
402468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  last_cluster = info[0].cluster;
403468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  for (i = 1; i < count; i++) {
404468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    if (last_cluster != info[i].cluster) {
405468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      reverse_range (start, i);
406468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      start = i;
407468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod      last_cluster = info[i].cluster;
408468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    }
409468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  }
410468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  reverse_range (start, i);
411a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod}
412a8abb8b994c3cd89808e8f7128a0c04b23eb3edeBehdad Esfahbod
41302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodvoid
414d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodhb_buffer_t::merge_clusters (unsigned int start,
415d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod			     unsigned int end)
416d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod{
417fe3dabc08df7501010564f8844bd4d11771cc6a4Behdad Esfahbod  if (unlikely (end - start < 2))
418cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod    return;
419cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod
420cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod  unsigned int cluster = info[start].cluster;
421d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod
422d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod  for (unsigned int i = start + 1; i < end; i++)
423cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod    cluster = MIN (cluster, info[i].cluster);
424cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod
425cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod  /* Extend end */
426cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod  while (end < len && info[end - 1].cluster == info[end].cluster)
427cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod    end++;
428cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod
429cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod  /* Extend start */
430cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod  while (idx < start && info[start - 1].cluster == info[start].cluster)
431cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod    start--;
432cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod
433cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod  /* If we hit the start of buffer, continue in out-buffer. */
434cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod  if (idx == start)
435cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod    for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--)
436cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod      out_info[i - 1].cluster = cluster;
437cd5891493df06fdb92e1ae526d29dee8df250235Behdad Esfahbod
438d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod  for (unsigned int i = start; i < end; i++)
439cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod    info[i].cluster = cluster;
440d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod}
441d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodvoid
442d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodhb_buffer_t::merge_out_clusters (unsigned int start,
443d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod				 unsigned int end)
444d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod{
445fe3dabc08df7501010564f8844bd4d11771cc6a4Behdad Esfahbod  if (unlikely (end - start < 2))
44672c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod    return;
44772c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod
448cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod  unsigned int cluster = out_info[start].cluster;
449d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod
450d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod  for (unsigned int i = start + 1; i < end; i++)
451cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod    cluster = MIN (cluster, out_info[i].cluster);
45272c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod
45372c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod  /* Extend start */
45472c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod  while (start && out_info[start - 1].cluster == out_info[start].cluster)
45572c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod    start--;
45672c0a1878313e7232d554bc226f4c6dc01418a95Behdad Esfahbod
4575ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod  /* Extend end */
4585ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod  while (end < out_len && out_info[end - 1].cluster == out_info[end].cluster)
4595ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod    end++;
4605ced012d9f58c51d557a835593c3277e35fe3b35Behdad Esfahbod
461e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod  /* If we hit the end of out-buffer, continue in buffer. */
462e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod  if (end == out_len)
463e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod    for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++)
464e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod      info[i].cluster = cluster;
465e51d2b6ed1c794ac28c5610bfd01dbc9fb383633Behdad Esfahbod
466d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod  for (unsigned int i = start; i < end; i++)
467cafa6f372721fd6b0a7c0da68b9421d3e94931bcBehdad Esfahbod    out_info[i].cluster = cluster;
468d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod}
469d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbod
470d4cc44716c1e098f8abbc0e495404598026ef242Behdad Esfahbodvoid
47102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_buffer_t::guess_properties (void)
47202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod{
47396fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod  if (unlikely (!len)) return;
47496fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod  assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
47596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod
47602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  /* If script is set to INVALID, guess from buffer contents */
47702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  if (props.script == HB_SCRIPT_INVALID) {
47802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    for (unsigned int i = 0; i < len; i++) {
479208f70f0553d73d2908b21b9552298029482a8b9Behdad Esfahbod      hb_script_t script = unicode->script (info[i].codepoint);
48002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      if (likely (script != HB_SCRIPT_COMMON &&
48102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod		  script != HB_SCRIPT_INHERITED &&
48202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod		  script != HB_SCRIPT_UNKNOWN)) {
48302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod        props.script = script;
48402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod        break;
48502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      }
48602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    }
48702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  }
48802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
48902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  /* If direction is set to INVALID, guess from script */
49002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  if (props.direction == HB_DIRECTION_INVALID) {
49102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    props.direction = hb_script_get_horizontal_direction (props.script);
49202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  }
49302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
49402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  /* If language is not set, use default language from locale */
49502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  if (props.language == HB_LANGUAGE_INVALID) {
49602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    /* TODO get_default_for_script? using $LANGUAGE */
49702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    props.language = hb_language_get_default ();
49802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  }
49902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod}
50002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
50102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
502a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodstatic inline void
503a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahboddump_var_allocation (const hb_buffer_t *buffer)
504a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{
505a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  char buf[80];
506a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  for (unsigned int i = 0; i < 8; i++)
507b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod    buf[i] = '0' + buffer->allocated_var_bytes[7 - i];
508a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  buf[8] = '\0';
509a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  DEBUG_MSG (BUFFER, buffer,
510a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod	     "Current var allocation: %s",
511a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod	     buf);
512a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod}
5133567b87cce541dfb0af7caf024ec67c9d3c09214Behdad Esfahbod
514f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner)
515f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{
516b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod  assert (byte_i < 8 && byte_i + count <= 8);
517a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod
518a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  if (DEBUG (BUFFER))
519a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod    dump_var_allocation (this);
520a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  DEBUG_MSG (BUFFER, this,
521a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod	     "Allocating var bytes %d..%d for %s",
522a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod	     byte_i, byte_i + count - 1, owner);
523a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod
524f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod  for (unsigned int i = byte_i; i < byte_i + count; i++) {
525f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod    assert (!allocated_var_bytes[i]);
526f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod    allocated_var_bytes[i]++;
527f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod    allocated_var_owner[i] = owner;
528f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod  }
529f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod}
530f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod
531f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbodvoid hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner)
532f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod{
533b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod  if (DEBUG (BUFFER))
534b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod    dump_var_allocation (this);
535b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod
536a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  DEBUG_MSG (BUFFER, this,
537a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod	     "Deallocating var bytes %d..%d for %s",
538a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod	     byte_i, byte_i + count - 1, owner);
539a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod
540b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod  assert (byte_i < 8 && byte_i + count <= 8);
541f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod  for (unsigned int i = byte_i; i < byte_i + count; i++) {
542b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod    assert (allocated_var_bytes[i]);
543b65c06025d2b54a44f716e030d4b10072c65bea8Behdad Esfahbod    assert (0 == strcmp (allocated_var_owner[i], owner));
544f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod    allocated_var_bytes[i]--;
545f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod  }
546f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod}
547f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod
548965c280de09b49d711cb78d629da321c802084deBehdad Esfahbodvoid hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner)
549965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod{
550965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod  if (DEBUG (BUFFER))
551965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod    dump_var_allocation (this);
552965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod
553965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod  DEBUG_MSG (BUFFER, this,
554965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod	     "Asserting var bytes %d..%d for %s",
555965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod	     byte_i, byte_i + count - 1, owner);
556965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod
557965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod  assert (byte_i < 8 && byte_i + count <= 8);
558965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod  for (unsigned int i = byte_i; i < byte_i + count; i++) {
559965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod    assert (allocated_var_bytes[i]);
560965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod    assert (0 == strcmp (allocated_var_owner[i], owner));
561965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod  }
562965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod}
563965c280de09b49d711cb78d629da321c802084deBehdad Esfahbod
564a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbodvoid hb_buffer_t::deallocate_var_all (void)
565a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod{
566a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes));
567a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod  memset (allocated_var_owner, 0, sizeof (allocated_var_owner));
568a9ad3d3460ba863a8d8f3766ccbeab288c3c6822Behdad Esfahbod}
569f4a579bc42fb811ff5c391a0e97b7d8656ef59b1Behdad Esfahbod
5706b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod/* Public API */
5716b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod
572b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbodhb_buffer_t *
573c54599ad269380c7aa28d885fcfd660fc2c10a7bBehdad Esfahbodhb_buffer_create (void)
5749f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod{
575b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod  hb_buffer_t *buffer;
576b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod
57747e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!(buffer = hb_object_create<hb_buffer_t> ()))
578f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    return hb_buffer_get_empty ();
5799f8da38cd108590514b71756b752d98952a9221fBehdad Esfahbod
580468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  buffer->reset ();
5815ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
58211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod  return buffer;
58311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}
5847a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod
58511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_t *
58680a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_get_empty (void)
58780a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod{
588f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  static const hb_buffer_t _hb_buffer_nil = {
589f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    HB_OBJECT_HEADER_STATIC,
590f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
591d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod    const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
592f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    _HB_BUFFER_PROPS_DEFAULT,
5930c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod    HB_BUFFER_FLAGS_DEFAULT,
594f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
59596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod    HB_BUFFER_CONTENT_TYPE_INVALID,
5960594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    true, /* in_error */
5970594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    true, /* have_output */
5980594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    true  /* have_positions */
59905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod
60005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    /* Zero is good enough for everything else. */
601f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  };
602f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
603f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
60480a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod}
60580a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod
60680a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_buffer_t *
60711fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_reference (hb_buffer_t *buffer)
60811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{
60947e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  return hb_object_reference (buffer);
61011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}
611f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod
6127a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid
61311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_buffer_destroy (hb_buffer_t *buffer)
6147a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod{
61547e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!hb_object_destroy (buffer)) return;
61611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod
6175ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod  hb_unicode_funcs_destroy (buffer->unicode);
6185ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
6197e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod  free (buffer->info);
6201b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod  free (buffer->pos);
62111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod
622b857b49c82782d29d6d189f1a9f4a84d39cd84eaBehdad Esfahbod  free (buffer);
6237a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod}
6247a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod
6255fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t
6265fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_set_user_data (hb_buffer_t        *buffer,
6275fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			 hb_user_data_key_t *key,
6285fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			 void *              data,
62933ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod			 hb_destroy_func_t   destroy,
63033ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod			 hb_bool_t           replace)
6315fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
63233ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod  return hb_object_set_user_data (buffer, key, data, destroy, replace);
6335fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
6345fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
6355fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid *
6365fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_buffer_get_user_data (hb_buffer_t        *buffer,
6375fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			 hb_user_data_key_t *key)
6385fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
6395fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod  return hb_object_get_user_data (buffer, key);
6405fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
6415fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
6425ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
6435ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid
64496fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodhb_buffer_set_content_type (hb_buffer_t              *buffer,
64596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod			    hb_buffer_content_type_t  content_type)
64696fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod{
64796fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod  buffer->content_type = content_type;
64896fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod}
64996fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod
65096fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodhb_buffer_content_type_t
65196fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodhb_buffer_get_content_type (hb_buffer_t *buffer)
65296fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod{
65396fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod  return buffer->content_type;
65496fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod}
65596fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod
65696fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbod
65796fdc04e5c6daafce3d45e7508418e4db94df44cBehdad Esfahbodvoid
6585ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
6595ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod			     hb_unicode_funcs_t *unicode)
6605ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{
661e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
662e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod    return;
663e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod
6640465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod  if (!unicode)
665d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod    unicode = hb_unicode_funcs_get_default ();
666d5045a5f4017631a4660f985fe451c5a64c42ca0Behdad Esfahbod
6670465e69832393cc1ed36508ec5d597fbab64877aBehdad Esfahbod
6685ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod  hb_unicode_funcs_reference (unicode);
6695ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod  hb_unicode_funcs_destroy (buffer->unicode);
6705ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod  buffer->unicode = unicode;
6715ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod}
6725ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
6735ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_unicode_funcs_t *
6745ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_unicode_funcs (hb_buffer_t        *buffer)
6755ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{
6765ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod  return buffer->unicode;
6775ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod}
6785ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
6795ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodvoid
6805ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_set_direction (hb_buffer_t    *buffer,
6815ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod			 hb_direction_t  direction)
6825ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
6835ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{
684e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
685e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod    return;
686e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod
6874e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod  buffer->props.direction = direction;
6885ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod}
6895ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
6905ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_direction_t
6915ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbodhb_buffer_get_direction (hb_buffer_t    *buffer)
6925ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod{
6934e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod  return buffer->props.direction;
6945ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod}
6955ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
696ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid
697ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_script (hb_buffer_t *buffer,
698ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod		      hb_script_t  script)
699ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{
700e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
701e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod    return;
702e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod
7034e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod  buffer->props.script = script;
704ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod}
705ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod
706ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_script_t
707ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_script (hb_buffer_t *buffer)
708ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{
7094e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod  return buffer->props.script;
710ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod}
711ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod
712ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodvoid
713ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_set_language (hb_buffer_t   *buffer,
714ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod			hb_language_t  language)
715ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{
716e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
717e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod    return;
718e0db4b868f9fdd8e680890f87dd4e13a1c27b7a1Behdad Esfahbod
7194e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod  buffer->props.language = language;
720ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod}
721ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod
722ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_language_t
723ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbodhb_buffer_get_language (hb_buffer_t *buffer)
724ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod{
7254e4ef24e46f273ad2bdda2f718223e05b37dd50fBehdad Esfahbod  return buffer->props.language;
726ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod}
727ae070b7d39d03bd8bc1244f687b24db505f4af3fBehdad Esfahbod
7280c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodvoid
7290c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodhb_buffer_set_flags (hb_buffer_t       *buffer,
7300c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod		     hb_buffer_flags_t  flags)
7310c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod{
7320c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
7330c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod    return;
7340c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
7350c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  buffer->flags = flags;
7360c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod}
7370c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
7380c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodhb_buffer_flags_t
7390c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbodhb_buffer_get_flags (hb_buffer_t *buffer)
7400c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod{
7410c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod  return buffer->flags;
7420c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod}
7430c7df2222862122ebbdc8665a21d6771ef5e0252Behdad Esfahbod
7445ebabecef382c3e8b0a2a5657b2c01f7ff37d796Behdad Esfahbod
7457a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbodvoid
746c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_reset (hb_buffer_t *buffer)
747c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{
748468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  buffer->reset ();
7497a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod}
7507a26864308bd1ca8d5f47d798411cac7239b7d38Behdad Esfahbod
75182ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodvoid
75282ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbodhb_buffer_clear (hb_buffer_t *buffer)
75382ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod{
75482ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod  buffer->clear ();
75582ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod}
75682ecaff736e245e117d70b6ec1497508c6eb08d2Behdad Esfahbod
757a6a79df5fe2ed2cd307e7a991346faee164e70d9Behdad Esfahbodhb_bool_t
75802a534b23f2d1e7475109563b9f61221ed020e8bRyan Lortiehb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
759f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod{
760468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  return buffer->ensure (size);
761f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod}
762f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbod
763aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_bool_t
764aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbodhb_buffer_allocation_successful (hb_buffer_t  *buffer)
765aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod{
766aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod  return !buffer->in_error;
767aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod}
768aab0de50e23727b69fa8c3d4e05c50c114c62835Behdad Esfahbod
769f9cd1014f8f4d0394b5e0e9eefc1e2af13c59cabBehdad Esfahbodvoid
770f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbodhb_buffer_add (hb_buffer_t    *buffer,
771f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod	       hb_codepoint_t  codepoint,
772f85faee9b3cb841ea977403945e2c877ab32b97aBehdad Esfahbod	       unsigned int    cluster)
7736b347138b597c41af24453f630336ba2fc033dc5Behdad Esfahbod{
77466ac2ff32e24f0d5658ca172147613081a133847Behdad Esfahbod  buffer->add (codepoint, cluster);
77505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  buffer->clear_context (1);
7769111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod}
7779111b21ef99d5e53348176f683261b0101eb427fBehdad Esfahbod
778c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_bool_t
779c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbodhb_buffer_set_length (hb_buffer_t  *buffer,
780c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod		      unsigned int  length)
781c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod{
782e1ac38f8dd04c29d2d4140f5a492cdaf25d72901Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
783e1ac38f8dd04c29d2d4140f5a492cdaf25d72901Behdad Esfahbod    return length == 0;
784e1ac38f8dd04c29d2d4140f5a492cdaf25d72901Behdad Esfahbod
785468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  if (!buffer->ensure (length))
7860594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod    return false;
787c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod
788c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod  /* Wipe the new space */
789c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod  if (length > buffer->len) {
790c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod    memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
791c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod    if (buffer->have_positions)
792c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod      memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
793c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod  }
794c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod
795c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod  buffer->len = length;
79605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod
79705207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  if (!length)
79805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    buffer->clear_context (0);
79905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  buffer->clear_context (1);
80005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod
8010594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return true;
802c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod}
803c910bec863215f918c659f58debbc7fe5264d7b6Behdad Esfahbod
80411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodunsigned int
8053d14528b8b2e7da425a9df7057fc9fb326d8298cBehdad Esfahbodhb_buffer_get_length (hb_buffer_t *buffer)
80611fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{
8076960350be97f24e97140391025b56369c393a3dfBehdad Esfahbod  return buffer->len;
80811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}
80911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod
81011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */
81111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_info_t *
81270566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
81370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie                           unsigned int *length)
81411fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{
81570566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie  if (length)
81670566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie    *length = buffer->len;
81770566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie
8187e7007a1c9bf2c07a8369752126ece8fa6164248Behdad Esfahbod  return (hb_glyph_info_t *) buffer->info;
81911fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}
82011fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod
82111fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod/* Return value valid as long as buffer not modified */
82211fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbodhb_glyph_position_t *
82370566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortiehb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
82470566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie                               unsigned int *length)
82511fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod{
826314905d7548d5be58354546d660754b807b6efb2Behdad Esfahbod  if (!buffer->have_positions)
827468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod    buffer->clear_positions ();
82811fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod
82970566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie  if (length)
83070566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie    *length = buffer->len;
83170566befc59cfa8b9c43ac682749c40ea783b1ddRyan Lortie
8321b621823f3e31b48c80cc8b0691dfa873ba086cdBehdad Esfahbod  return (hb_glyph_position_t *) buffer->pos;
83311fbb5487d9900a019440ef8235f35c9f525decbBehdad Esfahbod}
834fbaf8ffa098bd2b6fb4f4bc2d04b360a319c4af5Behdad Esfahbod
835ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid
836ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse (hb_buffer_t *buffer)
837ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{
838468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  buffer->reverse ();
839ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod}
840ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod
841ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodvoid
842ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbodhb_buffer_reverse_clusters (hb_buffer_t *buffer)
843ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod{
844468e9cb25c9bc14781b7013e447d763f93bf76a3Behdad Esfahbod  buffer->reverse_clusters ();
845ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod}
846ff44f88df2c46920f3ec2384ef321a4c7bb0f6efBehdad Esfahbod
84702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodvoid
84802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_buffer_guess_properties (hb_buffer_t *buffer)
84902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod{
85002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  buffer->guess_properties ();
85102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod}
85202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
8537f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbodtemplate <typename T>
8547f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbodstatic inline void
8557f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbodhb_buffer_add_utf (hb_buffer_t  *buffer,
8567f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod		   const T      *text,
8577f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod		   int           text_length,
8587f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod		   unsigned int  item_offset,
8597f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod		   int           item_length)
8607f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod{
8617f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
8627f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod	  (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
8637f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod
8647f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  if (unlikely (hb_object_is_inert (buffer)))
8657f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod    return;
8667f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod
8671f66c3c1a0eb869c0d85a015235313177e0cec62Behdad Esfahbod  if (text_length == -1)
8681f66c3c1a0eb869c0d85a015235313177e0cec62Behdad Esfahbod    text_length = hb_utf_strlen (text);
8697f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod
8707f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  if (item_length == -1)
8717f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod    item_length = text_length - item_offset;
8727f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod
8737f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
8747f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod
875da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod  /* If buffer is empty and pre-context provided, install it.
876da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod   * This check is written this way, to make sure people can
877da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod   * provide pre-context in one add_utf() call, then provide
878da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod   * text in a follow-up call.  See:
879da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod   *
880da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod   * https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
881da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod   */
882da70111ab234e8b740ce6fb1789a1809fbec0c44Behdad Esfahbod  if (!buffer->len && item_offset > 0)
88305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  {
88405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    /* Add pre-context */
88505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    buffer->clear_context (0);
88605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    const T *prev = text + item_offset;
88705207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    const T *start = text;
88805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
88905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    {
89005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod      hb_codepoint_t u;
89105207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod      prev = hb_utf_prev (prev, start, &u);
89205207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod      buffer->context[0][buffer->context_len[0]++] = u;
89305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    }
89405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  }
89505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod
89605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  const T *next = text + item_offset;
8977f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  const T *end = next + item_length;
89805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  while (next < end)
89905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  {
9007f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod    hb_codepoint_t u;
9017f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod    const T *old_next = next;
9027f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod    next = hb_utf_next (next, end, &u);
90366ac2ff32e24f0d5658ca172147613081a133847Behdad Esfahbod    buffer->add (u, old_next - (const T *) text);
90405207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  }
90505207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod
90605207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  /* Add post-context */
90705207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  buffer->clear_context (1);
90805207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  end = text + text_length;
90905207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
91005207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod  {
91105207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    hb_codepoint_t u;
91205207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    next = hb_utf_next (next, end, &u);
91305207a79e0ae1769c5feaebe3fd99bdf9cfcf834Behdad Esfahbod    buffer->context[1][buffer->context_len[1]++] = u;
9147f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  }
9157f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod
9167f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
917299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod}
918299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod
919299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid
920299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf8 (hb_buffer_t  *buffer,
921299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod		    const char   *text,
922944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod		    int           text_length,
923299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod		    unsigned int  item_offset,
924944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod		    int           item_length)
925299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{
9267f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
927299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod}
928299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod
929299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid
930299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf16 (hb_buffer_t    *buffer,
931299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod		     const uint16_t *text,
932944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod		     int             text_length,
933299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod		     unsigned int    item_offset,
934944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod		     int            item_length)
935299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{
9367f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
9370e0a4da9b7677a09e00d27313236e1f333864dd6Behdad Esfahbod}
9380e0a4da9b7677a09e00d27313236e1f333864dd6Behdad Esfahbod
939299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodvoid
940299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbodhb_buffer_add_utf32 (hb_buffer_t    *buffer,
941299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod		     const uint32_t *text,
942944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod		     int             text_length,
943299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod		     unsigned int    item_offset,
944944b2ba1ce076385f985212bbdf2df96a8a995f0Behdad Esfahbod		     int             item_length)
945299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod{
9467f19ae7b9f806a2e35206b2ad41651c5f80b2537Behdad Esfahbod  hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
947299f08961ffcea27e8def4f0743d0c86ef8dadf1Behdad Esfahbod}
948acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
949acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
95039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodstatic int
95139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodcompare_info_codepoint (const hb_glyph_info_t *pa,
95239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod			const hb_glyph_info_t *pb)
95339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{
95439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  return (int) pb->codepoint - (int) pa->codepoint;
95539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod}
95639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
95739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodstatic inline void
95839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodnormalize_glyphs_cluster (hb_buffer_t *buffer,
95939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod			  unsigned int start,
96039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod			  unsigned int end,
96139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod			  bool backward)
96239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{
96339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  hb_glyph_position_t *pos = buffer->pos;
96439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
96539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  /* Total cluster advance */
96639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  hb_position_t total_x_advance = 0, total_y_advance = 0;
96739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  for (unsigned int i = start; i < end; i++)
96839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  {
96939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    total_x_advance += pos[i].x_advance;
97039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    total_y_advance += pos[i].y_advance;
97139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  }
97239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
97339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  hb_position_t x_advance = 0, y_advance = 0;
97439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  for (unsigned int i = start; i < end; i++)
97539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  {
97639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[i].x_offset += x_advance;
97739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[i].y_offset += y_advance;
97839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
97939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    x_advance += pos[i].x_advance;
98039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    y_advance += pos[i].y_advance;
98139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
98239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[i].x_advance = 0;
98339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[i].y_advance = 0;
98439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  }
98539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
98639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  if (backward)
98739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  {
98839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    /* Transfer all cluster advance to the last glyph. */
98939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[end - 1].x_advance = total_x_advance;
99039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[end - 1].y_advance = total_y_advance;
99139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
99239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
99339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  } else {
99439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    /* Transfer all cluster advance to the first glyph. */
99539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[start].x_advance += total_x_advance;
99639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    pos[start].y_advance += total_y_advance;
99739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    for (unsigned int i = start + 1; i < end; i++) {
99839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod      pos[i].x_offset -= total_x_advance;
99939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod      pos[i].y_offset -= total_y_advance;
100039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    }
100139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
100239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  }
100339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod}
100439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
100539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodvoid
100639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbodhb_buffer_normalize_glyphs (hb_buffer_t *buffer)
100739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod{
100839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  assert (buffer->have_positions);
10097d37280600c157f3c4eae8746e99511702a58e8fBehdad Esfahbod  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
101039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
101139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
101239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
101339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  unsigned int count = buffer->len;
101439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  if (unlikely (!count)) return;
101539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  hb_glyph_info_t *info = buffer->info;
101639b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod
101739b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  unsigned int start = 0;
101839b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  unsigned int end;
101939b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  for (end = start + 1; end < count; end++)
102039b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    if (info[start].cluster != info[end].cluster) {
102139b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod      normalize_glyphs_cluster (buffer, start, end, backward);
102239b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod      start = end;
102339b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod    }
102439b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod  normalize_glyphs_cluster (buffer, start, end, backward);
102539b17837b4064d59c18cebb49c1c0b5b8cc0c117Behdad Esfahbod}
1026f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1027f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1028f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod/*
1029f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod * Serialize
1030f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod */
1031f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1032f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodstatic const char *serialize_formats[] = {
1033f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  "TEXT",
1034f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  "JSON",
1035f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  NULL
1036f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod};
1037f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1038072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbodconst char **
1039072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbodhb_buffer_serialize_list_formats (void)
1040072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod{
1041072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod  return serialize_formats;
1042072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod}
1043072ae7a982bf640804eee0b41525e7c328806bf5Behdad Esfahbod
1044f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_format_t
1045f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_format_from_string (const char *str, int len)
1046f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{
1047f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  /* Upper-case it. */
1048f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
1049f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}
1050f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1051f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodconst char *
1052f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
1053f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{
1054f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  switch (format)
1055f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  {
1056f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    case HB_BUFFER_SERIALIZE_FORMAT_TEXT:	return serialize_formats[0];
1057f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    case HB_BUFFER_SERIALIZE_FORMAT_JSON:	return serialize_formats[1];
1058f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    default:
1059f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    case HB_BUFFER_SERIALIZE_FORMAT_INVALID:	return NULL;
1060f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  }
1061f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}
1062f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1063f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodstatic unsigned int
1064f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
1065f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int start,
1066f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int end,
1067f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  char *buf,
1068f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int buf_size,
1069f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int *buf_consumed,
1070f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  hb_font_t *font,
1071f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  hb_buffer_serialize_flags_t flags)
1072f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{
1073f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
1074f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
1075f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1076f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  *buf_consumed = 0;
1077f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  for (unsigned int i = start; i < end; i++)
1078f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  {
1079f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    char b[1024];
1080f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    char *p = b;
1081f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1082f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    /* In the following code, we know b is large enough that no overflow can happen. */
1083f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1084f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
1085f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1086f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (i)
1087f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *p++ = ',';
1088f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1089f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    *p++ = '{';
1090f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1091f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    APPEND ("\"g\":");
1092f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
1093f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    {
1094f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      char g[128];
1095f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
1096f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *p++ = '"';
1097f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      for (char *q = g; *q; q++) {
1098f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod        if (*q == '"')
1099f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod	  *p++ = '\\';
1100f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod	*p++ = *q;
1101f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      }
1102f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *p++ = '"';
1103f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    }
1104f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    else
1105f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint);
1106f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1107f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
1108f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster);
1109f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    }
1110f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1111f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
1112f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    {
1113f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
1114f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod		     pos[i].x_offset, pos[i].y_offset);
1115f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
1116f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod		     pos[i].x_advance, pos[i].y_advance);
1117f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    }
1118f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1119f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    *p++ = '}';
1120f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1121f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (buf_size > (p - b))
1122f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    {
1123f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      unsigned int l = p - b;
1124f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      memcpy (buf, b, l);
1125f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      buf += l;
1126f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      buf_size -= l;
1127f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *buf_consumed += l;
1128f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *buf = '\0';
1129f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    } else
1130f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      return i - start;
1131f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  }
1132f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1133f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  return end - start;
1134f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}
1135f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1136f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodstatic unsigned int
1137f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
1138f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int start,
1139f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int end,
1140f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  char *buf,
1141f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int buf_size,
1142f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  unsigned int *buf_consumed,
1143f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  hb_font_t *font,
1144f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod				  hb_buffer_serialize_flags_t flags)
1145f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{
1146f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
1147f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
1148f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  hb_direction_t direction = hb_buffer_get_direction (buffer);
1149f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1150f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  *buf_consumed = 0;
1151f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  for (unsigned int i = start; i < end; i++)
1152f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  {
1153f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    char b[1024];
1154f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    char *p = b;
1155f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1156f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    /* In the following code, we know b is large enough that no overflow can happen. */
1157f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1158f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (i)
1159f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *p++ = '|';
1160f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1161f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
1162f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    {
1163f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
1164f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += strlen (p);
1165f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    }
1166f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    else
1167f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint);
1168f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1169f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
1170f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster);
1171f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    }
1172f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1173f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
1174f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    {
1175f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      if (pos[i].x_offset || pos[i].y_offset)
1176f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod	p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset);
1177f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1178f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *p++ = '+';
1179f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      if (HB_DIRECTION_IS_HORIZONTAL (direction) || pos[i].x_advance)
1180f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod	p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance);
1181f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      if (HB_DIRECTION_IS_VERTICAL (direction) || pos->y_advance)
1182f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod	p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance);
1183f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    }
1184f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1185f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    if (buf_size > (p - b))
1186f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    {
1187f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      unsigned int l = p - b;
1188f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      memcpy (buf, b, l);
1189f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      buf += l;
1190f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      buf_size -= l;
1191f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *buf_consumed += l;
1192f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      *buf = '\0';
1193f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    } else
1194f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      return i - start;
1195f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  }
1196f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1197f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  return end - start;
1198f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}
1199f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1200f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod/* Returns number of items, starting at start, that were serialized. */
1201f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodunsigned int
1202f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_serialize_glyphs (hb_buffer_t *buffer,
1203f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    unsigned int start,
1204f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    unsigned int end,
1205f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    char *buf,
1206f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    unsigned int buf_size,
1207f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    unsigned int *buf_consumed,
1208f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    hb_font_t *font, /* May be NULL */
1209f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    hb_buffer_serialize_format_t format,
1210f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			    hb_buffer_serialize_flags_t flags)
1211f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{
1212f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  assert (start <= end && end <= buffer->len);
1213f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1214f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  *buf_consumed = 0;
1215f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1216f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
1217f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod	  buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
1218f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1219f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  if (unlikely (start == end))
1220f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    return 0;
1221f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1222f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  if (!font)
1223f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    font = hb_font_get_empty ();
1224f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1225f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  switch (format)
1226f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  {
1227f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
1228f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      return _hb_buffer_serialize_glyphs_text (buffer, start, end,
1229f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod					       buf, buf_size, buf_consumed,
1230f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod					       font, flags);
1231f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1232f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    case HB_BUFFER_SERIALIZE_FORMAT_JSON:
1233f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      return _hb_buffer_serialize_glyphs_json (buffer, start, end,
1234f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod					       buf, buf_size, buf_consumed,
1235f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod					       font, flags);
1236f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1237f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    default:
1238f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod    case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
1239f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod      return 0;
1240f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1241f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  }
1242f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}
1243f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod
1244f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_bool_t
1245f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbodhb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
1246f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			      const char *buf,
1247f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			      unsigned int buf_len,
1248f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			      unsigned int *buf_consumed,
1249f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			      hb_font_t *font, /* May be NULL */
1250f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod			      hb_buffer_serialize_format_t format)
1251f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod{
1252f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod  return false;
1253f9edf1672511c3bcc3796cc79578ffea43b2bda1Behdad Esfahbod}
1254