wininet: Use a blank password if none is provided in FTP_Connect.
[wine] / dlls / usp10 / tests / usp10.c
1 /*
2  * Tests for usp10 dll
3  *
4  * Copyright 2006 Jeff Latimer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Notes:
21  * Uniscribe allows for processing of complex scripts such as joining
22  * and filtering characters and bi-directional text with custom line breaks.
23  */
24
25 #include <assert.h>
26 #include <stdio.h>
27
28 #include <wine/test.h>
29 #include <winbase.h>
30 #include <wingdi.h>
31 #include <winuser.h>
32 #include <winerror.h>
33 #include <usp10.h>
34
35 static void test_ScriptItemIzeShapePlace(unsigned short pwOutGlyphs[256])
36 {
37     HRESULT         hr;
38     int             iMaxProps;
39     const SCRIPT_PROPERTIES **ppSp;
40     HWND            hwnd;
41     HDC             hdc;
42
43     int             cInChars;
44     int             cMaxItems;
45     SCRIPT_ITEM     pItem[255];
46     int             pcItems;
47     WCHAR           TestItem1[6] = {'T', 'e', 's', 't', 'a', 0}; 
48     WCHAR           TestItem2[6] = {'T', 'e', 's', 't', 'b', 0}; 
49
50     SCRIPT_CACHE    psc;
51     int             cChars;
52     int             cMaxGlyphs;
53     unsigned short  pwOutGlyphs1[256];
54     unsigned short  pwOutGlyphs2[256];
55     unsigned short  pwLogClust[256];
56     SCRIPT_VISATTR  psva[256];
57     int             pcGlyphs;
58     int             piAdvance[256];
59     GOFFSET         pGoffset[256];
60     ABC             pABC[256];
61     LOGFONTW        lf;
62     HFONT           zfont;
63     int             cnt;
64
65     /* We need a valid HDC to drive a lot of Script functions which requires the following    *
66      * to set up for the tests.                                                               */
67     hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
68                            0, 0, 0, NULL);
69     assert(hwnd != 0);
70     ShowWindow(hwnd, SW_SHOW);
71     UpdateWindow(hwnd);
72
73     hdc = GetDC(hwnd);                                      /* We now have a hdc             */
74     ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
75
76     lstrcpyW(lf.lfFaceName, (WCHAR *) "Courier");
77     lf.lfHeight = 10;
78     lf.lfItalic = 0;
79     lf.lfEscapement = 0;
80     lf.lfOrientation = 0;
81     lf.lfUnderline = 0;
82     lf.lfStrikeOut = 0;
83     lf.lfWeight = 3;
84     lf.lfWidth = 10;
85
86     zfont = (HFONT) SelectObject(hdc, CreateFontIndirectW(&lf));
87
88     /* Start testing usp10 functions                                                         */
89     /* This test determines that the pointer returned by ScriptGetProperties is valid
90      * by checking a known value in the table                                                */
91     hr = ScriptGetProperties(&ppSp, &iMaxProps);
92     trace("number of script properties %d\n", iMaxProps);
93     ok (iMaxProps > 0, "Number of scripts returned should not be 0\n"); 
94     if  (iMaxProps > 0)
95          ok( ppSp[5]->langid == 9, "Langid[5] not = to 9\n"); /* Check a known value to ensure   */
96                                                               /* ptrs work                       */
97
98
99     /* This set of tests are to check that the various edits in ScriptIemize work           */
100     cInChars = 5;                                        /* Length of test without NULL     */
101     cMaxItems = 1;                                       /* Check threshold value           */
102     hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
103     ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2.  Was %d\n",
104         cMaxItems);
105     cInChars = 5;
106     cMaxItems = 255;
107     hr = ScriptItemize(NULL, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
108     ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n");
109
110     cInChars = 5;
111     cMaxItems = 255;
112     hr = ScriptItemize(TestItem1, 0, cMaxItems, NULL, NULL, pItem, &pcItems);
113     ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n");
114
115     cInChars = 5;
116     cMaxItems = 255;
117     hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, NULL, &pcItems);
118     ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n");
119
120     /* This is a valid test that will cause parsing to take place                             */
121     cInChars = 5;
122     cMaxItems = 255;
123     hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
124     ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr);
125     /*  This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is *
126      *  returned.                                                                             */
127     ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n");
128     if (pcItems > 0)
129         ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
130             "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
131             pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
132
133     /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue
134      * ie. ScriptItemize has succeeded and that pItem has been set                            */
135     cInChars = 5;
136     cMaxItems = 255;
137     if (hr == 0) {
138         psc = NULL;                                   /* must be null on first call           */
139         cChars = cInChars;
140         cMaxGlyphs = cInChars;
141         hr = ScriptShape(NULL, &psc, TestItem1, cChars,
142                          cMaxGlyphs, &pItem[0].a,
143                          pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
144         ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n",
145                         (unsigned int) hr);
146         cMaxGlyphs = 4;
147         hr = ScriptShape(hdc, &psc, TestItem1, cChars,
148                          cMaxGlyphs, &pItem[0].a,
149                          pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
150         ok (hr == E_OUTOFMEMORY, "If not enough output area cChars (%d) is > than CMaxGlyphs "
151                                  "(%d) but not E_OUTOFMEMORY\n",
152                                  cChars, cMaxGlyphs);
153         cMaxGlyphs = 256;
154         hr = ScriptShape(hdc, &psc, TestItem1, cChars,
155                          cMaxGlyphs, &pItem[0].a,
156                          pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
157         ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
158         ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
159         ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
160         if (hr ==0) {
161             hr = ScriptPlace(hdc, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
162                              pGoffset, pABC);
163             ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
164             hr = ScriptPlace(NULL, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
165                              pGoffset, pABC);
166             ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
167             for (cnt=0; cnt < pcGlyphs; cnt++)
168                 pwOutGlyphs[cnt] = pwOutGlyphs1[cnt];                 /* Send to next function */
169         }
170
171         /* This test will check to make sure that SCRIPT_CACHE is reused and that not translation   *
172          * takes place if fNoGlyphIndex is set.                                                     */
173
174         cInChars = 5;
175         cMaxItems = 255;
176         hr = ScriptItemize(TestItem2, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
177         ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr);
178         /*  This test is for the intertrim operation of ScriptItemize where only one SCRIPT_ITEM is *
179          *  returned.                                                                               */
180         ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
181                             "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
182                              pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
183         /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue                    */
184         if (hr == 0) {
185              cChars = cInChars;
186              cMaxGlyphs = 256;
187              pItem[0].a.fNoGlyphIndex = 1;                /* say no translate                     */
188              hr = ScriptShape(NULL, &psc, TestItem2, cChars,
189                               cMaxGlyphs, &pItem[0].a,
190                               pwOutGlyphs2, pwLogClust, psva, &pcGlyphs);
191              ok (hr != E_PENDING, "If psc should not be NULL (%08x) and the E_PENDING should be returned\n",
192                 (unsigned int) hr);
193              ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
194              ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
195              ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
196              for (cnt=0; cnt < cChars && TestItem2[cnt] == pwOutGlyphs2[cnt]; cnt++) {}
197              ok (cnt == cChars, "Translation to place when told not to. WCHAR %d - %04x != %04x\n",
198                            cnt, TestItem2[cnt], pwOutGlyphs2[cnt]);
199              if (hr ==0) {
200                  hr = ScriptPlace(hdc, &psc, pwOutGlyphs2, pcGlyphs, psva, &pItem[0].a, piAdvance,
201                                   pGoffset, pABC);
202                  ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
203              }
204         }
205         hr = ScriptFreeCache( &psc);
206         ok (!psc, "psc is not null after ScriptFreeCache\n");
207
208
209     }
210     ReleaseDC(hwnd, hdc);
211     DestroyWindow(hwnd);
212 }
213
214 void test_ScriptGetCMap(unsigned short pwOutGlyphs[256])
215 {
216     HRESULT         hr;
217     HWND            hwnd;
218     HDC             hdc;
219     SCRIPT_CACHE    psc = NULL;
220     int             cInChars;
221     int             cChars;
222     unsigned short  pwOutGlyphs3[256];
223     WCHAR           TestItem1[6] = {'T', 'e', 's', 't', 'a', 0}; 
224     DWORD           dwFlags;
225     int             cnt;
226
227     /* We need a valid HDC to drive a lot of Script functions which requires the following    *
228      * to set up for the tests.                                                               */
229     hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
230                            0, 0, 0, NULL);
231     assert(hwnd != 0);
232
233     hdc = GetDC(hwnd);
234     ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
235
236     /*  Check to make sure that SCRIPT_CACHE gets allocated ok                     */
237     dwFlags = 0;
238     cInChars = cChars = 5;
239     /* Some sanity checks for ScriptGetCMap */
240
241     hr = ScriptGetCMap(NULL, NULL, NULL, 0, 0, NULL);
242     ok( hr == E_INVALIDARG, "(NULL,NULL,NULL,0,0,NULL), "
243                             "expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
244
245     hr = ScriptGetCMap(NULL, NULL, TestItem1, cInChars, dwFlags, pwOutGlyphs3);
246     ok( hr == E_INVALIDARG, "(NULL,NULL,TestItem1, cInChars, dwFlags, pwOutGlyphs3), "
247                             "expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
248
249     /* Set psc to NULL, to be able to check if a pointer is returned in psc */
250     psc = NULL;
251     hr = ScriptGetCMap(NULL, &psc, NULL, 0, 0, NULL);
252     ok( hr == E_PENDING, "(NULL,&psc,NULL,0,0NULL), expected E_PENDING, "
253                          "got %08x\n", (unsigned int)hr);
254     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
255
256     /* Set psc to NULL but add hdc, to be able to check if a pointer is returned in psc */
257     psc = NULL;
258     hr = ScriptGetCMap(hdc, &psc, NULL, 0, 0, NULL);
259     ok( hr == S_OK, "ScriptGetCMap(NULL,&psc,NULL,0,0,NULL), expected S_OK, "
260                     "got %08x\n", (unsigned int)hr);
261     ok( psc != NULL, "ScritpGetCMap expected psc to be not NULL\n");
262
263     /* Set psc to NULL, to be able to check if a pointer is returned in psc */
264     psc = NULL;
265     hr = ScriptGetCMap(NULL, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3);
266     ok( hr == E_PENDING, "(NULL,&psc,), expected E_PENDING, got %08x\n", (unsigned int)hr);
267     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
268     /*  Check to see if the results are the same as those returned by ScriptShape  */
269     hr = ScriptGetCMap(hdc, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3);
270     ok (hr == 0, "ScriptGetCMap should return 0 not (%08x)\n", (unsigned int) hr);
271     ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
272     for (cnt=0; cnt < cChars && pwOutGlyphs[cnt] == pwOutGlyphs3[cnt]; cnt++) {}
273     ok (cnt == cInChars, "Translation not correct. WCHAR %d - %04x != %04x\n",
274                          cnt, pwOutGlyphs[cnt], pwOutGlyphs3[cnt]);
275         
276     hr = ScriptFreeCache( &psc);
277     ok (!psc, "psc is not null after ScriptFreeCache\n");
278 }
279
280 void test_ScriptGetFontProperties(void)
281 {
282     HRESULT         hr;
283     HDC             hdc;
284     HWND            hwnd;
285     SCRIPT_CACHE    psc,old_psc;
286     SCRIPT_FONTPROPERTIES sfp;
287
288     /* Only do the bare minumum to get a valid hdc */
289     hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
290     assert(hwnd != 0);
291
292     hdc = GetDC(hwnd);
293     ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
294
295     /* Some sanity checks for ScriptGetFontProperties */
296
297     hr = ScriptGetFontProperties(NULL,NULL,NULL);
298     ok( hr == E_INVALIDARG, "(NULL,NULL,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
299
300     hr = ScriptGetFontProperties(NULL,NULL,&sfp);
301     ok( hr == E_INVALIDARG, "(NULL,NULL,&sfp), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
302
303     /* Set psc to NULL, to be able to check if a pointer is returned in psc */
304     psc = NULL;
305     hr = ScriptGetFontProperties(NULL,&psc,NULL);
306     ok( hr == E_INVALIDARG, "(NULL,&psc,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
307     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
308
309     /* Set psc to NULL, to be able to check if a pointer is returned in psc */
310     psc = NULL;
311     hr = ScriptGetFontProperties(NULL,&psc,&sfp);
312     ok( hr == E_PENDING, "(NULL,&psc,&sfp), expected E_PENDING, got %08x\n", (unsigned int)hr);
313     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
314
315     hr = ScriptGetFontProperties(hdc,NULL,NULL);
316     ok( hr == E_INVALIDARG, "(hdc,NULL,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
317
318     hr = ScriptGetFontProperties(hdc,NULL,&sfp);
319     ok( hr == E_INVALIDARG, "(hdc,NULL,&sfp), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
320
321     /* Set psc to NULL, to be able to check if a pointer is returned in psc */
322     psc = NULL;
323     hr = ScriptGetFontProperties(hdc,&psc,NULL);
324     ok( hr == E_INVALIDARG, "(hdc,&psc,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
325     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
326
327     /* Pass an uninitialized sfp */
328     psc = NULL;
329     hr = ScriptGetFontProperties(hdc,&psc,&sfp);
330     ok( hr == E_INVALIDARG, "(hdc,&psc,&sfp) partly uninitialized, expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
331     ok( psc != NULL, "Expected a pointer in psc, got NULL\n");
332     ScriptFreeCache(&psc);
333     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
334
335     /* Give it the correct cBytes, we don't care about what's coming back */
336     sfp.cBytes = sizeof(SCRIPT_FONTPROPERTIES);
337     psc = NULL;
338     hr = ScriptGetFontProperties(hdc,&psc,&sfp);
339     ok( hr == S_OK, "(hdc,&psc,&sfp) partly initialized, expected S_OK, got %08x\n", (unsigned int)hr);
340     ok( psc != NULL, "Expected a pointer in psc, got NULL\n");
341
342     /* Save the psc pointer */
343     old_psc = psc;
344     /* Now a NULL hdc again */
345     hr = ScriptGetFontProperties(NULL,&psc,&sfp);
346     ok( hr == S_OK, "(NULL,&psc,&sfp), expected S_OK, got %08x\n", (unsigned int)hr);
347     ok( psc == old_psc, "Expected psc not to be changed, was %p is now %p\n", old_psc, psc);
348     ScriptFreeCache(&psc);
349     ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
350
351     /* Cleanup */
352     ReleaseDC(hwnd, hdc);
353     DestroyWindow(hwnd);
354 }
355
356 void test_ScriptTextOut(void)
357 {
358     HRESULT         hr;
359     HWND            hwnd;
360     HDC             hdc;
361
362     int             cInChars;
363     int             cMaxItems;
364     SCRIPT_ITEM     pItem[255];
365     int             pcItems;
366     WCHAR           TestItem1[6] = {'T', 'e', 's', 't', 'a', 0}; 
367
368     SCRIPT_CACHE    psc;
369     int             cChars;
370     int             cMaxGlyphs;
371     unsigned short  pwOutGlyphs1[256];
372     WORD            pwLogClust[256];
373     SCRIPT_VISATTR  psva[256];
374     int             pcGlyphs;
375     int             piAdvance[256];
376     GOFFSET         pGoffset[256];
377     ABC             pABC[256];
378     RECT            rect;
379     int             piX;
380     int             iCP = 1;
381     BOOL            fTrailing = FALSE;
382     SCRIPT_LOGATTR  *psla;
383     SCRIPT_LOGATTR  sla[256];
384
385     /* We need a valid HDC to drive a lot of Script functions which requires the following    *
386      * to set up for the tests.                                                               */
387     hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
388                            0, 0, 0, NULL);
389     assert(hwnd != 0);
390     ShowWindow(hwnd, SW_SHOW);
391     UpdateWindow(hwnd);
392
393     hdc = GetDC(hwnd);                                      /* We now have a hdc             */
394     ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
395
396     /* This is a valid test that will cause parsing to take place                             */
397     cInChars = 5;
398     cMaxItems = 255;
399     hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
400     ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr);
401     /*  This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is *
402      *  returned.                                                                             */
403     ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n");
404     if (pcItems > 0)
405         ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
406             "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
407             pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
408
409     /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue
410      * ie. ScriptItemize has succeeded and that pItem has been set                            */
411     cInChars = 5;
412     cMaxItems = 255;
413     if (hr == 0) {
414         psc = NULL;                                   /* must be null on first call           */
415         cChars = cInChars;
416         cMaxGlyphs = cInChars;
417         cMaxGlyphs = 256;
418         hr = ScriptShape(hdc, &psc, TestItem1, cChars,
419                          cMaxGlyphs, &pItem[0].a,
420                          pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
421         ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
422         ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
423         ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
424         if (hr ==0) {
425             /* Note hdc is needed as glyph info is not yet in psc                  */
426             hr = ScriptPlace(hdc, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
427                              pGoffset, pABC);
428             ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr);
429             ScriptFreeCache(&psc);              /* Get rid of psc for next test set */
430             ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
431
432             hr = ScriptTextOut(NULL, NULL, 0, 0, 0, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL);
433             ok (hr == E_INVALIDARG, "Should return 0 not (%08x)\n", (unsigned int) hr);
434
435             hr = ScriptTextOut(NULL, NULL, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
436                                piAdvance, NULL, pGoffset);
437             ok( hr == E_INVALIDARG, "(NULL,NULL,TestItem1, cInChars, dwFlags, pwOutGlyphs3), "
438                                     "expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
439
440             /* Set psc to NULL, to be able to check if a pointer is returned in psc */
441             psc = NULL;
442             hr = ScriptTextOut(NULL, &psc, 0, 0, 0, NULL, NULL, NULL, 0, NULL, 0,
443                                NULL, NULL, NULL);
444             ok( hr == E_INVALIDARG, "(NULL,&psc,NULL,0,0,0,NULL,), expected E_INVALIDARG, "
445                                     "got %08x\n", (unsigned int)hr);
446             ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
447
448             /* Set psc to NULL, to be able to check if a pointer is returned in psc
449              * hdc is required for this one rather than the usual optional          */
450             psc = NULL;
451             hr = ScriptTextOut(NULL, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
452                                piAdvance, NULL, pGoffset);
453             ok( hr == E_INVALIDARG, "(NULL,&psc,), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
454             ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
455
456             /* Set that is gets a psc and that returns 0 status */
457             hr = ScriptTextOut(hdc, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
458                                piAdvance, NULL, pGoffset);
459             ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", (unsigned int) hr);
460             ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
461
462             /* Test Rect Rgn is acceptable */
463             rect.top = 10;
464             rect.bottom = 20;
465             rect.left = 10;
466             rect.right = 40;
467             hr = ScriptTextOut(hdc, &psc, 0, 0, 0, &rect, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
468                                piAdvance, NULL, pGoffset);
469             ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", (unsigned int) hr);
470             ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
471
472             iCP = 1;
473             hr = ScriptCPtoX(iCP, fTrailing, cChars, pcGlyphs, (const WORD *) &pwLogClust,
474                             (const SCRIPT_VISATTR *) &psva, (const int *)&piAdvance, &pItem[0].a, &piX);
475             ok(hr == S_OK, "ScriptCPtoX Stub should return S_OK not %08x\n", (unsigned int) hr);
476
477             psla = (SCRIPT_LOGATTR *)&sla;
478             hr = ScriptBreak(TestItem1, cChars, &pItem[0].a, psla);
479             ok(hr == S_OK, "ScriptBreak Stub should return S_OK not %08x\n", (unsigned int) hr);
480
481             /* Clean up and go   */
482             ScriptFreeCache(&psc);
483             ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
484         }
485     }
486     ReleaseDC(hwnd, hdc);
487     DestroyWindow(hwnd);
488 }
489
490 static void test_ScriptString(void)
491 {
492     HRESULT         hr;
493     HWND            hwnd;
494     HDC             hdc = 0;
495     WCHAR           teststr[6] = {'T', 'e', 's', 't', 'a', '\0'};
496     void            *pString = (WCHAR *) &teststr;
497     int             cString = 5;
498     int             cGlyphs = cString * 2 + 16;
499     int             iCharset = -1;
500     DWORD           dwFlags = SSA_GLYPHS;
501     int             iReqWidth = 100;
502     SCRIPT_CONTROL  psControl;
503     SCRIPT_STATE    psState;
504     const int       piDx[5] = {10, 10, 10, 10, 10};
505     SCRIPT_TABDEF   pTabdef;
506     const BYTE      pbInClass = 0;
507     SCRIPT_STRING_ANALYSIS pssa = NULL;
508
509     int             iX = 10; 
510     int             iY = 100;
511     UINT            uOptions = 0; 
512     const RECT      prc = {0, 50, 100, 100}; 
513     int             iMinSel = 0; 
514     int             iMaxSel = 0;
515     BOOL            fDisabled = FALSE;
516
517     LOGFONTW        lf;
518     HFONT           zfont;
519
520     /* We need a valid HDC to drive a lot of Script functions which requires the following    *
521      * to set up for the tests.                                                               */
522     hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
523                            0, 0, 0, NULL);
524     assert(hwnd != 0);
525
526     hdc = GetDC(hwnd);                                      /* We now have a hdc             */
527     ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
528
529     lstrcpyW(lf.lfFaceName, (WCHAR *) "Courier");
530     lf.lfHeight = 10;
531     lf.lfItalic = 0;
532     lf.lfEscapement = 0;
533     lf.lfOrientation = 0;
534     lf.lfUnderline = 0;
535     lf.lfStrikeOut = 0;
536     lf.lfWeight = 3;
537     lf.lfWidth = 10;
538
539     zfont = (HFONT) SelectObject(hdc, CreateFontIndirectW(&lf));
540
541     /* Test without hdc to get E_INVALIDARG */
542     hr = ScriptStringAnalyse( NULL, pString, cString, cGlyphs, iCharset, dwFlags,
543                              iReqWidth, &psControl, &psState, piDx, &pTabdef,
544                              &pbInClass, &pssa);
545     ok(hr == E_PENDING, "ScriptStringAnalyse Stub should return E_PENDING not %08x\n", (unsigned int) hr);
546
547     /* test with hdc, this should be a valid test  */
548     hr = ScriptStringAnalyse( hdc, pString, cString, cGlyphs, iCharset, dwFlags,
549                               iReqWidth, &psControl, &psState, piDx, &pTabdef,
550                               &pbInClass, &pssa);
551     ok(hr == E_NOTIMPL, "ScriptStringAnalyse Stub should return E_NOTIMPL not %08x\n", (unsigned int) hr);
552 /*    Commented code it pending new code in ScriptStringAnalysis */
553 /*    ok(hr == S_OK, "ScriptStringAnalyse Stub should return S_OK not %08x\n", (unsigned int) hr);*/
554 /*    ok(pssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");*/
555     if  (hr == 0)
556     {
557         hr = ScriptStringOut(pssa, iX, iY, uOptions, &prc, iMinSel, iMaxSel,fDisabled);
558         ok(hr == E_NOTIMPL, "ScriptStringOut Stub should return E_NOTIMPL not %08x\n", (unsigned int) hr);
559         hr = ScriptStringFree(&pssa);
560         ok(hr == S_OK, "ScriptStringFree Stub should return S_OK not %08x\n", (unsigned int) hr);
561     }
562 }
563
564 START_TEST(usp10)
565 {
566     unsigned short  pwOutGlyphs[256];
567
568     test_ScriptItemIzeShapePlace(pwOutGlyphs);
569     test_ScriptGetCMap(pwOutGlyphs);
570     test_ScriptGetFontProperties();
571     test_ScriptTextOut();
572     test_ScriptString();
573 }