hb-buffer.cc revision 0594a2448440208efa0acac9a5d8d52d43108289
18e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner/*
28e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * Copyright © 1998-2004  David Turner and Werner Lemberg
38e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
48e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * Copyright © 2011  Google, Inc.
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner *
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner *  This is part of HarfBuzz, a text shaping library.
78e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner *
88e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * Permission is hereby granted, without written agreement and without
98e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * license or royalty fees, to use, copy, modify, and distribute this
108e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * software and its documentation for any purpose, provided that the
118e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * above copyright notice and the following two paragraphs appear in
128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * all copies of this software.
138e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner *
148e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17ff6c91efcf62d1cb99343fdcb2de6271520a1981Owen Anderson * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18d1e1703c39742f3c9fc3d27a442ff59bbdbfb5aaBenjamin Kramer * DAMAGE.
19d1e1703c39742f3c9fc3d27a442ff59bbdbfb5aaBenjamin Kramer *
20c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
218e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22d185f64f828ce1f8b476807a4a1345c0c53d8213Chris Lattner * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
2392bcb426c3e4503c99324afd4ed0a73521711a56Chris Lattner * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25bcef7df6ec9aba7c5009a4d33944f80227563665Duncan Sands *
26a896176973d59d8e22514b363d31e8d1becf185eChris Lattner * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
275679d18c54ef46170e46f51bf471bb334f2b6525Misha Brukman * Google Author(s): Behdad Esfahbod
288e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner */
298e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
30d1e1703c39742f3c9fc3d27a442ff59bbdbfb5aaBenjamin Kramer#include "hb-buffer-private.hh"
31eeb4a84ac8d91fb1d5a7c484a1c7047409faee30Chris Lattner
32df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner#include <string.h>
33df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
34df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
358e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
368e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#ifndef HB_DEBUG_BUFFER
378e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#define HB_DEBUG_BUFFER (HB_DEBUG+0)
388e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#endif
398e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
408e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT (const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_default))
418e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
428e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
43df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner/* Here is how the buffer works internally:
448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner *
458e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * There are two info pointers: info and out_info.  They always have
468e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * the same allocated size, but different lengths.
478e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner *
488e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * As an optimization, both info and out_info may point to the
498e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * same piece of memory, which is owned by info.  This remains the
50df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner * case as long as out_len doesn't exceed i at any time.
518e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * In that case, swap_buffers() is no-op and the glyph operations operate
528e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * mostly in-place.
538e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner *
548e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * As soon as out_info gets longer than info, out_info is moved over
558e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * to an alternate buffer (which we reuse the pos buffer for!), and its
568e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * current contents (out_len entries) are copied to the new place.
57df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner * This should all remain transparent to the user.  swap_buffers() then
588e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner * switches info and out_info.
598e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner */
608e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
618e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
628e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
638e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner/* Internal API */
648e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
658e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerbool
668e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::enlarge (unsigned int size)
678e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
688e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (in_error))
692c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    return false;
708e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
71df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  unsigned int new_allocated = allocated;
728e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_glyph_position_t *new_pos = NULL;
738e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_glyph_info_t *new_info = NULL;
748e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  bool separate_out = out_info != info;
758e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
768e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (_hb_unsigned_int_mul_overflows (size, sizeof (info[0]))))
778e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    goto done;
78df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
79df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  while (size > new_allocated)
808e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    new_allocated += (new_allocated >> 1) + 32;
818e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
828e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
838e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (_hb_unsigned_int_mul_overflows (new_allocated, sizeof (info[0]))))
848e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    goto done;
858e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
868e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  new_pos = (hb_glyph_position_t *) realloc (pos, new_allocated * sizeof (pos[0]));
878e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  new_info = (hb_glyph_info_t *) realloc (info, new_allocated * sizeof (info[0]));
888e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
898e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerdone:
908e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (!new_pos || !new_info))
918e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    in_error = true;
928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
938e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (likely (new_pos))
948e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    pos = new_pos;
958e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
968e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (likely (new_info))
978e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    info = new_info;
988e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
998e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info = separate_out ? (hb_glyph_info_t *) pos : info;
1008e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (likely (!in_error))
1018e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    allocated = new_allocated;
1028e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
103d343c6b70ec03b357d42e47ce7c00b3c3cb78efdChris Lattner  return likely (!in_error);
104df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
1058e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1068e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerbool
1071b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesenhb_buffer_t::make_room_for (unsigned int num_in,
1081b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen			    unsigned int num_out)
1091b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen{
1101b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  if (unlikely (!ensure (out_len + num_out))) return false;
1111b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1121b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  if (out_info == info &&
1131b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen      out_len + num_out > idx + num_in)
1141b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  {
1151b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen    assert (have_output);
1161b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1171b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen    out_info = (hb_glyph_info_t *) pos;
1181b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen    memcpy (out_info, info, out_len * sizeof (out_info[0]));
1191b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  }
1201b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1211b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  return true;
1221b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen}
1231b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1241b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesenvoid *
1251b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesenhb_buffer_t::get_scratch_buffer (unsigned int *size)
1261b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen{
1271b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  have_output = false;
1281b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  have_positions = false;
1291b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  out_len = 0;
1301b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  *size = allocated * sizeof (pos[0]);
1311b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  return pos;
1321b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen}
1331b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1341b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1351b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen/* HarfBuzz-Internal API */
1361b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen
1371b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesenvoid
1388e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::reset (void)
1398e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
1408e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (hb_object_is_inert (this)))
1418e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    return;
1422c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
1438e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_unicode_funcs_destroy (unicode);
1448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
1458e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1468e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
1478e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  props = default_props;
1488e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1498e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  in_error = false;
1508e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  have_output = false;
1518e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  have_positions = false;
1528e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1538e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  idx = 0;
1548e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  len = 0;
1558e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_len = 0;
1568e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1578e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  serial = 0;
1588e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
1598e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  memset (allocated_var_owner, 0, sizeof allocated_var_owner);
1608e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1618e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info = info;
1628e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
1638e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1648e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
1658e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::add (hb_codepoint_t  codepoint,
1668e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		  hb_mask_t       mask,
1678e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		  unsigned int    cluster)
1688e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
1698e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_glyph_info_t *glyph;
1708e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1718e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (!ensure (len + 1))) return;
1728e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1738e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  glyph = &info[len];
1748e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1758e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  memset (glyph, 0, sizeof (*glyph));
1768e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  glyph->codepoint = codepoint;
1778e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  glyph->mask = mask;
1788e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  glyph->cluster = cluster;
1798e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1808e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  len++;
1818e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
1828e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1838e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
1848e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::clear_output (void)
1858e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
1868e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (hb_object_is_inert (this)))
187ff6c91efcf62d1cb99343fdcb2de6271520a1981Owen Anderson    return;
188ff6c91efcf62d1cb99343fdcb2de6271520a1981Owen Anderson
189ff6c91efcf62d1cb99343fdcb2de6271520a1981Owen Anderson  have_output = true;
1908e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  have_positions = false;
1918e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_len = 0;
1938e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info = info;
1948e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
1958e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
1968e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
1978e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::clear_positions (void)
1988e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
1998e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (hb_object_is_inert (this)))
2008e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    return;
2018e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2028e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  have_output = false;
2038e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  have_positions = true;
2048e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2058e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  memset (pos, 0, sizeof (pos[0]) * len);
2062c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling}
2078e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2082c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlingvoid
2098e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::swap_buffers (void)
2102c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling{
2118e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (in_error)) return;
2128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2138e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  assert (have_output);
214df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  have_output = false;
2158e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2162c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  if (out_info != info)
2178e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  {
2188e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    hb_glyph_info_t *tmp_string;
2198e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    tmp_string = info;
2208e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    info = out_info;
2218e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    out_info = tmp_string;
2228e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    pos = (hb_glyph_position_t *) out_info;
2232c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  }
224df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
225df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  unsigned int tmp;
2268e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  tmp = len;
2278e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  len = out_len;
2288e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_len = tmp;
2298e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2308e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  idx = 0;
2318e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
2328e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2338e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
2348e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::replace_glyphs_be16 (unsigned int num_in,
2358e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner				  unsigned int num_out,
2368e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner				  const uint16_t *glyph_data_be)
2378e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
2388e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (!make_room_for (num_in, num_out)) return;
2398e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
240df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  hb_glyph_info_t orig_info = info[idx];
241df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  for (unsigned int i = 1; i < num_in; i++)
2428e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  {
2438e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    hb_glyph_info_t *inf = &info[idx + i];
2448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    orig_info.cluster = MIN (orig_info.cluster, inf->cluster);
245df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  }
2468e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
247df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  hb_glyph_info_t *pinfo = &out_info[out_len];
2488e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  for (unsigned int i = 0; i < num_out; i++)
2498e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  {
2508e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    *pinfo = orig_info;
251df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    pinfo->codepoint = hb_be_uint16 (glyph_data_be[i]);
252df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    pinfo++;
2538e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
254df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
2558e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  idx  += num_in;
2568e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_len += num_out;
2578e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
258e434d277ca5183eeb6f881000732dcf4c8edd52eChris Lattner
2598e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
2608e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::replace_glyphs (unsigned int num_in,
2612c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling			     unsigned int num_out,
2628e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner			     const uint32_t *glyph_data)
263df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
264df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (!make_room_for (num_in, num_out)) return;
265df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
266df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  hb_glyph_info_t orig_info = info[idx];
267df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  for (unsigned int i = 1; i < num_in; i++)
268df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  {
269df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    hb_glyph_info_t *inf = &info[idx + i];
270df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    orig_info.cluster = MIN (orig_info.cluster, inf->cluster);
271df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  }
272df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
273df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  hb_glyph_info_t *pinfo = &out_info[out_len];
274df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  for (unsigned int i = 0; i < num_out; i++)
2758e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  {
2768e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    *pinfo = orig_info;
2778e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    pinfo->codepoint = glyph_data[i];
2788e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    pinfo++;
2798e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
2808e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2818e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  idx  += num_in;
2828e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_len += num_out;
2838e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
2848e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2858e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
286df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_t::output_glyph (hb_codepoint_t glyph_index)
287df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
288df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (!make_room_for (0, 1)) return;
289df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
2908e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info[out_len] = info[idx];
2918e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info[out_len].codepoint = glyph_index;
2928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2932c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  out_len++;
2948e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
2958e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
2962c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlingvoid
2972c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlinghb_buffer_t::copy_glyph (void)
298df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
299df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (!make_room_for (0, 1)) return;
3008e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3018e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info[out_len] = info[idx];
302df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
303df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  out_len++;
304df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
3058e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3068e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
3078e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
3082c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling{
3098e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (!make_room_for (1, 1)) return;
3102c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
3118e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info[out_len] = info[idx];
3128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_info[out_len].codepoint = glyph_index;
3132c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
3148e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  idx++;
3158e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  out_len++;
3168e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
317df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
318df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid
3198e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::next_glyph (void)
3202c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling{
3218e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (have_output)
3228e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  {
3232c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    if (out_info != info)
3242c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    {
3252c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling      if (unlikely (!ensure (out_len + 1))) return;
3268e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      out_info[out_len] = info[idx];
3278e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    }
328df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    else if (out_len != idx)
329df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner      out_info[out_len] = info[idx];
330df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
3318e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    out_len++;
3322c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  }
333df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
3348e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  idx++;
3358e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
3368e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3378e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
338df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_t::set_masks (hb_mask_t    value,
339df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			hb_mask_t    mask,
340df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			unsigned int cluster_start,
341df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			unsigned int cluster_end)
342df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
3438e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_mask_t not_mask = ~mask;
3448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  value &= mask;
3452c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
3468e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (!mask)
3478e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    return;
3482c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
3492c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
350df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    unsigned int count = len;
351df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    for (unsigned int i = 0; i < count; i++)
3528e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      info[i].mask = (info[i].mask & not_mask) | value;
3538e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    return;
354df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  }
355df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
356df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  unsigned int count = len;
3578e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  for (unsigned int i = 0; i < count; i++)
3588e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
3598e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      info[i].mask = (info[i].mask & not_mask) | value;
3602c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling}
3618e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3622c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlingvoid
3638e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::reverse_range (unsigned int start,
3648e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner			    unsigned int end)
3652c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling{
3668e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  unsigned int i, j;
3678e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3682c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  if (start == end - 1)
369df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    return;
370df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
3718e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  for (i = start, j = end - 1; i < j; i++, j--) {
3722c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    hb_glyph_info_t t;
3738e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3748e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    t = info[i];
3752c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    info[i] = info[j];
3762c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    info[j] = t;
3772c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  }
3788e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3798e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (pos) {
380df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    for (i = start, j = end - 1; i < j; i++, j--) {
381df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner      hb_glyph_position_t t;
382df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
3838e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      t = pos[i];
3842c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling      pos[i] = pos[j];
385df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner      pos[j] = t;
3868e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    }
3878e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
3888e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
3898e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3908e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
391df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_t::reverse (void)
3928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
3938e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (!len))
3942c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    return;
3952c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
396df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  reverse_range (0, len);
397df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
3988e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
3992c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlingvoid
4008e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::reverse_clusters (void)
4018e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
4028e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  unsigned int i, start, count, last_cluster;
403df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
404df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (unlikely (!len))
405df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    return;
4068e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
4072c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  reverse ();
4088e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
409df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  count = len;
410df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  start = 0;
411df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  last_cluster = info[0].cluster;
4128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  for (i = 1; i < count; i++) {
4138e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    if (last_cluster != info[i].cluster) {
4148e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      reverse_range (start, i);
4158e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      start = i;
4168e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      last_cluster = info[i].cluster;
4178e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    }
4188e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
4198e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  reverse_range (start, i);
4208e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
4218e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
4228e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
4238e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::merge_clusters (unsigned int start,
4248e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner			     unsigned int end)
4258e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
426e434d277ca5183eeb6f881000732dcf4c8edd52eChris Lattner  unsigned int cluster = this->info[start].cluster;
427eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel
4281d92831759620a2e5ce4f5a3088c0a1a77a48c8fChris Lattner  for (unsigned int i = start + 1; i < end; i++)
429e434d277ca5183eeb6f881000732dcf4c8edd52eChris Lattner    cluster = MIN (cluster, this->info[i].cluster);
4301d92831759620a2e5ce4f5a3088c0a1a77a48c8fChris Lattner  for (unsigned int i = start; i < end; i++)
431eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel    this->info[i].cluster = cluster;
432eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel}
433eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patelvoid
434eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patelhb_buffer_t::merge_out_clusters (unsigned int start,
435eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel				 unsigned int end)
4368e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
437eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel  unsigned int cluster = this->out_info[start].cluster;
4381d92831759620a2e5ce4f5a3088c0a1a77a48c8fChris Lattner
439eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel  for (unsigned int i = start + 1; i < end; i++)
440e434d277ca5183eeb6f881000732dcf4c8edd52eChris Lattner    cluster = MIN (cluster, this->out_info[i].cluster);
441eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel  for (unsigned int i = start; i < end; i++)
442eff2ab61b5d411fe64ba601d402b7c549644b590Devang Patel    this->out_info[i].cluster = cluster;
4438e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
4448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
4458e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
4468e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_t::guess_properties (void)
4478e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
448df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  /* If script is set to INVALID, guess from buffer contents */
4498e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (props.script == HB_SCRIPT_INVALID) {
4508e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    for (unsigned int i = 0; i < len; i++) {
4518e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      hb_script_t script = hb_unicode_script (unicode, info[i].codepoint);
4522c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling      if (likely (script != HB_SCRIPT_COMMON &&
4538e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		  script != HB_SCRIPT_INHERITED &&
4548e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		  script != HB_SCRIPT_UNKNOWN)) {
4558e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner        props.script = script;
4568e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner        break;
4578e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      }
4582c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    }
4598e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
4608e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
461df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  /* If direction is set to INVALID, guess from script */
462df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (props.direction == HB_DIRECTION_INVALID) {
4638e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    props.direction = hb_script_get_horizontal_direction (props.script);
4642c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  }
4658e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
4668e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  /* If language is not set, use default language from locale */
4678e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (props.language == HB_LANGUAGE_INVALID) {
4688e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    /* TODO get_default_for_script? using $LANGUAGE */
4698e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    props.language = hb_language_get_default ();
4708e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
4712c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling}
4728e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
473df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
474df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerstatic inline void
4758e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerdump_var_allocation (const hb_buffer_t *buffer)
4761d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson{
477df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  char buf[80];
4788e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  for (unsigned int i = 0; i < 8; i++)
4792c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    buf[i] = '0' + buffer->allocated_var_bytes[7 - i];
4808e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  buf[8] = '\0';
4818e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  DEBUG_MSG (BUFFER, buffer,
4828e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	     "Current var allocation: %s",
4838e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	     buf);
4848e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
485df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
486df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner)
487df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
488df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  assert (byte_i < 8 && byte_i + count <= 8);
489df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
490df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (DEBUG (BUFFER))
491df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    dump_var_allocation (this);
492df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  DEBUG_MSG (BUFFER, this,
493df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	     "Allocating var bytes %d..%d for %s",
494bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola	     byte_i, byte_i + count - 1, owner);
4953d10a5a75794356a0a568ce283713adc3a963200Bill Wendling
4965e721d768254a920b78b9129d79a84c0163cb3f4Bill Wendling  for (unsigned int i = byte_i; i < byte_i + count; i++) {
49755ae515f9db484125a23429d4906c5edaf9f10d2Bill Wendling    assert (!allocated_var_bytes[i]);
498df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    allocated_var_bytes[i]++;
499266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner    allocated_var_owner[i] = owner;
500df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  }
501667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands}
502df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
503667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sandsvoid hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner)
504df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
505df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (DEBUG (BUFFER))
506df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    dump_var_allocation (this);
507df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
508df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  DEBUG_MSG (BUFFER, this,
509df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	     "Deallocating var bytes %d..%d for %s",
510df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	     byte_i, byte_i + count - 1, owner);
511df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
512df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  assert (byte_i < 8 && byte_i + count <= 8);
513df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  for (unsigned int i = byte_i; i < byte_i + count; i++) {
514df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    assert (allocated_var_bytes[i]);
515df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    assert (0 == strcmp (allocated_var_owner[i], owner));
516df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    allocated_var_bytes[i]--;
517df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  }
518df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
519df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
520df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid hb_buffer_t::deallocate_var_all (void)
521df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
522df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes));
523df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  memset (allocated_var_owner, 0, sizeof (allocated_var_owner));
52408d012eba490c4906ec773c39db9f2a18a78c997Dan Gohman}
52508d012eba490c4906ec773c39db9f2a18a78c997Dan Gohman
5261224c386981f7948f298ed9ad444c40609570f2eDan Gohman/* Public API */
527dd8004dc73d091ccb3927dbbc3b41639a3738ae3Dan Gohman
528df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_t *
529df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_create ()
530df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
531df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  hb_buffer_t *buffer;
532df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
533df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (!(buffer = hb_object_create<hb_buffer_t> ()))
534df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    return hb_buffer_get_empty ();
5358ba2d5befc05ca73d3bac8708819bbbe759e2cf9Dale Johannesen
536df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  buffer->reset ();
537df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
538df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return buffer;
539df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
540df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
541df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_t *
542df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_get_empty (void)
543ded05e34b65dc42998e9db6ca1abd513e7a9d120Anton Korobeynikov{
544385f5a99ecc7fee48a7539bc63d3e1d3b5089c0dAnton Korobeynikov  static const hb_buffer_t _hb_buffer_nil = {
545385f5a99ecc7fee48a7539bc63d3e1d3b5089c0dAnton Korobeynikov    HB_OBJECT_HEADER_STATIC,
546385f5a99ecc7fee48a7539bc63d3e1d3b5089c0dAnton Korobeynikov
547211a14e476abc9b864ab6a5d5e0bbb86d288b650Anton Korobeynikov    _HB_BUFFER_UNICODE_FUNCS_DEFAULT,
548f9930da2ef72350c6c805af09e754e4e6e13d47bChe-Liang Chiou    _HB_BUFFER_PROPS_DEFAULT,
549f9930da2ef72350c6c805af09e754e4e6e13d47bChe-Liang Chiou
550385f5a99ecc7fee48a7539bc63d3e1d3b5089c0dAnton Korobeynikov    true, /* in_error */
551df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    true, /* have_output */
552df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    true  /* have_positions */
553df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  };
554df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
555df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
556df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
557df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
558df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_t *
559df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_reference (hb_buffer_t *buffer)
560df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
561df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return hb_object_reference (buffer);
562df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
563df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
564df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid
565df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_destroy (hb_buffer_t *buffer)
566df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
567570a4a5d9ca31f276a67502d1e0533d59d331feaJakob Stoklund Olesen  if (!hb_object_destroy (buffer)) return;
568df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
569df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  hb_unicode_funcs_destroy (buffer->unicode);
570df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
571df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  free (buffer->info);
572df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  free (buffer->pos);
573d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel
574578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patel  free (buffer);
575c5ec8a78ea898087ad361e5b755f74a76150e5fdAnton Korobeynikov}
576970bfcc7d8b9991430caa7ab33975617f3f4c40dCharles Davis
577df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_bool_t
578df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_set_user_data (hb_buffer_t        *buffer,
579df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			 hb_user_data_key_t *key,
580df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			 void *              data,
581df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			 hb_destroy_func_t   destroy,
582df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			 hb_bool_t           replace)
583df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
584df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return hb_object_set_user_data (buffer, key, data, destroy, replace);
5859ea4034e007a83c778cd306ea66481be1317a51bMisha Brukman}
586df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
58709d9ef4122414a1a2ec95f52d660d6500f2819d0Chris Lattnervoid *
5888e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_get_user_data (hb_buffer_t        *buffer,
5898e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner			 hb_user_data_key_t *key)
5908e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
591df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return hb_object_get_user_data (buffer, key);
5928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
593df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
5941d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson
5951d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Andersonvoid
5961d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Andersonhb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
5971d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson			     hb_unicode_funcs_t *unicode)
5981d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson{
5991d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson  if (unlikely (hb_object_is_inert (buffer)))
6001d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson    return;
6011d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson
602bb811a244567aa8a1522203f15588f4d001b7353Dale Johannesen  if (!unicode)
6038e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    unicode = _HB_BUFFER_UNICODE_FUNCS_DEFAULT;
6048e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
6058e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_unicode_funcs_reference (unicode);
6068e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  hb_unicode_funcs_destroy (buffer->unicode);
6078e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  buffer->unicode = unicode;
6088e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
6098e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
610df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_unicode_funcs_t *
6118e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_get_unicode_funcs (hb_buffer_t        *buffer)
6128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
6138e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  return buffer->unicode;
614df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
61513ad5aaaff8a446758b402fd5e9aea22f5bc5682Victor Hernandez
616cf4d2f11a1acc12a0f6b50991907e4a998ee9cddChris Lattnervoid
617cf4d2f11a1acc12a0f6b50991907e4a998ee9cddChris Lattnerhb_buffer_set_direction (hb_buffer_t    *buffer,
61813ad5aaaff8a446758b402fd5e9aea22f5bc5682Victor Hernandez			 hb_direction_t  direction)
619046e78ce55a7c3d82b7b6758d2d77f2d99f970bfVictor Hernandez
620046e78ce55a7c3d82b7b6758d2d77f2d99f970bfVictor Hernandez{
621046e78ce55a7c3d82b7b6758d2d77f2d99f970bfVictor Hernandez  if (unlikely (hb_object_is_inert (buffer)))
622046e78ce55a7c3d82b7b6758d2d77f2d99f970bfVictor Hernandez    return;
6238e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
6242c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  buffer->props.direction = direction;
6258e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
626df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
627df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_direction_t
628df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_get_direction (hb_buffer_t    *buffer)
629df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
630ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman  return buffer->props.direction;
631ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman}
632ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman
633df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid
634df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_set_script (hb_buffer_t *buffer,
635df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner		      hb_script_t  script)
636df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
637df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (unlikely (hb_object_is_inert (buffer)))
638df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    return;
639df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
640df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  buffer->props.script = script;
641df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
642df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
643df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_script_t
644df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_get_script (hb_buffer_t *buffer)
645df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
646df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return buffer->props.script;
647df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
648df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
649df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid
650df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_set_language (hb_buffer_t   *buffer,
651df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner			hb_language_t  language)
652df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
653df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (unlikely (hb_object_is_inert (buffer)))
654df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    return;
655df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
656df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  buffer->props.language = language;
657df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
658ab21db79ef1d2530880ad11f21f0b87ffca02dd4Chris Lattner
659df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_language_t
660df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_get_language (hb_buffer_t *buffer)
661df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
662df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  return buffer->props.language;
663df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
664df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
665df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
666df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnervoid
667df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_reset (hb_buffer_t *buffer)
668df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
669df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  buffer->reset ();
670df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
671df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
672df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_bool_t
673df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
6742c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling{
6752c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  return buffer->ensure (size);
6768e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
6778e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
6788e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_bool_t
6798e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_allocation_successful (hb_buffer_t  *buffer)
6808e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
6818e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  return !buffer->in_error;
682689ad6ef3fd2e89394f1e8860dfebfe56b73c3daDaniel Dunbar}
6838e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
6848e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
6858e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_add (hb_buffer_t    *buffer,
686df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	       hb_codepoint_t  codepoint,
687df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	       hb_mask_t       mask,
6888e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	       unsigned int    cluster)
6892c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling{
6904ce0df610879e82d9853c6a38a75b1883feaee06Chris Lattner  buffer->add (codepoint, mask, cluster);
6918e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
6928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
693df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_bool_t
6948e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_set_length (hb_buffer_t  *buffer,
6952c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling		      unsigned int  length)
6964ce0df610879e82d9853c6a38a75b1883feaee06Chris Lattner{
6974ce0df610879e82d9853c6a38a75b1883feaee06Chris Lattner  if (unlikely (hb_object_is_inert (buffer)))
6984ce0df610879e82d9853c6a38a75b1883feaee06Chris Lattner    return length == 0;
6994ce0df610879e82d9853c6a38a75b1883feaee06Chris Lattner
700df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (!buffer->ensure (length))
701df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    return false;
7024ce0df610879e82d9853c6a38a75b1883feaee06Chris Lattner
7032c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  /* Wipe the new space */
704df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (length > buffer->len) {
7058e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
706df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    if (buffer->have_positions)
7078e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
7088e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  }
7098e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7108e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  buffer->len = length;
7118e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  return true;
7128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
7138e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7148e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerunsigned int
7158e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_get_length (hb_buffer_t *buffer)
716df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
7178e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  return buffer->len;
7182c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling}
7198e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7208e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner/* Return value valid as long as buffer not modified */
7218e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_glyph_info_t *
7228e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
7238e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner                           unsigned int *length)
7248e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
7258e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (length)
7268e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    *length = buffer->len;
727df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
7288e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  return (hb_glyph_info_t *) buffer->info;
729df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
7308e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7312c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling/* Return value valid as long as buffer not modified */
7328e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_glyph_position_t *
7338e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
7342c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling                               unsigned int *length)
7358e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
7368e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (!buffer->have_positions)
7378e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    buffer->clear_positions ();
7388e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
739df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  if (length)
740df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner    *length = buffer->len;
7418e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7422c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  return (hb_glyph_position_t *) buffer->pos;
7438e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
7448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
745c23197a26f34f559ea9797de51e187087c039c42Torok Edwinvoid
7468e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_reverse (hb_buffer_t *buffer)
7478e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
7481b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen  buffer->reverse ();
749df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
750df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
7518e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
7528e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_reverse_clusters (hb_buffer_t *buffer)
7531b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesen{
754df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  buffer->reverse_clusters ();
755df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
7568e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7578e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnervoid
7581b25cb2416c46a6cebf2a6c52235e9fe46a10d11Dale Johannesenhb_buffer_guess_properties (hb_buffer_t *buffer)
759df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner{
760df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner  buffer->guess_properties ();
7618e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
7628e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7638e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#define ADD_UTF(T) \
7648e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	HB_STMT_START { \
7658e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	  if (text_length == -1) { \
7668e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    text_length = 0; \
7678e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    const T *p = (const T *) text; \
7688e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    while (*p) { \
7698e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	      text_length++; \
7708e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	      p++; \
7718e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    } \
7728e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	  } \
773df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	  if (item_length == -1) \
7748e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    item_length = text_length - item_offset; \
7758e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	  buffer->ensure (buffer->len + item_length * sizeof (T) / 4); \
7768e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	  const T *next = (const T *) text + item_offset; \
7778e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	  const T *end = next + item_length; \
778df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	  while (next < end) { \
7798e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    hb_codepoint_t u; \
780df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	    const T *old_next = next; \
7818e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    next = UTF_NEXT (next, end, u); \
7822c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling	    hb_buffer_add (buffer, u, 1,  old_next - (const T *) text); \
783df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	  } \
7848e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	} HB_STMT_END
7852c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling
7868e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7872c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling#define UTF8_COMPUTE(Char, Mask, Len) \
7888e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (Char < 128) { Len = 1; Mask = 0x7f; } \
7892c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
7902c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
7912c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
7928e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  else Len = 0;
7938e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
7948e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerstatic inline const uint8_t *
795df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattnerhb_utf8_next (const uint8_t *text,
7968e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	      const uint8_t *end,
797df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	      hb_codepoint_t *unicode)
7988e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
7998e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  uint8_t c = *text;
8002c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  unsigned int mask, len;
8018e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
8028e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  /* TODO check for overlong sequences? */
8038e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
8048e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  UTF8_COMPUTE (c, mask, len);
8058e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  if (unlikely (!len || (unsigned int) (end - text) < len)) {
8068e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    *unicode = -1;
8078e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    return text + 1;
808689ad6ef3fd2e89394f1e8860dfebfe56b73c3daDaniel Dunbar  } else {
8098e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    hb_codepoint_t result;
8108e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    unsigned int i;
8118e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    result = c & mask;
8128e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    for (i = 1; i < len; i++)
813df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner      {
8148e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	if (unlikely ((text[i] & 0xc0) != 0x80))
8158e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	  {
8168e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    *unicode = -1;
8178e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	    return text + 1;
818df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	  }
8198e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	result <<= 6;
820df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	result |= (text[i] & 0x3f);
8218e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      }
8228e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    *unicode = result;
8238e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    return text + len;
8242c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  }
8258e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
8268e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
8272c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlingvoid
8288e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_add_utf8 (hb_buffer_t  *buffer,
8292c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling		    const char   *text,
8308e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		    int           text_length,
8318e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		    unsigned int  item_offset,
8328e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		    int           item_length)
8338e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
8348e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#define UTF_NEXT(S, E, U)	hb_utf8_next (S, E, &(U))
8352c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  ADD_UTF (uint8_t);
836df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner#undef UTF_NEXT
837df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
8388e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
8398e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerstatic inline const uint16_t *
8408e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_utf16_next (const uint16_t *text,
841df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner	       const uint16_t *end,
8428e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner	       hb_codepoint_t *unicode)
8438e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
8448e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  uint16_t c = *text++;
845df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner
8462c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  if (unlikely (c >= 0xd800 && c < 0xdc00)) {
8478e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    /* high surrogate */
8482c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    uint16_t l;
8492c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    if (text < end && ((l = *text), likely (l >= 0xdc00 && l < 0xe000))) {
8508e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      /* low surrogate */
8518e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner      *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000);
8528e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner       text++;
8538e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner    } else
854df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner      *unicode = -1;
8558e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner  } else
8562c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling    *unicode = c;
8578e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
8582c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  return text;
8598e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner}
8608e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
8612c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendlingvoid
8628e3a8e0452695643d04c21e15c94b802aef81baeChris Lattnerhb_buffer_add_utf16 (hb_buffer_t    *buffer,
8632c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling		     const uint16_t *text,
8648e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		     int             text_length,
8658e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		     unsigned int    item_offset,
8668e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner		     int            item_length)
8678e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner{
8688e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner#define UTF_NEXT(S, E, U)	hb_utf16_next (S, E, &(U))
8692c6fd8c7ceea0392635ce21038d2b7fc215d9116Bill Wendling  ADD_UTF (uint16_t);
870df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner#undef UTF_NEXT
871df98617b23315e427cc4fad8ccfdd50d68bec2f9Chris Lattner}
8728e3a8e0452695643d04c21e15c94b802aef81baeChris Lattner
873void
874hb_buffer_add_utf32 (hb_buffer_t    *buffer,
875		     const uint32_t *text,
876		     int             text_length,
877		     unsigned int    item_offset,
878		     int             item_length)
879{
880#define UTF_NEXT(S, E, U)	((U) = *(S), (S)+1)
881  ADD_UTF (uint32_t);
882#undef UTF_NEXT
883}
884
885
886