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 }
824