1 /***************************************************************************/ 2 /* */ 3 /* pfrcmap.c */ 4 /* */ 5 /* FreeType PFR cmap handling (body). */ 6 /* */ 7 /* Copyright 2002 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include "pfrcmap.h" 20 #include "pfrobjs.h" 21 #include FT_INTERNAL_DEBUG_H 22 23 24 FT_CALLBACK_DEF( FT_Error ) pfr_cmap_init(PFR_CMap cmap)25 pfr_cmap_init( PFR_CMap cmap ) 26 { 27 PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); 28 29 30 cmap->num_chars = face->phy_font.num_chars; 31 cmap->chars = face->phy_font.chars; 32 33 /* just for safety, check that the character entries are correctly */ 34 /* sorted in increasing character code order */ 35 { 36 FT_UInt n; 37 38 39 for ( n = 1; n < cmap->num_chars; n++ ) 40 { 41 if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) 42 FT_ASSERT( 0 ); 43 } 44 } 45 46 return 0; 47 } 48 49 50 FT_CALLBACK_DEF( void ) pfr_cmap_done(PFR_CMap cmap)51 pfr_cmap_done( PFR_CMap cmap ) 52 { 53 cmap->chars = NULL; 54 cmap->num_chars = 0; 55 } 56 57 58 FT_CALLBACK_DEF( FT_UInt ) pfr_cmap_char_index(PFR_CMap cmap,FT_UInt32 char_code)59 pfr_cmap_char_index( PFR_CMap cmap, 60 FT_UInt32 char_code ) 61 { 62 FT_UInt min = 0; 63 FT_UInt max = cmap->num_chars; 64 FT_UInt mid; 65 PFR_Char gchar; 66 67 68 while ( min < max ) 69 { 70 mid = min + ( max - min ) / 2; 71 gchar = cmap->chars + mid; 72 73 if ( gchar->char_code == char_code ) 74 return mid + 1; 75 76 if ( gchar->char_code < char_code ) 77 min = mid + 1; 78 else 79 max = mid; 80 } 81 return 0; 82 } 83 84 85 FT_CALLBACK_DEF( FT_UInt ) pfr_cmap_char_next(PFR_CMap cmap,FT_UInt32 * pchar_code)86 pfr_cmap_char_next( PFR_CMap cmap, 87 FT_UInt32 *pchar_code ) 88 { 89 FT_UInt result = 0; 90 FT_UInt32 char_code = *pchar_code + 1; 91 92 93 Restart: 94 { 95 FT_UInt min = 0; 96 FT_UInt max = cmap->num_chars; 97 FT_UInt mid; 98 PFR_Char gchar; 99 100 101 while ( min < max ) 102 { 103 mid = min + ( ( max - min ) >> 1 ); 104 gchar = cmap->chars + mid; 105 106 if ( gchar->char_code == char_code ) 107 { 108 result = mid; 109 if ( result != 0 ) 110 { 111 result++; 112 goto Exit; 113 } 114 115 char_code++; 116 goto Restart; 117 } 118 119 if ( gchar->char_code < char_code ) 120 min = mid+1; 121 else 122 max = mid; 123 } 124 125 /* we didn't find it, but we have a pair just above it */ 126 char_code = 0; 127 128 if ( min < cmap->num_chars ) 129 { 130 gchar = cmap->chars + min; 131 result = min; 132 if ( result != 0 ) 133 { 134 result++; 135 char_code = gchar->char_code; 136 } 137 } 138 } 139 140 Exit: 141 *pchar_code = char_code; 142 return result; 143 } 144 145 146 FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec 147 pfr_cmap_class_rec = 148 { 149 sizeof ( PFR_CMapRec ), 150 151 (FT_CMap_InitFunc) pfr_cmap_init, 152 (FT_CMap_DoneFunc) pfr_cmap_done, 153 (FT_CMap_CharIndexFunc)pfr_cmap_char_index, 154 (FT_CMap_CharNextFunc) pfr_cmap_char_next 155 }; 156 157 158 /* END */ 159