summaryrefslogtreecommitdiff
path: root/src/freetype2/psaux
diff options
context:
space:
mode:
Diffstat (limited to 'src/freetype2/psaux')
-rw-r--r--src/freetype2/psaux/afmparse.c38
-rw-r--r--src/freetype2/psaux/afmparse.h4
-rw-r--r--src/freetype2/psaux/psauxmod.h4
-rw-r--r--src/freetype2/psaux/psconv.c22
-rw-r--r--src/freetype2/psaux/psconv.h6
-rw-r--r--src/freetype2/psaux/psobjs.c89
-rw-r--r--src/freetype2/psaux/psobjs.h2
-rw-r--r--src/freetype2/psaux/t1cmap.c26
-rw-r--r--src/freetype2/psaux/t1decode.c365
9 files changed, 343 insertions, 213 deletions
diff --git a/src/freetype2/psaux/afmparse.c b/src/freetype2/psaux/afmparse.c
index 0528fe6..91a17e2 100644
--- a/src/freetype2/psaux/afmparse.c
+++ b/src/freetype2/psaux/afmparse.c
@@ -4,7 +4,7 @@
/* */
/* AFM parser (body). */
/* */
-/* Copyright 2006, 2007 by */
+/* Copyright 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,7 +18,6 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_DEBUG_H
#include "afmparse.h"
#include "psconv.h"
@@ -367,11 +366,11 @@
FT_LOCAL_DEF( FT_Int )
afm_parser_read_vals( AFM_Parser parser,
AFM_Value vals,
- FT_Int n )
+ FT_UInt n )
{
AFM_Stream stream = parser->stream;
char* str;
- FT_Int i;
+ FT_UInt i;
if ( n > AFM_MAX_ARGUMENTS )
@@ -379,7 +378,7 @@
for ( i = 0; i < n; i++ )
{
- FT_UInt len;
+ FT_Offset len;
AFM_Value val = vals + i;
@@ -441,7 +440,7 @@
FT_LOCAL_DEF( char* )
afm_parser_next_key( AFM_Parser parser,
FT_Bool line,
- FT_UInt* len )
+ FT_Offset* len )
{
AFM_Stream stream = parser->stream;
char* key = 0; /* make stupid compiler happy */
@@ -489,7 +488,7 @@
}
if ( len )
- *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key )
+ *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key )
: 0;
return key;
@@ -498,7 +497,7 @@
static AFM_Token
afm_tokenize( const char* key,
- FT_UInt len )
+ FT_Offset len )
{
int n;
@@ -586,7 +585,7 @@
AFM_FontInfo fi = parser->FontInfo;
AFM_TrackKern tk;
char* key;
- FT_UInt len;
+ FT_Offset len;
int n = -1;
@@ -672,7 +671,12 @@
FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 );
- return (int)( index1 - index2 );
+ if ( index1 > index2 )
+ return 1;
+ else if ( index1 < index2 )
+ return -1;
+ else
+ return 0;
}
@@ -682,7 +686,7 @@
AFM_FontInfo fi = parser->FontInfo;
AFM_KernPair kp;
char* key;
- FT_UInt len;
+ FT_Offset len;
int n = -1;
@@ -770,9 +774,9 @@
static FT_Error
afm_parse_kern_data( AFM_Parser parser )
{
- FT_Error error;
- char* key;
- FT_UInt len;
+ FT_Error error;
+ char* key;
+ FT_Offset len;
while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
@@ -814,8 +818,8 @@
FT_UInt n,
AFM_Token end_section )
{
- char* key;
- FT_UInt len;
+ char* key;
+ FT_Offset len;
while ( n-- > 0 )
@@ -846,7 +850,7 @@
AFM_FontInfo fi = parser->FontInfo;
FT_Error error = PSaux_Err_Syntax_Error;
char* key;
- FT_UInt len;
+ FT_Offset len;
FT_Int metrics_sets = 0;
diff --git a/src/freetype2/psaux/afmparse.h b/src/freetype2/psaux/afmparse.h
index c2fce75..de2a530 100644
--- a/src/freetype2/psaux/afmparse.h
+++ b/src/freetype2/psaux/afmparse.h
@@ -71,13 +71,13 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Int )
afm_parser_read_vals( AFM_Parser parser,
AFM_Value vals,
- FT_Int n );
+ FT_UInt n );
/* read the next key from the next line or column */
FT_LOCAL( char* )
afm_parser_next_key( AFM_Parser parser,
FT_Bool line,
- FT_UInt* len );
+ FT_Offset* len );
FT_END_HEADER
diff --git a/src/freetype2/psaux/psauxmod.h b/src/freetype2/psaux/psauxmod.h
index 92ac056..35e042d 100644
--- a/src/freetype2/psaux/psauxmod.h
+++ b/src/freetype2/psaux/psauxmod.h
@@ -26,6 +26,10 @@
FT_BEGIN_HEADER
+#ifdef FT_CONFIG_OPTION_PIC
+#error "this module does not support PIC yet"
+#endif
+
FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class;
diff --git a/src/freetype2/psaux/psconv.c b/src/freetype2/psaux/psconv.c
index 3bbeab6..1531d8f 100644
--- a/src/freetype2/psaux/psconv.c
+++ b/src/freetype2/psaux/psconv.c
@@ -4,7 +4,7 @@
/* */
/* Some convenience conversions (body). */
/* */
-/* Copyright 2006 by */
+/* 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, */
@@ -18,10 +18,8 @@
#include <ft2build.h>
#include FT_INTERNAL_POSTSCRIPT_AUX_H
-#include FT_INTERNAL_DEBUG_H
#include "psconv.h"
-#include "psobjs.h"
#include "psauxerr.h"
@@ -187,10 +185,18 @@
if ( c < 0 || c >= 10 )
break;
- if ( divider < 10000000L )
+ if ( !integral && power_ten > 0 )
{
+ power_ten--;
decimal = decimal * 10 + c;
- divider *= 10;
+ }
+ else
+ {
+ if ( divider < 10000000L )
+ {
+ decimal = decimal * 10 + c;
+ divider *= 10;
+ }
}
}
}
@@ -233,7 +239,7 @@
PS_Conv_StringDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
- FT_UInt n )
+ FT_Offset n )
{
FT_Byte* p;
FT_UInt r = 0;
@@ -328,7 +334,7 @@
PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
- FT_UInt n )
+ FT_Offset n )
{
FT_Byte* p;
FT_UInt r = 0;
@@ -417,7 +423,7 @@
PS_Conv_EexecDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
- FT_UInt n,
+ FT_Offset n,
FT_UShort* seed )
{
FT_Byte* p;
diff --git a/src/freetype2/psaux/psconv.h b/src/freetype2/psaux/psconv.h
index e511241..84854ba 100644
--- a/src/freetype2/psaux/psconv.h
+++ b/src/freetype2/psaux/psconv.h
@@ -46,20 +46,20 @@ FT_BEGIN_HEADER
PS_Conv_StringDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
- FT_UInt n );
+ FT_Offset n );
#endif
FT_LOCAL( FT_UInt )
PS_Conv_ASCIIHexDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
- FT_UInt n );
+ FT_Offset n );
FT_LOCAL( FT_UInt )
PS_Conv_EexecDecode( FT_Byte** cursor,
FT_Byte* limit,
FT_Byte* buffer,
- FT_UInt n,
+ FT_Offset n,
FT_UShort* seed );
diff --git a/src/freetype2/psaux/psobjs.c b/src/freetype2/psaux/psobjs.c
index 9570856..fe8398a 100644
--- a/src/freetype2/psaux/psobjs.c
+++ b/src/freetype2/psaux/psobjs.c
@@ -4,7 +4,7 @@
/* */
/* Auxiliary functions for PostScript fonts (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -19,6 +19,7 @@
#include <ft2build.h>
#include FT_INTERNAL_POSTSCRIPT_AUX_H
#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_CALC_H
#include "psobjs.h"
#include "psconv.h"
@@ -169,17 +170,23 @@
void* object,
FT_PtrDist length )
{
- if ( idx < 0 || idx > table->max_elems )
+ if ( idx < 0 || idx >= table->max_elems )
{
FT_ERROR(( "ps_table_add: invalid index\n" ));
return PSaux_Err_Invalid_Argument;
}
+ if ( length < 0 )
+ {
+ FT_ERROR(( "ps_table_add: invalid length\n" ));
+ return PSaux_Err_Invalid_Argument;
+ }
+
/* grow the base block if needed */
if ( table->cursor + length > table->capacity )
{
FT_Error error;
- FT_Offset new_size = table->capacity;
+ FT_Offset new_size = table->capacity;
FT_Long in_offset;
@@ -376,7 +383,7 @@
/* skip octal escape or ignore backslash */
for ( i = 0; i < 3 && cur < limit; ++i )
{
- if ( ! IS_OCTAL_DIGIT( *cur ) )
+ if ( !IS_OCTAL_DIGIT( *cur ) )
break;
++cur;
@@ -558,8 +565,8 @@
cur++;
if ( cur >= limit || *cur != '>' ) /* >> */
{
- FT_ERROR(( "ps_parser_skip_PS_token: "
- "unexpected closing delimiter `>'\n" ));
+ FT_ERROR(( "ps_parser_skip_PS_token:"
+ " unexpected closing delimiter `>'\n" ));
error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
@@ -584,9 +591,10 @@
Exit:
if ( cur == parser->cursor )
{
- FT_ERROR(( "ps_parser_skip_PS_token: "
- "current token is `%c', which is self-delimiting "
- "but invalid at this point\n",
+ FT_ERROR(( "ps_parser_skip_PS_token:"
+ " current token is `%c' which is self-delimiting\n"
+ " "
+ " but invalid at this point\n",
*cur ));
error = PSaux_Err_Invalid_File_Format;
@@ -1147,8 +1155,10 @@
}
else
{
- FT_ERROR(( "ps_parser_load_field: expected a name or string "
- "but found token of type %d instead\n",
+ FT_ERROR(( "ps_parser_load_field:"
+ " expected a name or string\n"
+ " "
+ " but found token of type %d instead\n",
token.type ));
error = PSaux_Err_Invalid_File_Format;
goto Exit;
@@ -1185,8 +1195,8 @@
if ( result < 0 )
{
- FT_ERROR(( "ps_parser_load_field: "
- "expected four integers in bounding box\n" ));
+ FT_ERROR(( "ps_parser_load_field:"
+ " expected four integers in bounding box\n" ));
error = PSaux_Err_Invalid_File_Format;
goto Exit;
}
@@ -1259,8 +1269,9 @@
old_cursor = parser->cursor;
old_limit = parser->limit;
- /* we store the elements count if necessary */
- if ( field->type != T1_FIELD_TYPE_BBOX )
+ /* we store the elements count if necessary; */
+ /* we further assume that `count_offset' can't be zero */
+ if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 )
*(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
(FT_Byte)num_elements;
@@ -1302,7 +1313,7 @@
FT_LOCAL_DEF( FT_Error )
ps_parser_to_bytes( PS_Parser parser,
FT_Byte* bytes,
- FT_Long max_bytes,
+ FT_Offset max_bytes,
FT_Long* pnum_bytes,
FT_Bool delimiters )
{
@@ -1483,12 +1494,6 @@
builder->hints_funcs = glyph->internal->glyph_hints;
}
- if ( size )
- {
- builder->scale_x = size->metrics.x_scale;
- builder->scale_y = size->metrics.y_scale;
- }
-
builder->pos_x = 0;
builder->pos_y = 0;
@@ -1550,16 +1555,9 @@
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
- if ( builder->shift )
- {
- x >>= 16;
- y >>= 16;
- }
- point->x = x;
- point->y = y;
+ point->x = FIXED_TO_INT( x );
+ point->y = FIXED_TO_INT( y );
*control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
-
- builder->last = *point;
}
outline->n_points++;
}
@@ -1640,27 +1638,24 @@
t1_builder_close_contour( T1_Builder builder )
{
FT_Outline* outline = builder->current;
+ FT_Int first;
if ( !outline )
return;
- /* XXXX: We must not include the last point in the path if it */
- /* is located on the first point. */
+ first = outline->n_contours <= 1
+ ? 0 : outline->contours[outline->n_contours - 2] + 1;
+
+ /* We must not include the last point in the path if it */
+ /* is located on the first point. */
if ( outline->n_points > 1 )
{
- FT_Int first = 0;
FT_Vector* p1 = outline->points + first;
FT_Vector* p2 = outline->points + outline->n_points - 1;
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
- if ( outline->n_contours > 1 )
- {
- first = outline->contours[outline->n_contours - 2] + 1;
- p1 = outline->points + first;
- }
-
/* `delete' last point only if it coincides with the first */
/* point and it is not a control point (which can happen). */
if ( p1->x == p2->x && p1->y == p2->y )
@@ -1669,8 +1664,18 @@
}
if ( outline->n_contours > 0 )
- outline->contours[outline->n_contours - 1] =
- (short)( outline->n_points - 1 );
+ {
+ /* Don't add contours only consisting of one point, i.e., */
+ /* check whether the first and the last point is the same. */
+ if ( first == outline->n_points - 1 )
+ {
+ outline->n_contours--;
+ outline->n_points--;
+ }
+ else
+ outline->contours[outline->n_contours - 1] =
+ (short)( outline->n_points - 1 );
+ }
}
diff --git a/src/freetype2/psaux/psobjs.h b/src/freetype2/psaux/psobjs.h
index c2cbf2c..e380c60 100644
--- a/src/freetype2/psaux/psobjs.h
+++ b/src/freetype2/psaux/psobjs.h
@@ -111,7 +111,7 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
ps_parser_to_bytes( PS_Parser parser,
FT_Byte* bytes,
- FT_Long max_bytes,
+ FT_Offset max_bytes,
FT_Long* pnum_bytes,
FT_Bool delimiters );
diff --git a/src/freetype2/psaux/t1cmap.c b/src/freetype2/psaux/t1cmap.c
index 2934686..f933e4d 100644
--- a/src/freetype2/psaux/t1cmap.c
+++ b/src/freetype2/psaux/t1cmap.c
@@ -4,7 +4,7 @@
/* */
/* Type 1 character map support (body). */
/* */
-/* Copyright 2002, 2003, 2006 by */
+/* Copyright 2002, 2003, 2006, 2007 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -95,7 +95,7 @@
}
- FT_CALLBACK_DEF( FT_UInt )
+ FT_CALLBACK_DEF( FT_UInt32 )
t1_cmap_std_char_next( T1_CMapStd cmap,
FT_UInt32 *pchar_code )
{
@@ -135,7 +135,9 @@
(FT_CMap_InitFunc) t1_cmap_standard_init,
(FT_CMap_DoneFunc) t1_cmap_std_done,
(FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_std_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -154,7 +156,9 @@
(FT_CMap_InitFunc) t1_cmap_expert_init,
(FT_CMap_DoneFunc) t1_cmap_std_done,
(FT_CMap_CharIndexFunc)t1_cmap_std_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_std_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_std_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -175,7 +179,7 @@
cmap->first = encoding->code_first;
- cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 );
+ cmap->count = (FT_UInt)( encoding->code_last - cmap->first );
cmap->indices = encoding->char_index;
FT_ASSERT( cmap->indices != NULL );
@@ -209,7 +213,7 @@
}
- FT_CALLBACK_DEF( FT_UInt )
+ FT_CALLBACK_DEF( FT_UInt32 )
t1_cmap_custom_char_next( T1_CMapCustom cmap,
FT_UInt32 *pchar_code )
{
@@ -245,7 +249,9 @@
(FT_CMap_InitFunc) t1_cmap_custom_init,
(FT_CMap_DoneFunc) t1_cmap_custom_done,
(FT_CMap_CharIndexFunc)t1_cmap_custom_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_custom_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_custom_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
@@ -306,7 +312,7 @@
}
- FT_CALLBACK_DEF( FT_UInt )
+ FT_CALLBACK_DEF( FT_UInt32 )
t1_cmap_unicode_char_next( PS_Unicodes unicodes,
FT_UInt32 *pchar_code )
{
@@ -326,7 +332,9 @@
(FT_CMap_InitFunc) t1_cmap_unicode_init,
(FT_CMap_DoneFunc) t1_cmap_unicode_done,
(FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index,
- (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next
+ (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next,
+
+ NULL, NULL, NULL, NULL, NULL
};
diff --git a/src/freetype2/psaux/t1decode.c b/src/freetype2/psaux/t1decode.c
index f790643..b3245a6 100644
--- a/src/freetype2/psaux/t1decode.c
+++ b/src/freetype2/psaux/t1decode.c
@@ -4,7 +4,7 @@
/* */
/* PostScript Type 1 decoding routines (body). */
/* */
-/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -17,6 +17,7 @@
#include <ft2build.h>
+#include FT_INTERNAL_CALC_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include FT_OUTLINE_H
@@ -144,7 +145,8 @@
FT_String* name = (FT_String*)decoder->glyph_names[n];
- if ( name && name[0] == glyph_name[0] &&
+ if ( name &&
+ name[0] == glyph_name[0] &&
ft_strcmp( name, glyph_name ) == 0 )
return n;
}
@@ -193,6 +195,16 @@
#endif
FT_Vector left_bearing, advance;
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ T1_Face face = (T1_Face)decoder->builder.face;
+#endif
+
+
+ if ( decoder->seac )
+ {
+ FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
+ return PSaux_Err_Syntax_Error;
+ }
/* seac weirdness */
adx += decoder->builder.left_bearing.x;
@@ -201,18 +213,29 @@
/* include an encoding. How can we deal with these? */
if ( decoder->glyph_names == 0 )
{
- FT_ERROR(( "t1operator_seac:" ));
- FT_ERROR(( " glyph names table not available in this font!\n" ));
+ FT_ERROR(( "t1operator_seac:"
+ " glyph names table not available in this font\n" ));
return PSaux_Err_Syntax_Error;
}
- bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
- achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
+#ifdef FT_CONFIG_OPTION_INCREMENTAL
+ if ( face->root.internal->incremental_interface )
+ {
+ /* the caller must handle the font encoding also */
+ bchar_index = bchar;
+ achar_index = achar;
+ }
+ else
+#endif
+ {
+ bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
+ achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
+ }
if ( bchar_index < 0 || achar_index < 0 )
{
- FT_ERROR(( "t1operator_seac:" ));
- FT_ERROR(( " invalid seac character code arguments\n" ));
+ FT_ERROR(( "t1operator_seac:"
+ " invalid seac character code arguments\n" ));
return PSaux_Err_Syntax_Error;
}
@@ -243,8 +266,8 @@
/* subglyph 1 = accent character */
subg->index = achar_index;
subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
- subg->arg1 = (FT_Int)( adx - asb );
- subg->arg2 = (FT_Int)ady;
+ subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
+ subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
/* set up remaining glyph fields */
glyph->num_subglyphs = 2;
@@ -260,7 +283,10 @@
FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
+ /* the seac operator must not be nested */
+ decoder->seac = TRUE;
error = t1_decoder_parse_glyph( decoder, bchar_index );
+ decoder->seac = FALSE;
if ( error )
goto Exit;
@@ -278,7 +304,11 @@
/* Now load `achar' on top of */
/* the base outline */
+
+ /* the seac operator must not be nested */
+ decoder->seac = TRUE;
error = t1_decoder_parse_glyph( decoder, achar_index );
+ decoder->seac = FALSE;
if ( error )
goto Exit;
@@ -327,9 +357,15 @@
FT_Pos x, y, orig_x, orig_y;
FT_Int known_othersubr_result_cnt = 0;
FT_Int unknown_othersubr_result_cnt = 0;
+ FT_Bool large_int;
+ FT_Fixed seed;
T1_Hints_Funcs hinter;
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_Bool bol = TRUE;
+#endif
+
/* we don't want to touch the source code -- use macro trick */
#define start_point t1_builder_start_point
@@ -339,6 +375,16 @@
#define add_contour t1_builder_add_contour
#define close_contour t1_builder_close_contour
+
+ /* compute random seed from stack address of parameter */
+ seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^
+ (FT_PtrDist)(char*)&decoder ^
+ (FT_PtrDist)(char*)&charstring_base ) &
+ FT_ULONG_MAX ) ;
+ seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
+ if ( seed == 0 )
+ seed = 0x7384;
+
/* First of all, initialize the decoder */
decoder->top = decoder->stack;
decoder->zone = decoder->zones;
@@ -351,15 +397,15 @@
/* a font that reads BuildCharArray without setting */
/* its values first is buggy, but ... */
FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
- ( decoder->buildchar == NULL ) );
+ ( decoder->buildchar == NULL ) );
if ( decoder->len_buildchar > 0 )
- memset( &decoder->buildchar[0],
- 0,
- sizeof( decoder->buildchar[0] ) *
- decoder->len_buildchar );
+ ft_memset( &decoder->buildchar[0],
+ 0,
+ sizeof( decoder->buildchar[0] ) * decoder->len_buildchar );
- FT_TRACE4(( "\nStart charstring\n" ));
+ FT_TRACE4(( "\n"
+ "Start charstring\n" ));
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
@@ -374,18 +420,26 @@
if ( hinter )
hinter->open( hinter->hints );
+ large_int = FALSE;
+
/* now, execute loop */
while ( ip < limit )
{
FT_Long* top = decoder->top;
T1_Operator op = op_none;
- FT_Long value = 0;
+ FT_Int32 value = 0;
FT_ASSERT( known_othersubr_result_cnt == 0 ||
unknown_othersubr_result_cnt == 0 );
- FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( bol )
+ {
+ FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
+ bol = FALSE;
+ }
+#endif
/*********************************************************************/
/* */
@@ -456,8 +510,8 @@
case 12:
if ( ip > limit )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "invalid escape (12+EOF)\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " invalid escape (12+EOF)\n" ));
goto Syntax_Error;
}
@@ -492,8 +546,8 @@
break;
default:
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "invalid escape (12+%d)\n",
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " invalid escape (12+%d)\n",
ip[-1] ));
goto Syntax_Error;
}
@@ -502,42 +556,69 @@
case 255: /* four bytes integer */
if ( ip + 4 > limit )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "unexpected EOF in integer\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unexpected EOF in integer\n" ));
goto Syntax_Error;
}
- value = (FT_Int32)( ((FT_Long)ip[0] << 24) |
- ((FT_Long)ip[1] << 16) |
- ((FT_Long)ip[2] << 8 ) |
- ip[3] );
+ value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) |
+ ( (FT_Long)ip[1] << 16 ) |
+ ( (FT_Long)ip[2] << 8 ) |
+ ip[3] );
ip += 4;
+
+ /* According to the specification, values > 32000 or < -32000 must */
+ /* be followed by a `div' operator to make the result be in the */
+ /* range [-32000;32000]. We expect that the second argument of */
+ /* `div' is not a large number. Additionally, we don't handle */
+ /* stuff like `<large1> <large2> <num> div <num> div' or */
+ /* <large1> <large2> <num> div div'. This is probably not allowed */
+ /* anyway. */
+ if ( value > 32000 || value < -32000 )
+ {
+ if ( large_int )
+ {
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " no `div' after large integer\n" ));
+ }
+ else
+ large_int = TRUE;
+ }
+ else
+ {
+ if ( !large_int )
+ value <<= 16;
+ }
+
break;
default:
if ( ip[-1] >= 32 )
{
if ( ip[-1] < 247 )
- value = (FT_Long)ip[-1] - 139;
+ value = (FT_Int32)ip[-1] - 139;
else
{
if ( ++ip > limit )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: " ));
- FT_ERROR(( "unexpected EOF in integer\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unexpected EOF in integer\n" ));
goto Syntax_Error;
}
if ( ip[-2] < 251 )
- value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
+ value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
else
- value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
+ value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
}
+
+ if ( !large_int )
+ value <<= 16;
}
else
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "invalid byte (%d)\n", ip[-1] ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " invalid byte (%d)\n", ip[-1] ));
goto Syntax_Error;
}
}
@@ -559,6 +640,14 @@
}
}
+ if ( large_int && !( op == op_none || op == op_div ) )
+ {
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " no `div' after large integer\n" ));
+
+ large_int = FALSE;
+ }
+
/*********************************************************************/
/* */
/* Push value on stack, or process operator */
@@ -568,11 +657,16 @@
{
if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" ));
goto Syntax_Error;
}
- FT_TRACE4(( " %ld", value ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( large_int )
+ FT_TRACE4(( " %ld", value ));
+ else
+ FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) ));
+#endif
*top++ = value;
decoder->top = top;
@@ -583,15 +677,18 @@
FT_Int arg_cnt;
- FT_TRACE4(( " callothersubr" ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE4(( " callothersubr\n" ));
+ bol = TRUE;
+#endif
if ( top - decoder->stack < 2 )
goto Stack_Underflow;
top -= 2;
- subr_no = (FT_Int)top[1];
- arg_cnt = (FT_Int)top[0];
+ subr_no = (FT_Int)( top[1] >> 16 );
+ arg_cnt = (FT_Int)( top[0] >> 16 );
/***********************************************************/
/* */
@@ -668,8 +765,8 @@
if ( decoder->flex_state == 0 ||
decoder->num_flex_vectors != 7 )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "unexpected flex end\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unexpected flex end\n" ));
goto Syntax_Error;
}
@@ -685,7 +782,6 @@
if ( hinter )
hinter->reset( hinter->hints, builder->current->n_points );
-
break;
case 12:
@@ -708,16 +804,16 @@
if ( !blend )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: " ));
- FT_ERROR(( "unexpected multiple masters operator!\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unexpected multiple masters operator\n" ));
goto Syntax_Error;
}
num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 );
if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: " ));
- FT_ERROR(( "incorrect number of mm arguments\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " incorrect number of multiple masters arguments\n" ));
goto Syntax_Error;
}
@@ -753,12 +849,6 @@
break;
}
-#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
-
- /* We cannot yet enable these since currently */
- /* our T1 stack stores integers which lack the */
- /* precision to express the values */
-
case 19:
/* <idx> 1 19 callothersubr */
/* => replace elements starting from index cvi( <idx> ) */
@@ -771,16 +861,16 @@
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
- idx = top[0];
+ idx = (FT_Int)( top[0] >> 16 );
- if ( idx < 0 ||
- idx + blend->num_designs > decoder->face->len_buildchar )
+ if ( idx < 0 ||
+ idx + blend->num_designs > decoder->len_buildchar )
goto Unexpected_OtherSubr;
- memcpy( &decoder->buildchar[idx],
- blend->weight_vector,
- blend->num_designs *
- sizeof( blend->weight_vector[ 0 ] ) );
+ ft_memcpy( &decoder->buildchar[idx],
+ blend->weight_vector,
+ blend->num_designs *
+ sizeof( blend->weight_vector[0] ) );
}
break;
@@ -812,7 +902,7 @@
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
- top[0] *= top[1]; /* XXX (over|under)flow */
+ top[0] = FT_MulFix( top[0], top[1] );
known_othersubr_result_cnt = 1;
break;
@@ -823,24 +913,23 @@
if ( arg_cnt != 2 || top[1] == 0 )
goto Unexpected_OtherSubr;
- top[0] /= top[1]; /* XXX (over|under)flow */
+ top[0] = FT_DivFix( top[0], top[1] );
known_othersubr_result_cnt = 1;
break;
-#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
-
case 24:
- /* <val> <idx> 2 24 callothersubr */
- /* => set BuildCharArray[cvi( <idx> )] = <val> */
+ /* <val> <idx> 2 24 callothersubr */
+ /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
+
if ( arg_cnt != 2 || blend == NULL )
goto Unexpected_OtherSubr;
- idx = top[1];
+ idx = (FT_Int)( top[1] >> 16 );
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
goto Unexpected_OtherSubr;
@@ -850,17 +939,18 @@
break;
case 25:
- /* <idx> 1 25 callothersubr pop */
- /* => push BuildCharArray[cvi( idx )] */
- /* onto T1 stack */
+ /* <idx> 1 25 callothersubr pop */
+ /* ==> push BuildCharArray[cvi( idx )] */
+ /* onto T1 stack */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
+
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
- idx = top[0];
+ idx = (FT_Int)( top[0] >> 16 );
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
goto Unexpected_OtherSubr;
@@ -876,13 +966,13 @@
/* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
/* leave mark on T1 stack */
/* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
- XXX who has left his mark on the (PostScript) stack ?;
+ XXX which routine has left its mark on the (PostScript) stack?;
break;
#endif
case 27:
/* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
- /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
+ /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
/* otherwise push <res2> */
if ( arg_cnt != 4 )
goto Unexpected_OtherSubr;
@@ -893,28 +983,40 @@
known_othersubr_result_cnt = 1;
break;
-#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
case 28:
/* 0 28 callothersubr pop */
/* => push random value from interval [0, 1) onto stack */
if ( arg_cnt != 0 )
goto Unexpected_OtherSubr;
- top[0] = FT_rand();
+ {
+ FT_Fixed Rand;
+
+
+ Rand = seed;
+ if ( Rand >= 0x8000L )
+ Rand++;
+
+ top[0] = Rand;
+
+ seed = FT_MulFix( seed, 0x10000L - seed );
+ if ( seed == 0 )
+ seed += 0x2873;
+ }
+
known_othersubr_result_cnt = 1;
break;
-#endif
default:
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "unknown othersubr [%d %d], wish me luck!\n",
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unknown othersubr [%d %d], wish me luck\n",
arg_cnt, subr_no ));
unknown_othersubr_result_cnt = arg_cnt;
break;
Unexpected_OtherSubr:
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "invalid othersubr [%d %d]!\n", arg_cnt, subr_no ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " invalid othersubr [%d %d]\n", arg_cnt, subr_no ));
goto Syntax_Error;
}
@@ -951,9 +1053,9 @@
default:
if ( top - decoder->stack != num_args )
- FT_TRACE0(( "t1_decoder_parse_charstrings: "
- "too much operands on the stack "
- "(seen %d, expected %d)\n",
+ FT_TRACE0(( "t1_decoder_parse_charstrings:"
+ " too much operands on the stack"
+ " (seen %d, expected %d)\n",
top - decoder->stack, num_args ));
break;
}
@@ -965,28 +1067,26 @@
switch ( op )
{
case op_endchar:
- FT_TRACE4(( " endchar" ));
+ FT_TRACE4(( " endchar\n" ));
close_contour( builder );
/* close hints recording session */
if ( hinter )
{
- if (hinter->close( hinter->hints, builder->current->n_points ))
+ if ( hinter->close( hinter->hints, builder->current->n_points ) )
goto Syntax_Error;
/* apply hints to the loaded glyph outline now */
hinter->apply( hinter->hints,
builder->current,
- (PSH_Globals) builder->hints_globals,
+ (PSH_Globals)builder->hints_globals,
decoder->hint_mode );
}
/* add current outline to the glyph slot */
FT_GlyphLoader_Add( builder->loader );
- FT_TRACE4(( "\n" ));
-
/* the compiler should optimize away this empty loop but ... */
#ifdef FT_DEBUG_LEVEL_TRACE
@@ -1020,8 +1120,8 @@
builder->advance.x = top[1];
builder->advance.y = 0;
- orig_x = builder->last.x = x = builder->pos_x + top[0];
- orig_y = builder->last.y = y = builder->pos_y;
+ orig_x = x = builder->pos_x + top[0];
+ orig_y = y = builder->pos_y;
FT_UNUSED( orig_y );
@@ -1034,9 +1134,12 @@
break;
case op_seac:
- /* return immediately after the processing */
- return t1operator_seac( decoder, top[0], top[1], top[2],
- (FT_Int)top[3], (FT_Int)top[4] );
+ return t1operator_seac( decoder,
+ top[0],
+ top[1],
+ top[2],
+ (FT_Int)( top[3] >> 16 ),
+ (FT_Int)( top[4] >> 16 ) );
case op_sbw:
FT_TRACE4(( " sbw" ));
@@ -1048,8 +1151,8 @@
builder->advance.x = top[2];
builder->advance.y = top[3];
- builder->last.x = x = builder->pos_x + top[0];
- builder->last.y = y = builder->pos_y + top[1];
+ x = builder->pos_x + top[0];
+ y = builder->pos_y + top[1];
/* the `metrics_only' indicates that we only want to compute */
/* the glyph's metrics (lsb + advance width), not load the */
@@ -1062,10 +1165,11 @@
case op_closepath:
FT_TRACE4(( " closepath" ));
- close_contour( builder );
- if ( !( builder->parse_state == T1_Parse_Have_Path ||
- builder->parse_state == T1_Parse_Have_Moveto ) )
- goto Syntax_Error;
+ /* if there is no path, `closepath' is a no-op */
+ if ( builder->parse_state == T1_Parse_Have_Path ||
+ builder->parse_state == T1_Parse_Have_Moveto )
+ close_contour( builder );
+
builder->parse_state = T1_Parse_Have_Width;
break;
@@ -1134,7 +1238,7 @@
break;
case op_rrcurveto:
- FT_TRACE4(( " rcurveto" ));
+ FT_TRACE4(( " rrcurveto" ));
if ( start_point( builder, x, y ) ||
check_points( builder, 3 ) )
@@ -1193,16 +1297,13 @@
case op_div:
FT_TRACE4(( " div" ));
- if ( top[1] )
- {
- *top = top[0] / top[1];
- ++top;
- }
- else
- {
- FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" ));
- goto Syntax_Error;
- }
+ /* if `large_int' is set, we divide unscaled numbers; */
+ /* otherwise, we divide numbers in 16.16 format -- */
+ /* in both cases, it is the same operation */
+ *top = FT_DivFix( top[0], top[1] );
+ ++top;
+
+ large_int = FALSE;
break;
case op_callsubr:
@@ -1212,18 +1313,18 @@
FT_TRACE4(( " callsubr" ));
- idx = (FT_Int)top[0];
+ idx = (FT_Int)( top[0] >> 16 );
if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "invalid subrs index\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " invalid subrs index\n" ));
goto Syntax_Error;
}
if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "too many nested subrs\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " too many nested subrs\n" ));
goto Syntax_Error;
}
@@ -1250,8 +1351,8 @@
if ( !zone->base )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "invoking empty subrs!\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " invoking empty subrs\n" ));
goto Syntax_Error;
}
@@ -1273,8 +1374,8 @@
if ( unknown_othersubr_result_cnt == 0 )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "no more operands for othersubr!\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " no more operands for othersubr\n" ));
goto Syntax_Error;
}
@@ -1287,7 +1388,8 @@
if ( zone <= decoder->zones )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unexpected return\n" ));
goto Syntax_Error;
}
@@ -1311,7 +1413,6 @@
/* top[0] += builder->left_bearing.y; */
hinter->stem( hinter->hints, 1, top );
}
-
break;
case op_hstem3:
@@ -1320,19 +1421,17 @@
/* record horizontal counter-controlled hints */
if ( hinter )
hinter->stem3( hinter->hints, 1, top );
-
break;
case op_vstem:
FT_TRACE4(( " vstem" ));
- /* record vertical hint */
+ /* record vertical hint */
if ( hinter )
{
top[0] += orig_x;
hinter->stem( hinter->hints, 0, top );
}
-
break;
case op_vstem3:
@@ -1362,9 +1461,8 @@
/* known_othersubr_result_cnt != 0 is already handled above */
if ( decoder->flex_state != 1 )
{
- FT_ERROR(( "t1_decoder_parse_charstrings: " ));
- FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
-
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unexpected `setcurrentpoint'\n" ));
goto Syntax_Error;
}
else
@@ -1377,8 +1475,8 @@
break;
default:
- FT_ERROR(( "t1_decoder_parse_charstrings: "
- "unhandled opcode %d\n", op ));
+ FT_ERROR(( "t1_decoder_parse_charstrings:"
+ " unhandled opcode %d\n", op ));
goto Syntax_Error;
}
@@ -1389,6 +1487,11 @@
decoder->top = top;
+#ifdef FT_DEBUG_LEVEL_TRACE
+ FT_TRACE4(( "\n" ));
+ bol = TRUE;
+#endif
+
} /* general operator processing */
} /* while ip < limit */
@@ -1437,8 +1540,8 @@
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
if ( !psnames )
{
- FT_ERROR(( "t1_decoder_init: " ));
- FT_ERROR(( "the `psnames' module is not available\n" ));
+ FT_ERROR(( "t1_decoder_init:"
+ " the `psnames' module is not available\n" ));
return PSaux_Err_Unimplemented_Feature;
}