1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for GetGlyphIndices
5 * PROGRAMMERS: Ged Murphy
6 */
7
8 #include "precomp.h"
9
10 #define ok_lasterrornotchanged() \
11 ok_err(0x12345)
12
13 #define MAX_BMP_GLYPHS 0xFFFF
14
GetResource(LPCWSTR FontName,LPDWORD Size)15 static LPVOID GetResource(LPCWSTR FontName, LPDWORD Size)
16 {
17 HRSRC hRsrc;
18 LPVOID Data;
19
20 hRsrc = FindResourceW(GetModuleHandleW(NULL), FontName, (LPCWSTR)RT_RCDATA);
21 if (!hRsrc) return NULL;
22
23 Data = LockResource(LoadResource(GetModuleHandleW(NULL), hRsrc));
24 if (!Data) return NULL;
25
26 *Size = SizeofResource(GetModuleHandleW(NULL), hRsrc);
27 if (*Size == 0) return NULL;
28
29 return Data;
30 }
31
ExtractTTFFile(LPCWSTR FontName,LPWSTR TempFile)32 static BOOL ExtractTTFFile(LPCWSTR FontName, LPWSTR TempFile)
33 {
34 WCHAR TempPath[MAX_PATH];
35 HANDLE hFile;
36 void *Data;
37 DWORD Size;
38 BOOL ret;
39
40 Data = GetResource(FontName, &Size);
41 if (!Data) return FALSE;
42
43 GetTempPathW(MAX_PATH, TempPath);
44 GetTempFileNameW(TempPath, L"ttf", 0, TempFile);
45
46 hFile = CreateFileW(TempFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
47 if (hFile == INVALID_HANDLE_VALUE) return FALSE;
48
49 ret = WriteFile(hFile, Data, Size, &Size, NULL);
50
51 CloseHandle(hFile);
52 return ret;
53 }
54
InstallTempFont(LPWSTR TempFile)55 static BOOL InstallTempFont(LPWSTR TempFile)
56 {
57 if (ExtractTTFFile(L"ReactOSTestTahoma.ttf", TempFile))
58 {
59 if (AddFontResourceExW(TempFile, FR_PRIVATE, 0) > 0)
60 {
61 return TRUE;
62 }
63 }
64
65 return FALSE;
66 }
67
RemoveTempFont(LPWSTR TempFile)68 static VOID RemoveTempFont(LPWSTR TempFile)
69 {
70 BOOL Success;
71 Success = RemoveFontResourceExW(TempFile, FR_PRIVATE, 0);
72 ok(Success, "RemoveFontResourceEx() failed, we're leaving fonts installed : %lu\n", GetLastError());
73 DeleteFileW(TempFile);
74 }
75
IntCreateFont(LPWSTR FontName)76 static HFONT IntCreateFont(LPWSTR FontName)
77 {
78 LOGFONTW Font = { 0 };
79 Font.lfCharSet = DEFAULT_CHARSET;
80 wcsncpy(Font.lfFaceName, FontName, sizeof(Font.lfFaceName) / sizeof(Font.lfFaceName[0]));
81 return CreateFontIndirectW(&Font);
82 }
83
START_TEST(GetGlyphIndices)84 START_TEST(GetGlyphIndices)
85 {
86 WCHAR Glyphs[MAX_BMP_GLYPHS];
87 WORD Indices[MAX_BMP_GLYPHS];
88 WCHAR Single[2] = { L' ', UNICODE_NULL };
89 WCHAR TempTTFFile[MAX_PATH];
90 HFONT hFont;
91 HDC hdc;
92 int i;
93 DWORD ret;
94 static const WCHAR s_invalids[] = {0xFEFE, 0xFEFF, 0xFFFE, 0};
95
96 if (!InstallTempFont(TempTTFFile))
97 {
98 skip("Failed to create ttf file for testing\n");
99 return;
100 }
101
102 hdc = CreateCompatibleDC(NULL);
103 ok(hdc != 0, "CreateCompatibleDC failed, skipping tests.\n");
104 if (!hdc) return;
105
106 hFont = IntCreateFont(L"ReactOSTestTahoma");
107 ok(hFont != NULL, "Failed to open the test font");
108 SelectObject(hdc, hFont);
109
110 SetLastError(0x12345);
111
112 /* Test NULL DC */
113 ok_int(GetGlyphIndicesW(NULL, Single, 1, Indices, 0), GDI_ERROR);
114 ok_lasterrornotchanged();
115
116 /* Test invalid DC */
117 ok_int(GetGlyphIndicesW((HDC)(ULONG_PTR)0x12345, Single, 1, Indices, 0), GDI_ERROR);
118 ok_lasterrornotchanged();
119
120 /* Test invalid params */
121 ok_int(GetGlyphIndicesW(hdc, NULL, 1, NULL, 0), GDI_ERROR);
122 ok_lasterrornotchanged();
123 ok_int(GetGlyphIndicesW(hdc, NULL, 32, NULL, 0), GDI_ERROR);
124 ok_lasterrornotchanged();
125 ok_int(GetGlyphIndicesW(hdc, NULL, 0, Indices, 0), GDI_ERROR);
126 ok_lasterrornotchanged();
127 ok_int(GetGlyphIndicesW(hdc, NULL, 1, Indices, 0), GDI_ERROR);
128 ok_lasterrornotchanged();
129 ok_int(GetGlyphIndicesW(hdc, NULL, 32, Indices, 0), GDI_ERROR);
130 ok_lasterrornotchanged();
131 ok_int(GetGlyphIndicesW(hdc, Single, 0, NULL, 0), GDI_ERROR);
132 ok_lasterrornotchanged();
133 ok_int(GetGlyphIndicesW(hdc, Single, 1, NULL, 0), GDI_ERROR);
134 ok_lasterrornotchanged();
135 ok_int(GetGlyphIndicesW(hdc, Glyphs, 32, NULL, 0), GDI_ERROR);
136 ok_lasterrornotchanged();
137 ok_int(GetGlyphIndicesW(hdc, Single, 0, Indices, 0), GDI_ERROR);
138 ok_lasterrornotchanged();
139 ok_int(GetGlyphIndicesW(hdc, Single, 1, Indices, 0xFFFFFFFF), 1);
140 ok_lasterrornotchanged();
141
142 /* Test an exceptional case that does not seem to return an error */
143 /* In this case, it returns the number of glyphs */
144 ret = GetGlyphIndicesW(hdc, NULL, 0, NULL, 0);
145 ok(ret == 988,
146 "GetGlyphIndicesW(hdc, NULL, 0, NULL, 0) return expected 988, but got %ld\n", ret);
147 ok_lasterrornotchanged();
148
149 /* Test a single valid char */
150 Single[0] = L'a';
151 ok_int(GetGlyphIndicesW(hdc, Single, 1, Indices, 0), 1);
152 ok_lasterrornotchanged();
153 ok_int(Indices[0], 68);
154
155 /* Setup an array of all possible BMP glyphs */
156 for (i = 0; i < 4; i++)
157 Glyphs[i] = (WCHAR)i;
158
159 /* Test a string of valid chars */
160 StringCchCopyW(Glyphs, MAX_BMP_GLYPHS, L"0123");
161 ok_int(GetGlyphIndicesW(hdc, Glyphs, 4, Indices, 0), 4);
162 ok_lasterrornotchanged();
163 ok_int(Indices[0], 19);
164 ok_int(Indices[1], 20);
165 ok_int(Indices[2], 21);
166 ok_int(Indices[3], 22);
167
168 ok_int(GetGlyphIndicesW(hdc, s_invalids, 3, Indices, 0), 3);
169 ok_lasterrornotchanged();
170 ok_int(Indices[0], 0);
171 ok_int(Indices[1], 0);
172 ok_int(Indices[2], 0);
173
174 ok_int(GetGlyphIndicesW(hdc, s_invalids, 3, Indices, GGI_MARK_NONEXISTING_GLYPHS), 3);
175 ok_lasterrornotchanged();
176 ok_int(Indices[0], 0xFFFF);
177 ok_int(Indices[1], 0xFFFF);
178 ok_int(Indices[2], 0xFFFF);
179
180 /* Setup an array of all possible BMP glyphs */
181 for (i = 0; i < MAX_BMP_GLYPHS; i++)
182 Glyphs[i] = (WCHAR)i;
183
184 /* Get all the glyphs */
185 ok_int(GetGlyphIndicesW(hdc,
186 Glyphs,
187 MAX_BMP_GLYPHS,
188 Indices,
189 GGI_MARK_NONEXISTING_GLYPHS), MAX_BMP_GLYPHS);
190
191 /* The first 32 are invalid and should contain 0xffff */
192 for (i = 0; i < 32; i++)
193 ok_int(Indices[i], 0xffff);
194
195 /* These are the first 2 valid chars */
196 ok(Indices[32] != 0xffff, "ascii char ' ' should be a valid char");
197 ok(Indices[33] != 0xffff, "ascii char '!' should be a valid char");
198
199 RemoveTempFont(TempTTFFile);
200 }
201
202