diff options
| author | Charles Forsyth <charles.forsyth@gmail.com> | 2024-04-22 07:10:23 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-22 07:10:23 +0100 |
| commit | aea6a5537d424a269675969ba3653d291121984e (patch) | |
| tree | 6d8f7ede33f403786bdfa91973676c1bf833f0f7 /libfreetype/t42parse.c | |
| parent | 73b5cba380d148e77d696880027a416cda50f756 (diff) | |
| parent | 3df3f6f7d81cd03b0f10ef557e0c96ab0f6cd702 (diff) | |
Merge pull request #12 from dboddie/update-freetype
Update FreeType to the latest code
Diffstat (limited to 'libfreetype/t42parse.c')
| -rw-r--r-- | libfreetype/t42parse.c | 994 |
1 files changed, 0 insertions, 994 deletions
diff --git a/libfreetype/t42parse.c b/libfreetype/t42parse.c deleted file mode 100644 index 8bb2e7ba..00000000 --- a/libfreetype/t42parse.c +++ /dev/null @@ -1,994 +0,0 @@ -/***************************************************************************/ -/* */ -/* t42parse.c */ -/* */ -/* Type 42 font parser (body). */ -/* */ -/* Copyright 2002 by Roberto Alameda. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#include "t42parse.h" -#include "t42error.h" -#include FT_INTERNAL_DEBUG_H -#include FT_INTERNAL_STREAM_H -#include FT_LIST_H -#include FT_INTERNAL_POSTSCRIPT_AUX_H - - - /*************************************************************************/ - /* */ - /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ - /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ - /* messages during execution. */ - /* */ -#undef FT_COMPONENT -#define FT_COMPONENT trace_t42 - - - static void - t42_parse_font_name( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_font_bbox( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_font_matrix( T42_Face face, - T42_Loader loader ); - static void - t42_parse_encoding( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_charstrings( T42_Face face, - T42_Loader loader ); - - static void - t42_parse_sfnts( T42_Face face, - T42_Loader loader ); - - - static const - T1_FieldRec t42_keywords[] = { - -#undef FT_STRUCTURE -#define FT_STRUCTURE T1_FontInfo -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_INFO - - T1_FIELD_STRING ( "version", version ) - T1_FIELD_STRING ( "Notice", notice ) - T1_FIELD_STRING ( "FullName", full_name ) - T1_FIELD_STRING ( "FamilyName", family_name ) - T1_FIELD_STRING ( "Weight", weight ) - T1_FIELD_NUM ( "ItalicAngle", italic_angle ) - T1_FIELD_TYPE_BOOL( "isFixedPitch", is_fixed_pitch ) - T1_FIELD_NUM ( "UnderlinePosition", underline_position ) - T1_FIELD_NUM ( "UnderlineThickness", underline_thickness ) - -#undef FT_STRUCTURE -#define FT_STRUCTURE T1_FontRec -#undef T1CODE -#define T1CODE T1_FIELD_LOCATION_FONT_DICT - - T1_FIELD_NUM( "PaintType", paint_type ) - T1_FIELD_NUM( "FontType", font_type ) - T1_FIELD_NUM( "StrokeWidth", stroke_width ) - - T1_FIELD_CALLBACK( "FontName", t42_parse_font_name ) - T1_FIELD_CALLBACK( "FontBBox", t42_parse_font_bbox ) - T1_FIELD_CALLBACK( "FontMatrix", t42_parse_font_matrix ) - T1_FIELD_CALLBACK( "Encoding", t42_parse_encoding ) - T1_FIELD_CALLBACK( "CharStrings", t42_parse_charstrings ) - T1_FIELD_CALLBACK( "sfnts", t42_parse_sfnts ) - - { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } - }; - - -#define T1_Add_Table( p, i, o, l ) (p)->funcs.add( (p), i, o, l ) -#define T1_Done_Table( p ) \ - do \ - { \ - if ( (p)->funcs.done ) \ - (p)->funcs.done( p ); \ - } while ( 0 ) -#define T1_Release_Table( p ) \ - do \ - { \ - if ( (p)->funcs.release ) \ - (p)->funcs.release( p ); \ - } while ( 0 ) - -#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root ) -#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root ) - -#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root ) -#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t ) - -#define T1_ToCoordArray( p, m, c ) \ - (p)->root.funcs.to_coord_array( &(p)->root, m, c ) -#define T1_ToFixedArray( p, m, f, t ) \ - (p)->root.funcs.to_fixed_array( &(p)->root, m, f, t ) -#define T1_ToToken( p, t ) \ - (p)->root.funcs.to_token( &(p)->root, t ) -#define T1_ToTokenArray( p, t, m, c ) \ - (p)->root.funcs.to_token_array( &(p)->root, t, m, c ) - -#define T1_Load_Field( p, f, o, m, pf ) \ - (p)->root.funcs.load_field( &(p)->root, f, o, m, pf ) -#define T1_Load_Field_Table( p, f, o, m, pf ) \ - (p)->root.funcs.load_field_table( &(p)->root, f, o, m, pf ) - - - /********************* Parsing Functions ******************/ - - FT_LOCAL_DEF( FT_Error ) - t42_parser_init( T42_Parser parser, - FT_Stream stream, - FT_Memory memory, - PSAux_Service psaux ) - { - FT_Error error = T42_Err_Ok; - FT_Long size; - - - psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); - - parser->stream = stream; - parser->base_len = 0; - parser->base_dict = 0; - parser->in_memory = 0; - - /*******************************************************************/ - /* */ - /* Here a short summary of what is going on: */ - /* */ - /* When creating a new Type 42 parser, we try to locate and load */ - /* the base dictionary, loading the whole font into memory. */ - /* */ - /* When `loading' the base dictionary, we only setup pointers in */ - /* the case of a memory-based stream. Otherwise, we allocate */ - /* and load the base dictionary in it. */ - /* */ - /* parser->in_memory is set if we have a memory stream. */ - /* */ - - if ( FT_STREAM_SEEK( 0L ) ) - goto Exit; - - size = stream->size; - - /* now, try to load `size' bytes of the `base' dictionary we */ - /* found previously */ - - /* if it is a memory-based resource, set up pointers */ - if ( !stream->read ) - { - parser->base_dict = (FT_Byte*)stream->base + stream->pos; - parser->base_len = size; - parser->in_memory = 1; - - /* check that the `size' field is valid */ - if ( FT_STREAM_SKIP( size ) ) - goto Exit; - } - else - { - /* read segment in memory */ - if ( FT_ALLOC( parser->base_dict, size ) || - FT_STREAM_READ( parser->base_dict, size ) ) - goto Exit; - - parser->base_len = size; - } - - /* Now check font format; we must see `%!PS-TrueTypeFont' */ - if (size <= 17 || - ( ft_strncmp( (const char*)parser->base_dict, - "%!PS-TrueTypeFont", 17) ) ) - error = T42_Err_Unknown_File_Format; - else - { - parser->root.base = parser->base_dict; - parser->root.cursor = parser->base_dict; - parser->root.limit = parser->root.cursor + parser->base_len; - } - - Exit: - if ( error && !parser->in_memory ) - FT_FREE( parser->base_dict ); - - return error; - } - - - FT_LOCAL_DEF( void ) - t42_parser_done( T42_Parser parser ) - { - FT_Memory memory = parser->root.memory; - - - /* free the base dictionary only when we have a disk stream */ - if ( !parser->in_memory ) - FT_FREE( parser->base_dict ); - - parser->root.funcs.done( &parser->root ); - } - - - static int - t42_is_alpha( FT_Byte c ) - { - /* Note: we must accept "+" as a valid character, as it is used in */ - /* embedded type1 fonts in PDF documents. */ - /* */ - return ( ft_isalnum( c ) || - c == '.' || - c == '_' || - c == '-' || - c == '+' ); - } - - - static int - t42_is_space( FT_Byte c ) - { - return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ); - } - - - static void - t42_parse_font_name( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Error error; - FT_Memory memory = parser->root.memory; - FT_Int len; - FT_Byte* cur; - FT_Byte* cur2; - FT_Byte* limit; - - - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - limit = parser->root.limit; - - if ( cur >= limit - 1 || - ( *cur != '/' && *cur != '(') ) - return; - - cur++; - cur2 = cur; - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - - len = (FT_Int)( cur2 - cur ); - if ( len > 0 ) - { - if ( FT_ALLOC( face->type1.font_name, len + 1 ) ) - { - parser->root.error = error; - return; - } - - FT_MEM_COPY( face->type1.font_name, cur, len ); - face->type1.font_name[len] = '\0'; - } - parser->root.cursor = cur2; - } - - - static void - t42_parse_font_bbox( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_BBox* bbox = &face->type1.font_bbox; - - bbox->xMin = T1_ToInt( parser ); - bbox->yMin = T1_ToInt( parser ); - bbox->xMax = T1_ToInt( parser ); - bbox->yMax = T1_ToInt( parser ); - } - - - static void - t42_parse_font_matrix( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Matrix* matrix = &face->type1.font_matrix; - FT_Vector* offset = &face->type1.font_offset; - FT_Face root = (FT_Face)&face->root; - FT_Fixed temp[6]; - FT_Fixed temp_scale; - - - (void)T1_ToFixedArray( parser, 6, temp, 3 ); - - temp_scale = ABS( temp[3] ); - - /* Set Units per EM based on FontMatrix values. We set the value to */ - /* 1000 / temp_scale, because temp_scale was already multiplied by */ - /* 1000 (in t1_tofixed, from psobjs.c). */ - - root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L, - temp_scale ) >> 16 ); - - /* we need to scale the values by 1.0/temp_scale */ - if ( temp_scale != 0x10000L ) { - temp[0] = FT_DivFix( temp[0], temp_scale ); - temp[1] = FT_DivFix( temp[1], temp_scale ); - temp[2] = FT_DivFix( temp[2], temp_scale ); - temp[4] = FT_DivFix( temp[4], temp_scale ); - temp[5] = FT_DivFix( temp[5], temp_scale ); - temp[3] = 0x10000L; - } - - matrix->xx = temp[0]; - matrix->yx = temp[1]; - matrix->xy = temp[2]; - matrix->yy = temp[3]; - - /* note that the offsets must be expressed in integer font units */ - offset->x = temp[4] >> 16; - offset->y = temp[5] >> 16; - } - - - static void - t42_parse_encoding( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Byte* cur = parser->root.cursor; - FT_Byte* limit = parser->root.limit; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - - /* skip whitespace */ - while ( t42_is_space( *cur ) ) - { - cur++; - if ( cur >= limit ) - { - FT_ERROR(( "t42_parse_encoding: out of bounds!\n" )); - parser->root.error = T42_Err_Invalid_File_Format; - return; - } - } - - /* if we have a number, then the encoding is an array, */ - /* and we must load it now */ - if ( (FT_Byte)( *cur - '0' ) < 10 ) - { - T1_Encoding encode = &face->type1.encoding; - FT_Int count, n; - PS_Table char_table = &loader->encoding_table; - FT_Memory memory = parser->root.memory; - FT_Error error; - - - /* read the number of entries in the encoding, should be 256 */ - count = T1_ToInt( parser ); - if ( parser->root.error ) - return; - - /* we use a T1_Table to store our charnames */ - loader->num_chars = encode->num_chars = count; - if ( FT_NEW_ARRAY( encode->char_index, count ) || - FT_NEW_ARRAY( encode->char_name, count ) || - FT_SET_ERROR( psaux->ps_table_funcs->init( - char_table, count, memory ) ) ) - { - parser->root.error = error; - return; - } - - /* We need to `zero' out encoding_table.elements */ - for ( n = 0; n < count; n++ ) - { - char* notdef = (char *)".notdef"; - - - T1_Add_Table( char_table, n, notdef, 8 ); - } - - /* Now, we will need to read a record of the form */ - /* ... charcode /charname ... for each entry in our table */ - /* */ - /* We simply look for a number followed by an immediate */ - /* name. Note that this ignores correctly the sequence */ - /* that is often seen in type1 fonts: */ - /* */ - /* 0 1 255 { 1 index exch /.notdef put } for dup */ - /* */ - /* used to clean the encoding array before anything else. */ - /* */ - /* We stop when we encounter a `def'. */ - - cur = parser->root.cursor; - limit = parser->root.limit; - n = 0; - - for ( ; cur < limit; ) - { - FT_Byte c; - - - c = *cur; - - /* we stop when we encounter a `def' */ - if ( c == 'd' && cur + 3 < limit ) - { - if ( cur[1] == 'e' && - cur[2] == 'f' && - t42_is_space( cur[-1] ) && - t42_is_space( cur[3] ) ) - { - FT_TRACE6(( "encoding end\n" )); - break; - } - } - - /* otherwise, we must find a number before anything else */ - if ( (FT_Byte)( c - '0' ) < 10 ) - { - FT_Int charcode; - - - parser->root.cursor = cur; - charcode = T1_ToInt( parser ); - cur = parser->root.cursor; - - /* skip whitespace */ - while ( cur < limit && t42_is_space( *cur ) ) - cur++; - - if ( cur < limit && *cur == '/' ) - { - /* bingo, we have an immediate name -- it must be a */ - /* character name */ - FT_Byte* cur2 = cur + 1; - FT_Int len; - - - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - - len = (FT_Int)( cur2 - cur - 1 ); - - parser->root.error = T1_Add_Table( char_table, charcode, - cur + 1, len + 1 ); - char_table->elements[charcode][len] = '\0'; - if ( parser->root.error ) - return; - - cur = cur2; - } - } - else - cur++; - } - - face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY; - parser->root.cursor = cur; - } - /* Otherwise, we should have either `StandardEncoding', */ - /* `ExpertEncoding', or `ISOLatin1Encoding' */ - else - { - if ( cur + 17 < limit && - ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD; - - else if ( cur + 15 < limit && - ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT; - - else if ( cur + 18 < limit && - ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 ) - face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; - - else { - FT_ERROR(( "t42_parse_encoding: invalid token!\n" )); - parser->root.error = T42_Err_Invalid_File_Format; - } - } - } - - - static FT_UInt - t42_hexval( FT_Byte v ) - { - FT_UInt d; - - d = (FT_UInt)( v - 'A' ); - if ( d < 6 ) - { - d += 10; - goto Exit; - } - - d = (FT_UInt)( v - 'a' ); - if ( d < 6 ) - { - d += 10; - goto Exit; - } - - d = (FT_UInt)( v - '0' ); - if ( d < 10 ) - goto Exit; - - d = 0; - - Exit: - return d; - } - - - static void - t42_parse_sfnts( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - FT_Memory memory = parser->root.memory; - FT_Byte* cur = parser->root.cursor; - FT_Byte* limit = parser->root.limit; - FT_Error error; - FT_Int num_tables = 0, status; - FT_ULong count, ttf_size = 0, string_size = 0; - FT_Bool in_string = 0; - FT_Byte v = 0; - - - /* The format is `/sfnts [ <...> <...> ... ] def' */ - - while ( t42_is_space( *cur ) ) - cur++; - - if (*cur++ == '[') - { - status = 0; - count = 0; - } - else - { - FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector!\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - while ( cur < limit - 2 ) - { - while ( t42_is_space( *cur ) ) - cur++; - - switch ( *cur ) - { - case ']': - parser->root.cursor = cur++; - return; - - case '<': - in_string = 1; - string_size = 0; - cur++; - continue; - - case '>': - if ( !in_string ) - { - FT_ERROR(( "t42_parse_sfnts: found unpaired `>'!\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - /* A string can have, as a last byte, */ - /* a zero byte for padding. If so, ignore it */ - if ( ( v == 0 ) && ( string_size % 2 == 1 ) ) - count--; - in_string = 0; - cur++; - continue; - - case '%': - if ( !in_string ) - { - /* Comment found; skip till end of line */ - while ( *cur != '\n' ) - cur++; - continue; - } - else - { - FT_ERROR(( "t42_parse_sfnts: found `%' in string!\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - default: - if ( !ft_xdigit( *cur ) || !ft_xdigit( *(cur + 1) ) ) - { - FT_ERROR(( "t42_parse_sfnts: found non-hex characters in string" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - v = (FT_Byte)( 16 * t42_hexval( cur[0] ) + t42_hexval( cur[1] ) ); - cur += 2; - string_size++; - } - - switch ( status ) - { - case 0: /* The '[' was read, so load offset table, 12 bytes */ - if ( count < 12 ) - { - face->ttf_data[count++] = v; - continue; - } - else - { - num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; - status = 1; - ttf_size = 12 + 16 * num_tables; - - if ( FT_REALLOC( face->ttf_data, 12, ttf_size ) ) - goto Fail; - } - /* No break, fall-through */ - - case 1: /* The offset table is read; read now the table directory */ - if ( count < ttf_size ) - { - face->ttf_data[count++] = v; - continue; - } - else - { - int i; - FT_ULong len; - - - for ( i = 0; i < num_tables; i++ ) - { - FT_Byte* p = face->ttf_data + 12 + 16*i + 12; - - len = FT_PEEK_ULONG( p ); - - /* Pad to a 4-byte boundary length */ - ttf_size += ( len + 3 ) & ~3; - } - - status = 2; - face->ttf_size = ttf_size; - - if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, - ttf_size + 1 ) ) - goto Fail; - } - /* No break, fall-through */ - - case 2: /* We are reading normal tables; just swallow them */ - face->ttf_data[count++] = v; - - } - } - - /* If control reaches this point, the format was not valid */ - error = T42_Err_Invalid_File_Format; - - Fail: - parser->root.error = error; - } - - - static void - t42_parse_charstrings( T42_Face face, - T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - PS_Table code_table = &loader->charstrings; - PS_Table name_table = &loader->glyph_names; - FT_Memory memory = parser->root.memory; - FT_Error error; - - PSAux_Service psaux = (PSAux_Service)face->psaux; - - FT_Byte* cur; - FT_Byte* limit = parser->root.limit; - FT_Int n; - - - loader->num_glyphs = T1_ToInt( parser ); - if ( parser->root.error ) - return; - - /* initialize tables */ - - error = psaux->ps_table_funcs->init( code_table, - loader->num_glyphs, - memory ); - if ( error ) - goto Fail; - - error = psaux->ps_table_funcs->init( name_table, - loader->num_glyphs, - memory ); - if ( error ) - goto Fail; - - n = 0; - - for (;;) - { - /* the format is simple: */ - /* `/glyphname' + index + def */ - /* */ - /* note that we stop when we find an `end' */ - /* */ - T1_Skip_Spaces( parser ); - - cur = parser->root.cursor; - if ( cur >= limit ) - break; - - /* we stop when we find an `end' keyword */ - if ( *cur == 'e' && - cur + 3 < limit && - cur[1] == 'n' && - cur[2] == 'd' ) - break; - - if ( *cur != '/' ) - T1_Skip_Alpha( parser ); - else - { - FT_Byte* cur2 = cur + 1; - FT_Int len; - - - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - len = (FT_Int)( cur2 - cur - 1 ); - - error = T1_Add_Table( name_table, n, cur + 1, len + 1 ); - if ( error ) - goto Fail; - - /* add a trailing zero to the name table */ - name_table->elements[n][len] = '\0'; - - parser->root.cursor = cur2; - T1_Skip_Spaces( parser ); - - cur2 = cur = parser->root.cursor; - if ( cur >= limit ) - break; - - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - len = (FT_Int)( cur2 - cur ); - - error = T1_Add_Table( code_table, n, cur, len + 1 ); - if ( error ) - goto Fail; - - code_table->elements[n][len] = '\0'; - - n++; - if ( n >= loader->num_glyphs ) - break; - } - } - - /* Index 0 must be a .notdef element */ - if ( ft_strcmp( (char *)name_table->elements[0], ".notdef" ) ) - { - FT_ERROR(( "t42_parse_charstrings: Index 0 is not `.notdef'!\n" )); - error = T42_Err_Invalid_File_Format; - goto Fail; - } - - loader->num_glyphs = n; - return; - - Fail: - parser->root.error = error; - } - - - static FT_Error - t42_load_keyword( T42_Face face, - T42_Loader loader, - T1_Field field ) - { - FT_Error error; - void* dummy_object; - void** objects; - FT_UInt max_objects = 0; - - - /* if the keyword has a dedicated callback, call it */ - if ( field->type == T1_FIELD_TYPE_CALLBACK ) { - field->reader( (FT_Face)face, loader ); - error = loader->parser.root.error; - goto Exit; - } - - /* now, the keyword is either a simple field, or a table of fields; */ - /* we are now going to take care of it */ - switch ( field->location ) - { - case T1_FIELD_LOCATION_FONT_INFO: - dummy_object = &face->type1.font_info; - objects = &dummy_object; - break; - - default: - dummy_object = &face->type1; - objects = &dummy_object; - } - - if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY || - field->type == T1_FIELD_TYPE_FIXED_ARRAY ) - error = T1_Load_Field_Table( &loader->parser, field, - objects, max_objects, 0 ); - else - error = T1_Load_Field( &loader->parser, field, - objects, max_objects, 0 ); - - Exit: - return error; - } - - - FT_LOCAL_DEF( FT_Error ) - t42_parse_dict( T42_Face face, - T42_Loader loader, - FT_Byte* base, - FT_Long size ) - { - T42_Parser parser = &loader->parser; - FT_Byte* cur = base; - FT_Byte* limit = cur + size; - FT_UInt n_keywords = sizeof ( t42_keywords ) / - sizeof ( t42_keywords[0] ); - - - parser->root.cursor = base; - parser->root.limit = base + size; - parser->root.error = 0; - - for ( ; cur < limit; cur++ ) - { - /* look for `FontDirectory', which causes problems on some fonts */ - if ( *cur == 'F' && cur + 25 < limit && - ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 ) - { - FT_Byte* cur2; - - - /* skip the `FontDirectory' keyword */ - cur += 13; - cur2 = cur; - - /* lookup the `known' keyword */ - while ( cur < limit && *cur != 'k' && - ft_strncmp( (char*)cur, "known", 5 ) ) - cur++; - - if ( cur < limit ) - { - T1_TokenRec token; - - - /* skip the `known' keyword and the token following it */ - cur += 5; - loader->parser.root.cursor = cur; - T1_ToToken( &loader->parser, &token ); - - /* if the last token was an array, skip it! */ - if ( token.type == T1_TOKEN_TYPE_ARRAY ) - cur2 = parser->root.cursor; - } - cur = cur2; - } - /* look for immediates */ - else if ( *cur == '/' && cur + 2 < limit ) - { - FT_Byte* cur2; - FT_UInt i, len; - - - cur++; - cur2 = cur; - while ( cur2 < limit && t42_is_alpha( *cur2 ) ) - cur2++; - - len = (FT_UInt)( cur2 - cur ); - if ( len > 0 && len < 22 ) /* XXX What shall it this 22? */ - { - /* now, compare the immediate name to the keyword table */ - - /* Loop through all known keywords */ - for ( i = 0; i < n_keywords; i++ ) - { - T1_Field keyword = (T1_Field)&t42_keywords[i]; - FT_Byte *name = (FT_Byte*)keyword->ident; - - - if ( !name ) - continue; - - if ( ( len == ft_strlen( (const char *)name ) ) && - ( ft_memcmp( cur, name, len ) == 0 ) ) - { - /* we found it -- run the parsing callback! */ - parser->root.cursor = cur2; - T1_Skip_Spaces( parser ); - parser->root.error = t42_load_keyword(face, - loader, - keyword ); - if ( parser->root.error ) - return parser->root.error; - cur = parser->root.cursor; - break; - } - } - } - } - } - return parser->root.error; - } - - - FT_LOCAL_DEF( void ) - t42_loader_init( T42_Loader loader, - T42_Face face ) - { - FT_UNUSED( face ); - - FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - } - - - FT_LOCAL_DEF( void ) - t42_loader_done( T42_Loader loader ) - { - T42_Parser parser = &loader->parser; - - - /* finalize tables */ - T1_Release_Table( &loader->encoding_table ); - T1_Release_Table( &loader->charstrings ); - T1_Release_Table( &loader->glyph_names ); - - /* finalize parser */ - t42_parser_done( parser ); - } - - -/* END */ |
