📄 psaux.c
字号:
{
if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */
{
cur++;
cur++;
goto Exit;
}
parser->cursor = cur;
skip_string( parser );
return;
}
if ( *cur == '>' )
{
cur++;
if ( cur >= limit || *cur != '>' ) /* >> */
{
FT_ERROR(( "ps_parser_skip_PS_token: "
"unexpected closing delimiter `>'\n" ));
parser->error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
cur++;
goto Exit;
}
if ( *cur == '/' )
cur++;
/* anything else */
while ( cur < limit )
{
if ( *cur == ')' )
{
FT_ERROR(( "ps_parser_skip_PS_token: "
"unexpected closing delimiter `)'\n" ));
parser->error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
else if ( IS_PS_DELIM( *cur ) )
break;
cur++;
}
Exit:
parser->cursor = cur;
}
FT_LOCAL_DEF( void )
ps_parser_skip_spaces( PS_Parser parser )
{
skip_spaces( &parser->cursor, parser->limit );
}
/* `token' here means either something between balanced delimiters */
/* or the next token; the delimiters are not removed. */
FT_LOCAL_DEF( void )
ps_parser_to_token( PS_Parser parser,
T1_Token token )
{
FT_Byte* cur;
FT_Byte* limit;
FT_Byte starter, ender;
FT_Int embed;
token->type = T1_TOKEN_TYPE_NONE;
token->start = 0;
token->limit = 0;
/* first of all, skip leading whitespace */
ps_parser_skip_spaces( parser );
cur = parser->cursor;
limit = parser->limit;
if ( cur >= limit )
return;
switch ( *cur )
{
/************* check for literal string *****************/
case '(':
token->type = T1_TOKEN_TYPE_STRING;
token->start = cur;
skip_literal_string( &cur, limit );
if ( cur < limit )
token->limit = cur;
break;
/************* check for programs/array *****************/
case '{':
token->type = T1_TOKEN_TYPE_ARRAY;
ender = '}';
goto Lookup_Ender;
/************* check for table/array ********************/
case '[':
token->type = T1_TOKEN_TYPE_ARRAY;
ender = ']';
/* fall through */
Lookup_Ender:
embed = 1;
starter = *cur;
token->start = cur++;
/* we need this to catch `[ ]' */
parser->cursor = cur;
ps_parser_skip_spaces( parser );
cur = parser->cursor;
while ( cur < limit && !parser->error )
{
if ( *cur == starter )
embed++;
else if ( *cur == ender )
{
embed--;
if ( embed <= 0 )
{
token->limit = ++cur;
break;
}
}
parser->cursor = cur;
ps_parser_skip_PS_token( parser );
/* we need this to catch `[XXX ]' */
ps_parser_skip_spaces ( parser );
cur = parser->cursor;
}
break;
/* ************ otherwise, it is any token **************/
default:
token->start = cur;
token->type = T1_TOKEN_TYPE_ANY;
ps_parser_skip_PS_token( parser );
cur = parser->cursor;
if ( !parser->error )
token->limit = cur;
}
if ( !token->limit )
{
token->start = 0;
token->type = T1_TOKEN_TYPE_NONE;
}
parser->cursor = cur;
}
FT_LOCAL_DEF( void )
ps_parser_to_token_array( PS_Parser parser,
T1_Token tokens,
FT_UInt max_tokens,
FT_Int* pnum_tokens )
{
T1_TokenRec master;
*pnum_tokens = -1;
/* this also handles leading whitespace */
ps_parser_to_token( parser, &master );
if ( master.type == T1_TOKEN_TYPE_ARRAY )
{
FT_Byte* old_cursor = parser->cursor;
FT_Byte* old_limit = parser->limit;
T1_Token cur = tokens;
T1_Token limit = cur + max_tokens;
/* don't include outermost delimiters */
parser->cursor = master.start + 1;
parser->limit = master.limit - 1;
while ( parser->cursor < parser->limit )
{
T1_TokenRec token;
ps_parser_to_token( parser, &token );
if ( !token.type )
break;
if ( cur < limit )
*cur = token;
cur++;
}
*pnum_tokens = (FT_Int)( cur - tokens );
parser->cursor = old_cursor;
parser->limit = old_limit;
}
}
/* first character must be a delimiter or a part of a number */
static FT_Int
ps_tocoordarray( FT_Byte* *acur,
FT_Byte* limit,
FT_Int max_coords,
FT_Short* coords )
{
FT_Byte* cur = *acur;
FT_Int count = 0;
FT_Byte c, ender;
if ( cur >= limit )
goto Exit;
/* check for the beginning of an array; otherwise, only one number */
/* will be read */
c = *cur;
ender = 0;
if ( c == '[' )
ender = ']';
if ( c == '{' )
ender = '}';
if ( ender )
cur++;
/* now, read the coordinates */
while ( cur < limit )
{
/* skip whitespace in front of data */
skip_spaces( &cur, limit );
if ( cur >= limit )
goto Exit;
if ( count >= max_coords )
break;
if ( c == ender )
{
cur++;
break;
}
coords[count] =
(FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
count++;
if ( !ender )
break;
}
Exit:
*acur = cur;
return count;
}
/* first character must be a delimiter or a part of a number */
static FT_Int
ps_tofixedarray( FT_Byte* *acur,
FT_Byte* limit,
FT_Int max_values,
FT_Fixed* values,
FT_Int power_ten )
{
FT_Byte* cur = *acur;
FT_Int count = 0;
FT_Byte c, ender;
if ( cur >= limit )
goto Exit;
/* Check for the beginning of an array. Otherwise, only one number */
/* will be read. */
c = *cur;
ender = 0;
if ( c == '[' )
ender = ']';
if ( c == '{' )
ender = '}';
if ( ender )
cur++;
/* now, read the values */
while ( cur < limit )
{
/* skip whitespace in front of data */
skip_spaces( &cur, limit );
if ( cur >= limit )
goto Exit;
if ( count >= max_values )
break;
if ( c == ender )
{
cur++;
break;
}
values[count] = PS_Conv_ToFixed( &cur, limit, power_ten );
count++;
if ( !ender )
break;
}
Exit:
*acur = cur;
return count;
}
#if 0
static FT_String*
ps_tostring( FT_Byte** cursor,
FT_Byte* limit,
FT_Memory memory )
{
FT_Byte* cur = *cursor;
FT_PtrDist len = 0;
FT_Int count;
FT_String* result;
FT_Error error;
/* XXX: some stupid fonts have a `Notice' or `Copyright' string */
/* that simply doesn't begin with an opening parenthesis, even */
/* though they have a closing one! E.g. "amuncial.pfb" */
/* */
/* We must deal with these ill-fated cases there. Note that */
/* these fonts didn't work with the old Type 1 driver as the */
/* notice/copyright was not recognized as a valid string token */
/* and made the old token parser commit errors. */
while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
cur++;
if ( cur + 1 >= limit )
return 0;
if ( *cur == '(' )
cur++; /* skip the opening parenthesis, if there is one */
*cursor = cur;
count = 0;
/* then, count its length */
for ( ; cur < limit; cur++ )
{
if ( *cur == '(' )
count++;
else if ( *cur == ')' )
{
count--;
if ( count < 0 )
break;
}
}
len = cur - *cursor;
if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
return 0;
/* now copy the string */
FT_MEM_COPY( result, *cursor, len );
result[len] = '\0';
*cursor = cur;
return result;
}
#endif /* 0 */
static int
ps_tobool( FT_Byte* *acur,
FT_Byte* limit )
{
FT_Byte* cur = *acur;
FT_Bool result = 0;
/* return 1 if we find `true', 0 otherwise */
if ( cur + 3 < limit &&
cur[0] == 't' &&
cur[1] == 'r' &&
cur[2] == 'u' &&
cur[3] == 'e' )
{
result = 1;
cur += 5;
}
else if ( cur + 4 < limit &&
cur[0] == 'f' &&
cur[1] == 'a' &&
cur[2] == 'l' &&
cur[3] == 's' &&
cur[4] == 'e' )
{
result = 0;
cur += 6;
}
*acur = cur;
return result;
}
/* load a simple field (i.e. non-table) into the current list of objects */
FT_LOCAL_DEF( FT_Error )
ps_parser_load_field( PS_Parser parser,
const T1_Field field,
void** objects,
FT_UInt max_objects,
FT_ULong* pflags )
{
T1_TokenRec token;
FT_Byte* cur;
FT_Byte* limit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -