fixing the function that computes an ASCII face name

This commit is contained in:
David Turner 2002-03-30 16:32:47 +00:00
parent d76050abd7
commit 56054f310b
2 changed files with 159 additions and 52 deletions

View File

@ -1,5 +1,7 @@
2002-03-30 David Turner <david@freetype.org>
* src/sfnt/sfobjs.c (tt_face_get_name): bug-fix
* include/freetype/internal/tttypes.h: adding comments to some of
the TT_FaceRec fields.

View File

@ -38,6 +38,94 @@
#define FT_COMPONENT trace_sfobjs
/* convert a UTF-16 name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_utf16( TT_NameEntry entry,
FT_Memory memory )
{
FT_String* string;
FT_UInt len, code, n;
FT_Byte* read = (FT_Byte*) entry->string;
len = (FT_UInt) entry->stringLength/2;
if ( FT_MEM_NEW_ARRAY( string, len+1 ) )
return NULL;
for ( n = 0; n < len; n++ )
{
code = FT_NEXT_USHORT(read);
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
string[len] = 0;
return string;
}
/* convert a UCS-4 name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_ucs4( TT_NameEntry entry,
FT_Memory memory )
{
FT_String* string;
FT_UInt len, code, n;
FT_Byte* read = (FT_Byte*) entry->string;
len = (FT_UInt) entry->stringLength/4;
if ( FT_MEM_NEW_ARRAY( string, len+1 ) )
return NULL;
for ( n = 0; n < len; n++ )
{
code = FT_NEXT_ULONG(read);
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
string[len] = 0;
return string;
}
/* convert an Apple Roman or symbol name entry to ASCII */
static FT_String*
tt_name_entry_ascii_from_other( TT_NameEntry entry,
FT_Memory memory )
{
FT_String* string;
FT_UInt len, code, n;
FT_Byte* read = (FT_Byte*) entry->string;
len = (FT_UInt) entry->stringLength;
if ( FT_MEM_NEW_ARRAY( string, len+1 ) )
return NULL;
for ( n = 0; n < len; n++ )
{
code = *read++;
if ( code < 32 || code > 127 )
code = '?';
string[n] = (char)code;
}
string[len] = 0;
return string;
}
/*************************************************************************/
/* */
/* <Function> */
@ -56,34 +144,48 @@
/* */
static FT_String*
tt_face_get_name( TT_Face face,
FT_UShort nameid )
FT_UShort nameid )
{
FT_Memory memory = face->root.memory;
FT_UShort n;
FT_Memory memory = face->root.memory;
FT_String* result = NULL;
FT_UShort n;
TT_NameEntryRec* rec;
FT_Bool wide_chars = 1;
FT_Int found_apple = -1;
FT_Int found_win = -1;
FT_Int found_unicode = -1;
FT_Int found;
FT_Int found_apple = -1;
FT_Int found_win = -1;
FT_Int found_unicode = -1;
rec = face->name_table.names;
for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ )
{
/* according to the OpenType 1.3 specification, only Microsoft of */
/* Apple platform ids might be used in the 'name' table. The */
/* 'Unicode' platform is reserved for the 'cmap' table, and */
/* the 'Iso' one is deprecated */
/* however the Apple TrueType specification doesn't says the same */
/* thing and goes to suggest that all Unicode 'name' table entries */
/* should be coded in UTF-16 (in big-endian format I suppose) */
/* */
if ( rec->nameID == nameid && rec->string )
{
switch ( rec->platformID )
{
case TT_PLATFORM_APPLE_UNICODE:
case TT_PLATFORM_ISO:
{
/* there is 'languageID' to check there. We should use this */
/* field only as a last solution when nothing else is */
/* available.. */
/* */
found_unicode = n;
break;
}
case TT_PLATFORM_MACINTOSH:
{
if ( rec->languageID == TT_MAC_ID_ROMAN )
if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
found_apple = n;
break;
@ -91,10 +193,22 @@
case TT_PLATFORM_MICROSOFT:
{
if ( rec->encodingID <= TT_MS_ID_UNICODE_CS &&
(rec->languageID & 0x3FF) == 0x009 )
/* we only take a non-English name when there is nothing */
/* else available in the font.. */
/* */
if ( found_win == -1 || (rec->languageID & 0x3FF) == 0x009 )
{
found_win = n;
switch ( rec->encodingID )
{
case TT_MS_ID_SYMBOL_CS:
case TT_MS_ID_UNICODE_CS:
case TT_MS_ID_UCS_4:
found_win = n;
break;
default:
;
}
}
break;
}
@ -109,49 +223,40 @@
/* we will thus favor name encoded in Windows formats when they're */
/* available.. */
/* */
found = found_win;
if ( found < 0 )
if ( found_win >= 0 )
{
found = found_apple;
if ( found_apple < 0 )
found = found_unicode;
else
wide_chars = 0;
rec = face->name_table.names + found_win;
switch ( rec->encodingID )
{
case TT_MS_ID_UNICODE_CS:
case TT_MS_ID_SYMBOL_CS:
{
result = tt_name_entry_ascii_from_utf16( rec, memory );
break;
}
case TT_MS_ID_UCS_4:
{
result = tt_name_entry_ascii_from_ucs4( rec, memory );
break;
}
default:
;
}
}
/* found a Unicode name */
if ( found >= 0 )
else if ( found_apple >= 0 )
{
FT_String* string;
FT_UInt len;
rec = face->name_table.names + found;
if ( wide_chars )
{
FT_UInt m;
len = (FT_UInt)rec->stringLength / 2;
if ( FT_MEM_ALLOC( string, len + 1 ) )
return NULL;
for ( m = 0; m < len; m ++ )
string[m] = rec->string[2 * m + 1];
}
else
{
len = rec->stringLength;
if ( FT_MEM_ALLOC( string, len + 1 ) )
return NULL;
FT_MEM_COPY( string, rec->string, len );
}
string[len] = '\0';
return string;
rec = face->name_table.names + found_apple;
result = tt_name_entry_ascii_from_other( rec, memory );
}
return NULL;
else if ( found_unicode >= 0 )
{
rec = face->name_table.names + found_unicode;
result = tt_name_entry_ascii_from_utf16( rec, memory );
}
return result;
}