15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2009,2010  Red Hat, Inc.
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * Copyright © 2010,2011,2012,2013  Google, Inc.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  This is part of HarfBuzz, a text shaping library.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, without written agreement and without
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * software and its documentation for any purpose, provided that the
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * above copyright notice and the following two paragraphs appear in
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all copies of this software.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * DAMAGE.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Red Hat Author(s): Behdad Esfahbod
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Google Author(s): Behdad Esfahbod
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef HB_OT_MAP_PRIVATE_HH
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_OT_MAP_PRIVATE_HH
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-buffer-private.hh"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct hb_ot_shape_plan_t;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_ot_map_t
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend struct hb_ot_map_builder_t;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public:
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct feature_map_t {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hb_tag_t tag; /* should be first for our bsearch to work */
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int index[2]; /* GSUB/GPOS */
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int stage[2]; /* GSUB/GPOS */
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int shift;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hb_mask_t mask;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hb_mask_t _1_mask; /* mask for value=1, for quick access */
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned int needs_fallback : 1;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned int auto_zwj : 1;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static int cmp (const feature_map_t *a, const feature_map_t *b)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct lookup_map_t {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned short index;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned short auto_zwj : 1;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hb_mask_t mask;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static int cmp (const lookup_map_t *a, const lookup_map_t *b)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  struct stage_map_t {
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    unsigned int last_lookup; /* Cumulative */
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    pause_func_t pause_func;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline hb_mask_t get_global_mask (void) const { return global_mask; }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const feature_map_t *map = features.bsearch (&feature_tag);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shift) *shift = map ? map->shift : 0;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return map ? map->mask : 0;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline bool needs_fallback (hb_tag_t feature_tag) const {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const feature_map_t *map = features.bsearch (&feature_tag);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return map ? map->needs_fallback : false;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const feature_map_t *map = features.bsearch (&feature_tag);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return map ? map->_1_mask : 0;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const feature_map_t *map = features.bsearch (&feature_tag);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const feature_map_t *map = features.bsearch (&feature_tag);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return map ? map->stage[table_index] : (unsigned int) -1;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (unlikely (stage == (unsigned int) -1)) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *plookups = NULL;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *lookup_count = 0;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    assert (stage <= stages[table_index].len);
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0;
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    unsigned int end   = stage < stages[table_index].len ? stages[table_index][stage].last_lookup : lookups[table_index].len;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *plookups = &lookups[table_index][start];
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *lookup_count = end - start;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  template <typename Proxy>
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HB_INTERNAL inline void apply (const Proxy &proxy,
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)				 const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void finish (void) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    features.finish ();
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for (unsigned int table_index = 0; table_index < 2; table_index++)
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    {
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      lookups[table_index].finish ();
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stages[table_index].finish ();
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  public:
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hb_tag_t chosen_script[2];
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool found_script[2];
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HB_INTERNAL void add_lookups (hb_face_t    *face,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				unsigned int  table_index,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				unsigned int  feature_index,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				hb_mask_t     mask,
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				bool          auto_zwj);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_mask_t global_mask;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_prealloced_array_t<feature_map_t, 8> features;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  hb_prealloced_array_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum hb_ot_map_feature_flags_t {
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  F_NONE		= 0x0000u,
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  F_GLOBAL		= 0x0001u,
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  F_HAS_FALLBACK	= 0x0002u,
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  F_MANUAL_ZWJ		= 0x0004u
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* Macro version for where const is desired. */
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static inline hb_ot_map_feature_flags_t
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); }
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static inline hb_ot_map_feature_flags_t
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); }
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static inline hb_ot_map_feature_flags_t
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)operator ~ (hb_ot_map_feature_flags_t r)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ return hb_ot_map_feature_flags_t (~(unsigned int) r); }
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static inline hb_ot_map_feature_flags_t&
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ l = l | r; return l; }
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static inline hb_ot_map_feature_flags_t&
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r)
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ l = l & r; return l; }
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct hb_ot_map_builder_t
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  public:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)				   const hb_segment_properties_t *props_);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)				hb_ot_map_feature_flags_t flags);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  inline void add_global_bool_feature (hb_tag_t tag)
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  { add_feature (tag, 1, F_GLOBAL); }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { add_pause (0, pause_func); }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { add_pause (1, pause_func); }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HB_INTERNAL void compile (struct hb_ot_map_t &m);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inline void finish (void) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    feature_infos.finish ();
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for (unsigned int table_index = 0; table_index < 2; table_index++)
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    {
2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stages[table_index].finish ();
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct feature_info_t {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hb_tag_t tag;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int seq; /* sequence#, used for stable sorting only */
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int max_value;
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    hb_ot_map_feature_flags_t flags;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int default_value; /* for non-global features, what should the unset glyphs take */
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int stage[2]; /* GSUB/GPOS */
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static int cmp (const feature_info_t *a, const feature_info_t *b)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { return (a->tag != b->tag) ?  (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  struct stage_info_t {
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    unsigned int index;
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    hb_ot_map_t::pause_func_t pause_func;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  public:
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hb_face_t *face;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hb_segment_properties_t props;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  hb_tag_t chosen_script[2];
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool found_script[2];
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned int script_index[2], language_index[2];
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  private:
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int current_stage[2]; /* GSUB/GPOS */
2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  hb_prealloced_array_t<feature_info_t, 32> feature_infos;
2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  hb_prealloced_array_t<stage_info_t, 8> stages[2]; /* GSUB/GPOS */
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_OT_MAP_PRIVATE_HH */
248