From adf828ff953b0db3492ddf7678fdcefe34a5058b Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 11 Jan 2006 10:08:49 +0000 Subject: [PATCH] Fix Savannah bug #15056 and use pscmap service in psaux module. * include/freetype/internal/services/svpscmap.h (PS_UniMap): Use FT_UInt32 for `glyph_index'. (PS_Unicodes_InitFunc): Use FT_String for `glyph_names'. (PS_Unicodes_CharIndexFunc): Use FT_UInt32 for `unicode'. (PS_Unicodes_CharNextFunc): Make second argument a pointer to FT_UInt32. * src/psnames/psmodule.c (VARIANT_BIT, BASE_GLYPH): New macros. (ps_unicode_value): Set VARIANT_BIT in return value if glyph is a variant glyph (this is, it has non-leading `.' in its name). (compare_uni_maps): Sort base glyphs before variant glyphs. (ps_unicodes_init): Use FT_String for `glyph_names' argument. Reallocate only if number of used entries is much smaller. Updated to handle variant glyphs. (ps_unicodes_char_index, ps_unicodes_char_next): Prefer base glyphs over variant glyphs. Simplify code. * src/psaux/t1cmap.c (t1_cmap_uni_pair_compare): Removed. (t1_cmap_unicode_init, t1_cmap_unicode_char_index, t1_cmap_unicode_char_next): Use pscmap service. (t1_cmap_unicode_done): Updated. * src/psaux/t1cmap.h (T1_CMapUniPair): Removed. (T1_CMapUnicode): Use PS_Unicodes structure. --- ChangeLog | 59 ++++-- include/freetype/internal/services/svpscmap.h | 14 +- src/psaux/t1cmap.c | 165 ++------------- src/psaux/t1cmap.h | 17 +- src/psnames/psmodule.c | 192 ++++++++++++------ 5 files changed, 199 insertions(+), 248 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba03a7d9c..f720b4edb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,22 +1,53 @@ -2006-01-11 suzuki toshiya +2006-01-10 Werner Lemberg - Jumbo patch to fix "deprecated" warning to cross-build for - Tiger on Intel, the issue is reported by Sean McBride - on 2005-08-24. + Fix Savannah bug #15056 and use pscmap service in psaux module. - * src/base/ftmac.c: Heavy change to build without deprecated - Carbon functions on Tiger. + * include/freetype/internal/services/svpscmap.h (PS_UniMap): Use + FT_UInt32 for `glyph_index'. + (PS_Unicodes_InitFunc): Use FT_String for `glyph_names'. + (PS_Unicodes_CharIndexFunc): Use FT_UInt32 for `unicode'. + (PS_Unicodes_CharNextFunc): Make second argument a pointer to + FT_UInt32. - * builds/unix/configure.ac: Add options and autochecks for - Carbon functions availabilities, for MacOS X. + * src/psnames/psmodule.c (VARIANT_BIT, BASE_GLYPH): New macros. + (ps_unicode_value): Set VARIANT_BIT in return value if glyph is a + variant glyph (this is, it has non-leading `.' in its name). + (compare_uni_maps): Sort base glyphs before variant glyphs. + (ps_unicodes_init): Use FT_String for `glyph_names' argument. + Reallocate only if number of used entries is much smaller. + Updated to handle variant glyphs. + (ps_unicodes_char_index, ps_unicodes_char_next): Prefer base glyphs + over variant glyphs. + Simplify code. - * builds/mac/ascii2mpw.py: Add convertor for character "\305". + * src/psaux/t1cmap.c (t1_cmap_uni_pair_compare): Removed. + (t1_cmap_unicode_init, t1_cmap_unicode_char_index, + t1_cmap_unicode_char_next): Use pscmap service. + (t1_cmap_unicode_done): Updated. + + * src/psaux/t1cmap.h (T1_CMapUniPair): Removed. + (T1_CMapUnicode): Use PS_Unicodes structure. + +2006-01-11 suzuki toshiya + + Jumbo patch to fix `deprecated' warning of cross-build for Tiger on + Intel, as reported by Sean McBride on + 2005-08-24. + + * src/base/ftmac.c: Heavy change to build without deprecated Carbon + functions on Tiger. + + * builds/unix/configure.ac: Add options and autochecks for Carbon + functions availabilities, for MacOS X. + + * builds/mac/ascii2mpw.py: Add converter for character `\305'. * builds/mac/FreeType.m68k_{far|cfm}.make.txt: Add conditional - macros to avoid unavailable functions. And ftmac.c must be - compiled without "-strict ansi", because it disables cpp macro - to use ToolBox system call. - * builds/mac/FreeType.ppc_{classic|carbon}.make.txt: Add - conditional macros to avoid unavailable functions. + macros to avoid unavailable functions. + ftmac.c must be compiled without `-strict ansi', because it disables + cpp macro to use ToolBox system call. + + * builds/mac/FreeType.ppc_{classic|carbon}.make.txt: Add conditional + macros to avoid unavailable functions. * builds/mac/README: Detailed notes on function availabilities. diff --git a/include/freetype/internal/services/svpscmap.h b/include/freetype/internal/services/svpscmap.h index ade96ef8f..74d57f965 100644 --- a/include/freetype/internal/services/svpscmap.h +++ b/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript charmap service (specification). */ /* */ -/* Copyright 2003 by */ +/* Copyright 2003, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,7 +27,7 @@ FT_BEGIN_HEADER /* - * Adobe glyph name to unicode value + * Adobe glyph name to unicode value. */ typedef FT_UInt32 (*PS_Unicode_ValueFunc)( const char* glyph_name ); @@ -58,8 +58,8 @@ FT_BEGIN_HEADER */ typedef struct PS_UniMap_ { - FT_UInt unicode; - FT_UInt glyph_index; + FT_UInt32 unicode; /* bit 31 set: is glyph variant */ + FT_UInt glyph_index; } PS_UniMap; @@ -75,16 +75,16 @@ FT_BEGIN_HEADER typedef FT_Error (*PS_Unicodes_InitFunc)( FT_Memory memory, FT_UInt num_glyphs, - const char** glyph_names, + FT_String** glyph_names, PS_Unicodes* unicodes ); typedef FT_UInt (*PS_Unicodes_CharIndexFunc)( PS_Unicodes* unicodes, - FT_UInt unicode ); + FT_UInt32 unicode ); typedef FT_ULong (*PS_Unicodes_CharNextFunc)( PS_Unicodes* unicodes, - FT_ULong unicode ); + FT_UInt32 *unicode ); FT_DEFINE_SERVICE( PsCMaps ) diff --git a/src/psaux/t1cmap.c b/src/psaux/t1cmap.c index dcd99be49..a0e25e2c6 100644 --- a/src/psaux/t1cmap.c +++ b/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003 by */ +/* Copyright 2002, 2003, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -257,105 +257,30 @@ /*************************************************************************/ /*************************************************************************/ - FT_CALLBACK_DEF( FT_Int ) - t1_cmap_uni_pair_compare( const void* pair1, - const void* pair2 ) - { - FT_UInt32 u1 = ((T1_CMapUniPair)pair1)->unicode; - FT_UInt32 u2 = ((T1_CMapUniPair)pair2)->unicode; - - - if ( u1 < u2 ) - return -1; - - if ( u1 > u2 ) - return +1; - - return 0; - } - - FT_CALLBACK_DEF( FT_Error ) t1_cmap_unicode_init( T1_CMapUnicode cmap ) { - FT_Error error; - FT_UInt count; T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); FT_Memory memory = FT_FACE_MEMORY( face ); FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - cmap->num_pairs = 0; - cmap->pairs = NULL; - - count = face->type1.num_glyphs; - - if ( !FT_NEW_ARRAY( cmap->pairs, count ) ) - { - FT_UInt n, new_count; - T1_CMapUniPair pair; - FT_UInt32 uni_code; - - - pair = cmap->pairs; - for ( n = 0; n < count; n++ ) - { - const char* gname = face->type1.glyph_names[n]; - - - /* build unsorted pair table by matching glyph names */ - if ( gname ) - { - uni_code = psnames->unicode_value( gname ); - - if ( uni_code != 0 ) - { - pair->unicode = uni_code; - pair->gindex = n; - pair++; - } - } - } - - new_count = (FT_UInt)( pair - cmap->pairs ); - if ( new_count == 0 ) - { - /* there are no unicode characters in here! */ - FT_FREE( cmap->pairs ); - error = PSaux_Err_Invalid_Argument; - } - else - { - /* re-allocate if the new array is much smaller than the original */ - /* one */ - if ( new_count != count && new_count < count / 2 ) - { - (void)FT_RENEW_ARRAY( cmap->pairs, count, new_count ); - error = 0; - } - - /* sort the pairs table to allow efficient binary searches */ - ft_qsort( cmap->pairs, - new_count, - sizeof ( T1_CMapUniPairRec ), - t1_cmap_uni_pair_compare ); - - cmap->num_pairs = new_count; - } - } - - return error; + return psnames->unicodes_init( memory, + face->type1.num_glyphs, + face->type1.glyph_names, + &cmap->unicodes ); } FT_CALLBACK_DEF( void ) t1_cmap_unicode_done( T1_CMapUnicode cmap ) { - FT_Face face = FT_CMAP_FACE(cmap); - FT_Memory memory = FT_FACE_MEMORY(face); + FT_Face face = FT_CMAP_FACE( cmap ); + FT_Memory memory = FT_FACE_MEMORY( face ); - FT_FREE( cmap->pairs ); - cmap->num_pairs = 0; + + FT_FREE( cmap->unicodes.maps ); + cmap->unicodes.num_maps = 0; } @@ -363,26 +288,11 @@ t1_cmap_unicode_char_index( T1_CMapUnicode cmap, FT_UInt32 char_code ) { - FT_UInt min = 0; - FT_UInt max = cmap->num_pairs; - FT_UInt mid; - T1_CMapUniPair pair; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - while ( min < max ) - { - mid = min + ( max - min ) / 2; - pair = cmap->pairs + mid; - - if ( pair->unicode == char_code ) - return pair->gindex; - - if ( pair->unicode < char_code ) - min = mid + 1; - else - max = mid; - } - return 0; + return psnames->unicodes_char_index( &cmap->unicodes, char_code ); } @@ -390,54 +300,11 @@ t1_cmap_unicode_char_next( T1_CMapUnicode cmap, FT_UInt32 *pchar_code ) { - FT_UInt result = 0; - FT_UInt32 char_code = *pchar_code + 1; + T1_Face face = (T1_Face)FT_CMAP_FACE( cmap ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; - Restart: - { - FT_UInt min = 0; - FT_UInt max = cmap->num_pairs; - FT_UInt mid; - T1_CMapUniPair pair; - - - while ( min < max ) - { - mid = min + ( ( max - min ) >> 1 ); - pair = cmap->pairs + mid; - - if ( pair->unicode == char_code ) - { - result = pair->gindex; - if ( result != 0 ) - goto Exit; - - char_code++; - goto Restart; - } - - if ( pair->unicode < char_code ) - min = mid+1; - else - max = mid; - } - - /* we didn't find it, but we have a pair just above it */ - char_code = 0; - - if ( min < cmap->num_pairs ) - { - pair = cmap->pairs + min; - result = pair->gindex; - if ( result != 0 ) - char_code = pair->unicode; - } - } - - Exit: - *pchar_code = char_code; - return result; + return psnames->unicodes_char_next( &cmap->unicodes, pchar_code ); } diff --git a/src/psaux/t1cmap.h b/src/psaux/t1cmap.h index aa93d746c..5382efc31 100644 --- a/src/psaux/t1cmap.h +++ b/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (specification). */ /* */ -/* Copyright 2002, 2003 by */ +/* Copyright 2002, 2003, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -89,22 +89,13 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ - /* unicode (syntehtic) cmaps */ + /* unicode (synthetic) cmaps */ typedef struct T1_CMapUnicodeRec_* T1_CMapUnicode; - typedef struct T1_CMapUniPairRec_ - { - FT_UInt32 unicode; - FT_UInt gindex; - - } T1_CMapUniPairRec, *T1_CMapUniPair; - - typedef struct T1_CMapUnicodeRec_ { - FT_CMapRec cmap; - FT_UInt num_pairs; - T1_CMapUniPair pairs; + FT_CMapRec cmap; + PS_Unicodes unicodes; } T1_CMapUnicodeRec; diff --git a/src/psnames/psmodule.c b/src/psnames/psmodule.c index ba9deae8a..db8b25fcd 100644 --- a/src/psnames/psmodule.c +++ b/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2005 by */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,9 +32,14 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST +#define VARIANT_BIT ( 1L << 31 ) +#define BASE_GLYPH( code ) ( (code) & ~VARIANT_BIT ) + + /* Return the Unicode value corresponding to a given glyph. Note that */ /* we do deal with glyph variants by detecting a non-initial dot in */ - /* the name, as in `A.swash' or `e.final'. */ + /* the name, as in `A.swash' or `e.final'; in this case, the */ + /* VARIANT_BIT is set in the return value. */ /* */ static FT_UInt32 ps_unicode_value( const char* glyph_name ) @@ -72,7 +77,9 @@ d += 10; } - /* exit if a non-uppercase hexadecimal character was found */ + /* Exit if a non-uppercase hexadecimal character was found */ + /* -- this also catches character codes below `0' since such */ + /* negative numbers cast to `unsigned int' are far too big. */ if ( d >= 16 ) break; @@ -80,8 +87,13 @@ } /* there must be exactly four hex digits */ - if ( ( *p == '\0' || *p == '.' ) && count == 0 ) - return value; + if ( count == 0 ) + { + if ( *p == '\0' ) + return value; + if ( *p == '.' ) + return value ^ VARIANT_BIT; + } } /* If the name begins with `u', followed by four to six uppercase */ @@ -115,12 +127,17 @@ value = ( value << 4 ) + d; } - if ( ( *p == '\0' || *p == '.' ) && count <= 2 ) - return value; + if ( count <= 2 ) + { + if ( *p == '\0' ) + return value; + if ( *p == '.' ) + return value ^ VARIANT_BIT; + } } - /* look for a non-initial dot in the glyph name in order to */ - /* sort-out variants like `A.swash', `e.final', etc. */ + /* Look for a non-initial dot in the glyph name in order to */ + /* find variants like `A.swash', `e.final', etc. */ { const char* p = glyph_name; const char* dot = NULL; @@ -128,15 +145,18 @@ for ( ; *p; p++ ) { - if ( *p == '.' && p > glyph_name && !dot ) + if ( *p == '.' && p > glyph_name ) + { dot = p; + break; + } } + /* now look up the glyph in the Adobe Glyph List */ if ( !dot ) - dot = p; - - /* now, look up the glyph in the Adobe Glyph List */ - return ft_get_adobe_glyph_index( glyph_name, dot ); + return ft_get_adobe_glyph_index( glyph_name, p ); + else + return ft_get_adobe_glyph_index( glyph_name, dot ) ^ VARIANT_BIT; } } @@ -148,17 +168,23 @@ { PS_UniMap* map1 = (PS_UniMap*)a; PS_UniMap* map2 = (PS_UniMap*)b; + FT_UInt32 unicode1 = BASE_GLYPH( map1->unicode ); + FT_UInt32 unicode2 = BASE_GLYPH( map2->unicode ); - return ( map1->unicode - map2->unicode ); + /* sort base glyphs before glyph variants */ + if ( unicode1 == unicode2 ) + return map1->unicode - map2->unicode; + else + return unicode1 - unicode2; } - /* Builds a table that maps Unicode values to glyph indices */ + /* Build a table that maps Unicode values to glyph indices. */ static FT_Error ps_unicodes_init( FT_Memory memory, FT_UInt num_glyphs, - const char** glyph_names, + FT_String** glyph_names, PS_Unicodes* table ) { FT_Error error; @@ -187,32 +213,37 @@ { uni_char = ps_unicode_value( gname ); - if ( uni_char != 0 && uni_char != 0xFFFFL ) + if ( BASE_GLYPH( uni_char ) != 0 ) { - map->unicode = (FT_UInt)uni_char; + map->unicode = uni_char; map->glyph_index = n; map++; } } } - /* now, compress the table a bit */ + /* now compress the table a bit */ count = (FT_UInt)( map - table->maps ); - if ( count > 0 && FT_REALLOC( table->maps, - num_glyphs * sizeof ( PS_UniMap ), - count * sizeof ( PS_UniMap ) ) ) - count = 0; - if ( count == 0 ) { FT_FREE( table->maps ); if ( !error ) - error = PSnames_Err_Invalid_Argument; /* no unicode chars here! */ + error = PSnames_Err_Invalid_Argument; /* No unicode chars here! */ + } + else { + /* Reallocate if the number of used entries is much smaller. */ + if ( count < num_glyphs / 2 ) + { + (void)FT_RENEW_ARRAY( table->maps, num_glyphs, count ); + error = PSnames_Err_Ok; + } + + /* Sort the table in increasing order of unicode values, */ + /* taking care of glyph variants. */ + ft_qsort( table->maps, count, sizeof ( PS_UniMap ), + compare_uni_maps ); } - else - /* sort the table in increasing order of unicode values */ - ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps ); table->num_maps = count; } @@ -223,74 +254,105 @@ static FT_UInt ps_unicodes_char_index( PS_Unicodes* table, - FT_ULong unicode ) + FT_UInt32 unicode ) { - PS_UniMap *min, *max, *mid; + PS_UniMap *min, *max, *mid, *result = NULL; - /* perform a binary search on the table */ + /* Perform a binary search on the table. */ min = table->maps; max = min + table->num_maps - 1; while ( min <= max ) { - mid = min + ( max - min ) / 2; + FT_UInt32 base_glyph; + + + mid = min + ( ( max - min ) >> 1 ); + if ( mid->unicode == unicode ) - return mid->glyph_index; + { + result = mid; + break; + } + + base_glyph = BASE_GLYPH( mid->unicode ); + + if ( base_glyph == unicode ) + result = mid; /* remember match but continue search for base glyph */ if ( min == max ) break; - if ( mid->unicode < unicode ) + if ( base_glyph < unicode ) min = mid + 1; else max = mid - 1; } - return 0xFFFFU; + if ( result ) + return result->glyph_index; + else + return 0; } static FT_ULong ps_unicodes_char_next( PS_Unicodes* table, - FT_ULong unicode ) + FT_UInt32 *unicode ) { - PS_UniMap *min, *max, *mid; + FT_UInt result = 0; + FT_UInt32 char_code = *unicode + 1; - unicode++; - /* perform a binary search on the table */ - - min = table->maps; - max = min + table->num_maps - 1; - - while ( min <= max ) { - mid = min + ( max - min ) / 2; - if ( mid->unicode == unicode ) - return unicode; + FT_UInt min = 0; + FT_UInt max = table->num_maps; + FT_UInt mid; + PS_UniMap* map; + FT_UInt32 base_glyph; - if ( min == max ) - break; - if ( mid->unicode < unicode ) - min = mid + 1; - else - max = mid - 1; + while ( min < max ) + { + mid = min + ( ( max - min ) >> 1 ); + map = table->maps + mid; + + if ( map->unicode == char_code ) + { + result = map->glyph_index; + goto Exit; + } + + base_glyph = BASE_GLYPH( map->unicode ); + + if ( base_glyph == char_code ) + result = map->glyph_index; + + if ( base_glyph < char_code ) + min = mid + 1; + else + max = mid; + } + + if ( result ) + goto Exit; /* we have a variant glyph */ + + /* we didn't find it; check whether we have a map just above it */ + char_code = 0; + + if ( min < table->num_maps ) + { + map = table->maps + min; + result = map->glyph_index; + char_code = map->unicode; + } } - if ( max < table->maps ) - max = table->maps; - - while ( max < table->maps + table->num_maps ) - { - if ( unicode < max->unicode ) - return max->unicode; - max++; - } - - return 0; + Exit: + *unicode = char_code; + return result; }