Skip to content

Commit da13293

Browse files
jfkthamebehdad
authored andcommitted
Rework handling of requiredFeature to solve problem with rlig in arial.ttf from winxp
https://bugzilla.mozilla.org/show_bug.cgi?id=986802 Fixes #39 API Change: -hb_ot_layout_language_get_required_feature_index +hb_ot_layout_language_get_required_feature New API takes an extra pointer argument. Pass NULL in to get behavior of previous API. Reworked by behdad
1 parent df554af commit da13293

File tree

5 files changed

+64
-34
lines changed

5 files changed

+64
-34
lines changed

src/hb-ot-layout-gsubgpos-private.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,8 +2268,8 @@ struct GSUBGPOS
22682268

22692269
inline unsigned int get_feature_count (void) const
22702270
{ return (this+featureList).len; }
2271-
inline const Tag& get_feature_tag (unsigned int i) const
2272-
{ return (this+featureList).get_tag (i); }
2271+
inline hb_tag_t get_feature_tag (unsigned int i) const
2272+
{ return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); }
22732273
inline unsigned int get_feature_tags (unsigned int start_offset,
22742274
unsigned int *feature_count /* IN/OUT */,
22752275
hb_tag_t *feature_tags /* OUT */) const

src/hb-ot-layout.cc

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,19 @@ hb_ot_layout_script_find_language (hb_face_t *face,
321321
}
322322

323323
hb_bool_t
324-
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
325-
hb_tag_t table_tag,
326-
unsigned int script_index,
327-
unsigned int language_index,
328-
unsigned int *feature_index)
324+
hb_ot_layout_language_get_required_feature (hb_face_t *face,
325+
hb_tag_t table_tag,
326+
unsigned int script_index,
327+
unsigned int language_index,
328+
unsigned int *feature_index,
329+
hb_tag_t *feature_tag)
329330
{
330-
const OT::LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
331+
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
332+
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
331333

332-
if (feature_index) *feature_index = l.get_required_feature_index ();
334+
unsigned int index = l.get_required_feature_index ();
335+
if (feature_index) *feature_index = index;
336+
if (feature_tag) *feature_tag = g.get_feature_tag (index);
333337

334338
return l.has_required_feature ();
335339
}
@@ -468,11 +472,12 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face,
468472
if (!features)
469473
{
470474
unsigned int required_feature_index;
471-
if (hb_ot_layout_language_get_required_feature_index (face,
472-
table_tag,
473-
script_index,
474-
language_index,
475-
&required_feature_index))
475+
if (hb_ot_layout_language_get_required_feature (face,
476+
table_tag,
477+
script_index,
478+
language_index,
479+
&required_feature_index,
480+
NULL))
476481
_hb_ot_layout_collect_lookups_lookups (face,
477482
table_tag,
478483
required_feature_index,

src/hb-ot-layout.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,12 @@ hb_ot_layout_script_find_language (hb_face_t *face,
140140
unsigned int *language_index);
141141

142142
hb_bool_t
143-
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
144-
hb_tag_t table_tag,
145-
unsigned int script_index,
146-
unsigned int language_index,
147-
unsigned int *feature_index);
143+
hb_ot_layout_language_get_required_feature (hb_face_t *face,
144+
hb_tag_t table_tag,
145+
unsigned int script_index,
146+
unsigned int language_index,
147+
unsigned int *feature_index,
148+
hb_tag_t *feature_tag);
148149

149150
unsigned int
150151
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,

src/hb-ot-map.cc

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
9999
{
100100
feature_info_t *info = feature_infos.push();
101101
if (unlikely (!info)) return;
102+
if (unlikely (!tag)) return;
102103
info->tag = tag;
103104
info->seq = feature_infos.len;
104105
info->max_value = value;
@@ -131,9 +132,25 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
131132
{
132133
m.global_mask = 1;
133134

134-
for (unsigned int table_index = 0; table_index < 2; table_index++) {
135+
unsigned int required_feature_index[2];
136+
hb_tag_t required_feature_tag[2];
137+
/* We default to applying required feature in stage 0. If the required
138+
* feature has a tag that is known to the shaper, we apply required feature
139+
* in the stage for that tag.
140+
*/
141+
unsigned int required_feature_stage[2] = {0, 0};
142+
143+
for (unsigned int table_index = 0; table_index < 2; table_index++)
144+
{
135145
m.chosen_script[table_index] = chosen_script[table_index];
136146
m.found_script[table_index] = found_script[table_index];
147+
148+
hb_ot_layout_language_get_required_feature (face,
149+
table_tags[table_index],
150+
script_index[table_index],
151+
language_index[table_index],
152+
&required_feature_index[table_index],
153+
&required_feature_tag[table_index]);
137154
}
138155

139156
if (!feature_infos.len)
@@ -166,7 +183,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
166183

167184
/* Allocate bits now */
168185
unsigned int next_bit = 1;
169-
for (unsigned int i = 0; i < feature_infos.len; i++) {
186+
for (unsigned int i = 0; i < feature_infos.len; i++)
187+
{
170188
const feature_info_t *info = &feature_infos[i];
171189

172190
unsigned int bits_needed;
@@ -184,12 +202,20 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
184202
hb_bool_t found = false;
185203
unsigned int feature_index[2];
186204
for (unsigned int table_index = 0; table_index < 2; table_index++)
205+
{
206+
if (required_feature_tag[table_index] == info->tag)
207+
{
208+
required_feature_stage[table_index] = info->stage[table_index];
209+
found = true;
210+
continue;
211+
}
187212
found |= hb_ot_layout_language_find_feature (face,
188213
table_tags[table_index],
189214
script_index[table_index],
190215
language_index[table_index],
191216
info->tag,
192217
&feature_index[table_index]);
218+
}
193219
if (!found && !(info->flags & F_HAS_FALLBACK))
194220
continue;
195221

@@ -224,23 +250,21 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
224250
add_gsub_pause (NULL);
225251
add_gpos_pause (NULL);
226252

227-
for (unsigned int table_index = 0; table_index < 2; table_index++) {
228-
hb_tag_t table_tag = table_tags[table_index];
229-
253+
for (unsigned int table_index = 0; table_index < 2; table_index++)
254+
{
230255
/* Collect lookup indices for features */
231256

232-
unsigned int required_feature_index;
233-
if (hb_ot_layout_language_get_required_feature_index (face,
234-
table_tag,
235-
script_index[table_index],
236-
language_index[table_index],
237-
&required_feature_index))
238-
m.add_lookups (face, table_index, required_feature_index, 1, true);
239-
240257
unsigned int stage_index = 0;
241258
unsigned int last_num_lookups = 0;
242259
for (unsigned stage = 0; stage < current_stage[table_index]; stage++)
243260
{
261+
if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
262+
required_feature_stage[table_index] == stage)
263+
m.add_lookups (face, table_index,
264+
required_feature_index[table_index],
265+
1 /* mask */,
266+
true /* auto_zwj */);
267+
244268
for (unsigned i = 0; i < m.features.len; i++)
245269
if (m.features[i].stage[table_index] == stage)
246270
m.add_lookups (face, table_index,

src/main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ main (int argc, char **argv)
151151
for (int n_feature = 0; n_feature < num_features; n_feature++) {
152152
const Feature &feature = g.get_feature (n_feature);
153153
int num_lookups = feature.get_lookup_count ();
154-
printf (" Feature %2d of %2d: %.4s\n", n_feature, num_features,
155-
(const char *)g.get_feature_tag(n_feature));
154+
printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
155+
HB_UNTAG(g.get_feature_tag(n_feature)));
156156

157157
printf (" %d lookup(s) found in feature\n", num_lookups);
158158
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {

0 commit comments

Comments
 (0)