00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "t42parse.h"
00020 #include "t42error.h"
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_INTERNAL_POSTSCRIPT_AUX_H
00024
00025
00026
00027
00028
00029
00030
00031
00032 #undef FT_COMPONENT
00033 #define FT_COMPONENT trace_t42
00034
00035
00036 static void
00037 t42_parse_font_matrix( T42_Face face,
00038 T42_Loader loader );
00039 static void
00040 t42_parse_encoding( T42_Face face,
00041 T42_Loader loader );
00042
00043 static void
00044 t42_parse_charstrings( T42_Face face,
00045 T42_Loader loader );
00046
00047 static void
00048 t42_parse_sfnts( T42_Face face,
00049 T42_Loader loader );
00050
00051
00052
00053
00054 static const
00055 T1_FieldRec t42_keywords[] = {
00056
00057 #undef FT_STRUCTURE
00058 #define FT_STRUCTURE T1_FontInfo
00059 #undef T1CODE
00060 #define T1CODE T1_FIELD_LOCATION_FONT_INFO
00061
00062 T1_FIELD_STRING( "version", version, 0 )
00063 T1_FIELD_STRING( "Notice", notice, 0 )
00064 T1_FIELD_STRING( "FullName", full_name, 0 )
00065 T1_FIELD_STRING( "FamilyName", family_name, 0 )
00066 T1_FIELD_STRING( "Weight", weight, 0 )
00067 T1_FIELD_NUM ( "ItalicAngle", italic_angle, 0 )
00068 T1_FIELD_BOOL ( "isFixedPitch", is_fixed_pitch, 0 )
00069 T1_FIELD_NUM ( "UnderlinePosition", underline_position, 0 )
00070 T1_FIELD_NUM ( "UnderlineThickness", underline_thickness, 0 )
00071
00072 #undef FT_STRUCTURE
00073 #define FT_STRUCTURE PS_FontExtraRec
00074 #undef T1CODE
00075 #define T1CODE T1_FIELD_LOCATION_FONT_EXTRA
00076
00077 T1_FIELD_NUM ( "FSType", fs_type, 0 )
00078
00079 #undef FT_STRUCTURE
00080 #define FT_STRUCTURE T1_FontRec
00081 #undef T1CODE
00082 #define T1CODE T1_FIELD_LOCATION_FONT_DICT
00083
00084 T1_FIELD_KEY ( "FontName", font_name, 0 )
00085 T1_FIELD_NUM ( "PaintType", paint_type, 0 )
00086 T1_FIELD_NUM ( "FontType", font_type, 0 )
00087 T1_FIELD_FIXED( "StrokeWidth", stroke_width, 0 )
00088
00089 #undef FT_STRUCTURE
00090 #define FT_STRUCTURE FT_BBox
00091 #undef T1CODE
00092 #define T1CODE T1_FIELD_LOCATION_BBOX
00093
00094 T1_FIELD_BBOX("FontBBox", xMin, 0 )
00095
00096 T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix, 0 )
00097 T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding, 0 )
00098 T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings, 0 )
00099 T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts, 0 )
00100
00101 { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0, 0 }
00102 };
00103
00104
00105 #define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l )
00106 #define T1_Done_Table( p ) \
00107 do \
00108 { \
00109 if ( (p)->funcs.done ) \
00110 (p)->funcs.done( p ); \
00111 } while ( 0 )
00112 #define T1_Release_Table( p ) \
00113 do \
00114 { \
00115 if ( (p)->funcs.release ) \
00116 (p)->funcs.release( p ); \
00117 } while ( 0 )
00118
00119 #define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
00120 #define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root )
00121
00122 #define T1_ToInt( p ) \
00123 (p)->root.funcs.to_int( &(p)->root )
00124 #define T1_ToBytes( p, b, m, n, d ) \
00125 (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d )
00126
00127 #define T1_ToFixedArray( p, m, f, t ) \
00128 (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )
00129 #define T1_ToToken( p, t ) \
00130 (p)->root.funcs.to_token( &(p)->root, t )
00131
00132 #define T1_Load_Field( p, f, o, m, pf ) \
00133 (p)->root.funcs.load_field( &(p)->root, f, o, m, pf )
00134 #define T1_Load_Field_Table( p, f, o, m, pf ) \
00135 (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf )
00136
00137
00138
00139
00140 FT_LOCAL_DEF( FT_Error )
00141 t42_parser_init( T42_Parser parser,
00142 FT_Stream stream,
00143 FT_Memory memory,
00144 PSAux_Service psaux )
00145 {
00146 FT_Error error = T42_Err_Ok;
00147 FT_Long size;
00148
00149
00150 psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
00151
00152 parser->stream = stream;
00153 parser->base_len = 0;
00154 parser->base_dict = 0;
00155 parser->in_memory = 0;
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 if ( FT_STREAM_SEEK( 0L ) ||
00172 FT_FRAME_ENTER( 17 ) )
00173 goto Exit;
00174
00175 if ( ft_memcmp( stream->cursor, "%!PS-TrueTypeFont", 17 ) != 0 )
00176 {
00177 FT_TRACE2(( "not a Type42 font\n" ));
00178 error = T42_Err_Unknown_File_Format;
00179 }
00180
00181 FT_FRAME_EXIT();
00182
00183 if ( error || FT_STREAM_SEEK( 0 ) )
00184 goto Exit;
00185
00186 size = stream->size;
00187
00188
00189
00190
00191
00192 if ( !stream->read )
00193 {
00194 parser->base_dict = (FT_Byte*)stream->base + stream->pos;
00195 parser->base_len = size;
00196 parser->in_memory = 1;
00197
00198
00199 if ( FT_STREAM_SKIP( size ) )
00200 goto Exit;
00201 }
00202 else
00203 {
00204
00205 if ( FT_ALLOC( parser->base_dict, size ) ||
00206 FT_STREAM_READ( parser->base_dict, size ) )
00207 goto Exit;
00208
00209 parser->base_len = size;
00210 }
00211
00212 parser->root.base = parser->base_dict;
00213 parser->root.cursor = parser->base_dict;
00214 parser->root.limit = parser->root.cursor + parser->base_len;
00215
00216 Exit:
00217 if ( error && !parser->in_memory )
00218 FT_FREE( parser->base_dict );
00219
00220 return error;
00221 }
00222
00223
00224 FT_LOCAL_DEF( void )
00225 t42_parser_done( T42_Parser parser )
00226 {
00227 FT_Memory memory = parser->root.memory;
00228
00229
00230
00231 if ( !parser->in_memory )
00232 FT_FREE( parser->base_dict );
00233
00234 parser->root.funcs.done( &parser->root );
00235 }
00236
00237
00238 static int
00239 t42_is_space( FT_Byte c )
00240 {
00241 return ( c == ' ' || c == '\t' ||
00242 c == '\r' || c == '\n' || c == '\f' ||
00243 c == '\0' );
00244 }
00245
00246
00247 static void
00248 t42_parse_font_matrix( T42_Face face,
00249 T42_Loader loader )
00250 {
00251 T42_Parser parser = &loader->parser;
00252 FT_Matrix* matrix = &face->type1.font_matrix;
00253 FT_Vector* offset = &face->type1.font_offset;
00254 FT_Face root = (FT_Face)&face->root;
00255 FT_Fixed temp[6];
00256 FT_Fixed temp_scale;
00257
00258
00259 (void)T1_ToFixedArray( parser, 6, temp, 3 );
00260
00261 temp_scale = FT_ABS( temp[3] );
00262
00263
00264
00265
00266
00267 root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,
00268 temp_scale ) >> 16 );
00269
00270
00271 if ( temp_scale != 0x10000L ) {
00272 temp[0] = FT_DivFix( temp[0], temp_scale );
00273 temp[1] = FT_DivFix( temp[1], temp_scale );
00274 temp[2] = FT_DivFix( temp[2], temp_scale );
00275 temp[4] = FT_DivFix( temp[4], temp_scale );
00276 temp[5] = FT_DivFix( temp[5], temp_scale );
00277 temp[3] = 0x10000L;
00278 }
00279
00280 matrix->xx = temp[0];
00281 matrix->yx = temp[1];
00282 matrix->xy = temp[2];
00283 matrix->yy = temp[3];
00284
00285
00286 offset->x = temp[4] >> 16;
00287 offset->y = temp[5] >> 16;
00288 }
00289
00290
00291 static void
00292 t42_parse_encoding( T42_Face face,
00293 T42_Loader loader )
00294 {
00295 T42_Parser parser = &loader->parser;
00296 FT_Byte* cur;
00297 FT_Byte* limit = parser->root.limit;
00298
00299 PSAux_Service psaux = (PSAux_Service)face->psaux;
00300
00301
00302 T1_Skip_Spaces( parser );
00303 cur = parser->root.cursor;
00304 if ( cur >= limit )
00305 {
00306 FT_ERROR(( "t42_parse_encoding: out of bounds\n" ));
00307 parser->root.error = T42_Err_Invalid_File_Format;
00308 return;
00309 }
00310
00311
00312
00313 if ( ft_isdigit( *cur ) || *cur == '[' )
00314 {
00315 T1_Encoding encode = &face->type1.encoding;
00316 FT_UInt count, n;
00317 PS_Table char_table = &loader->encoding_table;
00318 FT_Memory memory = parser->root.memory;
00319 FT_Error error;
00320 FT_Bool only_immediates = 0;
00321
00322
00323
00324 if ( *cur == '[' )
00325 {
00326 count = 256;
00327 only_immediates = 1;
00328 parser->root.cursor++;
00329 }
00330 else
00331 count = (FT_UInt)T1_ToInt( parser );
00332
00333 T1_Skip_Spaces( parser );
00334 if ( parser->root.cursor >= limit )
00335 return;
00336
00337
00338 loader->num_chars = encode->num_chars = count;
00339 if ( FT_NEW_ARRAY( encode->char_index, count ) ||
00340 FT_NEW_ARRAY( encode->char_name, count ) ||
00341 FT_SET_ERROR( psaux->ps_table_funcs->init(
00342 char_table, count, memory ) ) )
00343 {
00344 parser->root.error = error;
00345 return;
00346 }
00347
00348
00349 for ( n = 0; n < count; n++ )
00350 {
00351 char* notdef = (char *)".notdef";
00352
00353
00354 T1_Add_Table( char_table, n, notdef, 8 );
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 n = 0;
00378 T1_Skip_Spaces( parser );
00379
00380 while ( parser->root.cursor < limit )
00381 {
00382 cur = parser->root.cursor;
00383
00384
00385 if ( *cur == 'd' && cur + 3 < limit )
00386 {
00387 if ( cur[1] == 'e' &&
00388 cur[2] == 'f' &&
00389 t42_is_space( cur[3] ) )
00390 {
00391 FT_TRACE6(( "encoding end\n" ));
00392 cur += 3;
00393 break;
00394 }
00395 }
00396 if ( *cur == ']' )
00397 {
00398 FT_TRACE6(( "encoding end\n" ));
00399 cur++;
00400 break;
00401 }
00402
00403
00404 if ( ft_isdigit( *cur ) || only_immediates )
00405 {
00406 FT_Int charcode;
00407
00408
00409 if ( only_immediates )
00410 charcode = n;
00411 else
00412 {
00413 charcode = (FT_Int)T1_ToInt( parser );
00414 T1_Skip_Spaces( parser );
00415 }
00416
00417 cur = parser->root.cursor;
00418
00419 if ( *cur == '/' && cur + 2 < limit && n < count )
00420 {
00421 FT_PtrDist len;
00422
00423
00424 cur++;
00425
00426 parser->root.cursor = cur;
00427 T1_Skip_PS_Token( parser );
00428 if ( parser->root.error )
00429 return;
00430
00431 len = parser->root.cursor - cur;
00432
00433 parser->root.error = T1_Add_Table( char_table, charcode,
00434 cur, len + 1 );
00435 if ( parser->root.error )
00436 return;
00437 char_table->elements[charcode][len] = '\0';
00438
00439 n++;
00440 }
00441 }
00442 else
00443 {
00444 T1_Skip_PS_Token( parser );
00445 if ( parser->root.error )
00446 return;
00447 }
00448
00449 T1_Skip_Spaces( parser );
00450 }
00451
00452 face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
00453 parser->root.cursor = cur;
00454 }
00455
00456
00457
00458 else
00459 {
00460 if ( cur + 17 < limit &&
00461 ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
00462 face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
00463
00464 else if ( cur + 15 < limit &&
00465 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
00466 face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
00467
00468 else if ( cur + 18 < limit &&
00469 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
00470 face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
00471
00472 else
00473 {
00474 FT_ERROR(( "t42_parse_encoding: invalid token\n" ));
00475 parser->root.error = T42_Err_Invalid_File_Format;
00476 }
00477 }
00478 }
00479
00480
00481 typedef enum T42_Load_Status_
00482 {
00483 BEFORE_START,
00484 BEFORE_TABLE_DIR,
00485 OTHER_TABLES
00486
00487 } T42_Load_Status;
00488
00489
00490 static void
00491 t42_parse_sfnts( T42_Face face,
00492 T42_Loader loader )
00493 {
00494 T42_Parser parser = &loader->parser;
00495 FT_Memory memory = parser->root.memory;
00496 FT_Byte* cur;
00497 FT_Byte* limit = parser->root.limit;
00498 FT_Error error;
00499 FT_Int num_tables = 0;
00500 FT_ULong count, ttf_size = 0;
00501
00502 FT_Long n, string_size, old_string_size, real_size;
00503 FT_Byte* string_buf = NULL;
00504 FT_Bool allocated = 0;
00505
00506 T42_Load_Status status;
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 T1_Skip_Spaces( parser );
00524
00525 if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' )
00526 {
00527 FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" ));
00528 error = T42_Err_Invalid_File_Format;
00529 goto Fail;
00530 }
00531
00532 T1_Skip_Spaces( parser );
00533 status = BEFORE_START;
00534 string_size = 0;
00535 old_string_size = 0;
00536 count = 0;
00537
00538 while ( parser->root.cursor < limit )
00539 {
00540 cur = parser->root.cursor;
00541
00542 if ( *cur == ']' )
00543 {
00544 parser->root.cursor++;
00545 goto Exit;
00546 }
00547
00548 else if ( *cur == '<' )
00549 {
00550 T1_Skip_PS_Token( parser );
00551 if ( parser->root.error )
00552 goto Exit;
00553
00554
00555 string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 );
00556 if ( FT_REALLOC( string_buf, old_string_size, string_size ) )
00557 goto Fail;
00558
00559 allocated = 1;
00560
00561 parser->root.cursor = cur;
00562 (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );
00563 old_string_size = string_size;
00564 string_size = real_size;
00565 }
00566
00567 else if ( ft_isdigit( *cur ) )
00568 {
00569 if ( allocated )
00570 {
00571 FT_ERROR(( "t42_parse_sfnts: "
00572 "can't handle mixed binary and hex strings\n" ));
00573 error = T42_Err_Invalid_File_Format;
00574 goto Fail;
00575 }
00576
00577 string_size = T1_ToInt( parser );
00578
00579 T1_Skip_PS_Token( parser );
00580 if ( parser->root.error )
00581 return;
00582
00583 string_buf = parser->root.cursor + 1;
00584
00585 parser->root.cursor += string_size + 1;
00586 if ( parser->root.cursor >= limit )
00587 {
00588 FT_ERROR(( "t42_parse_sfnts: too many binary data\n" ));
00589 error = T42_Err_Invalid_File_Format;
00590 goto Fail;
00591 }
00592 }
00593
00594 if ( !string_buf )
00595 {
00596 FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" ));
00597 error = T42_Err_Invalid_File_Format;
00598 goto Fail;
00599 }
00600
00601
00602 if ( string_buf[string_size - 1] == 0 && ( string_size % 2 == 1 ) )
00603 string_size--;
00604
00605 if ( !string_size )
00606 {
00607 FT_ERROR(( "t42_parse_sfnts: invalid string\n" ));
00608 error = T42_Err_Invalid_File_Format;
00609 goto Fail;
00610 }
00611
00612 for ( n = 0; n < string_size; n++ )
00613 {
00614 switch ( status )
00615 {
00616 case BEFORE_START:
00617
00618 if ( count < 12 )
00619 {
00620 face->ttf_data[count++] = string_buf[n];
00621 continue;
00622 }
00623 else
00624 {
00625 num_tables = 16 * face->ttf_data[4] + face->ttf_data[5];
00626 status = BEFORE_TABLE_DIR;
00627 ttf_size = 12 + 16 * num_tables;
00628
00629 if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) )
00630 goto Fail;
00631 }
00632
00633
00634 case BEFORE_TABLE_DIR:
00635
00636 if ( count < ttf_size )
00637 {
00638 face->ttf_data[count++] = string_buf[n];
00639 continue;
00640 }
00641 else
00642 {
00643 int i;
00644 FT_ULong len;
00645
00646
00647 for ( i = 0; i < num_tables; i++ )
00648 {
00649 FT_Byte* p = face->ttf_data + 12 + 16 * i + 12;
00650
00651
00652 len = FT_PEEK_ULONG( p );
00653
00654
00655 ttf_size += ( len + 3 ) & ~3;
00656 }
00657
00658 status = OTHER_TABLES;
00659 face->ttf_size = ttf_size;
00660
00661
00662 if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables,
00663 ttf_size + 1 ) )
00664 goto Fail;
00665 }
00666
00667
00668 case OTHER_TABLES:
00669
00670 if ( count >= ttf_size )
00671 {
00672 FT_ERROR(( "t42_parse_sfnts: too many binary data\n" ));
00673 error = T42_Err_Invalid_File_Format;
00674 goto Fail;
00675 }
00676 face->ttf_data[count++] = string_buf[n];
00677 }
00678 }
00679
00680 T1_Skip_Spaces( parser );
00681 }
00682
00683
00684 error = T42_Err_Invalid_File_Format;
00685
00686 Fail:
00687 parser->root.error = error;
00688
00689 Exit:
00690 if ( allocated )
00691 FT_FREE( string_buf );
00692 }
00693
00694
00695 static void
00696 t42_parse_charstrings( T42_Face face,
00697 T42_Loader loader )
00698 {
00699 T42_Parser parser = &loader->parser;
00700 PS_Table code_table = &loader->charstrings;
00701 PS_Table name_table = &loader->glyph_names;
00702 PS_Table swap_table = &loader->swap_table;
00703 FT_Memory memory = parser->root.memory;
00704 FT_Error error;
00705
00706 PSAux_Service psaux = (PSAux_Service)face->psaux;
00707
00708 FT_Byte* cur;
00709 FT_Byte* limit = parser->root.limit;
00710 FT_UInt n;
00711 FT_UInt notdef_index = 0;
00712 FT_Byte notdef_found = 0;
00713
00714
00715 T1_Skip_Spaces( parser );
00716
00717 if ( parser->root.cursor >= limit )
00718 {
00719 FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));
00720 error = T42_Err_Invalid_File_Format;
00721 goto Fail;
00722 }
00723
00724 if ( ft_isdigit( *parser->root.cursor ) )
00725 {
00726 loader->num_glyphs = (FT_UInt)T1_ToInt( parser );
00727 if ( parser->root.error )
00728 return;
00729 }
00730 else if ( *parser->root.cursor == '<' )
00731 {
00732
00733
00734 FT_UInt count = 0;
00735
00736
00737 T1_Skip_PS_Token( parser );
00738 if ( parser->root.error )
00739 return;
00740 T1_Skip_Spaces( parser );
00741 cur = parser->root.cursor;
00742
00743 while ( parser->root.cursor < limit )
00744 {
00745 if ( *parser->root.cursor == '/' )
00746 count++;
00747 else if ( *parser->root.cursor == '>' )
00748 {
00749 loader->num_glyphs = count;
00750 parser->root.cursor = cur;
00751 break;
00752 }
00753 T1_Skip_PS_Token( parser );
00754 if ( parser->root.error )
00755 return;
00756 T1_Skip_Spaces( parser );
00757 }
00758 }
00759 else
00760 {
00761 FT_ERROR(( "t42_parse_charstrings: invalid token\n" ));
00762 error = T42_Err_Invalid_File_Format;
00763 goto Fail;
00764 }
00765
00766 if ( parser->root.cursor >= limit )
00767 {
00768 FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));
00769 error = T42_Err_Invalid_File_Format;
00770 goto Fail;
00771 }
00772
00773
00774
00775 error = psaux->ps_table_funcs->init( code_table,
00776 loader->num_glyphs,
00777 memory );
00778 if ( error )
00779 goto Fail;
00780
00781 error = psaux->ps_table_funcs->init( name_table,
00782 loader->num_glyphs,
00783 memory );
00784 if ( error )
00785 goto Fail;
00786
00787
00788
00789
00790 error = psaux->ps_table_funcs->init( swap_table, 4, memory );
00791 if ( error )
00792 goto Fail;
00793
00794 n = 0;
00795
00796 for (;;)
00797 {
00798
00799
00800
00801 T1_Skip_Spaces( parser );
00802
00803 cur = parser->root.cursor;
00804 if ( cur >= limit )
00805 break;
00806
00807
00808 if ( *cur == 'e' &&
00809 cur + 3 < limit &&
00810 cur[1] == 'n' &&
00811 cur[2] == 'd' &&
00812 t42_is_space( cur[3] ) )
00813 break;
00814 if ( *cur == '>' )
00815 break;
00816
00817 T1_Skip_PS_Token( parser );
00818 if ( parser->root.error )
00819 return;
00820
00821 if ( *cur == '/' )
00822 {
00823 FT_PtrDist len;
00824
00825
00826 if ( cur + 1 >= limit )
00827 {
00828 FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));
00829 error = T42_Err_Invalid_File_Format;
00830 goto Fail;
00831 }
00832
00833 cur++;
00834 len = parser->root.cursor - cur;
00835
00836 error = T1_Add_Table( name_table, n, cur, len + 1 );
00837 if ( error )
00838 goto Fail;
00839
00840
00841 name_table->elements[n][len] = '\0';
00842
00843
00844 if ( *cur == '.' &&
00845 ft_strcmp( ".notdef",
00846 (const char*)(name_table->elements[n]) ) == 0 )
00847 {
00848 notdef_index = n;
00849 notdef_found = 1;
00850 }
00851
00852 T1_Skip_Spaces( parser );
00853
00854 cur = parser->root.cursor;
00855
00856 (void)T1_ToInt( parser );
00857 if ( parser->root.cursor >= limit )
00858 {
00859 FT_ERROR(( "t42_parse_charstrings: out of bounds\n" ));
00860 error = T42_Err_Invalid_File_Format;
00861 goto Fail;
00862 }
00863
00864 len = parser->root.cursor - cur;
00865
00866 error = T1_Add_Table( code_table, n, cur, len + 1 );
00867 if ( error )
00868 goto Fail;
00869
00870 code_table->elements[n][len] = '\0';
00871
00872 n++;
00873 if ( n >= loader->num_glyphs )
00874 break;
00875 }
00876 }
00877
00878 loader->num_glyphs = n;
00879
00880 if ( !notdef_found )
00881 {
00882 FT_ERROR(( "t42_parse_charstrings: no /.notdef glyph\n" ));
00883 error = T42_Err_Invalid_File_Format;
00884 goto Fail;
00885 }
00886
00887
00888 if ( ft_strcmp( (const char*)".notdef",
00889 (const char*)name_table->elements[0] ) )
00890 {
00891
00892
00893
00894
00895
00896
00897
00898 error = T1_Add_Table( swap_table, 0,
00899 name_table->elements[0],
00900 name_table->lengths [0] );
00901 if ( error )
00902 goto Fail;
00903
00904
00905 error = T1_Add_Table( swap_table, 1,
00906 code_table->elements[0],
00907 code_table->lengths [0] );
00908 if ( error )
00909 goto Fail;
00910
00911
00912 error = T1_Add_Table( swap_table, 2,
00913 name_table->elements[notdef_index],
00914 name_table->lengths [notdef_index] );
00915 if ( error )
00916 goto Fail;
00917
00918
00919 error = T1_Add_Table( swap_table, 3,
00920 code_table->elements[notdef_index],
00921 code_table->lengths [notdef_index] );
00922 if ( error )
00923 goto Fail;
00924
00925 error = T1_Add_Table( name_table, notdef_index,
00926 swap_table->elements[0],
00927 swap_table->lengths [0] );
00928 if ( error )
00929 goto Fail;
00930
00931 error = T1_Add_Table( code_table, notdef_index,
00932 swap_table->elements[1],
00933 swap_table->lengths [1] );
00934 if ( error )
00935 goto Fail;
00936
00937 error = T1_Add_Table( name_table, 0,
00938 swap_table->elements[2],
00939 swap_table->lengths [2] );
00940 if ( error )
00941 goto Fail;
00942
00943 error = T1_Add_Table( code_table, 0,
00944 swap_table->elements[3],
00945 swap_table->lengths [3] );
00946 if ( error )
00947 goto Fail;
00948
00949 }
00950
00951 return;
00952
00953 Fail:
00954 parser->root.error = error;
00955 }
00956
00957
00958 static FT_Error
00959 t42_load_keyword( T42_Face face,
00960 T42_Loader loader,
00961 T1_Field field )
00962 {
00963 FT_Error error;
00964 void* dummy_object;
00965 void** objects;
00966 FT_UInt max_objects = 0;
00967
00968
00969
00970 if ( field->type == T1_FIELD_TYPE_CALLBACK )
00971 {
00972 field->reader( (FT_Face)face, loader );
00973 error = loader->parser.root.error;
00974 goto Exit;
00975 }
00976
00977
00978
00979
00980 switch ( field->location )
00981 {
00982 case T1_FIELD_LOCATION_FONT_INFO:
00983 dummy_object = &face->type1.font_info;
00984 break;
00985
00986 case T1_FIELD_LOCATION_FONT_EXTRA:
00987 dummy_object = &face->type1.font_extra;
00988 break;
00989
00990 case T1_FIELD_LOCATION_BBOX:
00991 dummy_object = &face->type1.font_bbox;
00992 break;
00993
00994 default:
00995 dummy_object = &face->type1;
00996 }
00997
00998 objects = &dummy_object;
00999
01000 if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
01001 field->type == T1_FIELD_TYPE_FIXED_ARRAY )
01002 error = T1_Load_Field_Table( &loader->parser, field,
01003 objects, max_objects, 0 );
01004 else
01005 error = T1_Load_Field( &loader->parser, field,
01006 objects, max_objects, 0 );
01007
01008 Exit:
01009 return error;
01010 }
01011
01012
01013 FT_LOCAL_DEF( FT_Error )
01014 t42_parse_dict( T42_Face face,
01015 T42_Loader loader,
01016 FT_Byte* base,
01017 FT_Long size )
01018 {
01019 T42_Parser parser = &loader->parser;
01020 FT_Byte* limit;
01021 FT_Int n_keywords = (FT_Int)( sizeof ( t42_keywords ) /
01022 sizeof ( t42_keywords[0] ) );
01023
01024
01025 parser->root.cursor = base;
01026 parser->root.limit = base + size;
01027 parser->root.error = T42_Err_Ok;
01028
01029 limit = parser->root.limit;
01030
01031 T1_Skip_Spaces( parser );
01032
01033 while ( parser->root.cursor < limit )
01034 {
01035 FT_Byte* cur;
01036
01037
01038 cur = parser->root.cursor;
01039
01040
01041 if ( *cur == 'F' && cur + 25 < limit &&
01042 ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )
01043 {
01044 FT_Byte* cur2;
01045
01046
01047
01048 T1_Skip_PS_Token( parser );
01049 T1_Skip_Spaces ( parser );
01050 cur = cur2 = parser->root.cursor;
01051
01052
01053 while ( cur < limit )
01054 {
01055 if ( *cur == 'k' && cur + 5 < limit &&
01056 ft_strncmp( (char*)cur, "known", 5 ) == 0 )
01057 break;
01058
01059 T1_Skip_PS_Token( parser );
01060 if ( parser->root.error )
01061 goto Exit;
01062 T1_Skip_Spaces ( parser );
01063 cur = parser->root.cursor;
01064 }
01065
01066 if ( cur < limit )
01067 {
01068 T1_TokenRec token;
01069
01070
01071
01072 T1_Skip_PS_Token( parser );
01073 T1_ToToken( parser, &token );
01074
01075
01076 if ( token.type == T1_TOKEN_TYPE_ARRAY )
01077 cur2 = parser->root.cursor;
01078 }
01079 parser->root.cursor = cur2;
01080 }
01081
01082
01083 else if ( *cur == '/' && cur + 2 < limit )
01084 {
01085 FT_PtrDist len;
01086
01087
01088 cur++;
01089
01090 parser->root.cursor = cur;
01091 T1_Skip_PS_Token( parser );
01092 if ( parser->root.error )
01093 goto Exit;
01094
01095 len = parser->root.cursor - cur;
01096
01097 if ( len > 0 && len < 22 && parser->root.cursor < limit )
01098 {
01099 int i;
01100
01101
01102
01103
01104
01105 for ( i = 0; i < n_keywords; i++ )
01106 {
01107 T1_Field keyword = (T1_Field)&t42_keywords[i];
01108 FT_Byte *name = (FT_Byte*)keyword->ident;
01109
01110
01111 if ( !name )
01112 continue;
01113
01114 if ( cur[0] == name[0] &&
01115 len == (FT_PtrDist)ft_strlen( (const char *)name ) &&
01116 ft_memcmp( cur, name, len ) == 0 )
01117 {
01118
01119 parser->root.error = t42_load_keyword( face,
01120 loader,
01121 keyword );
01122 if ( parser->root.error )
01123 return parser->root.error;
01124 break;
01125 }
01126 }
01127 }
01128 }
01129 else
01130 {
01131 T1_Skip_PS_Token( parser );
01132 if ( parser->root.error )
01133 goto Exit;
01134 }
01135
01136 T1_Skip_Spaces( parser );
01137 }
01138
01139 Exit:
01140 return parser->root.error;
01141 }
01142
01143
01144 FT_LOCAL_DEF( void )
01145 t42_loader_init( T42_Loader loader,
01146 T42_Face face )
01147 {
01148 FT_UNUSED( face );
01149
01150 FT_MEM_ZERO( loader, sizeof ( *loader ) );
01151 loader->num_glyphs = 0;
01152 loader->num_chars = 0;
01153
01154
01155 loader->encoding_table.init = 0;
01156 loader->charstrings.init = 0;
01157 loader->glyph_names.init = 0;
01158 }
01159
01160
01161 FT_LOCAL_DEF( void )
01162 t42_loader_done( T42_Loader loader )
01163 {
01164 T42_Parser parser = &loader->parser;
01165
01166
01167
01168 T1_Release_Table( &loader->encoding_table );
01169 T1_Release_Table( &loader->charstrings );
01170 T1_Release_Table( &loader->glyph_names );
01171 T1_Release_Table( &loader->swap_table );
01172
01173
01174 t42_parser_done( parser );
01175 }
01176
01177
01178