forked from minhngoc25a/freetype2
473 lines
9.4 KiB
C
473 lines
9.4 KiB
C
/***************************************************************************/
|
|
/* */
|
|
/* psconv.c */
|
|
/* */
|
|
/* Some convenience conversions (body). */
|
|
/* */
|
|
/* Copyright 2006, 2008, 2009 by */
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
|
/* */
|
|
/* 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 <ft2build.h>
|
|
#include FT_INTERNAL_POSTSCRIPT_AUX_H
|
|
|
|
#include "psconv.h"
|
|
#include "psauxerr.h"
|
|
|
|
|
|
/* The following array is used by various functions to quickly convert */
|
|
/* digits (both decimal and non-decimal) into numbers. */
|
|
|
|
#if 'A' == 65
|
|
/* ASCII */
|
|
|
|
static const FT_Char ft_char_table[128] =
|
|
{
|
|
/* 0x00 */
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
|
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
|
|
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
|
|
};
|
|
|
|
/* no character >= 0x80 can represent a valid number */
|
|
#define OP >=
|
|
|
|
#endif /* 'A' == 65 */
|
|
|
|
#if 'A' == 193
|
|
/* EBCDIC */
|
|
|
|
static const FT_Char ft_char_table[128] =
|
|
{
|
|
/* 0x80 */
|
|
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
|
|
-1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, -1, -1, -1, -1, -1,
|
|
-1, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
|
};
|
|
|
|
/* no character < 0x80 can represent a valid number */
|
|
#define OP <
|
|
|
|
#endif /* 'A' == 193 */
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Int )
|
|
PS_Conv_Strtol( FT_Byte** cursor,
|
|
FT_Byte* limit,
|
|
FT_Int base )
|
|
{
|
|
FT_Byte* p = *cursor;
|
|
FT_Int num = 0;
|
|
FT_Bool sign = 0;
|
|
|
|
|
|
if ( p == limit || base < 2 || base > 36 )
|
|
return 0;
|
|
|
|
if ( *p == '-' || *p == '+' )
|
|
{
|
|
sign = FT_BOOL( *p == '-' );
|
|
|
|
p++;
|
|
if ( p == limit )
|
|
return 0;
|
|
}
|
|
|
|
for ( ; p < limit; p++ )
|
|
{
|
|
FT_Char c;
|
|
|
|
|
|
if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
|
|
break;
|
|
|
|
c = ft_char_table[*p & 0x7f];
|
|
|
|
if ( c < 0 || c >= base )
|
|
break;
|
|
|
|
num = num * base + c;
|
|
}
|
|
|
|
if ( sign )
|
|
num = -num;
|
|
|
|
*cursor = p;
|
|
|
|
return num;
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Int )
|
|
PS_Conv_ToInt( FT_Byte** cursor,
|
|
FT_Byte* limit )
|
|
|
|
{
|
|
FT_Byte* p;
|
|
FT_Int num;
|
|
|
|
|
|
num = PS_Conv_Strtol( cursor, limit, 10 );
|
|
p = *cursor;
|
|
|
|
if ( p < limit && *p == '#' )
|
|
{
|
|
*cursor = p + 1;
|
|
|
|
return PS_Conv_Strtol( cursor, limit, num );
|
|
}
|
|
else
|
|
return num;
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Fixed )
|
|
PS_Conv_ToFixed( FT_Byte** cursor,
|
|
FT_Byte* limit,
|
|
FT_Int power_ten )
|
|
{
|
|
FT_Byte* p = *cursor;
|
|
FT_Fixed integral;
|
|
FT_Long decimal = 0, divider = 1;
|
|
FT_Bool sign = 0;
|
|
|
|
|
|
if ( p == limit )
|
|
return 0;
|
|
|
|
if ( *p == '-' || *p == '+' )
|
|
{
|
|
sign = FT_BOOL( *p == '-' );
|
|
|
|
p++;
|
|
if ( p == limit )
|
|
return 0;
|
|
}
|
|
|
|
if ( *p != '.' )
|
|
integral = PS_Conv_ToInt( &p, limit ) << 16;
|
|
else
|
|
integral = 0;
|
|
|
|
/* read the decimal part */
|
|
if ( p < limit && *p == '.' )
|
|
{
|
|
p++;
|
|
|
|
for ( ; p < limit; p++ )
|
|
{
|
|
FT_Char c;
|
|
|
|
|
|
if ( IS_PS_SPACE( *p ) || *p OP 0x80 )
|
|
break;
|
|
|
|
c = ft_char_table[*p & 0x7f];
|
|
|
|
if ( c < 0 || c >= 10 )
|
|
break;
|
|
|
|
if ( !integral && power_ten > 0 )
|
|
{
|
|
power_ten--;
|
|
decimal = decimal * 10 + c;
|
|
}
|
|
else
|
|
{
|
|
if ( divider < 10000000L )
|
|
{
|
|
decimal = decimal * 10 + c;
|
|
divider *= 10;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* read exponent, if any */
|
|
if ( p + 1 < limit && ( *p == 'e' || *p == 'E' ) )
|
|
{
|
|
p++;
|
|
power_ten += PS_Conv_ToInt( &p, limit );
|
|
}
|
|
|
|
while ( power_ten > 0 )
|
|
{
|
|
integral *= 10;
|
|
decimal *= 10;
|
|
power_ten--;
|
|
}
|
|
|
|
while ( power_ten < 0 )
|
|
{
|
|
integral /= 10;
|
|
divider *= 10;
|
|
power_ten++;
|
|
}
|
|
|
|
if ( decimal )
|
|
integral += FT_DivFix( decimal, divider );
|
|
|
|
if ( sign )
|
|
integral = -integral;
|
|
|
|
*cursor = p;
|
|
|
|
return integral;
|
|
}
|
|
|
|
|
|
#if 0
|
|
FT_LOCAL_DEF( FT_UInt )
|
|
PS_Conv_StringDecode( FT_Byte** cursor,
|
|
FT_Byte* limit,
|
|
FT_Byte* buffer,
|
|
FT_Offset n )
|
|
{
|
|
FT_Byte* p;
|
|
FT_UInt r = 0;
|
|
|
|
|
|
for ( p = *cursor; r < n && p < limit; p++ )
|
|
{
|
|
FT_Byte b;
|
|
|
|
|
|
if ( *p != '\\' )
|
|
{
|
|
buffer[r++] = *p;
|
|
|
|
continue;
|
|
}
|
|
|
|
p++;
|
|
|
|
switch ( *p )
|
|
{
|
|
case 'n':
|
|
b = '\n';
|
|
break;
|
|
case 'r':
|
|
b = '\r';
|
|
break;
|
|
case 't':
|
|
b = '\t';
|
|
break;
|
|
case 'b':
|
|
b = '\b';
|
|
break;
|
|
case 'f':
|
|
b = '\f';
|
|
break;
|
|
case '\r':
|
|
p++;
|
|
if ( *p != '\n' )
|
|
{
|
|
b = *p;
|
|
|
|
break;
|
|
}
|
|
/* no break */
|
|
case '\n':
|
|
continue;
|
|
break;
|
|
default:
|
|
if ( IS_PS_DIGIT( *p ) )
|
|
{
|
|
b = *p - '0';
|
|
|
|
p++;
|
|
|
|
if ( IS_PS_DIGIT( *p ) )
|
|
{
|
|
b = b * 8 + *p - '0';
|
|
|
|
p++;
|
|
|
|
if ( IS_PS_DIGIT( *p ) )
|
|
b = b * 8 + *p - '0';
|
|
else
|
|
{
|
|
buffer[r++] = b;
|
|
b = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[r++] = b;
|
|
b = *p;
|
|
}
|
|
}
|
|
else
|
|
b = *p;
|
|
break;
|
|
}
|
|
|
|
buffer[r++] = b;
|
|
}
|
|
|
|
*cursor = p;
|
|
|
|
return r;
|
|
}
|
|
#endif /* 0 */
|
|
|
|
|
|
FT_LOCAL_DEF( FT_UInt )
|
|
PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
|
|
FT_Byte* limit,
|
|
FT_Byte* buffer,
|
|
FT_Offset n )
|
|
{
|
|
FT_Byte* p;
|
|
FT_UInt r = 0;
|
|
FT_UInt w = 0;
|
|
FT_UInt pad = 0x01;
|
|
|
|
|
|
n *= 2;
|
|
|
|
#if 1
|
|
|
|
p = *cursor;
|
|
if ( n > (FT_UInt)( limit - p ) )
|
|
n = (FT_UInt)( limit - p );
|
|
|
|
/* we try to process two nibbles at a time to be as fast as possible */
|
|
for ( ; r < n; r++ )
|
|
{
|
|
FT_UInt c = p[r];
|
|
|
|
|
|
if ( IS_PS_SPACE( c ) )
|
|
continue;
|
|
|
|
if ( c OP 0x80 )
|
|
break;
|
|
|
|
c = ft_char_table[c & 0x7F];
|
|
if ( (unsigned)c >= 16 )
|
|
break;
|
|
|
|
pad = ( pad << 4 ) | c;
|
|
if ( pad & 0x100 )
|
|
{
|
|
buffer[w++] = (FT_Byte)pad;
|
|
pad = 0x01;
|
|
}
|
|
}
|
|
|
|
if ( pad != 0x01 )
|
|
buffer[w++] = (FT_Byte)( pad << 4 );
|
|
|
|
*cursor = p + r;
|
|
|
|
return w;
|
|
|
|
#else /* 0 */
|
|
|
|
for ( r = 0; r < n; r++ )
|
|
{
|
|
FT_Char c;
|
|
|
|
|
|
if ( IS_PS_SPACE( *p ) )
|
|
continue;
|
|
|
|
if ( *p OP 0x80 )
|
|
break;
|
|
|
|
c = ft_char_table[*p & 0x7f];
|
|
|
|
if ( (unsigned)c >= 16 )
|
|
break;
|
|
|
|
if ( r & 1 )
|
|
{
|
|
*buffer = (FT_Byte)(*buffer + c);
|
|
buffer++;
|
|
}
|
|
else
|
|
*buffer = (FT_Byte)(c << 4);
|
|
|
|
r++;
|
|
}
|
|
|
|
*cursor = p;
|
|
|
|
return ( r + 1 ) / 2;
|
|
|
|
#endif /* 0 */
|
|
|
|
}
|
|
|
|
|
|
FT_LOCAL_DEF( FT_UInt )
|
|
PS_Conv_EexecDecode( FT_Byte** cursor,
|
|
FT_Byte* limit,
|
|
FT_Byte* buffer,
|
|
FT_Offset n,
|
|
FT_UShort* seed )
|
|
{
|
|
FT_Byte* p;
|
|
FT_UInt r;
|
|
FT_UInt s = *seed;
|
|
|
|
|
|
#if 1
|
|
|
|
p = *cursor;
|
|
if ( n > (FT_UInt)(limit - p) )
|
|
n = (FT_UInt)(limit - p);
|
|
|
|
for ( r = 0; r < n; r++ )
|
|
{
|
|
FT_UInt val = p[r];
|
|
FT_UInt b = ( val ^ ( s >> 8 ) );
|
|
|
|
|
|
s = ( (val + s)*52845U + 22719 ) & 0xFFFFU;
|
|
buffer[r] = (FT_Byte) b;
|
|
}
|
|
|
|
*cursor = p + n;
|
|
*seed = (FT_UShort)s;
|
|
|
|
#else /* 0 */
|
|
|
|
for ( r = 0, p = *cursor; r < n && p < limit; r++, p++ )
|
|
{
|
|
FT_Byte b = (FT_Byte)( *p ^ ( s >> 8 ) );
|
|
|
|
|
|
s = (FT_UShort)( ( *p + s ) * 52845U + 22719 );
|
|
*buffer++ = b;
|
|
}
|
|
*cursor = p;
|
|
*seed = s;
|
|
|
|
#endif /* 0 */
|
|
|
|
return r;
|
|
}
|
|
|
|
|
|
/* END */
|