1 /***************************************************************************/ 2 /* */ 3 /* t42objs.c */ 4 /* */ 5 /* Type 42 objects manager (body). */ 6 /* */ 7 /* Copyright 2002 by Roberto Alameda. */ 8 /* */ 9 /* This file is part of the FreeType project, and may only be used, */ 10 /* modified, and distributed under the terms of the FreeType project */ 11 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 12 /* this file you indicate that you have read the license and */ 13 /* understand and accept it fully. */ 14 /* */ 15 /***************************************************************************/ 16 17 18 #include "t42objs.h" 19 #include "t42parse.h" 20 #include "t42error.h" 21 #include FT_INTERNAL_DEBUG_H 22 #include FT_INTERNAL_STREAM_H 23 #include FT_LIST_H 24 25 26 #undef FT_COMPONENT 27 #define FT_COMPONENT trace_t42 28 29 30 static FT_Error T42_Open_Face(T42_Face face)31 T42_Open_Face( T42_Face face ) 32 { 33 T42_LoaderRec loader; 34 T42_Parser parser; 35 T1_Font type1 = &face->type1; 36 FT_Memory memory = face->root.memory; 37 FT_Error error; 38 39 PSAux_Service psaux = (PSAux_Service)face->psaux; 40 41 42 t42_loader_init( &loader, face ); 43 44 parser = &loader.parser; 45 46 if ( FT_ALLOC( face->ttf_data, 12 ) ) 47 goto Exit; 48 49 error = t42_parser_init( parser, 50 face->root.stream, 51 memory, 52 psaux); 53 if ( error ) 54 goto Exit; 55 56 error = t42_parse_dict( face, &loader, parser->base_dict, parser->base_len ); 57 58 if ( type1->font_type != 42 ) 59 { 60 error = T42_Err_Unknown_File_Format; 61 goto Exit; 62 } 63 64 /* now, propagate the charstrings and glyphnames tables */ 65 /* to the Type1 data */ 66 type1->num_glyphs = loader.num_glyphs; 67 68 if ( !loader.charstrings.init ) { 69 FT_ERROR(( "T42_Open_Face: no charstrings array in face!\n" )); 70 error = T42_Err_Invalid_File_Format; 71 } 72 73 loader.charstrings.init = 0; 74 type1->charstrings_block = loader.charstrings.block; 75 type1->charstrings = loader.charstrings.elements; 76 type1->charstrings_len = loader.charstrings.lengths; 77 78 /* we copy the glyph names `block' and `elements' fields; */ 79 /* the `lengths' field must be released later */ 80 type1->glyph_names_block = loader.glyph_names.block; 81 type1->glyph_names = (FT_String**)loader.glyph_names.elements; 82 loader.glyph_names.block = 0; 83 loader.glyph_names.elements = 0; 84 85 /* we must now build type1.encoding when we have a custom array */ 86 if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) 87 { 88 FT_Int charcode, idx, min_char, max_char; 89 FT_Byte* char_name; 90 FT_Byte* glyph_name; 91 92 93 /* OK, we do the following: for each element in the encoding */ 94 /* table, look up the index of the glyph having the same name */ 95 /* as defined in the CharStrings array. */ 96 /* The index is then stored in type1.encoding.char_index, and */ 97 /* the name in type1.encoding.char_name */ 98 99 min_char = +32000; 100 max_char = -32000; 101 102 charcode = 0; 103 for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) 104 { 105 type1->encoding.char_index[charcode] = 0; 106 type1->encoding.char_name [charcode] = (char *)".notdef"; 107 108 char_name = loader.encoding_table.elements[charcode]; 109 if ( char_name ) 110 for ( idx = 0; idx < type1->num_glyphs; idx++ ) 111 { 112 glyph_name = (FT_Byte*)type1->glyph_names[idx]; 113 if ( ft_strcmp( (const char*)char_name, 114 (const char*)glyph_name ) == 0 ) 115 { 116 type1->encoding.char_index[charcode] = (FT_UShort)idx; 117 type1->encoding.char_name [charcode] = (char*)glyph_name; 118 119 /* Change min/max encoded char only if glyph name is */ 120 /* not /.notdef */ 121 if ( ft_strcmp( (const char*)".notdef", 122 (const char*)glyph_name ) != 0 ) 123 { 124 if ( charcode < min_char ) min_char = charcode; 125 if ( charcode > max_char ) max_char = charcode; 126 } 127 break; 128 } 129 } 130 } 131 type1->encoding.code_first = min_char; 132 type1->encoding.code_last = max_char; 133 type1->encoding.num_chars = loader.num_chars; 134 } 135 136 Exit: 137 t42_loader_done( &loader ); 138 return error; 139 } 140 141 142 /***************** Driver Functions *************/ 143 144 145 FT_LOCAL_DEF( FT_Error ) T42_Face_Init(FT_Stream stream,T42_Face face,FT_Int face_index,FT_Int num_params,FT_Parameter * params)146 T42_Face_Init( FT_Stream stream, 147 T42_Face face, 148 FT_Int face_index, 149 FT_Int num_params, 150 FT_Parameter* params ) 151 { 152 FT_Error error; 153 PSNames_Service psnames; 154 PSAux_Service psaux; 155 FT_Face root = (FT_Face)&face->root; 156 157 FT_UNUSED( num_params ); 158 FT_UNUSED( params ); 159 FT_UNUSED( face_index ); 160 FT_UNUSED( stream ); 161 162 163 face->ttf_face = NULL; 164 face->root.num_faces = 1; 165 166 face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 167 "psnames" ); 168 psnames = (PSNames_Service)face->psnames; 169 170 face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), 171 "psaux" ); 172 psaux = (PSAux_Service)face->psaux; 173 174 /* open the tokenizer, this will also check the font format */ 175 error = T42_Open_Face( face ); 176 if ( error ) 177 goto Exit; 178 179 /* if we just wanted to check the format, leave successfully now */ 180 if ( face_index < 0 ) 181 goto Exit; 182 183 /* check the face index */ 184 if ( face_index != 0 ) 185 { 186 FT_ERROR(( "T42_Face_Init: invalid face index\n" )); 187 error = T42_Err_Invalid_Argument; 188 goto Exit; 189 } 190 191 /* Now, load the font program into the face object */ 192 193 /* Init the face object fields */ 194 /* Now set up root face fields */ 195 196 root->num_glyphs = face->type1.num_glyphs; 197 root->num_charmaps = 0; 198 root->face_index = face_index; 199 200 root->face_flags = FT_FACE_FLAG_SCALABLE; 201 root->face_flags |= FT_FACE_FLAG_HORIZONTAL; 202 root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; 203 204 if ( face->type1.font_info.is_fixed_pitch ) 205 root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; 206 207 /* XXX: TODO -- add kerning with .afm support */ 208 209 /* get style name -- be careful, some broken fonts only */ 210 /* have a `/FontName' dictionary entry! */ 211 root->family_name = face->type1.font_info.family_name; 212 if ( root->family_name ) 213 { 214 char* full = face->type1.font_info.full_name; 215 char* family = root->family_name; 216 217 218 if ( full ) 219 { 220 while ( *family && *full == *family ) 221 { 222 family++; 223 full++; 224 } 225 226 root->style_name = ( *full == ' ' ? full + 1 227 : (char *)"Regular" ); 228 } 229 else 230 root->style_name = (char *)"Regular"; 231 } 232 else 233 { 234 /* do we have a `/FontName'? */ 235 if ( face->type1.font_name ) 236 { 237 root->family_name = face->type1.font_name; 238 root->style_name = (char *)"Regular"; 239 } 240 } 241 242 /* no embedded bitmap support */ 243 root->num_fixed_sizes = 0; 244 root->available_sizes = 0; 245 246 /* Load the TTF font embedded in the T42 font */ 247 error = FT_New_Memory_Face( FT_FACE_LIBRARY( face ), 248 face->ttf_data, 249 face->ttf_size, 250 0, 251 &face->ttf_face ); 252 if ( error ) 253 goto Exit; 254 255 FT_Done_Size( face->ttf_face->size ); 256 257 /* Ignore info in FontInfo dictionary and use the info from the */ 258 /* loaded TTF font. The PostScript interpreter also ignores it. */ 259 root->bbox = face->ttf_face->bbox; 260 root->units_per_EM = face->ttf_face->units_per_EM; 261 262 root->ascender = face->ttf_face->ascender; 263 root->descender = face->ttf_face->descender; 264 root->height = face->ttf_face->height; 265 266 root->max_advance_width = face->ttf_face->max_advance_width; 267 root->max_advance_height = face->ttf_face->max_advance_height; 268 269 root->underline_position = face->type1.font_info.underline_position; 270 root->underline_thickness = face->type1.font_info.underline_thickness; 271 272 root->internal->max_points = 0; 273 root->internal->max_contours = 0; 274 275 /* compute style flags */ 276 root->style_flags = 0; 277 if ( face->type1.font_info.italic_angle ) 278 root->style_flags |= FT_STYLE_FLAG_ITALIC; 279 280 if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) 281 root->style_flags |= FT_STYLE_FLAG_BOLD; 282 283 if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) 284 root->face_flags |= FT_FACE_FLAG_VERTICAL; 285 286 { 287 if ( psnames && psaux ) 288 { 289 FT_CharMapRec charmap; 290 T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; 291 FT_CMap_Class clazz; 292 293 294 charmap.face = root; 295 296 /* first of all, try to synthetize a Unicode charmap */ 297 charmap.platform_id = 3; 298 charmap.encoding_id = 1; 299 charmap.encoding = FT_ENCODING_UNICODE; 300 301 FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); 302 303 /* now, generate an Adobe Standard encoding when appropriate */ 304 charmap.platform_id = 7; 305 clazz = NULL; 306 307 switch ( face->type1.encoding_type ) 308 { 309 case T1_ENCODING_TYPE_STANDARD: 310 charmap.encoding = FT_ENCODING_ADOBE_STANDARD; 311 charmap.encoding_id = 0; 312 clazz = cmap_classes->standard; 313 break; 314 315 case T1_ENCODING_TYPE_EXPERT: 316 charmap.encoding = FT_ENCODING_ADOBE_EXPERT; 317 charmap.encoding_id = 1; 318 clazz = cmap_classes->expert; 319 break; 320 321 case T1_ENCODING_TYPE_ARRAY: 322 charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; 323 charmap.encoding_id = 2; 324 clazz = cmap_classes->custom; 325 break; 326 327 case T1_ENCODING_TYPE_ISOLATIN1: 328 charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; 329 charmap.encoding_id = 3; 330 clazz = cmap_classes->unicode; 331 break; 332 333 default: 334 ; 335 } 336 337 if ( clazz ) 338 FT_CMap_New( clazz, NULL, &charmap, NULL ); 339 340 #if 0 341 /* Select default charmap */ 342 if (root->num_charmaps) 343 root->charmap = root->charmaps[0]; 344 #endif 345 } 346 } 347 Exit: 348 return error; 349 } 350 351 352 FT_LOCAL_DEF( void ) T42_Face_Done(T42_Face face)353 T42_Face_Done( T42_Face face ) 354 { 355 T1_Font type1; 356 PS_FontInfo info; 357 FT_Memory memory; 358 359 360 if ( face ) 361 { 362 type1 = &face->type1; 363 info = &type1->font_info; 364 memory = face->root.memory; 365 366 /* delete internal ttf face prior to freeing face->ttf_data */ 367 if ( face->ttf_face ) 368 FT_Done_Face( face->ttf_face ); 369 370 /* release font info strings */ 371 FT_FREE( info->version ); 372 FT_FREE( info->notice ); 373 FT_FREE( info->full_name ); 374 FT_FREE( info->family_name ); 375 FT_FREE( info->weight ); 376 377 /* release top dictionary */ 378 FT_FREE( type1->charstrings_len ); 379 FT_FREE( type1->charstrings ); 380 FT_FREE( type1->glyph_names ); 381 382 FT_FREE( type1->charstrings_block ); 383 FT_FREE( type1->glyph_names_block ); 384 385 FT_FREE( type1->encoding.char_index ); 386 FT_FREE( type1->encoding.char_name ); 387 FT_FREE( type1->font_name ); 388 389 FT_FREE( face->ttf_data ); 390 391 #if 0 392 /* release afm data if present */ 393 if ( face->afm_data ) 394 T1_Done_AFM( memory, (T1_AFM*)face->afm_data ); 395 #endif 396 397 /* release unicode map, if any */ 398 FT_FREE( face->unicode_map.maps ); 399 face->unicode_map.num_maps = 0; 400 401 face->root.family_name = 0; 402 face->root.style_name = 0; 403 } 404 } 405 406 407 /*************************************************************************/ 408 /* */ 409 /* <Function> */ 410 /* T42_Driver_Init */ 411 /* */ 412 /* <Description> */ 413 /* Initializes a given Type 42 driver object. */ 414 /* */ 415 /* <Input> */ 416 /* driver :: A handle to the target driver object. */ 417 /* */ 418 /* <Return> */ 419 /* FreeType error code. 0 means success. */ 420 /* */ 421 FT_LOCAL_DEF( FT_Error ) T42_Driver_Init(T42_Driver driver)422 T42_Driver_Init( T42_Driver driver ) 423 { 424 FT_Module ttmodule; 425 426 427 ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" ); 428 driver->ttclazz = (FT_Driver_Class)ttmodule->clazz; 429 430 return T42_Err_Ok; 431 } 432 433 434 FT_LOCAL_DEF( void ) T42_Driver_Done(T42_Driver driver)435 T42_Driver_Done( T42_Driver driver ) 436 { 437 FT_UNUSED( driver ); 438 } 439 440 441 442 443 FT_LOCAL_DEF( FT_Error ) T42_Size_Init(T42_Size size)444 T42_Size_Init( T42_Size size ) 445 { 446 FT_Face face = size->root.face; 447 T42_Face t42face = (T42_Face)face; 448 FT_Size ttsize; 449 FT_Error error = T42_Err_Ok; 450 451 452 error = FT_New_Size( t42face->ttf_face, &ttsize ); 453 size->ttsize = ttsize; 454 455 FT_Activate_Size( ttsize ); 456 457 return error; 458 } 459 460 461 FT_LOCAL_DEF( void ) T42_Size_Done(T42_Size size)462 T42_Size_Done( T42_Size size ) 463 { 464 FT_Face face = size->root.face; 465 T42_Face t42face = (T42_Face)face; 466 FT_ListNode node; 467 468 469 node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); 470 if ( node ) 471 { 472 FT_Done_Size( size->ttsize ); 473 size->ttsize = NULL; 474 } 475 } 476 477 478 FT_LOCAL_DEF( FT_Error ) T42_GlyphSlot_Init(T42_GlyphSlot slot)479 T42_GlyphSlot_Init( T42_GlyphSlot slot ) 480 { 481 FT_Face face = slot->root.face; 482 T42_Face t42face = (T42_Face)face; 483 FT_GlyphSlot ttslot; 484 FT_Error error = T42_Err_Ok; 485 486 487 if ( face->glyph == NULL ) 488 { 489 /* First glyph slot for this face */ 490 slot->ttslot = t42face->ttf_face->glyph; 491 } 492 else 493 { 494 error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot ); 495 slot->ttslot = ttslot; 496 } 497 498 return error; 499 } 500 501 502 FT_LOCAL_DEF( void ) T42_GlyphSlot_Done(T42_GlyphSlot slot)503 T42_GlyphSlot_Done( T42_GlyphSlot slot ) 504 { 505 FT_Face face = slot->root.face; 506 T42_Face t42face = (T42_Face)face; 507 FT_GlyphSlot cur = t42face->ttf_face->glyph; 508 509 510 while ( cur ) 511 { 512 if ( cur == slot->ttslot ) 513 { 514 FT_Done_GlyphSlot( slot->ttslot ); 515 break; 516 } 517 518 cur = cur->next; 519 } 520 } 521 522 523 524 FT_LOCAL_DEF( FT_Error ) T42_Size_SetChars(T42_Size size,FT_F26Dot6 char_width,FT_F26Dot6 char_height,FT_UInt horz_resolution,FT_UInt vert_resolution)525 T42_Size_SetChars( T42_Size size, 526 FT_F26Dot6 char_width, 527 FT_F26Dot6 char_height, 528 FT_UInt horz_resolution, 529 FT_UInt vert_resolution ) 530 { 531 FT_Face face = size->root.face; 532 T42_Face t42face = (T42_Face)face; 533 534 535 FT_Activate_Size(size->ttsize); 536 537 return FT_Set_Char_Size( t42face->ttf_face, 538 char_width, 539 char_height, 540 horz_resolution, 541 vert_resolution ); 542 } 543 544 545 FT_LOCAL_DEF( FT_Error ) T42_Size_SetPixels(T42_Size size,FT_UInt pixel_width,FT_UInt pixel_height)546 T42_Size_SetPixels( T42_Size size, 547 FT_UInt pixel_width, 548 FT_UInt pixel_height ) 549 { 550 FT_Face face = size->root.face; 551 T42_Face t42face = (T42_Face)face; 552 553 554 FT_Activate_Size(size->ttsize); 555 556 return FT_Set_Pixel_Sizes( t42face->ttf_face, 557 pixel_width, 558 pixel_height ); 559 } 560 561 562 static void ft_glyphslot_clear(FT_GlyphSlot slot)563 ft_glyphslot_clear( FT_GlyphSlot slot ) 564 { 565 /* free bitmap if needed */ 566 if ( slot->flags & FT_GLYPH_OWN_BITMAP ) 567 { 568 FT_Memory memory = FT_FACE_MEMORY( slot->face ); 569 570 571 FT_FREE( slot->bitmap.buffer ); 572 slot->flags &= ~FT_GLYPH_OWN_BITMAP; 573 } 574 575 /* clear all public fields in the glyph slot */ 576 FT_ZERO( &slot->metrics ); 577 FT_ZERO( &slot->outline ); 578 FT_ZERO( &slot->bitmap ); 579 580 slot->bitmap_left = 0; 581 slot->bitmap_top = 0; 582 slot->num_subglyphs = 0; 583 slot->subglyphs = 0; 584 slot->control_data = 0; 585 slot->control_len = 0; 586 slot->other = 0; 587 slot->format = FT_GLYPH_FORMAT_NONE; 588 589 slot->linearHoriAdvance = 0; 590 slot->linearVertAdvance = 0; 591 } 592 593 594 FT_LOCAL_DEF( FT_Error ) T42_GlyphSlot_Load(FT_GlyphSlot glyph,FT_Size size,FT_Int glyph_index,FT_Int32 load_flags)595 T42_GlyphSlot_Load( FT_GlyphSlot glyph, 596 FT_Size size, 597 FT_Int glyph_index, 598 FT_Int32 load_flags ) 599 { 600 FT_Error error; 601 T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph; 602 T42_Size t42size = (T42_Size)size; 603 FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz; 604 605 606 ft_glyphslot_clear( t42slot->ttslot ); 607 error = ttclazz->load_glyph( t42slot->ttslot, 608 t42size->ttsize, 609 glyph_index, 610 load_flags | FT_LOAD_NO_BITMAP ); 611 612 if ( !error ) 613 { 614 glyph->metrics = t42slot->ttslot->metrics; 615 616 glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance; 617 glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance; 618 619 glyph->format = t42slot->ttslot->format; 620 glyph->outline = t42slot->ttslot->outline; 621 622 glyph->bitmap = t42slot->ttslot->bitmap; 623 glyph->bitmap_left = t42slot->ttslot->bitmap_left; 624 glyph->bitmap_top = t42slot->ttslot->bitmap_top; 625 626 glyph->num_subglyphs = t42slot->ttslot->num_subglyphs; 627 glyph->subglyphs = t42slot->ttslot->subglyphs; 628 629 glyph->control_data = t42slot->ttslot->control_data; 630 glyph->control_len = t42slot->ttslot->control_len; 631 } 632 633 return error; 634 } 635 636 637 /* END */ 638