hb-ot-layout-common-private.hh revision 40ec3bbb55b8af1668bb3d5f6232a85b15cff136
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> 158c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 15967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 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 */ 164cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod USHORT 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) { 17831f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod const USHORT *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 2197d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod Offset<> lookupOrderZ; /* = Null (reserved for an offset to a 2206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * reordering table) */ 2216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT 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 346875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT 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. */ 351875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT 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. */ 361875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT 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. */ 375875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT rangeStart; /* Large end of the recommended usage range 376875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive), stored in 720/inch units 377875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 378875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT 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 396e1ebf01d0cf3df55bb9137136e2d0c9630e7bd78Behdad Esfahbod USHORT 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 401875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT 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 4290bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT format; /* Format number is set to 0. */ 4300bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT 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.) */ 4350bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT 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.) */ 4410bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT 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.) */ 4450bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT numNamedParameters; /* Number of named parameters. (May 4460bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * be zero.) */ 4470bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT 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 56560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LookupFlag : USHORT 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 { 611e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const USHORT &markFilteringSet = StructAfter<USHORT> (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 { 643652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod USHORT &markFilteringSet = StructAfter<USHORT> (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 { 6568dddc231cf9d934eb93a39f2657717cbdad43a64Behdad Esfahbod const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 657b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!markFilteringSet.sanitize (c)) return_trace (false); 658cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 659b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 660cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 661cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 66270366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod private: 663d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod USHORT lookupType; /* Different enumerations for GSUB and GPOS */ 664d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod USHORT lookupFlag; /* Lookup qualifiers */ 66599d281712390fd54e523b2f0580d10445457ec2fBehdad Esfahbod ArrayOf<Offset<> > 666d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod subTable; /* Array of SubTables */ 667d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod USHORT 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> 718c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 71967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = glyphArray.len; 72067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 72167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod glyphs->add (glyphArray[i]); 72267bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 72367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 724365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 725365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 7267d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 727c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; 728c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->glyphArray.len; } 729c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { i++; } 730eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline hb_codepoint_t get_glyph (void) { return c->glyphArray[i]; } 731eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline unsigned int get_coverage (void) { return i; } 7327d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 7337d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 7347d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat1 *c; 7357d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod unsigned int i; 7367d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 737365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 7387d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 739ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 7406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT coverageFormat; /* Format identifier--format = 1 */ 741cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<GlyphID> 7426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod glyphArray; /* Array of GlyphIDs--in numerical order */ 743b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 7440eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, glyphArray); 7456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 7466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 74760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat2 74860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 7496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 7506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 7516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 75260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 75360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 754df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = rangeRecord.bsearch (glyph_id); 755cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 756cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 757cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return (unsigned int) range.value + (glyph_id - range.start); 7586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return NOT_COVERED; 7606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 762bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 763a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 764bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 7659f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 766be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 767b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 768bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 769851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod if (unlikely (!num_glyphs)) 770851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod { 771851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod rangeRecord.len.set (0); 772851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod return_trace (true); 773851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod } 774bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7759f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 7769f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7779f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 7789f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 779bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord.len.set (num_ranges); 780b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend (rangeRecord))) return_trace (false); 781bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7829f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int range = 0; 783fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[0]; 784bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].value.set (0); 7859f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7869f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) { 7879f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod range++; 788fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[i]; 789fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].value.set (i); 790fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7919f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } else { 792bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7939f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 794a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 795b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 7969f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 7979f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 798de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 799de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 800be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 801b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rangeRecord.sanitize (c)); 80270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 80370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 8046a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 80531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int i; 80631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 80731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (i = 0; i < count; i++) { 80831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 80931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (range.value <= index && 8103f18236a03880c0960f5990dc90685f6146951a6Behdad Esfahbod index < (unsigned int) range.value + (range.end - range.start) && 81131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod range.intersects (glyphs)) 81231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 81331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod else if (index < range.value) 81431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 81531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 81631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 81731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 81831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 819c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 820c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 82167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = rangeRecord.len; 82267bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 82367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod rangeRecord[i].add_coverage (glyphs); 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: 8636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT 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 930c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 931c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 93267bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod switch (u.format) { 93367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod case 1: u.format1.add_coverage (glyphs); break; 93467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod case 2: u.format2.add_coverage (glyphs); break; 93567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod default: break; 93667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 93767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 93867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 9397d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 9408820ba29dfd2e1302377da62a0527939a0d7d9fbBehdad Esfahbod Iter (void) : format (0), u () {}; 941c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const Coverage &c_) { 9427d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod format = c_.u.format; 9437d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 94448382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 1: u.format1.init (c_.u.format1); return; 94548382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 2: u.format2.init (c_.u.format2); return; 94648382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default: return; 9477d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9487d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 949c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { 9507d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 9517d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 1: return u.format1.more (); 9527d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 2: return u.format2.more (); 95348382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return false; 9547d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9557d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 956c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { 9570da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod switch (format) { 9580da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 1: u.format1.next (); break; 9590da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 2: u.format2.next (); break; 9600da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod default: break; 9610da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 9620da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 963eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline hb_codepoint_t get_glyph (void) { 964c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod switch (format) { 965c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_glyph (); 966c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_glyph (); 96748382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return 0; 968c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 969c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 970eab418c5e6fa34b90133862cc8ce11e617ce08bfBehdad Esfahbod inline unsigned int get_coverage (void) { 9717d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 972c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_coverage (); 973c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_coverage (); 97448382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return -1; 9757d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9767d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9777d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 9787d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 979c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int format; 9807d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod union { 9818820ba29dfd2e1302377da62a0527939a0d7d9fbBehdad Esfahbod CoverageFormat2::Iter format2; /* Put this one first since it's larger; helps shut up compiler. */ 9827d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod CoverageFormat1::Iter format1; 9837d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } u; 9847d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 9857d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 986ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 9876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 9886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT format; /* Format identifier */ 989dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat1 format1; 990dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat2 format2; 9916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 992ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 993596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 9946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 9956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 9986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Class Definition Table 9996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 10006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 100160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat1 100260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 10036f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 10046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10056f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 100698370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 100760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1008ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod unsigned int i = (unsigned int) (glyph_id - startGlyph); 1009ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod if (unlikely (i < classValue.len)) 1010ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod return classValue[i]; 10116f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 10126f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1014de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1015de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1016be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1017b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && classValue.sanitize (c)); 101870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 101970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 102089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 102189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (set_t *glyphs, unsigned int klass) const { 102289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = classValue.len; 102389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 102489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod if (classValue[i] == klass) 102589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod glyphs->add (startGlyph + i); 102689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 102789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10286a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 102931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = classValue.len; 1030625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1031625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1032625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1033625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod hb_codepoint_t g = -1; 1034625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1035625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return false; 1036625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < startGlyph) 1037625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1038625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = startGlyph + count - 1; 1039625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (hb_set_next (glyphs, &g)) 1040625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1041625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1042625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 104331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 104431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (classValue[i] == klass && glyphs->has (startGlyph + i)) 104531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 104631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 104731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 104831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1049ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 10506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT classFormat; /* Format identifier--format = 1 */ 10516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod GlyphID startGlyph; /* First GlyphID of the classValueArray */ 10526f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod ArrayOf<USHORT> 10536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod classValue; /* Array of Class Values--one per GlyphID */ 1054b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 10550eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, classValue); 10566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 10576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 105860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat2 105960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 10606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 10616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 106398370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 106460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1065df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = rangeRecord.bsearch (glyph_id); 10668e3d4bae033bdec649676da26cfc3eb7610832a8Behdad Esfahbod if (unlikely (i != -1)) 1067cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return rangeRecord[i].value; 10686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 10696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10706f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1071de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1072de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1073be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1074b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rangeRecord.sanitize (c)); 107570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 107670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 107789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 107889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (set_t *glyphs, unsigned int klass) const { 107989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = rangeRecord.len; 108089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 108189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod if (rangeRecord[i].value == klass) 108289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod rangeRecord[i].add_coverage (glyphs); 108389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 108489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10856a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 108631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 1087625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1088625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1089625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1090515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod hb_codepoint_t g = (hb_codepoint_t) -1; 1091625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1092625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1093625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1094625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod break; 1095625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < rangeRecord[i].start) 1096625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1097625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = rangeRecord[i].end; 1098625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 1099515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) 1100625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1101625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1102625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 110331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 110431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) 110531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 110631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 110731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 110831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1109ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT classFormat; /* Format identifier--format = 2 */ 1111cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 11126f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 11136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID */ 1114b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 11150eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 11166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 11176f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 111860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDef 111960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 112098370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 112160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 11226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 1123dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_class(glyph_id); 1124dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_class(glyph_id); 11256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return 0; 11266f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 11276f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 11286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1129de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1130de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1131be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1132b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 113370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 1134b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 1135b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.sanitize (c)); 1136b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 113770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 113870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 1139aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 114089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (hb_set_t *glyphs, unsigned int klass) const { 114189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod switch (u.format) { 114289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod case 1: u.format1.add_class (glyphs, klass); return; 114389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod case 2: u.format2.add_class (glyphs, klass); return; 114489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod default:return; 114589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 114689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 114789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 11486a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 114931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 115031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_class (glyphs, klass); 115131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_class (glyphs, klass); 115231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 115331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 115431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 115531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1156ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 11586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT format; /* Format identifier */ 1159dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat1 format1; 1160dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat2 format2; 11616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 1162ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 1163596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 11646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 11656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 11666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 11676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 1168dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod * Item Variation Store 1169dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod */ 1170dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1171dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarRegionAxis 1172dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1173dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float evaluate (int coord) const 1174dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1175dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int start = startCoord, peak = peakCoord, end = endCoord; 1176dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1177dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* TODO Move these to sanitize(). */ 1178dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (start > peak || peak > end)) 1179dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1180dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (start < 0 && end > 0 && peak != 0)) 1181dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1182dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1183dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (peak == 0 || coord == peak) 1184dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1185dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1186dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (coord <= start || end <= coord) 1187dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1188dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1189dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* Interpolate */ 1190dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (coord < peak) 1191dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return float (coord - start) / (peak - start); 1192dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod else 1193dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return float (end - coord) / (end - peak); 1194dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1195dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1196dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1197dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1198dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1199dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this)); 1200dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* TODO Handle invalid start/peak/end configs, so we don't 1201dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod * have to do that at runtime. */ 1202dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1203dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1204dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1205dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 startCoord; 1206dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 peakCoord; 1207dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 endCoord; 1208dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1209dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_STATIC (6); 1210dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1211dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1212dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarRegionList 1213dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1214dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float evaluate (unsigned int region_index, 1215dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_len) const 1216dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1217dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (region_index >= regionCount)) 1218dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1219dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1220dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const VarRegionAxis *axes = axesZ + (region_index * axisCount); 1221dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1222dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float v = 1.; 1223dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int count = MIN (coord_len, (unsigned int) axisCount); 1224dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1225dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1226dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float factor = axes[i].evaluate (coords[i]); 1227dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (factor == 0.) 1228dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1229dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod v *= factor; 1230dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1231dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return v; 1232dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1233dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1234dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1235dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1236dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1237dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1238dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod c->check_array (axesZ, axesZ[0].static_size, 1239dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod (unsigned int) axisCount * (unsigned int) regionCount)); 1240dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1241dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1242dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 1243dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT axisCount; 1244dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT regionCount; 1245dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod VarRegionAxis axesZ[VAR]; 1246dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1247dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY (4, axesZ); 1248dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1249dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1250dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarData 1251dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1252dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline unsigned int get_row_size (void) const 1253dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { return shortCount + regionIndices.len; } 1254dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1255dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline unsigned int get_size (void) const 1256dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { return itemCount * get_row_size (); } 1257dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1258dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float get_delta (unsigned int inner, 1259dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_count, 1260dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const VarRegionList ®ions) const 1261dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1262dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (inner >= itemCount)) 1263dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1264dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1265dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int count = regionIndices.len; 1266dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int scount = shortCount; 1267dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1268dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const BYTE *bytes = &StructAfter<BYTE> (regionIndices); 1269dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const BYTE *row = bytes + inner * (scount + count); 1270dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1271dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float delta = 0.; 1272dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int i = 0; 1273dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1274dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const SHORT *scursor = reinterpret_cast<const SHORT *> (row); 1275dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (; i < scount; i++) 1276dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1277dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); 1278dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod delta += scalar * *scursor++; 1279dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1280dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor); 1281dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (; i < count; i++) 1282dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1283dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); 1284dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod delta += scalar * *bcursor++; 1285dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1286dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1287dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return delta; 1288dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1289dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1290dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1291dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1292dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1293dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1294dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod regionIndices.sanitize(c) && 1295dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod shortCount <= regionIndices.len && 1296dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod c->check_array (&StructAfter<BYTE> (regionIndices), 1297dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod get_row_size (), itemCount)); 1298dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1299dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1300dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 1301dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT itemCount; 1302dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT shortCount; 1303dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod ArrayOf<USHORT> regionIndices; 1304dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod BYTE bytesX[VAR]; 1305dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1306dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); 1307dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1308dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1309cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbodstruct VariationStore 1310dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1311dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float get_delta (unsigned int outer, unsigned int inner, 1312dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_count) const 1313dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1314dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (outer >= dataSets.len)) 1315dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1316dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1317dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return (this+dataSets[outer]).get_delta (inner, 1318dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod coords, coord_count, 1319dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod this+regions); 1320dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1321dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1322a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod inline float get_delta (unsigned int index, 1323a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod int *coords, unsigned int coord_count) const 1324a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod { 1325a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod unsigned int outer = index >> 16; 1326a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod unsigned int inner = index & 0xFFFF; 1327a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod return get_delta (outer, inner, coords, coord_count); 1328a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod } 1329a4fca9f0051dbc177390a4e555b2d0fe642f724eBehdad Esfahbod 1330dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1331dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1332dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1333dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1334dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod format == 1 && 1335dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod regions.sanitize (c, this) && 1336dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod dataSets.sanitize (c, this)); 1337dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1338dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1339dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 1340dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT format; 13415e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<VarRegionList> regions; 1342dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod OffsetArrayOf<VarData, ULONG> dataSets; 1343dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1344dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY (8, dataSets); 1345dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1346dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 134759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod/* 134859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod * Feature Variations 134959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod */ 135059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 135159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct ConditionFormat1 135259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 135359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod friend struct Condition; 135459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 135559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod private: 135630c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool evaluate (const int *coords, unsigned int coord_len) const 135759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 135859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod int coord = axisIndex < coord_len ? coords[axisIndex] : 0; 135959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return filterRangeMinValue <= coord && coord <= filterRangeMaxValue; 136059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 136159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 136259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 136359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 136459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 136559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (c->check_struct (this)); 136659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 136759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 136859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 136959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod USHORT format; /* Format identifier--format = 1 */ 137059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod USHORT axisIndex; 137159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod F2DOT14 filterRangeMinValue; 137259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod F2DOT14 filterRangeMaxValue; 137359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 137459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_STATIC (8); 137559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 137659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 137759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct Condition 137859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 137930c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool evaluate (const int *coords, unsigned int coord_len) const 138059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 138159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod switch (u.format) { 138259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod case 1: return u.format1.evaluate (coords, coord_len); 138359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod default:return false; 138459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 138559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 138659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 138759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 138859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 138959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 139059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 139159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod switch (u.format) { 139259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 139359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod default:return_trace (true); 139459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 139559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 139659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 139759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 139859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod union { 139959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod USHORT format; /* Format identifier */ 140059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod ConditionFormat1 format1; 140159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } u; 140259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 140359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 140459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 140559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 140659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct ConditionSet 140759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 140830c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool evaluate (const int *coords, unsigned int coord_len) const 140959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 141059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod unsigned int count = conditions.len; 141159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 141259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod if (!(this+conditions.array[i]).evaluate (coords, coord_len)) 141359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return false; 141459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return true; 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 (conditions.sanitize (c, this)); 142159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 142259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 142359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 142459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod OffsetArrayOf<Condition, ULONG> conditions; 142559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 142659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_ARRAY (2, conditions); 142759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 142859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 142959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureTableSubstitutionRecord 143059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 14314ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod friend struct FeatureTableSubstitution; 1432ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 14334ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 143459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 143559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 14364ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod return_trace (c->check_struct (this) && feature.sanitize (c, base)); 143759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 143859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 143959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 14405e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod USHORT featureIndex; 14415e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<Feature> feature; 144259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 144359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_STATIC (6); 144459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 144559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 144659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureTableSubstitution 144759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 1448ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod inline const Feature *find_substitute (unsigned int feature_index) const 1449ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 1450ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod unsigned int count = substitutions.len; 1451ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 1452ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 14534ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod const FeatureTableSubstitutionRecord &record = substitutions.array[i]; 14544ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod if (record.featureIndex == feature_index) 14554ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod return &(this+record.feature); 1456ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 1457dbdbfe3d7b36613d893832dcb1884c756c20bfdaBehdad Esfahbod return nullptr; 1458ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 1459ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 146059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 146159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 146259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 146359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (version.sanitize (c) && 146459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod likely (version.major == 1) && 146559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions.sanitize (c, this)); 146659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 146759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 146859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 146959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod FixedVersion<> version; /* Version--0x00010000u */ 14704ebbeb7c50e5c1e934d230ceacf792602c6eb9b9Behdad Esfahbod ArrayOf<FeatureTableSubstitutionRecord> 147159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions; 147259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 147359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_ARRAY (6, substitutions); 147459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 147559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 147659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureVariationRecord 147759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 147859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod friend struct FeatureVariations; 147959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 148059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 148159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 148259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 148359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (conditions.sanitize (c, base) && 148459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions.sanitize (c, base)); 148559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 148659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 148759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 14885e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<ConditionSet> 148959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod conditions; 14905e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<FeatureTableSubstitution> 149159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod substitutions; 149259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 149359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_STATIC (8); 149459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 149559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 149659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbodstruct FeatureVariations 149759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod{ 1498ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod static const unsigned int NOT_FOUND_INDEX = 0xFFFFFFFFu; 1499ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 150030c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod inline bool find_index (const int *coords, unsigned int coord_len, 150130c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod unsigned int *index) const 150259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 150359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod unsigned int count = varRecords.len; 150459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 150559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 150659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod const FeatureVariationRecord &record = varRecords.array[i]; 150759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod if ((this+record.conditions).evaluate (coords, coord_len)) 150830c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod { 150930c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod *index = i; 151030c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod return true; 151130c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod } 151259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 1513ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod *index = NOT_FOUND_INDEX; 151430c42b644eb33551aa0986287182a46f2d8c32edBehdad Esfahbod return false; 151559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 151659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 1517ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod inline const Feature *find_substitute (unsigned int variations_index, 1518ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod unsigned int feature_index) const 1519ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod { 1520ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod const FeatureVariationRecord &record = varRecords[variations_index]; 1521ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod return (this+record.substitutions).find_substitute (feature_index); 1522ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod } 1523ec87ba9ba32a374d49dd3e40137f75f4f4232aeeBehdad Esfahbod 152459055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 152559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod { 152659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod TRACE_SANITIZE (this); 152759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod return_trace (version.sanitize (c) && 152859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod likely (version.major == 1) && 152959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod varRecords.sanitize (c, this)); 153059055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod } 153159055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 153259055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod protected: 153359055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod FixedVersion<> version; /* Version--0x00010000u */ 1534b732c53eb5bd0c2cc86f35a9d9623c92579a0b8cBehdad Esfahbod LArrayOf<FeatureVariationRecord> 153559055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod varRecords; 153659055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod public: 153759055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod DEFINE_SIZE_ARRAY (8, varRecords); 153859055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod}; 153959055b5494f802013ca3613a15e565ae1ca0c589Behdad Esfahbod 1540dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1541dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod/* 15426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Device Tables 15436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 15446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 15454c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbodstruct HintingDevice 154660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 15474c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod friend struct Device; 15484c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 15494c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod private: 1550b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1551abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font) const 1552abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->x_ppem, font->x_scale); } 1553b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1554abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font) const 1555abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->y_ppem, font->y_scale); } 1556b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1557d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod inline unsigned int get_size (void) const 1558d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod { 1559d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod unsigned int f = deltaFormat; 1560d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; 1561d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); 1562d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod } 1563d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1564d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1565d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod { 1566d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod TRACE_SANITIZE (this); 1567d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); 1568d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod } 1569d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1570d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod private: 1571d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1572da975419884a535281745f30f4b32fee0bc8a7a1Behdad Esfahbod inline int get_delta (unsigned int ppem, int scale) const 15735bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod { 15745bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!ppem) return 0; 15755bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 15765bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod int pixels = get_delta_pixels (ppem); 15775bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 15785bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!pixels) return 0; 15795bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 158083408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod return (int) (pixels * (int64_t) scale / ppem); 15815bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod } 15825bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod inline int get_delta_pixels (unsigned int ppem_size) const 158360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1584056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int f = deltaFormat; 158564d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (f < 1 || f > 3)) 1586056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 15876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1588056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod if (ppem_size < startSize || ppem_size > endSize) 1589056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 15906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1591056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int s = ppem_size - startSize; 15926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1593056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int byte = deltaValue[s >> (4 - f)]; 159409c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); 15957627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod unsigned int mask = (0xFFFFu >> (16 - (1 << f))); 1596056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1597056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod int delta = bits & mask; 1598056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 159915164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod if ((unsigned int) delta >= ((mask + 1) >> 1)) 1600056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod delta -= mask + 1; 1601056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1602056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return delta; 1603056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod } 1604056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1605ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 16060795b784dd1009976c185482a376df250167e73bBehdad Esfahbod USHORT startSize; /* Smallest size to correct--in ppem */ 16070795b784dd1009976c185482a376df250167e73bBehdad Esfahbod USHORT endSize; /* Largest size to correct--in ppem */ 1608caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 1609caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 1 Signed 2-bit value, 8 values per uint16 1610caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 2 Signed 4-bit value, 4 values per uint16 1611caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 3 Signed 8-bit value, 2 values per uint16 1612caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod */ 1613d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod USHORT deltaValue[VAR]; /* Array of compressed data */ 1614569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 16150eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, deltaValue); 16166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 16176f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 16186d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbodstruct VariationDevice 16196d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod{ 16204c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod friend struct Device; 16214c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 16224c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod private: 16236d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 1624cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store) const 162526648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod { return font->em_scalef_x (get_delta (font, store)); } 16266d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 1627cf3de4d8f79fc6e8413957cdef034e975343ce30Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const 162826648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod { return font->em_scalef_y (get_delta (font, store)); } 16296d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16306d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 16316d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod { 16326d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod TRACE_SANITIZE (this); 1633dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this)); 16346d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod } 16356d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16366d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod private: 16376d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 163826648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod inline float get_delta (hb_font_t *font, const VariationStore &store) const 16396d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod { 164026648cebcd14bd26142ccfe5ac8c0be08a213671Behdad Esfahbod return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords); 16416d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod } 16426d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16436d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod protected: 1644dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT outerIndex; 1645dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT innerIndex; 1646dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */ 16476d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod public: 1648dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_STATIC (6); 16496d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod}; 16506d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 16511f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbodstruct DeviceHeader 16521f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod{ 16531f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod protected: 16541f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod USHORT reserved1; 16551f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod USHORT reserved2; 16561f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod public: 16571f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod USHORT format; /* Format identifier */ 16581f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod public: 16591f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod DEFINE_SIZE_STATIC (6); 16601f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod}; 16611f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod 16624c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbodstruct Device 16634c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod{ 1664219cb29c5d230ecc6ee154b447fabd7b59fbe089Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const 16654c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 16664c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) 16674c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 16684c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 16694c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return u.hinting.get_x_delta (font); 1670dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 1671151d93de8a595924a8dcb00fcba648b4b3df0bf5Behdad Esfahbod return u.variation.get_x_delta (font, store); 16724c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 16734c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return 0; 16744c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 16754c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 1676219cb29c5d230ecc6ee154b447fabd7b59fbe089Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const 16774c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 16784c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) 16794c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 16804c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 168185ec4944346a1ac111217698e1424669a9732280Behdad Esfahbod return u.hinting.get_y_delta (font); 1682dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 1683151d93de8a595924a8dcb00fcba648b4b3df0bf5Behdad Esfahbod return u.variation.get_y_delta (font, store); 16844c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 16854c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return 0; 16864c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 16874c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 16884c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 16894c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 16904c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 16914c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod TRACE_SANITIZE (this); 16924c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod if (!u.b.format.sanitize (c)) return_trace (false); 16934c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) { 16944c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 16954c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (u.hinting.sanitize (c)); 1696dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 16974c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (u.variation.sanitize (c)); 16984c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 16994c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (true); 17004c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17014c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 17024c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 17034c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod protected: 17044c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod union { 17051f6ed356e0a849b61ce98b6a2f38d04d98c2191eBehdad Esfahbod DeviceHeader b; 17064c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod HintingDevice hinting; 17074c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod VariationDevice variation; 17084c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } u; 17094c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod public: 17104c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod DEFINE_SIZE_UNION (6, b); 17114c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod}; 17124c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 17136d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 17147d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 17157c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 1716acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 17175f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ 1718