16f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2007,2008,2009 Red Hat, Inc. 35b93e8d94fb4c2474816304ae3f52e1c704882deBehdad Esfahbod * Copyright © 2010,2012 Google, Inc. 46f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 66f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 76f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Permission is hereby granted, without written agreement and without 86f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 96f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * software and its documentation for any purpose, provided that the 106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * above copyright notice and the following two paragraphs appear in 116f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * all copies of this software. 126f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 176f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * DAMAGE. 186f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 236f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 246f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod 265bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod * Google Author(s): Behdad Esfahbod 276f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 295f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH 305f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#define HB_OT_LAYOUT_COMMON_PRIVATE_HH 316f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 3240ec3bbb55b8af1668bb3d5f6232a85b15cff136Behdad Esfahbod#include "hb-private.hh" 3340ec3bbb55b8af1668bb3d5f6232a85b15cff136Behdad Esfahbod#include "hb-debug.hh" 3422da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-ot-layout-private.hh" 357edb430f9182723b7b720708c56088cec1200a70Behdad Esfahbod#include "hb-open-type-private.hh" 360b08adb3539f2ec29682456b89c69e89ff5e9c03Behdad Esfahbod#include "hb-set-private.hh" 376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 386f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 395ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#ifndef HB_MAX_NESTING_LEVEL 405ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#define HB_MAX_NESTING_LEVEL 6 415ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#endif 425ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#ifndef HB_MAX_CONTEXT_LENGTH 435ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#define HB_MAX_CONTEXT_LENGTH 64 445ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#endif 455ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod 465ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod 477c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT { 487c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 497c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 50dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod#define NOT_COVERED ((unsigned int) -1) 51cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod 52acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 53cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod 546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * OpenType Layout Common Table Formats 576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 602e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod 616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList 636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type> 6660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Record 6760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 684e573715ae5f5ed486ad66382bb44c47a86591ffBehdad Esfahbod inline int cmp (hb_tag_t a) const { 6936b3862009c00ad922d68810173a69ac59723365Behdad Esfahbod return tag.cmp (a); 70cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 71cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 7287e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod struct sanitize_closure_t { 7387e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod hb_tag_t tag; 74de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const void *list_base; 7587e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod }; 76de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 77de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 78be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 7987e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod const sanitize_closure_t closure = {tag, base}; 80b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); 81cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 82cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod Tag tag; /* 4-byte Tag identifier */ 846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod OffsetTo<Type> 856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod offset; /* Offset from beginning of object holding 866f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * the Record */ 87569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 88569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod DEFINE_SIZE_STATIC (6); 896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type> 92cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RecordArrayOf : SortedArrayOf<Record<Type> > { 9360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Tag& get_tag (unsigned int i) const 9460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 954e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod /* We cheat slightly and don't define separate Null objects 964e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod * for Record types. Instead, we return the correct Null(Tag) 974e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod * here. */ 9864d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (i >= this->len)) return Null(Tag); 99d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod return (*this)[i].tag; 1006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 101e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_tags (unsigned int start_offset, 102e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *record_count /* IN/OUT */, 103e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *record_tags /* OUT */) const 104bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 105e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod if (record_count) { 10631f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod const Record<Type> *arr = this->sub_array (start_offset, record_count); 10748de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = *record_count; 108e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 10931f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod record_tags[i] = arr[i].tag; 110e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod } 111e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return this->len; 112bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 113bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_index (hb_tag_t tag, unsigned int *index) const 114bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 115df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* If we want to allow non-sorted data, we can lsearch(). */ 116df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = this->/*lsearch*/bsearch (tag); 117cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 118bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod if (index) *index = i; 119bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod return true; 120cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } else { 121cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (index) *index = Index::NOT_FOUND_INDEX; 122cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return false; 123bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 124bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 125bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod}; 126bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 127bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodtemplate <typename Type> 128bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodstruct RecordListOf : RecordArrayOf<Type> 129bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{ 130bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 1316bec81aa3a58b8be255568b2ea63b7854e1b0ea7Behdad Esfahbod { return this+RecordArrayOf<Type>::operator [](i).offset; } 132cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 133de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 134de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 135be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 136b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (RecordArrayOf<Type>::sanitize (c, this)); 137cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 1386f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 1396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 141cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RangeRecord 142cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod{ 143cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod inline int cmp (hb_codepoint_t g) const { 144797d76d07f80d796a825d850772087104e5a2575Behdad Esfahbod return g < start ? -1 : g <= end ? 0 : +1 ; 145cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 146cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 147de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 148de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 149be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 150b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 151cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 152cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 1536a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects (const hb_set_t *glyphs) const { 15431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->intersects (start, end); 15531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 15631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 157c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 1585d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 15981f27df4d9db1bfc1dd04593cbd121397b86e9a6Behdad Esfahbod return glyphs->add_range (start, end); 16067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 16167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 162cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod GlyphID start; /* First GlyphID in the range */ 163cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod GlyphID end; /* Last GlyphID in the range */ 1646f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 value; /* Value */ 165cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod public: 166cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod DEFINE_SIZE_STATIC (6); 167cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod}; 168cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad EsfahbodDEFINE_NULL_DATA (RangeRecord, "\000\001"); 169cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 170cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 171b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbodstruct IndexArray : ArrayOf<Index> 172bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{ 173e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_indexes (unsigned int start_offset, 174e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *_count /* IN/OUT */, 175e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *_indexes /* OUT */) const 176bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 177e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod if (_count) { 1786f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 *arr = this->sub_array (start_offset, _count); 17948de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = *_count; 180e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 18131f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod _indexes[i] = arr[i]; 182e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod } 183e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return this->len; 184bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 185bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod}; 186bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 187bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 1886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Script; 1896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct LangSys; 1906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Feature; 1916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 19360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LangSys 19460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 195bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_feature_count (void) const 196bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return featureIndex.len; } 197bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline hb_tag_t get_feature_index (unsigned int i) const 198bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return featureIndex[i]; } 199e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_feature_indexes (unsigned int start_offset, 200e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 201e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_indexes /* OUT */) const 202e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } 2036f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2047627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; } 2053d44fb6f15177dc6518166e435597936b044acc1Behdad Esfahbod inline unsigned int get_required_feature_index (void) const 20660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 2077627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (reqFeatureIndex == 0xFFFFu) 208b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod return Index::NOT_FOUND_INDEX; 2096f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return reqFeatureIndex;; 2106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 2116f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 21287e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 213dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod const Record<LangSys>::sanitize_closure_t * = nullptr) const 214de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 215be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 216b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && featureIndex.sanitize (c)); 217cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 218cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 219c6173a392cfaa3d339c768836e8cddf3ae4adc53Behdad Esfahbod Offset16 lookupOrderZ; /* = Null (reserved for an offset to a 2206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * reordering table) */ 2216f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 reqFeatureIndex;/* Index of a feature required for this 2226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * language system--if no required features 2237627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * = 0xFFFFu */ 224bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod IndexArray featureIndex; /* Array of indices into the FeatureList */ 225569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 2260eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, featureIndex); 2276f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 22865f46b00333e20ab8a52a4b350747507541ec1dbBehdad EsfahbodDEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF"); 2296f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2306f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 23160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Script 23260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 233bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lang_sys_count (void) const 234bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.len; } 235bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Tag& get_lang_sys_tag (unsigned int i) const 236bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.get_tag (i); } 237e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_lang_sys_tags (unsigned int start_offset, 238e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lang_sys_count /* IN/OUT */, 239e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *lang_sys_tags /* OUT */) const 240e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } 24160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const LangSys& get_lang_sys (unsigned int i) const 24260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 243b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); 2446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return this+langSys[i].offset; 2456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 246bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const 247bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.find_index (tag, index); } 2486f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 249cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } 25060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } 2516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 25287e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 253dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod const Record<Script>::sanitize_closure_t * = nullptr) const 254de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 255be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 256b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); 257cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 258cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 259ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod OffsetTo<LangSys> 2616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod defaultLangSys; /* Offset to DefaultLangSys table--from 2626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * beginning of Script table--may be Null */ 263cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod RecordArrayOf<LangSys> 2646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod langSys; /* Array of LangSysRecords--listed 2656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * alphabetically by LangSysTag */ 266b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2670eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, langSys); 2686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 2696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2706f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Script> ScriptList; 2716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 272875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 273875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ 274f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodstruct FeatureParamsSize 275f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 276de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 277de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 278f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod TRACE_SANITIZE (this); 279b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->check_struct (this))) return_trace (false); 280efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 281efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod /* This subtable has some "history", if you will. Some earlier versions of 282efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Adobe tools calculated the offset of the FeatureParams sutable from the 283efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * beginning of the FeatureList table! Now, that is dealt with in the 284efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Feature implementation. But we still need to be able to tell junk from 285efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * real data. Note: We don't check that the nameID actually exists. 286efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 287efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk : 288efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 289efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Yes, it is correct that a new version of the AFDKO (version 2.0) will be 290efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * coming out soon, and that the makeotf program will build a font with a 291efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 'size' feature that is correct by the specification. 292efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 293efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * The specification for this feature tag is in the "OpenType Layout Tag 294efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Registry". You can see a copy of this at: 295efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size 296efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 297efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Here is one set of rules to determine if the 'size' feature is built 298efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * correctly, or as by the older versions of MakeOTF. You may be able to do 299efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * better. 300efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 301efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Assume that the offset to the size feature is according to specification, 302efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * and make the following value checks. If it fails, assume the the size 303efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. 304efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If this fails, reject the 'size' feature. The older makeOTF's calculated the 305efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * offset from the beginning of the FeatureList table, rather than from the 306efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * beginning of the 'size' Feature table. 307efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 308efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If "design size" == 0: 309efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * fails check 310efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 311efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else if ("subfamily identifier" == 0 and 312efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range start" == 0 and 313efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range end" == 0 and 314efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range start" == 0 and 315efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" == 0) 316efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * passes check: this is the format used when there is a design size 317efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * specified, but there is no recommended size range. 318efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 319efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else if ("design size" < "range start" or 320efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "design size" > "range end" or 321efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range end" <= "range start" or 322efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" < 256 or 323efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" > 32767 or 324efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * menu name ID is not a name ID which is actually in the name table) 325efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * fails test 326efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else 327efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * passes test. 328efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod */ 329efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 330efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (!designSize) 331b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 332efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else if (subfamilyID == 0 && 333efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID == 0 && 334efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod rangeStart == 0 && 335efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod rangeEnd == 0) 336b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 337efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else if (designSize < rangeStart || 338efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod designSize > rangeEnd || 339efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID < 256 || 340efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID > 32767) 341b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 342efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else 343b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 344f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 345f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 3466f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 designSize; /* Represents the design size in 720/inch 347875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * units (decipoints). The design size entry 348875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * must be non-zero. When there is a design 349875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * size but no recommended size range, the 350875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * rest of the array will consist of zeros. */ 3516f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 subfamilyID; /* Has no independent meaning, but serves 352875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * as an identifier that associates fonts 353875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * in a subfamily. All fonts which share a 354875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Preferred or Font Family name and which 355875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * differ only by size range shall have the 356875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * same subfamily value, and no fonts which 357875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * differ in weight or style shall have the 358875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * same subfamily value. If this value is 359875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * zero, the remaining fields in the array 360875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * will be ignored. */ 3616f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 subfamilyNameID;/* If the preceding value is non-zero, this 362875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * value must be set in the range 256 - 32767 363875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive). It records the value of a 364875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * field in the name table, which must 365875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * contain English-language strings encoded 366875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * in Windows Unicode and Macintosh Roman, 367875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * and may contain additional strings 368875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * localized to other scripts and languages. 369875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Each of these strings is the name an 370875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * application should use, in combination 371875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * with the family name, to represent the 372875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * subfamily in a menu. Applications will 373875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * choose the appropriate version based on 374875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * their selection criteria. */ 3756f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 rangeStart; /* Large end of the recommended usage range 376875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive), stored in 720/inch units 377875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 3786f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 rangeEnd; /* Small end of the recommended usage range 379875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod (exclusive), stored in 720/inch units 380875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 381f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod public: 382f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod DEFINE_SIZE_STATIC (10); 383f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod}; 384f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 385875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ 386875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbodstruct FeatureParamsStylisticSet 387875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod{ 388de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 389de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 390875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod TRACE_SANITIZE (this); 391875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod /* Right now minorVersion is at zero. Which means, any table supports 392875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * the uiNameID field. */ 393b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 394875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod } 395875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 3966f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 version; /* (set to 0): This corresponds to a “minor” 397875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * version number. Additional data may be 398875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * added to the end of this Feature Parameters 399875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * table in the future. */ 400875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 4016f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 uiNameID; /* The 'name' table name ID that specifies a 402875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * string (or strings, for multiple languages) 403875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * for a user-interface label for this 404875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * feature. The values of uiLabelNameId and 405875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * sampleTextNameId are expected to be in the 406875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * font-specific name ID range (256-32767), 407875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * though that is not a requirement in this 408875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Feature Parameters specification. The 409875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * user-interface label for the feature can 410875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * be provided in multiple languages. An 411875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * English string should be included as a 412875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * fallback. The string should be kept to a 413875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * minimal length to fit comfortably with 414875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * different application interfaces. */ 415875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod public: 416875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod DEFINE_SIZE_STATIC (4); 417875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod}; 418875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 419a182dbc9e4e51fa7990c4aea3eaa425a061b29c7Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ 4200bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbodstruct FeatureParamsCharacterVariants 4210bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod{ 422de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 423de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 4240bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod TRACE_SANITIZE (this); 425b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 426b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod characters.sanitize (c)); 4270bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod } 428efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 4296f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format number is set to 0. */ 4306f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 featUILableNameID; /* The ‘name’ table name ID that 4310bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies a string (or strings, 4320bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * for multiple languages) for a 4330bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * user-interface label for this 434dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod * feature. (May be nullptr.) */ 4356f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 featUITooltipTextNameID;/* The ‘name’ table name ID that 4360bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies a string (or strings, 4370bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * for multiple languages) that an 4380bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * application can use for tooltip 4390bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * text for this feature. (May be 440dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod * nullptr.) */ 4416f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 sampleTextNameID; /* The ‘name’ table name ID that 4420bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies sample text that 4430bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * illustrates the effect of this 444dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod * feature. (May be nullptr.) */ 4456f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 numNamedParameters; /* Number of named parameters. (May 4460bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * be zero.) */ 4476f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID 4480bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * used to specify strings for 4490bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * user-interface labels for the 4500bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature parameters. (Must be zero 4510bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * if numParameters is zero.) */ 4520bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod ArrayOf<UINT24> 4530bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod characters; /* Array of the Unicode Scalar Value 4540bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * of the characters for which this 4550bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature provides glyph variants. 4560bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * (May be zero.) */ 4570bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod public: 4580bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod DEFINE_SIZE_ARRAY (14, characters); 4590bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod}; 4600bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod 461f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodstruct FeatureParams 462f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 463de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const 464de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 465f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod TRACE_SANITIZE (this); 466efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == HB_TAG ('s','i','z','e')) 467b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (u.size.sanitize (c)); 4687627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ 469b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (u.stylisticSet.sanitize (c)); 4707627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ 471b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (u.characterVariants.sanitize (c)); 472b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 473f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 474f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 475efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const 476efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod { 477efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == HB_TAG ('s','i','z','e')) 478efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return u.size; 479efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return Null(FeatureParamsSize); 480efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod } 481efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 482efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod private: 483f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod union { 4840bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsSize size; 4850bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsStylisticSet stylisticSet; 4860bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsCharacterVariants characterVariants; 487f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } u; 4880bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod DEFINE_SIZE_STATIC (17); 489f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod}; 4906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 49160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Feature 49260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 493bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lookup_count (void) const 494bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return lookupIndex.len; } 495bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline hb_tag_t get_lookup_index (unsigned int i) const 496bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return lookupIndex[i]; } 497e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_lookup_indexes (unsigned int start_index, 498e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lookup_count /* IN/OUT */, 499e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lookup_tags /* OUT */) const 500e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } 5016f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 502f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod inline const FeatureParams &get_feature_params (void) const 503f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod { return this+featureParams; } 504f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 50587e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 506dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod const Record<Feature>::sanitize_closure_t *closure = nullptr) const 507de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 508be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 5099b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) 510b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 5119b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 512efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod /* Some earlier versions of Adobe tools calculated the offset of the 513efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * FeatureParams subtable from the beginning of the FeatureList table! 514efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 515efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If sanitizing "failed" for the FeatureParams subtable, try it with the 516efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * alternative location. We would know sanitize "failed" if old value 517efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * of the offset was non-zero, but it's zeroed now. 5181ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * 5191ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * Only do this for the 'size' feature, since at the time of the faulty 5201ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * Adobe tools, only the 'size' feature had FeatureParams defined. 521efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod */ 522efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 523586b60622c33878f9ca4826b4ef07369d32bf039Behdad Esfahbod OffsetTo<FeatureParams> orig_offset = featureParams; 524efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) 525b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 526efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 5279da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod if (likely (orig_offset.is_null ())) 528b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 5299b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 5301ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod if (featureParams == 0 && closure && 5311ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod closure->tag == HB_TAG ('s','i','z','e') && 5321ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod closure->list_base && closure->list_base < this) 5339b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod { 534efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod unsigned int new_offset_int = (unsigned int) orig_offset - 535dac86026a6bae5a8a03cfe885bf93f32e5f48614Behdad Esfahbod (((char *) this) - ((char *) closure->list_base)); 536efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 537586b60622c33878f9ca4826b4ef07369d32bf039Behdad Esfahbod OffsetTo<FeatureParams> new_offset; 5389b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod /* Check that it did not overflow. */ 539efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod new_offset.set (new_offset_int); 540efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (new_offset == new_offset_int && 54151f563579b94e1ee23ced9bbcc7dd3341535ce72Behdad Esfahbod c->try_set (&featureParams, new_offset) && 542efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) 543b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 544da2fcfdc51a2cc0d0a782efa6c91b733f7aa84baBehdad Esfahbod 545da2fcfdc51a2cc0d0a782efa6c91b733f7aa84baBehdad Esfahbod if (c->edit_count > 1) 546da2fcfdc51a2cc0d0a782efa6c91b733f7aa84baBehdad Esfahbod c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */ 5479b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod } 5489b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 549b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 550cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 551cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 552f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod OffsetTo<FeatureParams> 553f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod featureParams; /* Offset to Feature Parameters table (if one 5546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * has been defined for the feature), relative 5556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * to the beginning of the Feature Table; = Null 5566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * if not required */ 557bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod IndexArray lookupIndex; /* Array of LookupList indices */ 558b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 5590eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, lookupIndex); 5606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 5616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Feature> FeatureList; 5636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5656f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbodstruct LookupFlag : UINT16 56660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 567c6035cf802c60f0526f421f39a55886061df94eeBehdad Esfahbod enum Flags { 5684fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod RightToLeft = 0x0001u, 5694fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreBaseGlyphs = 0x0002u, 5704fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreLigatures = 0x0004u, 5714fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreMarks = 0x0008u, 572aa87d951739f6beacb66daa235cd033fdcfcadd7Behdad Esfahbod IgnoreFlags = 0x000Eu, 573d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod UseMarkFilteringSet = 0x0010u, 574d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod Reserved = 0x00E0u, 5758f034d5849627ee95a5889fa34c9ba294fff13caBehdad Esfahbod MarkAttachmentType = 0xFF00u 5764fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod }; 577b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 578b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (2); 5796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 5806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 581aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod} /* namespace OT */ 582aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod/* This has to be outside the namespace. */ 583167c3271778cd1a8c4433b9d2230901ce17c099eChun-wei FanHB_MARK_AS_FLAG_T (OT::LookupFlag::Flags); 584aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbodnamespace OT { 585aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod 58660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Lookup 58760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 58860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_subtable_count (void) const { return subTable.len; } 5896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 59070366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod template <typename SubTableType> 59170366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod inline const SubTableType& get_subtable (unsigned int i) const 59270366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; } 59370366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod 59470366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod template <typename SubTableType> 59570366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod inline const OffsetArrayOf<SubTableType>& get_subtables (void) const 59670366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod { return CastR<OffsetArrayOf<SubTableType> > (subTable); } 59770366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod template <typename SubTableType> 59870366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod inline OffsetArrayOf<SubTableType>& get_subtables (void) 59970366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod { return CastR<OffsetArrayOf<SubTableType> > (subTable); } 60070366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod 6016f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod inline unsigned int get_type (void) const { return lookupType; } 6028c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod 6038c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and 6048c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod * higher 16-bit is mark-filtering-set if the lookup uses one. 6058c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod * Not to be confused with glyph_props which is very similar. */ 6068c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod inline uint32_t get_props (void) const 607d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod { 608d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod unsigned int flag = lookupFlag; 60964d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) 610d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod { 6116f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable); 61209c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod flag += (markFilteringSet << 16); 613d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod } 614d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod return flag; 615d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod } 6166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 61740c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod template <typename SubTableType, typename context_t> 61840c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 61940c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod { 62040c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod unsigned int lookup_type = get_type (); 62140c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod TRACE_DISPATCH (this, lookup_type); 62240c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod unsigned int count = get_subtable_count (); 62340c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod for (unsigned int i = 0; i < count; i++) { 62440c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type); 62540c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod if (c->stop_sublookup_iteration (r)) 626b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (r); 62740c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod } 628b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->default_return_value ()); 62940c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod } 63040c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod 631652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 632652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod unsigned int lookup_type, 633652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod uint32_t lookup_props, 634652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod unsigned int num_subtables) 635652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod { 636be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 637b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 638652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod lookupType.set (lookup_type); 6397627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod lookupFlag.set (lookup_props & 0xFFFFu); 640b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); 641b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (lookupFlag & LookupFlag::UseMarkFilteringSet) 642652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod { 6436f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 &markFilteringSet = StructAfter<UINT16> (subTable); 644652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod markFilteringSet.set (lookup_props >> 16); 645652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod } 646b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 647652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod } 648652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod 649de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 650de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 651be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 6523b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod /* Real sanitize of the subtables is done by GSUB/GPOS/... */ 653b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); 654652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod if (lookupFlag & LookupFlag::UseMarkFilteringSet) 655cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod { 6566f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable); 657b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!markFilteringSet.sanitize (c)) return_trace (false); 658cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 659b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 660cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 661cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 66270366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod private: 6636f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 lookupType; /* Different enumerations for GSUB and GPOS */ 6646f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 lookupFlag; /* Lookup qualifiers */ 665c6173a392cfaa3d339c768836e8cddf3ae4adc53Behdad Esfahbod ArrayOf<Offset16> 666d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod subTable; /* Array of SubTables */ 6676f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets 668d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod * structure. This field is only present if bit 669d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod * UseMarkFilteringSet of lookup flags is set. */ 670569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 6718dddc231cf9d934eb93a39f2657717cbdad43a64Behdad Esfahbod DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); 6726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 6736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6746f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef OffsetListOf<Lookup> LookupList; 6756f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 6786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Coverage Table 6796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 6806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 68160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat1 68260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 6846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 68660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 68760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 688df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = glyphArray.bsearch (glyph_id); 689c3448e8d21963eb7fc357a37a7a426a4bf130ef3Behdad Esfahbod static_assert ((((unsigned int) -1) == NOT_COVERED), ""); 690dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod return i; 6916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 6926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 693bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 694a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 695bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 6969f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 697be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 698b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 699bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod glyphArray.len.set (num_glyphs); 700b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend (glyphArray))) return_trace (false); 7019f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 0; i < num_glyphs; i++) 702fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod glyphArray[i] = glyphs[i]; 703a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 704b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 7059f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 7069f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 707de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 708de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 709be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 710b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (glyphArray.sanitize (c)); 71170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 71270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 7136a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 71431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->has (glyphArray[index]); 71531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 71631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 717c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 7185d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 7195d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod return glyphs->add_sorted_array (glyphArray.array, glyphArray.len); 72067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 72167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 722365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 723365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 7247d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 725c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; 726c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->glyphArray.len; } 727c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { i++; } 728eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline hb_codepoint_t get_glyph (void) { return c->glyphArray[i]; } 729eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline unsigned int get_coverage (void) { return i; } 7307d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 7317d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 7327d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat1 *c; 7337d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod unsigned int i; 7347d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 735365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 7367d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 737ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 7386f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 coverageFormat; /* Format identifier--format = 1 */ 739cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<GlyphID> 7406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod glyphArray; /* Array of GlyphIDs--in numerical order */ 741b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 7420eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, glyphArray); 7436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 7446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 74560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat2 74660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 7476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 7486f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 7496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 75060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 75160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 752df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = rangeRecord.bsearch (glyph_id); 753cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 754cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 755cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return (unsigned int) range.value + (glyph_id - range.start); 7566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return NOT_COVERED; 7586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 760bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 761a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 762bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 7639f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 764be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 765b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 766bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 767851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod if (unlikely (!num_glyphs)) 768851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod { 769851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod rangeRecord.len.set (0); 770851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod return_trace (true); 771851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod } 772bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7739f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 7749f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7759f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 7769f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 777bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord.len.set (num_ranges); 778b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend (rangeRecord))) return_trace (false); 779bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7809f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int range = 0; 781fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[0]; 782bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].value.set (0); 7839f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7849f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) { 7859f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod range++; 786fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[i]; 787fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].value.set (i); 788fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7899f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } else { 790bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7919f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 792a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 793b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 7949f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 7959f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 796de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 797de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 798be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 799b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rangeRecord.sanitize (c)); 80070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 80170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 8026a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 80331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int i; 80431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 80531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (i = 0; i < count; i++) { 80631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 80731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (range.value <= index && 8083f18236a03880c0960f5990dc90685f6146951a6Behdad Esfahbod index < (unsigned int) range.value + (range.end - range.start) && 80931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod range.intersects (glyphs)) 81031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 81131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod else if (index < range.value) 81231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 81331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 81431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 81531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 81631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 817c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 8185d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 81967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = rangeRecord.len; 82067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 8215d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod if (unlikely (!rangeRecord[i].add_coverage (glyphs))) 822a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod return false; 8235d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod return true; 82467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 82567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 826365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 827365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 828eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod struct Iter 829eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod { 830eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline void init (const CoverageFormat2 &c_) 831eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod { 832c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod c = &c_; 833c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod coverage = 0; 834c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod i = 0; 835c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; 836c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 837c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->rangeRecord.len; } 838eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline void next (void) 839eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod { 840eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod if (j >= c->rangeRecord[i].end) 841eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod { 8427d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod i++; 8430da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod if (more ()) 844eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod { 8450da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod j = c->rangeRecord[i].start; 846eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod coverage = c->rangeRecord[i].value; 847eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod } 8480da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod return; 8497d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 850eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod coverage++; 8510da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod j++; 8520da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 853eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline hb_codepoint_t get_glyph (void) { return j; } 854eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline unsigned int get_coverage (void) { return coverage; } 8557d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 8567d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 8577d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat2 *c; 858c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int i, j, coverage; 8597d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 860365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 8617d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 862ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 8636f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 coverageFormat; /* Format identifier--format = 2 */ 864cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 8656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 8666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID. rangeCount entries 8676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * long */ 868b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 8690eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 8706f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 8716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 87260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Coverage 87360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 87420b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 87560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 8766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 877dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_coverage(glyph_id); 878dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_coverage(glyph_id); 8796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return NOT_COVERED; 8806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 8816f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 8826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 883bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 884a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 885bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 8869f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 887be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 888b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 8899f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 8909f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 8919f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 8929f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 893bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); 894bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod switch (u.format) { 895b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs)); 896b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs)); 897b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (false); 8989f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 8999f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 9009f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 901de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 902de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 903be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 904b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 90570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 906b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 907b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.sanitize (c)); 908b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 90970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 91070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 9116f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9126a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects (const hb_set_t *glyphs) const { 913c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod /* TODO speed this up */ 914c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 915c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (*this); iter.more (); iter.next ()) { 916c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (glyphs->has (iter.get_glyph ())) 917c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod return true; 918c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 919c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod return false; 92031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 921c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 9226a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 92331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 92431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_coverage (glyphs, index); 92531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_coverage (glyphs, index); 92631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 92731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 928c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 929c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 9305d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod /* Might return false if array looks unsorted. 9315d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod * Used for faster rejection of corrupt data. */ 932c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 9335d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 93467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod switch (u.format) { 9355d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod case 1: return u.format1.add_coverage (glyphs); 9365d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod case 2: return u.format2.add_coverage (glyphs); 937a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod default:return false; 93867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 93967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 94067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 9417d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 9428820ba29dfd2e1302377da62a0527939a0d7d9fbBehdad Esfahbod Iter (void) : format (0), u () {}; 943c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const Coverage &c_) { 9447d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod format = c_.u.format; 9457d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 94648382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 1: u.format1.init (c_.u.format1); return; 94748382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 2: u.format2.init (c_.u.format2); return; 94848382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default: return; 9497d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9507d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 951c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { 9527d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 9537d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 1: return u.format1.more (); 9547d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 2: return u.format2.more (); 95548382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return false; 9567d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9577d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 958c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { 9590da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod switch (format) { 9600da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 1: u.format1.next (); break; 9610da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 2: u.format2.next (); break; 9620da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod default: break; 9630da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 9640da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 965eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline hb_codepoint_t get_glyph (void) { 966c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod switch (format) { 967c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_glyph (); 968c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_glyph (); 96948382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return 0; 970c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 971c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 972eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline unsigned int get_coverage (void) { 9737d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 974c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_coverage (); 975c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_coverage (); 97648382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return -1; 9777d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9787d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9797d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 9807d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 981c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int format; 9827d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod union { 9838820ba29dfd2e1302377da62a0527939a0d7d9fbBehdad Esfahbod CoverageFormat2::Iter format2; /* Put this one first since it's larger; helps shut up compiler. */ 9847d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod CoverageFormat1::Iter format1; 9857d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } u; 9867d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 9877d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 988ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 9896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 9906f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 991dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat1 format1; 992dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat2 format2; 9936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 994ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 995596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 9966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 9976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 10006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Class Definition Table 10016f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 10026f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 100360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat1 100460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 10056f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 10066f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10076f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 100898370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 100960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1010ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod unsigned int i = (unsigned int) (glyph_id - startGlyph); 1011ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod if (unlikely (i < classValue.len)) 1012ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod return classValue[i]; 10136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 10146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1016de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1017de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1018be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1019b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && classValue.sanitize (c)); 102070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 102170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 102289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 102371e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 102471e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod unsigned int start = 0; 102571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod unsigned int count = classValue.len; 102671e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 102771e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod { 102871e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (classValue[i]) 102971e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod continue; 103071e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod 103171e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (start != i) 103271e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i))) 1033a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod return false; 103471e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod 103571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod start = i + 1; 103671e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod } 103771e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (start != count) 103871e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count))) 1039a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod return false; 104071e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod 104171e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod return true; 104271e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod } 104371e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod 104471e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod template <typename set_t> 104571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod inline bool add_class (set_t *glyphs, unsigned int klass) const { 104689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = classValue.len; 104789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 10485d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod { 104971e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (classValue[i] == klass) 105089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod glyphs->add (startGlyph + i); 10515d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod } 10525d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod return true; 105389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 105489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10556a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 105631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = classValue.len; 1057625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1058625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1059625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1060625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod hb_codepoint_t g = -1; 1061625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1062625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return false; 1063625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < startGlyph) 1064625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1065625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = startGlyph + count - 1; 1066625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (hb_set_next (glyphs, &g)) 1067625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1068625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1069625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 107031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 107131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (classValue[i] == klass && glyphs->has (startGlyph + i)) 107231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 107331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 107431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 107531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1076ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 10776f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 classFormat; /* Format identifier--format = 1 */ 10786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod GlyphID startGlyph; /* First GlyphID of the classValueArray */ 10796f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod ArrayOf<UINT16> 10806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod classValue; /* Array of Class Values--one per GlyphID */ 1081b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 10820eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, classValue); 10836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 10846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 108560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat2 108660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 10876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 10886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 109098370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 109160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1092df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = rangeRecord.bsearch (glyph_id); 10938e3d4bae033bdec649676da26cfc3eb7610832a8Behdad Esfahbod if (unlikely (i != -1)) 1094cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return rangeRecord[i].value; 10956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 10966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1098de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1099de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1100be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1101b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rangeRecord.sanitize (c)); 110270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 110370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 110489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 110571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 110671e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod unsigned int count = rangeRecord.len; 110771e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 110871e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (rangeRecord[i].value) 110971e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (unlikely (!rangeRecord[i].add_coverage (glyphs))) 1110a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod return false; 111171e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod return true; 111271e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod } 111371e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod 111471e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod template <typename set_t> 111571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod inline bool add_class (set_t *glyphs, unsigned int klass) const { 111689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = rangeRecord.len; 111789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 11185d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod { 111971e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod if (rangeRecord[i].value == klass) 11205d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod if (unlikely (!rangeRecord[i].add_coverage (glyphs))) 1121a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod return false; 11225d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod } 11235d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod return true; 112489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 112589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 11266a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 112731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 1128625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1129625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1130625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1131515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod hb_codepoint_t g = (hb_codepoint_t) -1; 1132625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1133625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1134625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1135625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod break; 1136625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < rangeRecord[i].start) 1137625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1138625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = rangeRecord[i].end; 1139625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 1140515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) 1141625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1142625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1143625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 114431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 114531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) 114631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 114731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 114831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 114931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1150ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11516f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 classFormat; /* Format identifier--format = 2 */ 1152cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 11536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 11546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID */ 1155b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 11560eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 11576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 11586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 115960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDef 116060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 116198370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 116260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 11636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 1164dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_class(glyph_id); 1165dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_class(glyph_id); 11666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return 0; 11676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 11686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 11696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1170de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1171de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1172be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1173b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 117470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 1175b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 1176b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.sanitize (c)); 1177b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 117870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 117970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 1180aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 118171e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod /* Might return false if array looks unsorted. 118271e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod * Used for faster rejection of corrupt data. */ 118371e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod template <typename set_t> 118471e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod inline bool add_coverage (set_t *glyphs) const { 118571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod switch (u.format) { 118671e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod case 1: return u.format1.add_coverage (glyphs); 118771e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod case 2: return u.format2.add_coverage (glyphs); 1188a7bd6d7a4c53ff61d7d8286a594aaa0a0e15b1a1Behdad Esfahbod default:return false; 118971e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod } 119071e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod } 119171e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod 119271e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod /* Might return false if array looks unsorted. 119371e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod * Used for faster rejection of corrupt data. */ 11945d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod template <typename set_t> 119571e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod inline bool add_class (set_t *glyphs, unsigned int klass) const { 119689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod switch (u.format) { 119771e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod case 1: return u.format1.add_class (glyphs, klass); 119871e6adf1e2d65eb905a0ba247672fe36169955efBehdad Esfahbod case 2: return u.format2.add_class (glyphs, klass); 11995d02572034e3dafbe87000fd0aa34b858bd95075Behdad Esfahbod default:return false; 120089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 120189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 120289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 12036a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 120431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 120531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_class (glyphs, klass); 120631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_class (glyphs, klass); 120731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 120831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 120931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 121031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1211ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 12126f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 12136f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 1214dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat1 format1; 1215dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat2 format2; 12166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 1217ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 1218596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 12196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 12206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 12216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 12226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 1223dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod * Item Variation Store 1224dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod */ 1225dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1226dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarRegionAxis 1227dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1228dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float evaluate (int coord) const 1229dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1230dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int start = startCoord, peak = peakCoord, end = endCoord; 1231dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1232dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* TODO Move these to sanitize(). */ 1233dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (start > peak || peak > end)) 1234dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1235dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (start < 0 && end > 0 && peak != 0)) 1236dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1237dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1238dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (peak == 0 || coord == peak) 1239dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1240dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1241dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (coord <= start || end <= coord) 1242dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1243dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1244dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* Interpolate */ 1245dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (coord < peak) 1246dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return float (coord - start) / (peak - start); 1247dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod else 1248dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return float (end - coord) / (end - peak); 1249dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1250dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1251dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1252dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1253dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1254dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this)); 1255dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* TODO Handle invalid start/peak/end configs, so we don't 1256dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod * have to do that at runtime. */ 1257dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1258dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1259dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1260dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 startCoord; 1261dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 peakCoord; 1262dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 endCoord; 1263dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1264dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_STATIC (6); 1265dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1266dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1267dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarRegionList 1268dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1269dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float evaluate (unsigned int region_index, 1270dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_len) const 1271dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1272dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (region_index >= regionCount)) 1273dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1274dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1275dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const VarRegionAxis *axes = axesZ + (region_index * axisCount); 1276dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1277dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float v = 1.; 1278dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int count = MIN (coord_len, (unsigned int) axisCount); 1279dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1280dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1281dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float factor = axes[i].evaluate (coords[i]); 1282dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (factor == 0.) 1283dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1284dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod v *= factor; 1285dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1286dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return v; 1287dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1288dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1289dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1290dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1291dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1292dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1293dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod c->check_array (axesZ, axesZ[0].static_size, 1294dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod (unsigned int) axisCount * (unsigned int) regionCount)); 1295dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1296dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1297dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 12986f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 axisCount; 12996f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 regionCount; 1300dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod VarRegionAxis axesZ[VAR]; 1301dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1302dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY (4, axesZ); 1303dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1304dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1305dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarData 1306dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1307dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline unsigned int get_row_size (void) const 1308dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { return shortCount + regionIndices.len; } 1309dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1310dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline unsigned int get_size (void) const 1311dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { return itemCount * get_row_size (); } 1312dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1313dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float get_delta (unsigned int inner, 1314dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_count, 1315dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const VarRegionList ®ions) const 1316dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1317dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (inner >= itemCount)) 1318dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1319dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1320dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int count = regionIndices.len; 1321dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int scount = shortCount; 1322dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 13236f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT8 *bytes = &StructAfter<UINT8> (regionIndices); 13246f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const UINT8 *row = bytes + inner * (scount + count); 1325dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1326dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float delta = 0.; 1327dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int i = 0; 1328dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 13296f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod const INT16 *scursor = reinterpret_cast<const INT16 *> (row); 1330dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (; i < scount; i++) 1331dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1332dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); 1333dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod delta += scalar * *scursor++; 1334dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1335dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor); 1336dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (; i < count; i++) 1337dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1338dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); 1339dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod delta += scalar * *bcursor++; 1340dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1341dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1342dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return delta; 1343dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1344dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1345dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1346dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1347dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1348dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1349dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod regionIndices.sanitize(c) && 1350dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod shortCount <= regionIndices.len && 13516f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod c->check_array (&StructAfter<UINT8> (regionIndices), 1352dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod get_row_size (), itemCount)); 1353dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1354dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1355dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 13566f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 itemCount; 13576f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 shortCount; 13586f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod ArrayOf<UINT16> regionIndices; 13596f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT8 bytesX[VAR]; 1360dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1361dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); 1362dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1363dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1364cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbodstruct VariationStore 1365dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1366dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float get_delta (unsigned int outer, unsigned int inner, 1367dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_count) const 1368dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1369dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (outer >= dataSets.len)) 1370dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1371dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1372dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return (this+dataSets[outer]).get_delta (inner, 1373dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod coords, coord_count, 1374dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod this+regions); 1375dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1376dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1377a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod inline float get_delta (unsigned int index, 1378a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod int *coords, unsigned int coord_count) const 1379a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod { 1380a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod unsigned int outer = index >> 16; 1381a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod unsigned int inner = index & 0xFFFF; 1382a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod return get_delta (outer, inner, coords, coord_count); 1383a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod } 1384a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod 1385dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1386dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1387dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1388dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1389dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod format == 1 && 1390dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod regions.sanitize (c, this) && 1391dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod dataSets.sanitize (c, this)); 1392dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1393dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1394dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 13956f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; 13965e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<VarRegionList> regions; 13976f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod OffsetArrayOf<VarData, UINT32> dataSets; 1398dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1399dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY (8, dataSets); 1400dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1401dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 140259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod/* 140359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod * Feature Variations 140459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod */ 140559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 140659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct ConditionFormat1 140759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 140859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod friend struct Condition; 140959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 141059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod private: 141130c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool evaluate (const int *coords, unsigned int coord_len) const 141259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 141359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod int coord = axisIndex < coord_len ? coords[axisIndex] : 0; 141459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return filterRangeMinValue <= coord && coord <= filterRangeMaxValue; 141559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 141659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 141759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 141859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 141959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 142059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (c->check_struct (this)); 142159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 142259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 142359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 14246f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier--format = 1 */ 14256f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 axisIndex; 142659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod F2DOT14 filterRangeMinValue; 142759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod F2DOT14 filterRangeMaxValue; 142859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 142959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_STATIC (8); 143059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 143159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 143259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct Condition 143359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 143430c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool evaluate (const int *coords, unsigned int coord_len) const 143559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 143659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod switch (u.format) { 143759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod case 1: return u.format1.evaluate (coords, coord_len); 143859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod default:return false; 143959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 144059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 144159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 144259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 144359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 144459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 144559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 144659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod switch (u.format) { 144759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 144859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod default:return_trace (true); 144959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 145059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 145159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 145259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 145359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod union { 14546f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 145559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod ConditionFormat1 format1; 145659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } u; 145759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 145859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 145959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 146059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 146159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct ConditionSet 146259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 146330c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool evaluate (const int *coords, unsigned int coord_len) const 146459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 146559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod unsigned int count = conditions.len; 146659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 146759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod if (!(this+conditions.array[i]).evaluate (coords, coord_len)) 146859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return false; 146959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return true; 147059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 147159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 147259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 147359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 147459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 147559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (conditions.sanitize (c, this)); 147659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 147759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 147859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 14796f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod OffsetArrayOf<Condition, UINT32> conditions; 148059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 148159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_ARRAY (2, conditions); 148259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 148359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 148459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureTableSubstitutionRecord 148559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 14864ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod friend struct FeatureTableSubstitution; 1487ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 14884ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 148959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 149059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 14914ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod return_trace (c->check_struct (this) && feature.sanitize (c, base)); 149259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 149359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 149459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 14956f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 featureIndex; 14965e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<Feature> feature; 149759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 149859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_STATIC (6); 149959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 150059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 150159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureTableSubstitution 150259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 1503ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod inline const Feature *find_substitute (unsigned int feature_index) const 1504ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 1505ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod unsigned int count = substitutions.len; 1506ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 1507ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 15084ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod const FeatureTableSubstitutionRecord &record = substitutions.array[i]; 15094ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod if (record.featureIndex == feature_index) 15104ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod return &(this+record.feature); 1511ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 1512dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod return nullptr; 1513ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 1514ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 151559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 151659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 151759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 151859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (version.sanitize (c) && 151959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod likely (version.major == 1) && 152059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions.sanitize (c, this)); 152159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 152259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 152359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 152459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod FixedVersion<> version; /* Version--0x00010000u */ 15254ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod ArrayOf<FeatureTableSubstitutionRecord> 152659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions; 152759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 152859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_ARRAY (6, substitutions); 152959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 153059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 153159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureVariationRecord 153259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 153359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod friend struct FeatureVariations; 153459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 153559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 153659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 153759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 153859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (conditions.sanitize (c, base) && 153959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions.sanitize (c, base)); 154059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 154159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 154259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 15435e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<ConditionSet> 154459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod conditions; 15455e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<FeatureTableSubstitution> 154659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions; 154759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 154859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_STATIC (8); 154959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 155059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 155159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureVariations 155259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 1553ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod static const unsigned int NOT_FOUND_INDEX = 0xFFFFFFFFu; 1554ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 155530c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool find_index (const int *coords, unsigned int coord_len, 155630c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod unsigned int *index) const 155759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 155859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod unsigned int count = varRecords.len; 155959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 156059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 156159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod const FeatureVariationRecord &record = varRecords.array[i]; 156259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod if ((this+record.conditions).evaluate (coords, coord_len)) 156330c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod { 156430c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod *index = i; 156530c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod return true; 156630c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod } 156759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 1568ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod *index = NOT_FOUND_INDEX; 156930c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod return false; 157059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 157159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 1572ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod inline const Feature *find_substitute (unsigned int variations_index, 1573ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod unsigned int feature_index) const 1574ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 1575ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod const FeatureVariationRecord &record = varRecords[variations_index]; 1576ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod return (this+record.substitutions).find_substitute (feature_index); 1577ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 1578ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 157959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 158059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 158159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 158259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (version.sanitize (c) && 158359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod likely (version.major == 1) && 158459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod varRecords.sanitize (c, this)); 158559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 158659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 158759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 158859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod FixedVersion<> version; /* Version--0x00010000u */ 1589b732c53eb5bd0c2cc86f35a9d9623c92579a0b8cBehdad Esfahbod LArrayOf<FeatureVariationRecord> 159059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod varRecords; 159159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 159259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_ARRAY (8, varRecords); 159359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 159459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 1595dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1596dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod/* 15976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Device Tables 15986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 15996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 16004c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbodstruct HintingDevice 160160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 16024c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod friend struct Device; 16034c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 16044c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod private: 1605b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1606abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font) const 1607abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->x_ppem, font->x_scale); } 1608b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1609abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font) const 1610abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->y_ppem, font->y_scale); } 1611b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1612d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod inline unsigned int get_size (void) const 1613d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod { 1614d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod unsigned int f = deltaFormat; 16156f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * UINT16::static_size; 16166f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod return UINT16::static_size * (4 + ((endSize - startSize) >> (4 - f))); 1617d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod } 1618d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1619d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1620d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod { 1621d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod TRACE_SANITIZE (this); 1622d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); 1623d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod } 1624d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1625d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod private: 1626d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1627da975419884a535281745f30f4b32fee0bc8a7a1Behdad Esfahbod inline int get_delta (unsigned int ppem, int scale) const 16285bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod { 16295bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!ppem) return 0; 16305bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 16315bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod int pixels = get_delta_pixels (ppem); 16325bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 16335bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!pixels) return 0; 16345bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 163583408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod return (int) (pixels * (int64_t) scale / ppem); 16365bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod } 16375bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod inline int get_delta_pixels (unsigned int ppem_size) const 163860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1639056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int f = deltaFormat; 164064d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (f < 1 || f > 3)) 1641056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 16426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1643056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod if (ppem_size < startSize || ppem_size > endSize) 1644056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 16456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1646056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int s = ppem_size - startSize; 16476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1648056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int byte = deltaValue[s >> (4 - f)]; 164909c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); 16507627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod unsigned int mask = (0xFFFFu >> (16 - (1 << f))); 1651056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1652056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod int delta = bits & mask; 1653056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 165415164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod if ((unsigned int) delta >= ((mask + 1) >> 1)) 1655056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod delta -= mask + 1; 1656056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1657056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return delta; 1658056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod } 1659056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1660ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 16616f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 startSize; /* Smallest size to correct--in ppem */ 16626f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 endSize; /* Largest size to correct--in ppem */ 16636f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 1664caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 1 Signed 2-bit value, 8 values per uint16 1665caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 2 Signed 4-bit value, 4 values per uint16 1666caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 3 Signed 8-bit value, 2 values per uint16 1667caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod */ 16686f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 deltaValue[VAR]; /* Array of compressed data */ 1669569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 16700eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, deltaValue); 16716f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 16726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 16736d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbodstruct VariationDevice 16746d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod{ 16754c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod friend struct Device; 16764c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 16774c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod private: 16786d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 1679cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store) const 168026648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod { return font->em_scalef_x (get_delta (font, store)); } 16816d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 1682cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const 168326648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod { return font->em_scalef_y (get_delta (font, store)); } 16846d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16856d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 16866d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod { 16876d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod TRACE_SANITIZE (this); 1688dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this)); 16896d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod } 16906d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16916d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod private: 16926d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 169326648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod inline float get_delta (hb_font_t *font, const VariationStore &store) const 16946d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod { 169526648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords); 16966d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod } 16976d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16986d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod protected: 16996f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 outerIndex; 17006f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 innerIndex; 17016f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */ 17026d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod public: 1703dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_STATIC (6); 17046d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod}; 17056d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 17061f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbodstruct DeviceHeader 17071f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod{ 17081f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod protected: 17096f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 reserved1; 17106f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 reserved2; 17111f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod public: 17126f335ed1e52c6161fa0b0295776856fc07f7f46fBehdad Esfahbod UINT16 format; /* Format identifier */ 17131f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod public: 17141f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod DEFINE_SIZE_STATIC (6); 17151f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod}; 17161f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod 17174c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbodstruct Device 17184c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod{ 1719219cb29c5d230ecc6ee154b447fabd7b59fbe089Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const 17204c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 17214c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) 17224c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 17234c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 17244c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return u.hinting.get_x_delta (font); 1725dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 1726151d93de8a595924a8dcb00fcba648b4b3df0bf5Behdad Esfahbod return u.variation.get_x_delta (font, store); 17274c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 17284c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return 0; 17294c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17304c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 1731219cb29c5d230ecc6ee154b447fabd7b59fbe089Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const 17324c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 17334c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) 17344c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 17354c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 173685ec4944346a1ac111217698e1424669a9732280Behdad Esfahbod return u.hinting.get_y_delta (font); 1737dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 1738151d93de8a595924a8dcb00fcba648b4b3df0bf5Behdad Esfahbod return u.variation.get_y_delta (font, store); 17394c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 17404c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return 0; 17414c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17424c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17434c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 17444c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 17454c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 17464c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod TRACE_SANITIZE (this); 17474c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod if (!u.b.format.sanitize (c)) return_trace (false); 17484c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) { 17494c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 17504c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (u.hinting.sanitize (c)); 1751dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 17524c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (u.variation.sanitize (c)); 17534c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 17544c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (true); 17554c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17564c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17574c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 17584c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod protected: 17594c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod union { 17601f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod DeviceHeader b; 17614c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod HintingDevice hinting; 17624c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod VariationDevice variation; 17634c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } u; 17644c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod public: 17654c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod DEFINE_SIZE_UNION (6, b); 17664c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod}; 17674c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 17686d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 17697d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 17707c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 1771acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 17725f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ 1773