ref: 9b3d1c75ad150b7964b7e8cc5619c0f5b49ec72f
parent: 607358967fdedae281f8e6eac33f8a6d4c9aa403
author: David Turner <[email protected]>
date: Fri Jul 7 15:47:34 EDT 2000
- fixed a leak in the Type 1 driver - updated the CFF driver to support flex opcodes
--- 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
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -7,3 +7,4 @@
FT_USE_MODULE(tt_driver_class)
FT_USE_MODULE(t1_driver_class)
FT_USE_MODULE(t1z_driver_class)
+FT_USE_MODULE(winfnt_driver_class)
--- a/include/freetype/ftoutln.h
+++ b/include/freetype/ftoutln.h
@@ -96,7 +96,12 @@
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 );
+
/*************************************************************************/
/* */
/* <Function> */
@@ -128,6 +133,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 );
/*************************************************************************/
/* */
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -175,6 +175,10 @@
#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 @@
#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,8 +242,11 @@
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,
FT_Error* error );
@@ -247,6 +258,12 @@
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,
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1937,10 +1937,10 @@
{
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,
char_width,
@@ -2014,9 +2014,9 @@
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,
--- 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;
+ }
+
+
+
/*************************************************************************/
/* */
/* <Function> */
@@ -302,40 +335,17 @@
/* 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 );
+
}
+
-
/*************************************************************************/
/* */
/* <Function> */
@@ -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_Memory memory = library->memory;
-
+ FT_EXPORT_FUNC( FT_Error ) FT_Outline_Done_Internal( FT_Memory memory,
+ FT_Outline* outline )
+ {
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 @@
/* <MT-Note> */
/* 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 @@
/* <MT-Note> */
/* 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;
--- 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 )
{
@@ -507,6 +588,54 @@
return 0;
}
+
+
+ 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,
--- 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;
@@ -1191,6 +1190,198 @@
args = stack;
}
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" ));
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -239,7 +239,7 @@
const CID_Field_Rec t1_field_records[] =
{
#include <cidtokens.h>
- { 0 }
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
};
--- 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;
}