ref: adf828ff953b0db3492ddf7678fdcefe34a5058b
parent: f8d16cc540f1fcb6a466ec25176cc869d08bb18a
author: Werner Lemberg <[email protected]>
date: Wed Jan 11 05:08:49 EST 2006
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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,22 +1,53 @@
-2006-01-11 suzuki toshiya <[email protected]>
+2006-01-10 Werner Lemberg <[email protected]>
- Jumbo patch to fix "deprecated" warning to cross-build for
- Tiger on Intel, the issue is reported by Sean McBride
- <[email protected]> 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 <[email protected]>
+
+ Jumbo patch to fix `deprecated' warning of cross-build for Tiger on
+ Intel, as reported by Sean McBride <[email protected]> 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.
--- 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 @@
/*
- * 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 @@
*/
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 @@
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 )
--- 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,94 +257,18 @@
/*************************************************************************/
/*************************************************************************/
- 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 );
}
@@ -351,11 +275,12 @@
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 );
}
--- 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 @@
/*************************************************************************/
/*************************************************************************/
- /* 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;
--- 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,9 +213,9 @@
{
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++;
}
@@ -196,24 +222,29 @@
}
}
- /* 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
- /* sort the table in increasing order of unicode values */
- ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps );
+ 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 );
+ }
+
table->num_maps = count;
}
@@ -223,12 +254,12 @@
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;
@@ -235,62 +266,93 @@
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 */
+ {
+ FT_UInt min = 0;
+ FT_UInt max = table->num_maps;
+ FT_UInt mid;
+ PS_UniMap* map;
+ FT_UInt32 base_glyph;
- min = table->maps;
- max = min + table->num_maps - 1;
- while ( min <= max )
- {
- mid = min + ( max - min ) / 2;
- if ( mid->unicode == unicode )
- return unicode;
+ while ( min < max )
+ {
+ mid = min + ( ( max - min ) >> 1 );
+ map = table->maps + mid;
- if ( min == max )
- break;
+ if ( map->unicode == char_code )
+ {
+ result = map->glyph_index;
+ goto Exit;
+ }
- if ( mid->unicode < unicode )
- min = mid + 1;
- else
- max = mid - 1;
- }
+ base_glyph = BASE_GLYPH( map->unicode );
- if ( max < table->maps )
- max = table->maps;
+ if ( base_glyph == char_code )
+ result = map->glyph_index;
- while ( max < table->maps + table->num_maps )
- {
- if ( unicode < max->unicode )
- return max->unicode;
- max++;
+ 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;
+ }
}
- return 0;
+ Exit:
+ *unicode = char_code;
+ return result;
}