hb-ot-cmap-table.hh revision 500737e8e16dce5248aff394899bb3761a9c3bbf
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 friend struct CmapSubtable; 46b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 47b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod private: 48b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 49b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod { 50b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0; 51b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod if (!gid) 52b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod return false; 53b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod *glyph = gid; 54b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod return true; 55b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod } 56b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 57b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 58b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod TRACE_SANITIZE (this); 59b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 60b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod } 61b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 62b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod protected: 63b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod USHORT format; /* Format number is set to 0. */ 64b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod USHORT length; /* Byte length of this subtable. */ 65b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod USHORT language; /* Ignore. */ 66b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod BYTE glyphIdArray[256];/* An array that maps character 67b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod * code to glyph index values. */ 68b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod public: 69b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod DEFINE_SIZE_STATIC (6 + 256); 70b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod}; 71b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod 7241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtableFormat4 7341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 7441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod friend struct CmapSubtable; 7541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 7641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod private: 7741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 7841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 79c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int segCount; 80c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *endCount; 81c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *startCount; 82c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *idDelta; 83c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *idRangeOffset; 84c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod const USHORT *glyphIdArray; 85c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int glyphIdArrayLength; 86c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 87c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod segCount = this->segCountX2 / 2; 88c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod endCount = this->values; 89c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod startCount = endCount + segCount + 1; 90c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod idDelta = startCount + segCount; 91c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod idRangeOffset = idDelta + segCount; 92c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod glyphIdArray = idRangeOffset + segCount; 93c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; 94c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 95c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod /* Custom bsearch. */ 96c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod int min = 0, max = (int) segCount - 1; 97c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int i; 98c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod while (min <= max) 99c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 100c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod int mid = (min + max) / 2; 101c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (codepoint < startCount[mid]) 102c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod max = mid - 1; 103c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else if (codepoint > endCount[mid]) 104c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod min = mid + 1; 105c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 106c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 107c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod i = mid; 108c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod goto found; 109c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 110c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 11141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return false; 112c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 113c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod found: 114c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod hb_codepoint_t gid; 115c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int rangeOffset = idRangeOffset[i]; 116c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (rangeOffset == 0) 117c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid = codepoint + idDelta[i]; 118c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 119c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 120c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod /* Somebody has been smoking... */ 121c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; 122c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (unlikely (index >= glyphIdArrayLength)) 123c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return false; 124c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid = glyphIdArray[index]; 125c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod if (unlikely (!gid)) 126c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return false; 127c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod gid += idDelta[i]; 128c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 129c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 130c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod *glyph = gid & 0xFFFF; 131c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod return true; 13241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 13341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 13441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 13541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 13641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 13741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod c->check_range (this, length) && 13841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 16 + 4 * (unsigned int) segCountX2 < length); 13941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 14041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 14141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 14241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format number is set to 4. */ 14341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT length; /* This is the length in bytes of the 14441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * subtable. */ 14541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT language; /* Ignore. */ 14641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT segCountX2; /* 2 x segCount. */ 14741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT searchRange; /* 2 * (2**floor(log2(segCount))) */ 14841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT entrySelector; /* log2(searchRange/2) */ 14941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT rangeShift; /* 2 x segCount - searchRange */ 15041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 15141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT values[VAR]; 15241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#if 0 15341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT endCount[segCount]; /* End characterCode for each segment, 15441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * last=0xFFFF. */ 15541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT reservedPad; /* Set to 0. */ 15641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT startCount[segCount]; /* Start character code for each segment. */ 15741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod SHORT idDelta[segCount]; /* Delta for all character codes in segment. */ 15841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ 15941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ 16041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif 16141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 16241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 16341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (14, values); 16441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 16541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 166d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbodstruct CmapSubtableLongGroup 1670d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 1680d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod friend struct CmapSubtableFormat12; 169d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod friend struct CmapSubtableFormat13; 1700d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1710d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod int cmp (hb_codepoint_t codepoint) const 1720d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 1730d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint < startCharCode) return -1; 1740d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint > endCharCode) return +1; 1750d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return 0; 1760d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 1770d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1780d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 1790d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 1800d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return TRACE_RETURN (c->check_struct (this)); 1810d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 1820d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1830d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod private: 1840d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG startCharCode; /* First character code in this group. */ 1850d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG endCharCode; /* Last character code in this group. */ 186d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod ULONG glyphID; /* Glyph index; interpretation depends on 187d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod * subtable format. */ 1880d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod public: 1890d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod DEFINE_SIZE_STATIC (12); 1900d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 1910d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 19294759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodtemplate <typename UINT> 19394759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableTrimmed 19491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod{ 19591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod friend struct CmapSubtable; 19691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 19791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod private: 19891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 19991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod { 20091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod /* Rely on our implicit array bound-checking. */ 20191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode]; 20291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod if (!gid) 20391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return false; 20491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod *glyph = gid; 20591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return true; 20691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 20791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 20891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 20991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod TRACE_SANITIZE (this); 21091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); 21191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 21291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 21391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod protected: 21494759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT formatReserved; /* Subtable format and (maybe) padding. */ 21594759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT length; /* Byte length of this subtable. */ 21694759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT language; /* Ignore. */ 21794759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT startCharCode; /* First character code covered. */ 21894759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod GenericArrayOf<UINT, GlyphID> 21991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod glyphIdArray; /* Array of glyph index values for character 22091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod * codes in the range. */ 22191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod public: 22294759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray); 22391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod}; 22491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 22594759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {}; 22694759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {}; 22791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 228ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodtemplate <typename T> 229ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableLongSegmented 2300d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 2310d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod friend struct CmapSubtable; 2320d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2330d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod private: 2340d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 2350d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 2360d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod int i = groups.search (codepoint); 2370d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (i == -1) 2380d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return false; 239ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod *glyph = T::group_get_glyph (groups[i], codepoint); 2400d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return true; 2410d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2420d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2430d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 2440d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 2450d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); 2460d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2470d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2480d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod protected: 2490d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod USHORT format; /* Subtable format; set to 12. */ 2500d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod USHORT reserved; /* Reserved; set to 0. */ 25191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod ULONG length; /* Byte length of this subtable. */ 2520d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG language; /* Ignore. */ 253d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod LongArrayOf<CmapSubtableLongGroup> 254d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod groups; /* Groupings. */ 255d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod public: 256d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod DEFINE_SIZE_ARRAY (16, groups); 257d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod}; 258d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 259ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 260d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod{ 261ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 262ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u) 263ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID + (u - group.startCharCode); } 264ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod}; 265d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 266ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> 267ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod{ 268ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 269ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u HB_UNUSED) 270ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID; } 2710d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 2720d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 27341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtable 27441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 275c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ 276c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod 27741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 27841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 27941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 280b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod case 0: return u.format0 .get_glyph(codepoint, glyph); 2810d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 4: return u.format4 .get_glyph(codepoint, glyph); 28291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 6: return u.format6 .get_glyph(codepoint, glyph); 28391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 10: return u.format10.get_glyph(codepoint, glyph); 2840d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 12: return u.format12.get_glyph(codepoint, glyph); 285d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod case 13: return u.format13.get_glyph(codepoint, glyph); 28641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod default:return false; 28741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 28841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 28941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 29041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 29141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 29241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (!u.format.sanitize (c)) return TRACE_RETURN (false); 29341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 294b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod case 0: return TRACE_RETURN (u.format0 .sanitize (c)); 2950d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 4: return TRACE_RETURN (u.format4 .sanitize (c)); 29691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 6: return TRACE_RETURN (u.format6 .sanitize (c)); 29791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 10: return TRACE_RETURN (u.format10.sanitize (c)); 2980d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 12: return TRACE_RETURN (u.format12.sanitize (c)); 299d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod case 13: return TRACE_RETURN (u.format13.sanitize (c)); 30041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod default:return TRACE_RETURN (true); 30141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 30241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 30341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 30441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 30541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod union { 30641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format identifier */ 307b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod CmapSubtableFormat0 format0; 30841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod CmapSubtableFormat4 format4; 30991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat6 format6; 31091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat10 format10; 3110d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod CmapSubtableFormat12 format12; 312d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod CmapSubtableFormat13 format13; 31341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } u; 31441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 31541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 31641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 31741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 31841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 31941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct EncodingRecord 32041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 32141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod int cmp (const EncodingRecord &other) const 32241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 32341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod int ret; 32441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod ret = other.platformID.cmp (platformID); 32541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 32641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod ret = other.encodingID.cmp (encodingID); 32741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 32841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return 0; 32941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 33041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 33141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, void *base) { 33241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 33341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 33441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod subtable.sanitize (c, base)); 33541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 33641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 33741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT platformID; /* Platform ID. */ 33841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT encodingID; /* Platform-specific encoding ID. */ 33941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod LongOffsetTo<CmapSubtable> 34041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ 34141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 34241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_STATIC (8); 34341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 34441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 34541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct cmap 34641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 34741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod static const hb_tag_t tableTag = HB_OT_TAG_cmap; 34841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3493608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod inline const CmapSubtable *find_subtable (unsigned int platform_id, 3503608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod unsigned int encoding_id) const 35141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 35241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod EncodingRecord key; 35341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.platformID.set (platform_id); 35441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.encodingID.set (encoding_id); 35541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 3563608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod int result = encodingRecord.search (key); 357500737e8e16dce5248aff394899bb3761a9c3bbfBehdad Esfahbod if (result == -1 || !encodingRecord[result].subtable) 3583608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return NULL; 3593608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod 3603608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return &(this+encodingRecord[result].subtable); 36141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 36241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 36341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) { 36441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 36541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return TRACE_RETURN (c->check_struct (this) && 36641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod likely (version == 0) && 36741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod encodingRecord.sanitize (c, this)); 36841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 36941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 37041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT version; /* Table version number (0). */ 37141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod ArrayOf<EncodingRecord> encodingRecord; /* Encoding tables. */ 37241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 37341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (4, encodingRecord); 37441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 37541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 37641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 37741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod} /* namespace OT */ 37841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 37941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 38041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif /* HB_OT_CMAP_TABLE_HH */ 381