1 /***************************************************************************/ 2 /* */ 3 /* sfdriver.c */ 4 /* */ 5 /* High-level SFNT driver interface (body). */ 6 /* */ 7 /* Copyright 1996-2001, 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 <ft2build.h> 20 #include FT_INTERNAL_SFNT_H 21 #include FT_INTERNAL_OBJECTS_H 22 23 #include "sfdriver.h" 24 #include "ttload.h" 25 #include "ttcmap.h" 26 #include "sfobjs.h" 27 28 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 29 #include "ttsbit.h" 30 #endif 31 32 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 33 #include "ttpost.h" 34 #endif 35 36 37 static void* get_sfnt_table(TT_Face face,FT_Sfnt_Tag tag)38 get_sfnt_table( TT_Face face, 39 FT_Sfnt_Tag tag ) 40 { 41 void* table; 42 43 44 switch ( tag ) 45 { 46 case ft_sfnt_head: 47 table = &face->header; 48 break; 49 50 case ft_sfnt_hhea: 51 table = &face->horizontal; 52 break; 53 54 case ft_sfnt_vhea: 55 table = face->vertical_info ? &face->vertical : 0; 56 break; 57 58 case ft_sfnt_os2: 59 table = face->os2.version == 0xFFFFU ? 0 : &face->os2; 60 break; 61 62 case ft_sfnt_post: 63 table = &face->postscript; 64 break; 65 66 case ft_sfnt_maxp: 67 table = &face->max_profile; 68 break; 69 70 case ft_sfnt_pclt: 71 table = face->pclt.Version ? &face->pclt : 0; 72 break; 73 74 default: 75 table = 0; 76 } 77 78 return table; 79 } 80 81 82 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 83 84 85 static FT_Error get_sfnt_glyph_name(TT_Face face,FT_UInt glyph_index,FT_Pointer buffer,FT_UInt buffer_max)86 get_sfnt_glyph_name( TT_Face face, 87 FT_UInt glyph_index, 88 FT_Pointer buffer, 89 FT_UInt buffer_max ) 90 { 91 FT_String* gname; 92 FT_Error error; 93 94 95 error = tt_face_get_ps_name( face, glyph_index, &gname ); 96 if ( !error && buffer_max > 0 ) 97 { 98 FT_UInt len = (FT_UInt)( ft_strlen( gname ) ); 99 100 101 if ( len >= buffer_max ) 102 len = buffer_max - 1; 103 104 FT_MEM_COPY( buffer, gname, len ); 105 ((FT_Byte*)buffer)[len] = 0; 106 } 107 108 return error; 109 } 110 111 112 static const char* get_sfnt_postscript_name(TT_Face face)113 get_sfnt_postscript_name( TT_Face face ) 114 { 115 FT_Int n, found_win, found_apple; 116 const char* result = NULL; 117 118 119 /* shouldn't happen, but just in case to avoid memory leaks */ 120 if ( face->root.internal->postscript_name ) 121 return face->root.internal->postscript_name; 122 123 /* scan the name table to see whether we have a Postscript name here, */ 124 /* either in Macintosh or Windows platform encodings */ 125 found_win = -1; 126 found_apple = -1; 127 128 for ( n = 0; n < face->num_names; n++ ) 129 { 130 TT_NameEntryRec* name = face->name_table.names + n; 131 132 133 if ( name->nameID == 6 && name->stringLength > 0 ) 134 { 135 if ( name->platformID == 3 && 136 name->encodingID == 1 && 137 name->languageID == 0x409 ) 138 found_win = n; 139 140 if ( name->platformID == 1 && 141 name->encodingID == 0 && 142 name->languageID == 0 ) 143 found_apple = n; 144 } 145 } 146 147 if ( found_win != -1 ) 148 { 149 FT_Memory memory = face->root.memory; 150 TT_NameEntryRec* name = face->name_table.names + found_win; 151 FT_UInt len = name->stringLength / 2; 152 FT_Error error; 153 154 155 if ( !FT_ALLOC( result, name->stringLength + 1 ) ) 156 { 157 FT_Stream stream = face->name_table.stream; 158 FT_String* r = (FT_String*)result; 159 FT_Byte* p = (FT_Byte*)name->string; 160 161 162 if ( FT_STREAM_SEEK( name->stringOffset ) || 163 FT_FRAME_ENTER( name->stringLength ) ) 164 { 165 FT_FREE( result ); 166 name->stringLength = 0; 167 name->stringOffset = 0; 168 FT_FREE( name->string ); 169 170 goto Exit; 171 } 172 173 p = (FT_Byte*)stream->cursor; 174 175 for ( ; len > 0; len--, p += 2 ) 176 { 177 if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 ) 178 *r++ = p[1]; 179 } 180 *r = '\0'; 181 182 FT_FRAME_EXIT(); 183 } 184 goto Exit; 185 } 186 187 if ( found_apple != -1 ) 188 { 189 FT_Memory memory = face->root.memory; 190 TT_NameEntryRec* name = face->name_table.names + found_apple; 191 FT_UInt len = name->stringLength; 192 FT_Error error; 193 194 195 if ( !FT_ALLOC( result, len + 1 ) ) 196 { 197 FT_Stream stream = face->name_table.stream; 198 199 200 if ( FT_STREAM_SEEK( name->stringOffset ) || 201 FT_STREAM_READ( result, len ) ) 202 { 203 name->stringOffset = 0; 204 name->stringLength = 0; 205 FT_FREE( name->string ); 206 FT_FREE( result ); 207 goto Exit; 208 } 209 ((char*)result)[len] = '\0'; 210 } 211 } 212 213 Exit: 214 face->root.internal->postscript_name = result; 215 return result; 216 } 217 218 219 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ 220 221 222 FT_CALLBACK_DEF( FT_Module_Interface ) sfnt_get_interface(FT_Module module,const char * module_interface)223 sfnt_get_interface( FT_Module module, 224 const char* module_interface ) 225 { 226 FT_UNUSED( module ); 227 228 if ( ft_strcmp( module_interface, "get_sfnt" ) == 0 ) 229 return (FT_Module_Interface)get_sfnt_table; 230 231 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 232 if ( ft_strcmp( module_interface, "glyph_name" ) == 0 ) 233 return (FT_Module_Interface)get_sfnt_glyph_name; 234 #endif 235 236 if ( ft_strcmp( module_interface, "postscript_name" ) == 0 ) 237 return (FT_Module_Interface)get_sfnt_postscript_name; 238 239 return 0; 240 } 241 242 243 static 244 const SFNT_Interface sfnt_interface = 245 { 246 tt_face_goto_table, 247 248 sfnt_init_face, 249 sfnt_load_face, 250 sfnt_done_face, 251 sfnt_get_interface, 252 253 tt_face_load_any, 254 tt_face_load_sfnt_header, 255 tt_face_load_directory, 256 257 tt_face_load_header, 258 tt_face_load_metrics_header, 259 tt_face_load_cmap, 260 tt_face_load_max_profile, 261 tt_face_load_os2, 262 tt_face_load_postscript, 263 264 tt_face_load_names, 265 tt_face_free_names, 266 267 tt_face_load_hdmx, 268 tt_face_free_hdmx, 269 270 tt_face_load_kern, 271 tt_face_load_gasp, 272 tt_face_load_pclt, 273 274 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS 275 276 /* see `ttload.h' */ 277 tt_face_load_bitmap_header, 278 279 /* see `ttsbit.h' */ 280 tt_face_set_sbit_strike, 281 tt_face_load_sbit_strikes, 282 tt_face_load_sbit_image, 283 tt_face_free_sbit_strikes, 284 285 #else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 286 287 0, 288 0, 289 0, 290 0, 291 0, 292 293 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ 294 295 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES 296 297 /* see `ttpost.h' */ 298 tt_face_get_ps_name, 299 tt_face_free_ps_names, 300 301 #else /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ 302 303 0, 304 0, 305 306 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ 307 308 /* see `ttcmap.h' */ 309 tt_face_load_charmap, 310 tt_face_free_charmap, 311 }; 312 313 314 FT_CALLBACK_TABLE_DEF 315 const FT_Module_Class sfnt_module_class = 316 { 317 0, /* not a font driver or renderer */ 318 sizeof( FT_ModuleRec ), 319 320 "sfnt", /* driver name */ 321 0x10000L, /* driver version 1.0 */ 322 0x20000L, /* driver requires FreeType 2.0 or higher */ 323 324 (const void*)&sfnt_interface, /* module specific interface */ 325 326 (FT_Module_Constructor)0, 327 (FT_Module_Destructor) 0, 328 (FT_Module_Requester) sfnt_get_interface 329 }; 330 331 332 /* END */ 333