gdi32: Try to parse font names without FreeType.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e338d04697
commit
93ef83e903
|
@ -1092,6 +1092,86 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct family_names_data
|
||||
{
|
||||
LANGID primary_langid;
|
||||
struct opentype_name family_name;
|
||||
struct opentype_name second_name;
|
||||
BOOL primary_seen;
|
||||
BOOL english_seen;
|
||||
};
|
||||
|
||||
static BOOL search_family_names_callback( LANGID langid, struct opentype_name *name, void *user )
|
||||
{
|
||||
struct family_names_data *data = user;
|
||||
|
||||
if (langid == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
|
||||
{
|
||||
data->english_seen = TRUE;
|
||||
if (data->primary_langid == langid) data->primary_seen = TRUE;
|
||||
|
||||
if (!data->family_name.bytes) data->family_name = *name;
|
||||
else if (data->primary_langid != langid) data->second_name = *name;
|
||||
}
|
||||
else if (data->primary_langid == langid)
|
||||
{
|
||||
data->primary_seen = TRUE;
|
||||
if (!data->second_name.bytes) data->second_name = data->family_name;
|
||||
data->family_name = *name;
|
||||
}
|
||||
else if (!data->second_name.bytes) data->second_name = *name;
|
||||
|
||||
if (data->family_name.bytes && data->second_name.bytes && data->primary_seen && data->english_seen)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
struct face_name_data
|
||||
{
|
||||
LANGID primary_langid;
|
||||
struct opentype_name face_name;
|
||||
};
|
||||
|
||||
static BOOL search_face_name_callback( LANGID langid, struct opentype_name *name, void *user )
|
||||
{
|
||||
struct face_name_data *data = user;
|
||||
|
||||
if (langid == data->primary_langid || (langid == MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) && !data->face_name.bytes))
|
||||
data->face_name = *name;
|
||||
|
||||
return langid == data->primary_langid;
|
||||
}
|
||||
|
||||
static WCHAR *decode_opentype_name( struct opentype_name *name )
|
||||
{
|
||||
CPTABLEINFO codepage_info;
|
||||
USHORT *codepage_ptr;
|
||||
SIZE_T codepage_size;
|
||||
WCHAR buffer[512];
|
||||
DWORD len;
|
||||
|
||||
if (!name->codepage)
|
||||
{
|
||||
len = min( ARRAY_SIZE(buffer), name->length / sizeof(WCHAR) );
|
||||
while (len--) buffer[len] = GET_BE_WORD( ((WORD *)name->bytes)[len] );
|
||||
len = min( ARRAY_SIZE(buffer), name->length / sizeof(WCHAR) );
|
||||
}
|
||||
else
|
||||
{
|
||||
NtGetNlsSectionPtr( 11, name->codepage, NULL, (void **)&codepage_ptr, &codepage_size );
|
||||
RtlInitCodePageTable( codepage_ptr, &codepage_info );
|
||||
RtlCustomCPToUnicodeN( &codepage_info, buffer, sizeof(buffer), &len, name->bytes, name->length );
|
||||
len /= sizeof(WCHAR);
|
||||
NtUnmapViewOfSection( GetCurrentProcess(), codepage_ptr );
|
||||
}
|
||||
|
||||
buffer[ARRAY_SIZE(buffer) - 1] = 0;
|
||||
if (len == ARRAY_SIZE(buffer)) WARN("Truncated font name %s -> %s\n", debugstr_an(name->bytes, name->length), debugstr_w(buffer));
|
||||
else buffer[len] = 0;
|
||||
|
||||
return strdupW( buffer );
|
||||
}
|
||||
|
||||
struct unix_face
|
||||
{
|
||||
FT_Face ft_face;
|
||||
|
@ -1110,11 +1190,14 @@ struct unix_face
|
|||
static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr, DWORD data_size,
|
||||
UINT face_index, DWORD flags )
|
||||
{
|
||||
static const WCHAR space_w[] = {' ',0};
|
||||
|
||||
const struct ttc_sfnt_v1 *ttc_sfnt_v1;
|
||||
const struct tt_name_v0 *tt_name_v0;
|
||||
struct unix_face *This;
|
||||
struct stat st;
|
||||
DWORD face_count;
|
||||
int fd;
|
||||
int fd, length;
|
||||
|
||||
TRACE( "unix_name %s, face_index %u, data_ptr %p, data_size %u, flags %#x\n",
|
||||
unix_name, face_index, data_ptr, data_size, flags );
|
||||
|
@ -1140,20 +1223,55 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
|
|||
RtlFreeHeap( GetProcessHeap(), 0, This );
|
||||
This = NULL;
|
||||
}
|
||||
else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ))
|
||||
else if (opentype_get_ttc_sfnt_v1( data_ptr, data_size, face_index, &face_count, &ttc_sfnt_v1 ) &&
|
||||
opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ))
|
||||
{
|
||||
struct family_names_data family_names;
|
||||
struct face_name_data style_name;
|
||||
struct face_name_data full_name;
|
||||
LANGID primary_langid = system_lcid;
|
||||
|
||||
This->scalable = TRUE;
|
||||
This->num_faces = face_count;
|
||||
|
||||
memset( &family_names, 0, sizeof(family_names) );
|
||||
family_names.primary_langid = primary_langid;
|
||||
opentype_enum_family_names( tt_name_v0, search_family_names_callback, &family_names );
|
||||
This->family_name = decode_opentype_name( &family_names.family_name );
|
||||
This->second_name = decode_opentype_name( &family_names.second_name );
|
||||
|
||||
memset( &style_name, 0, sizeof(style_name) );
|
||||
style_name.primary_langid = primary_langid;
|
||||
opentype_enum_style_names( tt_name_v0, search_face_name_callback, &style_name );
|
||||
This->style_name = decode_opentype_name( &style_name.face_name );
|
||||
|
||||
memset( &full_name, 0, sizeof(full_name) );
|
||||
style_name.primary_langid = primary_langid;
|
||||
opentype_enum_full_names( tt_name_v0, search_face_name_callback, &full_name );
|
||||
This->full_name = decode_opentype_name( &full_name.face_name );
|
||||
|
||||
TRACE( "parsed font names family_name %s, second_name %s, primary_seen %d, english_seen %d, "
|
||||
"full_name %s, style_name %s\n",
|
||||
debugstr_w(This->family_name), debugstr_w(This->second_name),
|
||||
family_names.primary_seen, family_names.english_seen,
|
||||
debugstr_w(This->full_name), debugstr_w(This->style_name) );
|
||||
|
||||
if (!This->full_name && This->family_name && This->style_name)
|
||||
{
|
||||
length = lstrlenW( This->family_name ) + lstrlenW( space_w ) + lstrlenW( This->style_name ) + 1;
|
||||
This->full_name = RtlAllocateHeap( GetProcessHeap(), 0, length * sizeof(WCHAR) );
|
||||
lstrcpyW( This->full_name, This->family_name );
|
||||
lstrcatW( This->full_name, space_w );
|
||||
lstrcatW( This->full_name, This->style_name );
|
||||
WARN( "full name not found, using %s instead\n", debugstr_w(This->full_name) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN( "unable to parse font, falling back to FreeType\n" );
|
||||
This->scalable = FT_IS_SCALABLE( This->ft_face );
|
||||
This->num_faces = This->ft_face->num_faces;
|
||||
}
|
||||
|
||||
if (This)
|
||||
{
|
||||
This->family_name = ft_face_get_family_name( This->ft_face, system_lcid );
|
||||
This->second_name = ft_face_get_family_name( This->ft_face, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT) );
|
||||
|
||||
|
@ -1173,7 +1291,10 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr
|
|||
|
||||
This->style_name = ft_face_get_style_name( This->ft_face, system_lcid );
|
||||
This->full_name = ft_face_get_full_name( This->ft_face, system_lcid );
|
||||
}
|
||||
|
||||
if (This)
|
||||
{
|
||||
This->ntm_flags = get_ntm_flags( This->ft_face );
|
||||
This->font_version = get_font_version( This->ft_face );
|
||||
if (!This->scalable) get_bitmap_size( This->ft_face, &This->size );
|
||||
|
|
|
@ -417,9 +417,27 @@ extern void font_init(void) DECLSPEC_HIDDEN;
|
|||
/* opentype.c */
|
||||
|
||||
struct ttc_sfnt_v1;
|
||||
struct tt_name_v0;
|
||||
|
||||
struct opentype_name
|
||||
{
|
||||
DWORD codepage;
|
||||
DWORD length;
|
||||
const void *bytes;
|
||||
};
|
||||
|
||||
extern BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count,
|
||||
const struct ttc_sfnt_v1 **ttc_sfnt_v1 ) DECLSPEC_HIDDEN;
|
||||
extern BOOL opentype_get_tt_name_v0( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
|
||||
const struct tt_name_v0 **tt_name_v0 ) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef BOOL ( *opentype_enum_names_cb )( LANGID langid, struct opentype_name *name, void *user );
|
||||
extern BOOL opentype_enum_family_names( const struct tt_name_v0 *tt_name_v0,
|
||||
opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
|
||||
extern BOOL opentype_enum_style_names( const struct tt_name_v0 *tt_name_v0,
|
||||
opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
|
||||
extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0,
|
||||
opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* gdiobj.c */
|
||||
extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
@ -40,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(font);
|
|||
#define MS_EBSC_TAG MS_MAKE_TAG('E','B','S','C')
|
||||
#define MS_EBDT_TAG MS_MAKE_TAG('E','B','D','T')
|
||||
#define MS_CBDT_TAG MS_MAKE_TAG('C','B','D','T')
|
||||
#define MS_NAME_TAG MS_MAKE_TAG('n','a','m','e')
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define GET_BE_WORD(x) (x)
|
||||
|
@ -115,8 +117,125 @@ struct tt_os2_v1
|
|||
ULONG ulCodePageRange1;
|
||||
ULONG ulCodePageRange2;
|
||||
};
|
||||
|
||||
struct tt_namerecord
|
||||
{
|
||||
WORD platformID;
|
||||
WORD encodingID;
|
||||
WORD languageID;
|
||||
WORD nameID;
|
||||
WORD length;
|
||||
WORD offset;
|
||||
};
|
||||
|
||||
struct tt_name_v0
|
||||
{
|
||||
WORD format;
|
||||
WORD count;
|
||||
WORD stringOffset;
|
||||
struct tt_namerecord nameRecord[1];
|
||||
};
|
||||
#include "poppack.h"
|
||||
|
||||
enum OPENTYPE_PLATFORM_ID
|
||||
{
|
||||
OPENTYPE_PLATFORM_UNICODE = 0,
|
||||
OPENTYPE_PLATFORM_MAC,
|
||||
OPENTYPE_PLATFORM_ISO,
|
||||
OPENTYPE_PLATFORM_WIN,
|
||||
OPENTYPE_PLATFORM_CUSTOM
|
||||
};
|
||||
|
||||
enum TT_NAME_WIN_ENCODING_ID
|
||||
{
|
||||
TT_NAME_WIN_ENCODING_SYMBOL = 0,
|
||||
TT_NAME_WIN_ENCODING_UNICODE_BMP,
|
||||
TT_NAME_WIN_ENCODING_SJIS,
|
||||
TT_NAME_WIN_ENCODING_PRC,
|
||||
TT_NAME_WIN_ENCODING_BIG5,
|
||||
TT_NAME_WIN_ENCODING_WANSUNG,
|
||||
TT_NAME_WIN_ENCODING_JOHAB,
|
||||
TT_NAME_WIN_ENCODING_RESERVED1,
|
||||
TT_NAME_WIN_ENCODING_RESERVED2,
|
||||
TT_NAME_WIN_ENCODING_RESERVED3,
|
||||
TT_NAME_WIN_ENCODING_UNICODE_FULL
|
||||
};
|
||||
|
||||
enum TT_NAME_UNICODE_ENCODING_ID
|
||||
{
|
||||
TT_NAME_UNICODE_ENCODING_1_0 = 0,
|
||||
TT_NAME_UNICODE_ENCODING_1_1,
|
||||
TT_NAME_UNICODE_ENCODING_ISO_10646,
|
||||
TT_NAME_UNICODE_ENCODING_2_0_BMP,
|
||||
TT_NAME_UNICODE_ENCODING_2_0_FULL,
|
||||
TT_NAME_UNICODE_ENCODING_VAR,
|
||||
TT_NAME_UNICODE_ENCODING_FULL,
|
||||
};
|
||||
|
||||
enum TT_NAME_MAC_ENCODING_ID
|
||||
{
|
||||
TT_NAME_MAC_ENCODING_ROMAN = 0,
|
||||
TT_NAME_MAC_ENCODING_JAPANESE,
|
||||
TT_NAME_MAC_ENCODING_TRAD_CHINESE,
|
||||
TT_NAME_MAC_ENCODING_KOREAN,
|
||||
TT_NAME_MAC_ENCODING_ARABIC,
|
||||
TT_NAME_MAC_ENCODING_HEBREW,
|
||||
TT_NAME_MAC_ENCODING_GREEK,
|
||||
TT_NAME_MAC_ENCODING_RUSSIAN,
|
||||
TT_NAME_MAC_ENCODING_RSYMBOL,
|
||||
TT_NAME_MAC_ENCODING_DEVANAGARI,
|
||||
TT_NAME_MAC_ENCODING_GURMUKHI,
|
||||
TT_NAME_MAC_ENCODING_GUJARATI,
|
||||
TT_NAME_MAC_ENCODING_ORIYA,
|
||||
TT_NAME_MAC_ENCODING_BENGALI,
|
||||
TT_NAME_MAC_ENCODING_TAMIL,
|
||||
TT_NAME_MAC_ENCODING_TELUGU,
|
||||
TT_NAME_MAC_ENCODING_KANNADA,
|
||||
TT_NAME_MAC_ENCODING_MALAYALAM,
|
||||
TT_NAME_MAC_ENCODING_SINHALESE,
|
||||
TT_NAME_MAC_ENCODING_BURMESE,
|
||||
TT_NAME_MAC_ENCODING_KHMER,
|
||||
TT_NAME_MAC_ENCODING_THAI,
|
||||
TT_NAME_MAC_ENCODING_LAOTIAN,
|
||||
TT_NAME_MAC_ENCODING_GEORGIAN,
|
||||
TT_NAME_MAC_ENCODING_ARMENIAN,
|
||||
TT_NAME_MAC_ENCODING_SIMPL_CHINESE,
|
||||
TT_NAME_MAC_ENCODING_TIBETAN,
|
||||
TT_NAME_MAC_ENCODING_MONGOLIAN,
|
||||
TT_NAME_MAC_ENCODING_GEEZ,
|
||||
TT_NAME_MAC_ENCODING_SLAVIC,
|
||||
TT_NAME_MAC_ENCODING_VIETNAMESE,
|
||||
TT_NAME_MAC_ENCODING_SINDHI,
|
||||
TT_NAME_MAC_ENCODING_UNINTERPRETED
|
||||
};
|
||||
|
||||
enum OPENTYPE_NAME_ID
|
||||
{
|
||||
OPENTYPE_NAME_COPYRIGHT_NOTICE = 0,
|
||||
OPENTYPE_NAME_FAMILY,
|
||||
OPENTYPE_NAME_SUBFAMILY,
|
||||
OPENTYPE_NAME_UNIQUE_IDENTIFIER,
|
||||
OPENTYPE_NAME_FULLNAME,
|
||||
OPENTYPE_NAME_VERSION_STRING,
|
||||
OPENTYPE_NAME_POSTSCRIPT,
|
||||
OPENTYPE_NAME_TRADEMARK,
|
||||
OPENTYPE_NAME_MANUFACTURER,
|
||||
OPENTYPE_NAME_DESIGNER,
|
||||
OPENTYPE_NAME_DESCRIPTION,
|
||||
OPENTYPE_NAME_VENDOR_URL,
|
||||
OPENTYPE_NAME_DESIGNER_URL,
|
||||
OPENTYPE_NAME_LICENSE_DESCRIPTION,
|
||||
OPENTYPE_NAME_LICENSE_INFO_URL,
|
||||
OPENTYPE_NAME_RESERVED_ID15,
|
||||
OPENTYPE_NAME_TYPOGRAPHIC_FAMILY,
|
||||
OPENTYPE_NAME_TYPOGRAPHIC_SUBFAMILY,
|
||||
OPENTYPE_NAME_COMPATIBLE_FULLNAME,
|
||||
OPENTYPE_NAME_SAMPLE_TEXT,
|
||||
OPENTYPE_NAME_POSTSCRIPT_CID,
|
||||
OPENTYPE_NAME_WWS_FAMILY,
|
||||
OPENTYPE_NAME_WWS_SUBFAMILY
|
||||
};
|
||||
|
||||
static BOOL opentype_get_table_ptr( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
|
||||
UINT32 table_tag, const void **table_ptr, UINT32 *table_size )
|
||||
{
|
||||
|
@ -151,6 +270,306 @@ static BOOL opentype_get_tt_os2_v1( const void *data, size_t size, const struct
|
|||
return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_OS_2_TAG, (const void **)tt_os2_v1, &table_size );
|
||||
}
|
||||
|
||||
static UINT get_name_record_codepage( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding )
|
||||
{
|
||||
switch (platform)
|
||||
{
|
||||
case OPENTYPE_PLATFORM_UNICODE:
|
||||
return 0;
|
||||
case OPENTYPE_PLATFORM_MAC:
|
||||
switch (encoding)
|
||||
{
|
||||
case TT_NAME_MAC_ENCODING_ROMAN:
|
||||
return 10000;
|
||||
case TT_NAME_MAC_ENCODING_JAPANESE:
|
||||
return 10001;
|
||||
case TT_NAME_MAC_ENCODING_TRAD_CHINESE:
|
||||
return 10002;
|
||||
case TT_NAME_MAC_ENCODING_KOREAN:
|
||||
return 10003;
|
||||
case TT_NAME_MAC_ENCODING_ARABIC:
|
||||
return 10004;
|
||||
case TT_NAME_MAC_ENCODING_HEBREW:
|
||||
return 10005;
|
||||
case TT_NAME_MAC_ENCODING_GREEK:
|
||||
return 10006;
|
||||
case TT_NAME_MAC_ENCODING_RUSSIAN:
|
||||
return 10007;
|
||||
case TT_NAME_MAC_ENCODING_SIMPL_CHINESE:
|
||||
return 10008;
|
||||
case TT_NAME_MAC_ENCODING_THAI:
|
||||
return 10021;
|
||||
default:
|
||||
FIXME( "encoding %u not handled, platform %d.\n", encoding, platform );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OPENTYPE_PLATFORM_WIN:
|
||||
switch (encoding)
|
||||
{
|
||||
case TT_NAME_WIN_ENCODING_SYMBOL:
|
||||
case TT_NAME_WIN_ENCODING_UNICODE_BMP:
|
||||
case TT_NAME_WIN_ENCODING_UNICODE_FULL:
|
||||
return 0;
|
||||
case TT_NAME_WIN_ENCODING_SJIS:
|
||||
return 932;
|
||||
case TT_NAME_WIN_ENCODING_PRC:
|
||||
return 936;
|
||||
case TT_NAME_WIN_ENCODING_BIG5:
|
||||
return 950;
|
||||
case TT_NAME_WIN_ENCODING_WANSUNG:
|
||||
return 20949;
|
||||
case TT_NAME_WIN_ENCODING_JOHAB:
|
||||
return 1361;
|
||||
default:
|
||||
FIXME( "encoding %u not handled, platform %d.\n", encoding, platform );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME( "unknown platform %d\n", platform );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const LANGID mac_langid_table[] =
|
||||
{
|
||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ITALIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_DUTCH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SPANISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_PORTUGUESE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_NORWEGIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_FINNISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ICELANDIC, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MALTESE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_URDU, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_HINDI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_THAI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_LITHUANIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ESTONIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_LATVIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SAMI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_FAEROESE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_FARSI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH_BELGIAN),
|
||||
MAKELANGID(LANG_IRISH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ALBANIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ROMANIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SLOVENIAN, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_SERBIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MACEDONIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_BULGARIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_UKRAINIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_BELARUSIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_UZBEK, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_KAZAK, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_AZERI, SUBLANG_AZERI_CYRILLIC),
|
||||
0,
|
||||
MAKELANGID(LANG_ARMENIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_GEORGIAN, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_KYRGYZ, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TAJIK, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TURKMEN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MONGOLIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MONGOLIAN, SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA),
|
||||
MAKELANGID(LANG_PASHTO, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_KASHMIRI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SINDHI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TIBETAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_NEPALI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SANSKRIT, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MARATHI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_BENGALI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ASSAMESE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_GUJARATI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_PUNJABI, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ORIYA, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MALAYALAM, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_KANNADA, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TAMIL, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TELUGU, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SINHALESE, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_KHMER, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_LAO, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_VIETNAMESE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_INDONESIAN, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_MALAY, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_AMHARIC, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_TIGRIGNA, SUBLANG_DEFAULT),
|
||||
0,
|
||||
0,
|
||||
MAKELANGID(LANG_SWAHILI, SUBLANG_DEFAULT),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
MAKELANGID(LANG_MALAGASY, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_ESPERANTO, SUBLANG_DEFAULT),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
MAKELANGID(LANG_WELSH, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_BASQUE, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_CATALAN, SUBLANG_DEFAULT),
|
||||
0,
|
||||
MAKELANGID(LANG_QUECHUA, SUBLANG_DEFAULT),
|
||||
0,
|
||||
0,
|
||||
MAKELANGID(LANG_TATAR, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_UIGHUR, SUBLANG_DEFAULT),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
MAKELANGID(LANG_GALICIAN, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_AFRIKAANS, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_BRETON, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_INUKTITUT, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_SCOTTISH_GAELIC, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_MANX_GAELIC, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_IRISH, SUBLANG_IRISH_IRELAND),
|
||||
0,
|
||||
0,
|
||||
MAKELANGID(LANG_GREENLANDIC, SUBLANG_DEFAULT),
|
||||
MAKELANGID(LANG_AZERI, SUBLANG_AZERI_LATIN),
|
||||
};
|
||||
|
||||
static LANGID get_name_record_langid( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding, USHORT language )
|
||||
{
|
||||
switch (platform)
|
||||
{
|
||||
case OPENTYPE_PLATFORM_WIN:
|
||||
return language;
|
||||
case OPENTYPE_PLATFORM_MAC:
|
||||
if (language < ARRAY_SIZE(mac_langid_table)) return mac_langid_table[language];
|
||||
WARN( "invalid mac lang id %d\n", language );
|
||||
break;
|
||||
case OPENTYPE_PLATFORM_UNICODE:
|
||||
switch (encoding)
|
||||
{
|
||||
case TT_NAME_UNICODE_ENCODING_1_0:
|
||||
case TT_NAME_UNICODE_ENCODING_ISO_10646:
|
||||
case TT_NAME_UNICODE_ENCODING_2_0_BMP:
|
||||
if (language < ARRAY_SIZE(mac_langid_table)) return mac_langid_table[language];
|
||||
WARN( "invalid unicode lang id %d\n", language );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME( "unknown platform %d\n", platform );
|
||||
break;
|
||||
}
|
||||
|
||||
return MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
|
||||
}
|
||||
|
||||
static BOOL opentype_enum_font_names( const struct tt_name_v0 *header, enum OPENTYPE_PLATFORM_ID platform,
|
||||
enum OPENTYPE_NAME_ID name, opentype_enum_names_cb callback, void *user )
|
||||
{
|
||||
const char *name_data;
|
||||
USHORT i, name_count, encoding, language, length, offset;
|
||||
USHORT platform_id = GET_BE_WORD( platform ), name_id = GET_BE_WORD( name );
|
||||
LANGID langid;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
switch (GET_BE_WORD( header->format ))
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
FIXME( "unsupported name format %d\n", GET_BE_WORD( header->format ) );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
name_data = (const char *)header + GET_BE_WORD( header->stringOffset );
|
||||
name_count = GET_BE_WORD( header->count );
|
||||
for (i = 0; i < name_count; i++)
|
||||
{
|
||||
const struct tt_namerecord *record = &header->nameRecord[i];
|
||||
struct opentype_name opentype_name;
|
||||
|
||||
if (record->nameID != name_id) continue;
|
||||
if (record->platformID != platform_id) continue;
|
||||
|
||||
language = GET_BE_WORD( record->languageID );
|
||||
if (language >= 0x8000)
|
||||
{
|
||||
FIXME( "handle name format 1\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
encoding = GET_BE_WORD( record->encodingID );
|
||||
offset = GET_BE_WORD( record->offset );
|
||||
length = GET_BE_WORD( record->length );
|
||||
langid = get_name_record_langid( platform, encoding, language );
|
||||
|
||||
opentype_name.codepage = get_name_record_codepage( platform, encoding );
|
||||
opentype_name.length = length;
|
||||
opentype_name.bytes = name_data + offset;
|
||||
|
||||
if ((ret = callback( langid, &opentype_name, user ))) break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD *count, const struct ttc_sfnt_v1 **ttc_sfnt_v1 )
|
||||
{
|
||||
const struct ttc_header_v1 *ttc_header_v1 = data;
|
||||
|
@ -218,3 +637,43 @@ BOOL opentype_get_ttc_sfnt_v1( const void *data, size_t size, DWORD index, DWORD
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL opentype_get_tt_name_v0( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1,
|
||||
const struct tt_name_v0 **tt_name_v0 )
|
||||
{
|
||||
UINT32 table_size = sizeof(**tt_name_v0);
|
||||
return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_NAME_TAG, (const void **)tt_name_v0, &table_size );
|
||||
}
|
||||
|
||||
BOOL opentype_enum_family_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
|
||||
{
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_FAMILY, callback, user ))
|
||||
return TRUE;
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_FAMILY, callback, user ))
|
||||
return TRUE;
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_FAMILY, callback, user ))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL opentype_enum_style_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
|
||||
{
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_SUBFAMILY, callback, user ))
|
||||
return TRUE;
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_SUBFAMILY, callback, user ))
|
||||
return TRUE;
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_SUBFAMILY, callback, user ))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_names_cb callback, void *user )
|
||||
{
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_WIN, OPENTYPE_NAME_FULLNAME, callback, user ))
|
||||
return TRUE;
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_MAC, OPENTYPE_NAME_FULLNAME, callback, user ))
|
||||
return TRUE;
|
||||
if (opentype_enum_font_names( header, OPENTYPE_PLATFORM_UNICODE, OPENTYPE_NAME_FULLNAME, callback, user ))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue