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