From af67bc864e6940caf618fb742df47146b2305755 Mon Sep 17 00:00:00 2001 From: Jeff Latimer Date: Sun, 30 Apr 2006 23:44:30 +1000 Subject: [PATCH] usp10: Add ScriptTextOut functionality and restructure tests. --- dlls/usp10/tests/usp10.c | 398 +++++++++++++++++++++++++++------------ dlls/usp10/usp10.c | 47 ++++- 2 files changed, 323 insertions(+), 122 deletions(-) diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index f411ce8ce30..bf90b0fbb0a 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -32,6 +32,227 @@ #include #include +static void test_ScriptItemIzeShapePlace(unsigned short pwOutGlyphs[256]) +{ + HRESULT hr; + int iMaxProps; + const SCRIPT_PROPERTIES **ppSp; + HWND hwnd; + HDC hdc; + + int cInChars; + int cMaxItems; + SCRIPT_ITEM pItem[255]; + int pcItems; + WCHAR TestItem1[6] = {'T', 'e', 's', 't', 0x0166, 0}; + WCHAR TestItem2[6] = {'T', 'e', 's', 't', 0x0166, 0}; + + SCRIPT_CACHE psc; + int cChars; + int cMaxGlyphs; + unsigned short pwOutGlyphs1[256]; + unsigned short pwOutGlyphs2[256]; + unsigned short pwLogClust[256]; + SCRIPT_VISATTR psva[256]; + int pcGlyphs; + int piAdvance[256]; + GOFFSET pGoffset[256]; + ABC pABC[256]; + int cnt; + + /* We need a valid HDC to drive a lot of Script functions which requires the following * + * to set up for the tests. */ + hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100, + 0, 0, 0, NULL); + assert(hwnd != 0); + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + + hdc = GetDC(hwnd); /* We now have a hdc */ + ok( hdc != NULL, "HDC failed to be created %p\n", hdc); + + /* Start testing usp10 functions */ + /* This test determines that the pointer returned by ScriptGetProperties is valid + * by checking a known value in the table */ + hr = ScriptGetProperties(&ppSp, &iMaxProps); + trace("number of script properties %d\n", iMaxProps); + ok (iMaxProps > 0, "Number of scripts returned should not be 0\n"); + if (iMaxProps > 0) + ok( ppSp[5]->langid == 9, "Langid[5] not = to 9\n"); /* Check a known value to ensure */ + /* ptrs work */ + + + /* This set of tests are to check that the various edits in ScriptIemize work */ + cInChars = 5; /* Length of test without NULL */ + cMaxItems = 1; /* Check threshold value */ + hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2. Was %d\n", + cMaxItems); + cInChars = 5; + cMaxItems = 255; + hr = ScriptItemize(NULL, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n"); + + cInChars = 5; + cMaxItems = 255; + hr = ScriptItemize(TestItem1, 0, cMaxItems, NULL, NULL, pItem, &pcItems); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n"); + + cInChars = 5; + cMaxItems = 255; + hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, NULL, &pcItems); + ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n"); + + /* This is a valid test that will cause parsing to take place */ + cInChars = 5; + cMaxItems = 255; + hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); + ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr); + /* This test is for the interim operation of ScriptItemize where only one SCRIPT_ITEM is * + * returned. */ + ok (pcItems > 0, "The number of SCRIPT_ITEMS should be greater than 0\n"); + if (pcItems > 0) + ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars, + "Start pos not = 0 (%d) or end pos not = %d (%d)\n", + pItem[0].iCharPos, cInChars, pItem[1].iCharPos); + + /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue + * ie. ScriptItemize has succeeded and that pItem has been set */ + cInChars = 5; + cMaxItems = 255; + if (hr == 0) { + psc = NULL; /* must be null on first call */ + cChars = cInChars; + cMaxGlyphs = cInChars; + hr = ScriptShape(NULL, &psc, TestItem1, cChars, + cMaxGlyphs, &pItem[0].a, + pwOutGlyphs1, pwLogClust, psva, &pcGlyphs); + ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n", + (unsigned int) hr); + cMaxGlyphs = 4; + hr = ScriptShape(hdc, &psc, TestItem1, cChars, + cMaxGlyphs, &pItem[0].a, + pwOutGlyphs1, pwLogClust, psva, &pcGlyphs); + ok (hr == E_OUTOFMEMORY, "If not enough output area cChars (%d) is > than CMaxGlyphs " + "(%d) but not E_OUTOFMEMORY\n", + cChars, cMaxGlyphs); + cMaxGlyphs = 256; + hr = ScriptShape(hdc, &psc, TestItem1, cChars, + cMaxGlyphs, &pItem[0].a, + pwOutGlyphs1, pwLogClust, psva, &pcGlyphs); + ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs); + if (hr ==0) { + hr = ScriptPlace(NULL, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance, + pGoffset, pABC); + ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr); + for (cnt=0; cnt < pcGlyphs; cnt++) + pwOutGlyphs[cnt] = pwOutGlyphs1[cnt]; /* Send to next function */ + } + + /* This test will check to make sure that SCRIPT_CACHE is reused and that not translation * + * takes place if fNoGlyphIndex is set. */ + + cInChars = 5; + cMaxItems = 255; + hr = ScriptItemize(TestItem2, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); + ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr); + /* This test is for the intertrim operation of ScriptItemize where only one SCRIPT_ITEM is * + * returned. */ + ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars, + "Start pos not = 0 (%d) or end pos not = %d (%d)\n", + pItem[0].iCharPos, cInChars, pItem[1].iCharPos); + /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue */ + if (hr == 0) { + cChars = cInChars; + cMaxGlyphs = 256; + pItem[0].a.fNoGlyphIndex = 1; /* say no translate */ + hr = ScriptShape(NULL, &psc, TestItem2, cChars, + cMaxGlyphs, &pItem[0].a, + pwOutGlyphs2, pwLogClust, psva, &pcGlyphs); + ok (hr != E_PENDING, "If psc should not be NULL (%08x) and the E_PENDING should be returned\n", + (unsigned int) hr); + ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs); + for (cnt=0; cnt < cChars && TestItem2[cnt] == pwOutGlyphs2[cnt]; cnt++) {} + ok (cnt == cChars, "Translation to place when told not to. WCHAR %d - %04x != %04x\n", + cnt, TestItem2[cnt], pwOutGlyphs2[cnt]); + if (hr ==0) { + hr = ScriptPlace(NULL, &psc, pwOutGlyphs2, pcGlyphs, psva, &pItem[0].a, piAdvance, + pGoffset, pABC); + ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr); + } + } + hr = ScriptFreeCache( &psc); + ok (!psc, "psc is not null after ScriptFreeCache\n"); + + + } + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); +} + +void test_ScriptGetCMap(unsigned short pwOutGlyphs[256]) +{ + HRESULT hr; + HWND hwnd; + HDC hdc; + SCRIPT_CACHE psc = NULL; + int cInChars; + int cChars; + unsigned short pwOutGlyphs3[256]; + WCHAR TestItem1[6] = {'T', 'e', 's', 't', 0x0166, 0}; + DWORD dwFlags; + int cnt; + + /* We need a valid HDC to drive a lot of Script functions which requires the following * + * to set up for the tests. */ + hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100, + 0, 0, 0, NULL); + assert(hwnd != 0); + + hdc = GetDC(hwnd); + ok( hdc != NULL, "HDC failed to be created %p\n", hdc); + + /* Check to make sure that SCRIPT_CACHE gets allocated ok */ + dwFlags = 0; + cInChars = cChars = 5; + /* Some sanity checks for ScriptGetCMap */ + + hr = ScriptGetCMap(NULL, NULL, NULL, 0, 0, NULL); + ok( hr == E_INVALIDARG, "(NULL,NULL,NULL,0,0,NULL), " + "expected E_INVALIDARG, got %08x\n", (unsigned int)hr); + + hr = ScriptGetCMap(NULL, NULL, TestItem1, cInChars, dwFlags, pwOutGlyphs3); + ok( hr == E_INVALIDARG, "(NULL,NULL,TestItem1, cInChars, dwFlags, pwOutGlyphs3), " + "expected E_INVALIDARG, got %08x\n", (unsigned int)hr); + + /* Set psc to NULL, to be able to check if a pointer is returned in psc */ + psc = NULL; + hr = ScriptGetCMap(NULL, &psc, NULL, 0, 0, NULL); + ok( hr == E_INVALIDARG, "(NULL,&psc,NULL,0,0NULL), expected E_INVALIDARG, " + "got %08x\n", (unsigned int)hr); + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); + + /* Set psc to NULL, to be able to check if a pointer is returned in psc */ + psc = NULL; + hr = ScriptGetCMap(NULL, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3); + ok( hr == E_PENDING, "(NULL,&psc,), expected E_PENDING, got %08x\n", (unsigned int)hr); + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); + /* Check to see if the results are the same as those returned by ScriptShape */ + hr = ScriptGetCMap(hdc, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3); + ok (hr == 0, "ScriptGetCMap should return 0 not (%08x)\n", (unsigned int) hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + for (cnt=0; cnt < cChars && pwOutGlyphs[cnt] == pwOutGlyphs3[cnt]; cnt++) {} + ok (cnt == cInChars, "Translation not correct. WCHAR %d - %04x != %04x\n", + cnt, pwOutGlyphs[cnt], pwOutGlyphs3[cnt]); + + hr = ScriptFreeCache( &psc); + ok (!psc, "psc is not null after ScriptFreeCache\n"); +} + void test_ScriptGetFontProperties(void) { HRESULT hr; @@ -108,36 +329,29 @@ void test_ScriptGetFontProperties(void) DestroyWindow(hwnd); } -START_TEST(usp10) +void test_ScriptTextOut(void) { HRESULT hr; - int iMaxProps; - const SCRIPT_PROPERTIES **ppSp; HWND hwnd; - HRGN hrgn; HDC hdc; int cInChars; int cMaxItems; SCRIPT_ITEM pItem[255]; int pcItems; - WCHAR TestItem1[6] = {'T', 'e', 's', 't', '1', 0}; - WCHAR TestItem2[6] = {'T', 'e', 's', 't', '2', 0}; + WCHAR TestItem1[6] = {'T', 'e', 's', 't', 0x0166, 0}; SCRIPT_CACHE psc; int cChars; int cMaxGlyphs; - unsigned short pwOutGlyphs[256]; - unsigned short pwOutGlyphs2[256]; - unsigned short pwOutGlyphs3[256]; + unsigned short pwOutGlyphs1[256]; unsigned short pwLogClust[256]; SCRIPT_VISATTR psva[256]; int pcGlyphs; int piAdvance[256]; GOFFSET pGoffset[256]; ABC pABC[256]; - int cnt; - DWORD dwFlags; + RECT rect; /* We need a valid HDC to drive a lot of Script functions which requires the following * * to set up for the tests. */ @@ -147,44 +361,9 @@ START_TEST(usp10) ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); - hrgn = CreateRectRgn(0, 0, 0, 0); - assert(hrgn != 0); - hdc = GetDC(hwnd); /* We now have a hdc */ ok( hdc != NULL, "HDC failed to be created %p\n", hdc); - /* Start testing usp10 functions */ - /* This test determines that the pointer returned by ScriptGetProperties is valid - * by checking a known value in the table */ - hr = ScriptGetProperties(&ppSp, &iMaxProps); - trace("number of script properties %d\n", iMaxProps); - ok (iMaxProps > 0, "Number of scripts returned should not be 0\n"); - if (iMaxProps > 0) - ok( ppSp[5]->langid == 9, "Langid[5] not = to 9\n"); /* Check a known value to ensure */ - /* ptrs work */ - - - /* This set of tests are to check that the various edits in ScriptIemize work */ - cInChars = 5; /* Length of test without NULL */ - cMaxItems = 1; /* Check threshold value */ - hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2. Was %d\n", - cMaxItems); - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(NULL, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n"); - - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(TestItem1, 0, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n"); - - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(TestItem1, cInChars, cMaxItems, NULL, NULL, NULL, &pcItems); - ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n"); - /* This is a valid test that will cause parsing to take place */ cInChars = 5; cMaxItems = 255; @@ -206,87 +385,74 @@ START_TEST(usp10) psc = NULL; /* must be null on first call */ cChars = cInChars; cMaxGlyphs = cInChars; - hr = ScriptShape(NULL, &psc, TestItem1, cChars, - cMaxGlyphs, &pItem[0].a, - pwOutGlyphs, pwLogClust, psva, &pcGlyphs); - ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n", - (unsigned int) hr); - cMaxGlyphs = 4; - hr = ScriptShape(hdc, &psc, TestItem1, cChars, - cMaxGlyphs, &pItem[0].a, - pwOutGlyphs, pwLogClust, psva, &pcGlyphs); - ok (hr == E_OUTOFMEMORY, "If not enough output area cChars (%d) is > than CMaxGlyphs (%d) but not E_OUTOFMEMORY\n", - cChars, cMaxGlyphs); cMaxGlyphs = 256; hr = ScriptShape(hdc, &psc, TestItem1, cChars, cMaxGlyphs, &pItem[0].a, - pwOutGlyphs, pwLogClust, psva, &pcGlyphs); + pwOutGlyphs1, pwLogClust, psva, &pcGlyphs); ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr); ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs); if (hr ==0) { - hr = ScriptPlace(NULL, &psc, pwOutGlyphs, pcGlyphs, psva, &pItem[0].a, piAdvance, + hr = ScriptPlace(NULL, &psc, pwOutGlyphs1, pcGlyphs, psva, &pItem[0].a, piAdvance, pGoffset, pABC); ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr); + ScriptFreeCache(&psc); /* Get rid of psc for next test set */ + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); + + hr = ScriptTextOut(NULL, NULL, 0, 0, 0, NULL, NULL, NULL, 0, NULL, 0, NULL, NULL, NULL); + ok (hr == E_INVALIDARG, "Should return 0 not (%08x)\n", (unsigned int) hr); + + hr = ScriptTextOut(NULL, NULL, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs, + piAdvance, NULL, pGoffset); + ok( hr == E_INVALIDARG, "(NULL,NULL,TestItem1, cInChars, dwFlags, pwOutGlyphs3), " + "expected E_INVALIDARG, got %08x\n", (unsigned int)hr); + + /* Set psc to NULL, to be able to check if a pointer is returned in psc */ + psc = NULL; + hr = ScriptTextOut(NULL, &psc, 0, 0, 0, NULL, NULL, NULL, 0, NULL, 0, + NULL, NULL, NULL); + ok( hr == E_INVALIDARG, "(NULL,&psc,NULL,0,0,0,NULL,), expected E_INVALIDARG, " + "got %08x\n", (unsigned int)hr); + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); + + /* Set psc to NULL, to be able to check if a pointer is returned in psc */ + psc = NULL; + hr = ScriptTextOut(NULL, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs, + piAdvance, NULL, pGoffset); + ok( hr == E_PENDING, "(NULL,&psc,), expected E_PENDING, got %08x\n", (unsigned int)hr); + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); + + /* Se that is gets a psc and that returns 0 status */ + hr = ScriptTextOut(hdc, &psc, 0, 0, 0, NULL, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs, + piAdvance, NULL, pGoffset); + ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", (unsigned int) hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + + /* Test Rect Rgn is acceptable and that it works without hdc */ + rect.top = 10; + rect.bottom = 20; + rect.left = 10; + rect.right = 40; + hr = ScriptTextOut(NULL, &psc, 0, 0, 0, &rect, &pItem[0].a, NULL, 0, pwOutGlyphs1, pcGlyphs, + piAdvance, NULL, pGoffset); + ok (hr == 0, "ScriptTextOut should return 0 not (%08x)\n", (unsigned int) hr); + ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); + + /* Clean up and go */ + ScriptFreeCache(&psc); + ok( psc == NULL, "Expected psc to be NULL, got %p\n", psc); } - - /* This test will check to make sure that SCRIPT_CACHE is reused and that not translation * - * takes place if fNoGlyphIndex is set. */ - - cInChars = 5; - cMaxItems = 255; - hr = ScriptItemize(TestItem2, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems); - ok (hr == 0, "ScriptItemize should return 0, returned %08x\n", (unsigned int) hr); - /* This test is for the intertrim operation of ScriptItemize where only one SCRIPT_ITEM is * - * returned. */ - ok (pItem[0].iCharPos == 0 && pItem[1].iCharPos == cInChars, - "Start pos not = 0 (%d) or end pos not = %d (%d)\n", - pItem[0].iCharPos, cInChars, pItem[1].iCharPos); - /* It would appear that we have a valid SCRIPT_ANALYSIS and can continue */ - if (hr == 0) { - cChars = cInChars; - cMaxGlyphs = 256; - pItem[0].a.fNoGlyphIndex = 1; /* say no translate */ - hr = ScriptShape(NULL, &psc, TestItem2, cChars, - cMaxGlyphs, &pItem[0].a, - pwOutGlyphs2, pwLogClust, psva, &pcGlyphs); - ok (hr != E_PENDING, "If psc should not be NULL (%08x) and the E_PENDING should be returned\n", - (unsigned int) hr); - ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr); - ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); - ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs); - for (cnt=0; cnt < cChars && TestItem2[cnt] == pwOutGlyphs2[cnt]; cnt++) {} - ok (cnt == cChars, "Translation to place when told not to. WCHAR %d - %04x != %04x\n", - cnt, TestItem2[cnt], pwOutGlyphs2[cnt]); - if (hr ==0) { - hr = ScriptPlace(NULL, &psc, pwOutGlyphs2, pcGlyphs, psva, &pItem[0].a, piAdvance, - pGoffset, pABC); - ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr); - } - } - hr = ScriptFreeCache( &psc); - ok (!psc, "psc is not null after ScriptFreeCache\n"); - - /* Check to make sure that SCRIPT_CACHE gets allocated ok */ - dwFlags = 0; - hr = ScriptGetCMap(NULL, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3); - ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n", - (unsigned int) hr); - /* Check to see if teh results are the same as those returned by ScriptShape */ - hr = ScriptGetCMap(hdc, &psc, TestItem1, cInChars, dwFlags, pwOutGlyphs3); - ok (hr == 0, "ScriptGetCMap should return 0 not (%08x)\n", (unsigned int) hr); - ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n"); - for (cnt=0; cnt < cChars && pwOutGlyphs[cnt] == pwOutGlyphs3[cnt]; cnt++) {} - ok (cnt == cInChars, "Translation not correct. WCHAR %d - %04x != %04x\n", - cnt, pwOutGlyphs[cnt], pwOutGlyphs3[cnt]); - - hr = ScriptFreeCache( &psc); - ok (!psc, "psc is not null after ScriptFreeCache\n"); - } - DeleteObject(hrgn); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); - - test_ScriptGetFontProperties(); +} + +START_TEST(usp10) +{ + unsigned short pwOutGlyphs[256]; + + test_ScriptItemIzeShapePlace(pwOutGlyphs); + test_ScriptGetCMap(pwOutGlyphs); + test_ScriptGetFontProperties(); + test_ScriptTextOut(); } diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index efb942ef40c..be8c388a332 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -129,7 +129,6 @@ HRESULT WINAPI ScriptGetFontProperties(HDC hdc, SCRIPT_CACHE *psc, SCRIPT_FONTPR if (!psc || !sfp) return E_INVALIDARG; - if (!hdc && !*psc) { TRACE("No Script_Cache (psc) and no hdc. Ask for one. Hdc=%p, psc=%p\n", hdc, *psc); return E_PENDING; @@ -466,7 +465,11 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars int cnt; DWORD hr; Scriptcache *pScriptcache; - FIXME("(%p,%p,%s,%d,0x%lx,%p): semi-stub\n", hdc, psc, debugstr_wn(pwcInChars,cChars), cChars, dwFlags, pwOutGlyphs); + FIXME("(%p,%p,%s,%d,0x%lx,%p): semi-stub\n", hdc, psc, debugstr_wn(pwcInChars,cChars), + cChars, dwFlags, pwOutGlyphs); + + if (!psc || !pwcInChars || !pwOutGlyphs) + return E_INVALIDARG; if (!hdc && !*psc) { TRACE("No Script_Cache (psc) and no hdc. Ask for one. Hdc=%p, psc=%p\n", hdc, *psc); @@ -507,8 +510,40 @@ HRESULT WINAPI ScriptTextOut(const HDC hdc, SCRIPT_CACHE *psc, int x, int y, UIN int iReserved, const WORD *pwGlyphs, int cGlyphs, const int *piAdvance, const int *piJustify, const GOFFSET *pGoffset) { - FIXME("(%p, %p, %d, %d, %04x, %p, %p, %p, %d, %p, %d, %p, %p, %p): stub\n", - hdc, psc, x, y, fuOptions, lprc, psa, pwcReserved, iReserved, pwGlyphs, cGlyphs, - piAdvance, piJustify, pGoffset); - return E_NOTIMPL; + HDC phdc; + DWORD hr; + Scriptcache *pScriptcache; + TRACE ("(%p, %p, %d, %d, %04x, %p, %p, %p, %d, %p, %d, %p, %p, %p): stub\n", + hdc, psc, x, y, fuOptions, lprc, psa, pwcReserved, iReserved, pwGlyphs, cGlyphs, + piAdvance, piJustify, pGoffset); + + if (!psc || !piAdvance || !psa || !pwGlyphs) + return E_INVALIDARG; + + if (!hdc && !*psc) { + TRACE("No Script_Cache (psc) and no hdc. Ask for one. Hdc=%p, psc=%p\n", hdc, *psc); + return E_PENDING; + } else + if (hdc && !*psc) { + pScriptcache = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Scriptcache) ); + pScriptcache->hdc = hdc; + phdc = hdc; + *psc = pScriptcache; + } else + if (*psc) { + pScriptcache = *psc; + phdc = pScriptcache->hdc; + } + + fuOptions &= ETO_CLIPPED + ETO_OPAQUE; + if (!psa->fNoGlyphIndex) /* Have Glyphs? */ + fuOptions |= ETO_GLYPH_INDEX; /* Say don't do tranlastion to glyph */ + + hr = ExtTextOutW(phdc, x, y, fuOptions, lprc, pwGlyphs, cGlyphs, NULL); + + if (hr) return S_OK; + else { + FIXME("ExtTextOut returned:=%ld\n", hr); + return hr; + } }