hb-ot-cmap-table.hh revision b47159011ca518c3b94d782ed16a91ffe9dd2ab2
141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod/* 241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * Copyright © 2014 Google, Inc. 341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * 441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * 641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * Permission is hereby granted, without written agreement and without 741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * software and its documentation for any purpose, provided that the 941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 1041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * all copies of this software. 1141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * 1241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * DAMAGE. 1741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * 1841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * 2441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * Google Author(s): Behdad Esfahbod 2541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod */ 2641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 2741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#ifndef HB_OT_CMAP_TABLE_HH 2841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#define HB_OT_CMAP_TABLE_HH 2941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#include "hb-open-type-private.hh" 3141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodnamespace OT { 3441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod/* 3741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * cmap -- Character To Glyph Index Mapping Table 3841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod */ 3941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 4041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#define HB_OT_TAG_cmap HB_TAG('c','m','a','p') 4141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 4241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 43b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbodstruct CmapSubtableFormat0 44b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod{ 45b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 46b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod { 47b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0; 48b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod if (!gid) 49b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod return false; 50b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod *glyph = gid; 51b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod return true; 52b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod } 53b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 54de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 55de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 56b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod TRACE_SANITIZE (this); 57b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 58b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod } 59b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 60b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod protected: 61b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod USHORT format; /* Format number is set to 0. */ 627d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT lengthZ; /* Byte length of this subtable. */ 637d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT languageZ; /* Ignore. */ 64b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod BYTE glyphIdArray[256];/* An array that maps character 65b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod * code to glyph index values. */ 66b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod public: 67b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod DEFINE_SIZE_STATIC (6 + 256); 68b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod}; 69b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 7041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtableFormat4 7141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 7241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 7341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 74c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int segCount; 75c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *endCount; 76c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *startCount; 77c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *idDelta; 78c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *idRangeOffset; 79c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *glyphIdArray; 80c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int glyphIdArrayLength; 81c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 82c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod segCount = this->segCountX2 / 2; 83c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod endCount = this->values; 84c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod startCount = endCount + segCount + 1; 85c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod idDelta = startCount + segCount; 86c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod idRangeOffset = idDelta + segCount; 87c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod glyphIdArray = idRangeOffset + segCount; 88c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; 89c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 90df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* Custom two-array bsearch. */ 91c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod int min = 0, max = (int) segCount - 1; 92c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int i; 93c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod while (min <= max) 94c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 95c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod int mid = (min + max) / 2; 96c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (codepoint < startCount[mid]) 97c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod max = mid - 1; 98c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else if (codepoint > endCount[mid]) 99c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod min = mid + 1; 100c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 101c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 102c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod i = mid; 103c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod goto found; 104c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 105c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 10641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return false; 107c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 108c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod found: 109c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod hb_codepoint_t gid; 110c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int rangeOffset = idRangeOffset[i]; 111c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (rangeOffset == 0) 112c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid = codepoint + idDelta[i]; 113c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 114c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 115c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod /* Somebody has been smoking... */ 116c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; 117c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (unlikely (index >= glyphIdArrayLength)) 118c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return false; 119c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid = glyphIdArray[index]; 120c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (unlikely (!gid)) 121c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return false; 122c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid += idDelta[i]; 123c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 124c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 1257627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *glyph = gid & 0xFFFFu; 126c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return true; 12741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 12841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 129de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 130257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod { 13141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 132257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (unlikely (!c->check_struct (this))) 133b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 134257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod 135257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (unlikely (!c->check_range (this, length))) 136257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod { 137257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod /* Some broken fonts have too long of a "length" value. 138257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod * If that is the case, just change the value to truncate 139257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod * the subtable at the end of the blob. */ 140257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535, 141257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod (uintptr_t) (c->end - 142257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod (char *) this)); 143257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (!c->try_set (&length, new_length)) 144b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 145257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod } 146257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod 147b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (16 + 4 * (unsigned int) segCountX2 <= length); 14841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 14941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 15041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 15141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format number is set to 4. */ 15241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT length; /* This is the length in bytes of the 15341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * subtable. */ 1547d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT languageZ; /* Ignore. */ 15541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT segCountX2; /* 2 x segCount. */ 1567d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */ 1577d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT entrySelectorZ; /* log2(searchRange/2) */ 1587d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT rangeShiftZ; /* 2 x segCount - searchRange */ 15941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 16041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT values[VAR]; 16141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#if 0 16241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT endCount[segCount]; /* End characterCode for each segment, 1637627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * last=0xFFFFu. */ 16441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT reservedPad; /* Set to 0. */ 16541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT startCount[segCount]; /* Start character code for each segment. */ 16641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod SHORT idDelta[segCount]; /* Delta for all character codes in segment. */ 16741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ 16841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ 16941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif 17041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 17141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 17241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (14, values); 17341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 17441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 175d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbodstruct CmapSubtableLongGroup 1760d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 1770d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod friend struct CmapSubtableFormat12; 178d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod friend struct CmapSubtableFormat13; 1790d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1800d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod int cmp (hb_codepoint_t codepoint) const 1810d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 1820d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint < startCharCode) return -1; 1830d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint > endCharCode) return +1; 1840d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return 0; 1850d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 1860d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 187de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 188de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 1890d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 190b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 1910d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 1920d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1930d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod private: 1940d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG startCharCode; /* First character code in this group. */ 1950d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG endCharCode; /* Last character code in this group. */ 196d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod ULONG glyphID; /* Glyph index; interpretation depends on 197d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod * subtable format. */ 1980d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod public: 1990d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod DEFINE_SIZE_STATIC (12); 2000d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 2010d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 20294759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodtemplate <typename UINT> 20394759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableTrimmed 20491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod{ 20591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 20691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod { 20791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod /* Rely on our implicit array bound-checking. */ 20891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode]; 20991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod if (!gid) 21091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return false; 21191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod *glyph = gid; 21291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return true; 21391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 21491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 215de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 216de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 21791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod TRACE_SANITIZE (this); 218b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); 21991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 22091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 22191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod protected: 22294759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT formatReserved; /* Subtable format and (maybe) padding. */ 2237d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod UINT lengthZ; /* Byte length of this subtable. */ 2247d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod UINT languageZ; /* Ignore. */ 22594759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT startCharCode; /* First character code covered. */ 2269da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod ArrayOf<GlyphID, UINT> 22791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod glyphIdArray; /* Array of glyph index values for character 22891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod * codes in the range. */ 22991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod public: 23094759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray); 23191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod}; 23291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 23394759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {}; 23494759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {}; 23591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 236ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodtemplate <typename T> 237ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableLongSegmented 2380d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 2390d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 2400d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 241df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = groups.bsearch (codepoint); 2420d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (i == -1) 2430d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return false; 244ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod *glyph = T::group_get_glyph (groups[i], codepoint); 2450d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return true; 2460d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2470d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 248de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 249de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2500d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 251b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && groups.sanitize (c)); 2520d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2530d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2540d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod protected: 2550d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod USHORT format; /* Subtable format; set to 12. */ 2567d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT reservedZ; /* Reserved; set to 0. */ 2577d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG lengthZ; /* Byte length of this subtable. */ 2587d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG languageZ; /* Ignore. */ 25941ea59495032e712fa6f801350ee00d5f00b5724Behdad Esfahbod SortedArrayOf<CmapSubtableLongGroup, ULONG> 260d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod groups; /* Groupings. */ 261d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod public: 262d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod DEFINE_SIZE_ARRAY (16, groups); 263d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod}; 264d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 265ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 266d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod{ 267ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 268ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u) 269ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID + (u - group.startCharCode); } 270ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod}; 271d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 272ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> 273ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod{ 274ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 275ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u HB_UNUSED) 276ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID; } 2770d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 2780d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 279a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef enum 280a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 281a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_NOT_FOUND = 0, 282a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_FOUND = 1, 283a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_USE_DEFAULT = 2 284a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod} glyph_variant_t; 285a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 286a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct UnicodeValueRange 287a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 288a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &codepoint) const 289a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 290a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (codepoint < startUnicodeValue) return -1; 291a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (codepoint > startUnicodeValue + additionalCount) return +1; 292a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return 0; 293a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 294a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 295de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 296de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 297a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 298b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 299a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 300a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 301a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 startUnicodeValue; /* First value in this range. */ 302a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod BYTE additionalCount; /* Number of additional values in this 303a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod * range. */ 304a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 305a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (4); 306a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 307a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 308a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS; 309a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 310a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct UVSMapping 311a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 312a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &codepoint) const 313a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 314a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return unicodeValue.cmp (codepoint); 315a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 316a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 317de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 318de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 319a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 320b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 321a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 322a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 323a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 unicodeValue; /* Base Unicode value of the UVS */ 324a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GlyphID glyphID; /* Glyph ID of the UVS */ 325a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 326a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (5); 327a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 328a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 329a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS; 330a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 331a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct VariationSelectorRecord 332a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 333a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph (hb_codepoint_t codepoint, 334a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph, 335a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const void *base) const 336a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 337a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod int i; 338a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const DefaultUVS &defaults = base+defaultUVS; 339a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod i = defaults.bsearch (codepoint); 340a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (i != -1) 341a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_USE_DEFAULT; 342a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const NonDefaultUVS &nonDefaults = base+nonDefaultUVS; 343a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod i = nonDefaults.bsearch (codepoint); 344a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (i != -1) 345a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 346a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod *glyph = nonDefaults[i].glyphID; 347a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_FOUND; 348a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 349a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_NOT_FOUND; 350a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 351a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 352a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &variation_selector) const 353a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 354a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return varSelector.cmp (variation_selector); 355a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 356a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 357de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 358de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 359a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 360b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 361b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod defaultUVS.sanitize (c, base) && 362b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod nonDefaultUVS.sanitize (c, base)); 363a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 364a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 365a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 varSelector; /* Variation selector. */ 366a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod OffsetTo<DefaultUVS, ULONG> 367a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod defaultUVS; /* Offset to Default UVS Table. May be 0. */ 368a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod OffsetTo<NonDefaultUVS, ULONG> 369a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ 370a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 371a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (11); 372a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 373a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 374a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct CmapSubtableFormat14 375a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 376a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, 377a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t variation_selector, 378a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 379a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 380a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); 381a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 382a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 383de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 384de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 385a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 386b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 387b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod record.sanitize (c, this)); 388a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 389a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 390a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod protected: 391a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod USHORT format; /* Format number is set to 0. */ 3927d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG lengthZ; /* Byte length of this subtable. */ 393a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod SortedArrayOf<VariationSelectorRecord, ULONG> 394a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod record; /* Variation selector records; sorted 395a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod * in increasing order of `varSelector'. */ 396a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 397a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_ARRAY (10, record); 398a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 399a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 40041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtable 40141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 402c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ 403c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod 404a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, 405a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 40641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 40741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 408b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod case 0: return u.format0 .get_glyph(codepoint, glyph); 4090d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 4: return u.format4 .get_glyph(codepoint, glyph); 41091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 6: return u.format6 .get_glyph(codepoint, glyph); 41191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 10: return u.format10.get_glyph(codepoint, glyph); 4120d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 12: return u.format12.get_glyph(codepoint, glyph); 413d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod case 13: return u.format13.get_glyph(codepoint, glyph); 414a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod case 14: 415a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod default: return false; 416a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 417a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 418a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 419a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, 420a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t variation_selector, 421a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 422a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 423a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod switch (u.format) { 424a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph); 425a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod default: return GLYPH_VARIANT_NOT_FOUND; 42641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 42741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 42841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 429de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 430de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 43141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 432b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 43341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 434b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 0: return_trace (u.format0 .sanitize (c)); 435b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 4: return_trace (u.format4 .sanitize (c)); 436b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 6: return_trace (u.format6 .sanitize (c)); 437b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 10: return_trace (u.format10.sanitize (c)); 438b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 12: return_trace (u.format12.sanitize (c)); 439b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 13: return_trace (u.format13.sanitize (c)); 440b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 14: return_trace (u.format14.sanitize (c)); 441b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 44241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 44341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 44441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 44541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 44641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod union { 44741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format identifier */ 448b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod CmapSubtableFormat0 format0; 44941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod CmapSubtableFormat4 format4; 45091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat6 format6; 45191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat10 format10; 4520d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod CmapSubtableFormat12 format12; 453d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod CmapSubtableFormat13 format13; 454a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod CmapSubtableFormat14 format14; 45541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } u; 45641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 45741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 45841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 45941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 46041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 46141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct EncodingRecord 46241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 463f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod inline int cmp (const EncodingRecord &other) const 46441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 46541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod int ret; 466f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod ret = platformID.cmp (other.platformID); 46741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 468f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod ret = encodingID.cmp (other.encodingID); 46941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 47041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return 0; 47141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 47241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 473de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 474de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 47541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 476b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 477b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod subtable.sanitize (c, base)); 47841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 47941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 48041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT platformID; /* Platform ID. */ 48141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT encodingID; /* Platform-specific encoding ID. */ 4829da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod OffsetTo<CmapSubtable, ULONG> 48341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ 48441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 48541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_STATIC (8); 48641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 48741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 48841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct cmap 48941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 49041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod static const hb_tag_t tableTag = HB_OT_TAG_cmap; 49141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 4923608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod inline const CmapSubtable *find_subtable (unsigned int platform_id, 4933608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod unsigned int encoding_id) const 49441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 49541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod EncodingRecord key; 49641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.platformID.set (platform_id); 49741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.encodingID.set (encoding_id); 49841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 499df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* Note: We can use bsearch, but since it has no performance 500df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod * implications, we use lsearch and as such accept fonts with 501df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod * unsorted subtable list. */ 502df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int result = encodingRecord./*bsearch*/lsearch (key); 503500737e8e16dce5248aff394899bb3761a9c3bbfBehdad Esfahbod if (result == -1 || !encodingRecord[result].subtable) 5043608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return NULL; 5053608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod 5063608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return &(this+encodingRecord[result].subtable); 50741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 50841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 509de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 510de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 51141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 512b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 513b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod likely (version == 0) && 514b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod encodingRecord.sanitize (c, this)); 51541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 51641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 517f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod USHORT version; /* Table version number (0). */ 518df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod SortedArrayOf<EncodingRecord> 519f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod encodingRecord; /* Encoding tables. */ 52041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 52141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (4, encodingRecord); 52241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 52341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 52441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 52541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod} /* namespace OT */ 52641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 52741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 52841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif /* HB_OT_CMAP_TABLE_HH */ 529