15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2007,2008,2009 Red Hat, Inc. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright © 2010,2012 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)#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HB_OT_LAYOUT_COMMON_PRIVATE_HH 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-ot-layout-private.hh" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-open-type-private.hh" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hb-set-private.hh" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace OT { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NOT_COVERED ((unsigned int) -1) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_NESTING_LEVEL 8 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MAX_CONTEXT_LENGTH 64 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OpenType Layout Common Table Formats 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Record 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline int cmp (hb_tag_t a) const { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tag.cmp (a); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct sanitize_closure_t { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hb_tag_t tag; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void *list_base; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, void *base) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const sanitize_closure_t closure = {tag, base}; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tag tag; /* 4-byte Tag identifier */ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<Type> 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset; /* Offset from beginning of object holding 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Record */ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (6); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct RecordArrayOf : SortedArrayOf<Record<Type> > { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Tag& get_tag (unsigned int i) const 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* We cheat slightly and don't define separate Null objects 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for Record types. Instead, we return the correct Null(Tag) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * here. */ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (i >= this->len)) return Null(Tag); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (*this)[i].tag; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_tags (unsigned int start_offset, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *record_count /* IN/OUT */, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t *record_tags /* OUT */) const 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (record_count) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Record<Type> *arr = this->sub_array (start_offset, record_count); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = *record_count; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) record_tags[i] = arr[i].tag; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this->len; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find_index (hb_tag_t tag, unsigned int *index) const 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = this->search (tag); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != -1) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index) *index = i; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index) *index = Index::NOT_FOUND_INDEX; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct RecordListOf : RecordArrayOf<Type> 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Type& operator [] (unsigned int i) const 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return this+RecordArrayOf<Type>::operator [](i).offset; } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct RangeRecord 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline int cmp (hb_codepoint_t g) const { 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return g < start ? -1 : g <= end ? 0 : +1 ; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects (const hb_set_t *glyphs) const { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return glyphs->intersects (start, end); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename set_t> 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void add_coverage (set_t *glyphs) const { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs->add_range (start, end); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlyphID start; /* First GlyphID in the range */ 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlyphID end; /* Last GlyphID in the range */ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT value; /* Value */ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (6); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_NULL_DATA (RangeRecord, "\000\001"); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct IndexArray : ArrayOf<Index> 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_indexes (unsigned int start_offset, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *_count /* IN/OUT */, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *_indexes /* OUT */) const 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (_count) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT *arr = this->sub_array (start_offset, _count); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = *_count; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _indexes[i] = arr[i]; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this->len; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Script; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LangSys; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Feature; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LangSys 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_feature_count (void) const 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return featureIndex.len; } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline hb_tag_t get_feature_index (unsigned int i) const 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return featureIndex[i]; } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_feature_indexes (unsigned int start_offset, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *feature_count /* IN/OUT */, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *feature_indexes /* OUT */) const 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_required_feature_index (void) const 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reqFeatureIndex == 0xffff) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Index::NOT_FOUND_INDEX; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reqFeatureIndex;; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Record<LangSys>::sanitize_closure_t * = NULL) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Offset lookupOrder; /* = Null (reserved for an offset to a 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reordering table) */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT reqFeatureIndex;/* Index of a feature required for this 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * language system--if no required features 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * = 0xFFFF */ 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IndexArray featureIndex; /* Array of indices into the FeatureList */ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, featureIndex); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF"); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Script 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_lang_sys_count (void) const 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return langSys.len; } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const Tag& get_lang_sys_tag (unsigned int i) const 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return langSys.get_tag (i); } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_lang_sys_tags (unsigned int start_offset, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *lang_sys_count /* IN/OUT */, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hb_tag_t *lang_sys_tags /* OUT */) const 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const LangSys& get_lang_sys (unsigned int i) const 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this+langSys[i].offset; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return langSys.find_index (tag, index); } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Record<Script>::sanitize_closure_t * = NULL) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OffsetTo<LangSys> 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defaultLangSys; /* Offset to DefaultLangSys table--from 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * beginning of Script table--may be Null */ 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordArrayOf<LangSys> 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) langSys; /* Array of LangSysRecords--listed 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * alphabetically by LangSysTag */ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (4, langSys); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef RecordListOf<Script> ScriptList; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct FeatureParamsSize 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* This subtable has some "history", if you will. Some earlier versions of 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Adobe tools calculated the offset of the FeatureParams sutable from the 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * beginning of the FeatureList table! Now, that is dealt with in the 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Feature implementation. But we still need to be able to tell junk from 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * real data. Note: We don't check that the nameID actually exists. 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk : 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Yes, it is correct that a new version of the AFDKO (version 2.0) will be 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * coming out soon, and that the makeotf program will build a font with a 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 'size' feature that is correct by the specification. 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * The specification for this feature tag is in the "OpenType Layout Tag 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Registry". You can see a copy of this at: 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Here is one set of rules to determine if the 'size' feature is built 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * correctly, or as by the older versions of MakeOTF. You may be able to do 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * better. 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Assume that the offset to the size feature is according to specification, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * and make the following value checks. If it fails, assume the the size 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * If this fails, reject the 'size' feature. The older makeOTF's calculated the 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * offset from the beginning of the FeatureList table, rather than from the 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * beginning of the 'size' Feature table. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * If "design size" == 0: 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * fails check 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Else if ("subfamily identifier" == 0 and 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "range start" == 0 and 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "range end" == 0 and 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "range start" == 0 and 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "menu name ID" == 0) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * passes check: this is the format used when there is a design size 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * specified, but there is no recommended size range. 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Else if ("design size" < "range start" or 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "design size" > "range end" or 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "range end" <= "range start" or 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "menu name ID" < 256 or 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * "menu name ID" > 32767 or 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * menu name ID is not a name ID which is actually in the name table) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * fails test 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Else 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * passes test. 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!designSize) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (subfamilyID == 0 && 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) subfamilyNameID == 0 && 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rangeStart == 0 && 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rangeEnd == 0) 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (true); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (designSize < rangeStart || 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) designSize > rangeEnd || 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) subfamilyNameID < 256 || 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) subfamilyNameID > 32767) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (true); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT designSize; /* Represents the design size in 720/inch 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * units (decipoints). The design size entry 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * must be non-zero. When there is a design 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * size but no recommended size range, the 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * rest of the array will consist of zeros. */ 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT subfamilyID; /* Has no independent meaning, but serves 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * as an identifier that associates fonts 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * in a subfamily. All fonts which share a 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Preferred or Font Family name and which 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * differ only by size range shall have the 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * same subfamily value, and no fonts which 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * differ in weight or style shall have the 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * same subfamily value. If this value is 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * zero, the remaining fields in the array 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * will be ignored. */ 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT subfamilyNameID;/* If the preceding value is non-zero, this 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * value must be set in the range 256 - 32767 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * (inclusive). It records the value of a 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * field in the name table, which must 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * contain English-language strings encoded 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * in Windows Unicode and Macintosh Roman, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * and may contain additional strings 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * localized to other scripts and languages. 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Each of these strings is the name an 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * application should use, in combination 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * with the family name, to represent the 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * subfamily in a menu. Applications will 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * choose the appropriate version based on 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * their selection criteria. */ 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT rangeStart; /* Large end of the recommended usage range 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * (inclusive), stored in 720/inch units 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * (decipoints). */ 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT rangeEnd; /* Small end of the recommended usage range 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (exclusive), stored in 720/inch units 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * (decipoints). */ 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFINE_SIZE_STATIC (10); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct FeatureParamsStylisticSet 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Right now minorVersion is at zero. Which means, any table supports 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * the uiNameID field. */ 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (c->check_struct (this)); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT minorVersion; /* (set to 0): This corresponds to a “minor” 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * version number. Additional data may be 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * added to the end of this Feature Parameters 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * table in the future. */ 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT uiNameID; /* The 'name' table name ID that specifies a 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * string (or strings, for multiple languages) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * for a user-interface label for this 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * feature. The values of uiLabelNameId and 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * sampleTextNameId are expected to be in the 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * font-specific name ID range (256-32767), 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * though that is not a requirement in this 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Feature Parameters specification. The 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * user-interface label for the feature can 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * be provided in multiple languages. An 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * English string should be included as a 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * fallback. The string should be kept to a 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * minimal length to fit comfortably with 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * different application interfaces. */ 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFINE_SIZE_STATIC (4); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct FeatureParamsCharacterVariants 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) characters.sanitize (c)); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT format; /* Format number is set to 0. */ 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT featUILableNameID; /* The ‘name’ table name ID that 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * specifies a string (or strings, 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * for multiple languages) for a 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * user-interface label for this 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * feature. (May be NULL.) */ 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * specifies a string (or strings, 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * for multiple languages) that an 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * application can use for tooltip 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * text for this feature. (May be 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * NULL.) */ 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT sampleTextNameID; /* The ‘name’ table name ID that 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * specifies sample text that 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * illustrates the effect of this 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * feature. (May be NULL.) */ 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT numNamedParameters; /* Number of named parameters. (May 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * be zero.) */ 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * used to specify strings for 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * user-interface labels for the 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * feature parameters. (Must be zero 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * if numParameters is zero.) */ 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ArrayOf<UINT24> 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) characters; /* Array of the Unicode Scalar Value 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * of the characters for which this 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * feature provides glyph variants. 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * (May be zero.) */ 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFINE_SIZE_ARRAY (14, characters); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct FeatureParams 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tag == HB_TAG ('s','i','z','e')) 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (u.size.sanitize (c)); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((tag & 0xFFFF0000) == HB_TAG ('s','s','\0','\0')) /* ssXX */ 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (u.stylisticSet.sanitize (c)); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((tag & 0xFFFF0000) == HB_TAG ('c','v','\0','\0')) /* cvXX */ 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (u.characterVariants.sanitize (c)); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (true); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tag == HB_TAG ('s','i','z','e')) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return u.size; 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Null(FeatureParamsSize); 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) union { 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FeatureParamsSize size; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FeatureParamsStylisticSet stylisticSet; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FeatureParamsCharacterVariants characterVariants; 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } u; 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFINE_SIZE_STATIC (17); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Feature 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_lookup_count (void) const 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return lookupIndex.len; } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline hb_tag_t get_lookup_index (unsigned int i) const 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return lookupIndex[i]; } 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_lookup_indexes (unsigned int start_index, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *lookup_count /* IN/OUT */, 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int *lookup_tags /* OUT */) const 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline const FeatureParams &get_feature_params (void) const 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { return this+featureParams; } 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c, 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Record<Feature>::sanitize_closure_t *closure) { 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Some earlier versions of Adobe tools calculated the offset of the 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * FeatureParams subtable from the beginning of the FeatureList table! 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * If sanitizing "failed" for the FeatureParams subtable, try it with the 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * alternative location. We would know sanitize "failed" if old value 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * of the offset was non-zero, but it's zeroed now. 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Only do this for the 'size' feature, since at the time of the faulty 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Adobe tools, only the 'size' feature had FeatureParams defined. 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Offset orig_offset = featureParams; 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (likely (!orig_offset)) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (true); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (featureParams == 0 && closure && 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closure->tag == HB_TAG ('s','i','z','e') && 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) closure->list_base && closure->list_base < this) 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int new_offset_int = (unsigned int) orig_offset - 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ((char *) this - (char *) closure->list_base); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Offset new_offset; 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Check that it did not overflow. */ 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new_offset.set (new_offset_int); 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (new_offset == new_offset_int && 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) featureParams.try_set (c, new_offset) && 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (false); 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TRACE_RETURN (true); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OffsetTo<FeatureParams> 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) featureParams; /* Offset to Feature Parameters table (if one 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * has been defined for the feature), relative 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to the beginning of the Feature Table; = Null 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if not required */ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IndexArray lookupIndex; /* Array of LookupList indices */ 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (4, lookupIndex); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef RecordListOf<Feature> FeatureList; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LookupFlag : USHORT 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Flags { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RightToLeft = 0x0001u, 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IgnoreBaseGlyphs = 0x0002u, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IgnoreLigatures = 0x0004u, 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IgnoreMarks = 0x0008u, 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IgnoreFlags = 0x000Eu, 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UseMarkFilteringSet = 0x0010u, 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reserved = 0x00E0u, 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MarkAttachmentType = 0xFF00u 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_STATIC (2); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Lookup 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_subtable_count (void) const { return subTable.len; } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_type (void) const { return lookupType; } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * higher 16-bit is mark-filtering-set if the lookup uses one. 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Not to be confused with glyph_props which is very similar. */ 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint32_t get_props (void) const 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int flag = lookupFlag; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flag += (markFilteringSet << 16); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return flag; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool serialize (hb_serialize_context_t *c, 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int lookup_type, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t lookup_props, 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_subtables) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SERIALIZE (this); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupType.set (lookup_type); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lookupFlag.set (lookup_props & 0xFFFF); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookupFlag & LookupFlag::UseMarkFilteringSet) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) markFilteringSet.set (lookup_props >> 16); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Real sanitize of the subtables is done by GSUB/GPOS/... */ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lookupFlag & LookupFlag::UseMarkFilteringSet) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupType; /* Different enumerations for GSUB and GPOS */ 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT lookupFlag; /* Lookup qualifiers */ 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<Offset> 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subTable; /* Array of SubTables */ 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * structure. This field is only present if bit 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * UseMarkFilteringSet of lookup flags is set. */ 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef OffsetListOf<Lookup> LookupList; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Coverage Table 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CoverageFormat1 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct Coverage; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = glyphArray.search (glyph_id); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool serialize (hb_serialize_context_t *c, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Supplier<GlyphID> &glyphs, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_glyphs) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SERIALIZE (this); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphArray.len.set (num_glyphs); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < num_glyphs; i++) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphArray[i] = glyphs[i]; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs.advance (num_glyphs); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (glyphArray.sanitize (c)); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return glyphs->has (glyphArray[index]); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename set_t> 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void add_coverage (set_t *glyphs) const { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = glyphArray.len; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs->add (glyphArray[i]); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Older compilers need this to be public. */ 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Iter { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool more (void) { return i < c->glyphArray.len; } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void next (void) { i++; } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint16_t get_glyph (void) { return c->glyphArray[i]; } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint16_t get_coverage (void) { return i; } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct CoverageFormat1 *c; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT coverageFormat; /* Format identifier--format = 1 */ 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SortedArrayOf<GlyphID> 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphArray; /* Array of GlyphIDs--in numerical order */ 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (4, glyphArray); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CoverageFormat2 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct Coverage; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = rangeRecord.search (glyph_id); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != -1) { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RangeRecord &range = rangeRecord[i]; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (unsigned int) range.value + (glyph_id - range.start); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NOT_COVERED; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool serialize (hb_serialize_context_t *c, 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Supplier<GlyphID> &glyphs, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_glyphs) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SERIALIZE (this); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!num_glyphs)) return TRACE_RETURN (true); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_ranges = 1; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < num_glyphs; i++) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyphs[i - 1] + 1 != glyphs[i]) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_ranges++; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord.len.set (num_ranges); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!c->extend (rangeRecord))) return TRACE_RETURN (false); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int range = 0; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[range].start = glyphs[0]; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[range].value.set (0); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < num_glyphs; i++) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyphs[i - 1] + 1 != glyphs[i]) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range++; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[range].start = glyphs[i]; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[range].value.set (i); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[range].end = glyphs[i]; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[range].end = glyphs[i]; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glyphs.advance (num_glyphs); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (true); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rangeRecord.sanitize (c)); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = rangeRecord.len; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < count; i++) { 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RangeRecord &range = rangeRecord[i]; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range.value <= index && 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index < (unsigned int) range.value + (range.end - range.start) && 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range.intersects (glyphs)) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (index < range.value) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename set_t> 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void add_coverage (set_t *glyphs) const { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = rangeRecord.len; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord[i].add_coverage (glyphs); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* Older compilers need this to be public. */ 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Iter { 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void init (const CoverageFormat2 &c_) { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c = &c_; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage = 0; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = 0; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool more (void) { return i < c->rangeRecord.len; } 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void next (void) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coverage++; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j == c->rangeRecord[i].end) { 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (more ()) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = c->rangeRecord[i].start; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint16_t get_glyph (void) { return j; } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint16_t get_coverage (void) { return coverage; } 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct CoverageFormat2 *c; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i, j, coverage; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT coverageFormat; /* Format identifier--format = 2 */ 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SortedArrayOf<RangeRecord> 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord; /* Array of glyph ranges--ordered by 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Start GlyphID. rangeCount entries 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * long */ 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (4, rangeRecord); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Coverage 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_coverage(glyph_id); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.get_coverage(glyph_id); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return NOT_COVERED; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool serialize (hb_serialize_context_t *c, 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Supplier<GlyphID> &glyphs, 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_glyphs) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SERIALIZE (this); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int num_ranges = 1; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 1; i < num_glyphs; i++) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyphs[i - 1] + 1 != glyphs[i]) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_ranges++; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (false); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects (const hb_set_t *glyphs) const { 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO speed this up */ 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Coverage::Iter iter; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (iter.init (*this); iter.more (); iter.next ()) { 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (glyphs->has (iter.get_glyph ())) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.intersects_coverage (glyphs, index); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.intersects_coverage (glyphs, index); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return false; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename set_t> 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void add_coverage (set_t *glyphs) const { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: u.format1.add_coverage (glyphs); break; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: u.format2.add_coverage (glyphs); break; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: break; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Iter { 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Iter (void) : format (0) {}; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void init (const Coverage &c_) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) format = c_.u.format; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case 1: u.format1.init (c_.u.format1); return; 876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case 2: u.format2.init (c_.u.format2); return; 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: return; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool more (void) { 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.more (); 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.more (); 884f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default:return false; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void next (void) { 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: u.format1.next (); break; 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: u.format2.next (); break; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: break; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint16_t get_glyph (void) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_glyph (); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.get_glyph (); 898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default:return 0; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline uint16_t get_coverage (void) { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (format) { 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_coverage (); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.get_coverage (); 905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default:return -1; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int format; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CoverageFormat1::Iter format1; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CoverageFormat2::Iter format2; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CoverageFormat1 format1; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CoverageFormat2 format2; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_UNION (2, format); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Class Definition Table 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ClassDefFormat1 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct ClassDef; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_class (hb_codepoint_t glyph_id) const 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len)) 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return classValue[glyph_id - startGlyph]; 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename set_t> 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void add_class (set_t *glyphs, unsigned int klass) const { 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = classValue.len; 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (classValue[i] == klass) 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) glyphs->add (startGlyph + i); 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = classValue.len; 959f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (klass == 0) 960f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Match if there's any glyph that is not listed! */ 962f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_codepoint_t g = -1; 963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!hb_set_next (glyphs, &g)) 964f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (g < startGlyph) 966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g = startGlyph + count - 1; 968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hb_set_next (glyphs, &g)) 969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Fall through. */ 971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (classValue[i] == klass && glyphs->has (startGlyph + i)) 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classFormat; /* Format identifier--format = 1 */ 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlyphID startGlyph; /* First GlyphID of the classValueArray */ 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOf<USHORT> 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classValue; /* Array of Class Values--one per GlyphID */ 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, classValue); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ClassDefFormat2 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct ClassDef; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_class (hb_codepoint_t glyph_id) const 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = rangeRecord.search (glyph_id); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != -1) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rangeRecord[i].value; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (rangeRecord.sanitize (c)); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template <typename set_t> 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void add_class (set_t *glyphs, unsigned int klass) const { 10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned int count = rangeRecord.len; 10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (rangeRecord[i].value == klass) 10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rangeRecord[i].add_coverage (glyphs); 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int count = rangeRecord.len; 1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (klass == 0) 1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Match if there's any glyph that is not listed! */ 1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hb_codepoint_t g = (hb_codepoint_t) -1; 1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (unsigned int i = 0; i < count; i++) 1020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) { 1021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!hb_set_next (glyphs, &g)) 1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (g < rangeRecord[i].start) 1024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g = rangeRecord[i].end; 1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) 1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* Fall through. */ 1030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < count; i++) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT classFormat; /* Format identifier--format = 2 */ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SortedArrayOf<RangeRecord> 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rangeRecord; /* Array of glyph ranges--ordered by 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Start GlyphID */ 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (4, rangeRecord); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ClassDef 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_class (hb_codepoint_t glyph_id) const 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.get_class(glyph_id); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.get_class(glyph_id); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return 0; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!u.format.sanitize (c)) return TRACE_RETURN (false); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return TRACE_RETURN (u.format1.sanitize (c)); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return TRACE_RETURN (u.format2.sanitize (c)); 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return TRACE_RETURN (true); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inline void add_class (hb_set_t *glyphs, unsigned int klass) const { 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (u.format) { 10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 1: u.format1.add_class (glyphs, klass); return; 10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 2: u.format2.add_class (glyphs, klass); return; 10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default:return; 10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (u.format) { 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: return u.format1.intersects_class (glyphs, klass); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: return u.format2.intersects_class (glyphs, klass); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default:return false; 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT format; /* Format identifier */ 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClassDefFormat1 format1; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClassDefFormat2 format2; 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } u; 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_UNION (2, format); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Device Tables 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Device 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline hb_position_t get_x_delta (hb_font_t *font) const 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return get_delta (font->x_ppem, font->x_scale); } 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline hb_position_t get_y_delta (hb_font_t *font) const 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { return get_delta (font->y_ppem, font->y_scale); } 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline int get_delta (unsigned int ppem, int scale) const 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ppem) return 0; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pixels = get_delta_pixels (ppem); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pixels) return 0; 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (int) (pixels * (int64_t) scale / ppem); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline int get_delta_pixels (unsigned int ppem_size) const 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int f = deltaFormat; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (f < 1 || f > 3)) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ppem_size < startSize || ppem_size > endSize) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int s = ppem_size - startSize; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int byte = deltaValue[s >> (4 - f)]; 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int mask = (0xFFFF >> (16 - (1 << f))); 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int delta = bits & mask; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((unsigned int) delta >= ((mask + 1) >> 1)) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta -= mask + 1; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delta; 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline unsigned int get_size (void) const 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int f = deltaFormat; 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool sanitize (hb_sanitize_context_t *c) { 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_SANITIZE (this); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT startSize; /* Smallest size to correct--in ppem */ 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT endSize; /* Largest size to correct--in ppem */ 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1 Signed 2-bit value, 8 values per uint16 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2 Signed 4-bit value, 4 values per uint16 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3 Signed 8-bit value, 2 values per uint16 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USHORT deltaValue[VAR]; /* Array of compressed data */ 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEFINE_SIZE_ARRAY (6, deltaValue); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} /* namespace OT */ 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ 1172