From: Haoyang Chen chenhaoyang@kylinos.cn
--- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/font.c | 127 +++++++++++++++++++++++++++ dlls/gdi32/tests/resource.rc | 3 + dlls/gdi32/tests/wine_secondname.sfd | 76 ++++++++++++++++ dlls/gdi32/tests/wine_secondname.ttf | Bin 0 -> 3952 bytes 5 files changed, 207 insertions(+) create mode 100644 dlls/gdi32/tests/wine_secondname.sfd create mode 100644 dlls/gdi32/tests/wine_secondname.ttf
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index d6f33ee087d..482e12928cd 100644 --- a/dlls/gdi32/tests/Makefile.in +++ b/dlls/gdi32/tests/Makefile.in @@ -24,6 +24,7 @@ SOURCES = \ wine_langnames3.sfd \ wine_longname.sfd \ wine_nul.sfd \ + wine_secondname.sfd \ wine_test.sfd \ wine_ttfnames.sfd \ wine_ttfnames_bold.sfd \ diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 0513c2b2ca8..c39e3a2998d 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -28,6 +28,8 @@ #include "wingdi.h" #include "winuser.h" #include "winnls.h" +#include "winternl.h" +#include "winreg.h"
#include "wine/test.h"
@@ -51,6 +53,17 @@ static HMODULE hgdi32 = 0; static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} }; static WORD system_lang_id;
+static const WCHAR font_substitutes_keyW[] = +{ + '\','R','e','g','i','s','t','r','y', + '\','M','a','c','h','i','n','e', + '\','S','o','f','t','w','a','r','e', + '\','M','i','c','r','o','s','o','f','t', + '\','W','i','n','d','o','w','s',' ','N','T', + '\','C','u','r','r','e','n','t','V','e','r','s','i','o','n', + '\','F','o','n','t','S','u','b','s','t','i','t','u','t','e','s' +}; + #ifdef WORDS_BIGENDIAN #define GET_BE_WORD(x) (x) #define GET_BE_DWORD(x) (x) @@ -7767,11 +7780,115 @@ static void test_GetOutlineTextMetrics_subst(void) ReleaseDC(0, hdc); }
+static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len ) +{ + UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name }; + OBJECT_ATTRIBUTES attr; + HANDLE ret; + + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + if (NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 )) return 0; + return ret; +} + +static inline UINT asciiz_to_unicode( WCHAR *dst, const char *src ) +{ + WCHAR *p = dst; + while ((*p++ = *src++)); + return (p - dst) * sizeof(WCHAR); +} + +static BOOL set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void *value, DWORD count ) +{ + unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0; + UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name }; + return !NtSetValueKey( hkey, &nameW, 0, type, value, count ); +} + +static void set_reg_ascii_value( HKEY hkey, const char *name, const char *value ) +{ + WCHAR nameW[64], valueW[128]; + asciiz_to_unicode( nameW, name ); + set_reg_value( hkey, nameW, REG_SZ, valueW, asciiz_to_unicode( valueW, value )); +} + +static void reg_delete_value( HKEY hkey, const WCHAR *name ) +{ + unsigned int name_size = lstrlenW( name ) * sizeof(WCHAR); + UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name }; + + NtDeleteValueKey( hkey, &nameW ); +} + +static void test_second_name(void) +{ + char ttf_name[MAX_PATH]; + LOGFONTA font = {0}; + BOOL found_font; + int ret; + HDC dc; + HKEY hkey; + BOOL is_wine = !strcmp(winetest_platform, "wine"); + + if (!write_ttf_file("wine_secondname.ttf", ttf_name)) + { + skip("Failed to create ttf file for testing\n"); + return; + } + + if (is_wine) + { + hkey = reg_open_key(NULL, font_substitutes_keyW, sizeof(font_substitutes_keyW)); + ok(!!hkey, "open register key for FontSubstitutes failed.\n"); + } + + dc = GetDC(NULL); + + ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "AddFontResourceEx() failed\n"); + + strcpy(font.lfFaceName, "wine_this_is_first_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find wine_this_is_first_name font.\n"); + + strcpy(font.lfFaceName, "wine_this_is_second_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find wine_this_is_second_name font.\n"); + + if (is_wine) + { + strcpy(font.lfFaceName, "wine_this_is_second_name_subst"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find wine_this_is_second_name font.\n"); + } + + ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "RemoveFontResourceEx() failed\n"); + + DeleteFileA(ttf_name); + ReleaseDC(NULL, dc); + if (is_wine) + { + reg_delete_value( hkey, L"wine_this_is_second_name_subst"); + NtClose( hkey ); + } +} + START_TEST(font) { static const char *test_names[] = { "AddFontMemResource", + "test_second_name", }; char path_name[MAX_PATH]; STARTUPINFOA startup; @@ -7785,6 +7902,8 @@ START_TEST(font) { if (!strcmp(argv[2], "AddFontMemResource")) test_AddFontMemResource(); + if (!strcmp(argv[2], "test_second_name")) + test_second_name(); return; }
@@ -7868,6 +7987,14 @@ START_TEST(font) { PROCESS_INFORMATION info;
+ if (!strcmp(winetest_platform, "wine") && !strcmp(test_names[i], "test_second_name")) + { + HKEY hkey; + hkey = reg_open_key(NULL, font_substitutes_keyW, sizeof(font_substitutes_keyW)); + set_reg_ascii_value( hkey, "wine_this_is_second_name_subst", "wine_this_is_second_name"); + NtClose( hkey ); + } + memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); sprintf(path_name, "%s font %s", argv[0], test_names[i]); diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc index 784d8602a9a..acfaa106632 100644 --- a/dlls/gdi32/tests/resource.rc +++ b/dlls/gdi32/tests/resource.rc @@ -49,3 +49,6 @@ wine_langnames3.ttf RCDATA wine_langnames3.ttf
/* @makedep: wine_nul.ttf */ wine_nul.ttf RCDATA wine_nul.ttf + +/* @makedep: wine_secondname.ttf */ +wine_secondname.ttf RCDATA wine_secondname.ttf diff --git a/dlls/gdi32/tests/wine_secondname.sfd b/dlls/gdi32/tests/wine_secondname.sfd new file mode 100644 index 00000000000..5c0237cbfcb --- /dev/null +++ b/dlls/gdi32/tests/wine_secondname.sfd @@ -0,0 +1,76 @@ +SplineFontDB: 3.2 +FontName: wine_this_is_second_name +FullName: wine_this_is_second_name +FamilyName: wine_this_is_second_name +Weight: Regular +Copyright: Copyright (c) 2023, Haoyang Chen +UComments: "2023-12-18: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -100 +UnderlineWidth: 50 +Ascent: 800 +Descent: 200 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "+gMxmbwAA" 1 +Layer: 1 0 "+Uk1mbwAA" 0 +XUID: [1021 296 1263752128 9813898] +FSType: 0 +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1702866398 +ModificationTime: 1702877141 +PfmFamily: 17 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 90 +VLineGap: 0 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 90 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +LangName: 2052 "Copyright (c) 2023, Haoyang Chen" "wine_this_is_first_name" "Regular" "wine_this_is_first_name" "wine_this_is_first_name" "+ckhnLAAA 001.000" +LangName: 1033 "" "" "" "wine_this_is_second_name" +Encoding: ISO8859-1 +UnicodeInterp: simpchinese +NameList: Adobe Glyph List +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 64 16 4 +BeginPrivate: 0 +EndPrivate +TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144 +BeginChars: 256 1 + +StartChar: at +Encoding: 64 64 0 +Width: 1000 +VWidth: 0 +Flags: HW +LayerCount: 2 +Fore +SplineSet +259 332 m 29 + 468 664 l 29 + 514 332 l 29 + 259 332 l 29 +EndSplineSet +Validated: 1 +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/wine_secondname.ttf b/dlls/gdi32/tests/wine_secondname.ttf new file mode 100644 index 0000000000000000000000000000000000000000..35b135da7eee34cad7c1881a331854c44a71a21f GIT binary patch literal 3952 zcmeH~UuaWT9LImZb8p(H-E5(ob?d_|7FMOJF?CX*8)0?QhserSrAV=jNty)OG&FIx zAmW3AvX!l%V@2F>!+{Sn+ESsgP8^fjF$WHOkWsb{+~|ga4;}NNTlYOTU;peuhEouR zH@)}s{r%24zkB}V<oqfsB2UO6aineg_VyhgZ+`!2k=5<+R=@iC#_-P1Vg(WHfZZMM zi{*O4N4|zVD-zruf1}_@jTsVIS&niy70c(Amk~);M_~t3y+b{pzx`nt<sR%@IvGpU zj%<J}bGWyp;c)+Ot|MM0?Aml+VQ|&7*212KUEbRtkI7y^Usl@km3^_noV3bTlsCcl zva!D8k+OqbC>q7<-^umo3(G&s3wXbW@(p6ghWneXJGOMKZvI_XIScT}PoM1BQ{?bY zsSz>89D^McW4*Z0#`o+l);GqFR4gk#UEky0Zev@j?~6!-U&VD6bW{R}^p=@{XQW7- zmraV=Mgl8}q5PJ&rAS-PD+xI#5s5h7a+B=#d*b)$b|p^~Jwwk$Y!C4!%(;D+oqMS- z_O>(vu7w?i7bAk-@yny)iU-@p$ND2!Gyl2#WwE80l0|qPUk^G1K`ECi%ypfFqzNn9 zDs9ps-IA7^3}Vj>%czXW2{|R>GL1E#l}mC(=4C-{$W45mf?BRs>S>*Zv`Hh{s%_e# z-I~^%4(cHt)=?eP6M9O=bz0BqtX|S9I<E_QLvI=}K~rw3jA!ah$TXRVX*F%8!*rXp z$(ccO$PAlNGiFYhQ)b*un{#H?TryY8yzzGl2LBPhr@!He-Qw1g)np}EM!H2hOXMPX zjl4?Ek(bGf<au(2oFY$?C&}aFQF4SlOdcQ$WG|T@JIQu3N^T>Y$<1UvSxZ)vm1G&| z7HO8qMe-VXm7F6llNZVJ<P14Qo+eL{$H}AQ2zi)1Ko-beGC_8d?PQePMmCe1$$GMu ztR^eTGSV$lm&ir(8hMqRBQKK|$@An4IYpi(Pm;&UqvQyAm^?rh$X+r*c9QL6l-%~9 zoBe^?+u!cT*CU$&ExB{Z+7nvrefMS0%73~32TSPZbI6_S$7Wf^<{7#HS%@R0(lDX2 zv3au8mFwY&lE7T^q+=ju!m;jvbx)R-=u-0}rto^Wv7)BpxyFihHM(Nq!Uc2e&z>67 zfpF?*6j|4ponw6#=64Mm)#zVSc7C7HmzakL&d!&q6({L?xAGJ8<SexV|4nLFs<eeV zAmw_Hx&;0&px632lV_@_Ro0k3Y9pn_#<z7G_`jugWsUO`bwJ9T7L=-MbGHcYqE?*m zacUz^%BR#0{9jSK64DClfOy(TT>}5RRtH@hQ@^KHX)rHRBc^$i+JXNAY8U!v>VQ-_ z&r6H+Bexim0m(=Tc}4*<Sckr?2gB%1SQ?QBddNg#s5yjZ7WF)|OG^@3TKaQC1DRC1 z;MK*~d*M*HvEFNq^$*3eDX%4+M2-Cjokis?1W!Zfp^DEuym5rhN&>ztg7?8A`!m^O zS0SCrci}IejQ3{~T{d+Wc@4!W*(bfIIsh}7+SeO{c!;lfh@p0&w*we%#vh`G*$l}h zWc!vO%%SW`4&*caSuYgY)DQ}V;CYB|f21qhgF)M&7w);PJ(+=g;Xg0y{l&lctln3g zf!37W3jbV28UJPC?5!2VhP1y>_F6uJy>sV)@O}Qn?pj5yb-tzeU&^*nYyI%+_+HDq H|KI!@i=z@Q
literal 0 HcmV?d00001