4 * Copyright 2006 Jeff Latimer
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.
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.
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
21 * Uniscribe allows for processing of complex scripts such as joining
22 * and filtering characters and bi-directional text with custom line breaks.
28 #include <wine/test.h>
35 static void test_ScriptItemIzeShapePlace(HDC hdc, unsigned short pwOutGlyphs[256])
39 const SCRIPT_PROPERTIES **ppSp;
43 SCRIPT_ITEM pItem[255];
45 WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0};
46 WCHAR TestItem2[] = {'T', 'e', 's', 't', 'b', 0};
51 unsigned short pwOutGlyphs1[256];
52 unsigned short pwOutGlyphs2[256];
53 unsigned short pwLogClust[256];
54 SCRIPT_VISATTR psva[256];
57 GOFFSET pGoffset[256];
64 lstrcpyA(lf.lfFaceName, "Symbol");
74 zfont = (HFONT) SelectObject(hdc, CreateFontIndirectA(&lf));
76 /* Start testing usp10 functions */
77 /* This test determines that the pointer returned by ScriptGetProperties is valid
78 * by checking a known value in the table */
79 hr = ScriptGetProperties(&ppSp, &iMaxProps);
80 trace("number of script properties %d\n", iMaxProps);
81 ok (iMaxProps > 0, "Number of scripts returned should not be 0\n");
83 ok( ppSp[5]->langid == 9, "Langid[5] not = to 9\n"); /* Check a known value to ensure */
87 /* This set of tests are to check that the various edits in ScriptIemize work */
88 cInChars = 5; /* Length of test without NULL */
89 cMaxItems = 1; /* Check threshold value */
90 hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
91 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2. Was %d\n",
95 hr = ScriptItemize(NULL, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
96 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n");
100 hr = ScriptItemize(TestItem1, 0, cMaxItems, NULL, NULL, pItem, &pcItems);
101 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n");
105 hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, NULL, &pcItems);
106 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n");
108 /* This is a valid test that will cause parsing to take place */
111 hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
112 ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr);
113 /* This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is *
115 ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n");
117 ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
118 "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
119 pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
121 /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue
122 * ie. ScriptItemize has succeeded and that pItem has been set */
126 psc = NULL; /* must be null on first call */
128 cMaxGlyphs = cInChars;
129 hr = ScriptShape(NULL, &psc, TestItem1, cChars,
130 cMaxGlyphs, &pItem[0].a,
131 pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
132 ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n",
135 hr = ScriptShape(hdc, &psc, TestItem1, cChars,
136 cMaxGlyphs, &pItem[0].a,
137 pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
138 ok (hr == E_OUTOFMEMORY, "If not enough output area cChars (%d) is > than CMaxGlyphs "
139 "(%d) but not E_OUTOFMEMORY\n",
142 hr = ScriptShape(hdc, &psc, TestItem1, cChars,
143 cMaxGlyphs, &pItem[0].a,
144 pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
145 ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
146 ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
147 ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
149 hr = ScriptPlace(hdc, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
151 ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
152 hr = ScriptPlace(NULL, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
154 ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
155 for (cnt=0; cnt < pcGlyphs; cnt++)
156 pwOutGlyphs[cnt] = pwOutGlyphs1[cnt]; /* Send to next function */
159 /* This test will check to make sure that SCRIPT_CACHE is reused and that not translation *
160 * takes place if fNoGlyphIndex is set. */
164 hr = ScriptItemize(TestItem2, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
165 ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr);
166 /* This test is for the intertrim operation of ScriptItemize where only one SCRIPT_ITEM is *
168 ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
169 "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
170 pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
171 /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue */
175 pItem[0].a.fNoGlyphIndex = 1; /* say no translate */
176 hr = ScriptShape(NULL, &psc, TestItem2, cChars,
177 cMaxGlyphs, &pItem[0].a,
178 pwOutGlyphs2, pwLogClust, psva, &pcGlyphs);
179 ok (hr != E_PENDING, "If psc should not be NULL (%08x) and the E_PENDING should be returned\n",
181 ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
182 ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
183 ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
184 for (cnt=0; cnt < cChars && TestItem2[cnt] == pwOutGlyphs2[cnt]; cnt++) {}
185 ok (cnt == cChars, "Translation to place when told not to. WCHAR %d - %04x != %04x\n",
186 cnt, TestItem2[cnt], pwOutGlyphs2[cnt]);
188 hr = ScriptPlace(hdc, &psc, pwOutGlyphs2, pcGlyphs, psva, &pItem[0].a, piAdvance,
190 ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
193 hr = ScriptFreeCache( &psc);
194 ok (!psc, "psc is not null after ScriptFreeCache\n");
199 void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256])
202 SCRIPT_CACHE psc = NULL;
205 unsigned short pwOutGlyphs3[256];
206 WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0};
210 /* Check to make sure that SCRIPT_CACHE gets allocated ok */
212 cInChars = cChars = 5;
213 /* Some sanity checks for ScriptGetCMap */
215 hr = ScriptGetCMap(NULL, NULL, NULL, 0, 0, NULL);
216 ok( hr == E_INVALIDARG, "(NULL,NULL,NULL,0,0,NULL), "
217 "expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
219 hr = ScriptGetCMap(NULL, NULL, TestItem1, cInChars, dwFlags, pwOutGlyphs3);
220 ok( hr == E_INVALIDARG, "(NULL,NULL,TestItem1, cInChars, dwFlags, pwOutGlyphs3), "
221 "expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
223 /* Set psc to NULL, to be able to check if a pointer is returned in psc */
225 hr = ScriptGetCMap(NULL, &psc, NULL, 0, 0, NULL);
226 ok( hr == E_PENDING, "(NULL,&psc,NULL,0,0NULL), expected E_PENDING, "
227 "got %08x\n", (unsigned int)hr);
228 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
230 /* Set psc to NULL but add hdc, to be able to check if a pointer is returned in psc */
232 hr = ScriptGetCMap(hdc, &psc, NULL, 0, 0, NULL);
233 ok( hr == S_OK, "ScriptGetCMap(NULL,&psc,NULL,0,0,NULL), expected S_OK, "
234 "got %08x\n", (unsigned int)hr);
235 ok( psc != NULL, "ScritpGetCMap expected psc to be not NULL\n");
237 /* Set psc to NULL, to be able to check if a pointer is returned in psc */
239 hr = ScriptGetCMap(NULL, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3);
240 ok( hr == E_PENDING, "(NULL,&psc,), expected E_PENDING, got %08x\n", (unsigned int)hr);
241 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
242 /* Check to see if the results are the same as those returned by ScriptShape */
243 hr = ScriptGetCMap(hdc, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3);
244 ok (hr == 0, "ScriptGetCMap should return 0 not (%08x)\n", (unsigned int) hr);
245 ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
246 for (cnt=0; cnt < cChars && pwOutGlyphs[cnt] == pwOutGlyphs3[cnt]; cnt++) {}
247 ok (cnt == cInChars, "Translation not correct. WCHAR %d - %04x != %04x\n",
248 cnt, pwOutGlyphs[cnt], pwOutGlyphs3[cnt]);
250 hr = ScriptFreeCache( &psc);
251 ok (!psc, "psc is not null after ScriptFreeCache\n");
255 void test_ScriptGetFontProperties(void)
260 SCRIPT_CACHE psc,old_psc;
261 SCRIPT_FONTPROPERTIES sfp;
263 /* Only do the bare minumum to get a valid hdc */
264 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,0, 0, 0, NULL);
268 ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
270 /* Some sanity checks for ScriptGetFontProperties */
272 hr = ScriptGetFontProperties(NULL,NULL,NULL);
273 ok( hr == E_INVALIDARG, "(NULL,NULL,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
275 hr = ScriptGetFontProperties(NULL,NULL,&sfp);
276 ok( hr == E_INVALIDARG, "(NULL,NULL,&sfp), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
278 /* Set psc to NULL, to be able to check if a pointer is returned in psc */
280 hr = ScriptGetFontProperties(NULL,&psc,NULL);
281 ok( hr == E_INVALIDARG, "(NULL,&psc,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
282 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
284 /* Set psc to NULL, to be able to check if a pointer is returned in psc */
286 hr = ScriptGetFontProperties(NULL,&psc,&sfp);
287 ok( hr == E_PENDING, "(NULL,&psc,&sfp), expected E_PENDING, got %08x\n", (unsigned int)hr);
288 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
290 hr = ScriptGetFontProperties(hdc,NULL,NULL);
291 ok( hr == E_INVALIDARG, "(hdc,NULL,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
293 hr = ScriptGetFontProperties(hdc,NULL,&sfp);
294 ok( hr == E_INVALIDARG, "(hdc,NULL,&sfp), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
296 /* Set psc to NULL, to be able to check if a pointer is returned in psc */
298 hr = ScriptGetFontProperties(hdc,&psc,NULL);
299 ok( hr == E_INVALIDARG, "(hdc,&psc,NULL), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
300 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
302 /* Pass an uninitialized sfp */
304 hr = ScriptGetFontProperties(hdc,&psc,&sfp);
305 ok( hr == E_INVALIDARG, "(hdc,&psc,&sfp) partly uninitialized, expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
306 ok( psc != NULL, "Expected a pointer in psc, got NULL\n");
307 ScriptFreeCache(&psc);
308 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
310 /* Give it the correct cBytes, we don't care about what's coming back */
311 sfp.cBytes = sizeof(SCRIPT_FONTPROPERTIES);
313 hr = ScriptGetFontProperties(hdc,&psc,&sfp);
314 ok( hr == S_OK, "(hdc,&psc,&sfp) partly initialized, expected S_OK, got %08x\n", (unsigned int)hr);
315 ok( psc != NULL, "Expected a pointer in psc, got NULL\n");
317 /* Save the psc pointer */
319 /* Now a NULL hdc again */
320 hr = ScriptGetFontProperties(NULL,&psc,&sfp);
321 ok( hr == S_OK, "(NULL,&psc,&sfp), expected S_OK, got %08x\n", (unsigned int)hr);
322 ok( psc == old_psc, "Expected psc not to be changed, was %p is now %p\n", old_psc, psc);
323 ScriptFreeCache(&psc);
324 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
327 ReleaseDC(hwnd, hdc);
331 void test_ScriptTextOut(void)
339 SCRIPT_ITEM pItem[255];
341 WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0};
346 unsigned short pwOutGlyphs1[256];
347 WORD pwLogClust[256];
348 SCRIPT_VISATTR psva[256];
351 GOFFSET pGoffset[256];
356 BOOL fTrailing = FALSE;
357 SCRIPT_LOGATTR *psla;
358 SCRIPT_LOGATTR sla[256];
360 /* We need a valid HDC to drive a lot of Script functions which requires the following *
361 * to set up for the tests. */
362 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
365 ShowWindow(hwnd, SW_SHOW);
368 hdc = GetDC(hwnd); /* We now have a hdc */
369 ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
371 /* This is a valid test that will cause parsing to take place */
374 hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
375 ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr);
376 /* This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is *
378 ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n");
380 ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars,
381 "Start pos not = 0 (%d) or end pos not = %d (%d)\n",
382 pItem[0].iCharPos, cInChars, pItem[1].iCharPos);
384 /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue
385 * ie. ScriptItemize has succeeded and that pItem has been set */
389 psc = NULL; /* must be null on first call */
391 cMaxGlyphs = cInChars;
393 hr = ScriptShape(hdc, &psc, TestItem1, cChars,
394 cMaxGlyphs, &pItem[0].a,
395 pwOutGlyphs1, pwLogClust, psva, &pcGlyphs);
396 ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
397 ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
398 ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
400 /* Note hdc is needed as glyph info is not yet in psc */
401 hr = ScriptPlace(hdc, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance,
403 ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr);
404 ScriptFreeCache(&psc); /* Get rid of psc for next test set */
405 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
407 hr = ScriptTextOut(NULL, NULL, 0, 0, 0, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL);
408 ok (hr == E_INVALIDARG, "Should return 0 not (%08x)\n", (unsigned int) hr);
410 hr = ScriptTextOut(NULL, NULL, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
411 piAdvance, NULL, pGoffset);
412 ok( hr == E_INVALIDARG, "(NULL,NULL,TestItem1, cInChars, dwFlags, pwOutGlyphs3), "
413 "expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
415 /* Set psc to NULL, to be able to check if a pointer is returned in psc */
417 hr = ScriptTextOut(NULL, &psc, 0, 0, 0, NULL, NULL, NULL, 0, NULL, 0,
419 ok( hr == E_INVALIDARG, "(NULL,&psc,NULL,0,0,0,NULL,), expected E_INVALIDARG, "
420 "got %08x\n", (unsigned int)hr);
421 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
423 /* Set psc to NULL, to be able to check if a pointer is returned in psc
424 * hdc is required for this one rather than the usual optional */
426 hr = ScriptTextOut(NULL, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
427 piAdvance, NULL, pGoffset);
428 ok( hr == E_INVALIDARG, "(NULL,&psc,), expected E_INVALIDARG, got %08x\n", (unsigned int)hr);
429 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
431 /* Set that is gets a psc and that returns 0 status */
432 hr = ScriptTextOut(hdc, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
433 piAdvance, NULL, pGoffset);
434 ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", (unsigned int) hr);
435 ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
437 /* Test Rect Rgn is acceptable */
442 hr = ScriptTextOut(hdc, &psc, 0, 0, 0, &rect, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs,
443 piAdvance, NULL, pGoffset);
444 ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", (unsigned int) hr);
445 ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
448 hr = ScriptCPtoX(iCP, fTrailing, cChars, pcGlyphs, (const WORD *) &pwLogClust,
449 (const SCRIPT_VISATTR *) &psva, (const int *)&piAdvance, &pItem[0].a, &piX);
450 ok(hr == S_OK, "ScriptCPtoX Stub should return S_OK not %08x\n", (unsigned int) hr);
452 psla = (SCRIPT_LOGATTR *)&sla;
453 hr = ScriptBreak(TestItem1, cChars, &pItem[0].a, psla);
454 ok(hr == S_OK, "ScriptBreak Stub should return S_OK not %08x\n", (unsigned int) hr);
456 /* Clean up and go */
457 ScriptFreeCache(&psc);
458 ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc);
461 ReleaseDC(hwnd, hdc);
465 static void test_ScriptXtoX(void)
466 /****************************************************************************************
467 * This routine tests the ScriptXtoCP and ScriptCPtoX functions using static variables *
468 ****************************************************************************************/
473 WORD pwLogClust[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
474 SCRIPT_VISATTR psva[10];
475 int piAdvance[10] = {200, 190, 210, 180, 170, 204, 189, 195, 212, 203};
485 hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing);
486 ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr);
487 ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP);
488 ok(piTrailing == TRUE, "Negative iX should return piTrailing=TRUE not %d", piTrailing);
492 hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing);
493 ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr);
494 ok(piCP == 10, "Excessive iX should return piCP=10 not %d\n", piCP);
495 ok(piTrailing == FALSE, "Excessive iX should return piTrailing=FALSE not %d\n", piTrailing);
499 hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing);
500 ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr);
501 ok(piCP == 3, "iX=%d should return piCP=3 not %d\n", iX, piCP);
502 ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing);
506 hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing);
507 ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr);
508 ok(piCP == 3, "iX=%d should return piCP=3 not %d\n", iX, piCP);
509 ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing);
513 hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing);
514 ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr);
515 ok(piCP == 4, "iX=%d should return piCP=4 not %d\n", iX, piCP);
521 hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX);
522 ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr);
523 ok(piX == 976, "iCP=%d should return piX=976 not %d\n", iCP, piX);
528 hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX);
529 ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr);
530 ok(piX == 1171, "iCP=%d should return piX=1171 not %d\n", iCP, piX);
535 hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX);
536 ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr);
537 ok(piX == 1171, "iCP=%d should return piX=1171 not %d\n", iCP, piX);
542 hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX);
543 ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr);
544 ok(piX == 1953, "iCP=%d should return piX=1953 not %d\n", iCP, piX);
549 hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX);
550 ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr);
551 ok(piX == 1953, "iCP=%d should return piX=1953 not %d\n", iCP, piX);
555 static void test_ScriptString(void)
560 WCHAR teststr[] = {'T', 'e', 's', 't', 'a', '\0'};
561 void *pString = (WCHAR *) &teststr;
563 int cGlyphs = cString * 2 + 16;
565 DWORD dwFlags = SSA_GLYPHS;
567 SCRIPT_CONTROL psControl;
568 SCRIPT_STATE psState;
569 const int piDx[5] = {10, 10, 10, 10, 10};
570 SCRIPT_TABDEF pTabdef;
571 const BYTE pbInClass = 0;
572 SCRIPT_STRING_ANALYSIS pssa = NULL;
577 const RECT prc = {0, 50, 100, 100};
580 BOOL fDisabled = FALSE;
585 /* We need a valid HDC to drive a lot of Script functions which requires the following *
586 * to set up for the tests. */
587 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
591 hdc = GetDC(hwnd); /* We now have a hdc */
592 ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
594 lstrcpyA(lf.lfFaceName, "Symbol");
598 lf.lfOrientation = 0;
604 zfont = (HFONT) SelectObject(hdc, CreateFontIndirectA(&lf));
606 /* Test without hdc to get E_INVALIDARG */
607 hr = ScriptStringAnalyse( NULL, pString, cString, cGlyphs, iCharset, dwFlags,
608 iReqWidth, &psControl, &psState, piDx, &pTabdef,
610 ok(hr == E_PENDING, "ScriptStringAnalyse Stub should return E_PENDING not %08x\n", (unsigned int) hr);
612 /* test with hdc, this should be a valid test */
613 hr = ScriptStringAnalyse( hdc, pString, cString, cGlyphs, iCharset, dwFlags,
614 iReqWidth, &psControl, &psState, piDx, &pTabdef,
616 ok(hr == E_NOTIMPL, "ScriptStringAnalyse Stub should return E_NOTIMPL not %08x\n", (unsigned int) hr);
617 /* Commented code it pending new code in ScriptStringAnalysis */
618 /* ok(hr == S_OK, "ScriptStringAnalyse Stub should return S_OK not %08x\n", (unsigned int) hr);*/
619 /* ok(pssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");*/
622 hr = ScriptStringOut(pssa, iX, iY, uOptions, &prc, iMinSel, iMaxSel,fDisabled);
623 ok(hr == E_NOTIMPL, "ScriptStringOut Stub should return E_NOTIMPL not %08x\n", (unsigned int) hr);
624 hr = ScriptStringFree(&pssa);
625 ok(hr == S_OK, "ScriptStringFree Stub should return S_OK not %08x\n", (unsigned int) hr);
634 unsigned short pwOutGlyphs[256];
636 /* We need a valid HDC to drive a lot of Script functions which requires the following *
637 * to set up for the tests. */
638 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
641 ShowWindow(hwnd, SW_SHOW);
644 hdc = GetDC(hwnd); /* We now have a hdc */
645 ok( hdc != NULL, "HDC failed to be created %p\n", hdc);
647 test_ScriptItemIzeShapePlace(hdc,pwOutGlyphs);
648 test_ScriptGetCMap(hdc, pwOutGlyphs);
650 ReleaseDC(hwnd, hdc);
653 test_ScriptGetFontProperties();
654 test_ScriptTextOut();