/*
 * Copyright © 1998-2004  David Turner and Werner Lemberg
 * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
 * Copyright © 2011  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
 * Google Author(s): Behdad Esfahbod
 */

#include "hb-buffer-private.hh"

#include <string.h>

HB_BEGIN_DECLS


static hb_buffer_t _hb_buffer_nil = {
  HB_REFERENCE_COUNT_INVALID, /* ref_count */

  &_hb_unicode_funcs_nil,  /* unicode */
  {
    HB_DIRECTION_INVALID,
    HB_SCRIPT_INVALID,
    NULL,
  },
};

/* Here is how the buffer works internally:
 *
 * There are two info pointers: info and out_info.  They always have
 * the same allocated size, but different lengths.
 *
 * As an optimization, both info and out_info may point to the
 * same piece of memory, which is owned by info.  This remains the
 * case as long as out_len doesn't exceed i at any time.
 * In that case, swap() is no-op and the glyph operations operate
 * mostly in-place.
 *
 * As soon as out_info gets longer than info, out_info is moved over
 * to an alternate buffer (which we reuse the pos buffer for!), and its
 * current contents (out_len entries) are copied to the new place.
 * This should all remain transparent to the user.  swap() then
 * switches info and out_info.
 */


static hb_bool_t
_hb_buffer_enlarge (hb_buffer_t *buffer, unsigned int size)
{
  if (unlikely (buffer->in_error))
    return FALSE;

  unsigned int new_allocated = buffer->allocated;
  hb_glyph_position_t *new_pos;
  hb_glyph_info_t *new_info;
  bool separate_out;

  separate_out = buffer->out_info != buffer->info;

  while (size > new_allocated)
    new_allocated += (new_allocated >> 1) + 8;

  ASSERT_STATIC (sizeof (buffer->info[0]) == sizeof (buffer->pos[0]));
  bool overflows = new_allocated >= ((unsigned int) -1) / sizeof (buffer->info[0]);

  if (unlikely (overflows)) {
    new_pos = NULL;
    new_info = NULL;
  } else {
    new_pos = (hb_glyph_position_t *) realloc (buffer->pos, new_allocated * sizeof (buffer->pos[0]));
    new_info = (hb_glyph_info_t *) realloc (buffer->info, new_allocated * sizeof (buffer->info[0]));
  }

  if (unlikely (!new_pos || !new_info))
    buffer->in_error = TRUE;

  if (likely (new_pos))
    buffer->pos = new_pos;

  if (likely (new_info))
    buffer->info = new_info;

  buffer->out_info = separate_out ? (hb_glyph_info_t *) buffer->pos : buffer->info;
  if (likely (!buffer->in_error))
    buffer->allocated = new_allocated;

  return likely (!buffer->in_error);
}

static inline hb_bool_t
_hb_buffer_ensure (hb_buffer_t *buffer, unsigned int size)
{
  return likely (size <= buffer->allocated) ? TRUE : _hb_buffer_enlarge (buffer, size);
}

static inline hb_bool_t
_hb_buffer_ensure_separate (hb_buffer_t *buffer, unsigned int size)
{
  if (unlikely (!_hb_buffer_ensure (buffer, size))) return FALSE;

  if (buffer->out_info == buffer->info)
  {
    assert (buffer->have_output);

    buffer->out_info = (hb_glyph_info_t *) buffer->pos;
    memcpy (buffer->out_info, buffer->info, buffer->out_len * sizeof (buffer->out_info[0]));
  }

  return TRUE;
}


/* Public API */

hb_buffer_t *
hb_buffer_create (unsigned int pre_alloc_size)
{
  hb_buffer_t *buffer;

  if (!HB_OBJECT_DO_CREATE (hb_buffer_t, buffer))
    return &_hb_buffer_nil;

  if (pre_alloc_size)
    _hb_buffer_ensure (buffer, pre_alloc_size);

  hb_buffer_reset (buffer);

  return buffer;
}

hb_buffer_t *
hb_buffer_reference (hb_buffer_t *buffer)
{
  HB_OBJECT_DO_REFERENCE (buffer);
}

void
hb_buffer_destroy (hb_buffer_t *buffer)
{
  HB_OBJECT_DO_DESTROY (buffer);

  hb_unicode_funcs_destroy (buffer->unicode);

  free (buffer->info);
  free (buffer->pos);

  free (buffer);
}


void
hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
			     hb_unicode_funcs_t *unicode)
{
  if (!unicode)
    unicode = &_hb_unicode_funcs_nil;

  hb_unicode_funcs_reference (unicode);
  hb_unicode_funcs_destroy (buffer->unicode);
  buffer->unicode = unicode;
}

hb_unicode_funcs_t *
hb_buffer_get_unicode_funcs (hb_buffer_t        *buffer)
{
  return buffer->unicode;
}

void
hb_buffer_set_direction (hb_buffer_t    *buffer,
			 hb_direction_t  direction)

{
  buffer->props.direction = direction;
}

hb_direction_t
hb_buffer_get_direction (hb_buffer_t    *buffer)
{
  return buffer->props.direction;
}

void
hb_buffer_set_script (hb_buffer_t *buffer,
		      hb_script_t  script)
{
  buffer->props.script = script;
}

hb_script_t
hb_buffer_get_script (hb_buffer_t *buffer)
{
  return buffer->props.script;
}

void
hb_buffer_set_language (hb_buffer_t   *buffer,
			hb_language_t  language)
{
  buffer->props.language = language;
}

hb_language_t
hb_buffer_get_language (hb_buffer_t *buffer)
{
  return buffer->props.language;
}


void
hb_buffer_reset (hb_buffer_t *buffer)
{
  hb_unicode_funcs_destroy (buffer->unicode);
  buffer->unicode = _hb_buffer_nil.unicode;

  buffer->props = _hb_buffer_nil.props;

  buffer->have_output = FALSE;
  buffer->have_positions = FALSE;
  buffer->in_error = FALSE;

  buffer->i = 0;
  buffer->len = 0;
  buffer->out_len = 0;

  buffer->serial = 0;

  buffer->out_info = buffer->info;
}

hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
{
  return _hb_buffer_ensure (buffer, size);
}

hb_bool_t
hb_buffer_allocation_successful (hb_buffer_t  *buffer)
{
  return !buffer->in_error;
}

void
hb_buffer_add (hb_buffer_t    *buffer,
	       hb_codepoint_t  codepoint,
	       hb_mask_t       mask,
	       unsigned int    cluster)
{
  hb_glyph_info_t *glyph;

  if (unlikely (!_hb_buffer_ensure (buffer, buffer->len + 1))) return;

  glyph = &buffer->info[buffer->len];

  memset (glyph, 0, sizeof (*glyph));
  glyph->codepoint = codepoint;
  glyph->mask = mask;
  glyph->cluster = cluster;

  buffer->len++;
}

/* HarfBuzz-Internal API */

void
_hb_buffer_clear_output (hb_buffer_t *buffer)
{
  buffer->have_output = TRUE;
  buffer->have_positions = FALSE;

  buffer->out_len = 0;
  buffer->out_info = buffer->info;
}

void
_hb_buffer_clear_positions (hb_buffer_t *buffer)
{
  buffer->have_output = FALSE;
  buffer->have_positions = TRUE;

  memset (buffer->pos, 0, sizeof (buffer->pos[0]) * buffer->len);
}

void
_hb_buffer_swap (hb_buffer_t *buffer)
{
  unsigned int tmp;

  assert (buffer->have_output);

  if (unlikely (buffer->in_error)) return;

  if (buffer->out_info != buffer->info)
  {
    hb_glyph_info_t *tmp_string;
    tmp_string = buffer->info;
    buffer->info = buffer->out_info;
    buffer->out_info = tmp_string;
    buffer->pos = (hb_glyph_position_t *) buffer->out_info;
  }

  tmp = buffer->len;
  buffer->len = buffer->out_len;
  buffer->out_len = tmp;

  buffer->i = 0;
}

void
_hb_buffer_replace_glyphs_be16 (hb_buffer_t *buffer,
				unsigned int num_in,
				unsigned int num_out,
				const uint16_t *glyph_data_be)
{
  if (buffer->out_info != buffer->info ||
      buffer->out_len + num_out > buffer->i + num_in)
  {
    if (unlikely (!_hb_buffer_ensure_separate (buffer, buffer->out_len + num_out)))
      return;
  }

  hb_glyph_info_t orig_info = buffer->info[buffer->i];

  for (unsigned int i = 0; i < num_out; i++)
  {
    hb_glyph_info_t *info = &buffer->out_info[buffer->out_len + i];
    *info = orig_info;
    info->codepoint = hb_be_uint16 (glyph_data_be[i]);
  }

  buffer->i  += num_in;
  buffer->out_len += num_out;
}

void
_hb_buffer_replace_glyph (hb_buffer_t *buffer,
			  hb_codepoint_t glyph_index)
{
  hb_glyph_info_t *info;

  if (buffer->out_info != buffer->info)
  {
    if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return;
    buffer->out_info[buffer->out_len] = buffer->info[buffer->i];
  }
  else if (buffer->out_len != buffer->i)
    buffer->out_info[buffer->out_len] = buffer->info[buffer->i];

  info = &buffer->out_info[buffer->out_len];
  info->codepoint = glyph_index;

  buffer->i++;
  buffer->out_len++;
}

void
_hb_buffer_next_glyph (hb_buffer_t *buffer)
{
  if (buffer->have_output)
  {
    if (buffer->out_info != buffer->info)
    {
      if (unlikely (!_hb_buffer_ensure (buffer, buffer->out_len + 1))) return;
      buffer->out_info[buffer->out_len] = buffer->info[buffer->i];
    }
    else if (buffer->out_len != buffer->i)
      buffer->out_info[buffer->out_len] = buffer->info[buffer->i];

    buffer->out_len++;
  }

  buffer->i++;
}

void
_hb_buffer_reset_masks (hb_buffer_t *buffer,
			hb_mask_t    mask)
{
  unsigned int count = buffer->len;
  for (unsigned int i = 0; i < count; i++)
    buffer->info[i].mask = mask;
}

void
_hb_buffer_add_masks (hb_buffer_t *buffer,
		      hb_mask_t    mask)
{
  unsigned int count = buffer->len;
  for (unsigned int i = 0; i < count; i++)
    buffer->info[i].mask |= mask;
}

void
_hb_buffer_set_masks (hb_buffer_t *buffer,
		      hb_mask_t    value,
		      hb_mask_t    mask,
		      unsigned int cluster_start,
		      unsigned int cluster_end)
{
  hb_mask_t not_mask = ~mask;
  value &= mask;

  if (!mask)
    return;

  if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
    unsigned int count = buffer->len;
    for (unsigned int i = 0; i < count; i++)
      buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value;
    return;
  }

  /* XXX can't bsearch since .cluster may not be sorted. */
  /* Binary search to find the start position and go from there. */
  unsigned int min = 0, max = buffer->len;
  while (min < max)
  {
    unsigned int mid = min + ((max - min) / 2);
    if (buffer->info[mid].cluster < cluster_start)
      min = mid + 1;
    else
      max = mid;
  }
  unsigned int count = buffer->len;
  for (unsigned int i = min; i < count && buffer->info[i].cluster < cluster_end; i++)
    buffer->info[i].mask = (buffer->info[i].mask & not_mask) | value;
}


/* Public API again */

hb_bool_t
hb_buffer_set_length (hb_buffer_t  *buffer,
		      unsigned int  length)
{
  if (!_hb_buffer_ensure (buffer, length))
    return FALSE;

  /* Wipe the new space */
  if (length > buffer->len) {
    memset (buffer->info + buffer->len, 0, sizeof (buffer->info[0]) * (length - buffer->len));
    if (buffer->have_positions)
      memset (buffer->pos + buffer->len, 0, sizeof (buffer->pos[0]) * (length - buffer->len));
  }

  buffer->len = length;
  return TRUE;
}

unsigned int
hb_buffer_get_length (hb_buffer_t *buffer)
{
  return buffer->len;
}

/* Return value valid as long as buffer not modified */
hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
                           unsigned int *length)
{
  if (length)
    *length = buffer->len;

  return (hb_glyph_info_t *) buffer->info;
}

/* Return value valid as long as buffer not modified */
hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
                               unsigned int *length)
{
  if (!buffer->have_positions)
    _hb_buffer_clear_positions (buffer);

  if (length)
    *length = buffer->len;

  return (hb_glyph_position_t *) buffer->pos;
}


static void
reverse_range (hb_buffer_t *buffer,
	       unsigned int start,
	       unsigned int end)
{
  unsigned int i, j;

  for (i = start, j = end - 1; i < j; i++, j--) {
    hb_glyph_info_t t;

    t = buffer->info[i];
    buffer->info[i] = buffer->info[j];
    buffer->info[j] = t;
  }

  if (buffer->pos) {
    for (i = 0, j = end - 1; i < j; i++, j--) {
      hb_glyph_position_t t;

      t = buffer->pos[i];
      buffer->pos[i] = buffer->pos[j];
      buffer->pos[j] = t;
    }
  }
}

void
hb_buffer_reverse (hb_buffer_t *buffer)
{
  if (unlikely (!buffer->len))
    return;

  reverse_range (buffer, 0, buffer->len);
}

void
hb_buffer_reverse_clusters (hb_buffer_t *buffer)
{
  unsigned int i, start, count, last_cluster;

  if (unlikely (!buffer->len))
    return;

  hb_buffer_reverse (buffer);

  count = buffer->len;
  start = 0;
  last_cluster = buffer->info[0].cluster;
  for (i = 1; i < count; i++) {
    if (last_cluster != buffer->info[i].cluster) {
      reverse_range (buffer, start, i);
      start = i;
      last_cluster = buffer->info[i].cluster;
    }
  }
  reverse_range (buffer, start, i);
}


#define ADD_UTF(T) \
	HB_STMT_START { \
	  const T *next = (const T *) text + item_offset; \
	  const T *end = next + item_length; \
	  while (next < end) { \
	    hb_codepoint_t u; \
	    const T *old_next = next; \
	    next = UTF_NEXT (next, end, u); \
	    hb_buffer_add (buffer, u, 1,  old_next - (const T *) text); \
	  } \
	} HB_STMT_END


#define UTF8_COMPUTE(Char, Mask, Len) \
  if (Char < 128) { Len = 1; Mask = 0x7f; } \
  else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
  else if ((Char & 0xf0) == 0xe0) { Len = 3; Mask = 0x0f; } \
  else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
  else Len = 0;

static inline const uint8_t *
hb_utf8_next (const uint8_t *text,
	      const uint8_t *end,
	      hb_codepoint_t *unicode)
{
  uint8_t c = *text;
  unsigned int mask, len;

  /* TODO check for overlong sequences?  also: optimize? */

  UTF8_COMPUTE (c, mask, len);
  if (unlikely (!len || (unsigned int) (end - text) < len)) {
    *unicode = -1;
    return text + 1;
  } else {
    hb_codepoint_t result;
    unsigned int i;
    result = c & mask;
    for (i = 1; i < len; i++)
      {
	if (unlikely ((text[i] & 0xc0) != 0x80))
	  {
	    *unicode = -1;
	    return text + 1;
	  }
	result <<= 6;
	result |= (text[i] & 0x3f);
      }
    *unicode = result;
    return text + len;
  }
}

void
hb_buffer_add_utf8 (hb_buffer_t  *buffer,
		    const char   *text,
		    unsigned int  text_length HB_UNUSED,
		    unsigned int  item_offset,
		    unsigned int  item_length)
{
#define UTF_NEXT(S, E, U)	hb_utf8_next (S, E, &(U))
  ADD_UTF (uint8_t);
#undef UTF_NEXT
}

static inline const uint16_t *
hb_utf16_next (const uint16_t *text,
	       const uint16_t *end,
	       hb_codepoint_t *unicode)
{
  uint16_t c = *text++;

  if (unlikely (c >= 0xd800 && c < 0xdc00)) {
    /* high surrogate */
    uint16_t l;
    if (text < end && ((l = *text), likely (l >= 0xdc00 && l < 0xe000))) {
      /* low surrogate */
      *unicode = ((hb_codepoint_t) ((c) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000);
       text++;
    } else
      *unicode = -1;
  } else
    *unicode = c;

  return text;
}

void
hb_buffer_add_utf16 (hb_buffer_t    *buffer,
		     const uint16_t *text,
		     unsigned int    text_length HB_UNUSED,
		     unsigned int    item_offset,
		     unsigned int    item_length)
{
#define UTF_NEXT(S, E, U)	hb_utf16_next (S, E, &(U))
  ADD_UTF (uint16_t);
#undef UTF_NEXT
}

void
hb_buffer_add_utf32 (hb_buffer_t    *buffer,
		     const uint32_t *text,
		     unsigned int    text_length HB_UNUSED,
		     unsigned int    item_offset,
		     unsigned int    item_length)
{
#define UTF_NEXT(S, E, U)	((U) = *(S), (S)+1)
  ADD_UTF (uint32_t);
#undef UTF_NEXT
}


HB_END_DECLS
