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.
This commit is contained in:
Werner Lemberg 2006-01-11 10:08:49 +00:00
parent f8d16cc540
commit adf828ff95
5 changed files with 199 additions and 248 deletions

View File

@ -1,22 +1,53 @@
2006-01-11 suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>
2006-01-10 Werner Lemberg <wl@gnu.org>
Jumbo patch to fix "deprecated" warning to cross-build for
Tiger on Intel, the issue is reported by Sean McBride
<sean@rogue-research.com> 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 <mpsuzuki@hiroshima-u.ac.jp>
Jumbo patch to fix `deprecated' warning of cross-build for Tiger on
Intel, as reported by Sean McBride <sean@rogue-research.com> 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.

View File

@ -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 )

View File

@ -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 );
}

View File

@ -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;

View File

@ -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;
}