From d3cc0811ce99efa1e01a21fee464203c8e2b9459 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Thu, 30 Aug 2018 21:34:03 +0900 Subject: [PATCH] [0.4.10] [WIN32SS][FONT] Fix GetTextFace function and related (#829) CORE-14926 Google Chrome with -no-sandbox parameter in ReactOS wouldn't display the web page anymore because first-chance exception raised. - Remove FullName, Style, and FaceName members from TEXTOBJ structure. - Add TextFace member into TEXTOBJ structure. - Add MatchFontName() and MatchFontNames() helper functions. - Fix GetTextFace() and related. The symptom started showing with 0.4.10-dev-466-g 35f62fc5ba0b69e7335ff41400cb3b45660f4557 The fix was cherry-picked from commit 0.4.11-dev-48-g c8749d379beeb3a078c296feca1f4cdb3e9d11f1 Many Thx to Katayama, Mark & Doug. --- win32ss/gdi/ntgdi/freetype.c | 75 +++++++++++++++++++++++++++++++----- win32ss/gdi/ntgdi/text.c | 4 +- win32ss/gdi/ntgdi/text.h | 4 +- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 5275b365761..e172c5c5376 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -4667,6 +4667,53 @@ IntFontType(PFONTGDI Font) } } +static BOOL +MatchFontName(PSHARED_FACE SharedFace, LPCWSTR lfFaceName, FT_UShort NameID, FT_UShort LangID) +{ + NTSTATUS Status; + UNICODE_STRING Name1, Name2; + + if (lfFaceName[0] == UNICODE_NULL) + return FALSE; + + RtlInitUnicodeString(&Name1, lfFaceName); + + RtlInitUnicodeString(&Name2, NULL); + Status = IntGetFontLocalizedName(&Name2, SharedFace, NameID, LangID); + + if (NT_SUCCESS(Status)) + { + if (RtlCompareUnicodeString(&Name1, &Name2, TRUE) == 0) + { + RtlFreeUnicodeString(&Name2); + return TRUE; + } + + RtlFreeUnicodeString(&Name2); + } + + return FALSE; +} + +static BOOL +MatchFontNames(PSHARED_FACE SharedFace, LPCWSTR lfFaceName) +{ + if (MatchFontName(SharedFace, lfFaceName, TT_NAME_ID_FONT_FAMILY, LANG_ENGLISH) || + MatchFontName(SharedFace, lfFaceName, TT_NAME_ID_FULL_NAME, LANG_ENGLISH)) + { + return TRUE; + } + if (PRIMARYLANGID(gusLanguageID) != LANG_ENGLISH) + { + if (MatchFontName(SharedFace, lfFaceName, TT_NAME_ID_FONT_FAMILY, gusLanguageID) || + MatchFontName(SharedFace, lfFaceName, TT_NAME_ID_FULL_NAME, gusLanguageID)) + { + return TRUE; + } + } + return FALSE; +} + NTSTATUS FASTCALL TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj) @@ -4731,22 +4778,32 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj) } else { - UNICODE_STRING FaceName; + UNICODE_STRING Name; PFONTGDI FontGdi = ObjToGDI(TextObj->Font, FONT); + PSHARED_FACE SharedFace = FontGdi->SharedFace; IntLockFreeType(); IntRequestFontSize(NULL, FontGdi, pLogFont->lfWidth, pLogFont->lfHeight); IntUnLockFreeType(); - RtlInitUnicodeString(&FaceName, NULL); - IntGetFontLocalizedName(&FaceName, FontGdi->SharedFace, TT_NAME_ID_FONT_FAMILY, gusLanguageID); - - /* truncated copy */ - FaceName.Length = (USHORT)min(FaceName.Length, (LF_FACESIZE - 1) * sizeof(WCHAR)); - FaceName.MaximumLength = (USHORT)(FaceName.Length + sizeof(UNICODE_NULL)); - RtlCopyMemory(TextObj->FaceName, FaceName.Buffer, FaceName.MaximumLength); + TextObj->TextFace[0] = UNICODE_NULL; + if (MatchFontNames(SharedFace, SubstitutedLogFont.lfFaceName)) + { + RtlStringCchCopyW(TextObj->TextFace, _countof(TextObj->TextFace), pLogFont->lfFaceName); + } + else + { + RtlInitUnicodeString(&Name, NULL); + Status = IntGetFontLocalizedName(&Name, SharedFace, TT_NAME_ID_FONT_FAMILY, gusLanguageID); + if (NT_SUCCESS(Status)) + { + /* truncated copy */ + Name.Length = (USHORT)min(Name.Length, (LF_FACESIZE - 1) * sizeof(WCHAR)); + RtlStringCbCopyNW(TextObj->TextFace, Name.Length + sizeof(WCHAR), Name.Buffer, Name.Length); - RtlFreeUnicodeString(&FaceName); + RtlFreeUnicodeString(&Name); + } + } // Need hdev, when freetype is loaded need to create DEVOBJ for // Consumer and Producer. diff --git a/win32ss/gdi/ntgdi/text.c b/win32ss/gdi/ntgdi/text.c index ec0503fa465..2ea694103ae 100644 --- a/win32ss/gdi/ntgdi/text.c +++ b/win32ss/gdi/ntgdi/text.c @@ -513,12 +513,12 @@ NtGdiGetTextFaceW( TextObj = RealizeFontInit(hFont); ASSERT(TextObj != NULL); - fLen = wcslen(TextObj->FaceName) + 1; + fLen = wcslen(TextObj->TextFace) + 1; if (FaceName != NULL) { Count = min(Count, fLen); - Status = MmCopyToCaller(FaceName, TextObj->FaceName, Count * sizeof(WCHAR)); + Status = MmCopyToCaller(FaceName, TextObj->TextFace, Count * sizeof(WCHAR)); if (!NT_SUCCESS(Status)) { TEXTOBJ_UnlockText(TextObj); diff --git a/win32ss/gdi/ntgdi/text.h b/win32ss/gdi/ntgdi/text.h index cd8b5b22f07..830ceb11009 100644 --- a/win32ss/gdi/ntgdi/text.h +++ b/win32ss/gdi/ntgdi/text.h @@ -64,9 +64,7 @@ typedef struct _LFONT LFTYPE lft; FLONG fl; FONTOBJ *Font; - WCHAR FullName[LF_FULLFACESIZE]; - WCHAR Style[LF_FACESIZE]; - WCHAR FaceName[LF_FACESIZE]; + WCHAR TextFace[LF_FACESIZE]; DWORD dwOffsetEndArray; // Fixed: ENUMLOGFONTEXDVW logfont;