2 * Copyright © 2009,2010 Red Hat, Inc.
3 * Copyright © 2010,2011,2012 Google, Inc.
5 * This is part of HarfBuzz, a text shaping library.
7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in
11 * all copies of this software.
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25 * Red Hat Author(s): Behdad Esfahbod
26 * Google Author(s): Behdad Esfahbod
29 #ifndef HB_OT_MAP_PRIVATE_HH
30 #define HB_OT_MAP_PRIVATE_HH
32 #include "hb-buffer-private.hh"
34 #include "hb-ot-layout-private.hh"
37 static const hb_tag_t table_tags
[2] = {HB_OT_TAG_GSUB
, HB_OT_TAG_GPOS
};
41 friend struct hb_ot_map_builder_t
;
45 struct feature_map_t
{
46 hb_tag_t tag
; /* should be first for our bsearch to work */
47 unsigned int index
[2]; /* GSUB/GPOS */
48 unsigned int stage
[2]; /* GSUB/GPOS */
51 hb_mask_t _1_mask
; /* mask for value=1, for quick access */
52 hb_bool_t needs_fallback
;
54 static int cmp (const feature_map_t
*a
, const feature_map_t
*b
)
55 { return a
->tag
< b
->tag
? -1 : a
->tag
> b
->tag
? 1 : 0; }
62 static int cmp (const lookup_map_t
*a
, const lookup_map_t
*b
)
63 { return a
->index
< b
->index
? -1 : a
->index
> b
->index
? 1 : 0; }
66 typedef void (*pause_func_t
) (const struct hb_ot_shape_plan_t
*plan
, hb_font_t
*font
, hb_buffer_t
*buffer
);
69 unsigned int num_lookups
; /* Cumulative */
70 pause_func_t callback
;
74 hb_ot_map_t (void) { memset (this, 0, sizeof (*this)); }
76 inline hb_mask_t
get_global_mask (void) const { return global_mask
; }
78 inline hb_mask_t
get_mask (hb_tag_t feature_tag
, unsigned int *shift
= NULL
) const {
79 const feature_map_t
*map
= features
.bsearch (&feature_tag
);
80 if (shift
) *shift
= map
? map
->shift
: 0;
81 return map
? map
->mask
: 0;
84 inline bool needs_fallback (hb_tag_t feature_tag
) const {
85 const feature_map_t
*map
= features
.bsearch (&feature_tag
);
86 return map
? map
->needs_fallback
: false;
89 inline hb_mask_t
get_1_mask (hb_tag_t feature_tag
) const {
90 const feature_map_t
*map
= features
.bsearch (&feature_tag
);
91 return map
? map
->_1_mask
: 0;
94 inline unsigned int get_feature_index (unsigned int table_index
, hb_tag_t feature_tag
) const {
95 const feature_map_t
*map
= features
.bsearch (&feature_tag
);
96 return map
? map
->index
[table_index
] : HB_OT_LAYOUT_NO_FEATURE_INDEX
;
99 inline unsigned int get_feature_stage (unsigned int table_index
, hb_tag_t feature_tag
) const {
100 const feature_map_t
*map
= features
.bsearch (&feature_tag
);
101 return map
? map
->stage
[table_index
] : (unsigned int) -1;
104 inline void get_stage_lookups (unsigned int table_index
, unsigned int stage
,
105 const struct lookup_map_t
**plookups
, unsigned int *lookup_count
) const {
106 if (unlikely (stage
== (unsigned int) -1)) {
111 assert (stage
<= pauses
[table_index
].len
);
112 unsigned int start
= stage
? pauses
[table_index
][stage
- 1].num_lookups
: 0;
113 unsigned int end
= stage
< pauses
[table_index
].len
? pauses
[table_index
][stage
].num_lookups
: lookups
[table_index
].len
;
114 *plookups
= &lookups
[table_index
][start
];
115 *lookup_count
= end
- start
;
118 inline hb_tag_t
get_chosen_script (unsigned int table_index
) const
119 { return chosen_script
[table_index
]; }
121 HB_INTERNAL
void substitute_closure (const struct hb_ot_shape_plan_t
*plan
, hb_face_t
*face
, hb_set_t
*glyphs
) const;
122 HB_INTERNAL
void substitute (const struct hb_ot_shape_plan_t
*plan
, hb_font_t
*font
, hb_buffer_t
*buffer
) const;
123 HB_INTERNAL
void position (const struct hb_ot_shape_plan_t
*plan
, hb_font_t
*font
, hb_buffer_t
*buffer
) const;
125 inline void finish (void) {
127 lookups
[0].finish ();
128 lookups
[1].finish ();
136 HB_INTERNAL
void add_lookups (hb_face_t
*face
,
137 unsigned int table_index
,
138 unsigned int feature_index
,
141 hb_mask_t global_mask
;
143 hb_tag_t chosen_script
[2];
144 hb_prealloced_array_t
<feature_map_t
, 8> features
;
145 hb_prealloced_array_t
<lookup_map_t
, 32> lookups
[2]; /* GSUB/GPOS */
146 hb_prealloced_array_t
<pause_map_t
, 1> pauses
[2]; /* GSUB/GPOS */
150 struct hb_ot_map_builder_t
154 hb_ot_map_builder_t (void) { memset (this, 0, sizeof (*this)); }
156 HB_INTERNAL
void add_feature (hb_tag_t tag
, unsigned int value
, bool global
, bool has_fallback
= false);
158 inline void add_bool_feature (hb_tag_t tag
, bool global
= true, bool has_fallback
= false)
159 { add_feature (tag
, 1, global
, has_fallback
); }
161 inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func
)
162 { add_pause (0, pause_func
); }
163 inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func
)
164 { add_pause (1, pause_func
); }
166 HB_INTERNAL
void compile (hb_face_t
*face
,
167 const hb_segment_properties_t
*props
,
168 struct hb_ot_map_t
&m
);
170 inline void finish (void) {
171 feature_infos
.finish ();
178 struct feature_info_t
{
180 unsigned int seq
; /* sequence#, used for stable sorting only */
181 unsigned int max_value
;
182 bool global
; /* whether the feature applies value to every glyph in the buffer */
183 bool has_fallback
; /* whether to allocate bits even if feature not found */
184 unsigned int default_value
; /* for non-global features, what should the unset glyphs take */
185 unsigned int stage
[2]; /* GSUB/GPOS */
187 static int cmp (const feature_info_t
*a
, const feature_info_t
*b
)
188 { return (a
->tag
!= b
->tag
) ? (a
->tag
< b
->tag
? -1 : 1) : (a
->seq
< b
->seq
? -1 : 1); }
191 struct pause_info_t
{
193 hb_ot_map_t::pause_func_t callback
;
196 HB_INTERNAL
void add_pause (unsigned int table_index
, hb_ot_map_t::pause_func_t pause_func
);
198 unsigned int current_stage
[2]; /* GSUB/GPOS */
199 hb_prealloced_array_t
<feature_info_t
,16> feature_infos
;
200 hb_prealloced_array_t
<pause_info_t
, 1> pauses
[2]; /* GSUB/GPOS */
205 #endif /* HB_OT_MAP_PRIVATE_HH */