[PATCH 5/6] gdi32: Try to parse font props without FreeType.

Rémi Bernon rbernon at codeweavers.com
Tue Dec 1 08:54:50 CST 2020


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

This makes a tiny difference to the dump_gdi_font_list report, for some
fonts that do not have any bit set in fs->fsCsb[0]. This is the case for
instance for Noto Arabic font family. We were previously filling it with
FS_LATIN1 as fallback because FreeType reported some charmap encoded with
FT_ENCODING_APPLE_ROMAN, but I don't think it was correct.

 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 06bc29ff86a..f9d82644176 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;
+}
-- 
2.29.2




More information about the wine-devel mailing list