From: Paul Gofman pgofman@codeweavers.com
--- dlls/gdi32/tests/font.c | 2 +- dlls/win32u/font.c | 18 +++++++++++------- dlls/win32u/freetype.c | 12 +++++++++--- dlls/win32u/ntgdi_private.h | 4 ++-- dlls/win32u/opentype.c | 3 ++- 5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 1212e88fdfa..06d3b042deb 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -7827,7 +7827,7 @@ static void test_font_weight(void) SelectObject(hdc, hfont2); memset(&tm2, 0, sizeof(tm2)); GetTextMetricsW(hdc, &tm2); - todo_wine ok(tm1.tmMaxCharWidth == tm2.tmMaxCharWidth, "got %ld, %ld.\n", tm1.tmMaxCharWidth, tm2.tmMaxCharWidth); + ok(tm1.tmMaxCharWidth == tm2.tmMaxCharWidth, "got %ld, %ld.\n", tm1.tmMaxCharWidth, tm2.tmMaxCharWidth);
SelectObject(hdc, old); ReleaseDC(NULL, hdc); diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 8fb3128f5e0..c8ab5e4f625 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -85,6 +85,7 @@ struct gdi_font_face UINT face_index; FONTSIGNATURE fs; UINT ntmFlags; + UINT weight; UINT version; UINT flags; /* ADDFONT flags */ BOOL scalable; @@ -1165,7 +1166,7 @@ static BOOL insert_face_in_family_list( struct gdi_font_face *face, struct gdi_f static struct gdi_font_face *create_face( struct gdi_font_family *family, const WCHAR *style, const WCHAR *fullname, const WCHAR *file, void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs, - DWORD ntmflags, DWORD version, DWORD flags, + DWORD ntmflags, DWORD weight, DWORD version, DWORD flags, const struct bitmap_font_size *size ) { struct gdi_font_face *face = calloc( 1, sizeof(*face) ); @@ -1176,6 +1177,7 @@ static struct gdi_font_face *create_face( struct gdi_font_family *family, const face->face_index = index; face->fs = fs; face->ntmFlags = ntmflags; + face->weight = weight; face->version = version; face->flags = flags; face->data_ptr = data_ptr; @@ -1191,7 +1193,7 @@ static struct gdi_font_face *create_face( struct gdi_font_family *family, const int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, const WCHAR *style, const WCHAR *fullname, const WCHAR *file, void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs, - DWORD ntmflags, DWORD version, DWORD flags, + DWORD ntmflags, DWORD weight, DWORD version, DWORD flags, const struct bitmap_font_size *size ) { struct gdi_font_face *face; @@ -1202,7 +1204,7 @@ int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, else if (!(family = create_family( family_name, second_name ))) return ret;
if ((face = create_face( family, style, fullname, file, data_ptr, data_size, - index, fs, ntmflags, version, flags, size ))) + index, fs, ntmflags, weight, version, flags, size ))) { if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face ); release_face( face ); @@ -1235,7 +1237,7 @@ int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, else if (!(family = create_family( vert_family, vert_second ))) return ret;
if ((face = create_face( family, style, fullname, file, data_ptr, data_size, - index, fs, ntmflags, version, flags | ADDFONT_VERTICAL_FONT, size ))) + index, fs, ntmflags, weight, version, flags | ADDFONT_VERTICAL_FONT, size ))) { if (flags & ADDFONT_ADD_TO_CACHE) add_face_to_cache( face ); release_face( face ); @@ -1253,6 +1255,7 @@ struct cached_face DWORD index; DWORD flags; DWORD ntmflags; + DWORD weight; DWORD version; struct bitmap_font_size size; FONTSIGNATURE fs; @@ -1280,8 +1283,8 @@ static void load_face_from_cache( HKEY hkey_family, struct gdi_font_family *fami ((DWORD *)cached)[info->DataLength / sizeof(DWORD)] = 0; if ((face = create_face( family, name, cached->full_name, cached->full_name + lstrlenW(cached->full_name) + 1, - NULL, 0, cached->index, cached->fs, cached->ntmflags, cached->version, - cached->flags, scalable ? NULL : &cached->size ))) + NULL, 0, cached->index, cached->fs, cached->ntmflags, cached->weight, + cached->version, cached->flags, scalable ? NULL : &cached->size ))) { if (!scalable) TRACE("Adding bitmap size h %d w %d size %d x_ppem %d y_ppem %d\n", @@ -1372,6 +1375,7 @@ static void add_face_to_cache( struct gdi_font_face *face ) cached->index = face->face_index; cached->flags = face->flags; cached->ntmflags = face->ntmFlags; + cached->weight = face->weight; cached->version = face->version; cached->fs = face->fs; if (!face->scalable) cached->size = face->size; @@ -2444,7 +2448,7 @@ static struct gdi_font *create_gdi_font( const struct gdi_font_face *face, const font->fs = face->fs; font->lf = *lf; font->fake_italic = (lf->lfItalic && !(face->ntmFlags & NTM_ITALIC)); - font->fake_bold = (lf->lfWeight > 550 && !(face->ntmFlags & NTM_BOLD)); + font->fake_bold = lf->lfWeight > 550 && !(face->ntmFlags & NTM_BOLD) && face->weight < 550; font->scalable = face->scalable; font->face_index = face->face_index; font->ntmFlags = face->ntmFlags; diff --git a/dlls/win32u/freetype.c b/dlls/win32u/freetype.c index 2c4d2c446df..1c82fc9b602 100644 --- a/dlls/win32u/freetype.c +++ b/dlls/win32u/freetype.c @@ -1163,6 +1163,7 @@ struct unix_face WCHAR *style_name; WCHAR *full_name; DWORD ntm_flags; + UINT weight; DWORD font_version; FONTSIGNATURE fs; struct bitmap_font_size size; @@ -1202,7 +1203,7 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr 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_properties( data_ptr, data_size, ttc_sfnt_v1, &This->font_version, - &This->fs, &This->ntm_flags )) + &This->fs, &This->ntm_flags, &This->weight )) { struct family_names_data family_names; struct face_name_data style_name; @@ -1246,6 +1247,8 @@ static struct unix_face *unix_face_create( const char *unix_name, void *data_ptr } else if ((This->ft_face = new_ft_face( unix_name, data_ptr, data_size, face_index, flags & ADDFONT_ALLOW_BITMAP ))) { + TT_OS2 *os2; + 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; @@ -1267,8 +1270,11 @@ 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 ); - This->ntm_flags = get_ntm_flags( This->ft_face ); + if ((os2 = pFT_Get_Sfnt_Table(This->ft_face, ft_sfnt_os2))) + This->weight = os2->usWeightClass; + else + This->weight = This->ntm_flags & NTM_BOLD ? FW_BOLD : FW_NORMAL; This->font_version = get_font_version( This->ft_face ); if (!This->scalable) get_bitmap_size( This->ft_face, &This->size ); get_fontsig( This->ft_face, &This->fs ); @@ -1315,7 +1321,7 @@ static int add_unix_face( const char *unix_name, const WCHAR *file, void *data_p if (!HIWORD( flags )) flags |= ADDFONT_AA_FLAGS( default_aa_flags );
ret = add_gdi_face( unix_face->family_name, unix_face->second_name, unix_face->style_name, unix_face->full_name, - file, data_ptr, data_size, face_index, unix_face->fs, unix_face->ntm_flags, + file, data_ptr, data_size, face_index, unix_face->fs, unix_face->ntm_flags, unix_face->weight, unix_face->font_version, flags, unix_face->scalable ? NULL : &unix_face->size );
TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n", diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 5c4f8279c87..5e260d8713d 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -339,7 +339,7 @@ struct font_backend_funcs extern int add_gdi_face( const WCHAR *family_name, const WCHAR *second_name, const WCHAR *style, const WCHAR *fullname, const WCHAR *file, void *data_ptr, SIZE_T data_size, UINT index, FONTSIGNATURE fs, - DWORD ntmflags, DWORD version, DWORD flags, + DWORD ntmflags, DWORD weight, DWORD version, DWORD flags, const struct bitmap_font_size *size ); extern UINT font_init(void); extern const struct font_backend_funcs *init_freetype_lib(void); @@ -370,7 +370,7 @@ extern BOOL opentype_enum_full_names( const struct tt_name_v0 *tt_name_v0, opentype_enum_names_cb callback, void *user );
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 ); + DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags, UINT *weight );
/* gdiobj.c */ extern HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, diff --git a/dlls/win32u/opentype.c b/dlls/win32u/opentype.c index 7a541ae4e4a..97c8b9dbbce 100644 --- a/dlls/win32u/opentype.c +++ b/dlls/win32u/opentype.c @@ -724,7 +724,7 @@ BOOL opentype_enum_full_names( const struct tt_name_v0 *header, opentype_enum_na }
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 ) + DWORD *version, FONTSIGNATURE *fs, DWORD *ntm_flags, UINT *weight ) { const struct tt_os2_v1 *tt_os2_v1; const struct tt_head *tt_head; @@ -762,6 +762,7 @@ BOOL opentype_get_properties( const void *data, size_t size, const struct ttc_sf if (selection & OS2_FSSELECTION_BOLD) flags |= NTM_BOLD; if (selection & OS2_FSSELECTION_REGULAR) flags |= NTM_REGULAR; if (flags == 0) flags = NTM_REGULAR; + *weight = GET_BE_WORD( tt_os2_v1->usWeightClass );
if (opentype_get_table_ptr( data, size, ttc_sfnt_v1, MS_CFF__TAG, &cff_header, &table_size )) flags |= NTM_PS_OPENTYPE;