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/* */ 7a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin/* Copyright 2002-2017 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 54055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* Too large glyph index return values are caught in `FT_Get_Char_Index' */ 55055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* and `FT_Get_Next_Char' (the latter calls the internal `next' function */ 56055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* again in this case). To mark character code return values as invalid */ 57055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* it is sufficient to set the corresponding glyph index return value to */ 58055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* zero. */ 59055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 60055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap_init( TT_CMap cmap, 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->data = table; 66727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 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 /***** FORMAT 0 *****/ 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 0 */ 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length in bytes */ 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyph_ids 6 BYTE[256] array of glyph indices */ 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 262 */ 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_0 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_validate( FT_Byte* table, 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* p; 999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UInt length; 1009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( table + 2 + 2 > valid->limit ) 1039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_INVALID_TOO_SHORT; 1049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 1059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod p = table + 2; /* skip format */ 1069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod length = TT_NEXT_USHORT( p ); 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit || length < 262 ) 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices whenever necessary */ 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt n, idx; 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 6; 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < 256; n++ ) 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = *p++; 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_char_index( TT_CMap cmap, 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return char_code < 256 ? table[6 + char_code] : 0; 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 141295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_char_next( TT_CMap cmap, 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 charcode = *pchar_code; 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 15177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner table += 6; /* go to glyph IDs */ 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( ++charcode < 256 ) 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = table[charcode]; 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = charcode; 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = result; 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap0_get_info( TT_CMap cmap, 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 174295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 0; 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 177727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 182727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap0_class_rec, 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 184a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMapRec ), 185727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 186a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap_init, /* init */ 187a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 188a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap0_char_index, /* char_index */ 189a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap0_char_next, /* char_next */ 190a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 191a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 192a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 193a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 194a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 195a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 0, 198a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap0_validate, /* validate */ 199a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap0_get_info /* get_cmap_info */ 200a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_0 */ 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 2 *****/ 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** This is used for certain CJK encodings that encode text in a *****/ 211055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** mixed 8/16 bits encoding along the following lines. *****/ 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** * Certain byte values correspond to an 8-bit character code *****/ 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** (typically in the range 0..127 for ASCII compatibility). *****/ 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** * Certain byte values signal the first byte of a 2-byte *****/ 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** character code (but these values are also valid as the *****/ 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** second byte of a 2-byte character). *****/ 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** The following charmap lookup and iteration functions all *****/ 221055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** assume that the value `charcode' fulfills the following. *****/ 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 223055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** - For one byte characters, `charcode' is simply the *****/ 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** character code. *****/ 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 226055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** - For two byte characters, `charcode' is the 2-byte *****/ 227055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** character code in big endian format. More precisely: *****/ 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** (charcode >> 8) is the first byte value *****/ 230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** (charcode & 0xFF) is the second byte value *****/ 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 232055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** Note that not all values of `charcode' are valid according *****/ 233055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** to these rules, and the function moderately checks the *****/ 234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** arguments. *****/ 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 2 */ 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length in bytes */ 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* keys 6 USHORT[256] sub-header keys */ 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* subs 518 SUBHEAD[NSUBS] sub-headers array */ 25177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The `keys' table is used to map charcode high-bytes to sub-headers. */ 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The value of `NSUBS' is the number of sub-headers defined in the */ 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* table and is computed by finding the maximum of the `keys' table. */ 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* table, i.e., it is the corresponding sub-header index multiplied */ 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* by 8. */ 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 261055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* Each sub-header has the following format. */ 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* first 0 USHORT first valid low-byte */ 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 2 USHORT number of valid low-bytes */ 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* delta 4 SHORT see below */ 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* offset 6 USHORT see below */ 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A sub-header defines, for each high-byte, the range of valid */ 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* low-bytes within the charmap. Note that the range defined by `first' */ 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and `count' must be completely included in the interval [0..255] */ 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* according to the specification. */ 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If a character code is contained within a given sub-header, then */ 276055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* mapping it to a glyph index is done as follows. */ 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* * The value of `offset' is read. This is a _byte_ distance from the */ 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* location of the `offset' field itself into a slice of the */ 280055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* `glyph_ids' table. Let's call it `slice' (it is a USHORT[], too). */ 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* * The value `slice[char.lo - first]' is read. If it is 0, there is */ 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no glyph for the charcode. Otherwise, the value of `delta' is */ 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* added to it (modulo 65536) to form a new glyph index. */ 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* It is up to the validation routine to check that all offsets fall */ 28777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* within the glyph IDs table (and not within the `subs' table itself or */ 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* outside of the CMap). */ 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_2 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_validate( FT_Byte* table, 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* p; 2989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UInt length; 2999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt n, max_subs; 3019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* keys; /* keys table */ 3029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* subs; /* sub-headers */ 3039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* glyph_ids; /* glyph ID array */ 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( table + 2 + 2 > valid->limit ) 3079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_INVALID_TOO_SHORT; 3089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 3099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod p = table + 2; /* skip format */ 3109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod length = TT_NEXT_USHORT( p ); 3119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit || length < 6 + 512 ) 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project keys = table + 6; 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parse keys to compute sub-headers count */ 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = keys; 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max_subs = 0; 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < 256; n++ ) 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx = TT_NEXT_USHORT( p ); 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* value must be multiple of 8 */ 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID && ( idx & 7 ) != 0 ) 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx >>= 3; 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx > max_subs ) 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max_subs = idx; 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ASSERT( p == table + 518 ); 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project subs = p; 338055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin glyph_ids = subs + ( max_subs + 1 ) * 8; 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( glyph_ids > valid->limit ) 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parse sub-headers */ 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n <= max_subs; n++ ) 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 345ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt first_code, code_count, offset; 346ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Int delta; 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project first_code = TT_NEXT_USHORT( p ); 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project code_count = TT_NEXT_USHORT( p ); 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_NEXT_SHORT( p ); 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_NEXT_USHORT( p ); 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 35477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* many Dynalab fonts have empty sub-headers */ 35577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( code_count == 0 ) 35677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner continue; 35777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check range within 0..255 */ 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( first_code >= 256 || first_code + code_count > 256 ) 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check offset */ 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0 ) 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 368ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_Byte* ids; 369ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 370ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ids = p - 2 + offset; 372fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( ids < glyph_ids || ids + code_count * 2 > table + length ) 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_OFFSET; 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 37577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check glyph IDs */ 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit = p + code_count * 2; 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx; 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; p < limit; ) 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = TT_NEXT_USHORT( p ); 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 387fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* return sub header corresponding to a given character code */ 401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NULL on invalid charcode */ 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Byte* 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_get_subheader( FT_Byte* table, 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* result = NULL; 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < 0x10000UL ) 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 6; /* keys table */ 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subs = table + 518; /* subheaders table */ 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* sub; 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_hi == 0 ) 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* an 8-bit character code -- we use subHeader 0 in this case */ 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to test whether the character code is in the charmap */ 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sub = subs; /* jump to first sub-header */ 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that the sub-header for this byte is 0, which */ 42677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* indicates that it is really a valid one-byte value */ 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Otherwise, return 0 */ 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += char_lo * 2; 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( TT_PEEK_USHORT( p ) != 0 ) 431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* a 16-bit character code */ 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* jump to key entry */ 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += char_hi * 2; 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* jump to sub-header */ 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project sub = subs + ( FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 8 ) ); 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that the high byte isn't a valid one-byte value */ 443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( sub == subs ) 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = sub; 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 448055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_char_index( TT_CMap cmap, 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subheader; 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project subheader = tt_cmap2_get_subheader( table, char_code ); 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( subheader ) 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = subheader; 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx = (FT_UInt)(char_code & 0xFF); 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start, count; 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt offset; 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_USHORT( p ); 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = TT_NEXT_USHORT( p ); 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_NEXT_SHORT ( p ); 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx -= start; 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx < count && offset != 0 ) 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + 2 * idx; 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = TT_PEEK_USHORT( p ); 483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 485fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki result = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 488055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 493295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_char_next( TT_CMap cmap, 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pcharcode ) 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 charcode = *pcharcode + 1; 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* subheader; 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( charcode < 0x10000UL ) 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project subheader = tt_cmap2_get_subheader( table, charcode ); 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( subheader ) 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = subheader; 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start = TT_NEXT_USHORT( p ); 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt count = TT_NEXT_USHORT( p ); 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta = TT_NEXT_SHORT ( p ); 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt offset = TT_PEEK_USHORT( p ); 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt char_lo = (FT_UInt)( charcode & 0xFF ); 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt pos, idx; 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0 ) 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Next_SubHeader; 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_lo < start ) 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_lo = start; 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos = 0; 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project pos = (FT_UInt)( char_lo - start ); 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + pos * 2; 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = FT_PAD_FLOOR( charcode, 256 ) + char_lo; 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; pos < count; pos++, charcode++ ) 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = TT_NEXT_USHORT( p ); 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 538fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki gindex = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = charcode; 542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Exit; 543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* jump to next sub-header, i.e. higher byte value */ 549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Next_SubHeader: 550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; 551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Exit: 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = result; 555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap2_get_info( TT_CMap cmap, 562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 567295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 2; 568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 570727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 574727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 575727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap2_class_rec, 576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 577a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMapRec ), 578727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 579a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap_init, /* init */ 580a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 581a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap2_char_index, /* char_index */ 582a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap2_char_next, /* char_next */ 583a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 584a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 585a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 586a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 587a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 588a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2, 591a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap2_validate, /* validate */ 592a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap2_get_info /* get_cmap_info */ 593a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_2 */ 596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 4 *****/ 602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 4 */ 614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length */ 615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in bytes */ 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* segCountX2 6 USHORT 2*NUM_SEGS */ 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* searchRange 8 USHORT 2*(1 << LOG_SEGS) */ 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* entrySelector 10 USHORT LOG_SEGS */ 621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* rangeShift 12 USHORT segCountX2 - */ 622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* searchRange */ 623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* endCount 14 USHORT[NUM_SEGS] end charcode for */ 625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each segment; last */ 626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is 0xFFFF */ 627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* pad 14+NUM_SEGS*2 USHORT padding */ 629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* startCount 16+NUM_SEGS*2 USHORT[NUM_SEGS] first charcode for */ 631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each segment */ 632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* idDelta 16+NUM_SEGS*4 SHORT[NUM_SEGS] delta for each */ 634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* segment */ 635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* idOffset 16+NUM_SEGS*6 SHORT[NUM_SEGS] range offset for */ 636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* each segment; can be */ 637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* zero */ 638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 63977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */ 640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ranges */ 641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Character codes are modelled by a series of ordered (increasing) */ 643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* intervals called segments. Each segment has start and end codes, */ 644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* provided by the `startCount' and `endCount' arrays. Segments must */ 64577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* not overlap, and the last segment should always contain the value */ 64677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* 0xFFFF for `endCount'. */ 647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* The fields `searchRange', `entrySelector' and `rangeShift' are better */ 649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ignored (they are traces of over-engineering in the TrueType */ 650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* specification). */ 651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Each segment also has a signed `delta', as well as an optional offset */ 653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* within the `glyphIds' table. */ 654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If a segment's idOffset is 0, the glyph index corresponding to any */ 656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* charcode within the segment is obtained by adding the value of */ 657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* `idDelta' directly to the charcode, modulo 65536. */ 658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 65977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* Otherwise, a glyph index is taken from the glyph IDs sub-array for */ 660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the segment, and the value of `idDelta' is added to it. */ 661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 66377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* Finally, note that a lot of fonts contain an invalid last segment, */ 66477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* where `start' and `end' are correctly set to 0xFFFF but both `delta' */ 66577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */ 66677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* OpenOffice.org). We need special code to deal with them correctly. */ 667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_4 670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_CMap4Rec_ 672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapRec cmap; 674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 cur_charcode; /* current charcode */ 675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_gindex; /* current glyph index */ 676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_ranges; 678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_range; 679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_start; 680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_end; 681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int cur_delta; 682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* cur_values; 683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_CMap4Rec, *TT_CMap4; 685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_init( TT_CMap4 cmap, 689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cmap.data = table; 695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 6; 697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->num_ranges = FT_PEEK_USHORT( p ) >> 1; 698295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; 699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = 0; 700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 701727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Int 706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_set_range( TT_CMap4 cmap, 707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt range_index ) 708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->cmap.data; 710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_ranges = cmap->num_ranges; 712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( range_index < num_ranges ) 715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt offset; 717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 14 + range_index * 2; 720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_end = FT_PEEK_USHORT( p ); 721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_ranges * 2; 723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_start = FT_PEEK_USHORT( p ); 724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_ranges * 2; 726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_delta = FT_PEEK_SHORT( p ); 727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_ranges * 2; 729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = FT_PEEK_USHORT( p ); 730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 73177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts have an incorrect last segment; */ 73277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* we have to catch it */ 73377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( range_index >= num_ranges - 1 && 73477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner cmap->cur_start == 0xFFFFU && 73577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner cmap->cur_end == 0xFFFFU ) 73677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 73777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; 73877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Byte* limit = face->cmap_table + face->cmap_size; 73977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 74077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 74177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( offset && p + offset + 2 > limit ) 74277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 74377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner cmap->cur_delta = 1; 74477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner offset = 0; 74577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 74677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 74777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0xFFFFU ) 749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_values = offset ? p + offset : NULL; 751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_range = range_index; 752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we skip empty segments */ 756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project range_index++; 757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return -1; 760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search the index of the charcode next to cmap->cur_charcode; */ 764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* caller should call tt_cmap4_set_range with proper range */ 765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* before calling this function */ 766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_next( TT_CMap4 cmap ) 769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 770055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; 771055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* limit = face->cmap_table + face->cmap_size; 772055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt charcode; 774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->cur_charcode >= 0xFFFFUL ) 777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 779295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner charcode = (FT_UInt)cmap->cur_charcode + 1; 780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < cmap->cur_start ) 782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = cmap->cur_start; 783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 784055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for (;;) 785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* values = cmap->cur_values; 787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt end = cmap->cur_end; 788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta = cmap->cur_delta; 789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode <= end ) 792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( values ) 794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); 796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 798055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* if p > limit, the whole segment is invalid */ 799055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( p > limit ) 800055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Next_Segment; 801055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do 803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = FT_NEXT_USHORT( p ); 805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 807055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex ) 808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 809fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; 810055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex ) 811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_charcode = charcode; 813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = gindex; 814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } while ( ++charcode <= end ); 818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do 822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 823fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; 824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 826055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->root.num_glyphs ) 827055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 828055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we have an invalid glyph index; if there is an overflow, */ 829055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we can adjust `charcode', otherwise the whole segment is */ 830055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* invalid */ 831055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 832055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 833055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( (FT_Int)charcode + delta < 0 && 834055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin (FT_Int)end + delta >= 0 ) 835055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = (FT_UInt)( -delta ); 836055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 837055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( (FT_Int)charcode + delta < 0x10000L && 838055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin (FT_Int)end + delta >= 0x10000L ) 839055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = (FT_UInt)( 0x10000L - delta ); 840055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 841055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 842055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Next_Segment; 843055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 844055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 845055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex ) 846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_charcode = charcode; 848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = gindex; 849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } while ( ++charcode <= end ); 852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 855055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Next_Segment: 856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we need to find another range */ 857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) 858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < cmap->cur_start ) 861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode = cmap->cur_start; 862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 865295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL; 866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cur_gindex = 0; 867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_validate( FT_Byte* table, 872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 8749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* p; 8759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_UInt length; 8769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; 878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_segs; 879727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( table + 2 + 2 > valid->limit ) 8839c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_INVALID_TOO_SHORT; 8849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 8859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod p = table + 2; /* skip format */ 8869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod length = TT_NEXT_USHORT( p ); 8879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in certain fonts, the `length' field is invalid and goes */ 889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* out of bound. We try to correct this here... */ 890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit ) 891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = (FT_UInt)( valid->limit - table ); 896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 898fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( length < 16 ) 899fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_INVALID_TOO_SHORT; 900fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 6; 902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs = TT_NEXT_USHORT( p ); /* read segCountX2 */ 903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check that we have an even value here */ 907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( num_segs & 1 ) 908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs /= 2; 912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( length < 16 + num_segs * 2 * 4 ) 914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check the search parameters - even though we never use them */ 917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 92077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check the values of `searchRange', `entrySelector', `rangeShift' */ 921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt search_range = TT_NEXT_USHORT( p ); 922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt entry_selector = TT_NEXT_USHORT( p ); 923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt range_shift = TT_NEXT_USHORT( p ); 924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( search_range | range_shift ) & 1 ) /* must be even values */ 927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range /= 2; 930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project range_shift /= 2; 931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* `search range' is the greatest power of 2 that is <= num_segs */ 933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( search_range > num_segs || 935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range * 2 < num_segs || 936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range + range_shift != num_segs || 937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project search_range != ( 1U << entry_selector ) ) 938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ends = table + 14; 942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project starts = table + 16 + num_segs * 2; 943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project deltas = starts + num_segs * 2; 944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offsets = deltas + num_segs * 2; 945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project glyph_ids = offsets + num_segs * 2; 946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 94777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check last segment; its end count value must be 0xFFFF */ 948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_PARANOID ) 949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = ends + ( num_segs - 1 ) * 2; 951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( TT_PEEK_USHORT( p ) != 0xFFFFU ) 952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 95677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt start, end, offset, n; 95777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt last_start = 0, last_end = 0; 95877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Int delta; 959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_start = starts; 960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_end = ends; 961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_delta = deltas; 962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p_offset = offsets; 963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_segs; n++ ) 966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = p_offset; 968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_USHORT( p_start ); 969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_USHORT( p_end ); 970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_NEXT_SHORT( p_delta ); 971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_NEXT_USHORT( p_offset ); 972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start > end ) 974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 97677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* this test should be performed at default validation level; */ 97777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* unfortunately, some popular Asian fonts have overlapping */ 97877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* ranges in their charmaps */ 97977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* */ 980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start <= last_end && n > 0 ) 981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* allow overlapping segments, provided their start points */ 98777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* and end points, respectively, are in ascending order */ 988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( last_start > start || last_end > end ) 990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error |= TT_CMAP_FLAG_UNSORTED; 991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error |= TT_CMAP_FLAG_OVERLAPPING; 993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset && offset != 0xFFFFU ) 997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 99877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner p += offset; /* start of glyph ID array */ 999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* check that we point within the glyph IDs table only */ 1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p < glyph_ids || 1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p + ( end - start + 1 ) * 2 > table + length ) 1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 100777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* Some fonts handle the last segment incorrectly. In */ 100877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* theory, 0xFFFF might point to an ordinary glyph -- */ 100977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* a cmap 4 is versatile and could be used for any */ 101077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* encoding, not only Unicode. However, reality shows */ 101177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* that far too many fonts are sloppy and incorrectly */ 101277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* set all fields but `start' and `end' for the last */ 101377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* segment if it contains only a single character. */ 101477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* */ 101577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* We thus omit the test here, delaying it to the */ 1016055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* routines that actually access the cmap. */ 101777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner else if ( n != num_segs - 1 || 101877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner !( start == 0xFFFFU && end == 0xFFFFU ) ) 1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( p < glyph_ids || 1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p + ( end - start + 1 ) * 2 > valid->limit ) 1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices within the segment range */ 1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, idx; 1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = start; i < end; i++ ) 1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = FT_NEXT_USHORT( p ); 1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx != 0 ) 1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1036fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki idx = (FT_UInt)( (FT_Int)idx + delta ) & 0xFFFFU; 1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx >= TT_VALID_GLYPH_COUNT( valid ) ) 1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( offset == 0xFFFFU ) 1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 104677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts (erroneously?) use a range offset of 0xFFFF */ 1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* to mean missing glyph in cmap table */ 1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 104977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( valid->level >= FT_VALIDATE_PARANOID || 105077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner n != num_segs - 1 || 105177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner !( start == 0xFFFFU && end == 0xFFFFU ) ) 1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_start = start; 1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last_end = end; 1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 106577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner tt_cmap4_char_map_linear( TT_CMap cmap, 106677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt32* pcharcode, 106777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Bool next ) 1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1069055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin TT_Face face = (TT_Face)cmap->cmap.charmap.face; 1070055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* limit = face->cmap_table + face->cmap_size; 1071055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1072055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_segs2, start, end, offset; 1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i, num_segs; 1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 charcode = *pcharcode; 1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 1079055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* q; 1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 6; 1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); 1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs = num_segs2 >> 1; 1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !num_segs ) 1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode++; 1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1093055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( charcode > 0xFFFFU ) 1094055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 1095055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* linear search */ 1097055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin p = cmap->data + 14; /* ends table */ 1098055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin q = cmap->data + 16 + num_segs2; /* starts table */ 1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1100055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for ( i = 0; i < num_segs; i++ ) 1101055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1102055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin end = TT_NEXT_USHORT( p ); 1103055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin start = TT_NEXT_USHORT( q ); 1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1105055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( charcode < start ) 1106055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1107055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next ) 1108055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = start; 1109055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 1110055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1111055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1113055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Again: 1114055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( charcode <= end ) 1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1116055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* r; 1117055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1118055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1119055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin r = q - 2 + num_segs2; 1120055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin delta = TT_PEEK_SHORT( r ); 1121055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin r += num_segs2; 1122055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offset = TT_PEEK_USHORT( r ); 1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1124055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* some fonts have an incorrect last segment; */ 1125055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we have to catch it */ 1126055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( i >= num_segs - 1 && 1127055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin start == 0xFFFFU && end == 0xFFFFU ) 1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1129055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( offset && r + offset + 2 > limit ) 113077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 1131055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin delta = 1; 1132055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin offset = 0; 1133055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1134055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 113577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 1136055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( offset == 0xFFFFU ) 1137055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 113877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 1139055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( offset ) 1140055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1141055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin r += offset + ( charcode - start ) * 2; 114277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 1143055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* if r > limit, the whole segment is invalid */ 1144055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next && r > limit ) 1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project continue; 1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1147055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = TT_PEEK_USHORT( r ); 1148055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex ) 1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1150055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; 1151055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->root.num_glyphs ) 1152055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1154055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1155055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 1156055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1157055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; 1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1159055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) 1160055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1161055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we have an invalid glyph index; if there is an overflow, */ 1162055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we can adjust `charcode', otherwise the whole segment is */ 1163055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* invalid */ 1164055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 1165055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1166055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( (FT_Int)charcode + delta < 0 && 1167055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin (FT_Int)end + delta >= 0 ) 1168055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = (FT_UInt)( -delta ); 1169055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1170055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( (FT_Int)charcode + delta < 0x10000L && 1171055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin (FT_Int)end + delta >= 0x10000L ) 1172055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = (FT_UInt)( 0x10000L - delta ); 1173055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1174055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 1175055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 1176055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1177055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1178055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1179055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next && !gindex ) 1180055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1181055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( charcode >= 0xFFFFU ) 1182055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1183055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1184055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode++; 1185055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Again; 1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1189055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1192055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next ) 1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = charcode; 1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 120077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner tt_cmap4_char_map_binary( TT_CMap cmap, 120177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_UInt32* pcharcode, 120277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner FT_Bool next ) 1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1204055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin TT_Face face = (TT_Face)cmap->cmap.charmap.face; 1205055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* limit = face->cmap_table + face->cmap_size; 1206055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt num_segs2, start, end, offset; 1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int delta; 1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt max, min, mid, num_segs; 1210295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt charcode = (FT_UInt)*pcharcode; 1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 6; 1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 ); 1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !num_segs2 ) 1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_segs = num_segs2 >> 1; 1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* make compiler happy */ 1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = num_segs; 1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = 0xFFFFU; 1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode++; 1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = num_segs; 1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( min + max ) >> 1; 1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + mid * 2; 1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_PEEK_USHORT( p ); 1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < start ) 1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( charcode > end ) 1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 125377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* some fonts have an incorrect last segment; */ 125477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* we have to catch it */ 125577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( mid >= num_segs - 1 && 125677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner start == 0xFFFFU && end == 0xFFFFU ) 125777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 125877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner if ( offset && p + offset + 2 > limit ) 125977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner { 126077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner delta = 1; 126177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner offset = 0; 126277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 126377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 126477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search the first segment containing `charcode' */ 1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING ) 1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i; 1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* call the current segment `max' */ 1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0xFFFFU ) 1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = max + 1; 1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search in segments before the current segment */ 1278055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for ( i = max; i > 0; i-- ) 1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt prev_end; 1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* old_p; 1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project old_p = p; 1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + ( i - 1 ) * 2; 1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project prev_end = TT_PEEK_USHORT( p ); 1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode > prev_end ) 1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = old_p; 1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = prev_end; 1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0xFFFFU ) 1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = i - 1; 1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no luck */ 1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == max + 1 ) 1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( i != max ) 1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + max * 2; 1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_PEEK_USHORT( p ); 1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = max; 1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search in segments after the current segment */ 1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( i = max + 1; i < num_segs; i++ ) 1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt next_end, next_start; 1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + i * 2; 1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_end = TT_PEEK_USHORT( p ); 1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project next_start = TT_PEEK_USHORT( p ); 1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode < next_start ) 1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = next_end; 1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = next_start; 1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset != 0xFFFFU ) 1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = i; 1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project i--; 1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* still no luck */ 1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == max ) 1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = i; 1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end, start, delta, and offset are for the i'th segment */ 1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid != i ) 1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 14 + mid * 2; 1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_PEEK_USHORT( p ); 1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 + num_segs2; 1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_PEEK_USHORT( p ); 1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta = TT_PEEK_SHORT( p ); 1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += num_segs2; 1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_PEEK_USHORT( p ); 1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset == 0xFFFFU ) 1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset ) 1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += offset + ( charcode - start ) * 2; 1380055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1381055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* if p > limit, the whole segment is invalid */ 1382055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next && p > limit ) 1383055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1384055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_PEEK_USHORT( p ); 1386055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex ) 1387055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1388fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; 1389055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->root.num_glyphs ) 1390055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 1391055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1394055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1395fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; 1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1397055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) 1398055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1399055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we have an invalid glyph index; if there is an overflow, */ 1400055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* we can adjust `charcode', otherwise the whole segment is */ 1401055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* invalid */ 1402055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 1403055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1404055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( (FT_Int)charcode + delta < 0 && 1405055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin (FT_Int)end + delta >= 0 ) 1406055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = (FT_UInt)( -delta ); 1407055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1408055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( (FT_Int)charcode + delta < 0x10000L && 1409055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin (FT_Int)end + delta >= 0x10000L ) 1410055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin charcode = (FT_UInt)( 0x10000L - delta ); 1411055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1412055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1413055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap4 cmap4 = (TT_CMap4)cmap; 1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if `charcode' is not in any segment, then `mid' is */ 1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the segment nearest to `charcode' */ 1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( charcode > end ) 1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid++; 1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == num_segs ) 1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap4_set_range( cmap4, mid ) ) 1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = charcode; 1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap4->cur_charcode = charcode; 1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap4->cur_gindex = gindex; 1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap4->cur_charcode = charcode; 1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_next( cmap4 ); 1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap4->cur_gindex; 1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pcharcode = cmap4->cur_charcode; 1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_char_index( TT_CMap cmap, 1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code >= 0x10000UL ) 1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) 1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap4_char_map_linear( cmap, &char_code, 0 ); 1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap4_char_map_binary( cmap, &char_code, 0 ); 1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1474295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_char_next( TT_CMap cmap, 1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( *pchar_code >= 0xFFFFU ) 1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->flags & TT_CMAP_FLAG_UNSORTED ) 1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 ); 1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap4 cmap4 = (TT_CMap4)cmap; 1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no need to search */ 1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( *pchar_code == cmap4->cur_charcode ) 1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_next( cmap4 ); 1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap4->cur_gindex; 1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex ) 1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = cmap4->cur_charcode; 1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 ); 1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap4_get_info( TT_CMap cmap, 1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1514295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 4; 1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 1522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap4_class_rec, 1523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1524a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMap4Rec ), 1525a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1526a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap4_init, /* init */ 1527a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 1528a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap4_char_index, /* char_index */ 1529a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap4_char_next, /* char_next */ 1530a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1531a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 1532a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 1533a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 1534a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 1535a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 4, 1538a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap4_validate, /* validate */ 1539a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap4_get_info /* get_cmap_info */ 1540a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_4 */ 1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 6 *****/ 1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1560055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* format 0 USHORT must be 6 */ 1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 USHORT table length in bytes */ 1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 4 USHORT Mac language code */ 1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* first 6 USHORT first segment code */ 1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 8 USHORT segment size in chars */ 156677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* glyphIds 10 USHORT[count] glyph IDs */ 1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A very simplified segment mapping. */ 1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_6 1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_validate( FT_Byte* table, 1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt length, count; 1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 10 > valid->limit ) 1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 2; 1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_USHORT( p ); 1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 8; /* skip language and start index */ 1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = TT_NEXT_USHORT( p ); 1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + length > valid->limit || length < 10 + count * 2 ) 1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices */ 1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count-- ) 1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) 1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1607727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_char_index( TT_CMap cmap, 1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 6; 1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start = TT_NEXT_USHORT( p ); 1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt count = TT_NEXT_USHORT( p ); 1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx = (FT_UInt)( char_code - start ); 1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx < count ) 1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = TT_PEEK_USHORT( p ); 1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1628055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1633295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_char_next( TT_CMap cmap, 1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code = *pchar_code + 1; 1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 6; 1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt start = TT_NEXT_USHORT( p ); 1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt count = TT_NEXT_USHORT( p ); 1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt idx; 1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code >= 0x10000UL ) 1649055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project idx = (FT_UInt)( char_code - start ); 1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; idx < count; idx++ ) 1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = char_code; 1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1665055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1666055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code >= 0xFFFFU ) 1667055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 1668055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code++; 1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = result; 1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap6_get_info( TT_CMap cmap, 1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 4; 1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1684295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 6; 1685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_USHORT( p ); 1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1687727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1691727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 1692727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap6_class_rec, 1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1694a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMapRec ), 1695727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1696a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap_init, /* init */ 1697a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 1698a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap6_char_index, /* char_index */ 1699a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap6_char_next, /* char_next */ 1700a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1701a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 1702a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 1703a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 1704a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 1705a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 6, 1708a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap6_validate, /* validate */ 1709a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap6_get_info /* get_cmap_info */ 1710a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 1711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_6 */ 1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 8 *****/ 1719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 172077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /***** It is hard to completely understand what the OpenType spec *****/ 1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** says about this format, but here is my conclusion. *****/ 1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** The purpose of this format is to easily map UTF-16 text to *****/ 1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** glyph indices. Basically, the `char_code' must be in one of *****/ 1725055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** the following formats. *****/ 1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** - A 16-bit value that isn't part of the Unicode Surrogates *****/ 1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** Area (i.e. U+D800-U+DFFF). *****/ 1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** - A 32-bit value, made of two surrogate values, i.e.. if *****/ 1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** `char_code = (char_hi << 16) | char_lo', then both *****/ 1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** `char_hi' and `char_lo' must be in the Surrogates Area. *****/ 1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** Area. *****/ 1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 173577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /***** The `is32' table embedded in the charmap indicates whether a *****/ 1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** given 16-bit value is in the surrogates area or not. *****/ 1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1738055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /***** So, for any given `char_code', we can assert the following. *****/ 1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** If `char_hi == 0' then we must have `is32[char_lo] == 0'. *****/ 1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** If `char_hi != 0' then we must have both *****/ 1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** `is32[char_hi] != 0' and `is32[char_lo] != 0'. *****/ 1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 8 */ 1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* reserved 2 USHORT reserved */ 1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 4 ULONG length in bytes */ 1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 8 ULONG Mac language code */ 1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* is32 12 BYTE[8192] 32-bitness bitmap */ 1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 8204 ULONG number of groups */ 1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 176277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* This header is followed by `count' groups of the following format: */ 1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start 0 ULONG first charcode */ 1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end 4 ULONG last charcode */ 176677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* startId 8 ULONG start glyph ID for the group */ 1767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_8 1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_validate( FT_Byte* table, 1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 4; 1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* is32; 1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 length; 1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups; 1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 16 + 8192 > valid->limit ) 1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_ULONG( p ); 1785295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_UInt32)( valid->limit - table ) || length < 8192 + 16 ) 1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project is32 = table + 12; 1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = is32 + 8192; /* skip `is32' array */ 1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_groups = TT_NEXT_ULONG( p ); 1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1792fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* p + num_groups * 12 > valid->limit ? */ 1793fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( num_groups > (FT_UInt32)( valid->limit - p ) / 12 ) 1794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check groups, they must be in increasing order */ 1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 n, start, end, start_id, count, last = 0; 1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_groups; n++ ) 1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt hi, lo; 1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 1809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start > end ) 1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( n > 0 && start <= last ) 1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1818fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt32 d = end - start; 1819fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1820fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 1821fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ 1822fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( d > TT_VALID_GLYPH_COUNT( valid ) || 1823fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) 1824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = (FT_UInt32)( end - start + 1 ); 1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start & ~0xFFFFU ) 1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start_hi != 0; check that is32[i] is 1 for each i in */ 1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the `hi' and `lo' of the range [start..end] */ 1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count--, start++ ) 1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project hi = (FT_UInt)( start >> 16 ); 1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lo = (FT_UInt)( start & 0xFFFFU ); 1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( (is32[hi >> 3] & ( 0x80 >> ( hi & 7 ) ) ) == 0 ) 1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) == 0 ) 1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start_hi == 0; check that is32[i] is 0 for each i in */ 1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the range [start..end] */ 1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end_hi cannot be != 0! */ 1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( end & ~0xFFFFU ) 1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count--, start++ ) 1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lo = (FT_UInt)( start & 0xFFFFU ); 1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( (is32[lo >> 3] & ( 0x80 >> ( lo & 7 ) ) ) != 0 ) 1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = end; 1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1867727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_char_index( TT_CMap cmap, 1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 8204; 1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups = TT_NEXT_ULONG( p ); 1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start, end, start_id; 1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_groups > 0; num_groups-- ) 1883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code <= end ) 1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1893055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 1894055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 1895055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1896055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin result = (FT_UInt)( start_id + ( char_code - start ) ); 1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 1901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1904295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_char_next( TT_CMap cmap, 1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1908055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Face face = cmap->cmap.charmap.face; 1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 result = 0; 1910055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UInt32 char_code; 1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 8204; 1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups = TT_NEXT_ULONG( p ); 1915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start, end, start_id; 1916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1918055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( *pchar_code >= 0xFFFFFFFFUL ) 1919055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 1920055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1921055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char_code = *pchar_code + 1; 1922055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 8208; 1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_groups > 0; num_groups-- ) 1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 1932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1934055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Again: 1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code <= end ) 1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1937055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* ignore invalid group */ 1938055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 1939055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 1940055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1941055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = (FT_UInt)( start_id + ( char_code - start ) ); 1942055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1943055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* does first element of group point to `.notdef' glyph? */ 1944055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex == 0 ) 1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1946055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code >= 0xFFFFFFFFUL ) 1947055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1948055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1949055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char_code++; 1950055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Again; 1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1952055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1953055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* if `gindex' is invalid, the remaining values */ 1954055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* in this group are invalid, too */ 1955055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->num_glyphs ) 1956055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 1957055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 1958055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 1959055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 1960055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 1961055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin result = char_code; 1962055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin break; 1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = result; 1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap8_get_info( TT_CMap cmap, 1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 8; 1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1978295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 8; 1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1981727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1985727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 1986727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap8_class_rec, 1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 1988a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMapRec ), 1989727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1990a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap_init, /* init */ 1991a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 1992a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap8_char_index, /* char_index */ 1993a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap8_char_next, /* char_next */ 1994a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 1995a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 1996a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 1997a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 1998a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 1999a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8, 2002a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap8_validate, /* validate */ 2003a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap8_get_info /* get_cmap_info */ 2004a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_8 */ 2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 10 *****/ 2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 10 */ 2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* reserved 2 USHORT reserved */ 2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 4 ULONG length in bytes */ 2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 8 ULONG Mac language code */ 2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start 12 ULONG first char in range */ 2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 16 ULONG number of chars in range */ 2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyphIds 20 USHORT[count] glyph indices covered */ 2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_10 2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_validate( FT_Byte* table, 2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 4; 2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong length, count; 2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 20 > valid->limit ) 2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_ULONG( p ); 2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 16; 2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project count = TT_NEXT_ULONG( p ); 2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2051295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 2052fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* length < 20 + count * 2 ? */ 2053fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki length < 20 || 2054fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ( length - 20 ) / 2 < count ) 2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check glyph indices */ 2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 2059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; count > 0; count-- ) 2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex >= TT_VALID_GLYPH_COUNT( valid ) ) 2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2071727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_char_index( TT_CMap cmap, 2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 2078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt result = 0; 2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 12; 2082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start = TT_NEXT_ULONG( p ); 2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 count = TT_NEXT_ULONG( p ); 2084055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UInt32 idx; 2085055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2086055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2087055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code < start ) 2088055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 2089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2090055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin idx = char_code - start; 2091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( idx < count ) 2093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 2095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = TT_PEEK_USHORT( p ); 2096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2097055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 2099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2102295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 2103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_char_next( TT_CMap cmap, 2104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 2105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = cmap->data; 2107055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UInt32 char_code; 2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = table + 12; 2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start = TT_NEXT_ULONG( p ); 2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 count = TT_NEXT_ULONG( p ); 2112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 idx; 2113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2115055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( *pchar_code >= 0xFFFFFFFFUL ) 2116055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 2117055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2118055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char_code = *pchar_code + 1; 2119055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 2121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 2122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2123055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin idx = char_code - start; 2124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2 * idx; 2125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; idx < count; idx++ ) 2127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = TT_NEXT_USHORT( p ); 2129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( gindex != 0 ) 2130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2131055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2132055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code >= 0xFFFFFFFFUL ) 2133055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 2134055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code++; 2136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = char_code; 2139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 2140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap10_get_info( TT_CMap cmap, 2145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 2146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 8; 2148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2150295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 10; 2151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2153727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 2158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap10_class_rec, 2159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 2160a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMapRec ), 2161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2162a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap_init, /* init */ 2163a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 2164a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap10_char_index, /* char_index */ 2165a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap10_char_next, /* char_next */ 2166a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2167a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 2168a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 2169a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 2170a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 2171a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 2172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 10, 2174a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap10_validate, /* validate */ 2175a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap10_get_info /* get_cmap_info */ 2176a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 2177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_10 */ 2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 12 *****/ 2185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 2192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 2193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 2195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 12 */ 2197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* reserved 2 USHORT reserved */ 2198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 4 ULONG length in bytes */ 2199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* language 8 ULONG Mac language code */ 2200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* count 12 ULONG number of groups */ 2201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* 16 */ 2202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This header is followed by `count' groups of the following format: */ 2204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* start 0 ULONG first charcode */ 2206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* end 4 ULONG last charcode */ 220777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /* startId 8 ULONG start glyph ID for the group */ 2208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_12 2211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_CMap12Rec_ 2213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapRec cmap; 2215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool valid; 2216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong cur_charcode; 2217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cur_gindex; 2218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong cur_group; 2219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_groups; 2220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_CMap12Rec, *TT_CMap12; 2222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_init( TT_CMap12 cmap, 2226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 2227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cmap.data = table; 2229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project table += 12; 2231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->num_groups = FT_PEEK_ULONG( table ); 2232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->valid = 0; 2234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_validate( FT_Byte* table, 2241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 2242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 22439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* p; 22449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_ULong length; 22459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_ULong num_groups; 2246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( table + 16 > valid->limit ) 2249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 4; 2252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project length = TT_NEXT_ULONG( p ); 2253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = table + 12; 2255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_groups = TT_NEXT_ULONG( p ); 2256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2257295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 2258fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* length < 16 + 12 * num_groups ? */ 2259fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki length < 16 || 2260fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ( length - 16 ) / 12 < num_groups ) 2261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 2262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check groups, they must be in increasing order */ 2264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong n, start, end, start_id, last = 0; 2266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_groups; n++ ) 2269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 2271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 2272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_NEXT_ULONG( p ); 2273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( start > end ) 2275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( n > 0 && start <= last ) 2278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 2279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT ) 2281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2282fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki FT_UInt32 d = end - start; 2283fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2284fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki 2285fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* start_id + end - start >= TT_VALID_GLYPH_COUNT( valid ) ? */ 2286fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( d > TT_VALID_GLYPH_COUNT( valid ) || 2287fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki start_id >= TT_VALID_GLYPH_COUNT( valid ) - d ) 2288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 2289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project last = end; 2292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2295727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* search the index of the charcode next to cmap->cur_charcode */ 2300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* cmap->cur_group should be set up properly by caller */ 2301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 2303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_next( TT_CMap12 cmap ) 2304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2305055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Face face = cmap->cmap.cmap.charmap.face; 2306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p; 2307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong start, end, start_id, char_code; 2308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong n; 2309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex; 2310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) 2313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project goto Fail; 2314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = cmap->cur_charcode + 1; 2316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) 2318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->cmap.data + 16 + 12 * n; 2320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 2321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 2322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_PEEK_ULONG( p ); 2323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 2325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code = start; 2326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2327055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin Again: 2328055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code <= end ) 2329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2330055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* ignore invalid group */ 2331055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 2332055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 2333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2334055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = (FT_UInt)( start_id + ( char_code - start ) ); 2335055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2336055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* does first element of group point to `.notdef' glyph? */ 2337055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex == 0 ) 2338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2339055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code >= 0xFFFFFFFFUL ) 2340055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Fail; 2341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2342055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin char_code++; 2343055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin goto Again; 2344055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 2345055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2346055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* if `gindex' is invalid, the remaining values */ 2347055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* in this group are invalid, too */ 2348055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->num_glyphs ) 2349055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 2350055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 2351055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin continue; 2352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2353055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2354055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin cmap->cur_charcode = char_code; 2355055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin cmap->cur_gindex = gindex; 2356055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin cmap->cur_group = n; 2357055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2358055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return; 2359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Fail: 2363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->valid = 0; 2364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 2368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_char_map_binary( TT_CMap cmap, 2369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* pchar_code, 2370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Bool next ) 2371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt gindex = 0; 2373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 12; 2374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 num_groups = TT_PEEK_ULONG( p ); 2375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code = *pchar_code; 2376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 start, end, start_id; 2377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min, mid; 2378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !num_groups ) 2381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* make compiler happy */ 2384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = num_groups; 2385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = 0xFFFFFFFFUL; 2386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 2388055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 2389055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code >= 0xFFFFFFFFUL ) 2390055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 2391055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project char_code++; 2393055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 2394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 2396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = num_groups; 2397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 2399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 2400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid = ( min + max ) >> 1; 2402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + 16 + 12 * mid; 2403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start = TT_NEXT_ULONG( p ); 2405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project end = TT_NEXT_ULONG( p ); 2406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 2408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 2409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( char_code > end ) 2410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 2411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project start_id = TT_PEEK_ULONG( p ); 2414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2415055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* reject invalid glyph index */ 2416055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( start_id > 0xFFFFFFFFUL - ( char_code - start ) ) 2417055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 2418055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else 2419055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = (FT_UInt)( start_id + ( char_code - start ) ); 2420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 2421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( next ) 2425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2426055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Face face = cmap->cmap.charmap.face; 2427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap12 cmap12 = (TT_CMap12)cmap; 2428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* if `char_code' is not in any group, then `mid' is */ 2431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the group nearest to `char_code' */ 2432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code > end ) 2434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project mid++; 2436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( mid == num_groups ) 2437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 2438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->valid = 1; 2441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->cur_charcode = char_code; 2442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->cur_group = mid; 2443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2444055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->num_glyphs ) 2445055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 2446055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !gindex ) 2448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_next( cmap12 ); 2450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->valid ) 2452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = cmap12->cur_gindex; 2453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap12->cur_gindex = gindex; 2456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2457055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin *pchar_code = cmap12->cur_charcode; 2458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return gindex; 2461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 2465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_char_index( TT_CMap cmap, 2466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 2467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap12_char_map_binary( cmap, &char_code, 0 ); 2469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2472295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 2473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_char_next( TT_CMap cmap, 2474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 2475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap12 cmap12 = (TT_CMap12)cmap; 2477055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_UInt gindex; 2478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* no need to search */ 2481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->valid && cmap12->cur_charcode == *pchar_code ) 2482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_next( cmap12 ); 2484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( cmap12->valid ) 2485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2486055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = cmap12->cur_gindex; 2487055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin *pchar_code = (FT_UInt32)cmap12->cur_charcode; 2488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = 0; 2491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 2493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 ); 2494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2495055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return gindex; 2496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap12_get_info( TT_CMap cmap, 2501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 2502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 8; 2504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2506295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 12; 2507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 2514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap12_class_rec, 2515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 2516a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMap12Rec ), 2517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2518a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap12_init, /* init */ 2519a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 2520a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap12_char_index, /* char_index */ 2521a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap12_char_next, /* char_next */ 2522a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2523a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 2524a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 2525a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 2526a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 2527a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 2528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 12, 2530a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap12_validate, /* validate */ 2531a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap12_get_info /* get_cmap_info */ 2532a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 2533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_CMAP_FORMAT_12 */ 2535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2540295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /***** FORMAT 13 *****/ 2541295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /***** *****/ 2542295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2543295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2544295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2545295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2546295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2547295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* TABLE OVERVIEW */ 2548295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* -------------- */ 2549295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2550295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* NAME OFFSET TYPE DESCRIPTION */ 2551295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2552295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* format 0 USHORT must be 13 */ 2553295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* reserved 2 USHORT reserved */ 2554295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* length 4 ULONG length in bytes */ 2555295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* language 8 ULONG Mac language code */ 2556295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* count 12 ULONG number of groups */ 2557295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* 16 */ 2558295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2559295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* This header is followed by `count' groups of the following format: */ 2560295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2561295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* start 0 ULONG first charcode */ 2562295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* end 4 ULONG last charcode */ 2563295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* glyphId 8 ULONG glyph ID for the whole group */ 2564295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2565295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2566295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef TT_CONFIG_CMAP_FORMAT_13 2567295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2568295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner typedef struct TT_CMap13Rec_ 2569295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2570295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMapRec cmap; 2571295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Bool valid; 2572295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong cur_charcode; 2573295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt cur_gindex; 2574295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong cur_group; 2575295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong num_groups; 2576295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2577295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } TT_CMap13Rec, *TT_CMap13; 2578295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2579295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_Error ) 2581295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_init( TT_CMap13 cmap, 2582295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* table ) 2583295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2584295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cmap.data = table; 2585295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2586295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner table += 12; 2587295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->num_groups = FT_PEEK_ULONG( table ); 2588295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2589295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->valid = 0; 2590295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2591727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2592295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2593295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2594295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2595295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_Error ) 2596295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_validate( FT_Byte* table, 2597295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Validator valid ) 2598295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2599727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p; 2600727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong length; 2601727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_ULong num_groups; 2602295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2603295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2604295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( table + 16 > valid->limit ) 2605295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_TOO_SHORT; 2606295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2607295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = table + 4; 2608295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner length = TT_NEXT_ULONG( p ); 2609295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2610295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = table + 12; 2611295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner num_groups = TT_NEXT_ULONG( p ); 2612295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2613295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 2614fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* length < 16 + 12 * num_groups ? */ 2615fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki length < 16 || 2616fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ( length - 16 ) / 12 < num_groups ) 2617295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_TOO_SHORT; 2618295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2619295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* check groups, they must be in increasing order */ 2620295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2621295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong n, start, end, glyph_id, last = 0; 2622295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2623295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2624295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner for ( n = 0; n < num_groups; n++ ) 2625295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2626295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner start = TT_NEXT_ULONG( p ); 2627295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = TT_NEXT_ULONG( p ); 2628295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner glyph_id = TT_NEXT_ULONG( p ); 2629295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2630295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( start > end ) 2631295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_DATA; 2632295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2633295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( n > 0 && start <= last ) 2634295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_DATA; 2635295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2636295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( valid->level >= FT_VALIDATE_TIGHT ) 2637295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2638295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( glyph_id >= TT_VALID_GLYPH_COUNT( valid ) ) 2639295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_INVALID_GLYPH_ID; 2640295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2641295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2642295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner last = end; 2643295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2644295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2645295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2646727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2647295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2648295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2649295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2650295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* search the index of the charcode next to cmap->cur_charcode */ 2651295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* cmap->cur_group should be set up properly by caller */ 2652295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* */ 2653295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner static void 2654295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_next( TT_CMap13 cmap ) 2655295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2656055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Face face = cmap->cmap.cmap.charmap.face; 2657295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* p; 2658295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong start, end, glyph_id, char_code; 2659295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ULong n; 2660295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt gindex; 2661295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2662295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2663295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap->cur_charcode >= 0xFFFFFFFFUL ) 2664295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner goto Fail; 2665295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2666295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner char_code = cmap->cur_charcode + 1; 2667295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2668295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner for ( n = cmap->cur_group; n < cmap->num_groups; n++ ) 2669295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2670295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = cmap->cmap.data + 16 + 12 * n; 2671295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner start = TT_NEXT_ULONG( p ); 2672295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = TT_NEXT_ULONG( p ); 2673295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner glyph_id = TT_PEEK_ULONG( p ); 2674295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2675295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code < start ) 2676295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner char_code = start; 2677295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2678295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code <= end ) 2679295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2680295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = (FT_UInt)glyph_id; 2681295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2682055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex && gindex < (FT_UInt)face->num_glyphs ) 2683295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2684055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin cmap->cur_charcode = char_code; 2685295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_gindex = gindex; 2686295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->cur_group = n; 2687295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2688295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return; 2689295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2690295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2691295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2692295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2693295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner Fail: 2694295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap->valid = 0; 2695295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2696295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2697295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2698295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner static FT_UInt 2699295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_char_map_binary( TT_CMap cmap, 2700295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32* pchar_code, 2701295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Bool next ) 2702295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2703295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt gindex = 0; 2704295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* p = cmap->data + 12; 2705295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 num_groups = TT_PEEK_ULONG( p ); 2706295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 char_code = *pchar_code; 2707295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 start, end; 2708295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 max, min, mid; 2709295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2710295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2711295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( !num_groups ) 2712295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return 0; 2713295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2714295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* make compiler happy */ 2715295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner mid = num_groups; 2716295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = 0xFFFFFFFFUL; 2717295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2718295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( next ) 2719055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin { 2720055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( char_code >= 0xFFFFFFFFUL ) 2721055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin return 0; 2722055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2723295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner char_code++; 2724055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin } 2725295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2726295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner min = 0; 2727295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner max = num_groups; 2728295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2729295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* binary search */ 2730295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner while ( min < max ) 2731295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2732295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner mid = ( min + max ) >> 1; 2733295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner p = cmap->data + 16 + 12 * mid; 2734295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2735295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner start = TT_NEXT_ULONG( p ); 2736295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner end = TT_NEXT_ULONG( p ); 2737295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2738295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code < start ) 2739295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner max = mid; 2740295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else if ( char_code > end ) 2741295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner min = mid + 1; 2742295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2743295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2744295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = (FT_UInt)TT_PEEK_ULONG( p ); 2745295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2746295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner break; 2747295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2748295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2749295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2750295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( next ) 2751295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2752055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Face face = cmap->cmap.charmap.face; 2753295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMap13 cmap13 = (TT_CMap13)cmap; 2754295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2755295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2756295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* if `char_code' is not in any group, then `mid' is */ 2757295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* the group nearest to `char_code' */ 2758295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2759295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( char_code > end ) 2760295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2761295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner mid++; 2762295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( mid == num_groups ) 2763295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return 0; 2764295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2765295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2766295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->valid = 1; 2767295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->cur_charcode = char_code; 2768295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->cur_group = mid; 2769295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2770055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( gindex >= (FT_UInt)face->num_glyphs ) 2771055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = 0; 2772055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 2773295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( !gindex ) 2774295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2775295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_next( cmap13 ); 2776295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2777295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->valid ) 2778295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = cmap13->cur_gindex; 2779295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2780295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2781295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap13->cur_gindex = gindex; 2782295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2783055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin *pchar_code = cmap13->cur_charcode; 2784295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2785295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2786295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return gindex; 2787295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2788295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2789295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2790295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt ) 2791295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_char_index( TT_CMap cmap, 2792295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 char_code ) 2793295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2794295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return tt_cmap13_char_map_binary( cmap, &char_code, 0 ); 2795295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2796295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2797295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2798295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 2799295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_char_next( TT_CMap cmap, 2800295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 *pchar_code ) 2801295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2802295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMap13 cmap13 = (TT_CMap13)cmap; 2803295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt gindex; 2804295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2805295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2806295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* no need to search */ 2807295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->valid && cmap13->cur_charcode == *pchar_code ) 2808295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2809295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_next( cmap13 ); 2810295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( cmap13->valid ) 2811295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2812055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin gindex = cmap13->cur_gindex; 2813055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin *pchar_code = cmap13->cur_charcode; 2814295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2815295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2816295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = 0; 2817295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2818295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner else 2819295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 ); 2820295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2821295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return gindex; 2822295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2823295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2824295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2825295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_Error ) 2826295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap13_get_info( TT_CMap cmap, 2827295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMapInfo *cmap_info ) 2828295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 2829295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_Byte* p = cmap->data + 8; 2830295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2831295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2832295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 13; 2833295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->language = (FT_ULong)TT_PEEK_ULONG( p ); 2834295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2835727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2836295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 2837295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2838295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2839727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 2840727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap13_class_rec, 2841295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2842a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMap13Rec ), 2843727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 2844a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap13_init, /* init */ 2845a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) NULL, /* done */ 2846a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap13_char_index, /* char_index */ 2847a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap13_char_next, /* char_next */ 2848a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 2849a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ 2850a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ 2851a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) NULL, /* variant_list */ 2852a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ 2853a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 2854295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2855295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 13, 2856a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap13_validate, /* validate */ 2857a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap13_get_info /* get_cmap_info */ 2858a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 2859295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2860295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* TT_CONFIG_CMAP_FORMAT_13 */ 2861295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2862295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 2863295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2864295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /*************************************************************************/ 2865295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /***** *****/ 2866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** FORMAT 14 *****/ 2867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /***** *****/ 2868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /*************************************************************************/ 2872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* TABLE OVERVIEW */ 2874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* -------------- */ 2875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* NAME OFFSET TYPE DESCRIPTION */ 2877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* format 0 USHORT must be 14 */ 2879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* length 2 ULONG table length in bytes */ 2880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* numSelector 6 ULONG number of variation sel. records */ 2881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Followed by numSelector records, each of which looks like */ 2883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* varSelector 0 UINT24 Unicode codepoint of sel. */ 2885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* defaultOff 3 ULONG offset to a default UVS table */ 2886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* describing any variants to be found in */ 2887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* the normal Unicode subtable. */ 2888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* nonDefOff 7 ULONG offset to a non-default UVS table */ 2889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* describing any variants not in the */ 2890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* standard cmap, with GIDs here */ 2891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* (either offset may be 0 NULL) */ 2892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Selectors are sorted by code point. */ 2894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A default Unicode Variation Selector (UVS) subtable is just a list of */ 2896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* ranges of code points which are to be found in the standard cmap. No */ 2897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* glyph IDs (GIDs) here. */ 2898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* numRanges 0 ULONG number of ranges following */ 2900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A range looks like */ 2902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* uniStart 0 UINT24 code point of the first character in */ 2904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this range */ 2905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* additionalCnt 3 UBYTE count of additional characters in this */ 2906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* range (zero means a range of a single */ 2907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* character) */ 2908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Ranges are sorted by `uniStart'. */ 2910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A non-default Unicode Variation Selector (UVS) subtable is a list of */ 2912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* mappings from codepoint to GID. */ 2913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* numMappings 0 ULONG number of mappings */ 2915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* A range looks like */ 2917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* uniStart 0 UINT24 code point of the first character in */ 2919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this range */ 2920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* GID 3 USHORT and its GID */ 2921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 2922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Ranges are sorted by `uniStart'. */ 2923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_CMAP_FORMAT_14 2925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef struct TT_CMap14Rec_ 2927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapRec cmap; 2929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong num_selectors; 2930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This array is used to store the results of various 2932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * cmap 14 query functions. The data is overwritten 2933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * on each call to these functions. 2934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 2935295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 max_results; 2936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* results; 2937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory; 2938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } TT_CMap14Rec, *TT_CMap14; 2940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( void ) 2943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_done( TT_CMap14 cmap ) 2944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory = cmap->memory; 2946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->max_results = 0; 2949a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( memory && cmap->results ) 2950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_FREE( cmap->results ); 2951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Error 2955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_ensure( TT_CMap14 cmap, 2956295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 num_results, 2957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 2958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2959727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt32 old_max = cmap->max_results; 2960727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error = FT_Err_Ok; 2961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( num_results > cmap->max_results ) 2964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->memory = memory; 2966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) ) 2968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->max_results = num_results; 2971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return error; 2974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_init( TT_CMap14 cmap, 2979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table ) 2980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 2981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap->cmap.data = table; 2982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project table += 6; 2984727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease cmap->num_selectors = FT_PEEK_ULONG( table ); 2985727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease cmap->max_results = 0; 2986727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease cmap->results = NULL; 2987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2988727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 2989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 2990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 2992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 2993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_validate( FT_Byte* table, 2994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Validator valid ) 2995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 29969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_Byte* p; 29979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_ULong length; 29989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_ULong num_selectors; 29999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 30009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod 30019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod if ( table + 2 + 4 + 4 > valid->limit ) 30029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod FT_INVALID_TOO_SHORT; 3003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 30049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod p = table + 2; 30059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod length = TT_NEXT_ULONG( p ); 30069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod num_selectors = TT_NEXT_ULONG( p ); 3007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3008295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( length > (FT_ULong)( valid->limit - table ) || 3009fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* length < 10 + 11 * num_selectors ? */ 3010fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki length < 10 || 3011fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki ( length - 10 ) / 11 < num_selectors ) 3012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 3013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check selectors, they must be in increasing order */ 3015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* we start lastVarSel at 1 because a variant selector value of 0 3017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project * isn't valid. 3018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project */ 3019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong n, lastVarSel = 1; 3020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( n = 0; n < num_selectors; n++ ) 3023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong varSel = TT_NEXT_UINT24( p ); 3025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff = TT_NEXT_ULONG( p ); 3026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff = TT_NEXT_ULONG( p ); 3027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff >= length || nondefOff >= length ) 3030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 3031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( varSel < lastVarSel ) 3033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 3034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lastVarSel = varSel + 1; 3036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* check the default table (these glyphs should be reached */ 3038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* through the normal Unicode cmap, no GIDs, just check order) */ 3039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff != 0 ) 3040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3041055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* defp = table + defOff; 3042055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_ULong numRanges; 3043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong i; 3044055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_ULong lastBase = 0; 3045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3047055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( defp + 4 > valid->limit ) 3048055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_INVALID_TOO_SHORT; 3049055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3050055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin numRanges = TT_NEXT_ULONG( defp ); 3051055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3052fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki /* defp + numRanges * 4 > valid->limit ? */ 3053fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) 3054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 3055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3056a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < numRanges; i++ ) 3057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong base = TT_NEXT_UINT24( defp ); 3059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong cnt = FT_NEXT_BYTE( defp ); 3060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( base + cnt >= 0x110000UL ) /* end of Unicode */ 3063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 3064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( base < lastBase ) 3066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 3067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lastBase = base + cnt + 1U; 3069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and the non-default table (these glyphs are specified here) */ 3073aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich if ( nondefOff != 0 ) 3074aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich { 3075055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_Byte* ndp = table + nondefOff; 3076055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_ULong numMappings; 3077055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_ULong i, lastUni = 0; 3078055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3079055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin 3080055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( ndp + 4 > valid->limit ) 3081055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin FT_INVALID_TOO_SHORT; 3082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3083055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin numMappings = TT_NEXT_ULONG( ndp ); 3084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3085055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */ 3086055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 ) 3087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_TOO_SHORT; 3088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3089a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < numMappings; i++ ) 3090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong uni = TT_NEXT_UINT24( ndp ); 3092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong gid = TT_NEXT_USHORT( ndp ); 3093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( uni >= 0x110000UL ) /* end of Unicode */ 3096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 3097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( uni < lastUni ) 3099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_DATA; 3100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project lastUni = uni + 1U; 3102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( valid->level >= FT_VALIDATE_TIGHT && 3104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project gid >= TT_VALID_GLYPH_COUNT( valid ) ) 3105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_INVALID_GLYPH_ID; 3106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 3112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 3116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_index( TT_CMap cmap, 3117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 3118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( cmap ); 3120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( char_code ); 3121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This can't happen */ 3123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3127295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_CALLBACK_DEF( FT_UInt32 ) 3128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_next( TT_CMap cmap, 3129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *pchar_code ) 3130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( cmap ); 3132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This can't happen */ 3134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *pchar_code = 0; 3135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Error ) 3140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_get_info( TT_CMap cmap, 3141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 3142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UNUSED( cmap ); 3144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3145295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner cmap_info->format = 14; 3146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* subtable 14 does not define a language field */ 3147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap_info->language = 0xFFFFFFFFUL; 3148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3149727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 3150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 3154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( FT_Byte *base, 3155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 3156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numRanges = TT_PEEK_ULONG( base ); 3158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min; 3159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 3162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = numRanges; 3163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base += 4; 3165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 3167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 3168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 mid = ( min + max ) >> 1; 3170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = base + 4 * mid; 3171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong start = TT_NEXT_UINT24( p ); 3172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cnt = FT_NEXT_BYTE( p ); 3173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < start ) 3176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 3177055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin else if ( char_code > start + cnt ) 3178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 3179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TRUE; 3181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return FALSE; 3184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 3188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_nondef_binary( FT_Byte *base, 3189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 char_code ) 3190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numMappings = TT_PEEK_ULONG( base ); 3192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min; 3193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 3196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = numMappings; 3197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base += 4; 3199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 3201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 3202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 mid = ( min + max ) >> 1; 3204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = base + 5 * mid; 3205295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); 3206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( char_code < uni ) 3209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 3210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( char_code > uni ) 3211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 3212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return TT_PEEK_USHORT( p ); 3214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Byte* 3221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_find_variant( FT_Byte *base, 3222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 variantCode ) 3223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numVar = TT_PEEK_ULONG( base ); 3225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 max, min; 3226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = 0; 3229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = numVar; 3230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project base += 4; 3232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* binary search */ 3234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( min < max ) 3235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 mid = ( min + max ) >> 1; 3237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = base + 11 * mid; 3238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong varSel = TT_NEXT_UINT24( p ); 3239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( variantCode < varSel ) 3242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project max = mid; 3243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( variantCode > varSel ) 3244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project min = mid + 1; 3245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return p; 3247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt ) 3254295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap14_char_var_index( TT_CMap cmap, 3255295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner TT_CMap ucmap, 3256295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 charcode, 3257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt32 variantSelector ) 3258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); 3260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff; 3261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff; 3262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !p ) 3265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project defOff = TT_NEXT_ULONG( p ); 3268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nondefOff = TT_PEEK_ULONG( p ); 3269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff != 0 && 3271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) 3272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* This is the default variant of this charcode. GID not stored */ 3274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* here; stored in the normal Unicode charmap instead. */ 3275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode ); 3276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nondefOff != 0 ) 3279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode ); 3281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_Int ) 3287295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner tt_cmap14_char_var_isdefault( TT_CMap cmap, 3288295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 charcode, 3289295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 variantSelector ) 3290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); 3292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff; 3293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff; 3294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !p ) 3297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return -1; 3298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project defOff = TT_NEXT_ULONG( p ); 3300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nondefOff = TT_NEXT_ULONG( p ); 3301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff != 0 && 3303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) 3304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 1; 3305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nondefOff != 0 && 3307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charcode ) != 0 ) 3309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 3310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return -1; 3312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt32* ) 3316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_variants( TT_CMap cmap, 3317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 3318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14)cmap; 3320295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 count = cmap14->num_selectors; 3321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 10; 3322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* result; 3323295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 i; 3324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) 3327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result = cmap14->results; 3330a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < count; i++ ) 3331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3332295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); 3333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 8; 3334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project result[i] = 0; 3336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return result; 3338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt32 * ) 3342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_variants( TT_CMap cmap, 3343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 3344295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 charCode ) 3345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3347295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 count = cmap14->num_selectors; 3348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* p = cmap->data + 10; 3349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* q; 3350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) 3353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3355a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( q = cmap14->results; count > 0; count-- ) 3356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 varSel = TT_NEXT_UINT24( p ); 3358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff = TT_NEXT_ULONG( p ); 3359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff = TT_NEXT_ULONG( p ); 3360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ( defOff != 0 && 3363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_def_binary( cmap->data + defOff, 3364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charCode ) ) || 3365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ( nondefOff != 0 && 3366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, 3367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charCode ) != 0 ) ) 3368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = varSel; 3370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q++; 3371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = 0; 3374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return cmap14->results; 3376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt 3380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_def_char_count( FT_Byte *p ) 3381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3382295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); 3383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt tot = 0; 3384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 338677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner p += 3; /* point to the first `cnt' field */ 3387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; numRanges > 0; numRanges-- ) 3388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tot += 1 + p[0]; 3390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 4; 3391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tot; 3394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_UInt32* 3398727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap14_get_def_chars( TT_CMap cmap, 3399727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Byte* p, 3400727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Memory memory ) 3401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numRanges; 3404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt cnt; 3405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32* q; 3406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cnt = tt_cmap14_def_char_count( p ); 3409295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numRanges = (FT_UInt32)TT_NEXT_ULONG( p ); 3410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) 3412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3414a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( q = cmap14->results; numRanges > 0; numRanges-- ) 3415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3416727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); 3417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cnt = FT_NEXT_BYTE( p ) + 1; 3420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project do 3421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = uni; 3423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project uni += 1; 3424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q += 1; 3425727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } while ( --cnt != 0 ); 3427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project q[0] = 0; 3429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return cmap14->results; 3431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 343477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner static FT_UInt32* 3435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_get_nondef_chars( TT_CMap cmap, 3436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte *p, 3437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory ) 3438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numMappings; 3441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt i; 3442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 *ret; 3443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3445295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); 3446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( numMappings + 1 ), memory ) ) 3448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret = cmap14->results; 3451a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( i = 0; i < numMappings; i++ ) 3452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3453295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); 3454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i] = 0; 3457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ret; 3459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CALLBACK_DEF( FT_UInt32 * ) 3463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_cmap14_variant_chars( TT_CMap cmap, 3464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Memory memory, 3465295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_UInt32 variantSelector ) 3466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, 3468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project variantSelector ); 3469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int i; 3470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong defOff; 3471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_ULong nondefOff; 3472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !p ) 3475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project defOff = TT_NEXT_ULONG( p ); 3478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project nondefOff = TT_NEXT_ULONG( p ); 3479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff == 0 && nondefOff == 0 ) 3481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( defOff == 0 ) 3484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, 3485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( nondefOff == 0 ) 3487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, 3488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* Both a default and a non-default glyph set? That's probably not */ 3492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* good font design, but the spec allows for it... */ 3493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap14 cmap14 = (TT_CMap14) cmap; 3494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numRanges; 3495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 numMappings; 3496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 duni; 3497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 dcnt; 3498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 nuni; 3499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* dp; 3500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt di, ni, k; 3501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3502ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease FT_UInt32 *ret; 3503ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease 3504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p = cmap->data + nondefOff; 3506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dp = cmap->data + defOff; 3507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3508295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numMappings = (FT_UInt32)TT_NEXT_ULONG( p ); 3509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = tt_cmap14_def_char_count( dp ); 3510295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner numRanges = (FT_UInt32)TT_NEXT_ULONG( dp ); 3511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( numMappings == 0 ) 3513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, 3514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dcnt == 0 ) 3516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, 3517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project memory ); 3518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) ) 3520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return NULL; 3521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret = cmap14->results; 3523295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = FT_NEXT_BYTE( dp ); 3525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project di = 1; 3526295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner nuni = (FT_UInt32)TT_NEXT_UINT24( p ); 3527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ni = 1; 3529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project i = 0; 3530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3531055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin for (;;) 3532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nuni > duni + dcnt ) 3534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3535a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( k = 0; k <= dcnt; k++ ) 3536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = duni + k; 3537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3538a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin di++; 3539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( di > numRanges ) 3541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 3542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3543295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = FT_NEXT_BYTE( dp ); 3545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( nuni < duni ) 3549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = nuni; 3550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If it is within the default range then ignore it -- */ 3551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* that should not have happened */ 3552a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ni++; 3553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ni > numMappings ) 3554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 3555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3556295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner nuni = (FT_UInt32)TT_NEXT_UINT24( p ); 3557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( ni <= numMappings ) 3562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If we get here then we have run out of all default ranges. */ 3564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* We have read one non-default mapping which we haven't stored */ 3565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* and there may be others that need to be read. */ 3566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = nuni; 3567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( ni < numMappings ) 3568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3569295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); 3570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project p += 2; 3571a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ni++; 3572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( di <= numRanges ) 3575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* If we get here then we have run out of all non-default */ 3577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* mappings. We have read one default range which we haven't */ 3578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* stored and there may be others that need to be read. */ 3579a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( k = 0; k <= dcnt; k++ ) 3580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = duni + k; 3581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project while ( di < numRanges ) 3583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3584295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner duni = (FT_UInt32)TT_NEXT_UINT24( dp ); 3585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project dcnt = FT_NEXT_BYTE( dp ); 3586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3587a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin for ( k = 0; k <= dcnt; k++ ) 3588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i++] = duni + k; 3589a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin di++; 3590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ret[i] = 0; 3594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return ret; 3596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3600727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_DEFINE_TT_CMAP( 3601727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease tt_cmap14_class_rec, 3602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3603a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin sizeof ( TT_CMap14Rec ), 3604a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin 3605a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_InitFunc) tt_cmap14_init, /* init */ 3606a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_DoneFunc) tt_cmap14_done, /* done */ 3607a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharIndexFunc)tt_cmap14_char_index, /* char_index */ 3608a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharNextFunc) tt_cmap14_char_next, /* char_next */ 3609727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3610a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin /* Format 14 extension functions */ 3611a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, 3612a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, 3613a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantListFunc) tt_cmap14_variants, 3614a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, 3615a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, 3616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 14, 3618a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_ValidateFunc)tt_cmap14_validate, /* validate */ 3619a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin (TT_CMap_Info_GetFunc)tt_cmap14_get_info /* get_cmap_info */ 3620a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin ) 3621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 362277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif /* TT_CONFIG_CMAP_FORMAT_14 */ 3623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3625295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_CONFIG_OPTION_PIC 3626295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 3627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static const TT_CMap_Class tt_cmap_classes[] = 3628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3629727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define TTCMAPCITEM( a ) &a, 3630295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ttcmapc.h" 3631295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner NULL, 3632295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner }; 3633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3634295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else /*FT_CONFIG_OPTION_PIC*/ 3635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3636727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease void 3637727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Destroy_Class_tt_cmap_classes( FT_Library library, 3638727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_CMap_Class* clazz ) 3639295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 3640727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Memory memory = library->memory; 3641727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3642727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3643295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner if ( clazz ) 3644295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_FREE( clazz ); 3645295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 3646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3647727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3648727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error 3649727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Create_Class_tt_cmap_classes( FT_Library library, 3650727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_CMap_Class** output_class ) 3651295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner { 3652727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_CMap_Class* clazz = NULL; 3653727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease TT_CMap_ClassRec* recs; 3654727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Error error; 3655727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Memory memory = library->memory; 3656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3657727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease int i = 0; 3658727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3659727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3660727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define TTCMAPCITEM( a ) i++; 3661295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ttcmapc.h" 3662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3663727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* allocate enough space for both the pointers */ 3664727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* plus terminator and the class instances */ 3665727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( FT_ALLOC( clazz, sizeof ( *clazz ) * ( i + 1 ) + 3666727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease sizeof ( TT_CMap_ClassRec ) * i ) ) 3667295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner return error; 3668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3669295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner /* the location of the class instances follows the array of pointers */ 3670727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease recs = (TT_CMap_ClassRec*)( (char*)clazz + 3671727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease sizeof ( *clazz ) * ( i + 1 ) ); 3672727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease i = 0; 3673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3674295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#undef TTCMAPCITEM 3675727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define TTCMAPCITEM( a ) \ 3676727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Init_Class_ ## a( &recs[i] ); \ 3677727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease clazz[i] = &recs[i]; \ 3678295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner i++; 3679295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ttcmapc.h" 3680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3681295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner clazz[i] = NULL; 3682295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 3683295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner *output_class = clazz; 3684727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 3685295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner } 3686295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 3687295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /*FT_CONFIG_OPTION_PIC*/ 3688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* parse the `cmap' table and build the corresponding TT_CMap objects */ 3691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* in the current face */ 3692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* */ 3693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL_DEF( FT_Error ) 3694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_face_build_cmaps( TT_Face face ) 3695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* table = face->cmap_table; 3697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* limit = table + face->cmap_size; 3698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt volatile num_cmaps; 3699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* volatile p = table; 3700aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_Library library = FT_FACE_LIBRARY( face ); 3701aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich 3702aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich FT_UNUSED( library ); 3703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3705aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich if ( !p || p + 4 > limit ) 3706727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Table ); 3707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* only recognize format 0 */ 3709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( TT_NEXT_USHORT( p ) != 0 ) 3710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3711295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_ERROR(( "tt_face_build_cmaps:" 3712295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner " unsupported `cmap' table format = %d\n", 3713fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki TT_PEEK_USHORT( p - 2 ) )); 3714727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_THROW( Invalid_Table ); 3715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project num_cmaps = TT_NEXT_USHORT( p ); 3718727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 3719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- ) 3720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CharMapRec charmap; 3722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_UInt32 offset; 3723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.platform_id = TT_NEXT_USHORT( p ); 3726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.encoding_id = TT_NEXT_USHORT( p ); 3727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.face = FT_FACE( face ); 3728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project charmap.encoding = FT_ENCODING_NONE; /* will be filled later */ 3729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project offset = TT_NEXT_ULONG( p ); 3730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( offset && offset <= face->cmap_size - 2 ) 3732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Byte* volatile cmap = table + offset; 3734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project volatile FT_UInt format = TT_PEEK_USHORT( cmap ); 3735727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease const TT_CMap_Class* volatile pclazz = TT_CMAP_CLASSES_GET; 3736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap_Class volatile clazz; 3737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for ( ; *pclazz; pclazz++ ) 3740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project clazz = *pclazz; 3742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( clazz->format == format ) 3743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project volatile TT_ValidatorRec valid; 3745727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease volatile FT_Error error = FT_Err_Ok; 3746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_validator_init( FT_VALIDATOR( &valid ), cmap, limit, 3749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_VALIDATE_DEFAULT ); 3750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project valid.num_glyphs = (FT_UInt)face->max_profile.numGlyphs; 3752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3753727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( ft_setjmp( FT_VALIDATOR( &valid )->jump_buffer) == 0 ) 3754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* validate this cmap sub-table */ 3756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); 3757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3759a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !valid.validator.error ) 3760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CMap ttcmap; 3762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3764727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* It might make sense to store the single variation */ 3765727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* selector cmap somewhere special. But it would have to be */ 3766727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* in the public FT_FaceRec, and we can't change that. */ 3767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( !FT_CMap_New( (FT_CMap_Class)clazz, 3769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project cmap, &charmap, &ttcmap ) ) 3770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* it is simpler to directly set `flags' than adding */ 3772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* a parameter to FT_CMap_New */ 3773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ((TT_CMap)ttcmap)->flags = (FT_Int)error; 3774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 3777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3778295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE0(( "tt_face_build_cmaps:" 3779295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner " broken cmap sub-table ignored\n" )); 3780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project break; 3782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3785a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin if ( !*pclazz ) 3786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3787295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner FT_TRACE0(( "tt_face_build_cmaps:" 3788295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner " unsupported cmap sub-table ignored\n" )); 3789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3793727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_Err_Ok; 3794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_LOCAL( FT_Error ) 3798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project tt_get_cmap_info( FT_CharMap charmap, 3799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMapInfo *cmap_info ) 3800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 3801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_CMap cmap = (FT_CMap)charmap; 3802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; 3803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return clazz->get_cmap_info( charmap, cmap_info ); 3806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 3807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 3809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 3810