1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ttcmap.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* TrueType character mapping table (cmap) support (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/* Copyright 2002-2015 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */ 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_VALIDATE_H 25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_STREAM_H 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttload.h" 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttcmap.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "sfntpic.h" 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_ttcmap 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_PEEK_SHORT FT_PEEK_SHORT 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_PEEK_USHORT FT_PEEK_USHORT 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_PEEK_UINT24 FT_PEEK_UOFF3 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_PEEK_LONG FT_PEEK_LONG 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_PEEK_ULONG FT_PEEK_ULONG 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_NEXT_SHORT FT_NEXT_SHORT 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_NEXT_USHORT FT_NEXT_USHORT 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_NEXT_UINT24 FT_NEXT_UOFF3 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_NEXT_LONG FT_NEXT_LONG 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TT_NEXT_ULONG FT_NEXT_ULONG 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* Too large glyph index return values are caught in `FT_Get_Char_Index' */ 55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */ 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* again in this case). To mark character code return values as invalid */ 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* it is sufficient to set the corresponding glyph index return value to */ 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* zero. */ 59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap_init( TT_CMap cmap, 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table ) 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->data = table; 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 0 *****/ 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 0 */ 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 2 USHORT table length in bytes */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 4 USHORT Mac language code */ 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyph_ids 6 BYTE[256] array of glyph indices */ 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 262 */ 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_0 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap0_validate( FT_Byte* table, 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* p; 99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt length; 100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( table + 2 + 2 > valid->limit ) 103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_INVALID_TOO_SHORT; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov p = table + 2; /* skip format */ 106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length = TT_NEXT_USHORT( p ); 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + length > valid->limit || length < 262 ) 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check glyph indices whenever necessary */ 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n, idx; 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 6; 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < 256; n++ ) 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = *p++; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap0_char_index( TT_CMap cmap, 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return char_code < 256 ? table[6 + char_code] : 0; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap0_char_next( TT_CMap cmap, 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 charcode = *pchar_code; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 result = 0; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table += 6; /* go to glyph IDs */ 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( ++charcode < 256 ) 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = table[charcode]; 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = charcode; 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pchar_code = result; 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap0_get_info( TT_CMap cmap, 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 4; 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 0; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap0_class_rec, 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMapRec ), 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap_init, 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap0_char_index, 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap0_char_next, 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0, 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap0_validate, 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_0 */ 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 2 *****/ 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** This is used for certain CJK encodings that encode text in a *****/ 209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** mixed 8/16 bits encoding along the following lines. *****/ 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** * Certain byte values correspond to an 8-bit character code *****/ 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** (typically in the range 0..127 for ASCII compatibility). *****/ 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** * Certain byte values signal the first byte of a 2-byte *****/ 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** character code (but these values are also valid as the *****/ 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** second byte of a 2-byte character). *****/ 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** The following charmap lookup and iteration functions all *****/ 219ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** assume that the value `charcode' fulfills the following. *****/ 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 221ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** - For one byte characters, `charcode' is simply the *****/ 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** character code. *****/ 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 224ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** - For two byte characters, `charcode' is the 2-byte *****/ 225ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** character code in big endian format. More precisely: *****/ 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** (charcode >> 8) is the first byte value *****/ 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** (charcode & 0xFF) is the second byte value *****/ 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 230ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** Note that not all values of `charcode' are valid according *****/ 231ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** to these rules, and the function moderately checks the *****/ 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** arguments. *****/ 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 2 */ 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 2 USHORT table length in bytes */ 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 4 USHORT Mac language code */ 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* keys 6 USHORT[256] sub-header keys */ 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* subs 518 SUBHEAD[NSUBS] sub-headers array */ 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The `keys' table is used to map charcode high-bytes to sub-headers. */ 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The value of `NSUBS' is the number of sub-headers defined in the */ 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table and is computed by finding the maximum of the `keys' table. */ 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* table, i.e., it is the corresponding sub-header index multiplied */ 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* by 8. */ 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 259ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* Each sub-header has the following format. */ 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first 0 USHORT first valid low-byte */ 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count 2 USHORT number of valid low-bytes */ 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* delta 4 SHORT see below */ 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* offset 6 USHORT see below */ 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A sub-header defines, for each high-byte, the range of valid */ 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* low-bytes within the charmap. Note that the range defined by `first' */ 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and `count' must be completely included in the interval [0..255] */ 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* according to the specification. */ 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If a character code is contained within a given sub-header, then */ 274ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* mapping it to a glyph index is done as follows. */ 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* * The value of `offset' is read. This is a _byte_ distance from the */ 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* location of the `offset' field itself into a slice of the */ 278ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no glyph for the charcode. Otherwise, the value of `delta' is */ 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* added to it (modulo 65536) to form a new glyph index. */ 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* It is up to the validation routine to check that all offsets fall */ 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* within the glyph IDs table (and not within the `subs' table itself or */ 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* outside of the CMap). */ 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_2 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap2_validate( FT_Byte* table, 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* p; 296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt length; 297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n, max_subs; 299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* keys; /* keys table */ 300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* subs; /* sub-headers */ 301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* glyph_ids; /* glyph ID array */ 302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( table + 2 + 2 > valid->limit ) 305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_INVALID_TOO_SHORT; 306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov p = table + 2; /* skip format */ 308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length = TT_NEXT_USHORT( p ); 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + length > valid->limit || length < 6 + 512 ) 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov keys = table + 6; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parse keys to compute sub-headers count */ 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = keys; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_subs = 0; 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < 256; n++ ) 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx = TT_NEXT_USHORT( p ); 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* value must be multiple of 8 */ 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx >>= 3; 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx > max_subs ) 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_subs = idx; 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( p == table + 518 ); 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov subs = p; 336ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann glyph_ids = subs + ( max_subs + 1 ) * 8; 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_ids > valid->limit ) 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parse sub-headers */ 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n <= max_subs; n++ ) 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt first_code, code_count, offset; 344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Int delta; 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first_code = TT_NEXT_USHORT( p ); 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov code_count = TT_NEXT_USHORT( p ); 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_NEXT_SHORT( p ); 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_NEXT_USHORT( p ); 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* many Dynalab fonts have empty sub-headers */ 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( code_count == 0 ) 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check range within 0..255 */ 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_PARANOID ) 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( first_code >= 256 || first_code + code_count > 256 ) 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check offset */ 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset != 0 ) 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* ids; 367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ids = p - 2 + offset; 370ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( ids < glyph_ids || ids + code_count * 2 > table + length ) 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_OFFSET; 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check glyph IDs */ 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit = p + code_count * 2; 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx; 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; p < limit; ) 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = TT_NEXT_USHORT( p ); 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx != 0 ) 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 385ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return sub header corresponding to a given character code */ 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NULL on invalid charcode */ 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Byte* 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap2_get_subheader( FT_Byte* table, 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* result = NULL; 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < 0x10000UL ) 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 6; /* keys table */ 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* subs = table + 518; /* subheaders table */ 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* sub; 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_hi == 0 ) 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* an 8-bit character code -- we use subHeader 0 in this case */ 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to test whether the character code is in the charmap */ 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub = subs; /* jump to first sub-header */ 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the sub-header for this byte is 0, which */ 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* indicates that it is really a valid one-byte value */ 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Otherwise, return 0 */ 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += char_lo * 2; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( TT_PEEK_USHORT( p ) != 0 ) 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a 16-bit character code */ 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* jump to key entry */ 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += char_hi * 2; 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* jump to sub-header */ 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the high byte isn't a valid one-byte value */ 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( sub == subs ) 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = sub; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 446ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap2_char_index( TT_CMap cmap, 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* subheader; 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov subheader = tt_cmap2_get_subheader( table, char_code ); 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( subheader ) 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = subheader; 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx = (FT_UInt)(char_code & 0xFF); 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start, count; 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int delta; 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt offset; 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_USHORT( p ); 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = TT_NEXT_USHORT( p ); 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_NEXT_SHORT ( p ); 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_PEEK_USHORT( p ); 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx -= start; 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx < count && offset != 0 ) 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += offset + 2 * idx; 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = TT_PEEK_USHORT( p ); 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx != 0 ) 483ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 486ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap2_char_next( TT_CMap cmap, 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pcharcode ) 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 result = 0; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 charcode = *pcharcode + 1; 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* subheader; 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( charcode < 0x10000UL ) 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov subheader = tt_cmap2_get_subheader( table, charcode ); 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( subheader ) 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = subheader; 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start = TT_NEXT_USHORT( p ); 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count = TT_NEXT_USHORT( p ); 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int delta = TT_NEXT_SHORT ( p ); 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt offset = TT_PEEK_USHORT( p ); 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt pos, idx; 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset == 0 ) 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Next_SubHeader; 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_lo < start ) 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_lo = start; 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pos = 0; 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pos = (FT_UInt)( char_lo - start ); 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += offset + pos * 2; 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; pos < count; pos++, charcode++ ) 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = TT_NEXT_USHORT( p ); 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx != 0 ) 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 536ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = charcode; 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* jump to next sub-header, i.e. higher byte value */ 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Next_SubHeader: 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pcharcode = result; 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap2_get_info( TT_CMap cmap, 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 4; 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 2; 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap2_class_rec, 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMapRec ), 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap_init, 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap2_char_index, 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap2_char_next, 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2, 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap2_validate, 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_2 */ 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 4 *****/ 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 4 */ 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 2 USHORT table length */ 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in bytes */ 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 4 USHORT Mac language code */ 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* segCountX2 6 USHORT 2*NUM_SEGS */ 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* entrySelector 10 USHORT LOG_SEGS */ 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rangeShift 12 USHORT segCountX2 - */ 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* searchRange */ 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* endCount 14 USHORT[NUM_SEGS] end charcode for */ 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* each segment; last */ 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is 0xFFFF */ 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pad 14+NUM_SEGS*2 USHORT padding */ 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* each segment */ 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* segment */ 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* each segment; can be */ 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* zero */ 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ranges */ 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Character codes are modelled by a series of ordered (increasing) */ 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* intervals called segments. Each segment has start and end codes, */ 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* provided by the `startCount' and `endCount' arrays. Segments must */ 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* not overlap, and the last segment should always contain the value */ 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 0xFFFF for `endCount'. */ 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ignored (they are traces of over-engineering in the TrueType */ 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* specification). */ 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Each segment also has a signed `delta', as well as an optional offset */ 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* within the `glyphIds' table. */ 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If a segment's idOffset is 0, the glyph index corresponding to any */ 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* charcode within the segment is obtained by adding the value of */ 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `idDelta' directly to the charcode, modulo 65536. */ 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the segment, and the value of `idDelta' is added to it. */ 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finally, note that a lot of fonts contain an invalid last segment, */ 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* OpenOffice.org). We need special code to deal with them correctly. */ 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_4 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TT_CMap4Rec_ 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapRec cmap; 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 cur_charcode; /* current charcode */ 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cur_gindex; /* current glyph index */ 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_ranges; 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cur_range; 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cur_start; 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cur_end; 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int cur_delta; 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* cur_values; 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TT_CMap4Rec, *TT_CMap4; 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_init( TT_CMap4 cmap, 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table ) 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cmap.data = table; 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 6; 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_gindex = 0; 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Int 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_set_range( TT_CMap4 cmap, 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt range_index ) 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->cmap.data; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_ranges = cmap->num_ranges; 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( range_index < num_ranges ) 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt offset; 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 14 + range_index * 2; 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_end = FT_PEEK_USHORT( p ); 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 + num_ranges * 2; 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_start = FT_PEEK_USHORT( p ); 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_ranges * 2; 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_delta = FT_PEEK_SHORT( p ); 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_ranges * 2; 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = FT_PEEK_USHORT( p ); 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* some fonts have an incorrect last segment; */ 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we have to catch it */ 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( range_index >= num_ranges - 1 && 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_start == 0xFFFFU && 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_end == 0xFFFFU ) 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit = face->cmap_table + face->cmap_size; 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset && p + offset + 2 > limit ) 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_delta = 1; 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = 0; 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset != 0xFFFFU ) 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_values = offset ? p + offset : NULL; 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_range = range_index; 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we skip empty segments */ 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov range_index++; 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search the index of the charcode next to cmap->cur_charcode; */ 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* caller should call tt_cmap4_set_range with proper range */ 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* before calling this function */ 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_next( TT_CMap4 cmap ) 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt charcode; 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->cur_charcode >= 0xFFFFUL ) 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode = (FT_UInt)cmap->cur_charcode + 1; 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode < cmap->cur_start ) 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode = cmap->cur_start; 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ;; ) 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* values = cmap->cur_values; 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt end = cmap->cur_end; 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int delta = cmap->cur_delta; 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode <= end ) 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( values ) 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = FT_NEXT_USHORT( p ); 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 798ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_charcode = charcode; 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_gindex = gindex; 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( ++charcode <= end ); 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 812ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_charcode = charcode; 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_gindex = gindex; 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( ++charcode <= end ); 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we need to find another range */ 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode < cmap->cur_start ) 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode = cmap->cur_start; 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_gindex = 0; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_validate( FT_Byte* table, 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 843e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* p; 844e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt length; 845e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_segs; 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 851e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( table + 2 + 2 > valid->limit ) 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 854e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov p = table + 2; /* skip format */ 855e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length = TT_NEXT_USHORT( p ); 856e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in certain fonts, the `length' field is invalid and goes */ 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* out of bound. We try to correct this here... */ 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + length > valid->limit ) 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length = (FT_UInt)( valid->limit - table ); 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 867e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( length < 16 ) 868e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_INVALID_TOO_SHORT; 869e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 6; 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_PARANOID ) 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that we have an even value here */ 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_segs & 1 ) 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_segs /= 2; 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length < 16 + num_segs * 2 * 4 ) 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check the search parameters - even though we never use them */ 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_PARANOID ) 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check the values of `searchRange', `entrySelector', `rangeShift' */ 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt search_range = TT_NEXT_USHORT( p ); 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt entry_selector = TT_NEXT_USHORT( p ); 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt range_shift = TT_NEXT_USHORT( p ); 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( search_range | range_shift ) & 1 ) /* must be even values */ 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov search_range /= 2; 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov range_shift /= 2; 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `search range' is the greatest power of 2 that is <= num_segs */ 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( search_range > num_segs || 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov search_range * 2 < num_segs || 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov search_range + range_shift != num_segs || 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov search_range != ( 1U << entry_selector ) ) 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ends = table + 14; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov starts = table + 16 + num_segs * 2; 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov deltas = starts + num_segs * 2; 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsets = deltas + num_segs * 2; 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_ids = offsets + num_segs * 2; 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check last segment; its end count value must be 0xFFFF */ 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_PARANOID ) 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = ends + ( num_segs - 1 ) * 2; 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start, end, offset, n; 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt last_start = 0, last_end = 0; 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int delta; 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_start = starts; 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_end = ends; 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_delta = deltas; 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p_offset = offsets; 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < num_segs; n++ ) 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = p_offset; 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_USHORT( p_start ); 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_USHORT( p_end ); 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_NEXT_SHORT( p_delta ); 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_NEXT_USHORT( p_offset ); 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start > end ) 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this test should be performed at default validation level; */ 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* unfortunately, some popular Asian fonts have overlapping */ 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ranges in their charmaps */ 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start <= last_end && n > 0 ) 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allow overlapping segments, provided their start points */ 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and end points, respectively, are in ascending order */ 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( last_start > start || last_end > end ) 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error |= TT_CMAP_FLAG_UNSORTED; 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error |= TT_CMAP_FLAG_OVERLAPPING; 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset && offset != 0xFFFFU ) 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += offset; /* start of glyph ID array */ 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that we point within the glyph IDs table only */ 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p < glyph_ids || 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p + ( end - start + 1 ) * 2 > table + length ) 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Some fonts handle the last segment incorrectly. In */ 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* theory, 0xFFFF might point to an ordinary glyph -- */ 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a cmap 4 is versatile and could be used for any */ 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* encoding, not only Unicode. However, reality shows */ 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* that far too many fonts are sloppy and incorrectly */ 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set all fields but `start' and `end' for the last */ 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* segment if it contains only a single character. */ 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We thus omit the test here, delaying it to the */ 985ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* routines that actually access the cmap. */ 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( n != num_segs - 1 || 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( start == 0xFFFFU && end == 0xFFFFU ) ) 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p < glyph_ids || 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p + ( end - start + 1 ) * 2 > valid->limit ) 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check glyph indices within the segment range */ 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i, idx; 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = start; i < end; i++ ) 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = FT_NEXT_USHORT( p ); 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx != 0 ) 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1005ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( offset == 0xFFFFU ) 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* some fonts (erroneously?) use a range offset of 0xFFFF */ 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to mean missing glyph in cmap table */ 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_PARANOID || 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n != num_segs - 1 || 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( start == 0xFFFFU && end == 0xFFFFU ) ) 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov last_start = start; 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov last_end = end; 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_char_map_linear( TT_CMap cmap, 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* pcharcode, 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool next ) 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1038ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TT_Face face = (TT_Face)cmap->cmap.charmap.face; 1039ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Byte* limit = face->cmap_table + face->cmap_size; 1040ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1041ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_segs2, start, end, offset; 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int delta; 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i, num_segs; 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 charcode = *pcharcode; 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 1048ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Byte* q; 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 6; 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_segs = num_segs2 >> 1; 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !num_segs ) 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode++; 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1062ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( charcode > 0xFFFFU ) 1063ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 1064ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* linear search */ 1066ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann p = cmap->data + 14; /* ends table */ 1067ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann q = cmap->data + 16 + num_segs2; /* starts table */ 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1069ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann for ( i = 0; i < num_segs; i++ ) 1070ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 1071ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann end = TT_NEXT_USHORT( p ); 1072ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann start = TT_NEXT_USHORT( q ); 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1074ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( charcode < start ) 1075ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 1076ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( next ) 1077ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann charcode = start; 1078ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann else 1079ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 1080ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1082ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Again: 1083ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( charcode <= end ) 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1085ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Byte* r; 1086ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1088ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann r = q - 2 + num_segs2; 1089ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann delta = TT_PEEK_SHORT( r ); 1090ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann r += num_segs2; 1091ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann offset = TT_PEEK_USHORT( r ); 1092ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1093ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* some fonts have an incorrect last segment; */ 1094ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* we have to catch it */ 1095ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( i >= num_segs - 1 && 1096ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann start == 0xFFFFU && end == 0xFFFFU ) 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1098ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( offset && r + offset + 2 > limit ) 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann delta = 1; 1101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann offset = 0; 1102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( offset == 0xFFFFU ) 1106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( offset ) 1109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 1110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann r += offset + ( charcode - start ) * 2; 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* if r > limit, the whole segment is invalid */ 1113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( next && r > limit ) 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = TT_PEEK_USHORT( r ); 1117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex ) 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; 1120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex >= (FT_UInt)face->root.num_glyphs ) 1121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = 0; 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann else 1125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 1126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) 1129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 1130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* we have an invalid glyph index; if there is an overflow, */ 1131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* we can adjust `charcode', otherwise the whole segment is */ 1132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* invalid */ 1133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = 0; 1134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( (FT_Int)charcode + delta < 0 && 1136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Int)end + delta >= 0 ) 1137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann charcode = (FT_UInt)( -delta ); 1138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann else if ( (FT_Int)charcode + delta < 0x10000L && 1140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Int)end + delta >= 0x10000L ) 1141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann charcode = (FT_UInt)( 0x10000L - delta ); 1142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann else 1144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 1145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1148ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( next && !gindex ) 1149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 1150ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( charcode >= 0xFFFFU ) 1151ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 1152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1153ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann charcode++; 1154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann goto Again; 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( next ) 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pcharcode = charcode; 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_char_map_binary( TT_CMap cmap, 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* pcharcode, 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool next ) 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt num_segs2, start, end, offset; 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int delta; 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt max, min, mid, num_segs; 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt charcode = (FT_UInt)*pcharcode; 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 6; 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !num_segs2 ) 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_segs = num_segs2 >> 1; 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* make compiler happy */ 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = num_segs; 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = 0xFFFFU; 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode++; 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = 0; 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = num_segs; 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary search */ 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( min < max ) 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = ( min + max ) >> 1; 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 14 + mid * 2; 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_PEEK_USHORT( p ); 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 + num_segs2; 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_PEEK_USHORT( p ); 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode < start ) 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( charcode > end ) 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = mid + 1; 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_PEEK_SHORT( p ); 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_PEEK_USHORT( p ); 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* some fonts have an incorrect last segment; */ 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we have to catch it */ 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid >= num_segs - 1 && 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start == 0xFFFFU && end == 0xFFFFU ) 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_Face face = (TT_Face)cmap->cmap.charmap.face; 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit = face->cmap_table + face->cmap_size; 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset && p + offset + 2 > limit ) 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = 1; 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = 0; 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search the first segment containing `charcode' */ 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* call the current segment `max' */ 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset == 0xFFFFU ) 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = max + 1; 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search in segments before the current segment */ 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = max ; i > 0; i-- ) 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt prev_end; 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* old_p; 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_p = p; 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 14 + ( i - 1 ) * 2; 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prev_end = TT_PEEK_USHORT( p ); 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode > prev_end ) 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = old_p; 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = prev_end; 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 + num_segs2; 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_PEEK_USHORT( p ); 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_PEEK_SHORT( p ); 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_PEEK_USHORT( p ); 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset != 0xFFFFU ) 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = i - 1; 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no luck */ 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid == max + 1 ) 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( i != max ) 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 14 + max * 2; 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_PEEK_USHORT( p ); 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 + num_segs2; 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_PEEK_USHORT( p ); 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_PEEK_SHORT( p ); 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_PEEK_USHORT( p ); 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = max; 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search in segments after the current segment */ 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = max + 1; i < num_segs; i++ ) 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt next_end, next_start; 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 14 + i * 2; 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next_end = TT_PEEK_USHORT( p ); 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 + num_segs2; 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next_start = TT_PEEK_USHORT( p ); 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode < next_start ) 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = next_end; 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = next_start; 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_PEEK_SHORT( p ); 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_PEEK_USHORT( p ); 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset != 0xFFFFU ) 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = i; 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i--; 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* still no luck */ 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid == max ) 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = i; 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* end, start, delta, and offset are for the i'th segment */ 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid != i ) 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 14 + mid * 2; 1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_PEEK_USHORT( p ); 1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 + num_segs2; 1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_PEEK_USHORT( p ); 1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = TT_PEEK_SHORT( p ); 1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += num_segs2; 1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_PEEK_USHORT( p ); 1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset == 0xFFFFU ) 1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset ) 1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += offset + ( charcode - start ) * 2; 1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = TT_PEEK_USHORT( p ); 1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 1352ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; 1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1355ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; 1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap4 cmap4 = (TT_CMap4)cmap; 1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if `charcode' is not in any segment, then `mid' is */ 1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the segment nearest to `charcode' */ 1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( charcode > end ) 1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid++; 1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid == num_segs ) 1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap4_set_range( cmap4, mid ) ) 1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex ) 1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pcharcode = charcode; 1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap4->cur_charcode = charcode; 1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex ) 1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap4->cur_gindex = gindex; 1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap4->cur_charcode = charcode; 1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_next( cmap4 ); 1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = cmap4->cur_gindex; 1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex ) 1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pcharcode = cmap4->cur_charcode; 1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_char_index( TT_CMap cmap, 1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code >= 0x10000UL ) 1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) 1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); 1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); 1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_char_next( TT_CMap cmap, 1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex; 1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *pchar_code >= 0xFFFFU ) 1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) 1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); 1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap4 cmap4 = (TT_CMap4)cmap; 1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no need to search */ 1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *pchar_code == cmap4->cur_charcode ) 1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_next( cmap4 ); 1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = cmap4->cur_gindex; 1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex ) 1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pchar_code = cmap4->cur_charcode; 1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); 1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_get_info( TT_CMap cmap, 1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 4; 1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 4; 1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap4_class_rec, 1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMap4Rec ), 1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap4_init, 1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap4_char_index, 1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap4_char_next, 1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4, 1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap4_validate, 1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) 1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_4 */ 1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 6 *****/ 1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1500ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* format 0 USHORT must be 6 */ 1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 2 USHORT table length in bytes */ 1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 4 USHORT Mac language code */ 1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first 6 USHORT first segment code */ 1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count 8 USHORT segment size in chars */ 1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyphIds 10 USHORT[count] glyph IDs */ 1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A very simplified segment mapping. */ 1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_6 1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap6_validate( FT_Byte* table, 1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt length, count; 1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + 10 > valid->limit ) 1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 2; 1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length = TT_NEXT_USHORT( p ); 1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 8; /* skip language and start index */ 1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = TT_NEXT_USHORT( p ); 1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1530e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( table + length > valid->limit || length < 10 + count * 2 ) 1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check glyph indices */ 1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex; 1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count-- ) 1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = TT_NEXT_USHORT( p ); 1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) 1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap6_char_index( TT_CMap cmap, 1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 6; 1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start = TT_NEXT_USHORT( p ); 1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count = TT_NEXT_USHORT( p ); 1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx = (FT_UInt)( char_code - start ); 1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx < count ) 1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 * idx; 1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = TT_PEEK_USHORT( p ); 1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1568ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap6_char_next( TT_CMap cmap, 1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 result = 0; 1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code = *pchar_code + 1; 1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 6; 1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt start = TT_NEXT_USHORT( p ); 1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt count = TT_NEXT_USHORT( p ); 1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt idx; 1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code >= 0x10000UL ) 1589ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = start; 1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov idx = (FT_UInt)( char_code - start ); 1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 * idx; 1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; idx < count; idx++ ) 1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = TT_NEXT_USHORT( p ); 1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = char_code; 1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1605ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1606ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code >= 0xFFFFU ) 1607ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 1608ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code++; 1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pchar_code = result; 1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap6_get_info( TT_CMap cmap, 1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 4; 1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 6; 1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap6_class_rec, 1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMapRec ), 1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap_init, 1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap6_char_index, 1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap6_char_next, 1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 6, 1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap6_validate, 1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) 1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_6 */ 1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 8 *****/ 1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** It is hard to completely understand what the OpenType spec *****/ 1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** says about this format, but here is my conclusion. *****/ 1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** The purpose of this format is to easily map UTF-16 text to *****/ 1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** glyph indices. Basically, the `char_code' must be in one of *****/ 1663ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** the following formats. *****/ 1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ 1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** Area (i.e. U+D800-U+DFFF). *****/ 1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ 1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** `char_code = (char_hi << 16) | char_lo', then both *****/ 1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ 1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** Area. *****/ 1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** The `is32' table embedded in the charmap indicates whether a *****/ 1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** given 16-bit value is in the surrogates area or not. *****/ 1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1676ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /***** So, for any given `char_code', we can assert the following. *****/ 1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ 1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** If `char_hi != 0' then we must have both *****/ 1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ 1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 8 */ 1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reserved 2 USHORT reserved */ 1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 4 ULONG length in bytes */ 1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 8 ULONG Mac language code */ 1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is32 12 BYTE[8192] 32-bitness bitmap */ 1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count 8204 ULONG number of groups */ 1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This header is followed by `count' groups of the following format: */ 1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start 0 ULONG first charcode */ 1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* end 4 ULONG last charcode */ 1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* startId 8 ULONG start glyph ID for the group */ 1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_8 1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap8_validate( FT_Byte* table, 1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 4; 1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* is32; 1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 length; 1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 num_groups; 1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + 16 + 8192 > valid->limit ) 1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length = TT_NEXT_ULONG( p ); 1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) 1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov is32 = table + 12; 1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = is32 + 8192; /* skip `is32' array */ 1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_groups = TT_NEXT_ULONG( p ); 1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1730e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* p + num_groups * 12 > valid->limit ? */ 1731e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 ) 1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check groups, they must be in increasing order */ 1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 n, start, end, start_id, count, last = 0; 1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < num_groups; n++ ) 1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt hi, lo; 1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_id = TT_NEXT_ULONG( p ); 1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start > end ) 1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n > 0 && start <= last ) 1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1756e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt32 d = end - start; 1757e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1758e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1759e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ 1760e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( d > TT_VALID_GLYPH_COUNT( valid ) || 1761e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) 1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = (FT_UInt32)( end - start + 1 ); 1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start & ~0xFFFFU ) 1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start_hi != 0; check that is32[i] is 1 for each i in */ 1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the `hi' and `lo' of the range [start..end] */ 1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count--, start++ ) 1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hi = (FT_UInt)( start >> 16 ); 1773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lo = (FT_UInt)( start & 0xFFFFU ); 1774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) 1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) 1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start_hi == 0; check that is32[i] is 0 for each i in */ 1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the range [start..end] */ 1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* end_hi cannot be != 0! */ 1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( end & ~0xFFFFU ) 1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count--, start++ ) 1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lo = (FT_UInt)( start & 0xFFFFU ); 1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) 1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov last = end; 1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap8_char_index( TT_CMap cmap, 1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 8204; 1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 num_groups = TT_NEXT_ULONG( p ); 1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 start, end, start_id; 1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; num_groups > 0; num_groups-- ) 1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_id = TT_NEXT_ULONG( p ); 1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code <= end ) 1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1831ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 1832ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 1833ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1834ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann result = (FT_UInt)( start_id + ( char_code - start ) ); 1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap8_char_next( TT_CMap cmap, 1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1846ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Face face = cmap->cmap.charmap.face; 1847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 result = 0; 1848ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UInt32 char_code; 1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 1850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 8204; 1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 num_groups = TT_NEXT_ULONG( p ); 1853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 start, end, start_id; 1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1856ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( *pchar_code >= 0xFFFFFFFFUL ) 1857ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 1858ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1859ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann char_code = *pchar_code + 1; 1860ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 8208; 1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; num_groups > 0; num_groups-- ) 1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_id = TT_NEXT_ULONG( p ); 1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = start; 1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1872ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Again: 1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code <= end ) 1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1875ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* ignore invalid group */ 1876ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 1877ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 1878ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1879ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( start_id + ( char_code - start ) ); 1880ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1881ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* does first element of group point to `.notdef' glyph? */ 1882ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex == 0 ) 1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1884ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code >= 0xFFFFFFFFUL ) 1885ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 1886ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1887ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann char_code++; 1888ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann goto Again; 1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1890ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1891ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* if `gindex' is invalid, the remaining values */ 1892ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* in this group are invalid, too */ 1893ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex >= (FT_UInt)face->num_glyphs ) 1894ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 1895ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1896ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann result = char_code; 1897ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann break; 1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pchar_code = result; 1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap8_get_info( TT_CMap cmap, 1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 1909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 8; 1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 8; 1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap8_class_rec, 1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMapRec ), 1923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap_init, 1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 1926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap8_char_index, 1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap8_char_next, 1928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 1934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 8, 1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap8_validate, 1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) 1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_8 */ 1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 10 *****/ 1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 10 */ 1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reserved 2 USHORT reserved */ 1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 4 ULONG length in bytes */ 1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 8 ULONG Mac language code */ 1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start 12 ULONG first char in range */ 1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count 16 ULONG number of chars in range */ 1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyphIds 20 USHORT[count] glyph indices covered */ 1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_10 1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap10_validate( FT_Byte* table, 1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 4; 1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong length, count; 1975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + 20 > valid->limit ) 1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length = TT_NEXT_ULONG( p ); 1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 16; 1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = TT_NEXT_ULONG( p ); 1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length > (FT_ULong)( valid->limit - table ) || 1985e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* length < 20 + count * 2 ? */ 1986e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length < 20 || 1987e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ( length - 20 ) / 2 < count ) 1988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check glyph indices */ 1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex; 1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count-- ) 1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = TT_NEXT_USHORT( p ); 1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) 2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap10_char_index( TT_CMap cmap, 2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt result = 0; 2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 12; 2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 start = TT_NEXT_ULONG( p ); 2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 count = TT_NEXT_ULONG( p ); 2017ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UInt32 idx; 2018ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2019ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2020ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code < start ) 2021ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2023ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann idx = char_code - start; 2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( idx < count ) 2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 * idx; 2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = TT_PEEK_USHORT( p ); 2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2030ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap10_char_next( TT_CMap cmap, 2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = cmap->data; 2040ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UInt32 char_code; 2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = table + 12; 2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 start = TT_NEXT_ULONG( p ); 2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 count = TT_NEXT_ULONG( p ); 2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 idx; 2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2048ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( *pchar_code >= 0xFFFFFFFFUL ) 2049ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 2050ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2051ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann char_code = *pchar_code + 1; 2052ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = start; 2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2056ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann idx = char_code - start; 2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2 * idx; 2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; idx < count; idx++ ) 2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = TT_NEXT_USHORT( p ); 2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( gindex != 0 ) 2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2064ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2065ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code >= 0xFFFFFFFFUL ) 2066ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 2067ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code++; 2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pchar_code = char_code; 2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap10_get_info( TT_CMap cmap, 2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 2079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 8; 2081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 10; 2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 2091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap10_class_rec, 2092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMapRec ), 2093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap_init, 2095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 2096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap10_char_index, 2097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap10_char_next, 2098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 10, 2106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap10_validate, 2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) 2108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_10 */ 2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 12 *****/ 2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 2117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 2123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 2124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 2126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 12 */ 2128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reserved 2 USHORT reserved */ 2129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 4 ULONG length in bytes */ 2130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 8 ULONG Mac language code */ 2131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count 12 ULONG number of groups */ 2132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 16 */ 2133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This header is followed by `count' groups of the following format: */ 2135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start 0 ULONG first charcode */ 2137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* end 4 ULONG last charcode */ 2138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* startId 8 ULONG start glyph ID for the group */ 2139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_12 2142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TT_CMap12Rec_ 2144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapRec cmap; 2146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool valid; 2147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong cur_charcode; 2148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cur_gindex; 2149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong cur_group; 2150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong num_groups; 2151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TT_CMap12Rec, *TT_CMap12; 2153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_init( TT_CMap12 cmap, 2157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table ) 2158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cmap.data = table; 2160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table += 12; 2162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->num_groups = FT_PEEK_ULONG( table ); 2163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->valid = 0; 2165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_validate( FT_Byte* table, 2172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 2173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* p; 2175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ULong length; 2176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ULong num_groups; 2177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + 16 > valid->limit ) 2180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 4; 2183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length = TT_NEXT_ULONG( p ); 2184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 12; 2186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_groups = TT_NEXT_ULONG( p ); 2187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length > (FT_ULong)( valid->limit - table ) || 2189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* length < 16 + 12 * num_groups ? */ 2190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length < 16 || 2191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ( length - 16 ) / 12 < num_groups ) 2192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check groups, they must be in increasing order */ 2195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong n, start, end, start_id, last = 0; 2197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < num_groups; n++ ) 2200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 2202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 2203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_id = TT_NEXT_ULONG( p ); 2204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start > end ) 2206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n > 0 && start <= last ) 2209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 2212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt32 d = end - start; 2214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ 2217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( d > TT_VALID_GLYPH_COUNT( valid ) || 2218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) 2219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 2220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov last = end; 2223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search the index of the charcode next to cmap->cur_charcode */ 2231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cmap->cur_group should be set up properly by caller */ 2232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_next( TT_CMap12 cmap ) 2235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2236ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Face face = cmap->cmap.cmap.charmap.face; 2237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 2238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong start, end, start_id, char_code; 2239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong n; 2240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex; 2241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) 2244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = cmap->cur_charcode + 1; 2247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) 2249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->cmap.data + 16 + 12 * n; 2251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 2252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 2253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_id = TT_PEEK_ULONG( p ); 2254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 2256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = start; 2257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2258ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann Again: 2259ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code <= end ) 2260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2261ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* ignore invalid group */ 2262ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 2263ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 2264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2265ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( start_id + ( char_code - start ) ); 2266ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2267ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* does first element of group point to `.notdef' glyph? */ 2268ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex == 0 ) 2269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2270ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code >= 0xFFFFFFFFUL ) 2271ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann goto Fail; 2272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2273ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann char_code++; 2274ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann goto Again; 2275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2276ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2277ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* if `gindex' is invalid, the remaining values */ 2278ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* in this group are invalid, too */ 2279ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex >= (FT_UInt)face->num_glyphs ) 2280ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann continue; 2281ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2282ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cmap->cur_charcode = char_code; 2283ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cmap->cur_gindex = gindex; 2284ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cmap->cur_group = n; 2285ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2286ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 2287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 2291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->valid = 0; 2292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 2296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_char_map_binary( TT_CMap cmap, 2297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* pchar_code, 2298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool next ) 2299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 2301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 12; 2302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 num_groups = TT_PEEK_ULONG( p ); 2303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code = *pchar_code; 2304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 start, end, start_id; 2305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 max, min, mid; 2306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !num_groups ) 2309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 2310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* make compiler happy */ 2312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = num_groups; 2313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = 0xFFFFFFFFUL; 2314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 2316ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 2317ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code >= 0xFFFFFFFFUL ) 2318ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 2319ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code++; 2321ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 2322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = 0; 2324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = num_groups; 2325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary search */ 2327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( min < max ) 2328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = ( min + max ) >> 1; 2330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 16 + 12 * mid; 2331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 2333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 2334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 2336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 2337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( char_code > end ) 2338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = mid + 1; 2339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_id = TT_PEEK_ULONG( p ); 2342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2343ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* reject invalid glyph index */ 2344ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 2345ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = 0; 2346ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann else 2347ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = (FT_UInt)( start_id + ( char_code - start ) ); 2348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 2353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2354ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Face face = cmap->cmap.charmap.face; 2355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap12 cmap12 = (TT_CMap12)cmap; 2356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if `char_code' is not in any group, then `mid' is */ 2359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the group nearest to `char_code' */ 2360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code > end ) 2362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid++; 2364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid == num_groups ) 2365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 2366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap12->valid = 1; 2369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap12->cur_charcode = char_code; 2370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap12->cur_group = mid; 2371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2372ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex >= (FT_UInt)face->num_glyphs ) 2373ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = 0; 2374ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !gindex ) 2376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_next( cmap12 ); 2378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap12->valid ) 2380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = cmap12->cur_gindex; 2381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap12->cur_gindex = gindex; 2384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2385ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *pchar_code = cmap12->cur_charcode; 2386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 2389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 2393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_char_index( TT_CMap cmap, 2394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 2395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); 2397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 2401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_char_next( TT_CMap cmap, 2402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 2403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap12 cmap12 = (TT_CMap12)cmap; 2405ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UInt gindex; 2406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no need to search */ 2409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) 2410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_next( cmap12 ); 2412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap12->valid ) 2413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2414ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = cmap12->cur_gindex; 2415ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *pchar_code = (FT_UInt32)cmap12->cur_charcode; 2416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = 0; 2419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); 2422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2423ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return gindex; 2424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_get_info( TT_CMap cmap, 2429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 2430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 8; 2432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 12; 2435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 2442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap12_class_rec, 2443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMap12Rec ), 2444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap12_init, 2446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 2447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap12_char_index, 2448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap12_char_next, 2449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 12, 2457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap12_validate, 2458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) 2459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_12 */ 2461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 2466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 13 *****/ 2467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 2468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 2474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 2475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 2477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 13 */ 2479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* reserved 2 USHORT reserved */ 2480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 4 ULONG length in bytes */ 2481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* language 8 ULONG Mac language code */ 2482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* count 12 ULONG number of groups */ 2483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 16 */ 2484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This header is followed by `count' groups of the following format: */ 2486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start 0 ULONG first charcode */ 2488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* end 4 ULONG last charcode */ 2489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyphId 8 ULONG glyph ID for the whole group */ 2490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_13 2493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TT_CMap13Rec_ 2495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapRec cmap; 2497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool valid; 2498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong cur_charcode; 2499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cur_gindex; 2500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong cur_group; 2501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong num_groups; 2502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TT_CMap13Rec, *TT_CMap13; 2504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_init( TT_CMap13 cmap, 2508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table ) 2509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cmap.data = table; 2511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table += 12; 2513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->num_groups = FT_PEEK_ULONG( table ); 2514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->valid = 0; 2516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_validate( FT_Byte* table, 2523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 2524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 2526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong length; 2527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong num_groups; 2528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( table + 16 > valid->limit ) 2531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 4; 2534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov length = TT_NEXT_ULONG( p ); 2535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = table + 12; 2537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_groups = TT_NEXT_ULONG( p ); 2538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length > (FT_ULong)( valid->limit - table ) || 2540e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* length < 16 + 12 * num_groups ? */ 2541e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length < 16 || 2542e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ( length - 16 ) / 12 < num_groups ) 2543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check groups, they must be in increasing order */ 2546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong n, start, end, glyph_id, last = 0; 2548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < num_groups; n++ ) 2551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 2553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 2554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_id = TT_NEXT_ULONG( p ); 2555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( start > end ) 2557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n > 0 && start <= last ) 2560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT ) 2563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) 2565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 2566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov last = end; 2569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* search the index of the charcode next to cmap->cur_charcode */ 2577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cmap->cur_group should be set up properly by caller */ 2578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_next( TT_CMap13 cmap ) 2581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2582ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Face face = cmap->cmap.cmap.charmap.face; 2583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p; 2584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong start, end, glyph_id, char_code; 2585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong n; 2586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex; 2587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) 2590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = cmap->cur_charcode + 1; 2593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) 2595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->cmap.data + 16 + 12 * n; 2597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 2598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 2599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_id = TT_PEEK_ULONG( p ); 2600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 2602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code = start; 2603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code <= end ) 2605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = (FT_UInt)glyph_id; 2607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2608ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex && gindex < (FT_UInt)face->num_glyphs ) 2609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2610ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cmap->cur_charcode = char_code; 2611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_gindex = gindex; 2612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cur_group = n; 2613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 2620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->valid = 0; 2621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 2625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_char_map_binary( TT_CMap cmap, 2626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* pchar_code, 2627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bool next ) 2628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex = 0; 2630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 12; 2631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 num_groups = TT_PEEK_ULONG( p ); 2632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code = *pchar_code; 2633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 start, end; 2634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 max, min, mid; 2635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !num_groups ) 2638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 2639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* make compiler happy */ 2641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = num_groups; 2642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = 0xFFFFFFFFUL; 2643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 2645ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann { 2646ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( char_code >= 0xFFFFFFFFUL ) 2647ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return 0; 2648ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char_code++; 2650ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 2651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = 0; 2653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = num_groups; 2654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary search */ 2656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( min < max ) 2657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid = ( min + max ) >> 1; 2659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + 16 + 12 * mid; 2660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = TT_NEXT_ULONG( p ); 2662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov end = TT_NEXT_ULONG( p ); 2663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 2665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 2666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( char_code > end ) 2667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = mid + 1; 2668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = (FT_UInt)TT_PEEK_ULONG( p ); 2671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( next ) 2677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2678ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_Face face = cmap->cmap.charmap.face; 2679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap13 cmap13 = (TT_CMap13)cmap; 2680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if `char_code' is not in any group, then `mid' is */ 2683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the group nearest to `char_code' */ 2684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code > end ) 2686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mid++; 2688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mid == num_groups ) 2689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 2690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap13->valid = 1; 2693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap13->cur_charcode = char_code; 2694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap13->cur_group = mid; 2695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2696ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( gindex >= (FT_UInt)face->num_glyphs ) 2697ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = 0; 2698ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !gindex ) 2700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_next( cmap13 ); 2702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap13->valid ) 2704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = cmap13->cur_gindex; 2705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap13->cur_gindex = gindex; 2708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2709ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *pchar_code = cmap13->cur_charcode; 2710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 2713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 2717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_char_index( TT_CMap cmap, 2718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 2719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); 2721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 2725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_char_next( TT_CMap cmap, 2726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 2727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap13 cmap13 = (TT_CMap13)cmap; 2729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt gindex; 2730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no need to search */ 2733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) 2734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_next( cmap13 ); 2736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cmap13->valid ) 2737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2738ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gindex = cmap13->cur_gindex; 2739ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann *pchar_code = cmap13->cur_charcode; 2740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = 0; 2743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); 2746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gindex; 2748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_get_info( TT_CMap cmap, 2753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 2754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 8; 2756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 13; 2759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 2766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap13_class_rec, 2767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMap13Rec ), 2768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap13_init, 2770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) NULL, 2771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap13_char_index, 2772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap13_char_next, 2773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 2779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 13, 2781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap13_validate, 2782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) 2783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_13 */ 2785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 2790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** FORMAT 14 *****/ 2791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 2792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TABLE OVERVIEW */ 2798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* -------------- */ 2799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NAME OFFSET TYPE DESCRIPTION */ 2801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* format 0 USHORT must be 14 */ 2803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* length 2 ULONG table length in bytes */ 2804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* numSelector 6 ULONG number of variation sel. records */ 2805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Followed by numSelector records, each of which looks like */ 2807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* varSelector 0 UINT24 Unicode codepoint of sel. */ 2809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* defaultOff 3 ULONG offset to a default UVS table */ 2810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* describing any variants to be found in */ 2811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the normal Unicode subtable. */ 2812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nonDefOff 7 ULONG offset to a non-default UVS table */ 2813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* describing any variants not in the */ 2814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* standard cmap, with GIDs here */ 2815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* (either offset may be 0 NULL) */ 2816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Selectors are sorted by code point. */ 2818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A default Unicode Variation Selector (UVS) subtable is just a list of */ 2820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ranges of code points which are to be found in the standard cmap. No */ 2821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* glyph IDs (GIDs) here. */ 2822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* numRanges 0 ULONG number of ranges following */ 2824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A range looks like */ 2826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* uniStart 0 UINT24 code point of the first character in */ 2828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this range */ 2829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* additionalCnt 3 UBYTE count of additional characters in this */ 2830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* range (zero means a range of a single */ 2831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* character) */ 2832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Ranges are sorted by `uniStart'. */ 2834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ 2836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* mappings from codepoint to GID. */ 2837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* numMappings 0 ULONG number of mappings */ 2839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A range looks like */ 2841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* uniStart 0 UINT24 code point of the first character in */ 2843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this range */ 2844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* GID 3 USHORT and its GID */ 2845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Ranges are sorted by `uniStart'. */ 2847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef TT_CONFIG_CMAP_FORMAT_14 2849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TT_CMap14Rec_ 2851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapRec cmap; 2853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong num_selectors; 2854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This array is used to store the results of various 2856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * cmap 14 query functions. The data is overwritten 2857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * on each call to these functions. 2858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 2859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 max_results; 2860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* results; 2861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory; 2862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TT_CMap14Rec, *TT_CMap14; 2864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( void ) 2867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_done( TT_CMap14 cmap ) 2868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = cmap->memory; 2870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->max_results = 0; 2873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( memory != NULL && cmap->results != NULL ) 2874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( cmap->results ); 2875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Error 2879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_ensure( TT_CMap14 cmap, 2880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 num_results, 2881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 2882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 old_max = cmap->max_results; 2884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 2885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_results > cmap->max_results ) 2888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->memory = memory; 2890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) 2892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->max_results = num_results; 2895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_init( TT_CMap14 cmap, 2903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table ) 2904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->cmap.data = table; 2906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov table += 6; 2908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->num_selectors = FT_PEEK_ULONG( table ); 2909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->max_results = 0; 2910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap->results = NULL; 2911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 2913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 2917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_validate( FT_Byte* table, 2918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Validator valid ) 2919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2920e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_Byte* p; 2921e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ULong length; 2922e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ULong num_selectors; 2923e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2924e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2925e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( table + 2 + 4 + 4 > valid->limit ) 2926e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_INVALID_TOO_SHORT; 2927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2928e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov p = table + 2; 2929e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length = TT_NEXT_ULONG( p ); 2930e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov num_selectors = TT_NEXT_ULONG( p ); 2931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( length > (FT_ULong)( valid->limit - table ) || 2933e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* length < 10 + 11 * num_selectors ? */ 2934e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov length < 10 || 2935e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ( length - 10 ) / 11 < num_selectors ) 2936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check selectors, they must be in increasing order */ 2939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we start lastVarSel at 1 because a variant selector value of 0 2941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * isn't valid. 2942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 2943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong n, lastVarSel = 1; 2944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < num_selectors; n++ ) 2947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong varSel = TT_NEXT_UINT24( p ); 2949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong defOff = TT_NEXT_ULONG( p ); 2950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong nondefOff = TT_NEXT_ULONG( p ); 2951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( defOff >= length || nondefOff >= length ) 2954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( varSel < lastVarSel ) 2957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastVarSel = varSel + 1; 2960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check the default table (these glyphs should be reached */ 2962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* through the normal Unicode cmap, no GIDs, just check order) */ 2963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( defOff != 0 ) 2964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* defp = table + defOff; 2966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong numRanges = TT_NEXT_ULONG( defp ); 2967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong i; 2968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong lastBase = 0; 2969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2971e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* defp + numRanges * 4 > valid->limit ? */ 2972e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) 2973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 2974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < numRanges; ++i ) 2976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong base = TT_NEXT_UINT24( defp ); 2978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong cnt = FT_NEXT_BYTE( defp ); 2979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( base + cnt >= 0x110000UL ) /* end of Unicode */ 2982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( base < lastBase ) 2985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 2986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastBase = base + cnt + 1U; 2988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and the non-default table (these glyphs are specified here) */ 2992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nondefOff != 0 ) 2993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* ndp = table + nondefOff; 2995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong numMappings = TT_NEXT_ULONG( ndp ); 2996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong i, lastUni = 0; 2997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2999e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ? */ 3000e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 4 ) 3001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_TOO_SHORT; 3002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < numMappings; ++i ) 3004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong uni = TT_NEXT_UINT24( ndp ); 3006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong gid = TT_NEXT_USHORT( ndp ); 3007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( uni >= 0x110000UL ) /* end of Unicode */ 3010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 3011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( uni < lastUni ) 3013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_DATA; 3014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastUni = uni + 1U; 3016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid->level >= FT_VALIDATE_TIGHT && 3018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gid >= TT_VALID_GLYPH_COUNT( valid ) ) 3019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_INVALID_GLYPH_ID; 3020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 3026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 3030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_index( TT_CMap cmap, 3031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 3032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( cmap ); 3034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( char_code ); 3035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This can't happen */ 3037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 ) 3042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_next( TT_CMap cmap, 3043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *pchar_code ) 3044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( cmap ); 3046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This can't happen */ 3048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pchar_code = 0; 3049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Error ) 3054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_get_info( TT_CMap cmap, 3055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 3056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( cmap ); 3058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->format = 14; 3060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* subtable 14 does not define a language field */ 3061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap_info->language = 0xFFFFFFFFUL; 3062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 3064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 3068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_def_binary( FT_Byte *base, 3069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 3070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numRanges = TT_PEEK_ULONG( base ); 3072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 max, min; 3073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = 0; 3076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = numRanges; 3077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base += 4; 3079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary search */ 3081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( min < max ) 3082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 mid = ( min + max ) >> 1; 3084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = base + 4 * mid; 3085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong start = TT_NEXT_UINT24( p ); 3086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cnt = FT_NEXT_BYTE( p ); 3087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < start ) 3090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 3091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( char_code > start+cnt ) 3092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = mid + 1; 3093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 3098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 3102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_nondef_binary( FT_Byte *base, 3103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 char_code ) 3104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numMappings = TT_PEEK_ULONG( base ); 3106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 max, min; 3107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = 0; 3110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = numMappings; 3111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base += 4; 3113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary search */ 3115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( min < max ) 3116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 mid = ( min + max ) >> 1; 3118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = base + 5 * mid; 3119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); 3120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( char_code < uni ) 3123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 3124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( char_code > uni ) 3125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = mid + 1; 3126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TT_PEEK_USHORT( p ); 3128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_Byte* 3135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_find_variant( FT_Byte *base, 3136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 variantCode ) 3137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numVar = TT_PEEK_ULONG( base ); 3139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 max, min; 3140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = 0; 3143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = numVar; 3144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base += 4; 3146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* binary search */ 3148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( min < max ) 3149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 mid = ( min + max ) >> 1; 3151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = base + 11 * mid; 3152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong varSel = TT_NEXT_UINT24( p ); 3153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( variantCode < varSel ) 3156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = mid; 3157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( variantCode > varSel ) 3158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = mid + 1; 3159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return p; 3161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt ) 3168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_var_index( TT_CMap cmap, 3169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap ucmap, 3170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 charcode, 3171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 variantSelector ) 3172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); 3174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong defOff; 3175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong nondefOff; 3176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !p ) 3179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov defOff = TT_NEXT_ULONG( p ); 3182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nondefOff = TT_PEEK_ULONG( p ); 3183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( defOff != 0 && 3185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) 3186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is the default variant of this charcode. GID not stored */ 3188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* here; stored in the normal Unicode charmap instead. */ 3189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); 3190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nondefOff != 0 ) 3193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode ); 3195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_Int ) 3201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_var_isdefault( TT_CMap cmap, 3202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 charcode, 3203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 variantSelector ) 3204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); 3206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong defOff; 3207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong nondefOff; 3208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !p ) 3211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 3212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov defOff = TT_NEXT_ULONG( p ); 3214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nondefOff = TT_NEXT_ULONG( p ); 3215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( defOff != 0 && 3217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) 3218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 1; 3219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nondefOff != 0 && 3221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charcode ) != 0 ) 3223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return -1; 3226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32* ) 3230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_variants( TT_CMap cmap, 3231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 3232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap14 cmap14 = (TT_CMap14)cmap; 3234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 count = cmap14->num_selectors; 3235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 10; 3236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* result; 3237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 i; 3238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) 3241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = cmap14->results; 3244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < count; ++i ) 3245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); 3247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 8; 3248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result[i] = 0; 3250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 3252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 * ) 3256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_variants( TT_CMap cmap, 3257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory, 3258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 charCode ) 3259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap14 cmap14 = (TT_CMap14) cmap; 3261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 count = cmap14->num_selectors; 3262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p = cmap->data + 10; 3263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* q; 3264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) 3267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( q = cmap14->results; count > 0; --count ) 3270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 varSel = TT_NEXT_UINT24( p ); 3272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong defOff = TT_NEXT_ULONG( p ); 3273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong nondefOff = TT_NEXT_ULONG( p ); 3274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( defOff != 0 && 3277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_def_binary( cmap->data + defOff, 3278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charCode ) ) || 3279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( nondefOff != 0 && 3280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charCode ) != 0 ) ) 3282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q[0] = varSel; 3284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q++; 3285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q[0] = 0; 3288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmap14->results; 3290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt 3294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_def_char_count( FT_Byte *p ) 3295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); 3297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt tot = 0; 3298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 3; /* point to the first `cnt' field */ 3301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; numRanges > 0; numRanges-- ) 3302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tot += 1 + p[0]; 3304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 4; 3305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tot; 3308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt32* 3312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_get_def_chars( TT_CMap cmap, 3313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* p, 3314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 3315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap14 cmap14 = (TT_CMap14) cmap; 3317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numRanges; 3318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt cnt; 3319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32* q; 3320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cnt = tt_cmap14_def_char_count( p ); 3323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); 3324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) 3326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( q = cmap14->results; numRanges > 0; --numRanges ) 3329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); 3331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cnt = FT_NEXT_BYTE( p ) + 1; 3334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 3335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q[0] = uni; 3337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov uni += 1; 3338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q += 1; 3339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( --cnt != 0 ); 3341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov q[0] = 0; 3343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmap14->results; 3345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static FT_UInt32* 3349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_get_nondef_chars( TT_CMap cmap, 3350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte *p, 3351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory ) 3352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap14 cmap14 = (TT_CMap14) cmap; 3354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numMappings; 3355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt i; 3356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 *ret; 3357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); 3360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) 3362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret = cmap14->results; 3365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < numMappings; ++i ) 3366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); 3368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 3369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i] = 0; 3371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ret; 3373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CALLBACK_DEF( FT_UInt32 * ) 3377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_variant_chars( TT_CMap cmap, 3378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory, 3379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 variantSelector ) 3380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, 3382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov variantSelector ); 3383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Int i; 3384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong defOff; 3385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong nondefOff; 3386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !p ) 3389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov defOff = TT_NEXT_ULONG( p ); 3392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nondefOff = TT_NEXT_ULONG( p ); 3393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( defOff == 0 && nondefOff == 0 ) 3395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( defOff == 0 ) 3398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, 3399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory ); 3400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( nondefOff == 0 ) 3401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, 3402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory ); 3403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Both a default and a non-default glyph set? That's probably not */ 3406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* good font design, but the spec allows for it... */ 3407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap14 cmap14 = (TT_CMap14) cmap; 3408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numRanges; 3409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 numMappings; 3410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 duni; 3411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 dcnt; 3412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 nuni; 3413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* dp; 3414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt di, ni, k; 3415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3416e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UInt32 *ret; 3417e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 3418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmap->data + nondefOff; 3420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dp = cmap->data + defOff; 3421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); 3423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dcnt = tt_cmap14_def_char_count( dp ); 3424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); 3425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( numMappings == 0 ) 3427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, 3428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory ); 3429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dcnt == 0 ) 3430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, 3431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory ); 3432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) 3434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret = cmap14->results; 3437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dcnt = FT_NEXT_BYTE( dp ); 3439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov di = 1; 3440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nuni = (FT_UInt32)TT_NEXT_UINT24( p ); 3441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 3442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ni = 1; 3443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = 0; 3444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ;; ) 3446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nuni > duni + dcnt ) 3448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( k = 0; k <= dcnt; ++k ) 3450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i++] = duni + k; 3451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++di; 3453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( di > numRanges ) 3455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dcnt = FT_NEXT_BYTE( dp ); 3459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( nuni < duni ) 3463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i++] = nuni; 3464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If it is within the default range then ignore it -- */ 3465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* that should not have happened */ 3466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++ni; 3467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ni > numMappings ) 3468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nuni = (FT_UInt32)TT_NEXT_UINT24( p ); 3471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 3472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ni <= numMappings ) 3476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we get here then we have run out of all default ranges. */ 3478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We have read one non-default mapping which we haven't stored */ 3479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and there may be others that need to be read. */ 3480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i++] = nuni; 3481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( ni < numMappings ) 3482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); 3484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += 2; 3485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++ni; 3486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( di <= numRanges ) 3489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we get here then we have run out of all non-default */ 3491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* mappings. We have read one default range which we haven't */ 3492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stored and there may be others that need to be read. */ 3493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( k = 0; k <= dcnt; ++k ) 3494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i++] = duni + k; 3495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( di < numRanges ) 3497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dcnt = FT_NEXT_BYTE( dp ); 3500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( k = 0; k <= dcnt; ++k ) 3502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i++] = duni + k; 3503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++di; 3504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ret[i] = 0; 3508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ret; 3510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_TT_CMAP( 3515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_cmap14_class_rec, 3516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMap14Rec ), 3517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_InitFunc) tt_cmap14_init, 3519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_DoneFunc) tt_cmap14_done, 3520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharIndexFunc)tt_cmap14_char_index, 3521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharNextFunc) tt_cmap14_char_next, 3522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Format 14 extension functions */ 3524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, 3525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, 3526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_VariantListFunc) tt_cmap14_variants, 3527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, 3528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, 3529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 14, 3531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_ValidateFunc)tt_cmap14_validate, 3532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) 3533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* TT_CONFIG_CMAP_FORMAT_14 */ 3535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_CONFIG_OPTION_PIC 3538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const TT_CMap_Class tt_cmap_classes[] = 3540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TTCMAPCITEM( a ) &a, 3542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttcmapc.h" 3543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NULL, 3544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 3545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /*FT_CONFIG_OPTION_PIC*/ 3547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void 3549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Destroy_Class_tt_cmap_classes( FT_Library library, 3550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap_Class* clazz ) 3551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 3553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz ) 3556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( clazz ); 3557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error 3561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Create_Class_tt_cmap_classes( FT_Library library, 3562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap_Class** output_class ) 3563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap_Class* clazz = NULL; 3565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap_ClassRec* recs; 3566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 3567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = library->memory; 3568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i = 0; 3570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TTCMAPCITEM( a ) i++; 3573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttcmapc.h" 3574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* allocate enough space for both the pointers */ 3576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* plus terminator and the class instances */ 3577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) + 3578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( TT_CMap_ClassRec ) * i ) ) 3579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the location of the class instances follows the array of pointers */ 3582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov recs = (TT_CMap_ClassRec*)( (char*)clazz + 3583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sizeof ( *clazz ) * ( i + 1 ) ); 3584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = 0; 3585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef TTCMAPCITEM 3587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TTCMAPCITEM( a ) \ 3588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Init_Class_ ## a( &recs[i] ); \ 3589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i] = &recs[i]; \ 3590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i++; 3591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttcmapc.h" 3592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz[i] = NULL; 3594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *output_class = clazz; 3596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 3597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /*FT_CONFIG_OPTION_PIC*/ 3600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parse the `cmap' table and build the corresponding TT_CMap objects */ 3603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in the current face */ 3604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 3606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_face_build_cmaps( TT_Face face ) 3607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* table = face->cmap_table; 3609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* limit = table + face->cmap_size; 3610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt volatile num_cmaps; 3611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* volatile p = table; 3612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Library library = FT_FACE_LIBRARY( face ); 3613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( library ); 3615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !p || p + 4 > limit ) 3618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Table ); 3619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* only recognize format 0 */ 3621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( TT_NEXT_USHORT( p ) != 0 ) 3622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "tt_face_build_cmaps:" 3624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " unsupported `cmap' table format = %d\n", 3625ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TT_PEEK_USHORT( p - 2 ) )); 3626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Table ); 3627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_cmaps = TT_NEXT_USHORT( p ); 3630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) 3632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CharMapRec charmap; 3634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt32 offset; 3635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charmap.platform_id = TT_NEXT_USHORT( p ); 3638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charmap.encoding_id = TT_NEXT_USHORT( p ); 3639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charmap.face = FT_FACE( face ); 3640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ 3641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offset = TT_NEXT_ULONG( p ); 3642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( offset && offset <= face->cmap_size - 2 ) 3644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Byte* volatile cmap = table + offset; 3646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov volatile FT_UInt format = TT_PEEK_USHORT( cmap ); 3647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET; 3648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap_Class volatile clazz; 3649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; *pclazz; pclazz++ ) 3652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clazz = *pclazz; 3654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( clazz->format == format ) 3655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov volatile TT_ValidatorRec valid; 3657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov volatile FT_Error error = FT_Err_Ok; 3658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, 3661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_VALIDATE_DEFAULT ); 3662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; 3664e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 3665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 ) 3666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* validate this cmap sub-table */ 3668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); 3669e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 3670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( valid.validator.error == 0 ) 3672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap ttcmap; 3674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* It might make sense to store the single variation */ 3677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* selector cmap somewhere special. But it would have to be */ 3678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in the public FT_FaceRec, and we can't change that. */ 3679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_CMap_New( (FT_CMap_Class)clazz, 3681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmap, &charmap, &ttcmap ) ) 3682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* it is simpler to directly set `flags' than adding */ 3684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a parameter to FT_CMap_New */ 3685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((TT_CMap)ttcmap)->flags = (FT_Int)error; 3686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE0(( "tt_face_build_cmaps:" 3691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " broken cmap sub-table ignored\n" )); 3692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( *pclazz == NULL ) 3698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE0(( "tt_face_build_cmaps:" 3700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " unsupported cmap sub-table ignored\n" )); 3701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_Err_Ok; 3706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL( FT_Error ) 3710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tt_get_cmap_info( FT_CharMap charmap, 3711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMapInfo *cmap_info ) 3712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CMap cmap = (FT_CMap)charmap; 3714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; 3715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return clazz->get_cmap_info( charmap, cmap_info ); 3718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 3722