|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* found a Unicode name */ |
|
|
|
|
if ( found >= 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 |
|
|
|
|
rec = face->name_table.names + found_win; |
|
|
|
|
switch ( rec->encodingID ) |
|
|
|
|
{ |
|
|
|
|
len = rec->stringLength; |
|
|
|
|
if ( FT_MEM_ALLOC( string, len + 1 ) ) |
|
|
|
|
return NULL; |
|
|
|
|
|
|
|
|
|
FT_MEM_COPY( string, rec->string, len ); |
|
|
|
|
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: |
|
|
|
|
; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
string[len] = '\0'; |
|
|
|
|
return string; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return NULL; |
|
|
|
|
else if ( found_apple >= 0 ) |
|
|
|
|
{ |
|
|
|
|
rec = face->name_table.names + found_apple; |
|
|
|
|
result = tt_name_entry_ascii_from_other( rec, memory ); |
|
|
|
|
} |
|
|
|
|
else if ( found_unicode >= 0 ) |
|
|
|
|
{ |
|
|
|
|
rec = face->name_table.names + found_unicode; |
|
|
|
|
result = tt_name_entry_ascii_from_utf16( rec, memory ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|