diff --git a/CHANGES b/CHANGES index e3f1720fc..b78c57b27 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,23 @@ LATEST CHANGES + - found a memory leak in the "type1" driver + + - incorporated Tom's patches to support flex operators correctly + in OpenType/CFF fonts.. Now all I need is to support pure CFF + and CEF fonts to be done with this driver.. :-) + + - added the Windows FNT/FON driver in "src/winfonts". For now, + it always "simulates" a Unicode charmap, so it shouldn't be + considered completed right now.. + + It's there to be more a proof of concept than anything else + anyway. The driver is a single C source file, that compiles + to 3 Kb of code.. + + I'm still working on the PCF/BDF drivers.. but I'm too lazy + to finish them now.. + + - CHANGES TO THE HIGH-LEVEL API o FT_Get_Kerning has a new parameter that allows you to select diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index 69ef5f7c0..57164c8ac 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -7,3 +7,4 @@ FT_USE_MODULE(ft_smooth_renderer_class) FT_USE_MODULE(tt_driver_class) FT_USE_MODULE(t1_driver_class) FT_USE_MODULE(t1z_driver_class) +FT_USE_MODULE(winfnt_driver_class) diff --git a/include/freetype/ftoutln.h b/include/freetype/ftoutln.h index 04a9ecefa..12320d55e 100644 --- a/include/freetype/ftoutln.h +++ b/include/freetype/ftoutln.h @@ -96,6 +96,11 @@ FT_Int numContours, FT_Outline* outline ); + FT_EXPORT_DEF(FT_Error) FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline* outline ); + /*************************************************************************/ /* */ @@ -129,6 +134,9 @@ FT_EXPORT_DEF(FT_Error) FT_Outline_Done( FT_Library library, FT_Outline* outline ); + FT_EXPORT_DEF( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + /*************************************************************************/ /* */ /* */ diff --git a/include/freetype/internal/ftstream.h b/include/freetype/internal/ftstream.h index f7dbd3ba0..e7a86e2c1 100644 --- a/include/freetype/internal/ftstream.h +++ b/include/freetype/internal/ftstream.h @@ -175,6 +175,10 @@ typedef struct FT_Frame_Field_ #define GET_ULong() FT_GET_MACRO( FT_Get_Long, FT_ULong ) #define GET_Tag4() FT_GET_MACRO( FT_Get_Long, FT_ULong ) +#define GET_ShortLE() FT_GET_MACRO( FT_Get_ShortLE, FT_Short ) +#define GET_UShortLE() FT_GET_MACRO( FT_Get_ShortLE, FT_UShort ) +#define GET_LongLE() FT_GET_MACRO( FT_Get_LongLE, FT_Short ) +#define GET_ULongLE() FT_GET_MACRO( FT_Get_LongLE, FT_Short ) #define FT_READ_MACRO( func, type, var ) \ ( var = (type)func( stream, &error ), \ @@ -189,6 +193,10 @@ typedef struct FT_Frame_Field_ #define READ_Long( var ) FT_READ_MACRO( FT_Read_Long, FT_Long, var ) #define READ_ULong( var ) FT_READ_MACRO( FT_Read_Long, FT_ULong, var ) +#define READ_ShortLE( var ) FT_READ_MACRO( FT_Read_ShortLE, FT_Short, var ) +#define READ_UShortLE( var ) FT_READ_MACRO( FT_Read_ShortLE, FT_UShort, var ) +#define READ_LongLE( var ) FT_READ_MACRO( FT_Read_LongLE, FT_Long, var ) +#define READ_ULongLE( var ) FT_READ_MACRO( FT_Read_LongLE, FT_ULong, var ) BASE_DEF(void) FT_New_Memory_Stream( FT_Library library, @@ -234,6 +242,9 @@ typedef struct FT_Frame_Field_ BASE_DEF(FT_Long) FT_Get_Long( FT_Stream stream ); + BASE_DEF(FT_Short) FT_Get_ShortLE( FT_Stream stream ); + + BASE_DEF(FT_Long) FT_Get_LongLE( FT_Stream stream ); BASE_DEF(FT_Char) FT_Read_Char( FT_Stream stream, @@ -248,6 +259,12 @@ typedef struct FT_Frame_Field_ BASE_DEF(FT_Long) FT_Read_Long( FT_Stream stream, FT_Error* error ); + BASE_DEF(FT_Short) FT_Read_ShortLE( FT_Stream stream, + FT_Error* error ); + + BASE_DEF(FT_Long) FT_Read_LongLE( FT_Stream stream, + FT_Error* error ); + BASE_DEF(FT_Error) FT_Read_Fields( FT_Stream stream, const FT_Frame_Field* fields, void* structure ); diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 5ae839e98..474063b05 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -1937,9 +1937,9 @@ { metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM ); metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM ); - } - ft_recompute_scaled_metrics( face, metrics ); + ft_recompute_scaled_metrics( face, metrics ); + } if ( clazz->set_char_sizes ) error = clazz->set_char_sizes( face->size, @@ -2014,10 +2014,10 @@ metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, face->units_per_EM ); + + ft_recompute_scaled_metrics( face, metrics ); } - ft_recompute_scaled_metrics( face, metrics ); - if ( clazz->set_pixel_sizes ) error = clazz->set_pixel_sizes( face->size, pixel_width, diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index 1629abb16..cceefd750 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -270,6 +270,39 @@ } + FT_EXPORT_FUNC( FT_Error ) FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline* outline ) + { + FT_Error error; + + + if ( !outline ) + return FT_Err_Invalid_Argument; + + *outline = null_outline; + + if ( ALLOC_ARRAY( outline->points, numPoints * 2L, FT_Pos ) || + ALLOC_ARRAY( outline->tags, numPoints, FT_Byte ) || + ALLOC_ARRAY( outline->contours, numContours, FT_UShort ) ) + goto Fail; + + outline->n_points = (FT_UShort)numPoints; + outline->n_contours = (FT_Short)numContours; + outline->flags |= ft_outline_owner; + + return FT_Err_Ok; + + Fail: + outline->flags |= ft_outline_owner; + FT_Outline_Done_Internal( memory, outline ); + + return error; + } + + + /*************************************************************************/ /* */ /* */ @@ -302,39 +335,16 @@ /* The reason why this function takes a `library' parameter is simply */ /* to use the library's memory allocator. */ /* */ - BASE_FUNC( FT_Error ) FT_Outline_New( FT_Library library, - FT_UInt numPoints, - FT_Int numContours, - FT_Outline* outline ) + FT_EXPORT_FUNC( FT_Error ) FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline* outline ) { - FT_Error error; - FT_Memory memory; - - - if ( !outline ) - return FT_Err_Invalid_Argument; - - *outline = null_outline; - memory = library->memory; - - if ( ALLOC_ARRAY( outline->points, numPoints * 2L, FT_Pos ) || - ALLOC_ARRAY( outline->tags, numPoints, FT_Byte ) || - ALLOC_ARRAY( outline->contours, numContours, FT_UShort ) ) - goto Fail; - - outline->n_points = (FT_UShort)numPoints; - outline->n_contours = (FT_Short)numContours; - outline->flags |= ft_outline_owner; - - return FT_Err_Ok; - - Fail: - outline->flags |= ft_outline_owner; - FT_Outline_Done( library, outline ); - - return error; + return FT_Outline_New_Internal( library->memory, numPoints, + numContours, outline ); + } - + /*************************************************************************/ /* */ @@ -414,12 +424,10 @@ /* The reason why this function takes an `outline' parameter is */ /* simply to use FT_Free(). */ /* */ - BASE_FUNC( FT_Error ) FT_Outline_Done( FT_Library library, - FT_Outline* outline ) + + FT_EXPORT_FUNC( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ) { - FT_Memory memory = library->memory; - - if ( outline ) { if ( outline->flags & ft_outline_owner ) @@ -435,7 +443,14 @@ else return FT_Err_Invalid_Argument; } + + + FT_EXPORT_FUNC( FT_Error ) FT_Outline_Done( FT_Library library, + FT_Outline* outline ) + { + return FT_Outline_Done_Internal( library->memory, outline ); + } /*************************************************************************/ /* */ @@ -463,8 +478,8 @@ /* */ /* Yes. */ /* */ - BASE_FUNC( void ) FT_Outline_Get_CBox( FT_Outline* outline, - FT_BBox* cbox ) + FT_EXPORT_FUNC( void ) FT_Outline_Get_CBox( FT_Outline* outline, + FT_BBox* cbox ) { FT_Pos xMin, yMin, xMax, yMax; @@ -529,9 +544,9 @@ /* */ /* Yes. */ /* */ - BASE_FUNC( void ) FT_Outline_Translate( FT_Outline* outline, - FT_Pos xOffset, - FT_Pos yOffset ) + FT_EXPORT_FUNC( void ) FT_Outline_Translate( FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ) { FT_UShort n; FT_Vector* vec = outline->points; @@ -562,7 +577,7 @@ /* This functions toggles the bit flag `ft_outline_reverse_fill' in */ /* the outline's `flags' field. */ /* */ - BASE_FUNC( void ) FT_Outline_Reverse( FT_Outline* outline ) + FT_EXPORT_FUNC( void ) FT_Outline_Reverse( FT_Outline* outline ) { FT_UShort n; FT_Int first, last; diff --git a/src/base/ftstream.c b/src/base/ftstream.c index 03413ee02..b79ccba29 100644 --- a/src/base/ftstream.c +++ b/src/base/ftstream.c @@ -301,6 +301,24 @@ } + BASE_FUNC( FT_Short ) FT_Get_ShortLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Short result; + + + FT_Assert( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 1 < stream->limit ) + result = NEXT_ShortLE( p ); + stream->cursor = p; + + return result; + } + + BASE_FUNC( FT_Long ) FT_Get_Offset( FT_Stream stream ) { FT_Byte* p; @@ -335,6 +353,23 @@ } + BASE_FUNC( FT_Long ) FT_Get_LongLE( FT_Stream stream ) + { + FT_Byte* p; + FT_Long result; + + + FT_Assert( stream && stream->cursor ); + + result = 0; + p = stream->cursor; + if ( p + 3 < stream->limit ) + result = NEXT_LongLE( p ); + stream->cursor = p; + return result; + } + + BASE_FUNC( FT_Char ) FT_Read_Char( FT_Stream stream, FT_Error* error ) { @@ -417,6 +452,52 @@ } + BASE_FUNC( FT_Short ) FT_Read_ShortLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[2]; + FT_Byte* p = 0; + FT_Short result = 0; + + + FT_Assert( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 1 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 2L ) != 2L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = NEXT_ShortLE( p ); + } + else + goto Fail; + + stream->pos += 2; + + return result; + + Fail: + *error = FT_Err_Invalid_Stream_Operation; + FT_ERROR(( "FT_Read_Short:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + + return 0; + } + + BASE_FUNC( FT_Long ) FT_Read_Offset( FT_Stream stream, FT_Error* error ) { @@ -509,6 +590,54 @@ } + BASE_FUNC( FT_Long ) FT_Read_LongLE( FT_Stream stream, + FT_Error* error ) + { + FT_Byte reads[4]; + FT_Byte* p = 0; + FT_Long result = 0; + + + FT_Assert( stream ); + + *error = FT_Err_Ok; + + if ( stream->pos + 3 < stream->size ) + { + if ( stream->read ) + { + if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) + goto Fail; + + p = reads; + } + else + { + p = stream->base + stream->pos; + } + + if ( p ) + result = NEXT_LongLE( p ); + } + else + goto Fail; + + stream->pos += 4; + + return result; + + Fail: + FT_ERROR(( "FT_Read_Long:" )); + FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", + stream->pos, stream->size )); + *error = FT_Err_Invalid_Stream_Operation; + + return 0; + } + + + + BASE_FUNC( FT_Error ) FT_Read_Fields( FT_Stream stream, const FT_Frame_Field* fields, void* structure ) diff --git a/src/cff/t2gload.c b/src/cff/t2gload.c index 03bace5d9..12335af26 100644 --- a/src/cff/t2gload.c +++ b/src/cff/t2gload.c @@ -464,19 +464,17 @@ FT_Pos x, FT_Pos y ) { + FT_Error error; + /* test whether we are building a new contour */ if ( !builder->path_begun ) { - FT_Error error; - - builder->path_begun = 1; error = add_contour( builder ); - if ( error ) - return error; + if ( !error ) + error = add_point1( builder, x, y ); } - - return add_point1( builder, x, y ); + return error; } @@ -901,7 +899,7 @@ break; case t2_op_hmoveto: - FT_TRACE4(( " vmoveto" )); + FT_TRACE4(( " hmoveto" )); close_contour( builder ); builder->path_begun = 0; @@ -1152,6 +1150,7 @@ } break; + case t2_op_rcurveline: { FT_Int num_curves = ( num_args - 2 ) / 6; @@ -1192,6 +1191,198 @@ } break; + + + case t2_op_hflex1: + { + FT_Pos start_y; + + FT_TRACE4(( " hflex1" )); + + args = stack; + + /* Adding five more points; 4 control points, 1 on curve point. */ + if (start_point ( builder, x, y ) || check_points ( builder, 5 ) ) + goto Memory_Error; + + /* Record the starting point's y postion for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + y += args[1]; + add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[2]; + y += args[3]; + add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[4]; + add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[5]; + add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[6]; + y += args[7]; + add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start */ + /* point's y-value. we don't add this point, though. */ + x += args[8]; + y = start_y; + + args = stack; + break; + } + + + case t2_op_hflex: + { + FT_Pos start_y; + + FT_TRACE4(( " hflex" )); + + args = stack; + + /* Adding five more points; 4 control points, 1 on curve point. */ + if (start_point ( builder, x, y ) || check_points ( builder, 5 ) ) + + goto Memory_Error; + + /* Record the starting point's y postion for later use */ + start_y = y; + + /* first control point */ + x += args[0]; + add_point( builder, x, y, 0 ); + + /* second control point */ + x += args[1]; + y += args[2]; + add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x += args[3]; + add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x += args[4]; + add_point( builder, x, y, 0 ); + + /* fourth control point */ + x += args[5]; + y = start_y; + add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start point's */ + /* y-value we don't add this point, though. */ + x += args[6]; + + args = stack; + break; + } + + + case t2_op_flex1: + { + FT_Pos start_x, start_y; /* record start x,y values for alter use */ + FT_Int dx = 0, dy = 0; /* used in hort./vert. algorithm below */ + FT_Int hort_flag, count; + + FT_TRACE4(( " flex1" )); + + /* Adding five more points; 4 control points, 1 on curve point. */ + if (start_point ( builder, x, y ) || check_points ( builder, 5 ) ) + goto Memory_Error; + + /* Record the starting point's x,y postion for later use */ + start_x = x; + start_y = y; + + /* XXXX: figure out if this is supposed to be a horizontal or */ + /* vertical flex. The Type 2 specification is vague... */ + + args = stack; + + /* grab up to the last argument */ + while ( args < decoder->top - 1) + { + dx += args[0]; + dy += args[1]; + args += 2; + } + + /* rewind */ + args = stack; + + if ( dx < 0 ) dx = -dx; + if ( dy < 0 ) dy = -dy; + + /* strange test, but here it is... */ + hort_flag = (dx > dy); + + for ( count = 5; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + add_point( builder, x, y, (FT_Bool)(count == 3) ); + args += 2; + } + + if (hort_flag) + { + x += args[0]; + y = start_y; + } + else + { + x = start_x; + y += args[0]; + } + + args = stack; + break; + } + + + case t2_op_flex: + { + FT_UInt count; + + FT_TRACE4(( " flex" )); + + if (start_point ( builder, x, y ) || check_points ( builder, 5 ) ) + goto Memory_Error; + + args = stack; + for ( count = 5; count > 0; count-- ) + { + x += args[0]; + y += args[1]; + add_point( builder, x, y, (FT_Bool)(count == 3) ); + args += 2; + } + + x += args[0]; + y += args[1]; + + args = stack; + } + break; + + + + + case t2_op_endchar: FT_TRACE4(( " endchar" )); diff --git a/src/cid/cidload.c b/src/cid/cidload.c index a5957aedc..b9a94f52e 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -239,7 +239,7 @@ const CID_Field_Rec t1_field_records[] = { #include - { 0 } + { 0, 0, 0, 0, 0, 0, 0, 0 } }; diff --git a/src/type1/t1tokens.c b/src/type1/t1tokens.c index b9d7ca9ac..4487b49b6 100644 --- a/src/type1/t1tokens.c +++ b/src/type1/t1tokens.c @@ -373,6 +373,7 @@ return T1_Err_Ok; Fail: + FREE( tokzer->base ); FREE( tokzer ); return error; }