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{ 7223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod struct accelerator_t 7341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 7423335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod inline void init (const CmapSubtableFormat4 *subtable) 7523335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod { 7623335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod segCount = subtable->segCountX2 / 2; 7723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod endCount = subtable->values; 7823335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod startCount = endCount + segCount + 1; 7923335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod idDelta = startCount + segCount; 8023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod idRangeOffset = idDelta + segCount; 8123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod glyphIdArray = idRangeOffset + segCount; 8223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2; 8323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod } 84c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 8523335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) 86c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 8723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const accelerator_t *thiz = (const accelerator_t *) obj; 8823335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod 8923335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod /* Custom two-array bsearch. */ 9023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod int min = 0, max = (int) thiz->segCount - 1; 9123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *startCount = thiz->startCount; 9223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *endCount = thiz->endCount; 9323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod unsigned int i; 9423335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod while (min <= max) 9523335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod { 9623335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod int mid = (min + max) / 2; 9723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod if (codepoint < startCount[mid]) 9823335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod max = mid - 1; 9923335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod else if (codepoint > endCount[mid]) 10023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod min = mid + 1; 10123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod else 10223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod { 10323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod i = mid; 10423335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod goto found; 10523335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod } 10623335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod } 10723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod return false; 10823335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod 10923335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod found: 11023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod hb_codepoint_t gid; 11123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod unsigned int rangeOffset = thiz->idRangeOffset[i]; 11223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod if (rangeOffset == 0) 11323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod gid = codepoint + thiz->idDelta[i]; 114c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod else 115c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod { 11623335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod /* Somebody has been smoking... */ 11723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount; 11823335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod if (unlikely (index >= thiz->glyphIdArrayLength)) 11923335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod return false; 12023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod gid = thiz->glyphIdArray[index]; 12123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod if (unlikely (!gid)) 12223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod return false; 12323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod gid += thiz->idDelta[i]; 124c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 12523335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod 12623335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod *glyph = gid & 0xFFFFu; 12723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod return true; 128c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod } 129c8a47452993b9dee6854bfc866aca4a20142696fBehdad Esfahbod 13023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *endCount; 13123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *startCount; 13223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *idDelta; 13323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *idRangeOffset; 13423335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod const USHORT *glyphIdArray; 13523335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod unsigned int segCount; 13623335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod unsigned int glyphIdArrayLength; 13723335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod }; 13823335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod 13923335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 14023335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod { 14123335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod accelerator_t accel; 14223335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod accel.init (this); 14323335deaad9d4d9824ff41343264514d3f9f7e37Behdad Esfahbod return accel.get_glyph_func (&accel, codepoint, glyph); 14441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 14541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 146de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 147257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod { 14841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 149257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (unlikely (!c->check_struct (this))) 150b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 151257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod 152257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (unlikely (!c->check_range (this, length))) 153257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod { 154257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod /* Some broken fonts have too long of a "length" value. 155257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod * If that is the case, just change the value to truncate 156257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod * the subtable at the end of the blob. */ 157257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535, 158257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod (uintptr_t) (c->end - 159257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod (char *) this)); 160257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod if (!c->try_set (&length, new_length)) 161b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (false); 162257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod } 163257d1adfa1b3422c511c55e641840a6e31ec6008Behdad Esfahbod 164b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (16 + 4 * (unsigned int) segCountX2 <= length); 16541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 16641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 16741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod protected: 16841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format number is set to 4. */ 16941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT length; /* This is the length in bytes of the 17041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod * subtable. */ 1717d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT languageZ; /* Ignore. */ 17241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT segCountX2; /* 2 x segCount. */ 1737d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */ 1747d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT entrySelectorZ; /* log2(searchRange/2) */ 1757d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT rangeShiftZ; /* 2 x segCount - searchRange */ 17641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 17741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT values[VAR]; 17841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#if 0 17941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT endCount[segCount]; /* End characterCode for each segment, 1807627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * last=0xFFFFu. */ 18141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT reservedPad; /* Set to 0. */ 18241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT startCount[segCount]; /* Start character code for each segment. */ 18341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod SHORT idDelta[segCount]; /* Delta for all character codes in segment. */ 18441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ 18541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ 18641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif 18741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 18841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 18941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (14, values); 19041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 19141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 192d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbodstruct CmapSubtableLongGroup 1930d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 1940d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod friend struct CmapSubtableFormat12; 195d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod friend struct CmapSubtableFormat13; 1960d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 1970d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod int cmp (hb_codepoint_t codepoint) const 1980d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 1990d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint < startCharCode) return -1; 2000d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (codepoint > endCharCode) return +1; 2010d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return 0; 2020d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2030d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 204de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 205de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2060d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 207b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 2080d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2090d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2100d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod private: 2110d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG startCharCode; /* First character code in this group. */ 2120d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod ULONG endCharCode; /* Last character code in this group. */ 213d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod ULONG glyphID; /* Glyph index; interpretation depends on 214d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod * subtable format. */ 2150d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod public: 2160d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod DEFINE_SIZE_STATIC (12); 2170d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 2180d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 21994759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodtemplate <typename UINT> 22094759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableTrimmed 22191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod{ 22291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 22391bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod { 22491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod /* Rely on our implicit array bound-checking. */ 22591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode]; 22691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod if (!gid) 22791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return false; 22891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod *glyph = gid; 22991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod return true; 23091bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 23191bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 232de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 233de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 23491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod TRACE_SANITIZE (this); 235b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); 23691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod } 23791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 23891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod protected: 23994759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT formatReserved; /* Subtable format and (maybe) padding. */ 2407d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod UINT lengthZ; /* Byte length of this subtable. */ 2417d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod UINT languageZ; /* Ignore. */ 24294759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod UINT startCharCode; /* First character code covered. */ 2439da552dcc5b89b3bbbe5a55fb7c543222382e12aBehdad Esfahbod ArrayOf<GlyphID, UINT> 24491bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod glyphIdArray; /* Array of glyph index values for character 24591bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod * codes in the range. */ 24691bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod public: 24794759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbod DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray); 24891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod}; 24991bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 25094759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {}; 25194759e8219ed08392573bae948a8135e16b8e0d0Behdad Esfahbodstruct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {}; 25291bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod 253ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodtemplate <typename T> 254ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableLongSegmented 2550d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod{ 2560d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const 2570d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod { 258df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int i = groups.bsearch (codepoint); 2590d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod if (i == -1) 2600d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return false; 261ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod *glyph = T::group_get_glyph (groups[i], codepoint); 2620d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod return true; 2630d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2640d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 265de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 266de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 2670d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod TRACE_SANITIZE (this); 268b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && groups.sanitize (c)); 2690d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod } 2700d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 2710d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod protected: 2720d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod USHORT format; /* Subtable format; set to 12. */ 2737d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod USHORT reservedZ; /* Reserved; set to 0. */ 2747d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG lengthZ; /* Byte length of this subtable. */ 2757d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG languageZ; /* Ignore. */ 27641ea59495032e712fa6f801350ee00d5f00b5724Behdad Esfahbod SortedArrayOf<CmapSubtableLongGroup, ULONG> 277d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod groups; /* Groupings. */ 278d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod public: 279d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod DEFINE_SIZE_ARRAY (16, groups); 280d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod}; 281d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 282ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> 283d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod{ 284ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 285ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u) 286ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID + (u - group.startCharCode); } 287ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod}; 288d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod 289ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbodstruct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13> 290ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod{ 291ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group, 292ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod hb_codepoint_t u HB_UNUSED) 293ca7b77431d1e0aaa803722be8be85a368a385f47Behdad Esfahbod { return group.glyphID; } 2940d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod}; 2950d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod 296a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef enum 297a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 298a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_NOT_FOUND = 0, 299a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_FOUND = 1, 300a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GLYPH_VARIANT_USE_DEFAULT = 2 301a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod} glyph_variant_t; 302a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 303a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct UnicodeValueRange 304a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 305a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &codepoint) const 306a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 307a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (codepoint < startUnicodeValue) return -1; 308a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (codepoint > startUnicodeValue + additionalCount) return +1; 309a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return 0; 310a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 311a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 312de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 313de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 314a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 315b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 316a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 317a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 318a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 startUnicodeValue; /* First value in this range. */ 319a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod BYTE additionalCount; /* Number of additional values in this 320a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod * range. */ 321a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 322a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (4); 323a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 324a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 325a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS; 326a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 327a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct UVSMapping 328a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 329a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &codepoint) const 330a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 331a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return unicodeValue.cmp (codepoint); 332a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 333a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 334de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 335de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 336a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 337b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this)); 338a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 339a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 340a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 unicodeValue; /* Base Unicode value of the UVS */ 341a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod GlyphID glyphID; /* Glyph ID of the UVS */ 342a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 343a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (5); 344a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 345a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 346a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodtypedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS; 347a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 348a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct VariationSelectorRecord 349a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 350a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph (hb_codepoint_t codepoint, 351a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph, 352a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const void *base) const 353a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 354a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod int i; 355a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const DefaultUVS &defaults = base+defaultUVS; 356a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod i = defaults.bsearch (codepoint); 357a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (i != -1) 358a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_USE_DEFAULT; 359a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod const NonDefaultUVS &nonDefaults = base+nonDefaultUVS; 360a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod i = nonDefaults.bsearch (codepoint); 361a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod if (i != -1) 362a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 363a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod *glyph = nonDefaults[i].glyphID; 364a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_FOUND; 365a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 366a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return GLYPH_VARIANT_NOT_FOUND; 367a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 368a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 369a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline int cmp (const hb_codepoint_t &variation_selector) const 370a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 371a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return varSelector.cmp (variation_selector); 372a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 373a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 374de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 375de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 376a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 377b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 378b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod defaultUVS.sanitize (c, base) && 379b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod nonDefaultUVS.sanitize (c, base)); 380a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 381a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 382a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod UINT24 varSelector; /* Variation selector. */ 3835e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<DefaultUVS> 384a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod defaultUVS; /* Offset to Default UVS Table. May be 0. */ 3855e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<NonDefaultUVS> 386a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ 387a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 388a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_STATIC (11); 389a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 390a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 391a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbodstruct CmapSubtableFormat14 392a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod{ 393a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, 394a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t variation_selector, 395a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 396a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod { 397a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); 398a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 399a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 400de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 401de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 402a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod TRACE_SANITIZE (this); 403b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 404b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod record.sanitize (c, this)); 405a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 406a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 407a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod protected: 4085473ebfb84c7b6059ac16e04676b363acc51aa00Behdad Esfahbod USHORT format; /* Format number is set to 14. */ 4097d4ada66c96a748ce92f8e8edac149361c3dc829Behdad Esfahbod ULONG lengthZ; /* Byte length of this subtable. */ 410a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod SortedArrayOf<VariationSelectorRecord, ULONG> 411a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod record; /* Variation selector records; sorted 412a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod * in increasing order of `varSelector'. */ 413a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod public: 414a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod DEFINE_SIZE_ARRAY (10, record); 415a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod}; 416a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 41741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct CmapSubtable 41841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 419c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod /* Note: We intentionally do NOT implement subtable formats 2 and 8. */ 420c95587618c88d187be64f923033dae151cf820beBehdad Esfahbod 421a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod inline bool get_glyph (hb_codepoint_t codepoint, 422a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod hb_codepoint_t *glyph) const 42341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 42441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 425b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod case 0: return u.format0 .get_glyph(codepoint, glyph); 4260d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 4: return u.format4 .get_glyph(codepoint, glyph); 42791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 6: return u.format6 .get_glyph(codepoint, glyph); 42891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod case 10: return u.format10.get_glyph(codepoint, glyph); 4290d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod case 12: return u.format12.get_glyph(codepoint, glyph); 430d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod case 13: return u.format13.get_glyph(codepoint, glyph); 431a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod case 14: 432a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod default: return false; 433a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 434a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod } 435a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod 436de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 437de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 43841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 439b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod if (!u.format.sanitize (c)) return_trace (false); 44041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod switch (u.format) { 441b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 0: return_trace (u.format0 .sanitize (c)); 442b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 4: return_trace (u.format4 .sanitize (c)); 443b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 6: return_trace (u.format6 .sanitize (c)); 444b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 10: return_trace (u.format10.sanitize (c)); 445b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 12: return_trace (u.format12.sanitize (c)); 446b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 13: return_trace (u.format13.sanitize (c)); 447b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod case 14: return_trace (u.format14.sanitize (c)); 448b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod default:return_trace (true); 44941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 45041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 45141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 4525473ebfb84c7b6059ac16e04676b363acc51aa00Behdad Esfahbod public: 45341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod union { 45441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT format; /* Format identifier */ 455b7878cd58ea9a67236e1e0228c35b5b03ec4ff9cBehdad Esfahbod CmapSubtableFormat0 format0; 45641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod CmapSubtableFormat4 format4; 45791bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat6 format6; 45891bbfca87527fa14d6ebec86b087f2a989381872Behdad Esfahbod CmapSubtableFormat10 format10; 4590d75793fae95ed9f6b8522ae3af4fcdf397d8c36Behdad Esfahbod CmapSubtableFormat12 format12; 460d294a2cb165c4f20daa5624969067c51eb9aef58Behdad Esfahbod CmapSubtableFormat13 format13; 461a5a4736916b6035e6413d4619f9e7287e683d51bBehdad Esfahbod CmapSubtableFormat14 format14; 46241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } u; 46341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 46441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_UNION (2, format); 46541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 46641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 46741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 46841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct EncodingRecord 46941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 470f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod inline int cmp (const EncodingRecord &other) const 47141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 47241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod int ret; 473f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod ret = platformID.cmp (other.platformID); 47441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 475f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod ret = encodingID.cmp (other.encodingID); 47641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod if (ret) return ret; 47741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod return 0; 47841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 47941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 480de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c, const void *base) const 481de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 48241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 483b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 484b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod subtable.sanitize (c, base)); 48541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 48641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 48741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT platformID; /* Platform ID. */ 48841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod USHORT encodingID; /* Platform-specific encoding ID. */ 4895e156fa5ed33cd1a8ff388833563f15930bb12f9Behdad Esfahbod LOffsetTo<CmapSubtable> 49041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ 49141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 49241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_STATIC (8); 49341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 49441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 49541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbodstruct cmap 49641ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod{ 49741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod static const hb_tag_t tableTag = HB_OT_TAG_cmap; 49841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 4993608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod inline const CmapSubtable *find_subtable (unsigned int platform_id, 5003608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod unsigned int encoding_id) const 50141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod { 50241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod EncodingRecord key; 50341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.platformID.set (platform_id); 50441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod key.encodingID.set (encoding_id); 50541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 506df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod /* Note: We can use bsearch, but since it has no performance 507df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod * implications, we use lsearch and as such accept fonts with 508df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod * unsorted subtable list. */ 509df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod int result = encodingRecord./*bsearch*/lsearch (key); 510500737e8e16dce5248aff394899bb3761a9c3bbfBehdad Esfahbod if (result == -1 || !encodingRecord[result].subtable) 5113608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return NULL; 5123608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod 5133608a6847e7b7eb4206df049158513a085810afdBehdad Esfahbod return &(this+encodingRecord[result].subtable); 51441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 51541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 516de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod inline bool sanitize (hb_sanitize_context_t *c) const 517de2118ed7a998a1df9b28fd1be96b4af89ed82c3Behdad Esfahbod { 51841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod TRACE_SANITIZE (this); 519b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod return_trace (c->check_struct (this) && 520b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod likely (version == 0) && 521b47159011ca518c3b94d782ed16a91ffe9dd2ab2Behdad Esfahbod encodingRecord.sanitize (c, this)); 52241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod } 52341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 524f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod USHORT version; /* Table version number (0). */ 525df554af99db390e42d378983bb3fcf583477a1d7Behdad Esfahbod SortedArrayOf<EncodingRecord> 526f1a72fe7bf863535ec09b559cc0bd878fd0799f2Behdad Esfahbod encodingRecord; /* Encoding tables. */ 52741ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod public: 52841ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod DEFINE_SIZE_ARRAY (4, encodingRecord); 52941ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod}; 53041ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 53141ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 53241ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod} /* namespace OT */ 53341ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 53441ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod 53541ca1fbebf61cf26e1e0e4b11f4a5b52fb7d88a9Behdad Esfahbod#endif /* HB_OT_CMAP_TABLE_HH */ 536