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