hb-ot-layout-common-private.hh revision dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1
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 3222da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-ot-layout-private.hh" 337edb430f9182723b7b720708c56088cec1200a70Behdad Esfahbod#include "hb-open-type-private.hh" 340b08adb3539f2ec29682456b89c69e89ff5e9c03Behdad Esfahbod#include "hb-set-private.hh" 356f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 366f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 375ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#ifndef HB_MAX_NESTING_LEVEL 385ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#define HB_MAX_NESTING_LEVEL 6 395ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#endif 405ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#ifndef HB_MAX_CONTEXT_LENGTH 415ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#define HB_MAX_CONTEXT_LENGTH 64 425ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod#endif 435ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod 445ba450407b9d9856453e63a815499da8721ff6a7Behdad Esfahbod 457c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT { 467c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 477c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 4840c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod#define TRACE_DISPATCH(this, format) \ 4940c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ 5040c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 5140c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod "format %d", (int) format); 5240c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod 5340c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod 54dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod#define NOT_COVERED ((unsigned int) -1) 55cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod 56acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 57cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod 586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * OpenType Layout Common Table Formats 616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 642e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod 656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList 676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type> 7060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Record 7160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 724e573715ae5f5ed486ad66382bb44c47a86591ffBehdad Esfahbod inline int cmp (hb_tag_t a) const { 7336b3862009c00ad922d68810173a69ac59723365Behdad Esfahbod return tag.cmp (a); 74cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 75cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 7687e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod struct sanitize_closure_t { 7787e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod hb_tag_t tag; 78de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const void *list_base; 7987e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod }; 80de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 81de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 82be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 8387e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod const sanitize_closure_t closure = {tag, base}; 84b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); 85cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 86cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod Tag tag; /* 4-byte Tag identifier */ 886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod OffsetTo<Type> 896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod offset; /* Offset from beginning of object holding 906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * the Record */ 91569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 92569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod DEFINE_SIZE_STATIC (6); 936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type> 96cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RecordArrayOf : SortedArrayOf<Record<Type> > { 9760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Tag& get_tag (unsigned int i) const 9860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 994e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod /* We cheat slightly and don't define separate Null objects 1004e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod * for Record types. Instead, we return the correct Null(Tag) 1014e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod * here. */ 10264d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (i >= this->len)) return Null(Tag); 103d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod return (*this)[i].tag; 1046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 105e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_tags (unsigned int start_offset, 106e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *record_count /* IN/OUT */, 107e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *record_tags /* OUT */) const 108bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 109e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod if (record_count) { 11031f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod const Record<Type> *arr = this->sub_array (start_offset, record_count); 11148de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = *record_count; 112e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 11331f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod record_tags[i] = arr[i].tag; 114e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod } 115e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return this->len; 116bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 117bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_index (hb_tag_t tag, unsigned int *index) const 118bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 119df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* If we want to allow non-sorted data, we can lsearch(). */ 120df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = this->/*lsearch*/bsearch (tag); 121cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 122bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod if (index) *index = i; 123bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod return true; 124cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } else { 125cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (index) *index = Index::NOT_FOUND_INDEX; 126cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return false; 127bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 128bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 129bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod}; 130bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 131bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodtemplate <typename Type> 132bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodstruct RecordListOf : RecordArrayOf<Type> 133bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{ 134bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 1356bec81aa3a58b8be255568b2ea63b7854e1b0ea7Behdad Esfahbod { return this+RecordArrayOf<Type>::operator [](i).offset; } 136cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 137de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 138de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 139be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 140b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (RecordArrayOf<Type>::sanitize (c, this)); 141cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 1426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 1436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 145cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RangeRecord 146cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod{ 147cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod inline int cmp (hb_codepoint_t g) const { 148797d76d07f80d796a825d850772087104e5a2575Behdad Esfahbod return g < start ? -1 : g <= end ? 0 : +1 ; 149cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 150cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 151de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 152de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 153be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 154b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 155cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 156cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 1576a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects (const hb_set_t *glyphs) const { 15831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->intersects (start, end); 15931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 16031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 161c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 162c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 16367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod glyphs->add_range (start, end); 16467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 16567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 166cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod GlyphID start; /* First GlyphID in the range */ 167cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod GlyphID end; /* Last GlyphID in the range */ 168cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod USHORT value; /* Value */ 169cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod public: 170cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod DEFINE_SIZE_STATIC (6); 171cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod}; 172cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad EsfahbodDEFINE_NULL_DATA (RangeRecord, "\000\001"); 173cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 174cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 175b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbodstruct IndexArray : ArrayOf<Index> 176bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{ 177e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_indexes (unsigned int start_offset, 178e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *_count /* IN/OUT */, 179e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *_indexes /* OUT */) const 180bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 181e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod if (_count) { 18231f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod const USHORT *arr = this->sub_array (start_offset, _count); 18348de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = *_count; 184e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 18531f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod _indexes[i] = arr[i]; 186e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod } 187e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return this->len; 188bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 189bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod}; 190bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 191bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 1926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Script; 1936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct LangSys; 1946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Feature; 1956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 19760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LangSys 19860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 199bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_feature_count (void) const 200bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return featureIndex.len; } 201bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline hb_tag_t get_feature_index (unsigned int i) const 202bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return featureIndex[i]; } 203e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_feature_indexes (unsigned int start_offset, 204e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 205e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_indexes /* OUT */) const 206e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } 2076f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2087627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; } 2093d44fb6f15177dc6518166e435597936b044acc1Behdad Esfahbod inline unsigned int get_required_feature_index (void) const 21060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 2117627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (reqFeatureIndex == 0xFFFFu) 212b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod return Index::NOT_FOUND_INDEX; 2136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return reqFeatureIndex;; 2146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 2156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 21687e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 217de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const Record<LangSys>::sanitize_closure_t * = NULL) const 218de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 219be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 220b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && featureIndex.sanitize (c)); 221cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 222cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 2237d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod Offset<> lookupOrderZ; /* = Null (reserved for an offset to a 2246f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * reordering table) */ 2256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT reqFeatureIndex;/* Index of a feature required for this 2266f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * language system--if no required features 2277627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * = 0xFFFFu */ 228bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod IndexArray featureIndex; /* Array of indices into the FeatureList */ 229569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 2300eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, featureIndex); 2316f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 23265f46b00333e20ab8a52a4b350747507541ec1dbBehdad EsfahbodDEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF"); 2336f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2346f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 23560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Script 23660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 237bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lang_sys_count (void) const 238bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.len; } 239bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Tag& get_lang_sys_tag (unsigned int i) const 240bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.get_tag (i); } 241e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_lang_sys_tags (unsigned int start_offset, 242e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lang_sys_count /* IN/OUT */, 243e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *lang_sys_tags /* OUT */) const 244e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } 24560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const LangSys& get_lang_sys (unsigned int i) const 24660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 247b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); 2486f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return this+langSys[i].offset; 2496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 250bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const 251bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.find_index (tag, index); } 2526f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 253cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } 25460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } 2556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 25687e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 257de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const Record<Script>::sanitize_closure_t * = NULL) const 258de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 259be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 260b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); 261cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 262cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 263ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod OffsetTo<LangSys> 2656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod defaultLangSys; /* Offset to DefaultLangSys table--from 2666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * beginning of Script table--may be Null */ 267cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod RecordArrayOf<LangSys> 2686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod langSys; /* Array of LangSysRecords--listed 2696f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * alphabetically by LangSysTag */ 270b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2710eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, langSys); 2726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 2736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2746f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Script> ScriptList; 2756f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 276875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 277875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ 278f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodstruct FeatureParamsSize 279f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 280de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 281de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 282f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod TRACE_SANITIZE (this); 283b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->check_struct (this))) return_trace (false); 284efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 285efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod /* This subtable has some "history", if you will. Some earlier versions of 286efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Adobe tools calculated the offset of the FeatureParams sutable from the 287efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * beginning of the FeatureList table! Now, that is dealt with in the 288efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Feature implementation. But we still need to be able to tell junk from 289efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * real data. Note: We don't check that the nameID actually exists. 290efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 291efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk : 292efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 293efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Yes, it is correct that a new version of the AFDKO (version 2.0) will be 294efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * coming out soon, and that the makeotf program will build a font with a 295efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 'size' feature that is correct by the specification. 296efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 297efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * The specification for this feature tag is in the "OpenType Layout Tag 298efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Registry". You can see a copy of this at: 299efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size 300efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 301efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Here is one set of rules to determine if the 'size' feature is built 302efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * correctly, or as by the older versions of MakeOTF. You may be able to do 303efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * better. 304efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 305efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Assume that the offset to the size feature is according to specification, 306efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * and make the following value checks. If it fails, assume the the size 307efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. 308efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If this fails, reject the 'size' feature. The older makeOTF's calculated the 309efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * offset from the beginning of the FeatureList table, rather than from the 310efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * beginning of the 'size' Feature table. 311efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 312efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If "design size" == 0: 313efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * fails check 314efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 315efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else if ("subfamily identifier" == 0 and 316efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range start" == 0 and 317efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range end" == 0 and 318efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range start" == 0 and 319efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" == 0) 320efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * passes check: this is the format used when there is a design size 321efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * specified, but there is no recommended size range. 322efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 323efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else if ("design size" < "range start" or 324efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "design size" > "range end" or 325efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range end" <= "range start" or 326efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" < 256 or 327efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" > 32767 or 328efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * menu name ID is not a name ID which is actually in the name table) 329efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * fails test 330efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else 331efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * passes test. 332efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod */ 333efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 334efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (!designSize) 335b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 336efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else if (subfamilyID == 0 && 337efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID == 0 && 338efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod rangeStart == 0 && 339efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod rangeEnd == 0) 340b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 341efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else if (designSize < rangeStart || 342efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod designSize > rangeEnd || 343efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID < 256 || 344efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID > 32767) 345b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 346efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else 347b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 348f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 349f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 350875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT designSize; /* Represents the design size in 720/inch 351875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * units (decipoints). The design size entry 352875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * must be non-zero. When there is a design 353875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * size but no recommended size range, the 354875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * rest of the array will consist of zeros. */ 355875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT subfamilyID; /* Has no independent meaning, but serves 356875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * as an identifier that associates fonts 357875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * in a subfamily. All fonts which share a 358875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Preferred or Font Family name and which 359875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * differ only by size range shall have the 360875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * same subfamily value, and no fonts which 361875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * differ in weight or style shall have the 362875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * same subfamily value. If this value is 363875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * zero, the remaining fields in the array 364875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * will be ignored. */ 365875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT subfamilyNameID;/* If the preceding value is non-zero, this 366875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * value must be set in the range 256 - 32767 367875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive). It records the value of a 368875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * field in the name table, which must 369875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * contain English-language strings encoded 370875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * in Windows Unicode and Macintosh Roman, 371875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * and may contain additional strings 372875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * localized to other scripts and languages. 373875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Each of these strings is the name an 374875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * application should use, in combination 375875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * with the family name, to represent the 376875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * subfamily in a menu. Applications will 377875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * choose the appropriate version based on 378875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * their selection criteria. */ 379875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT rangeStart; /* Large end of the recommended usage range 380875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive), stored in 720/inch units 381875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 382875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT rangeEnd; /* Small end of the recommended usage range 383875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod (exclusive), stored in 720/inch units 384875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 385f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod public: 386f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod DEFINE_SIZE_STATIC (10); 387f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod}; 388f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 389875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ 390875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbodstruct FeatureParamsStylisticSet 391875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod{ 392de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 393de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 394875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod TRACE_SANITIZE (this); 395875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod /* Right now minorVersion is at zero. Which means, any table supports 396875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * the uiNameID field. */ 397b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 398875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod } 399875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 400e1ebf01d0cf3df55bb9137136e2d0c9630e7bd78Behdad Esfahbod USHORT version; /* (set to 0): This corresponds to a “minor” 401875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * version number. Additional data may be 402875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * added to the end of this Feature Parameters 403875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * table in the future. */ 404875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 405875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT uiNameID; /* The 'name' table name ID that specifies a 406875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * string (or strings, for multiple languages) 407875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * for a user-interface label for this 408875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * feature. The values of uiLabelNameId and 409875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * sampleTextNameId are expected to be in the 410875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * font-specific name ID range (256-32767), 411875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * though that is not a requirement in this 412875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Feature Parameters specification. The 413875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * user-interface label for the feature can 414875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * be provided in multiple languages. An 415875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * English string should be included as a 416875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * fallback. The string should be kept to a 417875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * minimal length to fit comfortably with 418875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * different application interfaces. */ 419875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod public: 420875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod DEFINE_SIZE_STATIC (4); 421875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod}; 422875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 423a182dbc9e4e51fa7990c4aea3eaa425a061b29c7Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ 4240bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbodstruct FeatureParamsCharacterVariants 4250bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod{ 426de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 427de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 4280bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod TRACE_SANITIZE (this); 429b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 430b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod characters.sanitize (c)); 4310bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod } 432efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 4330bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT format; /* Format number is set to 0. */ 4340bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT featUILableNameID; /* The ‘name’ table name ID that 4350bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies a string (or strings, 4360bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * for multiple languages) for a 4370bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * user-interface label for this 4380bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature. (May be NULL.) */ 4390bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that 4400bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies a string (or strings, 4410bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * for multiple languages) that an 4420bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * application can use for tooltip 4430bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * text for this feature. (May be 4440bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * NULL.) */ 4450bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT sampleTextNameID; /* The ‘name’ table name ID that 4460bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies sample text that 4470bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * illustrates the effect of this 4480bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature. (May be NULL.) */ 4490bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT numNamedParameters; /* Number of named parameters. (May 4500bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * be zero.) */ 4510bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID 4520bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * used to specify strings for 4530bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * user-interface labels for the 4540bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature parameters. (Must be zero 4550bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * if numParameters is zero.) */ 4560bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod ArrayOf<UINT24> 4570bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod characters; /* Array of the Unicode Scalar Value 4580bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * of the characters for which this 4590bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature provides glyph variants. 4600bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * (May be zero.) */ 4610bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod public: 4620bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod DEFINE_SIZE_ARRAY (14, characters); 4630bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod}; 4640bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod 465f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodstruct FeatureParams 466f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 467de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const 468de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 469f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod TRACE_SANITIZE (this); 470efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == HB_TAG ('s','i','z','e')) 471b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (u.size.sanitize (c)); 4727627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ 473b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (u.stylisticSet.sanitize (c)); 4747627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ 475b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (u.characterVariants.sanitize (c)); 476b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 477f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 478f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 479efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const 480efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod { 481efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == HB_TAG ('s','i','z','e')) 482efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return u.size; 483efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return Null(FeatureParamsSize); 484efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod } 485efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 486efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod private: 487f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod union { 4880bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsSize size; 4890bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsStylisticSet stylisticSet; 4900bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsCharacterVariants characterVariants; 491f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } u; 4920bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod DEFINE_SIZE_STATIC (17); 493f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod}; 4946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 49560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Feature 49660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 497bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lookup_count (void) const 498bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return lookupIndex.len; } 499bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline hb_tag_t get_lookup_index (unsigned int i) const 500bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return lookupIndex[i]; } 501e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_lookup_indexes (unsigned int start_index, 502e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lookup_count /* IN/OUT */, 503e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lookup_tags /* OUT */) const 504e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } 5056f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 506f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod inline const FeatureParams &get_feature_params (void) const 507f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod { return this+featureParams; } 508f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 50987e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 510de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod const Record<Feature>::sanitize_closure_t *closure) const 511de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 512be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 5139b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) 514b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 5159b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 516efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod /* Some earlier versions of Adobe tools calculated the offset of the 517efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * FeatureParams subtable from the beginning of the FeatureList table! 518efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 519efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If sanitizing "failed" for the FeatureParams subtable, try it with the 520efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * alternative location. We would know sanitize "failed" if old value 521efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * of the offset was non-zero, but it's zeroed now. 5221ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * 5231ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * Only do this for the 'size' feature, since at the time of the faulty 5241ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * Adobe tools, only the 'size' feature had FeatureParams defined. 525efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod */ 526efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 527586b60622c33878f9ca4826b4ef07369d32bf039Behdad Esfahbod OffsetTo<FeatureParams> orig_offset = featureParams; 528efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) 529b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 530efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 5319da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod if (likely (orig_offset.is_null ())) 532b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 5339b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 5341ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod if (featureParams == 0 && closure && 5351ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod closure->tag == HB_TAG ('s','i','z','e') && 5361ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod closure->list_base && closure->list_base < this) 5379b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod { 538efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod unsigned int new_offset_int = (unsigned int) orig_offset - 539dac86026a6bae5a8a03cfe885bf93f32e5f48614Behdad Esfahbod (((char *) this) - ((char *) closure->list_base)); 540efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 541586b60622c33878f9ca4826b4ef07369d32bf039Behdad Esfahbod OffsetTo<FeatureParams> new_offset; 5429b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod /* Check that it did not overflow. */ 543efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod new_offset.set (new_offset_int); 544efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (new_offset == new_offset_int && 54551f563579b94e1ee23ced9bbcc7dd3341535ce72Behdad Esfahbod c->try_set (&featureParams, new_offset) && 546efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) 547b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 548da2fcfdc51a2cc0d0a782efa6c91b733f7aa84baBehdad Esfahbod 549da2fcfdc51a2cc0d0a782efa6c91b733f7aa84baBehdad Esfahbod if (c->edit_count > 1) 550da2fcfdc51a2cc0d0a782efa6c91b733f7aa84baBehdad Esfahbod c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */ 5519b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod } 5529b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 553b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 554cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 555cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 556f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod OffsetTo<FeatureParams> 557f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod featureParams; /* Offset to Feature Parameters table (if one 5586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * has been defined for the feature), relative 5596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * to the beginning of the Feature Table; = Null 5606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * if not required */ 561bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod IndexArray lookupIndex; /* Array of LookupList indices */ 562b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 5630eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, lookupIndex); 5646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 5656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Feature> FeatureList; 5676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 56960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LookupFlag : USHORT 57060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 571c6035cf802c60f0526f421f39a55886061df94eeBehdad Esfahbod enum Flags { 5724fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod RightToLeft = 0x0001u, 5734fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreBaseGlyphs = 0x0002u, 5744fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreLigatures = 0x0004u, 5754fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreMarks = 0x0008u, 576aa87d951739f6beacb66daa235cd033fdcfcadd7Behdad Esfahbod IgnoreFlags = 0x000Eu, 577d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod UseMarkFilteringSet = 0x0010u, 578d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod Reserved = 0x00E0u, 5798f034d5849627ee95a5889fa34c9ba294fff13caBehdad Esfahbod MarkAttachmentType = 0xFF00u 5804fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod }; 581b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 582b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (2); 5836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 5846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 585aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod} /* namespace OT */ 586aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod/* This has to be outside the namespace. */ 587167c3271778cd1a8c4433b9d2230901ce17c099eChun-wei FanHB_MARK_AS_FLAG_T (OT::LookupFlag::Flags); 588aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbodnamespace OT { 589aa7044de0ceacd71cab19212d266c3a66c03b41eBehdad Esfahbod 59060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Lookup 59160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 59260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_subtable_count (void) const { return subTable.len; } 5936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 59470366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod template <typename SubTableType> 59570366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod inline const SubTableType& get_subtable (unsigned int i) const 59670366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; } 59770366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod 59870366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod template <typename SubTableType> 59970366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod inline const OffsetArrayOf<SubTableType>& get_subtables (void) const 60070366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod { return CastR<OffsetArrayOf<SubTableType> > (subTable); } 60170366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod template <typename SubTableType> 60270366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod inline OffsetArrayOf<SubTableType>& get_subtables (void) 60370366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod { return CastR<OffsetArrayOf<SubTableType> > (subTable); } 60470366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod 6056f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod inline unsigned int get_type (void) const { return lookupType; } 6068c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod 6078c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and 6088c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod * higher 16-bit is mark-filtering-set if the lookup uses one. 6098c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod * Not to be confused with glyph_props which is very similar. */ 6108c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod inline uint32_t get_props (void) const 611d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod { 612d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod unsigned int flag = lookupFlag; 61364d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) 614d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod { 615e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 61609c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod flag += (markFilteringSet << 16); 617d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod } 618d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod return flag; 619d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod } 6206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 62140c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod template <typename SubTableType, typename context_t> 62240c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod inline typename context_t::return_t dispatch (context_t *c) const 62340c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod { 62440c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod unsigned int lookup_type = get_type (); 62540c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod TRACE_DISPATCH (this, lookup_type); 62640c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod unsigned int count = get_subtable_count (); 62740c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod for (unsigned int i = 0; i < count; i++) { 62840c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type); 62940c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod if (c->stop_sublookup_iteration (r)) 630b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (r); 63140c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod } 632b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->default_return_value ()); 63340c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod } 63440c58923cbf689c465f9b65334c455a9b7f71ab0Behdad Esfahbod 635652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 636652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod unsigned int lookup_type, 637652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod uint32_t lookup_props, 638652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod unsigned int num_subtables) 639652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod { 640be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 641b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 642652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod lookupType.set (lookup_type); 6437627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod lookupFlag.set (lookup_props & 0xFFFFu); 644b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); 645b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (lookupFlag & LookupFlag::UseMarkFilteringSet) 646652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod { 647652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 648652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod markFilteringSet.set (lookup_props >> 16); 649652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod } 650b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 651652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod } 652652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod 653de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 654de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 655be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 6563b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod /* Real sanitize of the subtables is done by GSUB/GPOS/... */ 657b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); 658652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod if (lookupFlag & LookupFlag::UseMarkFilteringSet) 659cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod { 6608dddc231cf9d934eb93a39f2657717cbdad43a64Behdad Esfahbod const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 661b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!markFilteringSet.sanitize (c)) return_trace (false); 662cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 663b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 664cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 665cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 66670366f5d19df2e654f0933474fecf1aa16e27812Behdad Esfahbod private: 667d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod USHORT lookupType; /* Different enumerations for GSUB and GPOS */ 668d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod USHORT lookupFlag; /* Lookup qualifiers */ 66999d281712390fd54e523b2f0580d10445457ec2fBehdad Esfahbod ArrayOf<Offset<> > 670d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod subTable; /* Array of SubTables */ 671d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets 672d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod * structure. This field is only present if bit 673d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod * UseMarkFilteringSet of lookup flags is set. */ 674569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 6758dddc231cf9d934eb93a39f2657717cbdad43a64Behdad Esfahbod DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); 6766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 6776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef OffsetListOf<Lookup> LookupList; 6796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6816f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 6826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Coverage Table 6836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 6846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 68560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat1 68660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 6886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 69060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 69160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 692df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = glyphArray.bsearch (glyph_id); 693dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED); 694dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod return i; 6956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 6966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 697bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 698a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 699bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 7009f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 701be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 702b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 703bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod glyphArray.len.set (num_glyphs); 704b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend (glyphArray))) return_trace (false); 7059f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 0; i < num_glyphs; i++) 706fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod glyphArray[i] = glyphs[i]; 707a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 708b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 7099f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 7109f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 711de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 712de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 713be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 714b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (glyphArray.sanitize (c)); 71570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 71670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 7176a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 71831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->has (glyphArray[index]); 71931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 72031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 721c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 722c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 72367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = glyphArray.len; 72467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 72567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod glyphs->add (glyphArray[i]); 72667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 72767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 728365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 729365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 7307d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 731c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; 732c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->glyphArray.len; } 733c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { i++; } 734c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_glyph (void) { return c->glyphArray[i]; } 735c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_coverage (void) { return i; } 7367d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 7377d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 7387d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat1 *c; 7397d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod unsigned int i; 7407d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 741365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 7427d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 743ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 7446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT coverageFormat; /* Format identifier--format = 1 */ 745cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<GlyphID> 7466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod glyphArray; /* Array of GlyphIDs--in numerical order */ 747b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 7480eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, glyphArray); 7496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 7506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 75160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat2 75260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 7536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 7546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 7556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 75660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 75760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 758df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = rangeRecord.bsearch (glyph_id); 759cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 760cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 761cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return (unsigned int) range.value + (glyph_id - range.start); 7626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return NOT_COVERED; 7646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 766bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 767a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 768bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 7699f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 770be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 771b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 772bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 773851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod if (unlikely (!num_glyphs)) 774851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod { 775851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod rangeRecord.len.set (0); 776851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod return_trace (true); 777851b0db36d1b724fc1e0db506445119c78186285Behdad Esfahbod } 778bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7799f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 7809f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7819f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 7829f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 783bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord.len.set (num_ranges); 784b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend (rangeRecord))) return_trace (false); 785bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7869f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int range = 0; 787fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[0]; 788bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].value.set (0); 7899f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7909f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) { 7919f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod range++; 792fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[i]; 793fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].value.set (i); 794fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7959f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } else { 796bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7979f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 798a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 799b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (true); 8009f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 8019f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 802de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 803de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 804be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 805b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rangeRecord.sanitize (c)); 80670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 80770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 8086a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 80931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int i; 81031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 81131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (i = 0; i < count; i++) { 81231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 81331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (range.value <= index && 8143f18236a03880c0960f5990dc90685f6146951a6Behdad Esfahbod index < (unsigned int) range.value + (range.end - range.start) && 81531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod range.intersects (glyphs)) 81631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 81731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod else if (index < range.value) 81831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 81931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 82031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 82131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 82231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 823c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 824c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 82567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = rangeRecord.len; 82667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 82767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod rangeRecord[i].add_coverage (glyphs); 82867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 82967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 830365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 831365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 8327d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 833c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const CoverageFormat2 &c_) { 834c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod c = &c_; 835c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod coverage = 0; 836c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod i = 0; 837c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; 838c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 839c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->rangeRecord.len; } 840c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { 841c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod coverage++; 8427d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod if (j == c->rangeRecord[i].end) { 8437d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod i++; 8440da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod if (more ()) 8450da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod j = c->rangeRecord[i].start; 8460da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod return; 8477d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 8480da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod j++; 8490da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 850c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_glyph (void) { return j; } 851c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_coverage (void) { return coverage; } 8527d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 8537d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 8547d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat2 *c; 855c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int i, j, coverage; 8567d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 857365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 8587d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 859ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 8606f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT coverageFormat; /* Format identifier--format = 2 */ 861cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 8626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 8636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID. rangeCount entries 8646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * long */ 865b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 8660eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 8676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 8686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 86960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Coverage 87060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 87120b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 87260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 8736f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 874dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_coverage(glyph_id); 875dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_coverage(glyph_id); 8766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return NOT_COVERED; 8776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 8786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 8796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 880bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 881a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 882bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 8839f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 884be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 885b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return_trace (false); 8869f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 8879f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 8889f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 8899f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 890bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); 891bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod switch (u.format) { 892b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs)); 893b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs)); 894b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (false); 8959f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 8969f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 8979f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 898de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 899de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 900be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 901b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 90270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 903b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 904b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.sanitize (c)); 905b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 90670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 90770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 9086f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9096a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects (const hb_set_t *glyphs) const { 910c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod /* TODO speed this up */ 911c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 912c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (*this); iter.more (); iter.next ()) { 913c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (glyphs->has (iter.get_glyph ())) 914c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod return true; 915c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 916c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod return false; 91731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 918c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 9196a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 92031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 92131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_coverage (glyphs, index); 92231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_coverage (glyphs, index); 92331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 92431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 925c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 926c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 927c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 928c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 92967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod switch (u.format) { 93067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod case 1: u.format1.add_coverage (glyphs); break; 93167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod case 2: u.format2.add_coverage (glyphs); break; 93267bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod default: break; 93367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 93467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 93567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 9367d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 937c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Iter (void) : format (0) {}; 938c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const Coverage &c_) { 9397d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod format = c_.u.format; 9407d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 94148382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 1: u.format1.init (c_.u.format1); return; 94248382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 2: u.format2.init (c_.u.format2); return; 94348382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default: return; 9447d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9457d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 946c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { 9477d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 9487d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 1: return u.format1.more (); 9497d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 2: return u.format2.more (); 95048382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return false; 9517d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9527d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 953c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { 9540da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod switch (format) { 9550da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 1: u.format1.next (); break; 9560da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 2: u.format2.next (); break; 9570da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod default: break; 9580da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 9590da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 960c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_glyph (void) { 961c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod switch (format) { 962c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_glyph (); 963c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_glyph (); 96448382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return 0; 965c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 966c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 967c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_coverage (void) { 9687d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 969c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_coverage (); 970c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_coverage (); 97148382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return -1; 9727d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9737d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9747d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 9757d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 976c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int format; 9777d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod union { 9787d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod CoverageFormat1::Iter format1; 9797d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod CoverageFormat2::Iter format2; 9807d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } u; 9817d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 9827d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 983ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 9846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 9856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT format; /* Format identifier */ 986dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat1 format1; 987dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat2 format2; 9886f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 989ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 990596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 9916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 9926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 9956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Class Definition Table 9966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 9976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 99860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat1 99960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 10006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 10016f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10026f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 100398370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 100460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1005ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod unsigned int i = (unsigned int) (glyph_id - startGlyph); 1006ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod if (unlikely (i < classValue.len)) 1007ef79bdf73bbfde1bfaa222834809d105ab7755b3Behdad Esfahbod return classValue[i]; 10086f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 10096f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1011de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1012de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1013be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1014b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && classValue.sanitize (c)); 101570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 101670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 101789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 101889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (set_t *glyphs, unsigned int klass) const { 101989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = classValue.len; 102089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 102189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod if (classValue[i] == klass) 102289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod glyphs->add (startGlyph + i); 102389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 102489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10256a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 102631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = classValue.len; 1027625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1028625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1029625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1030625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod hb_codepoint_t g = -1; 1031625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1032625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return false; 1033625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < startGlyph) 1034625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1035625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = startGlyph + count - 1; 1036625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (hb_set_next (glyphs, &g)) 1037625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1038625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1039625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 104031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 104131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (classValue[i] == klass && glyphs->has (startGlyph + i)) 104231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 104331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 104431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 104531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1046ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 10476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT classFormat; /* Format identifier--format = 1 */ 10486f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod GlyphID startGlyph; /* First GlyphID of the classValueArray */ 10496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod ArrayOf<USHORT> 10506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod classValue; /* Array of Class Values--one per GlyphID */ 1051b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 10520eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, classValue); 10536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 10546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 105560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat2 105660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 10576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 10586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10596f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 106098370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 106160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1062df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = rangeRecord.bsearch (glyph_id); 10638e3d4bae033bdec649676da26cfc3eb7610832a8Behdad Esfahbod if (unlikely (i != -1)) 1064cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return rangeRecord[i].value; 10656f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 10666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1068de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1069de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1070be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1071b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (rangeRecord.sanitize (c)); 107270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 107370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 107489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 107589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (set_t *glyphs, unsigned int klass) const { 107689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = rangeRecord.len; 107789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 107889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod if (rangeRecord[i].value == klass) 107989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod rangeRecord[i].add_coverage (glyphs); 108089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 108189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10826a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 108331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 1084625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1085625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1086625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1087515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod hb_codepoint_t g = (hb_codepoint_t) -1; 1088625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1089625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1090625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1091625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod break; 1092625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < rangeRecord[i].start) 1093625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1094625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = rangeRecord[i].end; 1095625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 1096515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) 1097625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1098625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1099625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 110031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 110131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) 110231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 110331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 110431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 110531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1106ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11076f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT classFormat; /* Format identifier--format = 2 */ 1108cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 11096f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 11106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID */ 1111b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 11120eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 11136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 11146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 111560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDef 111660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 111798370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 111860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 11196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 1120dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_class(glyph_id); 1121dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_class(glyph_id); 11226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return 0; 11236f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 11246f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 11256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1126de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1127de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1128be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1129b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 113070de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 1131b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 1: return_trace (u.format1.sanitize (c)); 1132b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 2: return_trace (u.format2.sanitize (c)); 1133b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 113470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 113570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 1136aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 113789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (hb_set_t *glyphs, unsigned int klass) const { 113889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod switch (u.format) { 113989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod case 1: u.format1.add_class (glyphs, klass); return; 114089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod case 2: u.format2.add_class (glyphs, klass); return; 114189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod default:return; 114289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 114389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 114489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 11456a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 114631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 114731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_class (glyphs, klass); 114831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_class (glyphs, klass); 114931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 115031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 115131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 115231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1153ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 11556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT format; /* Format identifier */ 1156dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat1 format1; 1157dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat2 format2; 11586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 1159ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 1160596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 11616f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 11626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 11636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 11646f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 1165dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod * Item Variation Store 1166dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod */ 1167dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1168dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarRegionAxis 1169dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1170dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float evaluate (int coord) const 1171dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1172dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int start = startCoord, peak = peakCoord, end = endCoord; 1173dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1174dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* TODO Move these to sanitize(). */ 1175dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (start > peak || peak > end)) 1176dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1177dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (start < 0 && end > 0 && peak != 0)) 1178dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1179dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1180dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (peak == 0 || coord == peak) 1181dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 1.; 1182dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1183dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (coord <= start || end <= coord) 1184dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1185dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1186dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* Interpolate */ 1187dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (coord < peak) 1188dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return float (coord - start) / (peak - start); 1189dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod else 1190dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return float (end - coord) / (end - peak); 1191dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1192dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1193dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1194dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1195dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1196dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this)); 1197dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* TODO Handle invalid start/peak/end configs, so we don't 1198dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod * have to do that at runtime. */ 1199dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1200dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1201dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1202dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 startCoord; 1203dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 peakCoord; 1204dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod F2DOT14 endCoord; 1205dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1206dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_STATIC (6); 1207dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1208dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1209dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarRegionList 1210dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1211dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float evaluate (unsigned int region_index, 1212dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_len) const 1213dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1214dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (region_index >= regionCount)) 1215dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1216dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1217dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const VarRegionAxis *axes = axesZ + (region_index * axisCount); 1218dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1219dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float v = 1.; 1220dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int count = MIN (coord_len, (unsigned int) axisCount); 1221dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1222dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1223dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float factor = axes[i].evaluate (coords[i]); 1224dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (factor == 0.) 1225dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1226dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod v *= factor; 1227dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1228dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return v; 1229dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1230dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1231dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1232dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1233dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1234dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1235dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod c->check_array (axesZ, axesZ[0].static_size, 1236dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod (unsigned int) axisCount * (unsigned int) regionCount)); 1237dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1238dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1239dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 1240dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT axisCount; 1241dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT regionCount; 1242dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod VarRegionAxis axesZ[VAR]; 1243dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1244dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY (4, axesZ); 1245dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1246dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1247dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarData 1248dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1249dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline unsigned int get_row_size (void) const 1250dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { return shortCount + regionIndices.len; } 1251dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1252dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline unsigned int get_size (void) const 1253dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { return itemCount * get_row_size (); } 1254dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1255dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float get_delta (unsigned int inner, 1256dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_count, 1257dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const VarRegionList ®ions) const 1258dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1259dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (inner >= itemCount)) 1260dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1261dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1262dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int count = regionIndices.len; 1263dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int scount = shortCount; 1264dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1265dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const BYTE *bytes = &StructAfter<BYTE> (regionIndices); 1266dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const BYTE *row = bytes + inner * (scount + count); 1267dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1268dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1269dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float delta = 0.; 1270dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod unsigned int i = 0; 1271dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1272dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const SHORT *scursor = reinterpret_cast<const SHORT *> (row); 1273dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (; i < scount; i++) 1274dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1275dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); 1276dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod delta += scalar * *scursor++; 1277dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1278dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor); 1279dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod for (; i < count; i++) 1280dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1281dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); 1282dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod delta += scalar * *bcursor++; 1283dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1284dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1285dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return delta; 1286dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1287dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1288dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1289dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1290dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1291dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1292dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod regionIndices.sanitize(c) && 1293dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod shortCount <= regionIndices.len && 1294dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod c->check_array (&StructAfter<BYTE> (regionIndices), 1295dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod get_row_size (), itemCount)); 1296dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1297dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1298dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 1299dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT itemCount; 1300dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT shortCount; 1301dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod ArrayOf<USHORT> regionIndices; 1302dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod BYTE bytesX[VAR]; 1303dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1304dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); 1305dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1306dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1307dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbodstruct VarStore 1308dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod{ 1309dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline float get_delta (unsigned int outer, unsigned int inner, 1310dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod int *coords, unsigned int coord_count) const 1311dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1312dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod if (unlikely (outer >= dataSets.len)) 1313dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return 0.; 1314dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1315dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return (this+dataSets[outer]).get_delta (inner, 1316dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod coords, coord_count, 1317dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod this+regions); 1318dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1319dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1320dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1321dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod { 1322dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod TRACE_SANITIZE (this); 1323dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this) && 1324dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod format == 1 && 1325dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod regions.sanitize (c, this) && 1326dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod dataSets.sanitize (c, this)); 1327dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod } 1328dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1329dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod protected: 1330dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT format; 1331dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod OffsetTo<VarRegionList, ULONG> regions; 1332dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod OffsetArrayOf<VarData, ULONG> dataSets; 1333dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod public: 1334dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_ARRAY (8, dataSets); 1335dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod}; 1336dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1337dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod 1338dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod/* 13396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Device Tables 13406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 13416f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 13424c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbodstruct HintingDevice 134360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 13444c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod friend struct Device; 13454c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 13464c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod private: 1347b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1348abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font) const 1349abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->x_ppem, font->x_scale); } 1350b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1351abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font) const 1352abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->y_ppem, font->y_scale); } 1353b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1354d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod inline unsigned int get_size (void) const 1355d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod { 1356d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod unsigned int f = deltaFormat; 1357d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; 1358d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); 1359d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod } 1360d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1361d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 1362d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod { 1363d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod TRACE_SANITIZE (this); 1364d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); 1365d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod } 1366d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1367d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod private: 1368d163dc18e66c9e2f404d09310482464245cae704Behdad Esfahbod 1369da975419884a535281745f30f4b32fee0bc8a7a1Behdad Esfahbod inline int get_delta (unsigned int ppem, int scale) const 13705bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod { 13715bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!ppem) return 0; 13725bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 13735bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod int pixels = get_delta_pixels (ppem); 13745bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 13755bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!pixels) return 0; 13765bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 137783408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod return (int) (pixels * (int64_t) scale / ppem); 13785bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod } 13795bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod inline int get_delta_pixels (unsigned int ppem_size) const 138060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1381056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int f = deltaFormat; 138264d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (f < 1 || f > 3)) 1383056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 13846f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1385056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod if (ppem_size < startSize || ppem_size > endSize) 1386056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 13876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1388056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int s = ppem_size - startSize; 13896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1390056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int byte = deltaValue[s >> (4 - f)]; 139109c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); 13927627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod unsigned int mask = (0xFFFFu >> (16 - (1 << f))); 1393056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1394056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod int delta = bits & mask; 1395056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 139615164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod if ((unsigned int) delta >= ((mask + 1) >> 1)) 1397056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod delta -= mask + 1; 1398056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1399056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return delta; 1400056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod } 1401056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1402ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 14030795b784dd1009976c185482a376df250167e73bBehdad Esfahbod USHORT startSize; /* Smallest size to correct--in ppem */ 14040795b784dd1009976c185482a376df250167e73bBehdad Esfahbod USHORT endSize; /* Largest size to correct--in ppem */ 1405caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 1406caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 1 Signed 2-bit value, 8 values per uint16 1407caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 2 Signed 4-bit value, 4 values per uint16 1408caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 3 Signed 8-bit value, 2 values per uint16 1409caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod */ 1410d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod USHORT deltaValue[VAR]; /* Array of compressed data */ 1411569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 14120eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, deltaValue); 14136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 14146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 14156d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbodstruct VariationDevice 14166d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod{ 14174c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod friend struct Device; 14184c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 14194c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod private: 14206d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14216d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font) const 1422ca286703164caf1eda665f6f27ef83bf04e2f8baBehdad Esfahbod { return font->em_scalef_x (get_delta (font->x_coords, font->num_coords)); } 14236d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14246d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font) const 1425ca286703164caf1eda665f6f27ef83bf04e2f8baBehdad Esfahbod { return font->em_scalef_y (get_delta (font->y_coords, font->num_coords)); } 14266d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14276d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 14286d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod { 14296d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod TRACE_SANITIZE (this); 1430dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod return_trace (c->check_struct (this)); 14316d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod } 14326d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14336d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod private: 14346d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14356d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod inline float get_delta (int *coords, unsigned int coord_count) const 14366d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod { 14376d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod float v = 0; 1438dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod /* XXXXXXXXXXXXXXX call into GDEF. */ 14396d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod return v; 14406d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod } 14416d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14426d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod protected: 1443dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT outerIndex; 1444dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT innerIndex; 1445dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */ 14466d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod public: 1447dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod DEFINE_SIZE_STATIC (6); 14486d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod}; 14496d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 14504c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbodstruct Device 14514c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod{ 14524c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font) const 14534c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 14544c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) 14554c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 14564c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 14574c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return u.hinting.get_x_delta (font); 1458dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 14594c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return u.variation.get_x_delta (font); 14604c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 14614c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return 0; 14624c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 14634c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 14644c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font) const 14654c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 14664c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) 14674c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 14684c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 14694c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return u.hinting.get_x_delta (font); 1470dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 14714c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 14724c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return 0; 14734c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 14744c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 14754c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 14764c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 14774c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod { 14784c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod TRACE_SANITIZE (this); 14794c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod if (!u.b.format.sanitize (c)) return_trace (false); 14804c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod switch (u.b.format) { 14814c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod case 1: case 2: case 3: 14824c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (u.hinting.sanitize (c)); 1483dc9f2297998b4cbc4f9e4c2591fc2bb5f92986d1Behdad Esfahbod case 0x8000: 14844c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (u.variation.sanitize (c)); 14854c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod default: 14864c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod return_trace (true); 14874c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 14884c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } 14894c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 14904c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod protected: 14914c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod union { 14924c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod struct { 14934c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod USHORT reserved1; 14944c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod USHORT reserved2; 14954c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod USHORT format; /* Format identifier */ 14964c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod public: 14974c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod DEFINE_SIZE_STATIC (6); 14984c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } b; 14994c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod HintingDevice hinting; 15004c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod VariationDevice variation; 15014c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod } u; 15024c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod public: 15034c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod DEFINE_SIZE_UNION (6, b); 15044c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod}; 15054c535a822f16b23a4e41e14d1b17fe179b83eabcBehdad Esfahbod 15066d9d3c55bbd4209ba339ccd2b925bb4a6c97f622Behdad Esfahbod 15077d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 15087c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 1509acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 15105f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ 1511