33#define FT_COMPONENT t42
37 t42_parse_font_matrix( FT_Face face,
40 t42_parse_encoding( FT_Face face,
44 t42_parse_charstrings( FT_Face face,
48 t42_parse_sfnts( FT_Face face,
55 T1_FieldRec t42_keywords[] =
59#define FT_STRUCTURE T1_FontInfo
61#define T1CODE T1_FIELD_LOCATION_FONT_INFO
63 T1_FIELD_STRING(
"version", version, 0 )
64 T1_FIELD_STRING(
"Notice", notice, 0 )
65 T1_FIELD_STRING(
"FullName", full_name, 0 )
66 T1_FIELD_STRING(
"FamilyName", family_name, 0 )
67 T1_FIELD_STRING(
"Weight", weight, 0 )
68 T1_FIELD_NUM (
"ItalicAngle", italic_angle, 0 )
69 T1_FIELD_BOOL (
"isFixedPitch", is_fixed_pitch, 0 )
70 T1_FIELD_NUM (
"UnderlinePosition", underline_position, 0 )
71 T1_FIELD_NUM (
"UnderlineThickness", underline_thickness, 0 )
74#define FT_STRUCTURE PS_FontExtraRec
76#define T1CODE T1_FIELD_LOCATION_FONT_EXTRA
78 T1_FIELD_NUM (
"FSType", fs_type, 0 )
81#define FT_STRUCTURE T1_FontRec
83#define T1CODE T1_FIELD_LOCATION_FONT_DICT
85 T1_FIELD_KEY (
"FontName", font_name, 0 )
86 T1_FIELD_NUM (
"PaintType", paint_type, 0 )
87 T1_FIELD_NUM (
"FontType", font_type, 0 )
88 T1_FIELD_FIXED(
"StrokeWidth", stroke_width, 0 )
91#define FT_STRUCTURE FT_BBox
93#define T1CODE T1_FIELD_LOCATION_BBOX
95 T1_FIELD_BBOX(
"FontBBox", xMin, 0 )
97 T1_FIELD_CALLBACK(
"FontMatrix", t42_parse_font_matrix, 0 )
98 T1_FIELD_CALLBACK(
"Encoding", t42_parse_encoding, 0 )
99 T1_FIELD_CALLBACK(
"CharStrings", t42_parse_charstrings, 0 )
100 T1_FIELD_CALLBACK(
"sfnts", t42_parse_sfnts, 0 )
106#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l )
107#define T1_Release_Table( p ) \
110 if ( (p)->funcs.release ) \
111 (p)->funcs.release( p ); \
114#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
115#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root )
117#define T1_ToInt( p ) \
118 (p)->root.funcs.to_int( &(p)->root )
119#define T1_ToBytes( p, b, m, n, d ) \
120 (p)->root.funcs.to_bytes( &(p)->root, b, m, n, d )
122#define T1_ToFixedArray( p, m, f, t ) \
123 (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t )
124#define T1_ToToken( p, t ) \
125 (p)->root.funcs.to_token( &(p)->root, t )
127#define T1_Load_Field( p, f, o, m, pf ) \
128 (p)->root.funcs.load_field( &(p)->root, f, o, m, pf )
129#define T1_Load_Field_Table( p, f, o, m, pf ) \
130 (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf )
135 FT_LOCAL_DEF( FT_Error )
136 t42_parser_init( T42_Parser parser,
139 PSAux_Service psaux )
141 FT_Error error = FT_Err_Ok;
145 psaux->ps_parser_funcs->init( &parser->root, NULL, NULL, memory );
147 parser->stream = stream;
148 parser->base_len = 0;
149 parser->base_dict = NULL;
150 parser->in_memory = 0;
166 if ( FT_STREAM_SEEK( 0L ) ||
167 FT_FRAME_ENTER( 17 ) )
170 if ( ft_memcmp( stream->cursor,
"%!PS-TrueTypeFont", 17 ) != 0 )
172 FT_TRACE2((
" not a Type42 font\n" ));
173 error = FT_THROW( Unknown_File_Format );
178 if ( error || FT_STREAM_SEEK( 0 ) )
181 size = (FT_Long)stream->size;
189 parser->base_dict = (FT_Byte*)stream->base + stream->pos;
190 parser->base_len = size;
191 parser->in_memory = 1;
194 if ( FT_STREAM_SKIP( size ) )
200 if ( FT_QALLOC( parser->base_dict, size ) ||
201 FT_STREAM_READ( parser->base_dict, size ) )
204 parser->base_len = size;
207 parser->root.base = parser->base_dict;
208 parser->root.cursor = parser->base_dict;
209 parser->root.limit = parser->root.cursor + parser->base_len;
212 if ( error && !parser->in_memory )
213 FT_FREE( parser->base_dict );
220 t42_parser_done( T42_Parser parser )
222 FT_Memory memory = parser->root.memory;
226 if ( !parser->in_memory )
227 FT_FREE( parser->base_dict );
229 if ( parser->root.funcs.done )
230 parser->root.funcs.done( &parser->root );
235 t42_is_space( FT_Byte c )
237 return ( c ==
' ' || c ==
'\t' ||
238 c ==
'\r' || c ==
'\n' || c ==
'\f' ||
244 t42_parse_font_matrix( FT_Face face,
247 T42_Face t42face = (T42_Face)face;
248 T42_Loader loader = (T42_Loader)loader_;
249 T42_Parser parser = &loader->parser;
250 FT_Matrix* matrix = &t42face->type1.font_matrix;
251 FT_Vector* offset = &t42face->type1.font_offset;
257 result = T1_ToFixedArray( parser, 6, temp, 0 );
261 parser->root.error = FT_THROW( Invalid_File_Format );
265 temp_scale = FT_ABS( temp[3] );
267 if ( temp_scale == 0 )
269 FT_ERROR((
"t42_parse_font_matrix: invalid font matrix\n" ));
270 parser->root.error = FT_THROW( Invalid_File_Format );
275 if ( temp_scale != 0x10000L )
277 temp[0] = FT_DivFix( temp[0], temp_scale );
278 temp[1] = FT_DivFix( temp[1], temp_scale );
279 temp[2] = FT_DivFix( temp[2], temp_scale );
280 temp[4] = FT_DivFix( temp[4], temp_scale );
281 temp[5] = FT_DivFix( temp[5], temp_scale );
282 temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
285 matrix->xx = temp[0];
286 matrix->yx = temp[1];
287 matrix->xy = temp[2];
288 matrix->yy = temp[3];
290 if ( !FT_Matrix_Check( matrix ) )
292 FT_ERROR((
"t42_parse_font_matrix: invalid font matrix\n" ));
293 parser->root.error = FT_THROW( Invalid_File_Format );
298 offset->x = temp[4] >> 16;
299 offset->y = temp[5] >> 16;
304 t42_parse_encoding( FT_Face face,
307 T42_Face t42face = (T42_Face)face;
308 T42_Loader loader = (T42_Loader)loader_;
309 T42_Parser parser = &loader->parser;
311 FT_Byte* limit = parser->root.limit;
313 PSAux_Service psaux = (PSAux_Service)t42face->psaux;
316 T1_Skip_Spaces( parser );
317 cur = parser->root.cursor;
320 FT_ERROR((
"t42_parse_encoding: out of bounds\n" ));
321 parser->root.error = FT_THROW( Invalid_File_Format );
327 if ( ft_isdigit( *cur ) || *cur ==
'[' )
329 T1_Encoding encode = &t42face->type1.encoding;
331 PS_Table char_table = &loader->encoding_table;
332 FT_Memory memory = parser->root.memory;
334 FT_Bool only_immediates = 0;
342 parser->root.cursor++;
345 count = (FT_Int)T1_ToInt( parser );
351 FT_ERROR((
"t42_parse_encoding: invalid encoding array size\n" ));
352 parser->root.error = FT_THROW( Invalid_File_Format );
356 T1_Skip_Spaces( parser );
357 if ( parser->root.cursor >= limit )
361 if ( encode->char_index )
363 FT_FREE( encode->char_index );
364 FT_FREE( encode->char_name );
365 T1_Release_Table( char_table );
369 loader->num_chars = encode->num_chars = count;
370 if ( FT_QNEW_ARRAY( encode->char_index, count ) ||
371 FT_QNEW_ARRAY( encode->char_name, count ) ||
372 FT_SET_ERROR( psaux->ps_table_funcs->init(
373 char_table, count, memory ) ) )
375 parser->root.error = error;
380 for ( n = 0; n < count; n++ )
381 (
void)T1_Add_Table( char_table, n,
".notdef", 8 );
404 T1_Skip_Spaces( parser );
406 while ( parser->root.cursor < limit )
408 cur = parser->root.cursor;
411 if ( *cur ==
'd' && cur + 3 < limit )
413 if ( cur[1] ==
'e' &&
415 t42_is_space( cur[3] ) )
417 FT_TRACE6((
"encoding end\n" ));
424 FT_TRACE6((
"encoding end\n" ));
430 if ( ft_isdigit( *cur ) || only_immediates )
435 if ( only_immediates )
439 charcode = (FT_Int)T1_ToInt( parser );
440 T1_Skip_Spaces( parser );
443 if ( cur == parser->root.cursor )
445 parser->root.error = FT_THROW( Unknown_File_Format );
450 cur = parser->root.cursor;
452 if ( cur + 2 < limit && *cur ==
'/' && n < count )
459 parser->root.cursor = cur;
460 T1_Skip_PS_Token( parser );
461 if ( parser->root.cursor >= limit )
463 if ( parser->root.error )
466 len = (FT_UInt)( parser->root.cursor - cur );
468 parser->root.error = T1_Add_Table( char_table, charcode,
470 if ( parser->root.error )
472 char_table->elements[charcode][len] =
'\0';
476 else if ( only_immediates )
486 parser->root.error = FT_THROW( Unknown_File_Format );
492 T1_Skip_PS_Token( parser );
493 if ( parser->root.error )
497 T1_Skip_Spaces( parser );
500 t42face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
501 parser->root.cursor = cur;
508 if ( cur + 17 < limit &&
509 ft_strncmp( (
const char*)cur,
"StandardEncoding", 16 ) == 0 )
510 t42face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
512 else if ( cur + 15 < limit &&
513 ft_strncmp( (
const char*)cur,
"ExpertEncoding", 14 ) == 0 )
514 t42face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
516 else if ( cur + 18 < limit &&
517 ft_strncmp( (
const char*)cur,
"ISOLatin1Encoding", 17 ) == 0 )
518 t42face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
521 parser->root.error = FT_ERR( Ignore );
526 typedef enum T42_Load_Status_
536 t42_parse_sfnts( FT_Face face,
539 T42_Face t42face = (T42_Face)face;
540 T42_Loader loader = (T42_Loader)loader_;
541 T42_Parser parser = &loader->parser;
542 FT_Memory memory = parser->root.memory;
544 FT_Byte* limit = parser->root.limit;
546 FT_Int num_tables = 0;
548 FT_Long ttf_reserved;
550 FT_ULong n, string_size, old_string_size, real_size;
551 FT_Byte* string_buf = NULL;
552 FT_Bool allocated = 0;
554 T42_Load_Status status;
557 FT_FREE( t42face->ttf_data );
558 t42face->ttf_size = 0;
574 T1_Skip_Spaces( parser );
576 if ( parser->root.cursor >= limit || *parser->root.cursor++ !=
'[' )
578 FT_ERROR((
"t42_parse_sfnts: can't find begin of sfnts vector\n" ));
579 error = FT_THROW( Invalid_File_Format );
583 T1_Skip_Spaces( parser );
584 status = BEFORE_START;
589 if ( FT_QALLOC( t42face->ttf_data, ttf_reserved ) )
593 FT_TRACE2((
"t42_parse_sfnts:\n" ));
595 while ( parser->root.cursor < limit )
600 cur = parser->root.cursor;
604 parser->root.cursor++;
605 t42face->ttf_size = ttf_count;
609 else if ( *cur ==
'<' )
611 if ( string_buf && !allocated )
613 FT_ERROR((
"t42_parse_sfnts: "
614 "can't handle mixed binary and hex strings\n" ));
615 error = FT_THROW( Invalid_File_Format );
619 T1_Skip_PS_Token( parser );
620 if ( parser->root.error )
624 string_size = (FT_ULong)( ( parser->root.cursor - cur - 2 + 1 ) / 2 );
627 FT_ERROR((
"t42_parse_sfnts: invalid data in sfnts array\n" ));
628 error = FT_THROW( Invalid_File_Format );
631 if ( FT_QREALLOC( string_buf, old_string_size, string_size ) )
636 parser->root.cursor = cur;
637 (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 );
638 old_string_size = string_size;
639 string_size = real_size;
642 else if ( ft_isdigit( *cur ) )
649 FT_ERROR((
"t42_parse_sfnts: "
650 "can't handle mixed binary and hex strings\n" ));
651 error = FT_THROW( Invalid_File_Format );
655 tmp = T1_ToInt( parser );
658 FT_ERROR((
"t42_parse_sfnts: invalid string size\n" ));
659 error = FT_THROW( Invalid_File_Format );
663 string_size = (FT_ULong)tmp;
665 T1_Skip_PS_Token( parser );
666 if ( parser->root.error )
669 string_buf = parser->root.cursor + 1;
671 if ( (FT_ULong)( limit - parser->root.cursor ) <= string_size )
673 FT_ERROR((
"t42_parse_sfnts: too much binary data\n" ));
674 error = FT_THROW( Invalid_File_Format );
678 parser->root.cursor += string_size + 1;
683 FT_ERROR((
"t42_parse_sfnts: invalid data in sfnts array\n" ));
684 error = FT_THROW( Invalid_File_Format );
690 if ( ( string_size & 1 ) && string_buf[string_size - 1] == 0 )
695 FT_ERROR((
"t42_parse_sfnts: invalid string\n" ));
696 error = FT_THROW( Invalid_File_Format );
700 FT_TRACE2((
" PS string size %5lu bytes, offset 0x%08lx (%ld)\n",
701 string_size, ttf_count, ttf_count ));
706 size = (FT_ULong)( limit - parser->root.cursor );
708 for ( n = 0; n < string_size; n++ )
714 if ( ttf_count < 12 )
716 t42face->ttf_data[ttf_count++] = string_buf[n];
721 FT_Long ttf_reserved_prev = ttf_reserved;
724 num_tables = 16 * t42face->ttf_data[4] + t42face->ttf_data[5];
725 status = BEFORE_TABLE_DIR;
726 ttf_reserved = 12 + 16 * num_tables;
728 FT_TRACE2((
" SFNT directory contains %d tables\n",
731 if ( (FT_Long)size < ttf_reserved )
733 FT_ERROR((
"t42_parse_sfnts: invalid data in sfnts array\n" ));
734 error = FT_THROW( Invalid_File_Format );
738 if ( FT_QREALLOC( t42face->ttf_data, ttf_reserved_prev,
744 case BEFORE_TABLE_DIR:
746 if ( ttf_count < ttf_reserved )
748 t42face->ttf_data[ttf_count++] = string_buf[n];
755 FT_Long ttf_reserved_prev = ttf_reserved;
759 FT_TRACE2((
" table length\n" ));
760 FT_TRACE2((
" ------------------------------\n" ));
762 for ( i = 0; i < num_tables; i++ )
764 FT_Byte* p = t42face->ttf_data + 12 + 16 * i + 12;
767 len = FT_PEEK_ULONG( p );
768 FT_TRACE2((
" %4i 0x%08lx (%lu)\n", i, len, len ));
771 ttf_reserved > (FT_Long)( size - len ) )
773 FT_ERROR((
"t42_parse_sfnts:"
774 " invalid data in sfnts array\n" ));
775 error = FT_THROW( Invalid_File_Format );
780 ttf_reserved += (FT_Long)( ( len + 3 ) & ~3U );
784 status = OTHER_TABLES;
787 FT_TRACE2((
" allocating %ld bytes\n", ttf_reserved ));
790 if ( FT_QREALLOC( t42face->ttf_data, ttf_reserved_prev,
798 if ( ttf_count >= ttf_reserved )
800 FT_ERROR((
"t42_parse_sfnts: too much binary data\n" ));
801 error = FT_THROW( Invalid_File_Format );
804 t42face->ttf_data[ttf_count++] = string_buf[n];
808 T1_Skip_Spaces( parser );
812 error = FT_THROW( Invalid_File_Format );
815 parser->root.error = error;
818 if ( parser->root.error )
820 FT_FREE( t42face->ttf_data );
821 t42face->ttf_size = 0;
824 FT_FREE( string_buf );
829 t42_parse_charstrings( FT_Face face,
832 T42_Face t42face = (T42_Face)face;
833 T42_Loader loader = (T42_Loader)loader_;
834 T42_Parser parser = &loader->parser;
835 PS_Table code_table = &loader->charstrings;
836 PS_Table name_table = &loader->glyph_names;
837 PS_Table swap_table = &loader->swap_table;
838 FT_Memory memory = parser->root.memory;
841 PSAux_Service psaux = (PSAux_Service)t42face->psaux;
844 FT_Byte* limit = parser->root.limit;
846 FT_Int notdef_index = 0;
847 FT_Byte notdef_found = 0;
850 T1_Skip_Spaces( parser );
852 if ( parser->root.cursor >= limit )
854 FT_ERROR((
"t42_parse_charstrings: out of bounds\n" ));
855 error = FT_THROW( Invalid_File_Format );
859 if ( ft_isdigit( *parser->root.cursor ) )
861 loader->num_glyphs = T1_ToInt( parser );
862 if ( parser->root.error )
864 if ( loader->num_glyphs < 0 )
866 FT_ERROR((
"t42_parse_encoding: invalid number of glyphs\n" ));
867 error = FT_THROW( Invalid_File_Format );
872 if ( loader->num_glyphs > ( limit - parser->root.cursor ) >> 2 )
874 FT_TRACE0((
"t42_parse_charstrings: adjusting number of glyphs"
875 " (from %d to %zu)\n",
877 ( limit - parser->root.cursor ) >> 2 ));
878 loader->num_glyphs = ( limit - parser->root.cursor ) >> 2;
882 else if ( *parser->root.cursor ==
'<' )
889 T1_Skip_PS_Token( parser );
890 if ( parser->root.error )
892 T1_Skip_Spaces( parser );
893 cur = parser->root.cursor;
895 while ( parser->root.cursor < limit )
897 if ( *parser->root.cursor ==
'/' )
899 else if ( *parser->root.cursor ==
'>' )
901 loader->num_glyphs = count;
902 parser->root.cursor = cur;
905 T1_Skip_PS_Token( parser );
906 if ( parser->root.error )
908 T1_Skip_Spaces( parser );
913 FT_ERROR((
"t42_parse_charstrings: invalid token\n" ));
914 error = FT_THROW( Invalid_File_Format );
918 if ( parser->root.cursor >= limit )
920 FT_ERROR((
"t42_parse_charstrings: out of bounds\n" ));
921 error = FT_THROW( Invalid_File_Format );
928 if ( swap_table->init )
930 FT_ERROR((
"t42_parse_charstrings:"
931 " only one CharStrings array allowed\n" ));
932 error = FT_THROW( Invalid_File_Format );
936 error = psaux->ps_table_funcs->init( code_table,
942 error = psaux->ps_table_funcs->init( name_table,
951 error = psaux->ps_table_funcs->init( swap_table, 4, memory );
967 T1_Skip_Spaces( parser );
969 cur = parser->root.cursor;
978 t42_is_space( cur[3] ) )
983 T1_Skip_PS_Token( parser );
984 if ( parser->root.cursor >= limit )
986 FT_ERROR((
"t42_parse_charstrings: out of bounds\n" ));
987 error = FT_THROW( Invalid_File_Format );
990 if ( parser->root.error )
993 if ( *cur ==
'/' || *cur ==
'(' )
996 FT_Bool have_literal = FT_BOOL( *cur ==
'(' );
999 if ( cur + ( have_literal ? 3 : 2 ) >= limit )
1001 FT_ERROR((
"t42_parse_charstrings: out of bounds\n" ));
1002 error = FT_THROW( Invalid_File_Format );
1007 len = (FT_UInt)( parser->root.cursor - cur );
1011 error = T1_Add_Table( name_table, n, cur, len + 1 );
1016 name_table->elements[n][len] =
'\0';
1020 ft_strcmp(
".notdef",
1021 (
const char*)( name_table->elements[n] ) ) == 0 )
1027 T1_Skip_Spaces( parser );
1030 T1_Skip_PS_Token( parser );
1032 cur = parser->root.cursor;
1034 (void)T1_ToInt( parser );
1035 if ( parser->root.cursor >= limit )
1037 FT_ERROR((
"t42_parse_charstrings: out of bounds\n" ));
1038 error = FT_THROW( Invalid_File_Format );
1042 len = (FT_UInt)( parser->root.cursor - cur );
1044 error = T1_Add_Table( code_table, n, cur, len + 1 );
1048 code_table->elements[n][len] =
'\0';
1051 if ( n >= loader->num_glyphs )
1056 loader->num_glyphs = n;
1058 if ( !notdef_found )
1060 FT_ERROR((
"t42_parse_charstrings: no /.notdef glyph\n" ));
1061 error = FT_THROW( Invalid_File_Format );
1066 if ( ft_strcmp(
".notdef", (
const char*)name_table->elements[0] ) )
1075 error = T1_Add_Table( swap_table, 0,
1076 name_table->elements[0],
1077 name_table->lengths [0] );
1082 error = T1_Add_Table( swap_table, 1,
1083 code_table->elements[0],
1084 code_table->lengths [0] );
1089 error = T1_Add_Table( swap_table, 2,
1090 name_table->elements[notdef_index],
1091 name_table->lengths [notdef_index] );
1096 error = T1_Add_Table( swap_table, 3,
1097 code_table->elements[notdef_index],
1098 code_table->lengths [notdef_index] );
1102 error = T1_Add_Table( name_table, notdef_index,
1103 swap_table->elements[0],
1104 swap_table->lengths [0] );
1108 error = T1_Add_Table( code_table, notdef_index,
1109 swap_table->elements[1],
1110 swap_table->lengths [1] );
1114 error = T1_Add_Table( name_table, 0,
1115 swap_table->elements[2],
1116 swap_table->lengths [2] );
1120 error = T1_Add_Table( code_table, 0,
1121 swap_table->elements[3],
1122 swap_table->lengths [3] );
1131 parser->root.error = error;
1136 t42_load_keyword( T42_Face face,
1143 FT_UInt max_objects = 0;
1147 if ( field->type == T1_FIELD_TYPE_CALLBACK )
1149 field->reader( (FT_Face)face, loader );
1150 error = loader->parser.root.error;
1157 switch ( field->location )
1159 case T1_FIELD_LOCATION_FONT_INFO:
1160 dummy_object = &face->type1.font_info;
1163 case T1_FIELD_LOCATION_FONT_EXTRA:
1164 dummy_object = &face->type1.font_extra;
1167 case T1_FIELD_LOCATION_BBOX:
1168 dummy_object = &face->type1.font_bbox;
1172 dummy_object = &face->type1;
1175 objects = &dummy_object;
1177 if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
1178 field->type == T1_FIELD_TYPE_FIXED_ARRAY )
1179 error = T1_Load_Field_Table( &loader->parser, field,
1180 objects, max_objects, 0 );
1182 error = T1_Load_Field( &loader->parser, field,
1183 objects, max_objects, 0 );
1190 FT_LOCAL_DEF( FT_Error )
1191 t42_parse_dict( T42_Face face,
1196 T42_Parser parser = &loader->parser;
1200 parser->root.cursor = base;
1201 parser->root.limit = base + size;
1202 parser->root.error = FT_Err_Ok;
1204 limit = parser->root.limit;
1206 T1_Skip_Spaces( parser );
1208 while ( parser->root.cursor < limit )
1213 cur = parser->root.cursor;
1216 if ( *cur ==
'F' && cur + 25 < limit &&
1217 ft_strncmp( (
char*)cur,
"FontDirectory", 13 ) == 0 )
1223 T1_Skip_PS_Token( parser );
1224 T1_Skip_Spaces ( parser );
1225 cur = cur2 = parser->root.cursor;
1228 while ( cur < limit )
1230 if ( *cur ==
'k' && cur + 5 < limit &&
1231 ft_strncmp( (
char*)cur,
"known", 5 ) == 0 )
1234 T1_Skip_PS_Token( parser );
1235 if ( parser->root.error )
1237 T1_Skip_Spaces ( parser );
1238 cur = parser->root.cursor;
1247 T1_Skip_PS_Token( parser );
1248 T1_ToToken( parser, &token );
1251 if ( token.type == T1_TOKEN_TYPE_ARRAY )
1252 cur2 = parser->root.cursor;
1254 parser->root.cursor = cur2;
1258 else if ( *cur ==
'/' && cur + 2 < limit )
1265 parser->root.cursor = cur;
1266 T1_Skip_PS_Token( parser );
1267 if ( parser->root.error )
1270 len = (FT_UInt)( parser->root.cursor - cur );
1272 if ( len > 0 && len < 22 && parser->root.cursor < limit )
1274 T1_Field keyword = (T1_Field)t42_keywords;
1278 while ( keyword->len )
1280 FT_Byte* name = (FT_Byte*)keyword->ident;
1286 if ( keyword->len == len &&
1287 ft_memcmp( cur, name, len ) == 0 )
1290 parser->root.error = t42_load_keyword( face,
1293 if ( parser->root.error )
1294 return parser->root.error;
1304 T1_Skip_PS_Token( parser );
1305 if ( parser->root.error )
1309 T1_Skip_Spaces( parser );
1313 return parser->root.error;
1317 FT_LOCAL_DEF(
void )
1318 t42_loader_init( T42_Loader loader,
1324 loader->num_glyphs = 0;
1325 loader->num_chars = 0;
1328 loader->encoding_table.init = 0;
1329 loader->charstrings.init = 0;
1330 loader->glyph_names.init = 0;
1334 FT_LOCAL_DEF(
void )
1335 t42_loader_done( T42_Loader loader )
1337 T42_Parser parser = &loader->parser;
1341 T1_Release_Table( &loader->encoding_table );
1342 T1_Release_Table( &loader->charstrings );
1343 T1_Release_Table( &loader->glyph_names );
1344 T1_Release_Table( &loader->swap_table );
1347 t42_parser_done( parser );