* include/freetype/freetype.h, src/base/ftobjs.c: renamed

cmap14-related new APIs to the FT_Object_ActionName scheme.
        update the documentation for these APIs

        * src/sfnt/ttcmap.c: stronger cmap 14 validation, make the
        code a little more consistent with FreeType coding conventions
        and modify the cmap14 functions that returned a newly allocated
        array to use a persistent vector from the TT_CMap14 object
        instead.
This commit is contained in:
David Turner 2007-10-19 12:36:40 +00:00
parent 9a966b7d1b
commit cf432dbf22
4 changed files with 226 additions and 174 deletions

View File

@ -1,3 +1,15 @@
2007-10-18 David Turner <david@freetype.org>
* include/freetype/freetype.h, src/base/ftobjs.c: renamed
cmap14-related new APIs to the FT_Object_ActionName scheme.
update the documentation for these APIs
* src/sfnt/ttcmap.c: stronger cmap 14 validation, make the
code a little more consistent with FreeType coding conventions
and modify the cmap14 functions that returned a newly allocated
array to use a persistent vector from the TT_CMap14 object
instead.
2007-10-15 George Williams <gww@silcom.com> 2007-10-15 George Williams <gww@silcom.com>
Add support for cmap type 14. Add support for cmap type 14.
@ -46,7 +58,7 @@
2007-10-01 Werner Lemberg <wl@gnu.org> 2007-10-01 Werner Lemberg <wl@gnu.org>
* src/base/ftobjs.c (find_unicode_charmap): If search for a UCS-4 * src/base/ftobjs.c (find_unicode_charmap): If search for a UCS-4
charmap fails, do the loop again while searching a UCS-2 charmap. charmap fails, do the loop again while searching a UCS-2 charmap.
This favours MS charmaps over Apple ones. This favours MS charmaps over Apple ones.
2007-08-29 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> 2007-08-29 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
@ -121,7 +133,7 @@
2007-08-04 Werner Lemberg <wl@gnu.org> 2007-08-04 Werner Lemberg <wl@gnu.org>
* builds/unix/configure.raw: Add call to AC_LIBTOOL_WIN32_DLL. * builds/unix/configure.raw: Add call to AC_LIBTOOL_WIN32_DLL.
Fixes Savannah bug #20686. Fixes Savannah bug #20686.
2007-08-03 Werner Lemberg <wl@gnu.org> 2007-08-03 Werner Lemberg <wl@gnu.org>

View File

@ -2995,7 +2995,7 @@ FT_BEGIN_HEADER
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Function> */ /* <Function> */
/* FT_Get_Char_Variant_Index */ /* FT_Face_GetCharVariantIndex */
/* */ /* */
/* <Description> */ /* <Description> */
/* Return the glyph index of a given character code as modified by */ /* Return the glyph index of a given character code as modified by */
@ -3029,15 +3029,15 @@ FT_BEGIN_HEADER
/* b) the current charmap has a Unicode encoding */ /* b) the current charmap has a Unicode encoding */
/* */ /* */
FT_EXPORT( FT_UInt ) FT_EXPORT( FT_UInt )
FT_Get_Char_Variant_Index( FT_Face face, FT_Face_GetCharVariantIndex( FT_Face face,
FT_ULong charcode, FT_ULong charcode,
FT_ULong variantSelector ); FT_ULong variantSelector );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Function> */ /* <Function> */
/* FT_Get_Char_Variant_IsDefault */ /* FT_Face_GetCharVariantIsDefault */
/* */ /* */
/* <Description> */ /* <Description> */
/* Check whether this variant of this Unicode character is the one to */ /* Check whether this variant of this Unicode character is the one to */
@ -3062,15 +3062,15 @@ FT_BEGIN_HEADER
/* selector cmap subtable. */ /* selector cmap subtable. */
/* */ /* */
FT_EXPORT( FT_Int ) FT_EXPORT( FT_Int )
FT_Get_Char_Variant_IsDefault( FT_Face face, FT_Face_GetCharVariantIsDefault( FT_Face face,
FT_ULong charcode, FT_ULong charcode,
FT_ULong variantSelector ); FT_ULong variantSelector );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Function> */ /* <Function> */
/* FT_Get_Variant_Selectors */ /* FT_Face_GetVariantSelectors */
/* */ /* */
/* <Description> */ /* <Description> */
/* Return a zero-terminated list of Unicode variant selectors found */ /* Return a zero-terminated list of Unicode variant selectors found */
@ -3080,20 +3080,22 @@ FT_BEGIN_HEADER
/* face :: A handle to the source face object. */ /* face :: A handle to the source face object. */
/* */ /* */
/* <Return> */ /* <Return> */
/* A list of all the variant selector code points in the cmap */ /* A pointer to an array of selector code points, or NULL if there is */
/* or NULL if there is no valid variant selector cmap subtable. */ /* no valid variant selector cmap subtable. */
/* */ /* */
/* <Note> */ /* <Note> */
/* User is responsible for deallocating the returned list. */ /* the last item in the array is 0. the array is owned by the FT_Face */
/* but can be overwritten or released on the next call to a FreeType */
/* function. */
/* */ /* */
FT_EXPORT( FT_UInt32* ) FT_EXPORT( FT_UInt32* )
FT_Get_Variant_Selectors( FT_Face face ); FT_Face_GetVariantSelectors( FT_Face face );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Function> */ /* <Function> */
/* FT_Get_Variants_Of_Char */ /* FT_Face_GetVariantsOfChar */
/* */ /* */
/* <Description> */ /* <Description> */
/* Return a zero-terminated list of Unicode variant selectors found */ /* Return a zero-terminated list of Unicode variant selectors found */
@ -3107,22 +3109,24 @@ FT_BEGIN_HEADER
/* The character codepoint in Unicode. */ /* The character codepoint in Unicode. */
/* */ /* */
/* <Return> */ /* <Return> */
/* A list of all the variant selector code points which are active */ /* A pointer to an array of variant selector code points which are */
/* for the given character or NULL if there is no valid variant */ /* active for the given character, or NULL if the corresponding list */
/* selector cmap subtable (or if if this character has no variants). */ /* is empty. */
/* */ /* */
/* <Note> */ /* <Note> */
/* User is responsible for deallocating the returned list. */ /* the last item in the array is 0. the array is owned by the FT_Face */
/* but can be overwritten or released on the next call to a FreeType */
/* function. */
/* */ /* */
FT_EXPORT( FT_UInt32* ) FT_EXPORT( FT_UInt32* )
FT_Get_Variants_Of_Char( FT_Face face, FT_Face_GetVariantsOfChar( FT_Face face,
FT_ULong charcode ); FT_ULong charcode );
/*************************************************************************/ /*************************************************************************/
/* */ /* */
/* <Function> */ /* <Function> */
/* FT_Get_Chars_Of_Variant */ /* FT_Face_GetCharsOfVariant */
/* */ /* */
/* <Description> */ /* <Description> */
/* Return a zero-terminated list of Unicode character codes found for */ /* Return a zero-terminated list of Unicode character codes found for */
@ -3141,11 +3145,13 @@ FT_BEGIN_HEADER
/* is no valid cmap or the variant selector is invalid. */ /* is no valid cmap or the variant selector is invalid. */
/* */ /* */
/* <Note> */ /* <Note> */
/* User is responsible for deallocating the returned list. */ /* the last item in the array is 0. the array is owned by the FT_Face */
/* but can be overwritten or released on the next call to a FreeType */
/* function. */
/* */ /* */
FT_EXPORT( FT_UInt32* ) FT_EXPORT( FT_UInt32* )
FT_Get_Chars_Of_Variant( FT_Face face, FT_Face_GetCharsOfVariant( FT_Face face,
FT_ULong variantSelector ); FT_ULong variantSelector );
/*************************************************************************/ /*************************************************************************/

View File

@ -2893,9 +2893,9 @@
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_UInt ) FT_EXPORT_DEF( FT_UInt )
FT_Get_Char_Variant_Index( FT_Face face, FT_Face_GetCharVariantIndex( FT_Face face,
FT_ULong charcode, FT_ULong charcode,
FT_ULong variantSelector ) FT_ULong variantSelector )
{ {
FT_UInt result = 0; FT_UInt result = 0;
@ -2924,9 +2924,9 @@
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_Int ) FT_EXPORT_DEF( FT_Int )
FT_Get_Char_Variant_IsDefault( FT_Face face, FT_Face_GetCharVariantIsDefault( FT_Face face,
FT_ULong charcode, FT_ULong charcode,
FT_ULong variantSelector ) FT_ULong variantSelector )
{ {
FT_Int result = -1; FT_Int result = -1;
@ -2953,7 +2953,7 @@
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_UInt32* ) FT_EXPORT_DEF( FT_UInt32* )
FT_Get_Variant_Selectors( FT_Face face ) FT_Face_GetVariantSelectors( FT_Face face )
{ {
FT_UInt32 *result = NULL; FT_UInt32 *result = NULL;
@ -2980,8 +2980,8 @@
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_UInt32* ) FT_EXPORT_DEF( FT_UInt32* )
FT_Get_Variants_Of_Char( FT_Face face, FT_Face_GetVariantsOfChar( FT_Face face,
FT_ULong charcode ) FT_ULong charcode )
{ {
FT_UInt32 *result = NULL; FT_UInt32 *result = NULL;
@ -3007,8 +3007,8 @@
/* documentation is in freetype.h */ /* documentation is in freetype.h */
FT_EXPORT_DEF( FT_UInt32* ) FT_EXPORT_DEF( FT_UInt32* )
FT_Get_Chars_Of_Variant( FT_Face face, FT_Face_GetCharsOfVariant( FT_Face face,
FT_ULong variantSelector ) FT_ULong variantSelector )
{ {
FT_UInt32 *result = NULL; FT_UInt32 *result = NULL;

View File

@ -2287,7 +2287,7 @@
/* GID 3 USHORT and its GID */ /* GID 3 USHORT and its GID */
/* */ /* */
/* Ranges are sorted by `uniStart'. */ /* Ranges are sorted by `uniStart'. */
#ifdef TT_CONFIG_CMAP_FORMAT_14 #ifdef TT_CONFIG_CMAP_FORMAT_14
typedef struct TT_CMap14Rec_ typedef struct TT_CMap14Rec_
@ -2295,9 +2295,50 @@
TT_CMapRec cmap; TT_CMapRec cmap;
FT_ULong num_selectors; FT_ULong num_selectors;
/* this array is used to store the results of various
* cmap 14 query functions. its content is overwritten
* on each call to these functions
*/
FT_UInt max_results;
FT_UInt32* results;
FT_Memory memory;
} TT_CMap14Rec, *TT_CMap14; } TT_CMap14Rec, *TT_CMap14;
FT_CALLBACK_DEF( void )
tt_cmap14_done( TT_CMap14 cmap )
{
FT_Memory memory = cmap->memory;
cmap->max_results = 0;
if (memory != NULL && cmap->results != NULL)
FT_FREE( cmap->results );
}
static FT_Error
tt_cmap14_ensure( TT_CMap14 cmap,
FT_UInt num_results,
FT_Memory memory )
{
FT_UInt old_max = cmap->max_results;
FT_Error error = 0;
if (num_results > cmap->max_results)
{
cmap->memory = memory;
if ( FT_QRENEW_ARRAY( cmap->results, old_max, num_results ) )
return error;
cmap->max_results = num_results;
}
return error;
}
FT_CALLBACK_DEF( FT_Error ) FT_CALLBACK_DEF( FT_Error )
tt_cmap14_init( TT_CMap14 cmap, tt_cmap14_init( TT_CMap14 cmap,
FT_Byte* table ) FT_Byte* table )
@ -2306,6 +2347,8 @@
table += 6; table += 6;
cmap->num_selectors = FT_PEEK_ULONG( table ); cmap->num_selectors = FT_PEEK_ULONG( table );
cmap->max_results = 0;
cmap->results = NULL;
return SFNT_Err_Ok; return SFNT_Err_Ok;
} }
@ -2325,21 +2368,26 @@
/* check selectors, they must be in increasing order */ /* check selectors, they must be in increasing order */
{ {
FT_ULong n, varSel, defOff, nondefOff, last = 0; /* we start lastVarSel at 1 because a variant selector value of 0
* isn't legal.
*/
FT_ULong n, lastVarSel = 1;
for ( n = 0; n < num_selectors; n++ ) for ( n = 0; n < num_selectors; n++ )
{ {
varSel = TT_NEXT_UINT24( p ); FT_ULong varSel = TT_NEXT_UINT24( p );
defOff = TT_NEXT_ULONG( p ); FT_ULong defOff = TT_NEXT_ULONG( p );
nondefOff = TT_NEXT_ULONG( p ); FT_ULong nondefOff = TT_NEXT_ULONG( p );
if ( defOff >= length || nondefOff >= length ) if ( defOff >= length || nondefOff >= length )
FT_INVALID_TOO_SHORT; FT_INVALID_TOO_SHORT;
if ( n > 0 && varSel <= last ) if ( varSel < lastVarSel )
FT_INVALID_DATA; FT_INVALID_DATA;
last = varSel;
lastVarSel = varSel + 1;
/* check the default table (these glyphs should be reached */ /* check the default table (these glyphs should be reached */
/* through the normal Unicode cmap, no GIDs, just check order) */ /* through the normal Unicode cmap, no GIDs, just check order) */
@ -2347,20 +2395,25 @@
{ {
FT_Byte* defp = table + defOff; FT_Byte* defp = table + defOff;
FT_ULong numRanges = TT_NEXT_ULONG( defp ); FT_ULong numRanges = TT_NEXT_ULONG( defp );
FT_ULong i, base, cnt; FT_ULong i;
FT_ULong lastBase = 0;
if ( defp + numRanges*4 > valid->limit )
FT_INVALID_TOO_SHORT;
for ( i = 0; i < numRanges; ++i ) for ( i = 0; i < numRanges; ++i )
{ {
base = TT_NEXT_UINT24( defp ); FT_ULong base = TT_NEXT_UINT24( defp );
cnt = FT_NEXT_BYTE( defp ); FT_ULong cnt = FT_NEXT_BYTE( defp );
if ( base + cnt >= 0x110000UL ) /* end of Unicode */ if ( base + cnt >= 0x110000UL ) /* end of Unicode */
FT_INVALID_DATA; FT_INVALID_DATA;
if ( i > 0 && base <= last ) if ( base < lastBase )
FT_INVALID_DATA; FT_INVALID_DATA;
last = base + cnt;
lastBase = base + cnt + 1U;
} }
} }
@ -2368,20 +2421,25 @@
if ( nondefOff != 0 ) { if ( nondefOff != 0 ) {
FT_Byte* ndp = table + nondefOff; FT_Byte* ndp = table + nondefOff;
FT_ULong numMappings = TT_NEXT_ULONG( ndp ); FT_ULong numMappings = TT_NEXT_ULONG( ndp );
FT_ULong i, uni, gid; FT_ULong i, lastUni = 0;
if ( ndp + numMappings*4 > valid->limit )
FT_INVALID_TOO_SHORT;
for ( i = 0; i < numMappings; ++i ) for ( i = 0; i < numMappings; ++i )
{ {
uni = TT_NEXT_UINT24( ndp ); FT_ULong uni = TT_NEXT_UINT24( ndp );
gid = TT_NEXT_USHORT( ndp ); FT_ULong gid = TT_NEXT_USHORT( ndp );
if ( uni >= 0x110000UL ) /* end of Unicode */ if ( uni >= 0x110000UL ) /* end of Unicode */
FT_INVALID_DATA; FT_INVALID_DATA;
if ( i > 0 && uni <= last ) if ( uni < lastUni )
FT_INVALID_DATA; FT_INVALID_DATA;
last = uni;
lastUni = uni + 1U;
if ( valid->level >= FT_VALIDATE_TIGHT && if ( valid->level >= FT_VALIDATE_TIGHT &&
gid >= TT_VALID_GLYPH_COUNT( valid ) ) gid >= TT_VALID_GLYPH_COUNT( valid ) )
@ -2437,29 +2495,23 @@
tt_cmap14_char_map_def_binary( FT_Byte *base, tt_cmap14_char_map_def_binary( FT_Byte *base,
FT_UInt32 char_code ) FT_UInt32 char_code )
{ {
FT_Byte* p;
FT_UInt32 numRanges = TT_PEEK_ULONG( base ); FT_UInt32 numRanges = TT_PEEK_ULONG( base );
FT_UInt32 start, cnt; FT_UInt32 max, min;
FT_UInt32 max, min, mid;
if ( !numRanges )
return FALSE;
/* make compiler happy */
mid = numRanges;
min = 0; min = 0;
max = numRanges; max = numRanges;
base += 4;
/* binary search */ /* binary search */
while ( min < max ) while ( min < max )
{ {
mid = ( min + max ) >> 1; FT_UInt32 mid = ( min + max ) >> 1;
p = base + 4 + 4 * mid; FT_Byte* p = base + 4 * mid;
FT_ULong start = TT_NEXT_UINT24( p );
FT_UInt cnt = FT_NEXT_BYTE( p );
start = TT_NEXT_UINT24( p );
cnt = FT_NEXT_BYTE( p );
if ( char_code < start ) if ( char_code < start )
max = mid; max = mid;
@ -2477,38 +2529,30 @@
tt_cmap14_char_map_nondef_binary( FT_Byte *base, tt_cmap14_char_map_nondef_binary( FT_Byte *base,
FT_UInt32 char_code ) FT_UInt32 char_code )
{ {
FT_Byte* p;
FT_UInt32 numMappings = TT_PEEK_ULONG( base ); FT_UInt32 numMappings = TT_PEEK_ULONG( base );
FT_UInt32 uni, gid; FT_UInt32 max, min;
FT_UInt32 max, min, mid;
if ( !numMappings )
return 0;
/* make compiler happy */
mid = numMappings;
min = 0; min = 0;
max = numMappings; max = numMappings;
base += 4;
/* binary search */ /* binary search */
while ( min < max ) while ( min < max )
{ {
mid = ( min + max ) >> 1; FT_UInt32 mid = ( min + max ) >> 1;
p = base + 4 + 5 * mid; FT_Byte* p = base + 5 * mid;
FT_UInt32 uni = TT_PEEK_UINT24( p );
uni = TT_NEXT_UINT24( p );
gid = TT_NEXT_USHORT( p );
if ( char_code < uni ) if ( char_code < uni )
max = mid; max = mid;
else if ( char_code > uni ) else if ( char_code > uni )
min = mid + 1; min = mid + 1;
else else
return gid; return TT_PEEK_USHORT( p );
} }
return 0; return 0;
} }
@ -2517,28 +2561,22 @@
tt_cmap14_find_variant( FT_Byte *base, tt_cmap14_find_variant( FT_Byte *base,
FT_UInt32 variantCode ) FT_UInt32 variantCode )
{ {
FT_Byte* p;
FT_UInt32 numVar = TT_PEEK_ULONG( base ); FT_UInt32 numVar = TT_PEEK_ULONG( base );
FT_ULong varSel; FT_UInt32 max, min;
FT_UInt32 max, min, mid;
if ( !numVar )
return NULL;
/* make compiler happy */
mid = numVar;
min = 0; min = 0;
max = numVar; max = numVar;
base += 4;
/* binary search */ /* binary search */
while ( min < max ) while ( min < max )
{ {
mid = ( min + max ) >> 1; FT_UInt32 mid = ( min + max ) >> 1;
p = base + 4 + 11 * mid; FT_Byte* p = base + 11 * mid;
FT_ULong varSel = TT_PEEK_UINT24( p );
varSel = TT_NEXT_UINT24( p );
if ( variantCode < varSel ) if ( variantCode < varSel )
max = mid; max = mid;
@ -2558,7 +2596,7 @@
FT_ULong charcode, FT_ULong charcode,
FT_ULong variantSelector) FT_ULong variantSelector)
{ {
FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
FT_ULong defOff; FT_ULong defOff;
FT_ULong nondefOff; FT_ULong nondefOff;
@ -2567,7 +2605,7 @@
return 0; return 0;
defOff = TT_NEXT_ULONG( p ); defOff = TT_NEXT_ULONG( p );
nondefOff = TT_NEXT_ULONG( p ); nondefOff = TT_PEEK_ULONG( p );
if ( defOff != 0 && if ( defOff != 0 &&
tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) ) tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
@ -2590,7 +2628,7 @@
FT_ULong charcode, FT_ULong charcode,
FT_ULong variantSelector ) FT_ULong variantSelector )
{ {
FT_Byte *p = tt_cmap14_find_variant( cmap->data + 6, variantSelector ); FT_Byte* p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
FT_ULong defOff; FT_ULong defOff;
FT_ULong nondefOff; FT_ULong nondefOff;
@ -2619,24 +2657,23 @@
FT_Memory memory ) FT_Memory memory )
{ {
TT_CMap14 cmap14 = (TT_CMap14)cmap; TT_CMap14 cmap14 = (TT_CMap14)cmap;
FT_UInt count = cmap14->num_selectors;
FT_Byte* p = cmap->data + 10; FT_Byte* p = cmap->data + 10;
FT_UInt32* ret; FT_UInt32* result;
FT_UInt i; FT_UInt i;
FT_Error error;
if ( tt_cmap14_ensure( cmap14, (count + 1), memory ) )
if ( FT_ALLOC( ret,
( cmap14->num_selectors + 1 ) * sizeof ( FT_UInt32 ) ) )
return NULL; return NULL;
for ( i = 0; i < cmap14->num_selectors; ++i ) result = cmap14->results;
for ( i = 0; i < count; ++i )
{ {
ret[i] = TT_NEXT_UINT24( p ); result[i] = TT_NEXT_UINT24( p );
p += 8; p += 8;
} }
ret[i] = 0; result[i] = 0;
return ret; return result;
} }
@ -2646,108 +2683,109 @@
FT_ULong charCode ) FT_ULong charCode )
{ {
TT_CMap14 cmap14 = (TT_CMap14) cmap; TT_CMap14 cmap14 = (TT_CMap14) cmap;
FT_Byte* p = cmap->data + 10; FT_UInt count = cmap14->num_selectors;
FT_UInt32 *ret; FT_Byte* p = cmap->data + 10;
FT_UInt i, j; FT_UInt32* q;
FT_UInt32 varSel;
FT_ULong defOff;
FT_ULong nondefOff;
FT_Error error;
if ( FT_ALLOC( ret, if ( tt_cmap14_ensure( cmap14, (count + 1), memory ) )
( cmap14->num_selectors + 1 ) * sizeof ( FT_UInt32 ) ) )
return NULL; return NULL;
for ( i = j = 0; i < cmap14->num_selectors; ++i ) for ( q = cmap14->results; count > 0; --count )
{ {
varSel = TT_NEXT_UINT24( p ); FT_UInt32 varSel = TT_NEXT_UINT24( p );
defOff = TT_NEXT_ULONG( p ); FT_ULong defOff = TT_NEXT_ULONG( p );
nondefOff = TT_NEXT_ULONG( p ); FT_ULong nondefOff = TT_NEXT_ULONG( p );
if ( ( defOff != 0 && if ( ( defOff != 0 &&
tt_cmap14_char_map_def_binary( cmap->data + defOff, tt_cmap14_char_map_def_binary( cmap->data + defOff,
charCode ) ) || charCode ) ) ||
( nondefOff != 0 && ( nondefOff != 0 &&
tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff, tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
charCode ) != 0 ) ) charCode ) != 0 ) )
ret[j++] = varSel; {
q[0] = varSel;
q++;
}
} }
ret[j] = 0; q[0] = 0;
return ret; return cmap14->results;
} }
static FT_UInt static FT_UInt
tt_cmap14_def_char_count( FT_Byte *p ) tt_cmap14_def_char_count( FT_Byte *p )
{ {
FT_UInt32 numRanges; FT_UInt32 numRanges = TT_NEXT_ULONG( p );
FT_UInt tot; FT_UInt tot = 0;
FT_UInt cnt;
FT_UInt i;
numRanges = TT_NEXT_ULONG( p ); p += 3; /* point to the first 'cnt' field */
for ( ; numRanges > 0; numRanges-- )
tot = 0;
for ( i = 0; i < numRanges; ++i )
{ {
p += 3; tot += 1 + p[0];
cnt = FT_NEXT_BYTE( p ); p += 4;
tot += cnt + 1;
} }
return tot; return tot;
} }
static FT_UInt* static FT_UInt32*
tt_cmap14_get_def_chars( FT_Byte *p, tt_cmap14_get_def_chars( TT_CMap cmap,
FT_Byte* p,
FT_Memory memory ) FT_Memory memory )
{ {
TT_CMap14 cmap14 = (TT_CMap14) cmap;
FT_UInt32 numRanges; FT_UInt32 numRanges;
FT_UInt uni;
FT_UInt cnt; FT_UInt cnt;
FT_UInt i, j, k; FT_UInt32* q;
FT_UInt32 *ret;
FT_Error error;
cnt = tt_cmap14_def_char_count( p ); cnt = tt_cmap14_def_char_count( p );
numRanges = TT_NEXT_ULONG( p ); numRanges = TT_NEXT_ULONG( p );
if ( FT_ALLOC( ret , ( cnt + 1 ) * sizeof ( FT_UInt32 ) ) ) if ( tt_cmap14_ensure( cmap14, (cnt + 1), memory ) )
return NULL; return NULL;
for ( i = j = 0; i < numRanges; ++i ) for ( q = cmap14->results; numRanges > 0; --numRanges )
{ {
uni = TT_NEXT_UINT24( p ); FT_UInt uni = TT_NEXT_UINT24( p );
cnt = FT_NEXT_BYTE( p ); FT_UInt cnt = FT_NEXT_BYTE( p ) + 1;
for ( k = 0; k <= cnt; ++k ) do
ret[j++] = uni + k; {
q[0] = uni;
uni += 1;
q += 1;
}
while ( --cnt != 0 );
} }
ret[j] = 0; q[0] = 0;
return ret; return cmap14->results;
} }
static FT_UInt* static FT_UInt*
tt_cmap14_get_nondef_chars( FT_Byte *p, tt_cmap14_get_nondef_chars( TT_CMap cmap,
FT_Byte *p,
FT_Memory memory ) FT_Memory memory )
{ {
TT_CMap14 cmap14 = (TT_CMap14) cmap;
FT_UInt32 numMappings; FT_UInt32 numMappings;
FT_UInt i; FT_UInt i;
FT_UInt32 *ret; FT_UInt32 *ret;
FT_Error error;
numMappings = TT_NEXT_ULONG( p ); numMappings = TT_NEXT_ULONG( p );
if ( FT_ALLOC( ret, ( numMappings + 1 ) * sizeof ( FT_UInt32 ) ) ) if ( tt_cmap14_ensure( cmap14, (numMappings + 1), memory ) )
return NULL; return NULL;
ret = cmap14->results;
for ( i = 0; i < numMappings; ++i ) for ( i = 0; i < numMappings; ++i )
{ {
ret[i] = TT_NEXT_UINT24( p ); ret[i] = TT_NEXT_UINT24( p );
@ -2755,9 +2793,9 @@
} }
ret[i] = 0; ret[i] = 0;
return( ret ); return ret;
} }
FT_CALLBACK_DEF( FT_UInt32 * ) FT_CALLBACK_DEF( FT_UInt32 * )
tt_cmap14_variant_chars( TT_CMap cmap, tt_cmap14_variant_chars( TT_CMap cmap,
@ -2782,13 +2820,14 @@
return NULL; return NULL;
if ( defOff == 0 ) if ( defOff == 0 )
return tt_cmap14_get_nondef_chars( cmap->data + nondefOff, memory ); return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, memory );
else if ( nondefOff == 0 ) else if ( nondefOff == 0 )
return tt_cmap14_get_def_chars( cmap->data + defOff, memory ); return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, memory );
else else
{ {
/* Both a default and a non-default glyph set? That's probably not */ /* Both a default and a non-default glyph set? That's probably not */
/* good font design, but the spec allows for it... */ /* good font design, but the spec allows for it... */
TT_CMap14 cmap14 = (TT_CMap14) cmap;
FT_UInt32 numRanges; FT_UInt32 numRanges;
FT_UInt32 numMappings; FT_UInt32 numMappings;
FT_UInt32 duni; FT_UInt32 duni;
@ -2796,7 +2835,6 @@
FT_UInt32 nuni; FT_UInt32 nuni;
FT_Byte* dp; FT_Byte* dp;
FT_UInt di, ni, k; FT_UInt di, ni, k;
FT_Error error;
p = cmap->data + nondefOff; p = cmap->data + nondefOff;
@ -2807,14 +2845,14 @@
numRanges = TT_NEXT_ULONG( dp ); numRanges = TT_NEXT_ULONG( dp );
if ( numMappings == 0 ) if ( numMappings == 0 )
return tt_cmap14_get_def_chars( cmap->data + defOff, memory ); return tt_cmap14_get_def_chars( cmap, cmap->data + defOff, memory );
if ( dcnt == 0 ) if ( dcnt == 0 )
return tt_cmap14_get_nondef_chars( cmap->data + nondefOff, memory ); return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff, memory );
if ( FT_ALLOC( ret, if ( tt_cmap14_ensure( cmap14, (dcnt + numMappings + 1), memory ) )
( dcnt + numMappings + 1 ) * sizeof ( FT_UInt32 ) ) )
return NULL; return NULL;
ret = cmap14->results;
duni = TT_NEXT_UINT24( dp ); duni = TT_NEXT_UINT24( dp );
dcnt = FT_NEXT_BYTE( dp ); dcnt = FT_NEXT_BYTE( dp );
di = 1; di = 1;
@ -2832,13 +2870,11 @@
++di; ++di;
if ( di <= numRanges ) if ( di > numRanges )
{
duni = TT_NEXT_UINT24( dp );
dcnt = FT_NEXT_BYTE( dp );
}
else
break; break;
duni = TT_NEXT_UINT24( dp );
dcnt = FT_NEXT_BYTE( dp );
} }
else else
{ {
@ -2847,13 +2883,11 @@
/* If it is within the default range then ignore it -- */ /* If it is within the default range then ignore it -- */
/* that should not have happened */ /* that should not have happened */
++ni; ++ni;
if ( ni <= numMappings ) if ( ni > numMappings )
{
nuni = TT_NEXT_UINT24( p );
p += 2;
}
else
break; break;
nuni = TT_NEXT_UINT24( p );
p += 2;
} }
} }
@ -2903,7 +2937,7 @@
sizeof ( TT_CMap14Rec ), sizeof ( TT_CMap14Rec ),
(FT_CMap_InitFunc) tt_cmap14_init, (FT_CMap_InitFunc) tt_cmap14_init,
(FT_CMap_DoneFunc) NULL, (FT_CMap_DoneFunc) tt_cmap14_done,
(FT_CMap_CharIndexFunc)tt_cmap14_char_index, (FT_CMap_CharIndexFunc)tt_cmap14_char_index,
(FT_CMap_CharNextFunc) tt_cmap14_char_next, (FT_CMap_CharNextFunc) tt_cmap14_char_next,
/* Format 14 extension functions */ /* Format 14 extension functions */