hb-ot-map-private.hh revision 4924affe0f0adf75f2a0e2137a71206b0576d63f
14924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod/* 24924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * Copyright (C) 2009,2010 Red Hat, Inc. 34924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * Copyright (C) 2010 Google, Inc. 44924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * 54924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * This is part of HarfBuzz, a text shaping library. 64924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * 74924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * Permission is hereby granted, without written agreement and without 84924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 94924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * software and its documentation for any purpose, provided that the 104924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * above copyright notice and the following two paragraphs appear in 114924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * all copies of this software. 124924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * 134924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 144924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 154924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 164924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 174924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * DAMAGE. 184924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * 194924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 204924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 214924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 224924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 234924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 244924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * 254924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 264924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * Google Author(s): Behdad Esfahbod 274924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod */ 284924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 294924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#ifndef HB_OT_MAP_PRIVATE_HH 304924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#define HB_OT_MAP_PRIVATE_HH 314924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 324924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#include "hb-ot-shape-private.hh" 334924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 344924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#include "hb-ot-layout.h" 354924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 364924affe0f0adf75f2a0e2137a71206b0576d63fBehdad EsfahbodHB_BEGIN_DECLS 374924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 384924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 394924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#define MAX_FEATURES 100 /* FIXME */ 404924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#define MAX_LOOKUPS 1000 /* FIXME */ 414924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 424924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbodstatic const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; 434924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 444924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbodstruct hb_mask_allocator_t { 454924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 464924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod struct feature_info_t { 474924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_tag_t tag; 484924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int value; 494924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int seq; 504924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod bool global; 514924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 524924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod static int 534924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod cmp (const void *p1, const void *p2) 544924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 554924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const feature_info_t *a = reinterpret_cast<const feature_info_t *>(p1); 564924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const feature_info_t *b = reinterpret_cast<const feature_info_t *>(p2); 574924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 584924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (a->tag != b->tag) 594924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return a->tag < b->tag ? -1 : 1; 604924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 614924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return a->seq < b->seq ? -1 : 1; 624924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 634924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod }; 644924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 654924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod struct feature_map_t { 664924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_tag_t tag; /* should be first for our bsearch to work */ 674924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int index[2]; /* GSUB, GPOS */ 684924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int shift; 694924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_t mask; 704924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 714924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod static int 724924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod cmp (const void *p1, const void *p2) 734924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 744924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const feature_map_t *a = reinterpret_cast<const feature_map_t *>(p1); 754924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const feature_map_t *b = reinterpret_cast<const feature_map_t *>(p2); 764924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 774924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0; 784924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 794924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod }; 804924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 814924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod struct lookup_map_t { 824924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int index; 834924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_t mask; 844924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 854924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod static int 864924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod cmp (const void *p1, const void *p2) 874924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 884924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const lookup_map_t *a = reinterpret_cast<const lookup_map_t *>(p1); 894924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const lookup_map_t *b = reinterpret_cast<const lookup_map_t *>(p2); 904924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 914924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; 924924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 934924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod }; 944924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 954924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 964924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod void 974924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod add_lookups (hb_ot_shape_context_t *c, 984924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int table_index, 994924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int feature_index, 1004924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_t mask) 1014924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 1024924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int i = MAX_LOOKUPS - lookup_count[table_index]; 1034924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_map_t *lookups = lookup_maps[table_index] + lookup_count[table_index]; 1044924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1054924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int *lookup_indices = (unsigned int *) lookups; 1064924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1074924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_ot_layout_feature_get_lookup_indexes (c->face, 1084924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod table_tags[table_index], 1094924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_index, 1104924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 0, &i, 1114924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_indices); 1124924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1134924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_count[table_index] += i; 1144924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1154924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod while (i--) { 1164924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookups[i].mask = mask; 1174924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookups[i].index = lookup_indices[i]; 1184924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 1194924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 1204924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1214924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1224924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1234924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1244924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_allocator_t (void) : feature_count (0) {} 1254924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1264924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod void add_feature (hb_tag_t tag, 1274924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int value, 1284924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod bool global) 1294924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 1304924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_info_t *info = &feature_infos[feature_count++]; 1314924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod info->tag = tag; 1324924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod info->value = value; 1334924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod info->seq = feature_count; 1344924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod info->global = global; 1354924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 1364924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1374924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod void compile (hb_ot_shape_context_t *c) 1384924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 1394924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod global_mask = 0; 1404924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_count[0] = lookup_count[1] = 0; 1414924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1424924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (!feature_count) 1434924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return; 1444924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1454924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1464924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Fetch script/language indices for GSUB/GPOS. We need these later to skip 1474924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod * features not available in either table and not waste precious bits for them. */ 1484924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1494924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const hb_tag_t *script_tags; 1504924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_tag_t language_tag; 1514924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1524924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod script_tags = hb_ot_tags_from_script (c->buffer->props.script); 1534924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod language_tag = hb_ot_tag_from_language (c->buffer->props.language); 1544924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1554924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int script_index[2], language_index[2]; 1564924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int table_index = 0; table_index < 2; table_index++) { 1574924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_tag_t table_tag = table_tags[table_index]; 1584924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_ot_layout_table_choose_script (c->face, table_tag, script_tags, &script_index[table_index]); 1594924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_ot_layout_script_find_language (c->face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); 1604924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 1614924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1624924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1634924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Sort the features so we can bsearch later */ 1644924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod qsort (feature_infos, feature_count, sizeof (feature_infos[0]), feature_info_t::cmp); 1654924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1664924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Remove dups, let later-occurring features override earlier ones. */ 1674924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int j = 0; 1684924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int i = 1; i < feature_count; i++) 1694924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (feature_infos[i].tag != feature_infos[j].tag) 1704924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_infos[++j] = feature_infos[i]; 1714924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod else { 1724924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (feature_infos[i].global) 1734924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_infos[j] = feature_infos[i]; 1744924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod else { 1754924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_infos[j].global = feature_infos[j].global && (feature_infos[j].value == feature_infos[i].value); 1764924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_infos[j].value = MAX (feature_infos[j].value, feature_infos[i].value); 1774924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 1784924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 1794924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_count = j + 1; 1804924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1814924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1824924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Allocate bits now */ 1834924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int next_bit = 1; 1844924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod j = 0; 1854924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int i = 0; i < feature_count; i++) { 1864924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const feature_info_t *info = &feature_infos[i]; 1874924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1884924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int bits_needed; 1894924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1904924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (info->global && info->value == 1) 1914924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Uses the global bit */ 1924924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod bits_needed = 0; 1934924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod else 1944924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod bits_needed = _hb_bit_storage (info->value); 1954924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1964924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (!info->value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) 1974924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod continue; /* Feature disabled, or not enough bits. */ 1984924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 1994924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2004924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod bool found = false; 2014924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int feature_index[2]; 2024924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int table_index = 0; table_index < 2; table_index++) 2034924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod found |= hb_ot_layout_language_find_feature (c->face, 2044924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod table_tags[table_index], 2054924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod script_index[table_index], 2064924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod language_index[table_index], 2074924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod info->tag, 2084924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod &feature_index[table_index]); 2094924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (!found) 2104924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod continue; 2114924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2124924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2134924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_map_t *map = &feature_maps[j++]; 2144924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2154924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->tag = info->tag; 2164924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->index[0] = feature_index[0]; 2174924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->index[1] = feature_index[1]; 2184924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (info->global && info->value == 1) { 2194924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Uses the global bit */ 2204924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->shift = 0; 2214924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->mask = 1; 2224924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } else { 2234924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->shift = next_bit; 2244924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); 2254924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod next_bit += bits_needed; 2264924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (info->global) 2274924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod global_mask |= map->mask; 2284924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2294924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2304924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2314924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_count = j; 2324924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2334924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2344924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int table_index = 0; table_index < 2; table_index++) { 2354924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_tag_t table_tag = table_tags[table_index]; 2364924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2374924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Collect lookup indices for features */ 2384924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2394924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int required_feature_index; 2404924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (hb_ot_layout_language_get_required_feature_index (c->face, 2414924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod table_tag, 2424924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod script_index[table_index], 2434924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod language_index[table_index], 2444924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod &required_feature_index)) 2454924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod add_lookups (c, table_index, required_feature_index, 1); 2464924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2474924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned i = 0; i < feature_count; i++) 2484924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod add_lookups (c, table_index, feature_maps[i].index[table_index], feature_maps[i].mask); 2494924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2504924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod /* Sort lookups and merge duplicates */ 2514924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2524924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod qsort (lookup_maps[table_index], lookup_count[table_index], sizeof (lookup_maps[table_index][0]), lookup_map_t::cmp); 2534924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2544924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (lookup_count[table_index]) 2554924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod { 2564924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int j = 0; 2574924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int i = 1; i < lookup_count[table_index]; i++) 2584924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (lookup_maps[table_index][i].index != lookup_maps[table_index][j].index) 2594924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_maps[table_index][++j] = lookup_maps[table_index][i]; 2604924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod else 2614924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_maps[table_index][j].mask |= lookup_maps[table_index][i].mask; 2624924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod j++; 2634924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_count[table_index] = j; 2644924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2654924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2664924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2674924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2684924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_t get_global_mask (void) { return global_mask; } 2694924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2704924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift) const { 2714924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod const feature_map_t *map = (const feature_map_t *) bsearch (&tag, feature_maps, feature_count, sizeof (feature_maps[0]), feature_map_t::cmp); 2724924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (likely (map)) { 2734924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (shift) *shift = map->shift; 2744924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return map->mask; 2754924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } else { 2764924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod if (shift) *shift = 0; 2774924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod return 0; 2784924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2794924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2804924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2814924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod void substitute (hb_ot_shape_context_t *c) const { 2824924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int i = 0; i < lookup_count[0]; i++) 2834924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_ot_layout_substitute_lookup (c->face, c->buffer, lookup_maps[0][i].index, lookup_maps[0][i].mask); 2844924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2854924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2864924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod void position (hb_ot_shape_context_t *c) const { 2874924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod for (unsigned int i = 0; i < lookup_count[1]; i++) 2884924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_ot_layout_position_lookup (c->font, c->face, c->buffer, lookup_maps[1][i].index, lookup_maps[1][i].mask); 2894924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod } 2904924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2914924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod private: 2924924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2934924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod hb_mask_t global_mask; 2944924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2954924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int feature_count; 2964924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_info_t feature_infos[MAX_FEATURES]; /* used before compile() only */ 2974924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod feature_map_t feature_maps[MAX_FEATURES]; 2984924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 2994924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod lookup_map_t lookup_maps[2][MAX_LOOKUPS]; /* GSUB/GPOS */ 3004924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod unsigned int lookup_count[2]; 3014924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod}; 3024924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 3034924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 3044924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 3054924affe0f0adf75f2a0e2137a71206b0576d63fBehdad EsfahbodHB_END_DECLS 3064924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod 3074924affe0f0adf75f2a0e2137a71206b0576d63fBehdad Esfahbod#endif /* HB_OT_MAP_PRIVATE_HH */ 308