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> 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 * include/freetype/internal/tttypes.h: adding comments to some of
the TT_FaceRec fields. the TT_FaceRec fields.

View File

@ -38,6 +38,94 @@
#define FT_COMPONENT trace_sfobjs #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> */ /* <Function> */
@ -56,34 +144,48 @@
/* */ /* */
static FT_String* static FT_String*
tt_face_get_name( TT_Face face, tt_face_get_name( TT_Face face,
FT_UShort nameid ) FT_UShort nameid )
{ {
FT_Memory memory = face->root.memory; FT_Memory memory = face->root.memory;
FT_UShort n; FT_String* result = NULL;
FT_UShort n;
TT_NameEntryRec* rec; TT_NameEntryRec* rec;
FT_Bool wide_chars = 1; FT_Int found_apple = -1;
FT_Int found_apple = -1; FT_Int found_win = -1;
FT_Int found_win = -1; FT_Int found_unicode = -1;
FT_Int found_unicode = -1;
FT_Int found;
rec = face->name_table.names; rec = face->name_table.names;
for ( n = 0; n < face->name_table.numNameRecords; n++, rec++ ) 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 ) if ( rec->nameID == nameid && rec->string )
{ {
switch ( rec->platformID ) switch ( rec->platformID )
{ {
case TT_PLATFORM_APPLE_UNICODE: 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; found_unicode = n;
break; break;
} }
case TT_PLATFORM_MACINTOSH: case TT_PLATFORM_MACINTOSH:
{ {
if ( rec->languageID == TT_MAC_ID_ROMAN ) if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
found_apple = n; found_apple = n;
break; break;
@ -91,10 +193,22 @@
case TT_PLATFORM_MICROSOFT: case TT_PLATFORM_MICROSOFT:
{ {
if ( rec->encodingID <= TT_MS_ID_UNICODE_CS && /* we only take a non-English name when there is nothing */
(rec->languageID & 0x3FF) == 0x009 ) /* 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; break;
} }
@ -109,49 +223,40 @@
/* we will thus favor name encoded in Windows formats when they're */ /* we will thus favor name encoded in Windows formats when they're */
/* available.. */ /* available.. */
/* */ /* */
found = found_win; if ( found_win >= 0 )
if ( found < 0 )
{ {
found = found_apple; rec = face->name_table.names + found_win;
if ( found_apple < 0 ) switch ( rec->encodingID )
found = found_unicode; {
else case TT_MS_ID_UNICODE_CS:
wide_chars = 0; 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:
;
}
} }
else if ( found_apple >= 0 )
/* found a Unicode name */
if ( found >= 0 )
{ {
FT_String* string; rec = face->name_table.names + found_apple;
FT_UInt len; result = tt_name_entry_ascii_from_other( rec, memory );
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;
} }
else if ( found_unicode >= 0 )
return NULL; {
rec = face->name_table.names + found_unicode;
result = tt_name_entry_ascii_from_utf16( rec, memory );
}
return result;
} }