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 54b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 55b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod TRACE_SANITIZE (this); 56b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 57b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod } 58b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 59b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod protected: 60b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod USHORT format; /* Format number is set to 0. */ 617d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT lengthZ; /* Byte length of this subtable. */ 627d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT languageZ; /* Ignore. */ 63b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod BYTE glyphIdArray[256];/* An array that maps character 64b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod * code to glyph index values. */ 65b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod public: 66b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod DEFINE_SIZE_STATIC (6 + 256); 67b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod}; 68b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 6941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtableFormat4 7041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 7141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 7241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 73c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int segCount; 74c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *endCount; 75c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *startCount; 76c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *idDelta; 77c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *idRangeOffset; 78c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *glyphIdArray; 79c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int glyphIdArrayLength; 80c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 81c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod segCount = this->segCountX2 / 2; 82c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod endCount = this->values; 83c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod startCount = endCount + segCount + 1; 84c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod idDelta = startCount + segCount; 85c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod idRangeOffset = idDelta + segCount; 86c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod glyphIdArray = idRangeOffset + segCount; 87c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; 88c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 89df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* Custom two-array bsearch. */ 90c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod int min = 0, max = (int) segCount - 1; 91c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int i; 92c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod while (min <= max) 93c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 94c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod int mid = (min + max) / 2; 95c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (codepoint < startCount[mid]) 96c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod max = mid - 1; 97c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else if (codepoint > endCount[mid]) 98c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod min = mid + 1; 99c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 100c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 101c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod i = mid; 102c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod goto found; 103c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 104c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 10541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return false; 106c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 107c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod found: 108c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod hb_codepoint_t gid; 109c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int rangeOffset = idRangeOffset[i]; 110c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (rangeOffset == 0) 111c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid = codepoint + idDelta[i]; 112c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 113c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 114c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod /* Somebody has been smoking... */ 115c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; 116c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (unlikely (index >= glyphIdArrayLength)) 117c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return false; 118c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid = glyphIdArray[index]; 119c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (unlikely (!gid)) 120c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return false; 121c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid += idDelta[i]; 122c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 123c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 1247627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *glyph = gid & 0xFFFFu; 125c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return true; 12641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 12741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 128257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) 129257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod { 13041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 131257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (unlikely (!c->check_struct (this))) 132257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod return TRACE_RETURN (false); 133257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod 134257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (unlikely (!c->check_range (this, length))) 135257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod { 136257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod /* Some broken fonts have too long of a "length" value. 137257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod * If that is the case, just change the value to truncate 138257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod * the subtable at the end of the blob. */ 139257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535, 140257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod (uintptr_t) (c->end - 141257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod (char *) this)); 142257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (!c->try_set (&length, new_length)) 143257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod return TRACE_RETURN (false); 144257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod } 145257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod 146257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod return TRACE_RETURN (16 + 4 * (unsigned int) segCountX2 <= length); 14741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 14841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 14941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 15041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format number is set to 4. */ 15141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT length; /* This is the length in bytes of the 15241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * subtable. */ 1537d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT languageZ; /* Ignore. */ 15441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT segCountX2; /* 2 x segCount. */ 1557d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */ 1567d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT entrySelectorZ; /* log2(searchRange/2) */ 1577d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT rangeShiftZ; /* 2 x segCount - searchRange */ 15841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 15941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT values[VAR]; 16041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#if 0 16141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT endCount[segCount]; /* End characterCode for each segment, 1627627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * last=0xFFFFu. */ 16341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT reservedPad; /* Set to 0. */ 16441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT startCount[segCount]; /* Start character code for each segment. */ 16541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod SHORT idDelta[segCount]; /* Delta for all character codes in segment. */ 16641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ 16741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ 16841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif 16941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 17041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 17141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (14, values); 17241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 17341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 174d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbodstruct CmapSubtableLongGroup 1750d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 1760d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod friend struct CmapSubtableFormat12; 177d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod friend struct CmapSubtableFormat13; 1780d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1790d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod int cmp (hb_codepoint_t codepoint) const 1800d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 1810d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint < startCharCode) return -1; 1820d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint > endCharCode) return +1; 1830d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return 0; 1840d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 1850d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1860d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1870d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 1880d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 1890d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 1900d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1910d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod private: 1920d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG startCharCode; /* First character code in this group. */ 1930d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG endCharCode; /* Last character code in this group. */ 194d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod ULONG glyphID; /* Glyph index; interpretation depends on 195d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod * subtable format. */ 1960d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod public: 1970d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod DEFINE_SIZE_STATIC (12); 1980d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 1990d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 20094759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodtemplate <typename UINT> 20194759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableTrimmed 20291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod{ 20391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 20491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod { 20591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod /* Rely on our implicit array bound-checking. */ 20691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode]; 20791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod if (!gid) 20891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return false; 20991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod *glyph = gid; 21091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return true; 21191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 21291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 21391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 21491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod TRACE_SANITIZE (this); 21591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); 21691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 21791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 21891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod protected: 21994759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT formatReserved; /* Subtable format and (maybe) padding. */ 2207d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod UINT lengthZ; /* Byte length of this subtable. */ 2217d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod UINT languageZ; /* Ignore. */ 22294759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT startCharCode; /* First character code covered. */ 2239da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod ArrayOf<GlyphID, UINT> 22491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod glyphIdArray; /* Array of glyph index values for character 22591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod * codes in the range. */ 22691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod public: 22794759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray); 22891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod}; 22991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 23094759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {}; 23194759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {}; 23291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 233ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodtemplate <typename T> 234ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableLongSegmented 2350d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 2360d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 2370d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 238df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = groups.bsearch (codepoint); 2390d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (i == -1) 2400d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return false; 241ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod *glyph = T::group_get_glyph (groups[i], codepoint); 2420d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return true; 2430d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2440d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2450d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2460d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 2470d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); 2480d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2490d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2500d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod protected: 2510d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod USHORT format; /* Subtable format; set to 12. */ 2527d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT reservedZ; /* Reserved; set to 0. */ 2537d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG lengthZ; /* Byte length of this subtable. */ 2547d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG languageZ; /* Ignore. */ 25541ea59495032e712fa6f801350ee00d5f00b5724Behdad Esfahbod SortedArrayOf<CmapSubtableLongGroup, ULONG> 256d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod groups; /* Groupings. */ 257d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod public: 258d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod DEFINE_SIZE_ARRAY (16, groups); 259d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod}; 260d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 261ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 262d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod{ 263ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 264ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u) 265ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID + (u - group.startCharCode); } 266ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod}; 267d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 268ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> 269ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod{ 270ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 271ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u HB_UNUSED) 272ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID; } 2730d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 2740d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 275a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef enum 276a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 277a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_NOT_FOUND = 0, 278a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_FOUND = 1, 279a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_USE_DEFAULT = 2 280a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod} glyph_variant_t; 281a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 282a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct UnicodeValueRange 283a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 284a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &codepoint) const 285a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 286a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (codepoint < startUnicodeValue) return -1; 287a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (codepoint > startUnicodeValue + additionalCount) return +1; 288a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return 0; 289a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 290a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 291a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 292a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 293a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 294a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 295a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 296a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 startUnicodeValue; /* First value in this range. */ 297a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod BYTE additionalCount; /* Number of additional values in this 298a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod * range. */ 299a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 300a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (4); 301a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 302a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 303a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS; 304a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 305a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct UVSMapping 306a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 307a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &codepoint) const 308a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 309a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return unicodeValue.cmp (codepoint); 310a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 311a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 312a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 313a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 314a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 315a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 316a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 317a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 unicodeValue; /* Base Unicode value of the UVS */ 318a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GlyphID glyphID; /* Glyph ID of the UVS */ 319a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 320a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (5); 321a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 322a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 323a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS; 324a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 325a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct VariationSelectorRecord 326a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 327a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph (hb_codepoint_t codepoint, 328a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph, 329a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const void *base) const 330a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 331a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod int i; 332a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const DefaultUVS &defaults = base+defaultUVS; 333a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod i = defaults.bsearch (codepoint); 334a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (i != -1) 335a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_USE_DEFAULT; 336a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const NonDefaultUVS &nonDefaults = base+nonDefaultUVS; 337a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod i = nonDefaults.bsearch (codepoint); 338a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (i != -1) 339a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 340a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod *glyph = nonDefaults[i].glyphID; 341a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_FOUND; 342a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 343a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_NOT_FOUND; 344a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 345a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 346a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &variation_selector) const 347a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 348a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return varSelector.cmp (variation_selector); 349a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 350a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 351a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, void *base) { 352a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 353a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 354a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod defaultUVS.sanitize (c, base) && 355a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod nonDefaultUVS.sanitize (c, base)); 356a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 357a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 358a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 varSelector; /* Variation selector. */ 359a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod OffsetTo<DefaultUVS, ULONG> 360a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod defaultUVS; /* Offset to Default UVS Table. May be 0. */ 361a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod OffsetTo<NonDefaultUVS, ULONG> 362a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ 363a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 364a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (11); 365a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 366a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 367a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct CmapSubtableFormat14 368a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 369a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, 370a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t variation_selector, 371a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 372a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 373a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); 374a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 375a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 376a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 377a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 378a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 379a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod record.sanitize (c, this)); 380a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 381a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 382a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod protected: 383a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod USHORT format; /* Format number is set to 0. */ 3847d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG lengthZ; /* Byte length of this subtable. */ 385a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod SortedArrayOf<VariationSelectorRecord, ULONG> 386a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod record; /* Variation selector records; sorted 387a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod * in increasing order of `varSelector'. */ 388a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 389a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_ARRAY (10, record); 390a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 391a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 39241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtable 39341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 394c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ 395c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod 396a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, 397a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 39841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 39941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 400b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod case 0: return u.format0 .get_glyph(codepoint, glyph); 4010d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 4: return u.format4 .get_glyph(codepoint, glyph); 40291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 6: return u.format6 .get_glyph(codepoint, glyph); 40391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 10: return u.format10.get_glyph(codepoint, glyph); 4040d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 12: return u.format12.get_glyph(codepoint, glyph); 405d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod case 13: return u.format13.get_glyph(codepoint, glyph); 406a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod case 14: 407a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod default: return false; 408a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 409a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 410a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 411a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, 412a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t variation_selector, 413a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 414a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 415a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod switch (u.format) { 416a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph); 417a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod default: return GLYPH_VARIANT_NOT_FOUND; 41841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 41941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 42041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 42141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 42241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 42341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 42441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 425b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod case 0: return TRACE_RETURN (u.format0 .sanitize (c)); 4260d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 4: return TRACE_RETURN (u.format4 .sanitize (c)); 42791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 6: return TRACE_RETURN (u.format6 .sanitize (c)); 42891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 10: return TRACE_RETURN (u.format10.sanitize (c)); 4290d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 12: return TRACE_RETURN (u.format12.sanitize (c)); 430d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod case 13: return TRACE_RETURN (u.format13.sanitize (c)); 431af528b6674bccac3efd13f8b33fcdc6aeb178f4cBehdad Esfahbod case 14: return TRACE_RETURN (u.format14.sanitize (c)); 43241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod default:return TRACE_RETURN (true); 43341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 43441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 43541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 43641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 43741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod union { 43841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format identifier */ 439b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod CmapSubtableFormat0 format0; 44041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod CmapSubtableFormat4 format4; 44191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat6 format6; 44291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat10 format10; 4430d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod CmapSubtableFormat12 format12; 444d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod CmapSubtableFormat13 format13; 445a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod CmapSubtableFormat14 format14; 44641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } u; 44741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 44841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 44941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 45041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 45141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 45241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct EncodingRecord 45341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 454f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod inline int cmp (const EncodingRecord &other) const 45541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 45641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod int ret; 457f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod ret = platformID.cmp (other.platformID); 45841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 459f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod ret = encodingID.cmp (other.encodingID); 46041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 46141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return 0; 46241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 46341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 46441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, void *base) { 46541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 46641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 46741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod subtable.sanitize (c, base)); 46841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 46941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 47041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT platformID; /* Platform ID. */ 47141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT encodingID; /* Platform-specific encoding ID. */ 4729da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod OffsetTo<CmapSubtable, ULONG> 47341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ 47441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 47541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_STATIC (8); 47641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 47741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 47841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct cmap 47941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 48041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod static const hb_tag_t tableTag = HB_OT_TAG_cmap; 48141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 4823608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod inline const CmapSubtable *find_subtable (unsigned int platform_id, 4833608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod unsigned int encoding_id) const 48441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 48541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod EncodingRecord key; 48641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.platformID.set (platform_id); 48741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.encodingID.set (encoding_id); 48841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 489df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* Note: We can use bsearch, but since it has no performance 490df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod * implications, we use lsearch and as such accept fonts with 491df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod * unsorted subtable list. */ 492df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int result = encodingRecord./*bsearch*/lsearch (key); 493500737e8e16dce5248aff394899bb3761a9c3bbfBehdad Esfahbod if (result == -1 || !encodingRecord[result].subtable) 4943608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return NULL; 4953608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod 4963608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return &(this+encodingRecord[result].subtable); 49741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 49841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 49941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 50041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 50141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 50241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod likely (version == 0) && 50341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod encodingRecord.sanitize (c, this)); 50441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 50541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 506f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod USHORT version; /* Table version number (0). */ 507df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod SortedArrayOf<EncodingRecord> 508f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod encodingRecord; /* Encoding tables. */ 50941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 51041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (4, encodingRecord); 51141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 51241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 51341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 51441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod} /* namespace OT */ 51541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 51641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 51741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif /* HB_OT_CMAP_TABLE_HH */ 518