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