1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* ttcmap.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* TrueType character mapping table (cmap) support (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/* Copyright 2002-2010, 2012, 2013 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h> 20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H 21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "sferrors.h" /* must come before FT_INTERNAL_VALIDATE_H */ 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_VALIDATE_H 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttload.h" 27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttcmap.h" 28295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "sfntpic.h" 29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* messages during execution. */ 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef FT_COMPONENT 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT trace_ttcmap 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_PEEK_SHORT FT_PEEK_SHORT 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_PEEK_USHORT FT_PEEK_USHORT 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_PEEK_UINT24 FT_PEEK_UOFF3 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_PEEK_LONG FT_PEEK_LONG 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_PEEK_ULONG FT_PEEK_ULONG 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_NEXT_SHORT FT_NEXT_SHORT 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_NEXT_USHORT FT_NEXT_USHORT 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_NEXT_UINT24 FT_NEXT_UOFF3 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_NEXT_LONG FT_NEXT_LONG 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_NEXT_ULONG FT_NEXT_ULONG 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap_init( TT_CMap cmap, 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->data = table; 59a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 0 *****/ 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 0 */ 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length in bytes */ 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyph_ids 6 BYTE[256] array of glyph indices */ 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 262 */ 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_0 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_validate( FT_Byte* table, 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 2; 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt length = TT_NEXT_USHORT( p ); 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit || length < 262 ) 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices whenever necessary */ 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt n, idx; 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 6; 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < 256; n++ ) 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = *p++; 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 113a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_char_index( TT_CMap cmap, 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return char_code < 256 ? table[6 + char_code] : 0; 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 128295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_char_next( TT_CMap cmap, 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 charcode = *pchar_code; 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 13877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner table += 6; /* go to glyph IDs */ 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( ++charcode < 256 ) 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = table[charcode]; 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = charcode; 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = result; 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_get_info( TT_CMap cmap, 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 161295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 0; 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 164a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 168a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 169a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap0_class_rec, 170a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMapRec ), 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 172a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap_init, 173a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 174a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap0_char_index, 175a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap0_char_next, 176a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 177a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 178a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 179a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 180a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 181a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 0, 184a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap0_validate, 185a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) 186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_0 */ 188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 2 *****/ 194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** This is used for certain CJK encodings that encode text in a *****/ 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** mixed 8/16 bits encoding along the following lines: *****/ 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** * Certain byte values correspond to an 8-bit character code *****/ 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** (typically in the range 0..127 for ASCII compatibility). *****/ 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** * Certain byte values signal the first byte of a 2-byte *****/ 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** character code (but these values are also valid as the *****/ 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** second byte of a 2-byte character). *****/ 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** The following charmap lookup and iteration functions all *****/ 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** assume that the value "charcode" correspond to following: *****/ 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** - For one byte characters, "charcode" is simply the *****/ 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** character code. *****/ 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** - For two byte characters, "charcode" is the 2-byte *****/ 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** character code in big endian format. More exactly: *****/ 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** (charcode >> 8) is the first byte value *****/ 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** (charcode & 0xFF) is the second byte value *****/ 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** Note that not all values of "charcode" are valid according *****/ 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** to these rules, and the function moderately check the *****/ 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** arguments. *****/ 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 2 */ 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length in bytes */ 233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* keys 6 USHORT[256] sub-header keys */ 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* subs 518 SUBHEAD[NSUBS] sub-headers array */ 23677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ 237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The `keys' table is used to map charcode high-bytes to sub-headers. */ 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The value of `NSUBS' is the number of sub-headers defined in the */ 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* table and is computed by finding the maximum of the `keys' table. */ 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* table, i.e., it is the corresponding sub-header index multiplied */ 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* by 8. */ 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Each sub-header has the following format: */ 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* first 0 USHORT first valid low-byte */ 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 2 USHORT number of valid low-bytes */ 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* delta 4 SHORT see below */ 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* offset 6 USHORT see below */ 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A sub-header defines, for each high-byte, the range of valid */ 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* low-bytes within the charmap. Note that the range defined by `first' */ 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and `count' must be completely included in the interval [0..255] */ 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* according to the specification. */ 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If a character code is contained within a given sub-header, then */ 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* mapping it to a glyph index is done as follows: */ 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* * The value of `offset' is read. This is a _byte_ distance from the */ 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* location of the `offset' field itself into a slice of the */ 26577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[] too). */ 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no glyph for the charcode. Otherwise, the value of `delta' is */ 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* added to it (modulo 65536) to form a new glyph index. */ 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* It is up to the validation routine to check that all offsets fall */ 27277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* within the glyph IDs table (and not within the `subs' table itself or */ 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* outside of the CMap). */ 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_2 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_validate( FT_Byte* table, 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 2; /* skip format */ 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt length = TT_PEEK_USHORT( p ); 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt n, max_subs; 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* keys; /* keys table */ 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subs; /* sub-headers */ 28777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* glyph_ids; /* glyph ID array */ 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit || length < 6 + 512 ) 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project keys = table + 6; 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parse keys to compute sub-headers count */ 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = keys; 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max_subs = 0; 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < 256; n++ ) 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx = TT_NEXT_USHORT( p ); 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* value must be multiple of 8 */ 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx >>= 3; 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx > max_subs ) 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max_subs = idx; 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ASSERT( p == table + 518 ); 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project subs = p; 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project glyph_ids = subs + (max_subs + 1) * 8; 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( glyph_ids > valid->limit ) 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parse sub-headers */ 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n <= max_subs; n++ ) 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt first_code, code_count, offset; 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* ids; 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_code = TT_NEXT_USHORT( p ); 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project code_count = TT_NEXT_USHORT( p ); 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_NEXT_SHORT( p ); 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_NEXT_USHORT( p ); 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 33377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* many Dynalab fonts have empty sub-headers */ 33477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( code_count == 0 ) 33577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner continue; 33677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check range within 0..255 */ 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( first_code >= 256 || first_code + code_count > 256 ) 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check offset */ 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0 ) 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ids = p - 2 + offset; 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ids < glyph_ids || ids + code_count*2 > table + length ) 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_OFFSET; 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 35177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check glyph IDs */ 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit = p + code_count * 2; 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx; 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; p < limit; ) 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = TT_NEXT_USHORT( p ); 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = ( idx + delta ) & 0xFFFFU; 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 372a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* return sub header corresponding to a given character code */ 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NULL on invalid charcode */ 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Byte* 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_get_subheader( FT_Byte* table, 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* result = NULL; 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < 0x10000UL ) 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 6; /* keys table */ 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subs = table + 518; /* subheaders table */ 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* sub; 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_hi == 0 ) 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* an 8-bit character code -- we use subHeader 0 in this case */ 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to test whether the character code is in the charmap */ 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sub = subs; /* jump to first sub-header */ 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that the sub-header for this byte is 0, which */ 40277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* indicates that it is really a valid one-byte value */ 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Otherwise, return 0 */ 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += char_lo * 2; 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( TT_PEEK_USHORT( p ) != 0 ) 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* a 16-bit character code */ 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* jump to key entry */ 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += char_hi * 2; 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* jump to sub-header */ 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that the high byte isn't a valid one-byte value */ 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( sub == subs ) 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = sub; 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_char_index( TT_CMap cmap, 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subheader; 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project subheader = tt_cmap2_get_subheader( table, char_code ); 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( subheader ) 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = subheader; 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx = (FT_UInt)(char_code & 0xFF); 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start, count; 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt offset; 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_USHORT( p ); 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = TT_NEXT_USHORT( p ); 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_NEXT_SHORT ( p ); 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx -= start; 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx < count && offset != 0 ) 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + 2 * idx; 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = TT_PEEK_USHORT( p ); 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = (FT_UInt)( idx + delta ) & 0xFFFFU; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 467295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_char_next( TT_CMap cmap, 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pcharcode ) 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 charcode = *pcharcode + 1; 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subheader; 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( charcode < 0x10000UL ) 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project subheader = tt_cmap2_get_subheader( table, charcode ); 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( subheader ) 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = subheader; 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start = TT_NEXT_USHORT( p ); 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt count = TT_NEXT_USHORT( p ); 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta = TT_NEXT_SHORT ( p ); 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt offset = TT_PEEK_USHORT( p ); 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt pos, idx; 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0 ) 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Next_SubHeader; 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_lo < start ) 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_lo = start; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos = 0; 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos = (FT_UInt)( char_lo - start ); 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + pos * 2; 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; pos < count; pos++, charcode++ ) 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = TT_NEXT_USHORT( p ); 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = ( idx + delta ) & 0xFFFFU; 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = charcode; 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* jump to next sub-header, i.e. higher byte value */ 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Next_SubHeader: 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = result; 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_get_info( TT_CMap cmap, 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 541295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 2; 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 544a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 548a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 549a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap2_class_rec, 550a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMapRec ), 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 552a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap_init, 553a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 554a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap2_char_index, 555a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap2_char_next, 556a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 557a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 558a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 559a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 560a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 561a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2, 564a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap2_validate, 565a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_2 */ 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 4 *****/ 574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 4 */ 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length */ 587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in bytes */ 588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* segCountX2 6 USHORT 2*NUM_SEGS */ 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ 592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* entrySelector 10 USHORT LOG_SEGS */ 593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* rangeShift 12 USHORT segCountX2 - */ 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* searchRange */ 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* endCount 14 USHORT[NUM_SEGS] end charcode for */ 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each segment; last */ 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is 0xFFFF */ 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* pad 14+NUM_SEGS*2 USHORT padding */ 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each segment */ 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* segment */ 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each segment; can be */ 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* zero */ 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 61177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ranges */ 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Character codes are modelled by a series of ordered (increasing) */ 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* intervals called segments. Each segment has start and end codes, */ 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* provided by the `startCount' and `endCount' arrays. Segments must */ 61777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* not overlap, and the last segment should always contain the value */ 61877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* 0xFFFF for `endCount'. */ 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ignored (they are traces of over-engineering in the TrueType */ 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* specification). */ 623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Each segment also has a signed `delta', as well as an optional offset */ 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* within the `glyphIds' table. */ 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If a segment's idOffset is 0, the glyph index corresponding to any */ 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* charcode within the segment is obtained by adding the value of */ 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* `idDelta' directly to the charcode, modulo 65536. */ 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 63177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the segment, and the value of `idDelta' is added to it. */ 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 63577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* Finally, note that a lot of fonts contain an invalid last segment, */ 63677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ 63777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ 63877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* OpenOffice.org). We need special code to deal with them correctly. */ 639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_4 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_CMap4Rec_ 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapRec cmap; 646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 cur_charcode; /* current charcode */ 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_gindex; /* current glyph index */ 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_ranges; 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_range; 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_start; 652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_end; 653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int cur_delta; 654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* cur_values; 655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_CMap4Rec, *TT_CMap4; 657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_init( TT_CMap4 cmap, 661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cmap.data = table; 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 6; 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; 670295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = 0; 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 673a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Int 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_set_range( TT_CMap4 cmap, 679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt range_index ) 680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->cmap.data; 682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_ranges = cmap->num_ranges; 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( range_index < num_ranges ) 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt offset; 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 14 + range_index * 2; 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_end = FT_PEEK_USHORT( p ); 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_ranges * 2; 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_start = FT_PEEK_USHORT( p ); 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_ranges * 2; 698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_delta = FT_PEEK_SHORT( p ); 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_ranges * 2; 701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = FT_PEEK_USHORT( p ); 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 70377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts have an incorrect last segment; */ 70477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* we have to catch it */ 70577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( range_index >= num_ranges - 1 && 70677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner cmap->cur_start == 0xFFFFU && 70777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner cmap->cur_end == 0xFFFFU ) 70877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 70977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; 71077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* limit = face->cmap_table + face->cmap_size; 71177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 71277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 71377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( offset && p + offset + 2 > limit ) 71477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 71577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner cmap->cur_delta = 1; 71677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner offset = 0; 71777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 71877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 71977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0xFFFFU ) 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_values = offset ? p + offset : NULL; 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_range = range_index; 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we skip empty segments */ 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project range_index++; 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return -1; 732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search the index of the charcode next to cmap->cur_charcode; */ 736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* caller should call tt_cmap4_set_range with proper range */ 737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* before calling this function */ 738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_next( TT_CMap4 cmap ) 741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt charcode; 743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->cur_charcode >= 0xFFFFUL ) 746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 748295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner charcode = (FT_UInt)cmap->cur_charcode + 1; 749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < cmap->cur_start ) 751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = cmap->cur_start; 752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ;; ) 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* values = cmap->cur_values; 756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt end = cmap->cur_end; 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta = cmap->cur_delta; 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode <= end ) 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( values ) 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do 768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = FT_NEXT_USHORT( p ); 770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( ( gindex + delta ) & 0xFFFFU ); 775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_charcode = charcode; 778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = gindex; 779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } while ( ++charcode <= end ); 783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do 787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = (FT_UInt)( ( charcode + delta ) & 0xFFFFU ); 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_charcode = charcode; 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = gindex; 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } while ( ++charcode <= end ); 798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we need to find another range */ 802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < cmap->cur_start ) 806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = cmap->cur_start; 807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 810295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = 0; 812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_validate( FT_Byte* table, 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 2; /* skip format */ 820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt length = TT_NEXT_USHORT( p ); 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; 822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_segs; 823a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Error error = FT_Err_Ok; 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( length < 16 ) 827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in certain fonts, the `length' field is invalid and goes */ 830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* out of bound. We try to correct this here... */ 831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit ) 832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = (FT_UInt)( valid->limit - table ); 837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 6; 840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ 841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that we have an even value here */ 845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( num_segs & 1 ) 846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs /= 2; 850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( length < 16 + num_segs * 2 * 4 ) 852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check the search parameters - even though we never use them */ 855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 85877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check the values of `searchRange', `entrySelector', `rangeShift' */ 859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt search_range = TT_NEXT_USHORT( p ); 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt entry_selector = TT_NEXT_USHORT( p ); 861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt range_shift = TT_NEXT_USHORT( p ); 862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( search_range | range_shift ) & 1 ) /* must be even values */ 865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range /= 2; 868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project range_shift /= 2; 869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* `search range' is the greatest power of 2 that is <= num_segs */ 871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( search_range > num_segs || 873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range * 2 < num_segs || 874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range + range_shift != num_segs || 875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range != ( 1U << entry_selector ) ) 876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ends = table + 14; 880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project starts = table + 16 + num_segs * 2; 881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas = starts + num_segs * 2; 882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsets = deltas + num_segs * 2; 883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project glyph_ids = offsets + num_segs * 2; 884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 88577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check last segment; its end count value must be 0xFFFF */ 886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = ends + ( num_segs - 1 ) * 2; 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 89477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt start, end, offset, n; 89577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt last_start = 0, last_end = 0; 89677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Int delta; 897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_start = starts; 898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_end = ends; 899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_delta = deltas; 900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_offset = offsets; 901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_segs; n++ ) 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = p_offset; 906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_USHORT( p_start ); 907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_USHORT( p_end ); 908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_NEXT_SHORT( p_delta ); 909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_NEXT_USHORT( p_offset ); 910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start > end ) 912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 91477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* this test should be performed at default validation level; */ 91577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* unfortunately, some popular Asian fonts have overlapping */ 91677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* ranges in their charmaps */ 91777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* */ 918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start <= last_end && n > 0 ) 919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* allow overlapping segments, provided their start points */ 92577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* and end points, respectively, are in ascending order */ 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_start > start || last_end > end ) 928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error |= TT_CMAP_FLAG_UNSORTED; 929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error |= TT_CMAP_FLAG_OVERLAPPING; 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset && offset != 0xFFFFU ) 935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 93677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner p += offset; /* start of glyph ID array */ 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 93877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check that we point within the glyph IDs table only */ 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p < glyph_ids || 942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p + ( end - start + 1 ) * 2 > table + length ) 943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 94577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* Some fonts handle the last segment incorrectly. In */ 94677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* theory, 0xFFFF might point to an ordinary glyph -- */ 94777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* a cmap 4 is versatile and could be used for any */ 94877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* encoding, not only Unicode. However, reality shows */ 94977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* that far too many fonts are sloppy and incorrectly */ 95077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* set all fields but `start' and `end' for the last */ 95177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* segment if it contains only a single character. */ 95277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* */ 95377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* We thus omit the test here, delaying it to the */ 95477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* routines which actually access the cmap. */ 95577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner else if ( n != num_segs - 1 || 95677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner !( start == 0xFFFFU && end == 0xFFFFU ) ) 957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p < glyph_ids || 959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p + ( end - start + 1 ) * 2 > valid->limit ) 960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices within the segment range */ 964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, idx; 967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = start; i < end; i++ ) 970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = FT_NEXT_USHORT( p ); 972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (FT_UInt)( idx + delta ) & 0xFFFFU; 975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( offset == 0xFFFFU ) 983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 98477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts (erroneously?) use a range offset of 0xFFFF */ 985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to mean missing glyph in cmap table */ 986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 98777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( valid->level >= FT_VALIDATE_PARANOID || 98877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner n != num_segs - 1 || 98977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner !( start == 0xFFFFU && end == 0xFFFFU ) ) 990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_start = start; 994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_end = end; 995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 100377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner tt_cmap4_char_map_linear( TT_CMap cmap, 100477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt32* pcharcode, 100577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Bool next ) 1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_segs2, start, end, offset; 1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, num_segs; 1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 charcode = *pcharcode; 1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 6; 1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); 1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs = num_segs2 >> 1; 1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !num_segs ) 1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode++; 1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* linear search */ 1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; charcode <= 0xFFFFU; charcode++ ) 1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* q; 1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14; /* ends table */ 1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q = cmap->data + 16 + num_segs2; /* starts table */ 1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = 0; i < num_segs; i++ ) 1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_USHORT( p ); 1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_USHORT( q ); 1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode >= start && charcode <= end ) 1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = q - 2 + num_segs2; 1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 104777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts have an incorrect last segment; */ 104877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* we have to catch it */ 104977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( i >= num_segs - 1 && 105077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner start == 0xFFFFU && end == 0xFFFFU ) 105177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 105277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner TT_Face face = (TT_Face)cmap->cmap.charmap.face; 105377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* limit = face->cmap_table + face->cmap_size; 105477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 105577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 105677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( offset && p + offset + 2 > limit ) 105777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 105877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner delta = 1; 105977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner offset = 0; 106077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 106177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 106277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0xFFFFU ) 1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset ) 1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + ( charcode - start ) * 2; 1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_PEEK_USHORT( p ); 1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; 1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; 1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !next || gindex ) 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next && gindex ) 1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = charcode; 1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 109277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner tt_cmap4_char_map_binary( TT_CMap cmap, 109377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt32* pcharcode, 109477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Bool next ) 1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_segs2, start, end, offset; 1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt max, min, mid, num_segs; 1099295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt charcode = (FT_UInt)*pcharcode; 1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 6; 1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); 1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !num_segs2 ) 1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs = num_segs2 >> 1; 1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* make compiler happy */ 1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = num_segs; 1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = 0xFFFFU; 1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode++; 1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = num_segs; 1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( min + max ) >> 1; 1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + mid * 2; 1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_PEEK_USHORT( p ); 1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < start ) 1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( charcode > end ) 1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 114277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts have an incorrect last segment; */ 114377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* we have to catch it */ 114477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( mid >= num_segs - 1 && 114577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner start == 0xFFFFU && end == 0xFFFFU ) 114677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 114777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner TT_Face face = (TT_Face)cmap->cmap.charmap.face; 114877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* limit = face->cmap_table + face->cmap_size; 114977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 115077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 115177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( offset && p + offset + 2 > limit ) 115277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 115377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner delta = 1; 115477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner offset = 0; 115577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 115677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 115777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search the first segment containing `charcode' */ 1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) 1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i; 1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* call the current segment `max' */ 1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0xFFFFU ) 1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = max + 1; 1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search in segments before the current segment */ 1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = max ; i > 0; i-- ) 1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt prev_end; 1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* old_p; 1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project old_p = p; 1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + ( i - 1 ) * 2; 1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev_end = TT_PEEK_USHORT( p ); 1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode > prev_end ) 1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = old_p; 1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = prev_end; 1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0xFFFFU ) 1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = i - 1; 1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no luck */ 1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == max + 1 ) 1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( i != max ) 1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + max * 2; 1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_PEEK_USHORT( p ); 1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = max; 1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search in segments after the current segment */ 1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = max + 1; i < num_segs; i++ ) 1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt next_end, next_start; 1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + i * 2; 1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_end = TT_PEEK_USHORT( p ); 1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_start = TT_PEEK_USHORT( p ); 1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < next_start ) 1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = next_end; 1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = next_start; 1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0xFFFFU ) 1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = i; 1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project i--; 1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* still no luck */ 1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == max ) 1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = i; 1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end, start, delta, and offset are for the i'th segment */ 1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid != i ) 1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + mid * 2; 1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_PEEK_USHORT( p ); 1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0xFFFFU ) 1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset ) 1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + ( charcode - start ) * 2; 1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_PEEK_USHORT( p ); 1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( gindex + delta ) & 0xFFFFU; 1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( charcode + delta ) & 0xFFFFU; 1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap4 cmap4 = (TT_CMap4)cmap; 1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if `charcode' is not in any segment, then `mid' is */ 1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the segment nearest to `charcode' */ 1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode > end ) 1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid++; 1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == num_segs ) 1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap4_set_range( cmap4, mid ) ) 1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = charcode; 1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap4->cur_charcode = charcode; 1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap4->cur_gindex = gindex; 1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap4->cur_charcode = charcode; 1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_next( cmap4 ); 1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap4->cur_gindex; 1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = cmap4->cur_charcode; 1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_char_index( TT_CMap cmap, 1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code >= 0x10000UL ) 1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) 1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); 1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); 1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1341295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_char_next( TT_CMap cmap, 1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( *pchar_code >= 0xFFFFU ) 1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) 1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); 1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap4 cmap4 = (TT_CMap4)cmap; 1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no need to search */ 1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( *pchar_code == cmap4->cur_charcode ) 1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_next( cmap4 ); 1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap4->cur_gindex; 1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = cmap4->cur_charcode; 1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); 1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_get_info( TT_CMap cmap, 1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1381295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 4; 1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1384a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1388a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 1389a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap4_class_rec, 1390a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMap4Rec ), 1391a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap4_init, 1392a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 1393a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap4_char_index, 1394a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap4_char_next, 1395a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1396a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1397a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1398a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1399a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1400a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 4, 1403a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap4_validate, 1404a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) 1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_4 */ 1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 6 *****/ 1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 4 */ 1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length in bytes */ 1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* first 6 USHORT first segment code */ 1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 8 USHORT segment size in chars */ 143077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* glyphIds 10 USHORT[count] glyph IDs */ 1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A very simplified segment mapping. */ 1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_6 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_validate( FT_Byte* table, 1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt length, count; 1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 10 > valid->limit ) 1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 2; 1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_USHORT( p ); 1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 8; /* skip language and start index */ 1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = TT_NEXT_USHORT( p ); 1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit || length < 10 + count * 2 ) 1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices */ 1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count-- ) 1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) 1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1471a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_char_index( TT_CMap cmap, 1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 6; 1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start = TT_NEXT_USHORT( p ); 1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt count = TT_NEXT_USHORT( p ); 1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx = (FT_UInt)( char_code - start ); 1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx < count ) 1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = TT_PEEK_USHORT( p ); 1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1496295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_char_next( TT_CMap cmap, 1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code = *pchar_code + 1; 1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 6; 1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start = TT_NEXT_USHORT( p ); 1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt count = TT_NEXT_USHORT( p ); 1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx; 1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code >= 0x10000UL ) 1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (FT_UInt)( char_code - start ); 1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; idx < count; idx++ ) 1521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = char_code; 1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code++; 1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = result; 1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_get_info( TT_CMap cmap, 1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1544295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 6; 1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1547a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1551a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 1552a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap6_class_rec, 1553a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMapRec ), 1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1555a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap_init, 1556a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 1557a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap6_char_index, 1558a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap6_char_next, 1559a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1560a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1561a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1562a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1563a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1564a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 6, 1567a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap6_validate, 1568a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) 1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_6 */ 1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 8 *****/ 1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 157877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /***** It is hard to completely understand what the OpenType spec *****/ 1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** says about this format, but here is my conclusion. *****/ 1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** The purpose of this format is to easily map UTF-16 text to *****/ 1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** glyph indices. Basically, the `char_code' must be in one of *****/ 1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** the following formats: *****/ 1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ 1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** Area (i.e. U+D800-U+DFFF). *****/ 1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ 1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** `char_code = (char_hi << 16) | char_lo', then both *****/ 1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ 1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** Area. *****/ 1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 159377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /***** The `is32' table embedded in the charmap indicates whether a *****/ 1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** given 16-bit value is in the surrogates area or not. *****/ 1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** So, for any given `char_code', we can assert the following: *****/ 1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ 1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** If `char_hi != 0' then we must have both *****/ 1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ 1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 8 */ 1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* reserved 2 USHORT reserved */ 1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 4 ULONG length in bytes */ 1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 8 ULONG Mac language code */ 1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is32 12 BYTE[8192] 32-bitness bitmap */ 1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 8204 ULONG number of groups */ 1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 162077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* This header is followed by `count' groups of the following format: */ 1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start 0 ULONG first charcode */ 1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end 4 ULONG last charcode */ 162477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* startId 8 ULONG start glyph ID for the group */ 1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_8 1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_validate( FT_Byte* table, 1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 4; 1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* is32; 1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 length; 1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups; 1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 16 + 8192 > valid->limit ) 1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_ULONG( p ); 1643295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) 1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project is32 = table + 12; 1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = is32 + 8192; /* skip `is32' array */ 1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_groups = TT_NEXT_ULONG( p ); 1649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p + num_groups * 12 > valid->limit ) 1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check groups, they must be in increasing order */ 1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 n, start, end, start_id, count, last = 0; 1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_groups; n++ ) 1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt hi, lo; 1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start > end ) 1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( n > 0 && start <= last ) 1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) 1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = (FT_UInt32)( end - start + 1 ); 1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start & ~0xFFFFU ) 1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start_hi != 0; check that is32[i] is 1 for each i in */ 1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the `hi' and `lo' of the range [start..end] */ 1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count--, start++ ) 1685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hi = (FT_UInt)( start >> 16 ); 1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lo = (FT_UInt)( start & 0xFFFFU ); 1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) 1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) 1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start_hi == 0; check that is32[i] is 0 for each i in */ 1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the range [start..end] */ 1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end_hi cannot be != 0! */ 1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( end & ~0xFFFFU ) 1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count--, start++ ) 1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lo = (FT_UInt)( start & 0xFFFFU ); 1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) 1710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = end; 1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1719a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_char_index( TT_CMap cmap, 1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 8204; 1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups = TT_NEXT_ULONG( p ); 1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start, end, start_id; 1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_groups > 0; num_groups-- ) 1735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code <= end ) 1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = (FT_UInt)( start_id + char_code - start ); 1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1753295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_char_next( TT_CMap cmap, 1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code = *pchar_code + 1; 1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 8204; 1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups = TT_NEXT_ULONG( p ); 1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start, end, start_id; 1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 8208; 1767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_groups > 0; num_groups-- ) 1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code <= end ) 1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( char_code - start + start_id ); 1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = char_code; 1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = result; 1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_get_info( TT_CMap cmap, 1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 8; 1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1801295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 8; 1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1804a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1808a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 1809a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap8_class_rec, 1810a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMapRec ), 1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1812a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap_init, 1813a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 1814a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap8_char_index, 1815a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap8_char_next, 1816a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1817a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1818a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1819a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1820a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1821a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8, 1824a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap8_validate, 1825a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) 1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_8 */ 1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 10 *****/ 1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 10 */ 1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* reserved 2 USHORT reserved */ 1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 4 ULONG length in bytes */ 1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 8 ULONG Mac language code */ 1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start 12 ULONG first char in range */ 1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 16 ULONG number of chars in range */ 1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyphIds 20 USHORT[count] glyph indices covered */ 1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_10 1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_validate( FT_Byte* table, 1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 4; 1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong length, count; 1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 20 > valid->limit ) 1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_ULONG( p ); 1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 16; 1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = TT_NEXT_ULONG( p ); 1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1872295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 1873295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner length < 20 + count * 2 ) 1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices */ 1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count-- ) 1883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) 1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1890a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_char_index( TT_CMap cmap, 1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 12; 1901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start = TT_NEXT_ULONG( p ); 1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 count = TT_NEXT_ULONG( p ); 1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 idx = (FT_ULong)( char_code - start ); 1904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx < count ) 1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = TT_PEEK_USHORT( p ); 1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1915295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_char_next( TT_CMap cmap, 1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code = *pchar_code + 1; 1921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 12; 1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start = TT_NEXT_ULONG( p ); 1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 count = TT_NEXT_ULONG( p ); 1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 idx; 1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (FT_UInt32)( char_code - start ); 1932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; idx < count; idx++ ) 1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 1937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code++; 1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = char_code; 1943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_get_info( TT_CMap cmap, 1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 8; 1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1954295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 10; 1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1957a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1961a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 1962a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap10_class_rec, 1963a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMapRec ), 1964a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 1965a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap_init, 1966a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 1967a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap10_char_index, 1968a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap10_char_next, 1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1970a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1971a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1972a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1973a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1974a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10, 1977a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap10_validate, 1978a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) 1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_10 */ 1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 12 *****/ 1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 1995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 12 */ 1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* reserved 2 USHORT reserved */ 2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 4 ULONG length in bytes */ 2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 8 ULONG Mac language code */ 2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 12 ULONG number of groups */ 2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 16 */ 2004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This header is followed by `count' groups of the following format: */ 2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start 0 ULONG first charcode */ 2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end 4 ULONG last charcode */ 200977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* startId 8 ULONG start glyph ID for the group */ 2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_12 2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_CMap12Rec_ 2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapRec cmap; 2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool valid; 2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong cur_charcode; 2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_gindex; 2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong cur_group; 2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_groups; 2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_CMap12Rec, *TT_CMap12; 2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_init( TT_CMap12 cmap, 2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cmap.data = table; 2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project table += 12; 2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->num_groups = FT_PEEK_ULONG( table ); 2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->valid = 0; 2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2037a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_validate( FT_Byte* table, 2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong length; 2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_groups; 2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 16 > valid->limit ) 2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 4; 2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_ULONG( p ); 2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 12; 2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_groups = TT_NEXT_ULONG( p ); 2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2059295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 2060295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner length < 16 + 12 * num_groups ) 2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check groups, they must be in increasing order */ 2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong n, start, end, start_id, last = 0; 2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_groups; n++ ) 2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 2071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start > end ) 2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( n > 0 && start <= last ) 2078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ) 2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 2084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = end; 2087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2090a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search the index of the charcode next to cmap->cur_charcode */ 2095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* cmap->cur_group should be set up properly by caller */ 2096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 2098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_next( TT_CMap12 cmap ) 2099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 2101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong start, end, start_id, char_code; 2102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong n; 2103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 2104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) 2107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = cmap->cur_charcode + 1; 2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project n = cmap->cur_group; 2112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) 2114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->cmap.data + 16 + 12 * n; 2116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 2117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 2118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_PEEK_ULONG( p ); 2119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 2121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 2122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; char_code <= end; char_code++ ) 2124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( start_id + char_code - start ); 2126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 2128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_charcode = char_code;; 2130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = gindex; 2131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_group = n; 2132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 2134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 2139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->valid = 0; 2140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 2144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_char_map_binary( TT_CMap cmap, 2145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* pchar_code, 2146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool next ) 2147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 2149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 12; 2150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups = TT_PEEK_ULONG( p ); 2151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code = *pchar_code; 2152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start, end, start_id; 2153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min, mid; 2154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !num_groups ) 2157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* make compiler happy */ 2160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = num_groups; 2161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = 0xFFFFFFFFUL; 2162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 2164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code++; 2165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 2167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = num_groups; 2168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 2170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 2171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( min + max ) >> 1; 2173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 16 + 12 * mid; 2174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 2176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 2177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 2180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( char_code > end ) 2181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 2182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_PEEK_ULONG( p ); 2185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = (FT_UInt)( start_id + char_code - start ); 2186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 2192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap12 cmap12 = (TT_CMap12)cmap; 2194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if `char_code' is not in any group, then `mid' is */ 2197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the group nearest to `char_code' */ 2198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code > end ) 2201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid++; 2203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == num_groups ) 2204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->valid = 1; 2208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->cur_charcode = char_code; 2209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->cur_group = mid; 2210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !gindex ) 2212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_next( cmap12 ); 2214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->valid ) 2216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap12->cur_gindex; 2217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->cur_gindex = gindex; 2220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 2222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = cmap12->cur_charcode; 2223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 2226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 2230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_char_index( TT_CMap cmap, 2231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 2232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); 2234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2237295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 2238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_char_next( TT_CMap cmap, 2239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 2240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap12 cmap12 = (TT_CMap12)cmap; 2242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong gindex; 2243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->cur_charcode >= 0xFFFFFFFFUL ) 2246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no need to search */ 2249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) 2250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_next( cmap12 ); 2252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->valid ) 2253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap12->cur_gindex; 2255295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2256295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* XXX: check cur_charcode overflow is expected */ 2257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 2258295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner *pchar_code = (FT_UInt32)cmap12->cur_charcode; 2259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = 0; 2262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); 2265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2266295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* XXX: check gindex overflow is expected */ 2267295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return (FT_UInt32)gindex; 2268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_get_info( TT_CMap cmap, 2273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 2274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 8; 2276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2278295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 12; 2279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2281a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2285a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 2286a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap12_class_rec, 2287a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMap12Rec ), 2288a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 2289a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap12_init, 2290a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 2291a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap12_char_index, 2292a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap12_char_next, 2293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2294a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2295a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2296a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2297a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2298a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 12, 2301a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap12_validate, 2302a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) 2303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_12 */ 2305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2310295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /***** FORMAT 13 *****/ 2311295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /***** *****/ 2312295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2313295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2314295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2315295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2316295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2317295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* TABLE OVERVIEW */ 2318295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* -------------- */ 2319295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2320295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* NAME OFFSET TYPE DESCRIPTION */ 2321295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2322295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* format 0 USHORT must be 13 */ 2323295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* reserved 2 USHORT reserved */ 2324295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* length 4 ULONG length in bytes */ 2325295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* language 8 ULONG Mac language code */ 2326295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* count 12 ULONG number of groups */ 2327295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* 16 */ 2328295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2329295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* This header is followed by `count' groups of the following format: */ 2330295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2331295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* start 0 ULONG first charcode */ 2332295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* end 4 ULONG last charcode */ 2333295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* glyphId 8 ULONG glyph ID for the whole group */ 2334295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2335295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2336295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef TT_CONFIG_CMAP_FORMAT_13 2337295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2338295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner typedef struct TT_CMap13Rec_ 2339295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2340295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMapRec cmap; 2341295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Bool valid; 2342295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong cur_charcode; 2343295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt cur_gindex; 2344295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong cur_group; 2345295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong num_groups; 2346295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2347295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } TT_CMap13Rec, *TT_CMap13; 2348295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2349295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2350295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_Error ) 2351295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_init( TT_CMap13 cmap, 2352295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* table ) 2353295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2354295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cmap.data = table; 2355295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2356295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner table += 12; 2357295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->num_groups = FT_PEEK_ULONG( table ); 2358295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2359295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->valid = 0; 2360295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2361a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2362295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2363295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2364295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2365295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_Error ) 2366295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_validate( FT_Byte* table, 2367295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Validator valid ) 2368295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2369a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Byte* p; 2370a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_ULong length; 2371a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_ULong num_groups; 2372295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2373295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2374295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( table + 16 > valid->limit ) 2375295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_TOO_SHORT; 2376295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2377295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = table + 4; 2378295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner length = TT_NEXT_ULONG( p ); 2379295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2380295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = table + 12; 2381295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner num_groups = TT_NEXT_ULONG( p ); 2382295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2383295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 2384295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner length < 16 + 12 * num_groups ) 2385295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_TOO_SHORT; 2386295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2387295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* check groups, they must be in increasing order */ 2388295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2389295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong n, start, end, glyph_id, last = 0; 2390295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2391295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2392295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner for ( n = 0; n < num_groups; n++ ) 2393295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2394295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner start = TT_NEXT_ULONG( p ); 2395295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = TT_NEXT_ULONG( p ); 2396295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner glyph_id = TT_NEXT_ULONG( p ); 2397295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2398295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( start > end ) 2399295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_DATA; 2400295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2401295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( n > 0 && start <= last ) 2402295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_DATA; 2403295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2404295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( valid->level >= FT_VALIDATE_TIGHT ) 2405295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2406295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) 2407295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_GLYPH_ID; 2408295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2409295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2410295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner last = end; 2411295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2412295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2413295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2414a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2415295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2416295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2417295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2418295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* search the index of the charcode next to cmap->cur_charcode */ 2419295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* cmap->cur_group should be set up properly by caller */ 2420295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2421295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner static void 2422295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_next( TT_CMap13 cmap ) 2423295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2424295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* p; 2425295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong start, end, glyph_id, char_code; 2426295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong n; 2427295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt gindex; 2428295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2429295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2430295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) 2431295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner goto Fail; 2432295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2433295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner char_code = cmap->cur_charcode + 1; 2434295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2435295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner n = cmap->cur_group; 2436295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2437295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) 2438295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2439295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = cmap->cmap.data + 16 + 12 * n; 2440295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner start = TT_NEXT_ULONG( p ); 2441295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = TT_NEXT_ULONG( p ); 2442295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner glyph_id = TT_PEEK_ULONG( p ); 2443295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2444295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code < start ) 2445295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner char_code = start; 2446295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2447295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code <= end ) 2448295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2449295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = (FT_UInt)glyph_id; 2450295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2451295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( gindex ) 2452295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2453295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_charcode = char_code;; 2454295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_gindex = gindex; 2455295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_group = n; 2456295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2457295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return; 2458295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2459295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2460295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2461295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2462295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner Fail: 2463295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->valid = 0; 2464295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2465295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2466295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2467295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner static FT_UInt 2468295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_char_map_binary( TT_CMap cmap, 2469295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32* pchar_code, 2470295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Bool next ) 2471295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2472295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt gindex = 0; 2473295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* p = cmap->data + 12; 2474295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 num_groups = TT_PEEK_ULONG( p ); 2475295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 char_code = *pchar_code; 2476295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 start, end; 2477295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 max, min, mid; 2478295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2479295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2480295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( !num_groups ) 2481295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return 0; 2482295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2483295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* make compiler happy */ 2484295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner mid = num_groups; 2485295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = 0xFFFFFFFFUL; 2486295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2487295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( next ) 2488295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner char_code++; 2489295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2490295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner min = 0; 2491295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner max = num_groups; 2492295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2493295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* binary search */ 2494295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner while ( min < max ) 2495295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2496295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner mid = ( min + max ) >> 1; 2497295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = cmap->data + 16 + 12 * mid; 2498295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2499295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner start = TT_NEXT_ULONG( p ); 2500295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = TT_NEXT_ULONG( p ); 2501295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2502295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code < start ) 2503295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner max = mid; 2504295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else if ( char_code > end ) 2505295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner min = mid + 1; 2506295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2507295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2508295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = (FT_UInt)TT_PEEK_ULONG( p ); 2509295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2510295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner break; 2511295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2512295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2513295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2514295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( next ) 2515295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2516295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMap13 cmap13 = (TT_CMap13)cmap; 2517295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2518295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2519295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* if `char_code' is not in any group, then `mid' is */ 2520295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* the group nearest to `char_code' */ 2521295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2522295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code > end ) 2523295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2524295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner mid++; 2525295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( mid == num_groups ) 2526295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return 0; 2527295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2528295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2529295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->valid = 1; 2530295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->cur_charcode = char_code; 2531295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->cur_group = mid; 2532295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2533295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( !gindex ) 2534295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2535295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_next( cmap13 ); 2536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2537295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->valid ) 2538295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = cmap13->cur_gindex; 2539295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2540295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2541295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->cur_gindex = gindex; 2542295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2543295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( gindex ) 2544295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner *pchar_code = cmap13->cur_charcode; 2545295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2546295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2547295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return gindex; 2548295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2549295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2550295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2551295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt ) 2552295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_char_index( TT_CMap cmap, 2553295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 char_code ) 2554295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2555295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); 2556295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2557295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2558295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2559295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 2560295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_char_next( TT_CMap cmap, 2561295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 *pchar_code ) 2562295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2563295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMap13 cmap13 = (TT_CMap13)cmap; 2564295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt gindex; 2565295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2566295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2567295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->cur_charcode >= 0xFFFFFFFFUL ) 2568295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return 0; 2569295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2570295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* no need to search */ 2571295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) 2572295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2573295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_next( cmap13 ); 2574295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->valid ) 2575295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2576295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = cmap13->cur_gindex; 2577295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( gindex ) 2578295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner *pchar_code = cmap13->cur_charcode; 2579295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2581295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = 0; 2582295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2583295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2584295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); 2585295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2586295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return gindex; 2587295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2588295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2589295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2590295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_Error ) 2591295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_get_info( TT_CMap cmap, 2592295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMapInfo *cmap_info ) 2593295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2594295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* p = cmap->data + 8; 2595295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2596295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2597295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 13; 2598295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2599295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2600a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2601295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2602295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2603295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2604a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 2605a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap13_class_rec, 2606a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMap13Rec ), 2607295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2608a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap13_init, 2609a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) NULL, 2610a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap13_char_index, 2611a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap13_char_next, 2612a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 2613a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2614a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2615a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2616a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2617a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang NULL, 2618295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2619295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 13, 2620a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_ValidateFunc)tt_cmap13_validate, 2621a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) 2622295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2623295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* TT_CONFIG_CMAP_FORMAT_13 */ 2624295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2625295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2626295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2627295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2628295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /***** *****/ 2629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 14 *****/ 2630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 2637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 2638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 2640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 14 */ 2642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 ULONG table length in bytes */ 2643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* numSelector 6 ULONG number of variation sel. records */ 2644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Followed by numSelector records, each of which looks like */ 2646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* varSelector 0 UINT24 Unicode codepoint of sel. */ 2648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* defaultOff 3 ULONG offset to a default UVS table */ 2649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* describing any variants to be found in */ 2650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the normal Unicode subtable. */ 2651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* nonDefOff 7 ULONG offset to a non-default UVS table */ 2652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* describing any variants not in the */ 2653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* standard cmap, with GIDs here */ 2654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* (either offset may be 0 NULL) */ 2655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Selectors are sorted by code point. */ 2657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A default Unicode Variation Selector (UVS) subtable is just a list of */ 2659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ranges of code points which are to be found in the standard cmap. No */ 2660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyph IDs (GIDs) here. */ 2661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* numRanges 0 ULONG number of ranges following */ 2663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A range looks like */ 2665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* uniStart 0 UINT24 code point of the first character in */ 2667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this range */ 2668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* additionalCnt 3 UBYTE count of additional characters in this */ 2669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* range (zero means a range of a single */ 2670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* character) */ 2671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Ranges are sorted by `uniStart'. */ 2673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ 2675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* mappings from codepoint to GID. */ 2676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* numMappings 0 ULONG number of mappings */ 2678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A range looks like */ 2680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* uniStart 0 UINT24 code point of the first character in */ 2682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this range */ 2683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* GID 3 USHORT and its GID */ 2684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Ranges are sorted by `uniStart'. */ 2686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_14 2688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_CMap14Rec_ 2690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapRec cmap; 2692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_selectors; 2693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This array is used to store the results of various 2695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * cmap 14 query functions. The data is overwritten 2696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * on each call to these functions. 2697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 2698295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 max_results; 2699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* results; 2700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory; 2701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_CMap14Rec, *TT_CMap14; 2703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( void ) 2706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_done( TT_CMap14 cmap ) 2707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = cmap->memory; 2709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->max_results = 0; 2712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( memory != NULL && cmap->results != NULL ) 2713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( cmap->results ); 2714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 2718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_ensure( TT_CMap14 cmap, 2719295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 num_results, 2720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 2721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2722a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_UInt32 old_max = cmap->max_results; 2723a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Error error = FT_Err_Ok; 2724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( num_results > cmap->max_results ) 2727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->memory = memory; 2729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) 2731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->max_results = num_results; 2734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_init( TT_CMap14 cmap, 2742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 2743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cmap.data = table; 2745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project table += 6; 2747a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang cmap->num_selectors = FT_PEEK_ULONG( table ); 2748a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang cmap->max_results = 0; 2749a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang cmap->results = NULL; 2750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2751a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_validate( FT_Byte* table, 2757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 2758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 2; 2760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong length = TT_NEXT_ULONG( p ); 2761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_selectors = TT_NEXT_ULONG( p ); 2762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2764295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 2765295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner length < 10 + 11 * num_selectors ) 2766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check selectors, they must be in increasing order */ 2769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we start lastVarSel at 1 because a variant selector value of 0 2771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * isn't valid. 2772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 2773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong n, lastVarSel = 1; 2774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_selectors; n++ ) 2777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong varSel = TT_NEXT_UINT24( p ); 2779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff = TT_NEXT_ULONG( p ); 2780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff = TT_NEXT_ULONG( p ); 2781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff >= length || nondefOff >= length ) 2784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( varSel < lastVarSel ) 2787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lastVarSel = varSel + 1; 2790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check the default table (these glyphs should be reached */ 2792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* through the normal Unicode cmap, no GIDs, just check order) */ 2793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff != 0 ) 2794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* defp = table + defOff; 2796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong numRanges = TT_NEXT_ULONG( defp ); 2797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong i; 2798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong lastBase = 0; 2799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defp + numRanges * 4 > valid->limit ) 2802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = 0; i < numRanges; ++i ) 2805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong base = TT_NEXT_UINT24( defp ); 2807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong cnt = FT_NEXT_BYTE( defp ); 2808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( base + cnt >= 0x110000UL ) /* end of Unicode */ 2811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( base < lastBase ) 2814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lastBase = base + cnt + 1U; 2817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and the non-default table (these glyphs are specified here) */ 2821aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich if ( nondefOff != 0 ) 2822aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich { 2823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* ndp = table + nondefOff; 2824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong numMappings = TT_NEXT_ULONG( ndp ); 2825a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_ULong i, lastUni = 0; 2826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2828295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ) 2829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = 0; i < numMappings; ++i ) 2832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong uni = TT_NEXT_UINT24( ndp ); 2834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong gid = TT_NEXT_USHORT( ndp ); 2835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( uni >= 0x110000UL ) /* end of Unicode */ 2838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( uni < lastUni ) 2841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lastUni = uni + 1U; 2844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT && 2846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gid >= TT_VALID_GLYPH_COUNT( valid ) ) 2847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 2848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2853a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 2858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_index( TT_CMap cmap, 2859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 2860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( cmap ); 2862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( char_code ); 2863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This can't happen */ 2865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2869295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 2870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_next( TT_CMap cmap, 2871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 2872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( cmap ); 2874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This can't happen */ 2876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = 0; 2877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_get_info( TT_CMap cmap, 2883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 2884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( cmap ); 2886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2887295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 14; 2888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* subtable 14 does not define a language field */ 2889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = 0xFFFFFFFFUL; 2890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2891a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 2892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 2896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( FT_Byte *base, 2897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 2898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numRanges = TT_PEEK_ULONG( base ); 2900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min; 2901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 2904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = numRanges; 2905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base += 4; 2907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 2909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 2910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 mid = ( min + max ) >> 1; 2912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = base + 4 * mid; 2913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong start = TT_NEXT_UINT24( p ); 2914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cnt = FT_NEXT_BYTE( p ); 2915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 2918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 2919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( char_code > start+cnt ) 2920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 2921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TRUE; 2923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return FALSE; 2926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 2930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_nondef_binary( FT_Byte *base, 2931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 2932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numMappings = TT_PEEK_ULONG( base ); 2934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min; 2935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 2938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = numMappings; 2939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base += 4; 2941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 2943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 2944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 mid = ( min + max ) >> 1; 2946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = base + 5 * mid; 2947295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); 2948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < uni ) 2951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 2952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( char_code > uni ) 2953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 2954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_PEEK_USHORT( p ); 2956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Byte* 2963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_find_variant( FT_Byte *base, 2964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 variantCode ) 2965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numVar = TT_PEEK_ULONG( base ); 2967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min; 2968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 2971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = numVar; 2972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base += 4; 2974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 2976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 2977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 mid = ( min + max ) >> 1; 2979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = base + 11 * mid; 2980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong varSel = TT_NEXT_UINT24( p ); 2981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( variantCode < varSel ) 2984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 2985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( variantCode > varSel ) 2986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 2987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return p; 2989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 2992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 2996295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap14_char_var_index( TT_CMap cmap, 2997295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMap ucmap, 2998295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 charcode, 2999a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_UInt32 variantSelector ) 3000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); 3002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff; 3003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff; 3004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !p ) 3007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project defOff = TT_NEXT_ULONG( p ); 3010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nondefOff = TT_PEEK_ULONG( p ); 3011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff != 0 && 3013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) 3014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This is the default variant of this charcode. GID not stored */ 3016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* here; stored in the normal Unicode charmap instead. */ 3017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); 3018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nondefOff != 0 ) 3021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode ); 3023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Int ) 3029295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap14_char_var_isdefault( TT_CMap cmap, 3030295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 charcode, 3031295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 variantSelector ) 3032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); 3034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff; 3035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff; 3036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !p ) 3039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return -1; 3040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project defOff = TT_NEXT_ULONG( p ); 3042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nondefOff = TT_NEXT_ULONG( p ); 3043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff != 0 && 3045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) 3046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 1; 3047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nondefOff != 0 && 3049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode ) != 0 ) 3051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return -1; 3054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt32* ) 3058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_variants( TT_CMap cmap, 3059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 3060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14)cmap; 3062295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 count = cmap14->num_selectors; 3063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 10; 3064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* result; 3065295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 i; 3066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) 3069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = cmap14->results; 3072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = 0; i < count; ++i ) 3073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3074295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); 3075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 8; 3076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result[i] = 0; 3078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 3080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt32 * ) 3084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_variants( TT_CMap cmap, 3085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 3086295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 charCode ) 3087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3089295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 count = cmap14->num_selectors; 3090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 10; 3091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* q; 3092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) 3095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( q = cmap14->results; count > 0; --count ) 3098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 varSel = TT_NEXT_UINT24( p ); 3100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff = TT_NEXT_ULONG( p ); 3101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff = TT_NEXT_ULONG( p ); 3102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( defOff != 0 && 3105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( cmap->data + defOff, 3106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charCode ) ) || 3107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ( nondefOff != 0 && 3108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charCode ) != 0 ) ) 3110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = varSel; 3112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q++; 3113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = 0; 3116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return cmap14->results; 3118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 3122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_def_char_count( FT_Byte *p ) 3123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3124295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); 3125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tot = 0; 3126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 312877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner p += 3; /* point to the first `cnt' field */ 3129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; numRanges > 0; numRanges-- ) 3130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tot += 1 + p[0]; 3132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 4; 3133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tot; 3136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt32* 3140a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap14_get_def_chars( TT_CMap cmap, 3141a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Byte* p, 3142a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Memory memory ) 3143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numRanges; 3146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cnt; 3147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* q; 3148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cnt = tt_cmap14_def_char_count( p ); 3151295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); 3152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) 3154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( q = cmap14->results; numRanges > 0; --numRanges ) 3157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3158a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); 3159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cnt = FT_NEXT_BYTE( p ) + 1; 3162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do 3163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = uni; 3165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project uni += 1; 3166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q += 1; 3167a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } while ( --cnt != 0 ); 3169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = 0; 3171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return cmap14->results; 3173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 317677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner static FT_UInt32* 3177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_get_nondef_chars( TT_CMap cmap, 3178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte *p, 3179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 3180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numMappings; 3183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i; 3184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *ret; 3185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3187295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); 3188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) 3190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret = cmap14->results; 3193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = 0; i < numMappings; ++i ) 3194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3195295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); 3196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i] = 0; 3199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ret; 3201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt32 * ) 3205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_variant_chars( TT_CMap cmap, 3206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 3207295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 variantSelector ) 3208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, 3210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project variantSelector ); 3211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *ret; 3212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int i; 3213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff; 3214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff; 3215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !p ) 3218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project defOff = TT_NEXT_ULONG( p ); 3221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nondefOff = TT_NEXT_ULONG( p ); 3222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff == 0 && nondefOff == 0 ) 3224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff == 0 ) 3227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, 3228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( nondefOff == 0 ) 3230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, 3231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Both a default and a non-default glyph set? That's probably not */ 3235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* good font design, but the spec allows for it... */ 3236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numRanges; 3238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numMappings; 3239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 duni; 3240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 dcnt; 3241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 nuni; 3242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* dp; 3243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt di, ni, k; 3244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + nondefOff; 3247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dp = cmap->data + defOff; 3248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3249295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); 3250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = tt_cmap14_def_char_count( dp ); 3251295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); 3252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( numMappings == 0 ) 3254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, 3255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dcnt == 0 ) 3257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, 3258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) 3261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret = cmap14->results; 3264295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = FT_NEXT_BYTE( dp ); 3266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project di = 1; 3267295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner nuni = (FT_UInt32)TT_NEXT_UINT24( p ); 3268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ni = 1; 3270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project i = 0; 3271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ;; ) 3273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nuni > duni + dcnt ) 3275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( k = 0; k <= dcnt; ++k ) 3277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = duni + k; 3278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ++di; 3280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( di > numRanges ) 3282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 3283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3284295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = FT_NEXT_BYTE( dp ); 3286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nuni < duni ) 3290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = nuni; 3291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If it is within the default range then ignore it -- */ 3292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* that should not have happened */ 3293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ++ni; 3294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ni > numMappings ) 3295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 3296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3297295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner nuni = (FT_UInt32)TT_NEXT_UINT24( p ); 3298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ni <= numMappings ) 3303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If we get here then we have run out of all default ranges. */ 3305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* We have read one non-default mapping which we haven't stored */ 3306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and there may be others that need to be read. */ 3307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = nuni; 3308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( ni < numMappings ) 3309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3310295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); 3311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ++ni; 3313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( di <= numRanges ) 3316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If we get here then we have run out of all non-default */ 3318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* mappings. We have read one default range which we haven't */ 3319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stored and there may be others that need to be read. */ 3320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( k = 0; k <= dcnt; ++k ) 3321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = duni + k; 3322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( di < numRanges ) 3324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3325295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = FT_NEXT_BYTE( dp ); 3327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( k = 0; k <= dcnt; ++k ) 3329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = duni + k; 3330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ++di; 3331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i] = 0; 3335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ret; 3337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3341a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_DEFINE_TT_CMAP( 3342a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang tt_cmap14_class_rec, 3343a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMap14Rec ), 3344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3345a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_InitFunc) tt_cmap14_init, 3346a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_DoneFunc) tt_cmap14_done, 3347a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharIndexFunc)tt_cmap14_char_index, 3348a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharNextFunc) tt_cmap14_char_next, 3349a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3350a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /* Format 14 extension functions */ 3351a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, 3352a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, 3353a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_VariantListFunc) tt_cmap14_variants, 3354a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, 3355a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, 3356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 14, 3358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project (TT_CMap_ValidateFunc)tt_cmap14_validate, 3359a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) 3360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 336177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif /* TT_CONFIG_CMAP_FORMAT_14 */ 3362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3364295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_CONFIG_OPTION_PIC 3365295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 3366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const TT_CMap_Class tt_cmap_classes[] = 3367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3368a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define TTCMAPCITEM( a ) &a, 3369295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ttcmapc.h" 3370295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner NULL, 3371295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner }; 3372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3373295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else /*FT_CONFIG_OPTION_PIC*/ 3374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3375a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang void 3376a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Destroy_Class_tt_cmap_classes( FT_Library library, 3377a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang TT_CMap_Class* clazz ) 3378295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 3379a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Memory memory = library->memory; 3380a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3381a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3382295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( clazz ) 3383295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_FREE( clazz ); 3384295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 3385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3386a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3387a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Error 3388a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Create_Class_tt_cmap_classes( FT_Library library, 3389a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang TT_CMap_Class** output_class ) 3390295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 3391a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang TT_CMap_Class* clazz = NULL; 3392a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang TT_CMap_ClassRec* recs; 3393a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Error error; 3394a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Memory memory = library->memory; 3395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3396a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang int i = 0; 3397a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3398a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3399a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define TTCMAPCITEM( a ) i++; 3400295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ttcmapc.h" 3401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3402a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /* allocate enough space for both the pointers */ 3403a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /* plus terminator and the class instances */ 3404a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) + 3405a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( TT_CMap_ClassRec ) * i ) ) 3406295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return error; 3407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3408295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* the location of the class instances follows the array of pointers */ 3409a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang recs = (TT_CMap_ClassRec*)( (char*)clazz + 3410a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang sizeof ( *clazz ) * ( i + 1 ) ); 3411a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang i = 0; 3412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3413295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef TTCMAPCITEM 3414a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#define TTCMAPCITEM( a ) \ 3415a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_Init_Class_ ## a( &recs[i] ); \ 3416a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang clazz[i] = &recs[i]; \ 3417295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner i++; 3418295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ttcmapc.h" 3419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3420295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner clazz[i] = NULL; 3421295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 3422295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner *output_class = clazz; 3423a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 3424295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 3425295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 3426295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /*FT_CONFIG_OPTION_PIC*/ 3427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parse the `cmap' table and build the corresponding TT_CMap objects */ 3430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in the current face */ 3431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 3433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_build_cmaps( TT_Face face ) 3434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = face->cmap_table; 3436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit = table + face->cmap_size; 3437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt volatile num_cmaps; 3438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* volatile p = table; 3439aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Library library = FT_FACE_LIBRARY( face ); 3440aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 3441aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_UNUSED( library ); 3442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3444aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich if ( !p || p + 4 > limit ) 3445a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_THROW( Invalid_Table ); 3446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* only recognize format 0 */ 3448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( TT_NEXT_USHORT( p ) != 0 ) 3449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p -= 2; 3451295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ERROR(( "tt_face_build_cmaps:" 3452295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner " unsupported `cmap' table format = %d\n", 3453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_PEEK_USHORT( p ) )); 3454a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_THROW( Invalid_Table ); 3455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_cmaps = TT_NEXT_USHORT( p ); 3458a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang 3459aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE 3460aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich if ( num_cmaps > FT_MAX_CHARMAP_CACHEABLE ) 3461a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang FT_ERROR(( "tt_face_build_cmaps: too many cmap subtables (%d)\n" 3462a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang " subtable #%d and higher are loaded" 3463a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang " but cannot be searched\n", 3464aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich num_cmaps, FT_MAX_CHARMAP_CACHEABLE + 1 )); 3465aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif 3466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) 3468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CharMapRec charmap; 3470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 offset; 3471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.platform_id = TT_NEXT_USHORT( p ); 3474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.encoding_id = TT_NEXT_USHORT( p ); 3475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.face = FT_FACE( face ); 3476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ 3477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_NEXT_ULONG( p ); 3478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset && offset <= face->cmap_size - 2 ) 3480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* volatile cmap = table + offset; 3482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project volatile FT_UInt format = TT_PEEK_USHORT( cmap ); 3483a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET; 3484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap_Class volatile clazz; 3485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; *pclazz; pclazz++ ) 3488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project clazz = *pclazz; 3490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( clazz->format == format ) 3491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project volatile TT_ValidatorRec valid; 3493a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang volatile FT_Error error = FT_Err_Ok; 3494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, 3497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_VALIDATE_DEFAULT ); 3498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; 3500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3501a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 ) 3502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* validate this cmap sub-table */ 3504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); 3505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid.validator.error == 0 ) 3508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CMap ttcmap; 3510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3512a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /* It might make sense to store the single variation */ 3513a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /* selector cmap somewhere special. But it would have to be */ 3514a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang /* in the public FT_FaceRec, and we can't change that. */ 3515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !FT_CMap_New( (FT_CMap_Class)clazz, 3517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap, &charmap, &ttcmap ) ) 3518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* it is simpler to directly set `flags' than adding */ 3520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* a parameter to FT_CMap_New */ 3521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ((TT_CMap)ttcmap)->flags = (FT_Int)error; 3522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3526295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE0(( "tt_face_build_cmaps:" 3527295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner " broken cmap sub-table ignored\n" )); 3528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 3530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( *pclazz == NULL ) 3534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3535295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE0(( "tt_face_build_cmaps:" 3536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner " unsupported cmap sub-table ignored\n" )); 3537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3541a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang return FT_Err_Ok; 3542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL( FT_Error ) 3546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_get_cmap_info( FT_CharMap charmap, 3547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 3548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CMap cmap = (FT_CMap)charmap; 3550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; 3551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return clazz->get_cmap_info( charmap, cmap_info ); 3554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 3558