Getting rid of the FT_OPTIMIZE_MEMORY macro, since the optimization

is no longer experimental
This commit is contained in:
David Turner 2007-01-04 17:03:11 +00:00
parent a8cf42bb7a
commit 8a6c44e673
11 changed files with 13 additions and 480 deletions

View File

@ -1,5 +1,11 @@
2007-01-04 David Turner <david@freetype.org>
* src/sfnt/sfobjs.c, src/sfnt/ttkern.c, src/sfnt/ttkern.h,
src/sfnt/ttmtx.c, src/sfnt/ttsbit.c, src/sfnt/ttsbit.h,
src/truetype/ttpload.c, include/freetype/config/ftoption.h:
remove FT_OPTIMIZE_MEMORY macro, since the optimization is
no longer experimental
* src/pshinter/pshalgo.c: remove a stupid typo that results in no
hinting and a memory leak with some large Asian CFF fonts

View File

@ -594,11 +594,6 @@ FT_BEGIN_HEADER
/* */
/*
* This temporary macro is used to control various optimizations for
* reducing the heap footprint of memory-mapped TrueType files.
*/
#define FT_OPTIMIZE_MEMORY
/*

View File

@ -594,12 +594,6 @@ FT_BEGIN_HEADER
/* */
/*
* This temporary macro is used to control various optimizations for
* reducing the heap footprint of memory-mapped TrueType files.
*/
#define FT_OPTIMIZE_MEMORY
/*
* Define this variable if you want to keep the layout of internal

View File

@ -1395,7 +1395,6 @@ FT_BEGIN_HEADER
/* since version 2.2 */
#ifdef FT_OPTIMIZE_MEMORY
FT_Byte* horz_metrics;
FT_ULong horz_metrics_size;
@ -1420,7 +1419,6 @@ FT_BEGIN_HEADER
FT_UInt num_kern_tables;
FT_UInt32 kern_avail_bits;
FT_UInt32 kern_order_bits;
#endif
#ifdef TT_CONFIG_OPTION_BDF
TT_BDFRec bdf;

View File

@ -901,7 +901,7 @@
FT_UInt i, count;
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
count = face->sbit_num_strikes;
#else
count = (FT_UInt)face->num_sbit_strikes;
@ -1008,7 +1008,7 @@
}
/* freeing the horizontal metrics */
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
{
FT_Stream stream = FT_FACE_STREAM( face );

View File

@ -41,8 +41,6 @@
#define TT_KERN_INDEX( g1, g2 ) ( ( (FT_ULong)(g1) << 16 ) | (g2) )
#ifdef FT_OPTIMIZE_MEMORY
FT_LOCAL_DEF( FT_Error )
tt_face_load_kern( TT_Face face,
FT_Stream stream )
@ -289,206 +287,6 @@
return result;
}
#else /* !OPTIMIZE_MEMORY */
FT_CALLBACK_DEF( int )
tt_kern_pair_compare( const void* a,
const void* b );
FT_LOCAL_DEF( FT_Error )
tt_face_load_kern( TT_Face face,
FT_Stream stream )
{
FT_Error error;
FT_Memory memory = stream->memory;
FT_UInt n, num_tables;
/* the kern table is optional; exit silently if it is missing */
error = face->goto_table( face, TTAG_kern, stream, 0 );
if ( error )
return SFNT_Err_Ok;
if ( FT_FRAME_ENTER( 4L ) )
goto Exit;
(void)FT_GET_USHORT(); /* version */
num_tables = FT_GET_USHORT();
FT_FRAME_EXIT();
for ( n = 0; n < num_tables; n++ )
{
FT_UInt coverage;
FT_UInt length;
if ( FT_FRAME_ENTER( 6L ) )
goto Exit;
(void)FT_GET_USHORT(); /* version */
length = FT_GET_USHORT() - 6; /* substract header length */
coverage = FT_GET_USHORT();
FT_FRAME_EXIT();
if ( coverage == 0x0001 )
{
FT_UInt num_pairs;
TT_Kern0_Pair pair;
TT_Kern0_Pair limit;
/* found a horizontal format 0 kerning table! */
if ( FT_FRAME_ENTER( 8L ) )
goto Exit;
num_pairs = FT_GET_USHORT();
/* skip the rest */
FT_FRAME_EXIT();
/* allocate array of kerning pairs */
if ( FT_QNEW_ARRAY( face->kern_pairs, num_pairs ) ||
FT_FRAME_ENTER( 6L * num_pairs ) )
goto Exit;
pair = face->kern_pairs;
limit = pair + num_pairs;
for ( ; pair < limit; pair++ )
{
pair->left = FT_GET_USHORT();
pair->right = FT_GET_USHORT();
pair->value = FT_GET_USHORT();
}
FT_FRAME_EXIT();
face->num_kern_pairs = num_pairs;
face->kern_table_index = n;
/* ensure that the kerning pair table is sorted (yes, some */
/* fonts have unsorted tables!) */
if ( num_pairs > 0 )
{
TT_Kern0_Pair pair0 = face->kern_pairs;
FT_ULong prev = TT_KERN_INDEX( pair0->left, pair0->right );
for ( pair0++; pair0 < limit; pair0++ )
{
FT_ULong next = TT_KERN_INDEX( pair0->left, pair0->right );
if ( next < prev )
goto SortIt;
prev = next;
}
goto Exit;
SortIt:
ft_qsort( (void*)face->kern_pairs, (int)num_pairs,
sizeof ( TT_Kern0_PairRec ), tt_kern_pair_compare );
}
goto Exit;
}
if ( FT_STREAM_SKIP( length ) )
goto Exit;
}
/* no kern table found -- doesn't matter */
face->kern_table_index = -1;
face->num_kern_pairs = 0;
face->kern_pairs = NULL;
Exit:
return error;
}
FT_CALLBACK_DEF( int )
tt_kern_pair_compare( const void* a,
const void* b )
{
TT_Kern0_Pair pair1 = (TT_Kern0_Pair)a;
TT_Kern0_Pair pair2 = (TT_Kern0_Pair)b;
FT_ULong index1 = TT_KERN_INDEX( pair1->left, pair1->right );
FT_ULong index2 = TT_KERN_INDEX( pair2->left, pair2->right );
return index1 < index2 ? -1
: ( index1 > index2 ? 1
: 0 );
}
FT_LOCAL_DEF( void )
tt_face_done_kern( TT_Face face )
{
FT_Memory memory = face->root.stream->memory;
FT_FREE( face->kern_pairs );
face->num_kern_pairs = 0;
}
FT_LOCAL_DEF( FT_Int )
tt_face_get_kerning( TT_Face face,
FT_UInt left_glyph,
FT_UInt right_glyph )
{
FT_Int result = 0;
TT_Kern0_Pair pair;
if ( face && face->kern_pairs )
{
/* there are some kerning pairs in this font file! */
FT_ULong search_tag = TT_KERN_INDEX( left_glyph, right_glyph );
FT_Long left, right;
left = 0;
right = face->num_kern_pairs - 1;
while ( left <= right )
{
FT_Long middle = left + ( ( right - left ) >> 1 );
FT_ULong cur_pair;
pair = face->kern_pairs + middle;
cur_pair = TT_KERN_INDEX( pair->left, pair->right );
if ( cur_pair == search_tag )
goto Found;
if ( cur_pair < search_tag )
left = middle + 1;
else
right = middle - 1;
}
}
Exit:
return result;
Found:
result = pair->value;
goto Exit;
}
#endif /* !OPTIMIZE_MEMORY */
#undef TT_KERN_INDEX
/* END */

View File

@ -41,11 +41,7 @@ FT_BEGIN_HEADER
FT_UInt left_glyph,
FT_UInt right_glyph );
#ifdef FT_OPTIMIZE_MEMORY
# define TT_FACE_HAS_KERNING( face ) ( (face)->kern_avail_bits != 0 )
#else
# define TT_FACE_HAS_KERNING( face ) ( (face)->kern_pairs != NULL )
#endif
FT_END_HEADER

View File

@ -60,7 +60,7 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
FT_LOCAL_DEF( FT_Error )
tt_face_load_hmtx( TT_Face face,
@ -334,7 +334,7 @@
/* */
/* advance :: The advance width resp. advance height. */
/* */
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
FT_LOCAL_DEF( FT_Error )
tt_face_get_metrics( TT_Face face,

View File

@ -24,7 +24,7 @@
* Alas, the memory-optimized sbit loader can't be used when implementing
* the `old internals' hack
*/
#if defined FT_OPTIMIZE_MEMORY && !defined FT_CONFIG_OPTION_OLD_INTERNALS
#if !defined FT_CONFIG_OPTION_OLD_INTERNALS
#include "ttsbit0.c"

View File

@ -45,7 +45,7 @@ FT_BEGIN_HEADER
FT_ULong strike_index,
FT_Size_Metrics* metrics );
#if !defined FT_OPTIMIZE_MEMORY || defined FT_CONFIG_OPTION_OLD_INTERNALS
#if defined FT_CONFIG_OPTION_OLD_INTERNALS
FT_LOCAL( FT_Error )
tt_find_sbit_image( TT_Face face,
FT_UInt glyph_index,
@ -59,7 +59,7 @@ FT_BEGIN_HEADER
TT_SBit_Range range,
TT_SBit_Metrics metrics );
#endif /* !FT_OPTIMIZE_MEMORY || FT_CONFIG_OPTION_OLD_INTERNALS */
#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
FT_LOCAL( FT_Error )
tt_face_load_sbit_image( TT_Face face,

View File

@ -58,7 +58,6 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
#ifdef FT_OPTIMIZE_MEMORY
FT_LOCAL_DEF( FT_Error )
tt_face_load_loca( TT_Face face,
@ -183,135 +182,6 @@
}
#else /* !FT_OPTIMIZE_MEMORY */
FT_LOCAL_DEF( FT_Error )
tt_face_load_loca( TT_Face face,
FT_Stream stream )
{
FT_Error error;
FT_Memory memory = stream->memory;
FT_Short LongOffsets;
FT_ULong table_len;
/* we need the size of the `glyf' table for malformed `loca' tables */
error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
if ( error )
goto Exit;
FT_TRACE2(( "Locations " ));
LongOffsets = face->header.Index_To_Loc_Format;
error = face->goto_table( face, TTAG_loca, stream, &table_len );
if ( error )
{
error = TT_Err_Locations_Missing;
goto Exit;
}
if ( LongOffsets != 0 )
{
face->num_locations = (FT_UShort)( table_len >> 2 );
FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations ));
if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) )
goto Exit;
if ( FT_FRAME_ENTER( face->num_locations * 4L ) )
goto Exit;
{
FT_Long* loc = face->glyph_locations;
FT_Long* limit = loc + face->num_locations;
for ( ; loc < limit; loc++ )
*loc = FT_GET_LONG();
}
FT_FRAME_EXIT();
}
else
{
face->num_locations = (FT_UShort)( table_len >> 1 );
FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations ));
if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) )
goto Exit;
if ( FT_FRAME_ENTER( face->num_locations * 2L ) )
goto Exit;
{
FT_Long* loc = face->glyph_locations;
FT_Long* limit = loc + face->num_locations;
for ( ; loc < limit; loc++ )
*loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 );
}
FT_FRAME_EXIT();
}
FT_TRACE2(( "loaded\n" ));
Exit:
return error;
}
FT_LOCAL_DEF( FT_ULong )
tt_face_get_location( TT_Face face,
FT_UInt gindex,
FT_UInt *asize )
{
FT_ULong offset;
FT_UInt count;
offset = face->glyph_locations[gindex];
count = 0;
if ( gindex < (FT_UInt)face->num_locations - 1 )
{
FT_ULong offset1 = face->glyph_locations[gindex + 1];
/* It isn't mentioned explicitly that the `loca' table must be */
/* ordered, but implicitly it refers to the length of an entry */
/* as the difference between the current and the next position. */
/* Anyway, there do exist (malformed) fonts which don't obey */
/* this rule, so we are only able to provide an upper bound for */
/* the size. */
if ( offset1 >= offset )
count = (FT_UInt)( offset1 - offset );
else
count = (FT_UInt)( face->glyf_len - offset );
}
*asize = count;
return offset;
}
FT_LOCAL_DEF( void )
tt_face_done_loca( TT_Face face )
{
FT_Memory memory = face->root.memory;
FT_FREE( face->glyph_locations );
face->num_locations = 0;
}
#endif /* !FT_OPTIMIZE_MEMORY */
/*************************************************************************/
/* */
@ -533,7 +403,6 @@
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
#ifdef FT_OPTIMIZE_MEMORY
FT_LOCAL_DEF( FT_Error )
tt_face_load_hdmx( TT_Face face,
@ -621,114 +490,6 @@
FT_FRAME_RELEASE( face->hdmx_table );
}
#else /* !FT_OPTIMIZE_MEMORY */
FT_LOCAL_DEF( FT_Error )
tt_face_load_hdmx( TT_Face face,
FT_Stream stream )
{
FT_Error error;
FT_Memory memory = stream->memory;
TT_Hdmx hdmx = &face->hdmx;
FT_Short num_records;
FT_Long num_glyphs;
FT_Long record_size;
hdmx->version = 0;
hdmx->num_records = 0;
hdmx->records = 0;
/* this table is optional */
error = face->goto_table( face, TTAG_hdmx, stream, 0 );
if ( error )
return TT_Err_Ok;
if ( FT_FRAME_ENTER( 8L ) )
goto Exit;
hdmx->version = FT_GET_USHORT();
num_records = FT_GET_SHORT();
record_size = FT_GET_LONG();
FT_FRAME_EXIT();
/* The maximum number of bytes in an hdmx device record is the */
/* maximum number of glyphs + 2; this is 0xFFFF + 2; this is */
/* the reason why `record_size' is a long. In practice, two */
/* bytes sufficient to hold the size value. */
/* */
/* There are at least two fonts, HANNOM-A and HANNOM-B version */
/* 2.0 (2005), which get this wrong: The upper two bytes of */
/* the size value are set to 0xFF instead of 0x00. We catch */
/* and fix this. */
if ( (FT_ULong)record_size >= 0xFFFF0000UL )
record_size = (FT_Long)( (FT_ULong)record_size & 0xFFFFU );
if ( record_size < 0 || num_records < 0 )
return TT_Err_Invalid_File_Format;
/* Only recognize format 0 */
if ( hdmx->version != 0 )
return TT_Err_Invalid_File_Format;
/* we can't use FT_QNEW_ARRAY here; otherwise tt_face_free_hdmx */
/* could fail during deallocation */
if ( FT_NEW_ARRAY( hdmx->records, num_records ) )
goto Exit;
hdmx->num_records = num_records;
num_glyphs = face->root.num_glyphs;
record_size -= num_glyphs + 2;
{
TT_HdmxEntry cur = hdmx->records;
TT_HdmxEntry limit = cur + hdmx->num_records;
for ( ; cur < limit; cur++ )
{
/* read record */
if ( FT_READ_BYTE( cur->ppem ) ||
FT_READ_BYTE( cur->max_width ) )
goto Exit;
if ( FT_QALLOC( cur->widths, num_glyphs ) ||
FT_STREAM_READ( cur->widths, num_glyphs ) )
goto Exit;
/* skip padding bytes */
if ( record_size > 0 && FT_STREAM_SKIP( record_size ) )
goto Exit;
}
}
Exit:
return error;
}
FT_LOCAL_DEF( void )
tt_face_free_hdmx( TT_Face face )
{
if ( face )
{
FT_Int n;
FT_Memory memory = face->root.driver->root.memory;
for ( n = 0; n < face->hdmx.num_records; n++ )
FT_FREE( face->hdmx.records[n].widths );
FT_FREE( face->hdmx.records );
face->hdmx.num_records = 0;
}
}
#endif /* !OPTIMIZE_MEMORY */
/*************************************************************************/
/* */
@ -740,8 +501,6 @@
FT_UInt ppem,
FT_UInt gindex )
{
#ifdef FT_OPTIMIZE_MEMORY
FT_UInt nn;
FT_Byte* result = NULL;
FT_ULong record_size = face->hdmx_record_size;
@ -758,19 +517,6 @@
}
return result;
#else
FT_UShort n;
for ( n = 0; n < face->hdmx.num_records; n++ )
if ( face->hdmx.records[n].ppem == ppem )
return &face->hdmx.records[n].widths[gindex];
return NULL;
#endif
}