1 /***************************************************************************/ 2 /* */ 3 /* pfrcmap.c */ 4 /* */ 5 /* FreeType PFR cmap handling (body). */ 6 /* */ 7 /* Copyright 2002, 2007, 2009 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 22 #include "pfrerror.h" 23 24 25 FT_CALLBACK_DEF( FT_Error ) pfr_cmap_init(PFR_CMap cmap)26 pfr_cmap_init( PFR_CMap cmap ) 27 { 28 FT_Error error = PFR_Err_Ok; 29 PFR_Face face = (PFR_Face)FT_CMAP_FACE( cmap ); 30 31 32 cmap->num_chars = face->phy_font.num_chars; 33 cmap->chars = face->phy_font.chars; 34 35 /* just for safety, check that the character entries are correctly */ 36 /* sorted in increasing character code order */ 37 { 38 FT_UInt n; 39 40 41 for ( n = 1; n < cmap->num_chars; n++ ) 42 { 43 if ( cmap->chars[n - 1].char_code >= cmap->chars[n].char_code ) 44 { 45 error = PFR_Err_Invalid_Table; 46 goto Exit; 47 } 48 } 49 } 50 51 Exit: 52 return error; 53 } 54 55 56 FT_CALLBACK_DEF( void ) pfr_cmap_done(PFR_CMap cmap)57 pfr_cmap_done( PFR_CMap cmap ) 58 { 59 cmap->chars = NULL; 60 cmap->num_chars = 0; 61 } 62 63 64 FT_CALLBACK_DEF( FT_UInt ) pfr_cmap_char_index(PFR_CMap cmap,FT_UInt32 char_code)65 pfr_cmap_char_index( PFR_CMap cmap, 66 FT_UInt32 char_code ) 67 { 68 FT_UInt min = 0; 69 FT_UInt max = cmap->num_chars; 70 FT_UInt mid; 71 PFR_Char gchar; 72 73 74 while ( min < max ) 75 { 76 mid = min + ( max - min ) / 2; 77 gchar = cmap->chars + mid; 78 79 if ( gchar->char_code == char_code ) 80 return mid + 1; 81 82 if ( gchar->char_code < char_code ) 83 min = mid + 1; 84 else 85 max = mid; 86 } 87 return 0; 88 } 89 90 91 FT_CALLBACK_DEF( FT_UInt32 ) pfr_cmap_char_next(PFR_CMap cmap,FT_UInt32 * pchar_code)92 pfr_cmap_char_next( PFR_CMap cmap, 93 FT_UInt32 *pchar_code ) 94 { 95 FT_UInt result = 0; 96 FT_UInt32 char_code = *pchar_code + 1; 97 98 99 Restart: 100 { 101 FT_UInt min = 0; 102 FT_UInt max = cmap->num_chars; 103 FT_UInt mid; 104 PFR_Char gchar; 105 106 107 while ( min < max ) 108 { 109 mid = min + ( ( max - min ) >> 1 ); 110 gchar = cmap->chars + mid; 111 112 if ( gchar->char_code == char_code ) 113 { 114 result = mid; 115 if ( result != 0 ) 116 { 117 result++; 118 goto Exit; 119 } 120 121 char_code++; 122 goto Restart; 123 } 124 125 if ( gchar->char_code < char_code ) 126 min = mid+1; 127 else 128 max = mid; 129 } 130 131 /* we didn't find it, but we have a pair just above it */ 132 char_code = 0; 133 134 if ( min < cmap->num_chars ) 135 { 136 gchar = cmap->chars + min; 137 result = min; 138 if ( result != 0 ) 139 { 140 result++; 141 char_code = gchar->char_code; 142 } 143 } 144 } 145 146 Exit: 147 *pchar_code = char_code; 148 return result; 149 } 150 151 152 FT_CALLBACK_TABLE_DEF const FT_CMap_ClassRec 153 pfr_cmap_class_rec = 154 { 155 sizeof ( PFR_CMapRec ), 156 157 (FT_CMap_InitFunc) pfr_cmap_init, 158 (FT_CMap_DoneFunc) pfr_cmap_done, 159 (FT_CMap_CharIndexFunc)pfr_cmap_char_index, 160 (FT_CMap_CharNextFunc) pfr_cmap_char_next, 161 162 NULL, NULL, NULL, NULL, NULL 163 }; 164 165 166 /* END */ 167