hb-ot-layout-common-private.hh revision 51f563579b94e1ee23ced9bbcc7dd3341535ce72
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 377c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbodnamespace OT { 387c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 397c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 40dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod#define NOT_COVERED ((unsigned int) -1) 41cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod#define MAX_NESTING_LEVEL 8 42ba6ddc421e5e440231c2ece2db1363f8e6d2ecbfBehdad Esfahbod#define MAX_CONTEXT_LENGTH 64 43cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod 44acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 45cd33cb9ed84308da72bd7c64b9355dc2410c63ecBehdad Esfahbod 466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 486f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * OpenType Layout Common Table Formats 496f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * 506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 522e8fb6c38dbc01cb77b384c0ae0212514dfbb588Behdad Esfahbod 536f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList 556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type> 5860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Record 5960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 604e573715ae5f5ed486ad66382bb44c47a86591ffBehdad Esfahbod inline int cmp (hb_tag_t a) const { 6136b3862009c00ad922d68810173a69ac59723365Behdad Esfahbod return tag.cmp (a); 62cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 63cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 6487e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod struct sanitize_closure_t { 6587e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod hb_tag_t tag; 6687e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod void *list_base; 6787e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod }; 68d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, void *base) { 69be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 7087e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod const sanitize_closure_t closure = {tag, base}; 7187e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); 72cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 73cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 746f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod Tag tag; /* 4-byte Tag identifier */ 756f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod OffsetTo<Type> 766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod offset; /* Offset from beginning of object holding 776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * the Record */ 78569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 79569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod DEFINE_SIZE_STATIC (6); 806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 816f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtemplate <typename Type> 83cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RecordArrayOf : SortedArrayOf<Record<Type> > { 8460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const Tag& get_tag (unsigned int i) const 8560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 864e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod /* We cheat slightly and don't define separate Null objects 874e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod * for Record types. Instead, we return the correct Null(Tag) 884e22c7e94102c9f00c32b8cb6aaa832f83909149Behdad Esfahbod * here. */ 8964d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (i >= this->len)) return Null(Tag); 90d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod return (*this)[i].tag; 916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 92e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_tags (unsigned int start_offset, 93e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *record_count /* IN/OUT */, 94e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *record_tags /* OUT */) const 95bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 96e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod if (record_count) { 9731f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod const Record<Type> *arr = this->sub_array (start_offset, record_count); 9848de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = *record_count; 99e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 10031f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod record_tags[i] = arr[i].tag; 101e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod } 102e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return this->len; 103bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 104bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_index (hb_tag_t tag, unsigned int *index) const 105bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 106cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod int i = this->search (tag); 107cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 108bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod if (index) *index = i; 109bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod return true; 110cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } else { 111cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (index) *index = Index::NOT_FOUND_INDEX; 112cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return false; 113bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 114bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 115bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod}; 116bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 117bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodtemplate <typename Type> 118bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbodstruct RecordListOf : RecordArrayOf<Type> 119bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{ 120bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Type& operator [] (unsigned int i) const 1216bec81aa3a58b8be255568b2ea63b7854e1b0ea7Behdad Esfahbod { return this+RecordArrayOf<Type>::operator [](i).offset; } 122cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 123d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 124be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1250ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); 126cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 1276f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 1286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1296f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 130cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbodstruct RangeRecord 131cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod{ 132cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod inline int cmp (hb_codepoint_t g) const { 133797d76d07f80d796a825d850772087104e5a2575Behdad Esfahbod return g < start ? -1 : g <= end ? 0 : +1 ; 134cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 135cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 136cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 137be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 1380ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 139cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod } 140cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 1416a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects (const hb_set_t *glyphs) const { 14231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->intersects (start, end); 14331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 14431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 145c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 146c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 14767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod glyphs->add_range (start, end); 14867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 14967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 150cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod GlyphID start; /* First GlyphID in the range */ 151cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod GlyphID end; /* Last GlyphID in the range */ 152cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod USHORT value; /* Value */ 153cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod public: 154cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod DEFINE_SIZE_STATIC (6); 155cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod}; 156cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad EsfahbodDEFINE_NULL_DATA (RangeRecord, "\000\001"); 157cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 158cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod 159b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbodstruct IndexArray : ArrayOf<Index> 160bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod{ 161e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_indexes (unsigned int start_offset, 162e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *_count /* IN/OUT */, 163e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *_indexes /* OUT */) const 164bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { 165e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod if (_count) { 16631f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod const USHORT *arr = this->sub_array (start_offset, _count); 16748de3730cdf91b9f6473509e22260a902ccec992Behdad Esfahbod unsigned int count = *_count; 168e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 16931f18abecb149f8888a72510f2660328dd6de16dBehdad Esfahbod _indexes[i] = arr[i]; 170e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod } 171e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod return this->len; 172bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod } 173bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod}; 174bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 175bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod 1766f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Script; 1776f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct LangSys; 1786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodstruct Feature; 1796f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 18160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LangSys 18260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 183bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_feature_count (void) const 184bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return featureIndex.len; } 185bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline hb_tag_t get_feature_index (unsigned int i) const 186bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return featureIndex[i]; } 187e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_feature_indexes (unsigned int start_offset, 188e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_count /* IN/OUT */, 189e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *feature_indexes /* OUT */) const 190e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } 1916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 192cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; } 1933d44fb6f15177dc6518166e435597936b044acc1Behdad Esfahbod inline unsigned int get_required_feature_index (void) const 19460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod if (reqFeatureIndex == 0xffff) 196b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod return Index::NOT_FOUND_INDEX; 1976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return reqFeatureIndex;; 1986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 1996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 20087e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 20187e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod const Record<LangSys>::sanitize_closure_t * = NULL) { 202be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2030ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); 204cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 205cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 2066f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod Offset lookupOrder; /* = Null (reserved for an offset to a 2076f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * reordering table) */ 2086f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT reqFeatureIndex;/* Index of a feature required for this 2096f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * language system--if no required features 2106f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * = 0xFFFF */ 211bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod IndexArray featureIndex; /* Array of indices into the FeatureList */ 212569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 2130eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, featureIndex); 2146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 21565f46b00333e20ab8a52a4b350747507541ec1dbBehdad EsfahbodDEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF"); 2166f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2176f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 21860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Script 21960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 220bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lang_sys_count (void) const 221bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.len; } 222bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline const Tag& get_lang_sys_tag (unsigned int i) const 223bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.get_tag (i); } 224e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_lang_sys_tags (unsigned int start_offset, 225e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lang_sys_count /* IN/OUT */, 226e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod hb_tag_t *lang_sys_tags /* OUT */) const 227e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } 22860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const LangSys& get_lang_sys (unsigned int i) const 22960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 230b5db4f1e4eefa266a71a28b5496f47ff9d1a81e8Behdad Esfahbod if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); 2316f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return this+langSys[i].offset; 2326f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 233bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const 234bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return langSys.find_index (tag, index); } 2356f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 236cc6c644ff2af5f6669b6ec100ff13e904872b21cBehdad Esfahbod inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } 23760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } 2386f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 23987e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 24087e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod const Record<Script>::sanitize_closure_t * = NULL) { 241be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 2420ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); 243cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 244cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 245ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 2466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod OffsetTo<LangSys> 2476f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod defaultLangSys; /* Offset to DefaultLangSys table--from 2486f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * beginning of Script table--may be Null */ 249cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod RecordArrayOf<LangSys> 2506f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod langSys; /* Array of LangSysRecords--listed 2516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * alphabetically by LangSysTag */ 252b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 2530eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, langSys); 2546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 2556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 2566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Script> ScriptList; 2576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 258875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 259875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ 260f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodstruct FeatureParamsSize 261f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 262f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 263f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod TRACE_SANITIZE (this); 264efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); 265efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 266efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod /* This subtable has some "history", if you will. Some earlier versions of 267efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Adobe tools calculated the offset of the FeatureParams sutable from the 268efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * beginning of the FeatureList table! Now, that is dealt with in the 269efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Feature implementation. But we still need to be able to tell junk from 270efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * real data. Note: We don't check that the nameID actually exists. 271efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 272efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk : 273efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 274efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Yes, it is correct that a new version of the AFDKO (version 2.0) will be 275efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * coming out soon, and that the makeotf program will build a font with a 276efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 'size' feature that is correct by the specification. 277efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 278efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * The specification for this feature tag is in the "OpenType Layout Tag 279efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Registry". You can see a copy of this at: 280efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size 281efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 282efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Here is one set of rules to determine if the 'size' feature is built 283efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * correctly, or as by the older versions of MakeOTF. You may be able to do 284efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * better. 285efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 286efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Assume that the offset to the size feature is according to specification, 287efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * and make the following value checks. If it fails, assume the the size 288efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. 289efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If this fails, reject the 'size' feature. The older makeOTF's calculated the 290efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * offset from the beginning of the FeatureList table, rather than from the 291efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * beginning of the 'size' Feature table. 292efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 293efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If "design size" == 0: 294efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * fails check 295efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 296efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else if ("subfamily identifier" == 0 and 297efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range start" == 0 and 298efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range end" == 0 and 299efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range start" == 0 and 300efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" == 0) 301efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * passes check: this is the format used when there is a design size 302efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * specified, but there is no recommended size range. 303efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 304efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else if ("design size" < "range start" or 305efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "design size" > "range end" or 306efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "range end" <= "range start" or 307efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" < 256 or 308efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * "menu name ID" > 32767 or 309efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * menu name ID is not a name ID which is actually in the name table) 310efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * fails test 311efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * Else 312efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * passes test. 313efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod */ 314efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 315efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (!designSize) 316efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (false); 317efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else if (subfamilyID == 0 && 318efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID == 0 && 319efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod rangeStart == 0 && 320efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod rangeEnd == 0) 321efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (true); 322efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else if (designSize < rangeStart || 323efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod designSize > rangeEnd || 324efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID < 256 || 325efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod subfamilyNameID > 32767) 326efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (false); 327efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod else 328efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (true); 329f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 330f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 331875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT designSize; /* Represents the design size in 720/inch 332875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * units (decipoints). The design size entry 333875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * must be non-zero. When there is a design 334875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * size but no recommended size range, the 335875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * rest of the array will consist of zeros. */ 336875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT subfamilyID; /* Has no independent meaning, but serves 337875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * as an identifier that associates fonts 338875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * in a subfamily. All fonts which share a 339875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Preferred or Font Family name and which 340875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * differ only by size range shall have the 341875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * same subfamily value, and no fonts which 342875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * differ in weight or style shall have the 343875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * same subfamily value. If this value is 344875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * zero, the remaining fields in the array 345875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * will be ignored. */ 346875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT subfamilyNameID;/* If the preceding value is non-zero, this 347875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * value must be set in the range 256 - 32767 348875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive). It records the value of a 349875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * field in the name table, which must 350875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * contain English-language strings encoded 351875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * in Windows Unicode and Macintosh Roman, 352875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * and may contain additional strings 353875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * localized to other scripts and languages. 354875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Each of these strings is the name an 355875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * application should use, in combination 356875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * with the family name, to represent the 357875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * subfamily in a menu. Applications will 358875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * choose the appropriate version based on 359875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * their selection criteria. */ 360875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT rangeStart; /* Large end of the recommended usage range 361875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (inclusive), stored in 720/inch units 362875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 363875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT rangeEnd; /* Small end of the recommended usage range 364875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod (exclusive), stored in 720/inch units 365875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * (decipoints). */ 366f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod public: 367f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod DEFINE_SIZE_STATIC (10); 368f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod}; 369f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 370875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ 371875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbodstruct FeatureParamsStylisticSet 372875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod{ 373875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 374875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod TRACE_SANITIZE (this); 375875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod /* Right now minorVersion is at zero. Which means, any table supports 376875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * the uiNameID field. */ 377875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 378875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod } 379875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 380e1ebf01d0cf3df55bb9137136e2d0c9630e7bd78Behdad Esfahbod USHORT version; /* (set to 0): This corresponds to a “minor” 381875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * version number. Additional data may be 382875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * added to the end of this Feature Parameters 383875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * table in the future. */ 384875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 385875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod USHORT uiNameID; /* The 'name' table name ID that specifies a 386875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * string (or strings, for multiple languages) 387875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * for a user-interface label for this 388875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * feature. The values of uiLabelNameId and 389875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * sampleTextNameId are expected to be in the 390875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * font-specific name ID range (256-32767), 391875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * though that is not a requirement in this 392875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * Feature Parameters specification. The 393875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * user-interface label for the feature can 394875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * be provided in multiple languages. An 395875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * English string should be included as a 396875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * fallback. The string should be kept to a 397875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * minimal length to fit comfortably with 398875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod * different application interfaces. */ 399875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod public: 400875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod DEFINE_SIZE_STATIC (4); 401875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod}; 402875a5cbc9c37f4264241c43b80afad2628eab749Behdad Esfahbod 403a182dbc9e4e51fa7990c4aea3eaa425a061b29c7Behdad Esfahbod/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ 4040bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbodstruct FeatureParamsCharacterVariants 4050bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod{ 4060bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 4070bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod TRACE_SANITIZE (this); 4080bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 4090bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod characters.sanitize (c)); 4100bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod } 411efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 4120bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT format; /* Format number is set to 0. */ 4130bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT featUILableNameID; /* The ‘name’ table name ID that 4140bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies a string (or strings, 4150bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * for multiple languages) for a 4160bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * user-interface label for this 4170bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature. (May be NULL.) */ 4180bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that 4190bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies a string (or strings, 4200bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * for multiple languages) that an 4210bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * application can use for tooltip 4220bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * text for this feature. (May be 4230bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * NULL.) */ 4240bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT sampleTextNameID; /* The ‘name’ table name ID that 4250bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * specifies sample text that 4260bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * illustrates the effect of this 4270bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature. (May be NULL.) */ 4280bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT numNamedParameters; /* Number of named parameters. (May 4290bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * be zero.) */ 4300bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID 4310bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * used to specify strings for 4320bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * user-interface labels for the 4330bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature parameters. (Must be zero 4340bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * if numParameters is zero.) */ 4350bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod ArrayOf<UINT24> 4360bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod characters; /* Array of the Unicode Scalar Value 4370bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * of the characters for which this 4380bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * feature provides glyph variants. 4390bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod * (May be zero.) */ 4400bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod public: 4410bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod DEFINE_SIZE_ARRAY (14, characters); 4420bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod}; 4430bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod 444f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbodstruct FeatureParams 445f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod{ 446efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) { 447f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod TRACE_SANITIZE (this); 448efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == HB_TAG ('s','i','z','e')) 449efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (u.size.sanitize (c)); 450efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if ((tag & 0xFFFF0000) == HB_TAG ('s','s','\0','\0')) /* ssXX */ 451efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (u.stylisticSet.sanitize (c)); 452efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if ((tag & 0xFFFF0000) == HB_TAG ('c','v','\0','\0')) /* cvXX */ 453efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (u.characterVariants.sanitize (c)); 454efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (true); 455f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } 456f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 457efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const 458efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod { 459efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (tag == HB_TAG ('s','i','z','e')) 460efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return u.size; 461efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return Null(FeatureParamsSize); 462efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod } 463efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 464efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod private: 465f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod union { 4660bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsSize size; 4670bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsStylisticSet stylisticSet; 4680bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod FeatureParamsCharacterVariants characterVariants; 469f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod } u; 4700bae50a36f3022f9bb6b2c001c191eeaaa4ef954Behdad Esfahbod DEFINE_SIZE_STATIC (17); 471f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod}; 4726f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 47360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Feature 47460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 475bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline unsigned int get_lookup_count (void) const 476bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return lookupIndex.len; } 477bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod inline hb_tag_t get_lookup_index (unsigned int i) const 478bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod { return lookupIndex[i]; } 479e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod inline unsigned int get_lookup_indexes (unsigned int start_index, 480e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lookup_count /* IN/OUT */, 481e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod unsigned int *lookup_tags /* OUT */) const 482e21899bc3593aa0d3adf64cee21c5de2ea219783Behdad Esfahbod { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } 4836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 484f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod inline const FeatureParams &get_feature_params (void) const 485f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod { return this+featureParams; } 486f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod 48787e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, 48887e43b7f2be25840748f920ca33ff553833da45fBehdad Esfahbod const Record<Feature>::sanitize_closure_t *closure) { 489be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 4909b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) 4919b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod return TRACE_RETURN (false); 4929b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 493efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod /* Some earlier versions of Adobe tools calculated the offset of the 494efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * FeatureParams subtable from the beginning of the FeatureList table! 495efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * 496efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * If sanitizing "failed" for the FeatureParams subtable, try it with the 497efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * alternative location. We would know sanitize "failed" if old value 498efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod * of the offset was non-zero, but it's zeroed now. 4991ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * 5001ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * Only do this for the 'size' feature, since at the time of the faulty 5011ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod * Adobe tools, only the 'size' feature had FeatureParams defined. 502efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod */ 503efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 5049b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod Offset orig_offset = featureParams; 505efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) 506efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (false); 507efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 508efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (likely (!orig_offset)) 5099b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod return TRACE_RETURN (true); 5109b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 5111ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod if (featureParams == 0 && closure && 5121ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod closure->tag == HB_TAG ('s','i','z','e') && 5131ffd23cb47a61465d52a7aeebb9c1b676e7c9a7eBehdad Esfahbod closure->list_base && closure->list_base < this) 5149b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod { 515efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod unsigned int new_offset_int = (unsigned int) orig_offset - 516dac86026a6bae5a8a03cfe885bf93f32e5f48614Behdad Esfahbod (((char *) this) - ((char *) closure->list_base)); 517efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod 5189b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod Offset new_offset; 5199b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod /* Check that it did not overflow. */ 520efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod new_offset.set (new_offset_int); 521efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod if (new_offset == new_offset_int && 52251f563579b94e1ee23ced9bbcc7dd3341535ce72Behdad Esfahbod c->try_set (&featureParams, new_offset) && 523efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) 5249b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod return TRACE_RETURN (false); 5259b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod } 5269b54562d63f1a9e0e5b33d71c32bd1588759ebf1Behdad Esfahbod 527efe252e6000558f78075adadb2a3dba25ab67c04Behdad Esfahbod return TRACE_RETURN (true); 528cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 529cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 530f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod OffsetTo<FeatureParams> 531f54cce3c6a0432268ce159dbe6c5c6b7f583b87aBehdad Esfahbod featureParams; /* Offset to Feature Parameters table (if one 5326f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * has been defined for the feature), relative 5336f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * to the beginning of the Feature Table; = Null 5346f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * if not required */ 535bff3c0fde5da04a70d1f7aeeb9fa2a75fe5c07f6Behdad Esfahbod IndexArray lookupIndex; /* Array of LookupList indices */ 536b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 5370eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, lookupIndex); 5386f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 5396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5406f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef RecordListOf<Feature> FeatureList; 5416f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 54360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct LookupFlag : USHORT 54460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 545c6035cf802c60f0526f421f39a55886061df94eeBehdad Esfahbod enum Flags { 5464fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod RightToLeft = 0x0001u, 5474fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreBaseGlyphs = 0x0002u, 5484fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreLigatures = 0x0004u, 5494fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod IgnoreMarks = 0x0008u, 550aa87d951739f6beacb66daa235cd033fdcfcadd7Behdad Esfahbod IgnoreFlags = 0x000Eu, 551d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod UseMarkFilteringSet = 0x0010u, 552d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod Reserved = 0x00E0u, 5538f034d5849627ee95a5889fa34c9ba294fff13caBehdad Esfahbod MarkAttachmentType = 0xFF00u 5544fa77d3c4305a76b956de8c1a9b83a961d035a80Behdad Esfahbod }; 555b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 556b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod DEFINE_SIZE_STATIC (2); 5576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 5586f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 55960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Lookup 56060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 56160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_subtable_count (void) const { return subTable.len; } 5626f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 5636f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod inline unsigned int get_type (void) const { return lookupType; } 5648c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod 5658c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and 5668c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod * higher 16-bit is mark-filtering-set if the lookup uses one. 5678c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod * Not to be confused with glyph_props which is very similar. */ 5688c69e65abed961002d90024c92e18538c6516262Behdad Esfahbod inline uint32_t get_props (void) const 569d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod { 570d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod unsigned int flag = lookupFlag; 57164d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) 572d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod { 573e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 57409c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod flag += (markFilteringSet << 16); 575d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod } 576d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod return flag; 577d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod } 5786f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 579652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 580652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod unsigned int lookup_type, 581652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod uint32_t lookup_props, 582652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod unsigned int num_subtables) 583652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod { 584be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 585652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 586652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod lookupType.set (lookup_type); 587652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod lookupFlag.set (lookup_props & 0xFFFF); 588652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false); 589b3b89b66586897a69b410ef02e7434691de84ae6Behdad Esfahbod if (lookupFlag & LookupFlag::UseMarkFilteringSet) 590652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod { 591652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 592652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod markFilteringSet.set (lookup_props >> 16); 593652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod } 594652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod return TRACE_RETURN (true); 595652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod } 596652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod 597d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 598be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 5993b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod /* Real sanitize of the subtables is done by GSUB/GPOS/... */ 6000ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); 601652d1e0d64e47313ead2fc8318d1236f0e0d80caBehdad Esfahbod if (lookupFlag & LookupFlag::UseMarkFilteringSet) 602cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod { 603e961c86c579fd98ee604342a9c70c4e7f8d4f220Behdad Esfahbod USHORT &markFilteringSet = StructAfter<USHORT> (subTable); 6040ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); 605cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 6060ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (true); 607cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod } 608cd3827ee567612c5500206b62840702fc956e0f5Behdad Esfahbod 609d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod USHORT lookupType; /* Different enumerations for GSUB and GPOS */ 610d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod USHORT lookupFlag; /* Lookup qualifiers */ 6113b2c2df41b90f2a1d9e33b3dc15a92cff58a689aBehdad Esfahbod ArrayOf<Offset> 612d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod subTable; /* Array of SubTables */ 613d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets 614d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod * structure. This field is only present if bit 615d7df42d7ee586219475878d160f85ae5a188bd59Behdad Esfahbod * UseMarkFilteringSet of lookup flags is set. */ 616569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 6170eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); 6186f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 6196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbodtypedef OffsetListOf<Lookup> LookupList; 6216f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6226f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6236f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 6246f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Coverage Table 6256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 6266f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 62760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat1 62860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6296f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 6306f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6316f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 63260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 63360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 634cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod int i = glyphArray.search (glyph_id); 635dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED); 636dadede012e4841f9fcb70d514fdc752f3ea4663dBehdad Esfahbod return i; 6376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 6386f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 639bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 640a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 641bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 6429f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 643be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 644bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 645bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod glyphArray.len.set (num_glyphs); 646bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); 6479f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 0; i < num_glyphs; i++) 648fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod glyphArray[i] = glyphs[i]; 649a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 6509f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod return TRACE_RETURN (true); 6519f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 6529f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 653d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 654be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 6550ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (glyphArray.sanitize (c)); 65670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 65770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 6586a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 65931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return glyphs->has (glyphArray[index]); 66031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 66131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 662c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 663c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 66467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = glyphArray.len; 66567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 66667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod glyphs->add (glyphArray[i]); 66767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 66867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 669365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 670365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 6717d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 672c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; 673c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->glyphArray.len; } 674c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { i++; } 675c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_glyph (void) { return c->glyphArray[i]; } 676c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_coverage (void) { return i; } 6777d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 6787d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 6797d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat1 *c; 6807d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod unsigned int i; 6817d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 682365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 6837d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 684ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 6856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT coverageFormat; /* Format identifier--format = 1 */ 686cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<GlyphID> 6876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod glyphArray; /* Array of GlyphIDs--in numerical order */ 688b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 6890eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, glyphArray); 6906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 6916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 69260d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct CoverageFormat2 69360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 6946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct Coverage; 6956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 6966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 69760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 69860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 699cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod int i = rangeRecord.search (glyph_id); 700cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) { 701cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 702cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return (unsigned int) range.value + (glyph_id - range.start); 7036f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return NOT_COVERED; 7056f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 7066f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 707bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 708a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 709bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 7109f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 711be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 712bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 713bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 714bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod if (unlikely (!num_glyphs)) return TRACE_RETURN (true); 715bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7169f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 7179f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7189f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 7199f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 720bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord.len.set (num_ranges); 721bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod if (unlikely (!c->extend (rangeRecord))) return TRACE_RETURN (false); 722bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod 7239f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int range = 0; 724fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[0]; 725bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].value.set (0); 7269f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 7279f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) { 7289f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod range++; 729fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].start = glyphs[i]; 730fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].value.set (i); 731fabd3113a98c5f4114f48920fa7ea38bd65a8d32Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7329f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } else { 733bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod rangeRecord[range].end = glyphs[i]; 7349f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 735a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod glyphs.advance (num_glyphs); 7369f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod return TRACE_RETURN (true); 7379f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 7389f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 739d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 740be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 7410ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (rangeRecord.sanitize (c)); 74270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 74370de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 7446a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 74531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int i; 74631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 74731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (i = 0; i < count; i++) { 74831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod const RangeRecord &range = rangeRecord[i]; 74931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (range.value <= index && 7503f18236a03880c0960f5990dc90685f6146951a6Behdad Esfahbod index < (unsigned int) range.value + (range.end - range.start) && 75131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod range.intersects (glyphs)) 75231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 75331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod else if (index < range.value) 75431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 75531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 75631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 75731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 75831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 759c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 760c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 76167bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod unsigned int count = rangeRecord.len; 76267bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 76367bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod rangeRecord[i].add_coverage (glyphs); 76467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 76567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 766365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod public: 767365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod /* Older compilers need this to be public. */ 7687d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 769c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const CoverageFormat2 &c_) { 770c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod c = &c_; 771c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod coverage = 0; 772c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod i = 0; 773c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; 774c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 775c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { return i < c->rangeRecord.len; } 776c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { 777c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod coverage++; 7787d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod if (j == c->rangeRecord[i].end) { 7797d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod i++; 7800da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod if (more ()) 7810da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod j = c->rangeRecord[i].start; 7820da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod return; 7837d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 7840da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod j++; 7850da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 786c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_glyph (void) { return j; } 787c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_coverage (void) { return coverage; } 7887d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 7897d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 7907d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod const struct CoverageFormat2 *c; 791c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int i, j, coverage; 7927d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 793365f27ab5ba025bf1be6a882ed213c695cbfed7eBehdad Esfahbod private: 7947d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 795ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 7966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT coverageFormat; /* Format identifier--format = 2 */ 797cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 7986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 7996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID. rangeCount entries 8006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * long */ 801b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 8020eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 8036f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 8046f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 80560d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Coverage 80660d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 80720b035dad41247076815a2bbb0346d63058b322fBehdad Esfahbod inline unsigned int get_coverage (hb_codepoint_t glyph_id) const 80860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 8096f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 810dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_coverage(glyph_id); 811dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_coverage(glyph_id); 8126f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return NOT_COVERED; 8136f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 8146f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 8156f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 816bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod inline bool serialize (hb_serialize_context_t *c, 817a930c68e9c50aade78c1eb0eef075c9c117e4ef6Behdad Esfahbod Supplier<GlyphID> &glyphs, 818bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod unsigned int num_glyphs) 8199f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod { 820be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SERIALIZE (this); 821c61be03d6df122f18eebda3b29e42c9e768d45b9Behdad Esfahbod if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); 8229f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod unsigned int num_ranges = 1; 8239f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod for (unsigned int i = 1; i < num_glyphs; i++) 8249f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod if (glyphs[i - 1] + 1 != glyphs[i]) 8259f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod num_ranges++; 826bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); 827bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod switch (u.format) { 828bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); 829bc5be24014371ceb811b9ffd37062ede63d87bb1Behdad Esfahbod case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); 8309f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod default:return TRACE_RETURN (false); 8319f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 8329f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod } 8339f2348de58f0f85593027378169bc03c4dd64e59Behdad Esfahbod 834d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 835be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 8360ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 83770de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 8380ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 8390ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 2: return TRACE_RETURN (u.format2.sanitize (c)); 8400ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 84170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 84270de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 8436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 8446a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects (const hb_set_t *glyphs) const { 845c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod /* TODO speed this up */ 846c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Coverage::Iter iter; 847c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod for (iter.init (*this); iter.more (); iter.next ()) { 848c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod if (glyphs->has (iter.get_glyph ())) 849c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod return true; 850c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 851c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod return false; 85231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 853c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 8546a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { 85531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 85631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_coverage (glyphs, index); 85731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_coverage (glyphs, index); 85831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 85931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 860c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 861c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod 862c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod template <typename set_t> 863c8accf1dd2d92cc4f714393eb0ea46f69bb182a6Behdad Esfahbod inline void add_coverage (set_t *glyphs) const { 86467bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod switch (u.format) { 86567bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod case 1: u.format1.add_coverage (glyphs); break; 86667bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod case 2: u.format2.add_coverage (glyphs); break; 86767bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod default: break; 86867bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 86967bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod } 87067bb9e8cea49a44be6996515e1c7d8cdc95a77e6Behdad Esfahbod 8717d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod struct Iter { 872c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod Iter (void) : format (0) {}; 873c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void init (const Coverage &c_) { 8747d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod format = c_.u.format; 8757d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 87648382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 1: u.format1.init (c_.u.format1); return; 87748382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod case 2: u.format2.init (c_.u.format2); return; 87848382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default: return; 8797d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 8807d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 881c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline bool more (void) { 8827d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 8837d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 1: return u.format1.more (); 8847d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod case 2: return u.format2.more (); 88548382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return false; 8867d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 8877d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 888c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline void next (void) { 8890da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod switch (format) { 8900da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 1: u.format1.next (); break; 8910da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod case 2: u.format2.next (); break; 8920da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod default: break; 8930da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 8940da132bde4d576a03095d6738507954f7f85103dBehdad Esfahbod } 895c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_glyph (void) { 896c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod switch (format) { 897c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_glyph (); 898c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_glyph (); 89948382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return 0; 900c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 901c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod } 902c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod inline uint16_t get_coverage (void) { 9037d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod switch (format) { 904c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 1: return u.format1.get_coverage (); 905c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod case 2: return u.format2.get_coverage (); 90648382e2f41499a91181bea0acc5792989d2485bbBehdad Esfahbod default:return -1; 9077d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9087d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } 9097d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 9107d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod private: 911c64ddab3c34897cd520d4d73a054866e649e8793Behdad Esfahbod unsigned int format; 9127d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod union { 9137d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod CoverageFormat1::Iter format1; 9147d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod CoverageFormat2::Iter format2; 9157d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod } u; 9167d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod }; 9177d50d502635d7c95e6bd091e7d4cc993f0853f76Behdad Esfahbod 918ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 9196f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 9206f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT format; /* Format identifier */ 921dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat1 format1; 922dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod CoverageFormat2 format2; 9236f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 924ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 925596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 9266f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 9276f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9296f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 9306f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Class Definition Table 9316f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 9326f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 93360d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat1 93460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 9356f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 9366f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9376f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 93898370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 93960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 940caf0412690542e58e23246dccc4b2fb83bd652ecBehdad Esfahbod if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len)) 9416f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return classValue[glyph_id - startGlyph]; 9426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 9436f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 9446f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 945d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 946be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 9470ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); 94870de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 94970de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 95089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 95189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (set_t *glyphs, unsigned int klass) const { 95289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = classValue.len; 95389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 95489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod if (classValue[i] == klass) 95589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod glyphs->add (startGlyph + i); 95689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 95789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 9586a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 95931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = classValue.len; 960625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 961625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 962625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 963625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod hb_codepoint_t g = -1; 964625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 965625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return false; 966625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < startGlyph) 967625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 968625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = startGlyph + count - 1; 969625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (hb_set_next (glyphs, &g)) 970625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 971625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 972625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 97331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 97431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (classValue[i] == klass && glyphs->has (startGlyph + i)) 97531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 97631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 97731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 97831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 979ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 9806f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT classFormat; /* Format identifier--format = 1 */ 9816f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod GlyphID startGlyph; /* First GlyphID of the classValueArray */ 9826f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod ArrayOf<USHORT> 9836f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod classValue; /* Array of Class Values--one per GlyphID */ 984b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 9850eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, classValue); 9866f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 9876f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 98860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDefFormat2 98960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 9906f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod friend struct ClassDef; 9916f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 9926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod private: 99398370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 99460d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 995cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod int i = rangeRecord.search (glyph_id); 996cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod if (i != -1) 997cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod return rangeRecord[i].value; 9986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod return 0; 9996f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10006f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1001d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1002be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 10030ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (rangeRecord.sanitize (c)); 100470de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 100570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod 100689ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod template <typename set_t> 100789ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (set_t *glyphs, unsigned int klass) const { 100889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod unsigned int count = rangeRecord.len; 100989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod for (unsigned int i = 0; i < count; i++) 101089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod if (rangeRecord[i].value == klass) 101189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod rangeRecord[i].add_coverage (glyphs); 101289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 101389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10146a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 101531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod unsigned int count = rangeRecord.len; 1016625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (klass == 0) 1017625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1018625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Match if there's any glyph that is not listed! */ 1019515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod hb_codepoint_t g = (hb_codepoint_t) -1; 1020625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 1021625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod { 1022625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (!hb_set_next (glyphs, &g)) 1023625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod break; 1024625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod if (g < rangeRecord[i].start) 1025625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1026625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod g = rangeRecord[i].end; 1027625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 1028515a0ac81e531c95b1bb7f1a3c5df73a9e64b14fBehdad Esfahbod if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) 1029625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod return true; 1030625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod /* Fall through. */ 1031625678436c29100eef82d87e635b251030a18f60Behdad Esfahbod } 103231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod for (unsigned int i = 0; i < count; i++) 103331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) 103431081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return true; 103531081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod return false; 103631081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 103731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1038ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 10396f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT classFormat; /* Format identifier--format = 2 */ 1040cc8a4abea68f2dba26feb5785f9e518e6853c744Behdad Esfahbod SortedArrayOf<RangeRecord> 10416f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod rangeRecord; /* Array of glyph ranges--ordered by 10426f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Start GlyphID */ 1043b3651231bf80bb7009214547a75ed90e21815c68Behdad Esfahbod public: 10440eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (4, rangeRecord); 10456f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 10466f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 104760d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct ClassDef 104860d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 104998370e89d1bff248737b482d129c2a4deb8bfd95Behdad Esfahbod inline unsigned int get_class (hb_codepoint_t glyph_id) const 105060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 10516f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod switch (u.format) { 1052dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 1: return u.format1.get_class(glyph_id); 1053dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod case 2: return u.format2.get_class(glyph_id); 10546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod default:return 0; 10556f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10566f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } 10576f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1058d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1059be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 10600ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 106170de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod switch (u.format) { 10620ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 1: return TRACE_RETURN (u.format1.sanitize (c)); 10630ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod case 2: return TRACE_RETURN (u.format2.sanitize (c)); 10640ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod default:return TRACE_RETURN (true); 106570de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 106670de50c11ed7037b20eb6814ff60f6e32a9944e4Behdad Esfahbod } 1067aa3d7adca5c821c91a2a1b5380fd6b3d19656ab1Behdad Esfahbod 106889ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod inline void add_class (hb_set_t *glyphs, unsigned int klass) const { 106989ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod switch (u.format) { 107089ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod case 1: u.format1.add_class (glyphs, klass); return; 107189ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod case 2: u.format2.add_class (glyphs, klass); return; 107289ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod default:return; 107389ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 107489ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod } 107589ca8eeb83fedde06727d386369a0a39d410f12bBehdad Esfahbod 10766a9be5bd3524dc3eb1e88d1063bde2e4d8b57011Behdad Esfahbod inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { 107731081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod switch (u.format) { 107831081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 1: return u.format1.intersects_class (glyphs, klass); 107931081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod case 2: return u.format2.intersects_class (glyphs, klass); 108031081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod default:return false; 108131081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 108231081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod } 108331081f7390e5130df72f89acc609ccab5dc77a48Behdad Esfahbod 1084ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 10856f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod union { 10866f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod USHORT format; /* Format identifier */ 1087dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat1 format1; 1088dacebcadae36b35531d635d81df2afb937677b7aBehdad Esfahbod ClassDefFormat2 format2; 10896f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod } u; 1090ed07422c33bbb52ff4d79e65986171e3f07697d8Behdad Esfahbod public: 1091596e471aa5053d955fb5d5b5923088c8814469b1Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 10926f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 10936f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10946f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 10956f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod/* 10966f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod * Device Tables 10976f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod */ 10986f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 109960d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbodstruct Device 110060d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod{ 1101b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1102abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_x_delta (hb_font_t *font) const 1103abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->x_ppem, font->x_scale); } 1104b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1105abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod inline hb_position_t get_y_delta (hb_font_t *font) const 1106abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod { return get_delta (font->y_ppem, font->y_scale); } 1107b634beb39e0a4fef7167a8af646f6b2d8cafe69bBehdad Esfahbod 1108da975419884a535281745f30f4b32fee0bc8a7a1Behdad Esfahbod inline int get_delta (unsigned int ppem, int scale) const 11095bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod { 11105bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!ppem) return 0; 11115bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 11125bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod int pixels = get_delta_pixels (ppem); 11135bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 11145bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod if (!pixels) return 0; 11155bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 111683408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod return (int) (pixels * (int64_t) scale / ppem); 11175bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod } 11185bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 11195bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod 11205bd1e95236320aed60fb29ca1e93b9595d4aeeecBehdad Esfahbod inline int get_delta_pixels (unsigned int ppem_size) const 112160d77cf05fddc5304b4b1fc19cdedba15cbee1e9Behdad Esfahbod { 1122056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int f = deltaFormat; 112364d3fc8d0dada673245cc8c0b1c12cd849b30997Behdad Esfahbod if (unlikely (f < 1 || f > 3)) 1124056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 11256f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1126056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod if (ppem_size < startSize || ppem_size > endSize) 1127056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return 0; 11286f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1129056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int s = ppem_size - startSize; 11306f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1131056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod unsigned int byte = deltaValue[s >> (4 - f)]; 113209c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f))); 113309c292e3b688a67fbae67b645d1e6ffcf8d8eb6eBehdad Esfahbod unsigned int mask = (0xFFFF >> (16 - (1 << f))); 1134056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1135056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod int delta = bits & mask; 1136056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 113715164d9258a74122a4db748d35532bd72c47cec2Behdad Esfahbod if ((unsigned int) delta >= ((mask + 1) >> 1)) 1138056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod delta -= mask + 1; 1139056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 1140056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod return delta; 1141056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod } 1142056c7ec1aea1eca60a3b20b583b8a8072be9d758Behdad Esfahbod 11437f97d2cd904ea999c099c73c52187c5d65aeec67Behdad Esfahbod inline unsigned int get_size (void) const 1144dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod { 1145dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod unsigned int f = deltaFormat; 1146b961518b9611471ff7060e97686e5625974847ebBehdad Esfahbod if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; 1147b961518b9611471ff7060e97686e5625974847ebBehdad Esfahbod return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); 1148dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod } 1149dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod 1150d7cfb3b2d1dd2e9fdae2b3e540bbe313660895e8Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1151be218c688cbb037a99c8c64bb835f3c980040c0bBehdad Esfahbod TRACE_SANITIZE (this); 11520ab8c8621712d33e1e91dfdb4ad0b335e3d2a3fbBehdad Esfahbod return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); 1153dc9c4d93cd0f3ac991f32df08c1c17fc389054c0Behdad Esfahbod } 11546f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 1155ec8d2494694275dfbbac2dd0d33ca2894b0463d6Behdad Esfahbod protected: 11560795b784dd1009976c185482a376df250167e73bBehdad Esfahbod USHORT startSize; /* Smallest size to correct--in ppem */ 11570795b784dd1009976c185482a376df250167e73bBehdad Esfahbod USHORT endSize; /* Largest size to correct--in ppem */ 1158caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 1159caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 1 Signed 2-bit value, 8 values per uint16 1160caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 2 Signed 4-bit value, 4 values per uint16 1161caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod * 3 Signed 8-bit value, 2 values per uint16 1162caff7db93d205e32a535d49e51a3cad70f91dfddBehdad Esfahbod */ 1163d3480ba37fbb5d4be75b094060f5b2f1ce98fb53Behdad Esfahbod USHORT deltaValue[VAR]; /* Array of compressed data */ 1164569da92bc6956f42d9b2d65c784e184fb6380efeBehdad Esfahbod public: 11650eb9fc6e37935707dba2bf4b3705de2161a08cb7Behdad Esfahbod DEFINE_SIZE_ARRAY (6, deltaValue); 11666f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod}; 11676f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 11686f20f72e9c58ba23db2e31afa5d331acfea3d77eBehdad Esfahbod 11697d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod} /* namespace OT */ 11707c8e844d92aa604fc4b396343721ea90eb83adb8Behdad Esfahbod 1171acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod 11725f5b24f99f52bbc922e238b65c06061ba07c8548Behdad Esfahbod#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ 1173