hb-ot-map.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2009,2010 Red Hat, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2010,2011 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)#include "hb-ot-map-private.hh" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_map_t::add_lookups (hb_face_t *face, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int table_index, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int feature_index, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_mask_t mask) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_indices[32]; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int offset, len; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = 0; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = ARRAY_LENGTH (lookup_indices); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_feature_get_lookup_indexes (face, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_tags[table_index], 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_index, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset, &len, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup_indices); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < len; i++) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push (); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!lookup)) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup->mask = mask; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup->index = lookup_indices[i]; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += len; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (len == ARRAY_LENGTH (lookup_indices)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_info_t *info = feature_infos.push(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!info)) return; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->tag = tag; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->seq = feature_infos.len; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->max_value = value; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->global = global; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->has_fallback = has_fallback; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->default_value = global ? value : 0; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->stage[0] = current_stage[0]; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->stage[1] = current_stage[1]; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Keep the next two functions in sync. */ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned int table_index = 0; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i = 0; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pause_map_t *pause = &pauses[table_index][pause_index]; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < pause->num_lookups; i++) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->clear_output (); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pause->callback) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause->callback (plan, font, buffer); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < lookups[table_index].len; i++) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned int table_index = 1; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pause_map_t *pause = &pauses[table_index][pause_index]; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < pause->num_lookups; i++) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pause->callback) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause->callback (plan, font, buffer); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < lookups[table_index].len; i++) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hb_ot_map_t::substitute_closure (const hb_ot_shape_plan_t *plan, hb_face_t *face, hb_set_t *glyphs) const 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int table_index = 0; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < lookups[table_index].len; i++) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_substitute_closure_lookup (face, lookups[table_index][i].index, glyphs); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause_info_t *p = pauses[table_index].push (); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (p)) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->stage = current_stage[table_index]; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->callback = pause_func; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_stage[table_index]++; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_map_builder_t::compile (hb_face_t *face, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const hb_segment_properties_t *props, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t &m) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.global_mask = 1; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!feature_infos.len) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fetch script/language indices for GSUB/GPOS. We need these later to skip 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * features not available in either table and not waste precious bits for them. */ 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t script_tags[3] = {HB_TAG_NONE}; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t language_tag; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_tags_from_script (props->script, &script_tags[0], &script_tags[1]); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_tag = hb_ot_tag_from_language (props->language); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int script_index[2], language_index[2]; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t table_tag = table_tags[table_index]; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &m.chosen_script[table_index]); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Sort features and merge duplicates */ 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos.sort (); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = 0; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < feature_infos.len; i++) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_infos[i].tag != feature_infos[j].tag) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[++j] = feature_infos[i]; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_infos[i].global) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].global = true; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].max_value = feature_infos[i].max_value; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].default_value = feature_infos[i].default_value; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].global = false; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].has_fallback = feature_infos[j].has_fallback || feature_infos[i].has_fallback; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Inherit default_value from j */ 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos.shrink (j + 1); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allocate bits now */ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int next_bit = 1; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < feature_infos.len; i++) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const feature_info_t *info = &feature_infos[i]; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int bits_needed; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->global && info->max_value == 1) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Uses the global bit */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bits_needed = 0; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bits_needed = _hb_bit_storage (info->max_value); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; /* Feature disabled, or not enough bits. */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = false; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int feature_index[2]; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found |= hb_ot_layout_language_find_feature (face, 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_tags[table_index], 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_index[table_index], 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_index[table_index], 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->tag, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &feature_index[table_index]); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found && !info->has_fallback) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t::feature_map_t *map = m.features.push (); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!map)) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->tag = info->tag; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->index[0] = feature_index[0]; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->index[1] = feature_index[1]; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->stage[0] = info->stage[0]; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->stage[1] = info->stage[1]; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->global && info->max_value == 1) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Uses the global bit */ 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->shift = 0; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->mask = 1; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->shift = next_bit; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_bit += bits_needed; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (info->global) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.global_mask |= (info->default_value << map->shift) & map->mask; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->_1_mask = (1 << map->shift) & map->mask; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->needs_fallback = !found; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos.shrink (0); /* Done with these */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_gsub_pause (NULL); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_gpos_pause (NULL); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t table_tag = table_tags[table_index]; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Collect lookup indices for features */ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int required_feature_index; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hb_ot_layout_language_get_required_feature_index (face, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_tag, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_index[table_index], 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_index[table_index], 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &required_feature_index)) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.add_lookups (face, table_index, required_feature_index, 1); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int pause_index = 0; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int last_num_lookups = 0; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned stage = 0; stage < current_stage[table_index]; stage++) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < m.features.len; i++) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m.features[i].stage[table_index] == stage) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.add_lookups (face, table_index, m.features[i].index[table_index], m.features[i].mask); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Sort lookups and merge duplicates */ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_num_lookups < m.lookups[table_index].len) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index].sort (last_num_lookups, m.lookups[table_index].len); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = last_num_lookups; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index][++j] = m.lookups[table_index][i]; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index].shrink (j + 1); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_num_lookups = m.lookups[table_index].len; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pause_index < pauses[table_index].len && pauses[table_index][pause_index].stage == stage) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t::pause_map_t *pause_map = m.pauses[table_index].push (); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (likely (pause_map)) { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause_map->num_lookups = last_num_lookups; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause_map->callback = pauses[table_index][pause_index].callback; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pause_index++; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 297