|
|
|
@ -4,7 +4,7 @@ |
|
|
|
|
/* */ |
|
|
|
|
/* TrueType-specific tables loader (body). */ |
|
|
|
|
/* */ |
|
|
|
|
/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ |
|
|
|
|
/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */ |
|
|
|
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
|
|
|
|
/* */ |
|
|
|
|
/* This file is part of the FreeType project, and may only be used, */ |
|
|
|
@ -65,6 +65,7 @@ |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
FT_ULong table_len; |
|
|
|
|
FT_Int shift; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* we need the size of the `glyf' table for malformed `loca' tables */ |
|
|
|
@ -82,23 +83,65 @@ |
|
|
|
|
|
|
|
|
|
if ( face->header.Index_To_Loc_Format != 0 ) |
|
|
|
|
{ |
|
|
|
|
shift = 2; |
|
|
|
|
|
|
|
|
|
if ( table_len >= 0x40000L ) |
|
|
|
|
{ |
|
|
|
|
FT_TRACE2(( "table too large!\n" )); |
|
|
|
|
error = TT_Err_Invalid_Table; |
|
|
|
|
goto Exit; |
|
|
|
|
} |
|
|
|
|
face->num_locations = (FT_UInt)( table_len >> 2 ); |
|
|
|
|
face->num_locations = (FT_UInt)( table_len >> shift ); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
shift = 1; |
|
|
|
|
|
|
|
|
|
if ( table_len >= 0x20000L ) |
|
|
|
|
{ |
|
|
|
|
FT_TRACE2(( "table too large!\n" )); |
|
|
|
|
error = TT_Err_Invalid_Table; |
|
|
|
|
goto Exit; |
|
|
|
|
} |
|
|
|
|
face->num_locations = (FT_UInt)( table_len >> 1 ); |
|
|
|
|
face->num_locations = (FT_UInt)( table_len >> shift ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( face->num_locations != (FT_UInt)face->root.num_glyphs ) |
|
|
|
|
{ |
|
|
|
|
FT_TRACE2(( "glyph count mismatch! loca: %d, maxp: %d\n", |
|
|
|
|
face->num_locations, face->root.num_glyphs )); |
|
|
|
|
|
|
|
|
|
/* we only handle the case where `maxp' gives a larger value */ |
|
|
|
|
if ( face->num_locations < (FT_UInt)face->root.num_glyphs ) |
|
|
|
|
{ |
|
|
|
|
FT_Long new_loca_len = (FT_Long)face->root.num_glyphs << shift; |
|
|
|
|
|
|
|
|
|
TT_Table entry = face->dir_tables; |
|
|
|
|
TT_Table limit = entry + face->num_tables; |
|
|
|
|
|
|
|
|
|
FT_Long pos = FT_Stream_Pos( stream ); |
|
|
|
|
FT_Long dist = 0x7FFFFFFFL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* compute the distance to next table in font file */ |
|
|
|
|
for ( ; entry < limit; entry++ ) |
|
|
|
|
{ |
|
|
|
|
FT_Long diff = entry->Offset - pos; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( diff > 0 && diff < dist ) |
|
|
|
|
dist = diff; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ( new_loca_len <= dist ) |
|
|
|
|
{ |
|
|
|
|
face->num_locations = (FT_Long)face->root.num_glyphs; |
|
|
|
|
table_len = new_loca_len; |
|
|
|
|
|
|
|
|
|
FT_TRACE2(( "adjusting num_locations to %d\n", |
|
|
|
|
face->num_locations )); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|