/*
 * Copyright © 2018  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.
 *
 * Google Author(s): Behdad Esfahbod
 */

#ifndef HB_AAT_MAP_HH
#define HB_AAT_MAP_HH

#include "hb.hh"


struct hb_ot_shape_plan_t;

struct hb_aat_map_t
{
  friend struct hb_aat_map_builder_t;

  public:

  inline void init (void)
  {
    memset (this, 0, sizeof (*this));
    chain_flags.init ();
  }
  inline void fini (void)
  {
    chain_flags.fini ();
  }

  public:
  hb_vector_t<hb_mask_t, 1> chain_flags;
};

struct hb_aat_map_builder_t
{
  public:

  HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_,
				    const hb_segment_properties_t *props_ HB_UNUSED) :
				      face (face_)
  {
    features.init ();
  }

  ~hb_aat_map_builder_t (void)
  {
    features.fini ();
  }

  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1);

  HB_INTERNAL void compile (hb_aat_map_t  &m,
			    const int    *coords,
			    unsigned int  num_coords);

  public:
  struct feature_info_t
  {
    uint16_t  type;
    uint16_t  setting;
    unsigned  seq; /* For stable sorting only. */

    static int cmp (const void *pa, const void *pb)
    {
      const feature_info_t *a = (const feature_info_t *) pa;
      const feature_info_t *b = (const feature_info_t *) pb;
      return (a->type != b->type) ? (a->type < b->type ? -1 : 1) :
	     (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
    }

    int cmp (const short unsigned int *ty) const
    {
      return (type != *ty) ? (type < *ty ? -1 : 1) : 0;
    }
  };

  public:
  hb_face_t *face;

  public:
  hb_vector_t<feature_info_t, 32> features;
};


#endif /* HB_AAT_MAP_HH */
