15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2009,2010 Red Hat, Inc. 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) * Copyright © 2010,2011,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)#include "hb-ot-map-private.hh" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "hb-ot-layout-private.hh" 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hb_ot_map_t::add_lookups (hb_face_t *face, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int table_index, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int feature_index, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_mask_t mask, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool auto_zwj) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_indices[32]; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int offset, len; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned int table_lookup_count; 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = 0; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = ARRAY_LENGTH (lookup_indices); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_ot_layout_feature_get_lookups (face, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) table_tags[table_index], 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) feature_index, 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) offset, &len, 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lookup_indices); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned int i = 0; i < len; i++) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (lookup_indices[i] >= table_lookup_count) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) continue; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push (); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!lookup)) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup->mask = mask; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookup->index = lookup_indices[i]; 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) lookup->auto_zwj = auto_zwj; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset += len; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (len == ARRAY_LENGTH (lookup_indices)); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const hb_segment_properties_t *props_) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memset (this, 0, sizeof (*this)); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) face = face_; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) props = *props_; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Fetch script/language indices for GSUB/GPOS. We need these later to skip 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * features not available in either table and not waste precious bits for them. */ 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE}; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_tag_t language_tag; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) language_tag = hb_ot_tag_from_language (props.language); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_tag_t table_tag = table_tags[table_index]; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) hb_ot_map_feature_flags_t flags) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_info_t *info = feature_infos.push(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!info)) return; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->tag = tag; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->seq = feature_infos.len; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->max_value = value; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info->flags = flags; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) info->default_value = (flags & F_GLOBAL) ? value : 0; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->stage[0] = current_stage[0]; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->stage[1] = current_stage[1]; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < lookups[table_index].len; i++) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_set_add (lookups_out, lookups[table_index][i].index); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) stage_info_t *s = stages[table_index].push (); 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (likely (s)) { 1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) s->index = current_stage[table_index]; 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) s->pause_func = pause_func; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_stage[table_index]++; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)hb_ot_map_builder_t::compile (hb_ot_map_t &m) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m.global_mask = 1; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) { 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m.chosen_script[table_index] = chosen_script[table_index]; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m.found_script[table_index] = found_script[table_index]; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!feature_infos.len) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Sort features and merge duplicates */ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos.sort (); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = 0; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < feature_infos.len; i++) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_infos[i].tag != feature_infos[j].tag) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[++j] = feature_infos[i]; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (feature_infos[i].flags & F_GLOBAL) { 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feature_infos[j].flags |= F_GLOBAL; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].max_value = feature_infos[i].max_value; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].default_value = feature_infos[i].default_value; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feature_infos[j].flags &= ~F_GLOBAL; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /* Inherit default_value from j */ 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos.shrink (j + 1); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Allocate bits now */ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int next_bit = 1; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < feature_infos.len; i++) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const feature_info_t *info = &feature_infos[i]; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int bits_needed; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((info->flags & F_GLOBAL) && info->max_value == 1) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Uses the global bit */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bits_needed = 0; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bits_needed = _hb_bit_storage (info->max_value); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; /* Feature disabled, or not enough bits. */ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_bool_t found = false; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int feature_index[2]; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found |= hb_ot_layout_language_find_feature (face, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_tags[table_index], 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_index[table_index], 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_index[table_index], 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->tag, 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &feature_index[table_index]); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!found && !(info->flags & F_HAS_FALLBACK)) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_ot_map_t::feature_map_t *map = m.features.push (); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!map)) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->tag = info->tag; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->index[0] = feature_index[0]; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->index[1] = feature_index[1]; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->stage[0] = info->stage[0]; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->stage[1] = info->stage[1]; 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) map->auto_zwj = !(info->flags & F_MANUAL_ZWJ); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((info->flags & F_GLOBAL) && info->max_value == 1) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Uses the global bit */ 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->shift = 0; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->mask = 1; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->shift = next_bit; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_bit += bits_needed; 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.global_mask |= (info->default_value << map->shift) & map->mask; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->_1_mask = (1 << map->shift) & map->mask; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map->needs_fallback = !found; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_infos.shrink (0); /* Done with these */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_gsub_pause (NULL); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_gpos_pause (NULL); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int table_index = 0; table_index < 2; table_index++) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t table_tag = table_tags[table_index]; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Collect lookup indices for features */ 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int required_feature_index; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hb_ot_layout_language_get_required_feature_index (face, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) table_tag, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script_index[table_index], 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) language_index[table_index], 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &required_feature_index)) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.add_lookups (face, table_index, required_feature_index, 1, true); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) unsigned int stage_index = 0; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int last_num_lookups = 0; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned stage = 0; stage < current_stage[table_index]; stage++) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0; i < m.features.len; i++) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m.features[i].stage[table_index] == stage) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.add_lookups (face, table_index, 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.features[i].index[table_index], 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.features[i].mask, 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.features[i].auto_zwj); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Sort lookups and merge duplicates */ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_num_lookups < m.lookups[table_index].len) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index].sort (last_num_lookups, m.lookups[table_index].len); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int j = last_num_lookups; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = j + 1; i < m.lookups[table_index].len; i++) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (m.lookups[table_index][i].index != m.lookups[table_index][j].index) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index][++j] = m.lookups[table_index][i]; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index][j].mask |= m.lookups[table_index][i].mask; 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) m.lookups[table_index][j].auto_zwj &= m.lookups[table_index][i].auto_zwj; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.lookups[table_index].shrink (j + 1); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_num_lookups = m.lookups[table_index].len; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (stage_index < stages[table_index].len && stages[table_index][stage_index].index == stage) { 2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) hb_ot_map_t::stage_map_t *stage_map = m.stages[table_index].push (); 2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (likely (stage_map)) { 2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) stage_map->last_lookup = last_num_lookups; 2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) stage_map->pause_func = stages[table_index][stage_index].pause_func; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) stage_index++; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 282