From 3ea171dee542027a4497a17920c69315994526eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Tue, 1 Dec 2020 15:54:50 +0100 Subject: [PATCH] gdi32: Try to parse font props without FreeType. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/freetype.c | 7 ++-- dlls/gdi32/gdi_private.h | 3 ++ dlls/gdi32/opentype.c | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 4 deletions(-) diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 521bf054e43..364d58b4450 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1224,7 +1224,9 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr This = NULL; } 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 )) + opentype_get_tt_name_v0( data_ptr, data_size, ttc_sfnt_v1, &tt_name_v0 ) && + opentype_get_properties( data_ptr, data_size, ttc_sfnt_v1, &This->font_version, + &This->fs, &This->ntm_flags )) { struct family_names_data family_names; struct face_name_data style_name; @@ -1291,10 +1293,7 @@ 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 ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 9a988d08d7e..8d917a795c0 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -439,6 +439,9 @@ extern BOOL opentype_enum_style_names( const struct tt_name_v0 *tt_name_v0, extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0, opentype_enum_names_cb callback, void *user ) DECLSPEC_HIDDEN; +extern BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1, + DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ) DECLSPEC_HIDDEN; + /* gdiobj.c */ extern HGDIOBJ alloc_gdi_handle( void *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN; extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/opentype.c b/dlls/gdi32/opentype.c index 4200b08d318..67af44dfe91 100644 --- a/dlls/gdi32/opentype.c +++ b/dlls/gdi32/opentype.c @@ -42,6 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(font); #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') +#define MS_CFF__TAG MS_MAKE_TAG('C','F','F',' ') #ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) @@ -135,6 +136,28 @@ struct tt_name_v0 WORD stringOffset; struct tt_namerecord nameRecord[1]; }; + +struct tt_head +{ + USHORT majorVersion; + USHORT minorVersion; + ULONG revision; + ULONG checksumadj; + ULONG magic; + USHORT flags; + USHORT unitsPerEm; + ULONGLONG created; + ULONGLONG modified; + SHORT xMin; + SHORT yMin; + SHORT xMax; + SHORT yMax; + USHORT macStyle; + USHORT lowestRecPPEM; + SHORT direction_hint; + SHORT index_format; + SHORT glyphdata_format; +}; #include "poppack.h" enum OPENTYPE_PLATFORM_ID @@ -236,6 +259,20 @@ enum OPENTYPE_NAME_ID OPENTYPE_NAME_WWS_SUBFAMILY }; +enum OS2_FSSELECTION +{ + OS2_FSSELECTION_ITALIC = 1 << 0, + OS2_FSSELECTION_UNDERSCORE = 1 << 1, + OS2_FSSELECTION_NEGATIVE = 1 << 2, + OS2_FSSELECTION_OUTLINED = 1 << 3, + OS2_FSSELECTION_STRIKEOUT = 1 << 4, + OS2_FSSELECTION_BOLD = 1 << 5, + OS2_FSSELECTION_REGULAR = 1 << 6, + OS2_FSSELECTION_USE_TYPO_METRICS = 1 << 7, + OS2_FSSELECTION_WWS = 1 << 8, + OS2_FSSELECTION_OBLIQUE = 1 << 9 +}; + 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 ) { @@ -270,6 +307,13 @@ 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 BOOL opentype_get_tt_head( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1, + const struct tt_head **tt_head ) +{ + UINT32 table_size = sizeof(**tt_head); + return opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_HEAD_TAG, (const void **)tt_head, &table_size ); +} + static UINT get_name_record_codepage( enum OPENTYPE_PLATFORM_ID platform, USHORT encoding ) { switch (platform) @@ -677,3 +721,50 @@ BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_na return TRUE; return FALSE; } + +BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sfnt_v1 *ttc_sfnt_v1, + DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags ) +{ + const struct tt_os2_v1 *tt_os2_v1; + const struct tt_head *tt_head; + const void *cff_header; + UINT32 table_size = 0; + USHORT idx, selection; + DWORD flags = 0; + + if (!opentype_get_tt_head( data, size, ttc_sfnt_v1, &tt_head )) return FALSE; + if (!opentype_get_tt_os2_v1( data, size, ttc_sfnt_v1, &tt_os2_v1 )) return FALSE; + + *version = GET_BE_DWORD( tt_head->revision ); + + fs->fsUsb[0] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange1 ); + fs->fsUsb[1] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange2 ); + fs->fsUsb[2] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange3 ); + fs->fsUsb[3] = GET_BE_DWORD( tt_os2_v1->ulUnicodeRange4 ); + + if (tt_os2_v1->version == 0) + { + idx = GET_BE_WORD( tt_os2_v1->usFirstCharIndex ); + if (idx >= 0xf000 && idx < 0xf100) fs->fsCsb[0] = FS_SYMBOL; + else fs->fsCsb[0] = FS_LATIN1; + fs->fsCsb[1] = 0; + } + else + { + fs->fsCsb[0] = GET_BE_DWORD( tt_os2_v1->ulCodePageRange1 ); + fs->fsCsb[1] = GET_BE_DWORD( tt_os2_v1->ulCodePageRange2 ); + } + + selection = GET_BE_WORD( tt_os2_v1->fsSelection ); + + if (selection & OS2_FSSELECTION_ITALIC) flags |= NTM_ITALIC; + if (selection & OS2_FSSELECTION_BOLD) flags |= NTM_BOLD; + if (selection & OS2_FSSELECTION_REGULAR) flags |= NTM_REGULAR; + if (flags == 0) flags = NTM_REGULAR; + + if (opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_CFF__TAG, &cff_header, &table_size )) + flags |= NTM_PS_OPENTYPE; + + *ntm_flags = flags; + return TRUE; +}