hb-ot-map-private.hh 6.8 KB
Newer Older
B
Behdad Esfahbod 已提交
1
/*
B
Behdad Esfahbod 已提交
2
 * Copyright © 2009,2010  Red Hat, Inc.
B
Behdad Esfahbod 已提交
3
 * Copyright © 2010,2011,2012  Google, Inc.
B
Behdad Esfahbod 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *
 *  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): Behdad Esfahbod
 * Google Author(s): Behdad Esfahbod
 */

#ifndef HB_OT_MAP_PRIVATE_HH
#define HB_OT_MAP_PRIVATE_HH

32
#include "hb-buffer-private.hh"
B
Behdad Esfahbod 已提交
33

B
Behdad Esfahbod 已提交
34
#include "hb-ot-layout-private.hh"
B
Behdad Esfahbod 已提交
35 36 37 38


static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};

39 40 41
struct hb_ot_map_t
{
  friend struct hb_ot_map_builder_t;
B
Behdad Esfahbod 已提交
42

B
Behdad Esfahbod 已提交
43
  public:
B
Behdad Esfahbod 已提交
44

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  struct feature_map_t {
    hb_tag_t tag; /* should be first for our bsearch to work */
    unsigned int index[2]; /* GSUB/GPOS */
    unsigned int stage[2]; /* GSUB/GPOS */
    unsigned int shift;
    hb_mask_t mask;
    hb_mask_t _1_mask; /* mask for value=1, for quick access */

    static int cmp (const feature_map_t *a, const feature_map_t *b)
    { return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; }
  };

  struct lookup_map_t {
    unsigned int index;
    hb_mask_t mask;

    static int cmp (const lookup_map_t *a, const lookup_map_t *b)
    { return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
  };

  typedef void (*pause_func_t) (const hb_ot_map_t *map, void *face_or_font, hb_buffer_t *buffer, void *user_data);
  typedef struct {
    pause_func_t func;
    void *user_data;
  } pause_callback_t;

  struct pause_map_t {
    unsigned int num_lookups; /* Cumulative */
    pause_callback_t callback;
  };


B
Behdad Esfahbod 已提交
77 78
  hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }

79 80 81
  typedef void (*gsub_pause_func_t) (const hb_ot_map_t *map, hb_face_t *face, hb_buffer_t *buffer, void *user_data);
  typedef void (*gpos_pause_func_t) (const hb_ot_map_t *map, hb_font_t *font, hb_buffer_t *buffer, void *user_data);

82
  inline hb_mask_t get_global_mask (void) const { return global_mask; }
B
Behdad Esfahbod 已提交
83

84 85
  inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
    const feature_map_t *map = features.bsearch (&feature_tag);
B
Behdad Esfahbod 已提交
86 87
    if (shift) *shift = map ? map->shift : 0;
    return map ? map->mask : 0;
B
Behdad Esfahbod 已提交
88 89
  }

90 91
  inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
    const feature_map_t *map = features.bsearch (&feature_tag);
92 93 94
    return map ? map->_1_mask : 0;
  }

95
  inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
96 97 98 99
    const feature_map_t *map = features.bsearch (&feature_tag);
    return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
  }

100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
    const feature_map_t *map = features.bsearch (&feature_tag);
    return map ? map->stage[table_index] : (unsigned int) -1;
  }

  inline void get_stage_lookups (unsigned int table_index, unsigned int stage,
				 const struct lookup_map_t **plookups, unsigned int *lookup_count) const {
    if (unlikely (stage == (unsigned int) -1)) {
      *plookups = NULL;
      *lookup_count = 0;
      return;
    }
    assert (stage <= pauses[table_index].len);
    unsigned int start = stage ? pauses[table_index][stage - 1].num_lookups : 0;
    unsigned int end   = stage < pauses[table_index].len ? pauses[table_index][stage].num_lookups : lookups[table_index].len;
    *plookups = &lookups[table_index][start];
    *lookup_count = end - start;
  }

119 120 121
  inline hb_tag_t get_chosen_script (unsigned int table_index) const
  { return chosen_script[table_index]; }

B
Behdad Esfahbod 已提交
122 123 124
  HB_INTERNAL void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const;
  HB_INTERNAL void substitute (hb_face_t *face, hb_buffer_t *buffer) const;
  HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const;
125

B
Behdad Esfahbod 已提交
126
  inline void finish (void) {
127 128 129
    features.finish ();
    lookups[0].finish ();
    lookups[1].finish ();
130 131
    pauses[0].finish ();
    pauses[1].finish ();
B
Behdad Esfahbod 已提交
132 133
  }

134

135
  private:
136

137 138 139 140 141 142 143
  HB_INTERNAL void add_lookups (hb_face_t    *face,
				unsigned int  table_index,
				unsigned int  feature_index,
				hb_mask_t     mask);

  hb_mask_t global_mask;

B
Behdad Esfahbod 已提交
144
  hb_tag_t chosen_script[2];
145 146
  hb_prealloced_array_t<feature_map_t, 8> features;
  hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
147
  hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */
148
};
B
Behdad Esfahbod 已提交
149 150


B
Behdad Esfahbod 已提交
151 152 153 154
struct hb_ot_map_builder_t
{
  public:

B
Behdad Esfahbod 已提交
155 156
  hb_ot_map_builder_t (void) { memset (this, 0, sizeof (*this)); }

B
Behdad Esfahbod 已提交
157 158 159 160 161
  HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global);

  inline void add_bool_feature (hb_tag_t tag, bool global = true)
  { add_feature (tag, 1, global); }

162 163 164 165
  inline void add_gsub_pause (hb_ot_map_t::gsub_pause_func_t pause_func, void *user_data)
  { add_pause (0, (hb_ot_map_t::pause_func_t) pause_func, user_data); }
  inline void add_gpos_pause (hb_ot_map_t::gpos_pause_func_t pause_func, void *user_data)
  { add_pause (1, (hb_ot_map_t::pause_func_t) pause_func, user_data); }
166

B
Behdad Esfahbod 已提交
167 168 169 170 171 172
  HB_INTERNAL void compile (hb_face_t *face,
			    const hb_segment_properties_t *props,
			    struct hb_ot_map_t &m);

  inline void finish (void) {
    feature_infos.finish ();
173 174
    pauses[0].finish ();
    pauses[1].finish ();
B
Behdad Esfahbod 已提交
175 176 177 178 179 180 181 182 183 184
  }

  private:

  struct feature_info_t {
    hb_tag_t tag;
    unsigned int seq; /* sequence#, used for stable sorting only */
    unsigned int max_value;
    bool global; /* whether the feature applies value to every glyph in the buffer */
    unsigned int default_value; /* for non-global features, what should the unset glyphs take */
185
    unsigned int stage[2]; /* GSUB/GPOS */
B
Behdad Esfahbod 已提交
186 187 188 189 190

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

191 192 193 194 195
  struct pause_info_t {
    unsigned int stage;
    hb_ot_map_t::pause_callback_t callback;
  };

196 197
  HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func, void *user_data);

198 199 200
  unsigned int current_stage[2]; /* GSUB/GPOS */
  hb_prealloced_array_t<feature_info_t,16> feature_infos;
  hb_prealloced_array_t<pause_info_t, 1> pauses[2]; /* GSUB/GPOS */
B
Behdad Esfahbod 已提交
201 202 203
};


B
Behdad Esfahbod 已提交
204 205

#endif /* HB_OT_MAP_PRIVATE_HH */