Merge branch 'ntfs_rebase'
[reactos.git] / modules / rostests / winetests / user32 / text.c
1 /*
2 * DrawText tests
3 *
4 * Copyright (c) 2004 Zach Gorman
5 * Copyright 2007,2016 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "precomp.h"
23
24 #define MODIFIED(rect) (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)
25 #define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top)
26
27 static void test_DrawTextCalcRect(void)
28 {
29 HWND hwnd;
30 HDC hdc;
31 HFONT hFont, hOldFont;
32 LOGFONTA lf;
33 static CHAR text[] = "Example text for testing DrawText in "
34 "MM_HIENGLISH mode";
35 static WCHAR textW[] = {'W','i','d','e',' ','c','h','a','r',' ',
36 's','t','r','i','n','g','\0'};
37 static CHAR emptystring[] = "";
38 static WCHAR emptystringW[] = { 0 };
39 static CHAR wordbreak_text[] = "line1 line2";
40 static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0};
41 static char tabstring[] = "one\ttwo";
42 INT textlen, textheight, heightcheck;
43 RECT rect = { 0, 0, 100, 0 }, rect2;
44 BOOL ret;
45 DRAWTEXTPARAMS dtp;
46 BOOL conform_xp = TRUE;
47
48 /* Initialization */
49 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
50 0, 0, 200, 200, 0, 0, 0, NULL);
51 ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
52 hdc = GetDC(hwnd);
53 ok(hdc != 0, "GetDC error %u\n", GetLastError());
54 trace("hdc %p\n", hdc);
55 textlen = lstrlenA(text);
56
57 /* LOGFONT initialization */
58 memset(&lf, 0, sizeof(lf));
59 lf.lfCharSet = ANSI_CHARSET;
60 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
61 lf.lfWeight = FW_DONTCARE;
62 lf.lfHeight = 0; /* mapping mode dependent */
63 lf.lfQuality = DEFAULT_QUALITY;
64 lstrcpyA(lf.lfFaceName, "Arial");
65
66 /* DrawText in MM_HIENGLISH with DT_CALCRECT */
67 SetMapMode(hdc, MM_HIENGLISH);
68 lf.lfHeight = 100 * 9 / 72; /* 9 point */
69 hFont = CreateFontIndirectA(&lf);
70 ok(hFont != 0, "CreateFontIndirectA error %u\n",
71 GetLastError());
72 hOldFont = SelectObject(hdc, hFont);
73
74 textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
75 DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
76 DT_NOPREFIX);
77 ok( textheight, "DrawTextA error %u\n", GetLastError());
78
79 trace("MM_HIENGLISH rect.bottom %d\n", rect.bottom);
80 ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with "
81 "DT_CALCRECT should return a negative rectangle bottom. "
82 "(bot=%d)\n", rect.bottom);
83
84 SelectObject(hdc, hOldFont);
85 ret = DeleteObject(hFont);
86 ok( ret, "DeleteObject error %u\n", GetLastError());
87
88
89 /* DrawText in MM_TEXT with DT_CALCRECT */
90 SetMapMode(hdc, MM_TEXT);
91 lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc,
92 LOGPIXELSY), 72); /* 9 point */
93 hFont = CreateFontIndirectA(&lf);
94 ok(hFont != 0, "CreateFontIndirectA error %u\n",
95 GetLastError());
96 hOldFont = SelectObject(hdc, hFont);
97
98 textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT |
99 DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT |
100 DT_NOPREFIX);
101 ok( textheight, "DrawTextA error %u\n", GetLastError());
102
103 trace("MM_TEXT rect.bottom %d\n", rect.bottom);
104 ok(rect.bottom > 0, "In MM_TEXT, DrawText with DT_CALCRECT "
105 "should return a positive rectangle bottom. (bot=%d)\n",
106 rect.bottom);
107
108 /* empty or null text should in some cases calc an empty rectangle */
109
110 SetRect( &rect, 10,10, 100, 100);
111 heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
112 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
113 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
114 ok(textheight==0,"Got textheight from DrawTextExA\n");
115
116 SetRect( &rect, 10,10, 100, 100);
117 textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
118 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
119 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
120 if (conform_xp)
121 ok(textheight==0,"Got textheight from DrawTextA\n");
122 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
123
124 SetRect( &rect, 10,10, 100, 100);
125 SetLastError( 0);
126 heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL );
127 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
128 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
129
130 SetRect( &rect, 10,10, 100, 100);
131 textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT);
132 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
133 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
134 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
135
136 SetRect( &rect, 10,10, 100, 100);
137 SetLastError( 0);
138 heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
139 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
140 if (!textheight) /* Windows NT 4 */
141 {
142 if (conform_xp)
143 win_skip("XP conformity failed, skipping XP tests. Probably winNT\n");
144 conform_xp = FALSE;
145 }
146 else
147 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
148
149 SetRect( &rect, 10,10, 100, 100);
150 textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT);
151 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
152 if (conform_xp)
153 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
154 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
155
156 SetRect( &rect, 10,10, 100, 100);
157 heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
158 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
159 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
160 if (conform_xp)
161 ok(textheight==0,"Got textheight from DrawTextExA\n");
162
163 SetRect( &rect, 10,10, 100, 100);
164 textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT);
165 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
166 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
167 if (conform_xp)
168 ok(textheight==0,"Got textheight from DrawTextA\n");
169 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
170
171 /* DT_SINGLELINE tests */
172
173 SetRect( &rect, 10,10, 100, 100);
174 heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
175 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
176 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
177 if (conform_xp)
178 ok(textheight==0,"Got textheight from DrawTextExA\n");
179
180 SetRect( &rect, 10,10, 100, 100);
181 textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
182 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
183 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
184 if (conform_xp)
185 ok(textheight==0,"Got textheight from DrawTextA\n");
186 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
187
188 SetRect( &rect, 10,10, 100, 100);
189 SetLastError( 0);
190 heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
191 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
192 wine_dbgstr_rect(&rect));
193 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
194
195 SetRect( &rect, 10,10, 100, 100);
196 textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
197 ok(!EMPTY(rect) && MODIFIED (rect), "rectangle should be modified got %s\n",
198 wine_dbgstr_rect(&rect));
199 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
200 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
201
202 SetRect( &rect, 10,10, 100, 100);
203 SetLastError( 0);
204 heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
205 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
206 wine_dbgstr_rect(&rect));
207 if (conform_xp)
208 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
209
210 SetRect( &rect, 10,10, 100, 100);
211 textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
212 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
213 wine_dbgstr_rect(&rect));
214 if (conform_xp)
215 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
216 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
217
218 SetRect( &rect, 10,10, 100, 100);
219 heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
220 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
221 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
222 if (conform_xp)
223 ok(textheight==0,"Got textheight from DrawTextExA\n");
224
225 SetRect( &rect, 10,10, 100, 100);
226 textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
227 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
228 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
229 if (conform_xp)
230 ok(textheight==0,"Got textheight from DrawTextA\n");
231 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
232
233 /* further tests with 0 count, NULL and empty strings */
234 heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0);
235 if (conform_xp)
236 ok(textheight==0,"Got textheight from DrawTextA\n");
237 textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL );
238 if (conform_xp)
239 ok(textheight==0,"Got textheight from DrawTextExA\n");
240 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
241 heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0);
242 if (conform_xp)
243 ok(textheight==0,"Got textheight from DrawTextA\n");
244 textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL );
245 if (conform_xp)
246 ok(textheight==0,"Got textheight from DrawTextExA\n");
247 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
248 heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0);
249 if (conform_xp)
250 ok(textheight==0,"Got textheight from DrawTextA\n");
251 textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL );
252 if (conform_xp)
253 ok(textheight==0,"Got textheight from DrawTextExA\n");
254 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
255 heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0);
256 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
257 textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL );
258 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
259 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
260 heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0);
261 if (conform_xp)
262 ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
263 textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL );
264 if (conform_xp)
265 ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
266 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
267 heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0);
268 ok(textheight==0,"Got textheight from DrawTextA\n");
269 textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL );
270 ok(textheight==0,"Got textheight from DrawTextA\n");
271 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
272
273
274 /* invalid dtp size test */
275 dtp.cbSize = -1; /* Invalid */
276 dtp.uiLengthDrawn = 1337;
277 textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
278 ok(textheight==0,"Got textheight from DrawTextExA\n");
279 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
280 dtp.uiLengthDrawn = 1337;
281 textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
282 ok(textheight==0,"Got textheight from DrawTextExA\n");
283 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
284 dtp.uiLengthDrawn = 1337;
285 textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
286 ok(textheight==0,"Got textheight from DrawTextExA\n");
287 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
288 dtp.uiLengthDrawn = 1337;
289 textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
290 ok(textheight==0,"Got textheight from DrawTextExA\n");
291 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
292 dtp.uiLengthDrawn = 1337;
293 textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
294 ok(textheight==0,"Got textheight from DrawTextExA\n");
295 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
296
297 /* Margin calculations */
298 dtp.cbSize = sizeof(dtp);
299 dtp.iLeftMargin = 0;
300 dtp.iRightMargin = 0;
301 SetRectEmpty(&rect);
302 DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
303 textlen = rect.right; /* Width without margin */
304 dtp.iLeftMargin = 8;
305 SetRectEmpty(&rect);
306 DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
307 ok(rect.right==dtp.iLeftMargin+textlen ,"Incorrect left margin calculated rc(%d,%d)\n", rect.left, rect.right);
308 dtp.iLeftMargin = 0;
309 dtp.iRightMargin = 8;
310 SetRectEmpty(&rect);
311 DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp);
312 ok(rect.right==dtp.iRightMargin+textlen ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right);
313
314 /* Wide char versions */
315 SetRect( &rect, 10,10, 100, 100);
316 SetLastError( 0);
317 heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
318 if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
319 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
320 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
321 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
322
323 SetRect( &rect, 10,10, 100, 100);
324 textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
325 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
326 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
327 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
328 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
329
330 SetRect( &rect, 10,10, 100, 100);
331 heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
332 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
333 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
334
335 SetRect( &rect, 10,10, 100, 100);
336 textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
337 ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect));
338 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
339 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
340
341 SetRect( &rect, 10,10, 100, 100);
342 heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
343 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
344 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
345 if (textheight) /* windows 2000 */
346 {
347 if (conform_xp)
348 win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
349 conform_xp = FALSE;
350 }
351 else
352 ok(textheight==0,"Got textheight from DrawTextExW\n");
353
354 SetRect( &rect, 10,10, 100, 100);
355 textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
356 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
357 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
358 if (conform_xp)
359 ok(textheight==0,"Got textheight from DrawTextW\n");
360 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
361
362 if (conform_xp) {
363 /* Crashes on NT4 */
364 SetRect( &rect, 10,10, 100, 100);
365 heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
366 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
367 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
368 ok(textheight==0,"Got textheight from DrawTextExW\n");
369
370 SetRect( &rect, 10,10, 100, 100);
371 textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
372 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
373 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
374 ok(textheight==0,"Got textheight from DrawTextW\n");
375 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
376 }
377
378
379 /* DT_SINGLELINE tests */
380
381 heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
382 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
383 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
384 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
385
386 SetRect( &rect, 10,10, 100, 100);
387 textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
388 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
389 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
390 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
391 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
392
393 SetRect( &rect, 10,10, 100, 100);
394 heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
395 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
396 wine_dbgstr_rect(&rect));
397 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
398
399 SetRect( &rect, 10,10, 100, 100);
400 textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
401 ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n",
402 wine_dbgstr_rect(&rect));
403 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
404 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
405
406 if (conform_xp) {
407 /* Crashes on NT4 */
408 SetRect( &rect, 10,10, 100, 100);
409 heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
410 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
411 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
412 ok(textheight==0,"Got textheight from DrawTextExW\n");
413
414 SetRect( &rect, 10,10, 100, 100);
415 textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
416 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
417 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
418 ok(textheight==0,"Got textheight from DrawTextW\n");
419 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
420 }
421
422 SetRect( &rect, 10,10, 100, 100);
423 heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
424 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
425 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
426 if (conform_xp)
427 ok(textheight==0,"Got textheight from DrawTextExW\n");
428
429 SetRect( &rect, 10,10, 100, 100);
430 textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
431 ok(!IsRectEmpty(&rect) && !MODIFIED(rect),
432 "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect));
433 if (conform_xp)
434 ok(textheight==0,"Got textheight from DrawTextW\n");
435 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
436
437 /* further tests with NULL and empty strings */
438 heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
439 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
440 textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
441 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
442 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
443 heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
444 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
445 textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
446 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
447 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
448 heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
449 if (conform_xp)
450 ok(textheight==0,"Got textheight from DrawTextW\n");
451 textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
452 if (conform_xp)
453 ok(textheight==0,"Got textheight from DrawTextExW\n");
454 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
455 heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
456 ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
457 textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL );
458 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
459 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
460 if (conform_xp) {
461 /* Crashes on NT4 */
462 heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
463 ok(textheight==0,"Got textheight from DrawTextW\n");
464 textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
465 ok(textheight==0,"Got textheight from DrawTextExW\n");
466 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
467 heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
468 ok(textheight==0,"Got textheight from DrawTextW\n");
469 textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
470 ok(textheight==0,"Got textheight from DrawTextW\n");
471 ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
472 }
473
474 dtp.cbSize = -1; /* Invalid */
475 dtp.uiLengthDrawn = 1337;
476 textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
477 ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
478 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
479 dtp.uiLengthDrawn = 1337;
480 textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
481 if (conform_xp)
482 ok(textheight==0,"Got textheight from DrawTextExW\n");
483 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
484 dtp.uiLengthDrawn = 1337;
485 textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
486 if (conform_xp)
487 ok(textheight==0,"Got textheight from DrawTextExW\n");
488 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
489 dtp.uiLengthDrawn = 1337;
490 textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
491 ok(textheight==0,"Got textheight from DrawTextExW\n");
492 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
493 if (conform_xp) {
494 /* Crashes on NT4 */
495 dtp.uiLengthDrawn = 1337;
496 textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
497 ok(textheight==0,"Got textheight from DrawTextExW\n");
498 ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
499 }
500 }
501
502 /* More test cases from bug 12226 */
503 SetRectEmpty(&rect);
504 textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
505 ok(textheight, "DrawTextA error %u\n", GetLastError());
506 ok(0 == rect.left, "expected 0, got %d\n", rect.left);
507 ok(0 == rect.right, "expected 0, got %d\n", rect.right);
508 ok(0 == rect.top, "expected 0, got %d\n", rect.top);
509 ok(rect.bottom, "rect.bottom should not be 0\n");
510
511 SetRectEmpty(&rect);
512 textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
513 if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
514 {
515 win_skip( "DrawTextW not implemented\n" );
516 }
517 else
518 {
519 ok(textheight, "DrawTextW error %u\n", GetLastError());
520 ok(0 == rect.left, "expected 0, got %d\n", rect.left);
521 ok(0 == rect.right, "expected 0, got %d\n", rect.right);
522 ok(0 == rect.top, "expected 0, got %d\n", rect.top);
523 ok(rect.bottom, "rect.bottom should not be 0\n");
524 }
525
526 SetRect(&rect, 0, 0, 1, 1);
527 heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT);
528 SetRect(&rect, 0, 0, 1, 1);
529 textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
530 ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
531 textheight, heightcheck * 2);
532 SetRect(&rect, 0, 0, 1, 1);
533 textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
534 ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
535 textheight, heightcheck * 6);
536
537 SetRect(&rect, 0, 0, 1, 1);
538 heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT);
539 SetRect(&rect, 0, 0, 1, 1);
540 textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK);
541 ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n",
542 textheight, heightcheck * 2);
543 SetRect(&rect, 0, 0, 1, 1);
544 textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL);
545 ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n",
546 textheight, heightcheck * 6);
547
548 /* DT_TABSTOP | DT_EXPANDTABS tests */
549 SetRect( &rect, 0,0, 10, 10);
550 textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS );
551 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
552
553 SetRect( &rect, 0,0, 10, 10);
554 memset(&dtp, 0, sizeof(dtp));
555 dtp.cbSize = sizeof(dtp);
556 textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp);
557 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
558 ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
559
560 SetRect( &rect2, 0,0, 10, 10);
561 memset(&dtp, 0, sizeof(dtp));
562 dtp.cbSize = sizeof(dtp);
563 textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
564 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
565 ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
566 ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom,
567 "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2));
568
569 SetRect( &rect, 0,0, 10, 10);
570 memset(&dtp, 0, sizeof(dtp));
571 dtp.cbSize = sizeof(dtp);
572 dtp.iTabLength = 8;
573 textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp);
574 ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight);
575 ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength);
576 ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left);
577 /* XP, 2003 appear to not give the same values. */
578 ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right);
579 ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top);
580 ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom);
581
582
583 SelectObject(hdc, hOldFont);
584 ret = DeleteObject(hFont);
585 ok( ret, "DeleteObject error %u\n", GetLastError());
586
587 /* Clean up */
588 ret = ReleaseDC(hwnd, hdc);
589 ok( ret, "ReleaseDC error %u\n", GetLastError());
590 ret = DestroyWindow(hwnd);
591 ok( ret, "DestroyWindow error %u\n", GetLastError());
592 }
593
594 /* replace tabs by \t */
595 static void strfmt( const char *str, char *strout)
596 {
597 unsigned int i,j ;
598 for(i=0,j=0;i<=strlen(str);i++,j++)
599 if((strout[j]=str[i])=='\t') {
600 strout[j++]='\\';
601 strout[j]='t';
602 }
603 }
604
605
606 #define TABTEST( tabval, tabcount, string, _exp) \
607 { int i; char strdisp[64];\
608 for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \
609 extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \
610 strfmt( string, strdisp); \
611 /* trace( "Extent is %08lx\n", extent); */\
612 ok( extent == _exp, "Test case \"%s\". Text extent is 0x%x, expected 0x%x tab %d tabcount %d\n", \
613 strdisp, extent, _exp, tabval, tabcount); \
614 } \
615
616
617 static void test_TabbedText(void)
618 {
619 HWND hwnd;
620 HDC hdc;
621 BOOL ret;
622 TEXTMETRICA tm;
623 DWORD extent;
624 INT tabs[8], cx, cy, tab, tabcount,t,align;
625
626 /* Initialization */
627 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
628 0, 0, 200, 200, 0, 0, 0, NULL);
629 ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
630 hdc = GetDC(hwnd);
631 ok(hdc != 0, "GetDC error %u\n", GetLastError());
632
633 ret = GetTextMetricsA( hdc, &tm);
634 ok( ret, "GetTextMetrics error %u\n", GetLastError());
635
636 extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs);
637 ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n");
638
639 extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs);
640 cx = LOWORD( extent);
641 cy = HIWORD( extent);
642 trace( "cx is %d cy is %d\n", cx, cy);
643
644 align=1;
645 for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
646 catch the one off errors */
647 tab = (cx *4 + t);
648 /* test the special case tabcount =1 and the general array (80 of tabs */
649 for( tabcount = 1; tabcount <= 8; tabcount +=7) {
650 TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
651 TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
652 TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
653 TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
654 TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
655 TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
656 TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
657 TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
658 TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
659 TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
660 }
661 }
662 align=-1;
663 for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to
664 catch the one off errors */
665 tab = (cx *4 + t);
666 /* test the special case tabcount =1 and the general array (8) of tabs */
667 for( tabcount = 1; tabcount <= 8; tabcount +=7) {
668 TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
669 TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
670 TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
671 TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
672 TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
673 TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
674 TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
675 TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
676 TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
677 TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
678 }
679 }
680
681 ReleaseDC( hwnd, hdc );
682 DestroyWindow( hwnd );
683 }
684
685 static void test_DrawState(void)
686 {
687 static const char text[] = "Sample text string";
688 HWND hwnd;
689 HDC hdc;
690 BOOL ret;
691
692 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
693 0, 0, 200, 200, 0, 0, 0, NULL);
694 assert(hwnd);
695
696 hdc = GetDC(hwnd);
697 assert(hdc);
698
699 SetLastError(0xdeadbeef);
700 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, strlen(text),
701 0, 0, 10, 10, DST_TEXT);
702 ok(ret, "DrawState error %u\n", GetLastError());
703
704 SetLastError(0xdeadbeef);
705 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, 0,
706 0, 0, 10, 10, DST_TEXT);
707 ok(ret, "DrawState error %u\n", GetLastError());
708
709 SetLastError(0xdeadbeef);
710 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text),
711 0, 0, 10, 10, DST_TEXT);
712 ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
713 ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
714
715 SetLastError(0xdeadbeef);
716 ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0,
717 0, 0, 10, 10, DST_TEXT);
718 ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
719 ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
720
721 ReleaseDC(hwnd, hdc);
722 DestroyWindow(hwnd);
723 }
724
725 static void test_CharToOem_OemToChar(void)
726 {
727 static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
728 static const WCHAR emptyW[] = {0};
729 static const char helloWorld[] = "Hello World";
730 static const struct
731 {
732 BOOL src, dst, ret;
733 }
734 tests[] =
735 {
736 { FALSE, FALSE, FALSE },
737 { TRUE, FALSE, FALSE },
738 { FALSE, TRUE, FALSE },
739 { TRUE, TRUE, TRUE },
740 };
741 BOOL ret;
742 int i;
743 char oem;
744 WCHAR uni, expect;
745
746 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
747 {
748 const char *expected = tests[i].ret ? helloWorld : "";
749 const char *src = tests[i].src ? helloWorld : NULL;
750 char buf[64], *dst = tests[i].dst ? buf : NULL;
751
752 memset(buf, 0, sizeof(buf));
753 ret = CharToOemA(src, dst);
754 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
755 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
756
757 memset(buf, 0, sizeof(buf));
758 ret = CharToOemBuffA(src, dst, sizeof(helloWorld));
759 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
760 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
761
762 memset(buf, 0, sizeof(buf));
763 ret = OemToCharA(src, dst);
764 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
765 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
766
767 memset(buf, 0, sizeof(buf));
768 ret = OemToCharBuffA(src, dst, sizeof(helloWorld));
769 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
770 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
771 }
772
773 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
774 {
775 const char *expected = tests[i].ret ? helloWorld : "";
776 const WCHAR *src = tests[i].src ? helloWorldW : NULL;
777 char buf[64], *dst = tests[i].dst ? buf : NULL;
778
779 memset(buf, 0, sizeof(buf));
780 ret = CharToOemW(src, dst);
781 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
782 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
783
784 memset(buf, 0, sizeof(buf));
785 ret = CharToOemBuffW(src, dst, sizeof(helloWorldW)/sizeof(WCHAR));
786 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
787 ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf);
788 }
789
790 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
791 {
792 const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW;
793 const char *src = tests[i].src ? helloWorld : NULL;
794 WCHAR buf[64], *dst = tests[i].dst ? buf : NULL;
795
796 memset(buf, 0, sizeof(buf));
797 ret = OemToCharW(src, dst);
798 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
799 ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
800
801 memset(buf, 0, sizeof(buf));
802 ret = OemToCharBuffW(src, dst, sizeof(helloWorld));
803 ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret);
804 ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf));
805 }
806
807 for (i = 0; i < 0x100; i++)
808 {
809 oem = i;
810 ret = OemToCharBuffW( &oem, &uni, 1 );
811 ok( ret, "%02x: returns FALSE\n", i );
812 MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, &oem, 1, &expect, 1 );
813 ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect );
814 }
815 }
816
817 START_TEST(text)
818 {
819 test_TabbedText();
820 test_DrawTextCalcRect();
821 test_DrawState();
822 test_CharToOem_OemToChar();
823 }