[USP10_WINETEST] Sync with Wine Staging 3.9. CORE-14656
[reactos.git] / modules / rostests / winetests / usp10 / usp10.c
1 /*
2 * Tests for usp10 dll
3 *
4 * Copyright 2006 Jeff Latimer
5 * Copyright 2006 Hans Leidekker
6 * Copyright 2010 CodeWeavers, Aric Stewart
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * Notes:
23 * Uniscribe allows for processing of complex scripts such as joining
24 * and filtering characters and bi-directional text with custom line breaks.
25 */
26
27 #include <assert.h>
28 #include <stdio.h>
29
30 #include <wine/test.h>
31 #include <windows.h>
32 #include <usp10.h>
33
34 typedef struct _itemTest {
35 char todo_flag[6];
36 int iCharPos;
37 int fRTL;
38 int fLayoutRTL;
39 int uBidiLevel;
40 int fOverrideDirection;
41 ULONG scriptTag;
42 BOOL isBroken;
43 int broken_value[6];
44 } itemTest;
45
46 typedef struct _shapeTest_char {
47 WORD wLogClust;
48 SCRIPT_CHARPROP CharProp;
49 } shapeTest_char;
50
51 typedef struct _shapeTest_glyph {
52 int Glyph;
53 SCRIPT_GLYPHPROP GlyphProp;
54 } shapeTest_glyph;
55
56 typedef struct _font_fingerprint {
57 WCHAR check[10];
58 WORD result[10];
59 } font_fingerprint;
60
61 /* Uniscribe 1.6 calls */
62 static HRESULT (WINAPI *pScriptItemizeOpenType)( const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, ULONG *pScriptTags, int *pcItems);
63
64 static HRESULT (WINAPI *pScriptShapeOpenType)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int *rcRangeChars, TEXTRANGE_PROPERTIES **rpRangeProperties, int cRanges, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProps, WORD *pwOutGlyphs, SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs);
65
66 static HRESULT (WINAPI *pScriptGetFontScriptTags)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags);
67 static HRESULT (WINAPI *pScriptGetFontLanguageTags)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags);
68 static HRESULT (WINAPI *pScriptGetFontFeatureTags)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, OPENTYPE_TAG tagLangSys, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags);
69
70 static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
71 SCRIPT_CONTROL *Control, SCRIPT_STATE *State,
72 DWORD nItems, const itemTest* items, BOOL nItemsToDo,
73 const INT nItemsBroken[2])
74 {
75 HRESULT hr;
76 int x, outnItems;
77 SCRIPT_ITEM outpItems[15];
78 ULONG tags[15] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
79
80 if (pScriptItemizeOpenType)
81 hr = pScriptItemizeOpenType(string, cchString, 15, Control, State, outpItems, tags, &outnItems);
82 else
83 hr = ScriptItemize(string, cchString, 15, Control, State, outpItems, &outnItems);
84
85 winetest_ok(hr == S_OK, "ScriptItemize should return S_OK not %08x\n", hr);
86 if (nItemsBroken && (broken(nItemsBroken[0] == outnItems) || broken(nItemsBroken[1] == outnItems)))
87 {
88 winetest_win_skip("This test broken on this platform: nitems %d\n", outnItems);
89 return;
90 }
91 todo_wine_if (nItemsToDo)
92 winetest_ok(outnItems == nItems, "Wrong number of items (%u)\n", outnItems);
93 outnItems = min(outnItems, nItems);
94 for (x = 0; x <= outnItems; x++)
95 {
96 if (items[x].isBroken && broken(outpItems[x].iCharPos == items[x].broken_value[0]))
97 winetest_win_skip("This test broken on this platform: item %d CharPos %d\n", x, outpItems[x].iCharPos);
98 else todo_wine_if (items[x].todo_flag[0])
99 winetest_ok(outpItems[x].iCharPos == items[x].iCharPos, "%i:Wrong CharPos (%i)\n",x,outpItems[x].iCharPos);
100
101 if (items[x].isBroken && broken(outpItems[x].a.fRTL== items[x].broken_value[1]))
102 winetest_win_skip("This test broken on this platform: item %d fRTL %d\n", x, outpItems[x].a.fRTL);
103 else todo_wine_if (items[x].todo_flag[1])
104 winetest_ok(outpItems[x].a.fRTL == items[x].fRTL, "%i:Wrong fRTL(%i)\n",x,outpItems[x].a.fRTL);
105
106 if (items[x].isBroken && broken(outpItems[x].a.fLayoutRTL == items[x].broken_value[2]))
107 winetest_win_skip("This test broken on this platform: item %d fLayoutRTL %d\n", x, outpItems[x].a.fLayoutRTL);
108 else todo_wine_if (items[x].todo_flag[2])
109 winetest_ok(outpItems[x].a.fLayoutRTL == items[x].fLayoutRTL, "%i:Wrong fLayoutRTL(%i)\n",x,outpItems[x].a.fLayoutRTL);
110
111 if (items[x].isBroken && broken(outpItems[x].a.s.uBidiLevel == items[x].broken_value[3]))
112 winetest_win_skip("This test broken on this platform: item %d BidiLevel %d\n", x, outpItems[x].a.s.uBidiLevel);
113 else todo_wine_if (items[x].todo_flag[3])
114 winetest_ok(outpItems[x].a.s.uBidiLevel == items[x].uBidiLevel, "%i:Wrong BidiLevel(%i)\n",x,outpItems[x].a.s.uBidiLevel);
115
116 if (items[x].isBroken && broken(outpItems[x].a.s.fOverrideDirection == items[x].broken_value[4]))
117 winetest_win_skip("This test broken on this platform: item %d fOverrideDirection %d\n", x, outpItems[x].a.s.fOverrideDirection);
118 else todo_wine_if (items[x].todo_flag[4])
119 winetest_ok(outpItems[x].a.s.fOverrideDirection == items[x].fOverrideDirection, "%i:Wrong fOverrideDirection(%i)\n",x,outpItems[x].a.s.fOverrideDirection);
120
121 if (x != outnItems)
122 winetest_ok(outpItems[x].a.eScript != SCRIPT_UNDEFINED, "%i: Undefined script\n",x);
123 if (pScriptItemizeOpenType)
124 {
125 if (items[x].isBroken && broken(tags[x] == items[x].broken_value[5]))
126 winetest_win_skip("This test broken on this platform: item %d Script Tag %x\n", x, tags[x]);
127 else todo_wine_if (items[x].todo_flag[5])
128 winetest_ok(tags[x] == items[x].scriptTag,"%i:Incorrect Script Tag %x != %x\n",x,tags[x],items[x].scriptTag);
129 }
130
131 }
132 }
133
134 #define test_items_ok(a,b,c,d,e,f,g,h) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _test_items_ok(a,b,c,d,e,f,g,h)
135
136 #define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
137 ( ( (ULONG)_x4 << 24 ) | \
138 ( (ULONG)_x3 << 16 ) | \
139 ( (ULONG)_x2 << 8 ) | \
140 (ULONG)_x1 )
141
142 #define latn_tag MS_MAKE_TAG('l','a','t','n')
143 #define arab_tag MS_MAKE_TAG('a','r','a','b')
144 #define thai_tag MS_MAKE_TAG('t','h','a','i')
145 #define hebr_tag MS_MAKE_TAG('h','e','b','r')
146 #define syrc_tag MS_MAKE_TAG('s','y','r','c')
147 #define thaa_tag MS_MAKE_TAG('t','h','a','a')
148 #define deva_tag MS_MAKE_TAG('d','e','v','a')
149 #define beng_tag MS_MAKE_TAG('b','e','n','g')
150 #define guru_tag MS_MAKE_TAG('g','u','r','u')
151 #define gujr_tag MS_MAKE_TAG('g','u','j','r')
152 #define orya_tag MS_MAKE_TAG('o','r','y','a')
153 #define taml_tag MS_MAKE_TAG('t','a','m','l')
154 #define telu_tag MS_MAKE_TAG('t','e','l','u')
155 #define knda_tag MS_MAKE_TAG('k','n','d','a')
156 #define mlym_tag MS_MAKE_TAG('m','l','y','m')
157 #define mymr_tag MS_MAKE_TAG('m','y','m','r')
158 #define tale_tag MS_MAKE_TAG('t','a','l','e')
159 #define talu_tag MS_MAKE_TAG('t','a','l','u')
160 #define khmr_tag MS_MAKE_TAG('k','h','m','r')
161 #define hani_tag MS_MAKE_TAG('h','a','n','i')
162 #define bopo_tag MS_MAKE_TAG('b','o','p','o')
163 #define kana_tag MS_MAKE_TAG('k','a','n','a')
164 #define hang_tag MS_MAKE_TAG('h','a','n','g')
165 #define yi_tag MS_MAKE_TAG('y','i',' ',' ')
166 #define ethi_tag MS_MAKE_TAG('e','t','h','i')
167 #define mong_tag MS_MAKE_TAG('m','o','n','g')
168 #define tfng_tag MS_MAKE_TAG('t','f','n','g')
169 #define nko_tag MS_MAKE_TAG('n','k','o',' ')
170 #define vai_tag MS_MAKE_TAG('v','a','i',' ')
171 #define cher_tag MS_MAKE_TAG('c','h','e','r')
172 #define cans_tag MS_MAKE_TAG('c','a','n','s')
173 #define ogam_tag MS_MAKE_TAG('o','g','a','m')
174 #define runr_tag MS_MAKE_TAG('r','u','n','r')
175 #define brai_tag MS_MAKE_TAG('b','r','a','i')
176 #define dsrt_tag MS_MAKE_TAG('d','s','r','t')
177 #define osma_tag MS_MAKE_TAG('o','s','m','a')
178 #define math_tag MS_MAKE_TAG('m','a','t','h')
179
180 static void test_ScriptItemize( void )
181 {
182 static const WCHAR test1[] = {'t', 'e', 's', 't',0};
183 static const itemTest t11[2] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1}};
184 static const itemTest t12[2] = {{{0,0,0,0,0,0},0,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
185
186 static const WCHAR test1b[] = {' ', ' ', ' ', ' ',0};
187 static const itemTest t1b1[2] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
188 static const itemTest t1b2[2] = {{{0,0,0,0,0,0},0,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
189
190 static const WCHAR test1c[] = {' ', ' ', ' ', '1', '2', ' ',0};
191 static const itemTest t1c1[2] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
192 static const itemTest t1c2[4] = {{{0,0,0,0,0,0},0,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},3,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},5,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
193
194 /* Arabic, English*/
195 static const WCHAR test2[] = {'1','2','3','-','5','2',0x064a,0x064f,0x0633,0x0627,0x0648,0x0650,0x064a,'7','1','.',0};
196 static const itemTest t21[7] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},6,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},13,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},15,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},16,0,0,0,0,-1,FALSE}};
197 static const itemTest t22[5] = {{{0,0,0,0,0,0},0,0,0,2,0,0,FALSE},{{0,0,0,0,0,0},6,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},13,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},15,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},16,0,0,0,0,-1,FALSE}};
198 static const itemTest t23[5] = {{{0,0,0,0,0,0},0,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},6,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},13,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},15,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},16,0,0,0,0,-1,FALSE}};
199 static const itemTest t24[5] = {{{0,0,0,0,0,0},0,0,0,0,1,0,FALSE},
200 {{0,0,0,0,0,0},6,0,0,0,1,arab_tag,FALSE},
201 {{0,0,0,0,0,0},13,0,1,0,1,0,FALSE},
202 {{0,0,0,0,0,0},15,0,0,0,1,0,FALSE},
203 {{0,0,0,0,0,0},16,0,0,0,0,-1,FALSE}};
204
205 static const WCHAR test2b[] = {'A','B','C','-','D','E','F',' ',0x0621,0x0623,0x0624,0};
206 static const itemTest t2b1[5] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},8,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
207 static const itemTest t2b2[5] = {{{0,0,0,0,0,0},0,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,0,0,2,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
208 static const itemTest t2b3[3] = {{{0,0,0,0,0,0},0,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
209 static const itemTest t2b4[5] = {{{0,0,0,0,0,0},0,0,0,0,1,latn_tag,FALSE},
210 {{0,0,0,0,0,0},3,0,0,0,1,0,FALSE},
211 {{0,0,0,0,0,0},4,0,0,0,1,latn_tag,FALSE},
212 {{0,0,0,0,0,0},8,0,0,0,1,arab_tag,FALSE},
213 {{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
214 static const int b2[2] = {4,4};
215
216 /* leading space */
217 static const WCHAR test2c[] = {' ',0x0621,0x0623,0x0624,'A','B','C','-','D','E','F',0};
218 static const itemTest t2c1[5] = {{{0,0,0,0,0,0},0,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
219 static const itemTest t2c2[6] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},1,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
220 static const itemTest t2c3[5] = {{{0,0,0,0,0,0},0,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},4,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,0,0,2,0,0,FALSE},{{0,0,0,0,0,0},8,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
221 static const itemTest t2c4[3] = {{{0,0,0,0,0,0},0,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},4,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
222 static const itemTest t2c5[5] = {{{0,0,0,0,0,0},0,0,0,0,1,arab_tag,FALSE},
223 {{0,0,0,0,0,0},4,0,0,0,1,latn_tag,FALSE},
224 {{0,0,0,0,0,0},7,0,0,0,1,0,FALSE},
225 {{0,0,0,0,0,0},8,0,0,0,1,latn_tag,FALSE},
226 {{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
227
228 /* trailing space */
229 static const WCHAR test2d[] = {'A','B','C','-','D','E','F',0x0621,0x0623,0x0624,' ',0};
230 static const itemTest t2d1[5] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
231 static const itemTest t2d2[6] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},10,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
232 static const itemTest t2d3[5] = {{{0,0,0,0,0,0},0,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,0,0,2,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
233 static const itemTest t2d4[3] = {{{0,0,0,0,0,0},0,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},7,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
234 static const itemTest t2d5[5] = {{{0,0,0,0,0,0},0,0,0,0,1,latn_tag,FALSE},
235 {{0,0,0,0,0,0},3,0,0,0,1,0,FALSE},
236 {{0,0,0,0,0,0},4,0,0,0,1,latn_tag,FALSE},
237 {{0,0,0,0,0,0},7,0,0,0,1,arab_tag,FALSE},
238 {{0,0,0,0,0,0},11,0,0,0,0,-1,FALSE}};
239
240 /* Thai */
241 static const WCHAR test3[] =
242 {0x0e04,0x0e27,0x0e32,0x0e21,0x0e1e,0x0e22,0x0e32,0x0e22,0x0e32, 0x0e21
243 ,0x0e2d,0x0e22,0x0e39,0x0e48,0x0e17,0x0e35,0x0e48,0x0e44,0x0e2b,0x0e19
244 ,0x0e04,0x0e27,0x0e32,0x0e21,0x0e2a, 0x0e33,0x0e40,0x0e23,0x0e47,0x0e08,
245 0x0e2d,0x0e22,0x0e39,0x0e48,0x0e17,0x0e35,0x0e48,0x0e19,0x0e31,0x0e48,0x0e19,0};
246
247 static const itemTest t31[2] = {{{0,0,0,0,0,0},0,0,0,0,0,thai_tag,FALSE},{{0,0,0,0,0,0},41,0,0,0,0,-1,FALSE}};
248 static const itemTest t32[2] = {{{0,0,0,0,0,0},0,0,0,2,0,thai_tag,FALSE},{{0,0,0,0,0,0},41,0,0,0,0,-1,FALSE}};
249
250 static const WCHAR test4[] = {'1','2','3','-','5','2',' ','i','s',' ','7','1','.',0};
251
252 static const itemTest t41[6] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},10,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},12,0,0,0,0,-1,FALSE}};
253 static const itemTest t42[5] = {{{0,0,0,0,0,0},0,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},6,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},7,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},10,0,0,2,0,0,FALSE},{{0,0,0,0,0,0},12,0,0,0,0,-1,FALSE}};
254 static const itemTest t43[4] = {{{0,0,0,0,0,0},0,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},6,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},7,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},12,0,0,0,0,-1,FALSE}};
255 static const int b43[2] = {4,4};
256
257 /* Arabic */
258 static const WCHAR test5[] = {0x0627,0x0644,0x0635,0x0651,0x0650,0x062d,0x0629,0x064f,' ',0x062a,0x064e,
259 0x0627,0x062c,0x064c,' ',0x0639,0x064e,0x0644,0x0649,' ',
260 0x0631,0x064f,0x0624,0x0648,0x0633,0x0650,' ',0x0627,0x0644,
261 0x0623,0x0635,0x0650,0x062d,0x0651,0x064e,0x0627,0x0621,0x0650,0};
262 static const itemTest t51[2] = {{{0,0,0,0,0,0},0,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},38,0,0,0,0,-1,FALSE}};
263 static const itemTest t52[2] = {{{0,0,0,0,0,0},0,0,0,0,1,arab_tag,FALSE},
264 {{0,0,0,0,0,0},38,0,0,0,0,-1,FALSE}};
265
266
267 /* Hebrew */
268 static const WCHAR test6[] = {0x05e9, 0x05dc, 0x05d5, 0x05dd, '.',0};
269 static const itemTest t61[3] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,TRUE,{-1,0,0,0,-1,-1}},{{0,0,0,0,0,0},4,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
270 static const itemTest t62[3] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},{{0,0,0,0,0,0},4,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
271 static const itemTest t63[2] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
272 static const itemTest t64[3] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
273 {{0,0,0,0,0,0},4,0,0,0,1,0,FALSE},
274 {{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
275
276 static const int b63[2] = {2,2};
277 static const WCHAR test7[] = {'p','a','r','t',' ','o','n','e',' ',0x05d7, 0x05dc, 0x05e7, ' ', 0x05e9, 0x05ea, 0x05d9, 0x05d9, 0x05dd, ' ','p','a','r','t',' ','t','h','r','e','e', 0};
278 static const itemTest t71[4] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},9,1,1,1,0,hebr_tag,TRUE,{-1,0,0,0,-1,-1}},{{0,0,0,0,0,0},19,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},29,0,0,0,0,-1,FALSE}};
279 static const itemTest t72[4] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},9,1,1,1,0,hebr_tag,FALSE},{{0,0,0,0,0,0},18,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},29,0,0,0,0,-1,FALSE}};
280 static const itemTest t73[4] = {{{0,0,0,0,0,0},0,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},8,1,1,1,0,hebr_tag,FALSE},{{0,0,0,0,0,0},19,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},29,0,0,0,0,-1,FALSE}};
281 static const itemTest t74[4] = {{{0,0,0,0,0,0},0,0,0,0,1,latn_tag,FALSE},
282 {{0,0,0,0,0,0},9,0,0,0,1,hebr_tag,FALSE},
283 {{0,0,0,0,0,0},19,0,0,0,1,latn_tag,FALSE},
284 {{0,0,0,0,0,0},29,0,0,0,0,-1,FALSE}};
285
286 static const WCHAR test8[] = {0x0633, 0x0644, 0x0627, 0x0645,0};
287 static const itemTest t81[2] = {{{0,0,0,0,0,0},0,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
288 static const itemTest t82[2] = {{{0,0,0,0,0,0},0,0,0,0,1,arab_tag,FALSE},
289 {{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
290
291 /* Syriac (Like Arabic )*/
292 static const WCHAR test9[] = {0x0710, 0x0712, 0x0712, 0x0714, '.',0};
293 static const itemTest t91[3] = {{{0,0,0,0,0,0},0,1,1,1,0,syrc_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
294 static const itemTest t92[3] = {{{0,0,0,0,0,0},0,1,1,1,0,syrc_tag},{{0,0,0,0,0,0},4,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
295 static const itemTest t93[2] = {{{0,0,0,0,0,0},0,1,1,1,0,syrc_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
296 static const itemTest t94[3] = {{{0,0,0,0,0,0},0,0,0,0,1,syrc_tag,FALSE},
297 {{0,0,0,0,0,0},4,0,0,0,1,0,FALSE},
298 {{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
299 static const int b93[2] = {2,2};
300
301 static const WCHAR test10[] = {0x0717, 0x0718, 0x071a, 0x071b,0};
302 static const itemTest t101[2] = {{{0,0,0,0,0,0},0,1,1,1,0,syrc_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
303 static const itemTest t102[2] = {{{0,0,0,0,0,0},0,0,0,0,1,syrc_tag,FALSE},
304 {{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
305
306 /* Devanagari */
307 static const WCHAR test11[] = {0x0926, 0x0947, 0x0935, 0x0928, 0x093e, 0x0917, 0x0930, 0x0940};
308 static const itemTest t111[2] = {{{0,0,0,0,0,0},0,0,0,0,0,deva_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
309 static const itemTest t112[2] = {{{0,0,0,0,0,0},0,0,0,2,0,deva_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
310
311 /* Bengali */
312 static const WCHAR test12[] = {0x09ac, 0x09be, 0x0982, 0x09b2, 0x09be};
313 static const itemTest t121[2] = {{{0,0,0,0,0,0},0,0,0,0,0,beng_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
314 static const itemTest t122[2] = {{{0,0,0,0,0,0},0,0,0,2,0,beng_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
315
316 /* Gurmukhi */
317 static const WCHAR test13[] = {0x0a17, 0x0a41, 0x0a30, 0x0a2e, 0x0a41, 0x0a16, 0x0a40};
318 static const itemTest t131[2] = {{{0,0,0,0,0,0},0,0,0,0,0,guru_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
319 static const itemTest t132[2] = {{{0,0,0,0,0,0},0,0,0,2,0,guru_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
320
321 /* Gujarati */
322 static const WCHAR test14[] = {0x0a97, 0x0ac1, 0x0a9c, 0x0ab0, 0x0abe, 0x0aa4, 0x0ac0};
323 static const itemTest t141[2] = {{{0,0,0,0,0,0},0,0,0,0,0,gujr_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
324 static const itemTest t142[2] = {{{0,0,0,0,0,0},0,0,0,2,0,gujr_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
325
326 /* Oriya */
327 static const WCHAR test15[] = {0x0b13, 0x0b21, 0x0b3c, 0x0b3f, 0x0b06};
328 static const itemTest t151[2] = {{{0,0,0,0,0,0},0,0,0,0,0,orya_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
329 static const itemTest t152[2] = {{{0,0,0,0,0,0},0,0,0,2,0,orya_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
330
331 /* Tamil */
332 static const WCHAR test16[] = {0x0ba4, 0x0bae, 0x0bbf, 0x0bb4, 0x0bcd};
333 static const itemTest t161[2] = {{{0,0,0,0,0,0},0,0,0,0,0,taml_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
334 static const itemTest t162[2] = {{{0,0,0,0,0,0},0,0,0,2,0,taml_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
335
336 /* Telugu */
337 static const WCHAR test17[] = {0x0c24, 0x0c46, 0x0c32, 0x0c41, 0x0c17, 0x0c41};
338 static const itemTest t171[2] = {{{0,0,0,0,0,0},0,0,0,0,0,telu_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
339 static const itemTest t172[2] = {{{0,0,0,0,0,0},0,0,0,2,0,telu_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
340
341 /* Kannada */
342 static const WCHAR test18[] = {0x0c95, 0x0ca8, 0x0ccd, 0x0ca8, 0x0ca1};
343 static const itemTest t181[2] = {{{0,0,0,0,0,0},0,0,0,0,0,knda_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
344 static const itemTest t182[2] = {{{0,0,0,0,0,0},0,0,0,2,0,knda_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
345
346 /* Malayalam */
347 static const WCHAR test19[] = {0x0d2e, 0x0d32, 0x0d2f, 0x0d3e, 0x0d33, 0x0d02};
348 static const itemTest t191[2] = {{{0,0,0,0,0,0},0,0,0,0,0,mlym_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
349 static const itemTest t192[2] = {{{0,0,0,0,0,0},0,0,0,2,0,mlym_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
350
351 /* Diacritical */
352 static const WCHAR test20[] = {0x0309,'a','b','c','d',0};
353 static const itemTest t201[3] = {{{0,0,0,0,0,0},0,0,0,0,0x0,0,FALSE},{{0,0,0,0,0,0},1,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
354 static const itemTest t202[3] = {{{0,0,0,0,0,0},0,0,0,2,0,0,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},1,0,0,2,0,latn_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
355
356 static const WCHAR test21[] = {0x0710, 0x0712, 0x0308, 0x0712, 0x0714,0};
357 static const itemTest t211[2] = {{{0,0,0,0,0,0},0,1,1,1,0,syrc_tag,FALSE},{{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
358 static const itemTest t212[2] = {{{0,0,0,0,0,0},0,0,0,0,1,syrc_tag,FALSE},
359 {{0,0,0,0,0,0},5,0,0,0,0,-1,FALSE}};
360
361 /* Latin Punctuation */
362 static const WCHAR test22[] = {'#','$',',','!','\"','*',0};
363 static const itemTest t221[3] = {{{0,0,0,0,0,0},0,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
364 static const itemTest t222[3] = {{{0,0,0,0,0,0},0,1,1,1,0,latn_tag,FALSE},{{0,0,0,0,0,0},3,1,1,1,0,0,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
365 static const itemTest t223[2] = {{{0,0,0,0,0,0},0,1,1,1,0,latn_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
366 static const int b222[2] = {1,1};
367 static const int b223[2] = {2,2};
368
369 /* Number 2*/
370 static const WCHAR test23[] = {'1','2','3',0x00b2,0x00b3,0x2070,0};
371 static const itemTest t231[3] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
372 static const itemTest t232[3] = {{{0,0,0,0,0,0},0,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},3,0,1,2,0,0,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
373
374 /* Myanmar */
375 static const WCHAR test24[] = {0x1019,0x103c,0x1014,0x103a,0x1019,0x102c,0x1021,0x1000,0x1039,0x1001,0x101b,0x102c};
376 static const itemTest t241[2] = {{{0,0,0,0,0,0},0,0,0,0,0,mymr_tag,FALSE},{{0,0,0,0,0,0},12,0,0,0,0,-1,FALSE}};
377 static const itemTest t242[2] = {{{0,0,0,0,0,0},0,0,0,2,0,mymr_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},12,0,0,0,0,-1,FALSE}};
378
379 /* Tai Le */
380 static const WCHAR test25[] = {0x1956,0x196d,0x1970,0x1956,0x196c,0x1973,0x1951,0x1968,0x1952,0x1970};
381 static const itemTest t251[2] = {{{0,0,0,0,0,0},0,0,0,0,0,tale_tag,TRUE,{-1,-1,-1,-1,-1,latn_tag}},{{0,0,0,0,0,0},10,0,0,0,0,-1,FALSE}};
382 static const itemTest t252[2] = {{{0,0,0,0,0,0},0,0,0,2,0,tale_tag,TRUE,{-1,1,1,1,-1,latn_tag}},{{0,0,0,0,0,0},10,0,0,0,0,-1,FALSE}};
383
384 /* New Tai Lue */
385 static const WCHAR test26[] = {0x1992,0x19c4};
386 static const itemTest t261[2] = {{{0,0,0,0,0,0},0,0,0,0,0,talu_tag,TRUE,{-1,-1,-1,-1,-1,latn_tag}},{{0,0,0,0,0,0},2,0,0,0,0,-1,FALSE}};
387 static const itemTest t262[2] = {{{0,0,0,0,0,0},0,0,0,2,0,talu_tag,TRUE,{-1,1,1,1,-1,latn_tag}},{{0,0,0,0,0,0},2,0,0,0,0,-1,FALSE}};
388
389 /* Khmer */
390 static const WCHAR test27[] = {0x1781,0x17c1,0x1798,0x179a,0x1797,0x17b6,0x179f,0x17b6};
391 static const itemTest t271[2] = {{{0,0,0,0,0,0},0,0,0,0,0,khmr_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
392 static const itemTest t272[2] = {{{0,0,0,0,0,0},0,0,0,2,0,khmr_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
393
394 /* CJK Han */
395 static const WCHAR test28[] = {0x8bed,0x7d20,0x6587,0x5b57};
396 static const itemTest t281[2] = {{{0,0,0,0,0,0},0,0,0,0,0,hani_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
397 static const itemTest t282[2] = {{{0,0,0,0,0,0},0,0,0,2,0,hani_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
398
399 /* Ideographic */
400 static const WCHAR test29[] = {0x2ff0,0x2ff3,0x2ffb,0x2ff0,0x65e5,0x65e5,0x5de5,0x7f51,0x4e02,0x4e5e};
401 static const itemTest t291[3] = {{{0,0,0,0,0,0},0,0,0,0,0,hani_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,hani_tag,FALSE},{{0,0,0,0,0,0},10,0,0,0,0,-1,FALSE}};
402 static const itemTest t292[3] = {{{0,0,0,0,0,0},0,1,1,1,0,hani_tag,FALSE},{{0,0,0,0,0,0},4,0,0,2,0,hani_tag,FALSE},{{0,0,0,0,0,0},10,0,0,0,0,-1,FALSE}};
403
404 /* Bopomofo */
405 static const WCHAR test30[] = {0x3113,0x3128,0x3127,0x3123,0x3108,0x3128,0x310f,0x3120};
406 static const itemTest t301[2] = {{{0,0,0,0,0,0},0,0,0,0,0,bopo_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
407 static const itemTest t302[2] = {{{0,0,0,0,0,0},0,0,0,2,0,bopo_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
408
409 /* Kana */
410 static const WCHAR test31[] = {0x3072,0x3089,0x304b,0x306a,0x30ab,0x30bf,0x30ab,0x30ca};
411 static const itemTest t311[2] = {{{0,0,0,0,0,0},0,0,0,0,0,kana_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
412 static const itemTest t312[2] = {{{0,0,0,0,0,0},0,0,0,2,0,kana_tag,FALSE},{{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
413 static const int b311[2] = {2,2};
414 static const int b312[2] = {2,2};
415
416 /* Hangul */
417 static const WCHAR test32[] = {0xd55c,0xad6d,0xc5b4};
418 static const itemTest t321[2] = {{{0,0,0,0,0,0},0,0,0,0,0,hang_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
419 static const itemTest t322[2] = {{{0,0,0,0,0,0},0,0,0,2,0,hang_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
420
421 /* Yi */
422 static const WCHAR test33[] = {0xa188,0xa320,0xa071,0xa0b7};
423 static const itemTest t331[2] = {{{0,0,0,0,0,0},0,0,0,0,0,yi_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
424 static const itemTest t332[2] = {{{0,0,0,0,0,0},0,0,0,2,0,yi_tag,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
425
426 /* Ethiopic */
427 static const WCHAR test34[] = {0x130d,0x12d5,0x12dd};
428 static const itemTest t341[2] = {{{0,0,0,0,0,0},0,0,0,0,0,ethi_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
429 static const itemTest t342[2] = {{{0,0,0,0,0,0},0,0,0,2,0,ethi_tag,FALSE},{{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
430 static const int b342[2] = {2,2};
431
432 /* Mongolian */
433 static const WCHAR test35[] = {0x182e,0x1823,0x1829,0x182d,0x1823,0x182f,0x0020,0x182a,0x1822,0x1834,0x1822,0x182d,0x180c};
434 static const itemTest t351[2] = {{{0,0,0,0,0,0},0,0,0,0,0,mong_tag,FALSE},{{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
435 static const int b351[2] = {2,2};
436 static const itemTest t352[2] = {{{0,0,0,0,0,0},0,0,0,2,0,mong_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
437 static const int b352[2] = {2,3};
438 static const itemTest t353[2] = {{{0,0,0,0,1,0},0,0,0,0,1,mong_tag,TRUE,{-1,-1,-1,-1,0,0}},{{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
439
440 /* Tifinagh */
441 static const WCHAR test36[] = {0x2d5c,0x2d49,0x2d3c,0x2d49,0x2d4f,0x2d30,0x2d56};
442 static const itemTest t361[2] = {{{0,0,0,0,0,0},0,0,0,0,0,tfng_tag,TRUE,{-1,-1,-1,-1,-1,latn_tag}},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
443 static const itemTest t362[2] = {{{0,0,0,0,0,0},0,0,0,2,0,tfng_tag,TRUE,{-1,1,1,1,-1,latn_tag}},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
444
445 /* N'Ko */
446 static const WCHAR test37[] = {0x07d2,0x07de,0x07cf};
447 static const itemTest t371[2] = {{{0,0,0,0,0,0},0,1,1,1,0,nko_tag,TRUE,{-1,0,0,0,-1,arab_tag}},{{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
448 static const itemTest t372[2] = {{{0,0,0,0,0,0},0,1,1,1,0,nko_tag,TRUE,{-1,0,0,2,-1,arab_tag}},{{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
449 static const itemTest t373[2] = {{{0,0,0,0,0,0},0,0,0,0,1,nko_tag,TRUE,{-1,-1,-1,2,0,arab_tag}}, {{0,0,0,0,0,0},3,0,0,0,0,-1,FALSE}};
450
451 /* Vai */
452 static const WCHAR test38[] = {0xa559,0xa524};
453 static const itemTest t381[2] = {{{0,0,0,0,0,0},0,0,0,0,0,vai_tag,TRUE,{-1,-1,-1,-1,-1,latn_tag}},{{0,0,0,0,0,0},2,0,0,0,0,-1,FALSE}};
454 static const itemTest t382[2] = {{{0,0,0,0,0,0},0,0,0,2,0,vai_tag,TRUE,{-1,1,1,1,-1,latn_tag}},{{0,0,0,0,0,0},2,0,0,0,0,-1,FALSE}};
455
456 /* Cherokee */
457 static const WCHAR test39[] = {0x13e3,0x13b3,0x13a9,0x0020,0x13a6,0x13ec,0x13c2,0x13af,0x13cd,0x13d7};
458 static const itemTest t391[2] = {{{0,0,0,0,0,0},0,0,0,0,0,cher_tag,FALSE},{{0,0,0,0,0,0},10,0,0,0,0,-1,FALSE}};
459 static const itemTest t392[2] = {{{0,0,0,0,0,0},0,0,0,2,0,cher_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},10,0,0,0,0,-1,FALSE}};
460
461 /* Canadian Aboriginal Syllabics */
462 static const WCHAR test40[] = {0x1403,0x14c4,0x1483,0x144e,0x1450,0x1466};
463 static const itemTest t401[2] = {{{0,0,0,0,0,0},0,0,0,0,0,cans_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
464 static const itemTest t402[2] = {{{0,0,0,0,0,0},0,0,0,2,0,cans_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
465
466 /* Ogham */
467 static const WCHAR test41[] = {0x169b,0x1691,0x168c,0x1690,0x168b,0x169c};
468 static const itemTest t411[2] = {{{0,0,0,0,0,0},0,0,0,0,0,ogam_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
469 static const itemTest t412[4] = {{{0,0,0,0,0,0},0,1,1,1,0,ogam_tag,FALSE},{{0,0,0,0,0,0},1,0,0,2,0,ogam_tag,FALSE},{{0,0,0,0,0,0},5,1,1,1,0,ogam_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
470 static const int b412[2] = {1,1};
471
472 /* Runic */
473 static const WCHAR test42[] = {0x16a0,0x16a1,0x16a2,0x16a3,0x16a4,0x16a5};
474 static const itemTest t421[2] = {{{0,0,0,0,0,0},0,0,0,0,0,runr_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
475 static const itemTest t422[4] = {{{0,0,0,0,0,0},0,0,0,2,0,runr_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
476
477 /* Braille */
478 static const WCHAR test43[] = {0x280f,0x2817,0x2811,0x280d,0x280a,0x2811,0x2817};
479 static const itemTest t431[2] = {{{0,0,0,0,0,0},0,0,0,0,0,brai_tag,FALSE},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
480 static const itemTest t432[4] = {{{0,0,0,0,0,0},0,0,0,2,0,brai_tag,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
481
482 /* Private and Surrogates Area */
483 static const WCHAR test44[] = {0xe000, 0xe001, 0xd800, 0xd801};
484 static const itemTest t441[3] = {{{0,0,0,0,0,0},0,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},2,0,0,0,0,0,FALSE},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
485 static const itemTest t442[4] = {{{0,0,0,0,0,0},0,0,0,2,0,0,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},2,0,0,2,0,0,TRUE,{-1,1,1,1,-1,-1}},{{0,0,0,0,0,0},4,0,0,0,0,-1,FALSE}};
486
487 /* Deseret */
488 static const WCHAR test45[] = {0xd801,0xdc19,0xd801,0xdc32,0xd801,0xdc4c,0xd801,0xdc3c,0xd801,0xdc32,0xd801,0xdc4b,0xd801,0xdc2f,0xd801,0xdc4c,0xd801,0xdc3b,0xd801,0xdc32,0xd801,0xdc4a,0xd801,0xdc28};
489 static const itemTest t451[2] = {{{0,0,0,0,0,0},0,0,0,0,0,dsrt_tag,TRUE,{-1,-1,-1,-1,-1,0x0}},{{0,0,0,0,0,0},24,0,0,0,0,-1,FALSE}};
490 static const itemTest t452[2] = {{{0,0,0,0,0,0},0,0,0,2,0,dsrt_tag,TRUE,{-1,1,1,1,-1,0x0}},{{0,0,0,0,0,0},24,0,0,0,0,-1,FALSE}};
491
492 /* Osmanya */
493 static const WCHAR test46[] = {0xd801,0xdc8b,0xd801,0xdc98,0xd801,0xdc88,0xd801,0xdc91,0xd801,0xdc9b,0xd801,0xdc92,0xd801,0xdc95,0xd801,0xdc80};
494 static const itemTest t461[2] = {{{0,0,0,0,0,0},0,0,0,0,0,osma_tag,TRUE,{-1,-1,-1,-1,-1,0x0}},{{0,0,0,0,0,0},16,0,0,0,0,-1,FALSE}};
495 static const itemTest t462[2] = {{{0,0,0,0,0,0},0,0,0,2,0,osma_tag,TRUE,{-1,1,1,1,-1,0x0}},{{0,0,0,0,0,0},16,0,0,0,0,-1,FALSE}};
496
497 /* Mathematical Alphanumeric Symbols */
498 static const WCHAR test47[] = {0xd835,0xdc00,0xd835,0xdc35,0xd835,0xdc6a,0xd835,0xdc9f,0xd835,0xdcd4,0xd835,0xdd09,0xd835,0xdd3e,0xd835,0xdd73,0xd835,0xdda8,0xd835,0xdddd,0xd835,0xde12,0xd835,0xde47,0xd835,0xde7c};
499 static const itemTest t471[2] = {{{0,0,0,0,0,0},0,0,0,0,0,math_tag,TRUE,{-1,-1,-1,-1,-1,0x0}},{{0,0,0,0,0,0},26,0,0,0,0,-1,FALSE}};
500 static const itemTest t472[2] = {{{0,0,0,0,0,0},0,0,0,2,0,math_tag,TRUE,{-1,1,1,1,-1,0x0}},{{0,0,0,0,0,0},26,0,0,0,0,-1,FALSE}};
501
502 /* Mathematical and Numeric combinations */
503 /* These have a leading hebrew character to force complicated itemization */
504 static const WCHAR test48[] = {0x05e9,' ','1','2','3','.'};
505 static const itemTest t481[4] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
506 {{0,0,0,0,0},2,0,1,2,0,0,FALSE},{{0,0,0,0,0},5,0,0,0,0,0,FALSE},
507 {{0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
508 static const itemTest t482[4] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
509 {{0,0,0,0,0,0},2,0,1,0,1,0,FALSE},
510 {{0,0,0,0,0,0},5,0,0,0,1,0,FALSE},
511 {{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
512
513 static const WCHAR test49[] = {0x05e9,' ','1','2','.','1','2'};
514 static const itemTest t491[3] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
515 {{0,0,0,0,0},2,0,1,2,0,0,FALSE},{{0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
516 static const itemTest t492[3] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
517 {{0,0,0,0,0,0},2,0,1,0,1,0,FALSE},
518 {{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
519
520 static const WCHAR test50[] = {0x05e9,' ','.','1','2','3'};
521 static const itemTest t501[4] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
522 {{0,0,0,0,0},2,1,1,1,0,0,FALSE},{{0,0,0,0,0},3,0,1,2,0,0,FALSE},
523 {{0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
524 static const itemTest t502[4] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
525 {{0,0,0,0,0,0},2,0,0,0,1,0,FALSE},
526 {{0,0,0,0,0,0},3,0,1,0,1,0,FALSE},
527 {{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
528
529 static const WCHAR test51[] = {0x05e9,' ','a','b','.','1','2'};
530 static const itemTest t511[5] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
531 {{0,0,0,0,0},1,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0},4,0,0,0,0,0,FALSE},
532 {{0,0,0,0,0},5,0,0,2,0,0,FALSE},{{0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
533 static const itemTest t512[5] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
534 {{0,0,0,0,0,0},2,0,0,0,1,latn_tag,FALSE},
535 {{0,0,0,0,0,0},4,0,0,0,1,0,FALSE},
536 {{0,0,0,0,0,0},5,0,0,0,1,0,FALSE},
537 {{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
538
539 static const WCHAR test52[] = {0x05e9,' ','1','2','.','a','b'};
540 static const itemTest t521[5] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
541 {{0,0,0,0,0},2,0,1,2,0,0,FALSE},{{0,0,0,0,0},4,0,0,0,0,0,FALSE},
542 {{0,0,0,0,0},5,0,0,0,0,latn_tag,FALSE},{{0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
543 static const itemTest t522[5] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
544 {{0,0,0,0,0,0},2,0,1,0,1,0,FALSE},
545 {{0,0,0,0,0,0},4,0,0,0,1,0,FALSE},
546 {{0,0,0,0,0,0},5,0,0,0,1,latn_tag,FALSE},
547 {{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
548
549 static const WCHAR test53[] = {0x05e9,' ','1','2','.','.','1','2'};
550 static const itemTest t531[5] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
551 {{0,0,0,0,0},2,0,1,2,0,0,FALSE},{{0,0,0,0,0},4,1,1,1,0,0,FALSE},
552 {{0,0,0,0,0},6,0,1,2,0,0,FALSE},{{0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
553 static const itemTest t532[5] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
554 {{0,0,0,0,0,0},2,0,1,0,1,0,FALSE},
555 {{0,0,0,0,0,0},4,0,0,0,1,0,FALSE},
556 {{0,0,0,0,0,0},6,0,1,0,1,0,FALSE},
557 {{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
558
559 static const WCHAR test54[] = {0x05e9,' ','1','2','+','1','2'};
560 static const itemTest t541[3] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
561 {{0,0,0,0,0},2,0,1,2,0,0,FALSE},{{0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
562 static const itemTest t542[3] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
563 {{0,0,0,0,0,0},2,0,1,0,1,0,FALSE},
564 {{0,0,0,0,0,0},7,0,0,0,0,-1,FALSE}};
565 static const WCHAR test55[] = {0x05e9,' ','1','2','+','+','1','2'};
566 static const itemTest t551[3] = {{{0,0,0,0,0,0},0,1,1,1,0,hebr_tag,FALSE},
567 {{0,0,0,0,0},2,0,1,2,0,0,FALSE},{{0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
568 static const itemTest t552[3] = {{{0,0,0,0,0,0},0,0,0,0,1,hebr_tag,FALSE},
569 {{0,0,0,0,0,0},2,0,1,0,1,0,FALSE},
570 {{0,0,0,0,0,0},8,0,0,0,0,-1,FALSE}};
571
572 /* ZWNJ */
573 static const WCHAR test56[] = {0x0645, 0x06cc, 0x200c, 0x06a9, 0x0646, 0x0645}; /* می‌کنم */
574 static const itemTest t561[] = {{{0,0,0,0,0,0},0,1,1,1,0,arab_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
575 static const itemTest t562[] = {{{0,0,0,0,0,0},0,0,0,0,1,arab_tag,FALSE},{{0,0,0,0,0,0},6,0,0,0,0,-1,FALSE}};
576
577 /* Persian numerals and punctuation. */
578 static const WCHAR test57[] = {0x06f1, 0x06f2, 0x066c, 0x06f3, 0x06f4, 0x06f5, 0x066c, /* ۱۲٬۳۴۵٬ */
579 0x06f6, 0x06f7, 0x06f8, 0x066b, 0x06f9, 0x06f0}; /* ۶۷۸٫۹۰ */
580 static const itemTest t571[] = {{{0,0,0,0,0,0}, 0,0,1,2,0,arab_tag,FALSE},{{0,0,0,0,0,0}, 2,0,1,2,0,arab_tag,FALSE},
581 {{0,0,0,0,0,0}, 3,0,1,2,0,arab_tag,FALSE},{{0,0,0,0,0,0}, 6,0,1,2,0,arab_tag,FALSE},
582 {{0,0,0,0,0,0}, 7,0,1,2,0,arab_tag,FALSE},{{0,0,0,0,0,0},10,0,1,2,0,arab_tag,FALSE},
583 {{0,0,0,0,0,0},11,0,1,2,0,arab_tag,FALSE},{{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
584 static const itemTest t572[] = {{{0,0,0,0,0,0}, 0,0,0,2,0,arab_tag,FALSE},{{0,0,1,0,0,0}, 2,0,1,2,0,arab_tag,FALSE},
585 {{0,0,0,0,0,0}, 3,0,0,2,0,arab_tag,FALSE},{{0,0,1,0,0,0}, 6,0,1,2,0,arab_tag,FALSE},
586 {{0,0,0,0,0,0}, 7,0,0,2,0,arab_tag,FALSE},{{0,0,1,0,0,0},10,0,1,2,0,arab_tag,FALSE},
587 {{0,0,0,0,0,0},11,0,0,2,0,arab_tag,FALSE},{{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
588 static const itemTest t573[] = {{{0,0,0,0,0,0}, 0,0,0,0,1,arab_tag,FALSE},{{0,0,0,0,0,0}, 2,0,0,0,1,arab_tag,FALSE},
589 {{0,0,0,0,0,0}, 3,0,0,0,1,arab_tag,FALSE},{{0,0,0,0,0,0}, 6,0,0,0,1,arab_tag,FALSE},
590 {{0,0,0,0,0,0}, 7,0,0,0,1,arab_tag,FALSE},{{0,0,0,0,0,0},10,0,0,0,1,arab_tag,FALSE},
591 {{0,0,0,0,0,0},11,0,0,0,1,arab_tag,FALSE},{{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
592 /* Arabic numerals and punctuation. */
593 static const WCHAR test58[] = {0x0661, 0x0662, 0x066c, 0x0663, 0x0664, 0x0665, 0x066c, /* ١٢٬٣٤٥٬ */
594 0x0666, 0x0667, 0x0668, 0x066b, 0x0669, 0x0660}; /* ٦٧٨٫٩٠ */
595 static const itemTest t581[] = {{{0,0,0,0,0,0}, 0,0,1,2,0,arab_tag,FALSE},
596 {{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
597 static const itemTest t582[] = {{{0,0,1,1,1,0}, 0,0,0,0,1,arab_tag,FALSE},
598 {{0,0,0,0,0,0},13,0,0,0,0,-1,FALSE}};
599
600 SCRIPT_ITEM items[15];
601 SCRIPT_CONTROL Control;
602 SCRIPT_STATE State;
603 HRESULT hr;
604 int nItems;
605
606 memset(&Control, 0, sizeof(Control));
607 memset(&State, 0, sizeof(State));
608
609 hr = ScriptItemize(NULL, 4, 10, &Control, &State, items, NULL);
610 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pwcInChars is NULL\n");
611
612 hr = ScriptItemize(test1, 4, 10, &Control, &State, NULL, NULL);
613 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if pItems is NULL\n");
614
615 hr = ScriptItemize(test1, 4, 1, &Control, &State, items, NULL);
616 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cMaxItems < 2.\n");
617
618 hr = ScriptItemize(test1, 0, 10, NULL, NULL, items, &nItems);
619 ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n");
620
621 test_items_ok(test1,4,NULL,NULL,1,t11,FALSE,0);
622 test_items_ok(test1b,4,NULL,NULL,1,t1b1,FALSE,0);
623 test_items_ok(test1c,6,NULL,NULL,1,t1c1,FALSE,0);
624 test_items_ok(test2,16,NULL,NULL,6,t21,FALSE,0);
625 test_items_ok(test2b,11,NULL,NULL,4,t2b1,FALSE,0);
626 test_items_ok(test2c,11,NULL,NULL,4,t2c1,FALSE,0);
627 test_items_ok(test2d,11,NULL,NULL,4,t2d1,FALSE,0);
628 test_items_ok(test3,41,NULL,NULL,1,t31,FALSE,0);
629 test_items_ok(test4,12,NULL,NULL,5,t41,FALSE,0);
630 test_items_ok(test5,38,NULL,NULL,1,t51,FALSE,0);
631 test_items_ok(test6,5,NULL,NULL,2,t61,FALSE,0);
632 test_items_ok(test7,29,NULL,NULL,3,t71,FALSE,0);
633 test_items_ok(test8,4,NULL,NULL,1,t81,FALSE,0);
634 test_items_ok(test9,5,NULL,NULL,2,t91,FALSE,0);
635 test_items_ok(test10,4,NULL,NULL,1,t101,FALSE,0);
636 test_items_ok(test11,8,NULL,NULL,1,t111,FALSE,0);
637 test_items_ok(test12,5,NULL,NULL,1,t121,FALSE,0);
638 test_items_ok(test13,7,NULL,NULL,1,t131,FALSE,0);
639 test_items_ok(test14,7,NULL,NULL,1,t141,FALSE,0);
640 test_items_ok(test15,5,NULL,NULL,1,t151,FALSE,0);
641 test_items_ok(test16,5,NULL,NULL,1,t161,FALSE,0);
642 test_items_ok(test17,6,NULL,NULL,1,t171,FALSE,0);
643 test_items_ok(test18,5,NULL,NULL,1,t181,FALSE,0);
644 test_items_ok(test19,6,NULL,NULL,1,t191,FALSE,0);
645 test_items_ok(test20,5,NULL,NULL,2,t201,FALSE,0);
646 test_items_ok(test21,5,NULL,NULL,1,t211,FALSE,0);
647 test_items_ok(test22,6,NULL,NULL,2,t221,FALSE,0);
648 test_items_ok(test23,6,NULL,NULL,2,t231,FALSE,0);
649 test_items_ok(test24,12,NULL,NULL,1,t241,FALSE,0);
650 test_items_ok(test25,10,NULL,NULL,1,t251,FALSE,0);
651 test_items_ok(test26,2,NULL,NULL,1,t261,FALSE,0);
652 test_items_ok(test27,8,NULL,NULL,1,t271,FALSE,0);
653 test_items_ok(test28,4,NULL,NULL,1,t281,FALSE,0);
654 test_items_ok(test29,10,NULL,NULL,2,t291,FALSE,0);
655 test_items_ok(test30,8,NULL,NULL,1,t301,FALSE,0);
656 test_items_ok(test31,8,NULL,NULL,1,t311,FALSE,b311);
657 test_items_ok(test32,3,NULL,NULL,1,t321,FALSE,0);
658 test_items_ok(test33,4,NULL,NULL,1,t331,FALSE,0);
659 test_items_ok(test34,3,NULL,NULL,1,t341,FALSE,0);
660 test_items_ok(test35,13,NULL,NULL,1,t351,FALSE,b351);
661 test_items_ok(test36,7,NULL,NULL,1,t361,FALSE,0);
662 test_items_ok(test37,3,NULL,NULL,1,t371,FALSE,0);
663 test_items_ok(test38,2,NULL,NULL,1,t381,FALSE,0);
664 test_items_ok(test39,10,NULL,NULL,1,t391,FALSE,0);
665 test_items_ok(test40,6,NULL,NULL,1,t401,FALSE,0);
666 test_items_ok(test41,6,NULL,NULL,1,t411,FALSE,0);
667 test_items_ok(test42,6,NULL,NULL,1,t421,FALSE,0);
668 test_items_ok(test43,7,NULL,NULL,1,t431,FALSE,0);
669 test_items_ok(test44,4,NULL,NULL,2,t441,FALSE,0);
670 test_items_ok(test45,24,NULL,NULL,1,t451,FALSE,0);
671 test_items_ok(test46,16,NULL,NULL,1,t461,FALSE,0);
672 test_items_ok(test47,26,NULL,NULL,1,t471,FALSE,0);
673 test_items_ok(test56,6,NULL,NULL,1,t561,FALSE,0);
674 test_items_ok(test57,13,NULL,NULL,7,t571,FALSE,0);
675 test_items_ok(test58,13,NULL,NULL,1,t581,FALSE,0);
676
677 State.uBidiLevel = 0;
678 test_items_ok(test1,4,&Control,&State,1,t11,FALSE,0);
679 test_items_ok(test1b,4,&Control,&State,1,t1b1,FALSE,0);
680 test_items_ok(test1c,6,&Control,&State,1,t1c1,FALSE,0);
681 test_items_ok(test2,16,&Control,&State,4,t22,FALSE,0);
682 test_items_ok(test2b,11,&Control,&State,4,t2b1,FALSE,0);
683 test_items_ok(test2c,11,&Control,&State,5,t2c2,FALSE,0);
684 test_items_ok(test2d,11,&Control,&State,5,t2d2,FALSE,0);
685 test_items_ok(test3,41,&Control,&State,1,t31,FALSE,0);
686 test_items_ok(test4,12,&Control,&State,5,t41,FALSE,0);
687 test_items_ok(test5,38,&Control,&State,1,t51,FALSE,0);
688 test_items_ok(test6,5,&Control,&State,2,t61,FALSE,0);
689 test_items_ok(test7,29,&Control,&State,3,t72,FALSE,0);
690 test_items_ok(test8,4,&Control,&State,1,t81,FALSE,0);
691 test_items_ok(test9,5,&Control,&State,2,t91,FALSE,0);
692 test_items_ok(test10,4,&Control,&State,1,t101,FALSE,0);
693 test_items_ok(test11,8,&Control,&State,1,t111,FALSE,0);
694 test_items_ok(test12,5,&Control,&State,1,t121,FALSE,0);
695 test_items_ok(test13,7,&Control,&State,1,t131,FALSE,0);
696 test_items_ok(test14,7,&Control,&State,1,t141,FALSE,0);
697 test_items_ok(test15,5,&Control,&State,1,t151,FALSE,0);
698 test_items_ok(test16,5,&Control,&State,1,t161,FALSE,0);
699 test_items_ok(test17,6,&Control,&State,1,t171,FALSE,0);
700 test_items_ok(test18,5,&Control,&State,1,t181,FALSE,0);
701 test_items_ok(test19,6,&Control,&State,1,t191,FALSE,0);
702 test_items_ok(test20,5,&Control,&State,2,t201,FALSE,0);
703 test_items_ok(test21,5,&Control,&State,1,t211,FALSE,0);
704 test_items_ok(test22,6,&Control,&State,2,t221,FALSE,0);
705 test_items_ok(test23,6,&Control,&State,2,t231,FALSE,0);
706 test_items_ok(test24,12,&Control,&State,1,t241,FALSE,0);
707 test_items_ok(test25,10,&Control,&State,1,t251,FALSE,0);
708 test_items_ok(test26,2,&Control,&State,1,t261,FALSE,0);
709 test_items_ok(test27,8,&Control,&State,1,t271,FALSE,0);
710 test_items_ok(test28,4,&Control,&State,1,t281,FALSE,0);
711 test_items_ok(test29,10,&Control,&State,2,t291,FALSE,0);
712 test_items_ok(test30,8,&Control,&State,1,t301,FALSE,0);
713 test_items_ok(test31,8,&Control,&State,1,t311,FALSE,b311);
714 test_items_ok(test32,3,&Control,&State,1,t321,FALSE,0);
715 test_items_ok(test33,4,&Control,&State,1,t331,FALSE,0);
716 test_items_ok(test34,3,&Control,&State,1,t341,FALSE,0);
717 test_items_ok(test35,13,&Control,&State,1,t351,FALSE,b351);
718 test_items_ok(test36,7,&Control,&State,1,t361,FALSE,0);
719 test_items_ok(test37,3,&Control,&State,1,t371,FALSE,0);
720 test_items_ok(test38,2,&Control,&State,1,t381,FALSE,0);
721 test_items_ok(test39,10,&Control,&State,1,t391,FALSE,0);
722 test_items_ok(test40,6,&Control,&State,1,t401,FALSE,0);
723 test_items_ok(test41,6,&Control,&State,1,t411,FALSE,0);
724 test_items_ok(test42,6,&Control,&State,1,t421,FALSE,0);
725 test_items_ok(test43,7,&Control,&State,1,t431,FALSE,0);
726 test_items_ok(test44,4,&Control,&State,2,t441,FALSE,0);
727 test_items_ok(test45,24,&Control,&State,1,t451,FALSE,0);
728 test_items_ok(test46,16,&Control,&State,1,t461,FALSE,0);
729 test_items_ok(test47,26,&Control,&State,1,t471,FALSE,0);
730 test_items_ok(test48,6,&Control,&State,3,t481,FALSE,0);
731 test_items_ok(test49,7,&Control,&State,2,t491,FALSE,0);
732 test_items_ok(test50,6,&Control,&State,3,t501,FALSE,0);
733 test_items_ok(test51,7,&Control,&State,4,t511,FALSE,0);
734 test_items_ok(test52,7,&Control,&State,4,t521,FALSE,0);
735 test_items_ok(test53,8,&Control,&State,4,t531,FALSE,0);
736 test_items_ok(test54,7,&Control,&State,2,t541,FALSE,0);
737 test_items_ok(test55,8,&Control,&State,2,t551,FALSE,0);
738 test_items_ok(test56,6,&Control,&State,1,t561,FALSE,0);
739 test_items_ok(test57,13,&Control,&State,7,t572,FALSE,0);
740 test_items_ok(test58,13,&Control,&State,1,t581,FALSE,0);
741
742 State.uBidiLevel = 1;
743 test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0);
744 test_items_ok(test1b,4,&Control,&State,1,t1b2,FALSE,0);
745 test_items_ok(test1c,6,&Control,&State,3,t1c2,FALSE,0);
746 test_items_ok(test2,16,&Control,&State,4,t23,FALSE,0);
747 test_items_ok(test2b,11,&Control,&State,4,t2b2,FALSE,0);
748 test_items_ok(test2c,11,&Control,&State,4,t2c3,FALSE,0);
749 test_items_ok(test2d,11,&Control,&State,4,t2d3,FALSE,0);
750 test_items_ok(test3,41,&Control,&State,1,t32,FALSE,0);
751 test_items_ok(test4,12,&Control,&State,4,t42,FALSE,0);
752 test_items_ok(test5,38,&Control,&State,1,t51,FALSE,0);
753 test_items_ok(test6,5,&Control,&State,2,t62,FALSE,0);
754 test_items_ok(test7,29,&Control,&State,3,t73,FALSE,0);
755 test_items_ok(test8,4,&Control,&State,1,t81,FALSE,0);
756 test_items_ok(test9,5,&Control,&State,2,t92,FALSE,0);
757 test_items_ok(test10,4,&Control,&State,1,t101,FALSE,0);
758 test_items_ok(test11,8,&Control,&State,1,t112,FALSE,0);
759 test_items_ok(test12,5,&Control,&State,1,t122,FALSE,0);
760 test_items_ok(test13,7,&Control,&State,1,t132,FALSE,0);
761 test_items_ok(test14,7,&Control,&State,1,t142,FALSE,0);
762 test_items_ok(test15,5,&Control,&State,1,t152,FALSE,0);
763 test_items_ok(test16,5,&Control,&State,1,t162,FALSE,0);
764 test_items_ok(test17,6,&Control,&State,1,t172,FALSE,0);
765 test_items_ok(test18,5,&Control,&State,1,t182,FALSE,0);
766 test_items_ok(test19,6,&Control,&State,1,t192,FALSE,0);
767 test_items_ok(test20,5,&Control,&State,2,t202,FALSE,0);
768 test_items_ok(test21,5,&Control,&State,1,t211,FALSE,0);
769 test_items_ok(test22,6,&Control,&State,2,t222,FALSE,b222);
770 test_items_ok(test23,6,&Control,&State,2,t232,FALSE,0);
771 test_items_ok(test24,12,&Control,&State,1,t242,FALSE,0);
772 test_items_ok(test25,10,&Control,&State,1,t252,FALSE,0);
773 test_items_ok(test26,2,&Control,&State,1,t262,FALSE,0);
774 test_items_ok(test27,8,&Control,&State,1,t272,FALSE,0);
775 test_items_ok(test28,4,&Control,&State,1,t282,FALSE,0);
776 test_items_ok(test29,10,&Control,&State,2,t292,FALSE,0);
777 test_items_ok(test30,8,&Control,&State,1,t302,FALSE,0);
778 test_items_ok(test31,8,&Control,&State,1,t312,FALSE,b312);
779 test_items_ok(test32,3,&Control,&State,1,t322,FALSE,0);
780 test_items_ok(test33,4,&Control,&State,1,t332,FALSE,0);
781 test_items_ok(test34,3,&Control,&State,1,t342,FALSE,b342);
782 test_items_ok(test35,13,&Control,&State,1,t352,FALSE,b352);
783 test_items_ok(test36,7,&Control,&State,1,t362,FALSE,0);
784 test_items_ok(test37,3,&Control,&State,1,t372,FALSE,0);
785 test_items_ok(test38,2,&Control,&State,1,t382,FALSE,0);
786 test_items_ok(test39,10,&Control,&State,1,t392,FALSE,0);
787 test_items_ok(test40,6,&Control,&State,1,t402,FALSE,0);
788 test_items_ok(test41,6,&Control,&State,3,t412,FALSE,b412);
789 test_items_ok(test42,6,&Control,&State,1,t422,FALSE,0);
790 test_items_ok(test43,7,&Control,&State,1,t432,FALSE,0);
791 test_items_ok(test44,4,&Control,&State,2,t442,FALSE,0);
792 test_items_ok(test45,24,&Control,&State,1,t452,FALSE,0);
793 test_items_ok(test46,16,&Control,&State,1,t462,FALSE,0);
794 test_items_ok(test47,26,&Control,&State,1,t472,FALSE,0);
795 test_items_ok(test56,6,&Control,&State,1,t561,FALSE,0);
796 test_items_ok(test57,13,&Control,&State,7,t571,FALSE,0);
797 test_items_ok(test58,13,&Control,&State,1,t581,FALSE,0);
798
799 State.uBidiLevel = 1;
800 Control.fMergeNeutralItems = TRUE;
801 test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0);
802 test_items_ok(test1b,4,&Control,&State,1,t1b2,FALSE,0);
803 test_items_ok(test1c,6,&Control,&State,3,t1c2,FALSE,0);
804 test_items_ok(test2,16,&Control,&State,4,t23,FALSE,0);
805 test_items_ok(test2b,11,&Control,&State,2,t2b3,FALSE,b2);
806 test_items_ok(test2c,11,&Control,&State,2,t2c4,FALSE,b2);
807 test_items_ok(test2d,11,&Control,&State,2,t2d4,FALSE,b2);
808 test_items_ok(test3,41,&Control,&State,1,t32,FALSE,0);
809 test_items_ok(test4,12,&Control,&State,3,t43,FALSE,b43);
810 test_items_ok(test5,38,&Control,&State,1,t51,FALSE,0);
811 test_items_ok(test6,5,&Control,&State,1,t63,FALSE,b63);
812 test_items_ok(test7,29,&Control,&State,3,t73,FALSE,0);
813 test_items_ok(test8,4,&Control,&State,1,t81,FALSE,0);
814 test_items_ok(test9,5,&Control,&State,1,t93,FALSE,b93);
815 test_items_ok(test10,4,&Control,&State,1,t101,FALSE,0);
816 test_items_ok(test11,8,&Control,&State,1,t112,FALSE,0);
817 test_items_ok(test12,5,&Control,&State,1,t122,FALSE,0);
818 test_items_ok(test13,7,&Control,&State,1,t132,FALSE,0);
819 test_items_ok(test14,7,&Control,&State,1,t142,FALSE,0);
820 test_items_ok(test15,5,&Control,&State,1,t152,FALSE,0);
821 test_items_ok(test16,5,&Control,&State,1,t162,FALSE,0);
822 test_items_ok(test17,6,&Control,&State,1,t172,FALSE,0);
823 test_items_ok(test18,5,&Control,&State,1,t182,FALSE,0);
824 test_items_ok(test19,6,&Control,&State,1,t192,FALSE,0);
825 test_items_ok(test20,5,&Control,&State,2,t202,FALSE,0);
826 test_items_ok(test21,5,&Control,&State,1,t211,FALSE,0);
827 test_items_ok(test22,6,&Control,&State,1,t223,FALSE,b223);
828 test_items_ok(test23,6,&Control,&State,2,t232,FALSE,0);
829 test_items_ok(test24,12,&Control,&State,1,t242,FALSE,0);
830 test_items_ok(test25,10,&Control,&State,1,t252,FALSE,0);
831 test_items_ok(test26,2,&Control,&State,1,t262,FALSE,0);
832 test_items_ok(test27,8,&Control,&State,1,t272,FALSE,0);
833 test_items_ok(test28,4,&Control,&State,1,t282,FALSE,0);
834 test_items_ok(test29,10,&Control,&State,2,t292,FALSE,0);
835 test_items_ok(test30,8,&Control,&State,1,t302,FALSE,0);
836 test_items_ok(test31,8,&Control,&State,1,t312,FALSE,b312);
837 test_items_ok(test32,3,&Control,&State,1,t322,FALSE,0);
838 test_items_ok(test33,4,&Control,&State,1,t332,FALSE,0);
839 test_items_ok(test34,3,&Control,&State,1,t342,FALSE,b342);
840 test_items_ok(test35,13,&Control,&State,1,t352,FALSE,b352);
841 test_items_ok(test36,7,&Control,&State,1,t362,FALSE,0);
842 test_items_ok(test37,3,&Control,&State,1,t372,FALSE,0);
843 test_items_ok(test38,2,&Control,&State,1,t382,FALSE,0);
844 test_items_ok(test39,10,&Control,&State,1,t392,FALSE,0);
845 test_items_ok(test40,6,&Control,&State,1,t402,FALSE,0);
846 test_items_ok(test41,6,&Control,&State,3,t412,FALSE,b412);
847 test_items_ok(test42,6,&Control,&State,1,t422,FALSE,0);
848 test_items_ok(test43,7,&Control,&State,1,t432,FALSE,0);
849 test_items_ok(test44,4,&Control,&State,2,t442,FALSE,0);
850 test_items_ok(test45,24,&Control,&State,1,t452,FALSE,0);
851 test_items_ok(test46,16,&Control,&State,1,t462,FALSE,0);
852 test_items_ok(test47,26,&Control,&State,1,t472,FALSE,0);
853 test_items_ok(test56,6,&Control,&State,1,t561,FALSE,0);
854 test_items_ok(test57,13,&Control,&State,7,t571,FALSE,0);
855 test_items_ok(test58,13,&Control,&State,1,t581,FALSE,0);
856
857 State.uBidiLevel = 0;
858 Control.fMergeNeutralItems = FALSE;
859 State.fOverrideDirection = 1;
860 test_items_ok(test1,4,&Control,&State,1,t11,FALSE,0);
861 test_items_ok(test1b,4,&Control,&State,1,t1b1,FALSE,0);
862 test_items_ok(test1c,6,&Control,&State,1,t1c1,FALSE,0);
863 test_items_ok(test2,16,&Control,&State,4,t24,FALSE,0);
864 test_items_ok(test2b,11,&Control,&State,4,t2b4,FALSE,0);
865 test_items_ok(test2c,11,&Control,&State,4,t2c5,FALSE,0);
866 test_items_ok(test2d,11,&Control,&State,4,t2d5,FALSE,0);
867 test_items_ok(test3,41,&Control,&State,1,t31,FALSE,0);
868 test_items_ok(test4,12,&Control,&State,5,t41,FALSE,0);
869 test_items_ok(test5,38,&Control,&State,1,t52,FALSE,0);
870 test_items_ok(test6,5,&Control,&State,2,t64,FALSE,0);
871 test_items_ok(test7,29,&Control,&State,3,t74,FALSE,0);
872 test_items_ok(test8,4,&Control,&State,1,t82,FALSE,0);
873 test_items_ok(test9,5,&Control,&State,2,t94,FALSE,0);
874 test_items_ok(test10,4,&Control,&State,1,t102,FALSE,0);
875 test_items_ok(test11,8,&Control,&State,1,t111,FALSE,0);
876 test_items_ok(test12,5,&Control,&State,1,t121,FALSE,0);
877 test_items_ok(test13,7,&Control,&State,1,t131,FALSE,0);
878 test_items_ok(test14,7,&Control,&State,1,t141,FALSE,0);
879 test_items_ok(test15,5,&Control,&State,1,t151,FALSE,0);
880 test_items_ok(test16,5,&Control,&State,1,t161,FALSE,0);
881 test_items_ok(test17,6,&Control,&State,1,t171,FALSE,0);
882 test_items_ok(test18,5,&Control,&State,1,t181,FALSE,0);
883 test_items_ok(test19,6,&Control,&State,1,t191,FALSE,0);
884 test_items_ok(test20,5,&Control,&State,2,t201,FALSE,0);
885 test_items_ok(test21,5,&Control,&State,1,t212,FALSE,0);
886 test_items_ok(test22,6,&Control,&State,2,t221,FALSE,0);
887 test_items_ok(test23,6,&Control,&State,2,t231,FALSE,0);
888 test_items_ok(test24,12,&Control,&State,1,t241,FALSE,0);
889 test_items_ok(test25,10,&Control,&State,1,t251,FALSE,0);
890 test_items_ok(test26,2,&Control,&State,1,t261,FALSE,0);
891 test_items_ok(test27,8,&Control,&State,1,t271,FALSE,0);
892 test_items_ok(test28,4,&Control,&State,1,t281,FALSE,0);
893 test_items_ok(test29,10,&Control,&State,2,t291,FALSE,0);
894 test_items_ok(test30,8,&Control,&State,1,t301,FALSE,0);
895 test_items_ok(test31,8,&Control,&State,1,t311,FALSE,b311);
896 test_items_ok(test32,3,&Control,&State,1,t321,FALSE,0);
897 test_items_ok(test33,4,&Control,&State,1,t331,FALSE,0);
898 test_items_ok(test34,3,&Control,&State,1,t341,FALSE,0);
899 test_items_ok(test35,13,&Control,&State,1,t353,FALSE,b351);
900 test_items_ok(test36,7,&Control,&State,1,t361,FALSE,0);
901 test_items_ok(test37,3,&Control,&State,1,t373,FALSE,0);
902 test_items_ok(test38,2,&Control,&State,1,t381,FALSE,0);
903 test_items_ok(test39,10,&Control,&State,1,t391,FALSE,0);
904 test_items_ok(test40,6,&Control,&State,1,t401,FALSE,0);
905 test_items_ok(test41,6,&Control,&State,1,t411,FALSE,0);
906 test_items_ok(test42,6,&Control,&State,1,t421,FALSE,0);
907 test_items_ok(test43,7,&Control,&State,1,t431,FALSE,0);
908 test_items_ok(test44,4,&Control,&State,2,t441,FALSE,0);
909 test_items_ok(test45,24,&Control,&State,1,t451,FALSE,0);
910 test_items_ok(test46,16,&Control,&State,1,t461,FALSE,0);
911 test_items_ok(test47,26,&Control,&State,1,t471,FALSE,0);
912 test_items_ok(test48,6,&Control,&State,3,t482,FALSE,0);
913 test_items_ok(test49,7,&Control,&State,2,t492,FALSE,0);
914 test_items_ok(test50,6,&Control,&State,3,t502,FALSE,0);
915 test_items_ok(test51,7,&Control,&State,4,t512,FALSE,0);
916 test_items_ok(test52,7,&Control,&State,4,t522,FALSE,0);
917 test_items_ok(test53,8,&Control,&State,4,t532,FALSE,0);
918 test_items_ok(test54,7,&Control,&State,2,t542,FALSE,0);
919 test_items_ok(test55,8,&Control,&State,2,t552,FALSE,0);
920 test_items_ok(test56,6,&Control,&State,1,t562,FALSE,0);
921 test_items_ok(test57,13,&Control,&State,7,t573,FALSE,0);
922 test_items_ok(test58,13,&Control,&State,1,t582,FALSE,0);
923 }
924
925 static void make_surrogate(DWORD i, WORD out[2])
926 {
927 static const DWORD mask = (1 << 10) - 1;
928
929 if (i <= 0xffff)
930 {
931 out[0] = i;
932 out[1] = 0;
933 }
934 else
935 {
936 i -= 0x010000;
937 out[0] = ((i >> 10) & mask) + 0xd800;
938 out[1] = (i & mask) + 0xdc00;
939 }
940 }
941
942 static void test_ScriptItemize_surrogates(void)
943 {
944 HRESULT hr;
945 WCHAR surrogate[2];
946 WORD Script_Surrogates;
947 SCRIPT_ITEM items[2];
948 int num;
949
950 /* Find Script_Surrogates */
951 surrogate[0] = 0xd800;
952 hr = ScriptItemize( surrogate, 1, 2, NULL, NULL, items, &num );
953 ok( hr == S_OK, "got %08x\n", hr );
954 ok( num == 1, "got %d\n", num );
955 ok( items[0].a.eScript != SCRIPT_UNDEFINED, "got script %x\n", items[0].a.eScript );
956 Script_Surrogates = items[0].a.eScript;
957
958 /* Show that an invalid character has script Script_Surrogates */
959 make_surrogate( 0x01ffff, surrogate );
960 hr = ScriptItemize( surrogate, 2, 2, NULL, NULL, items, &num );
961 ok( hr == S_OK, "got %08x\n", hr );
962 ok( num == 1, "got %d\n", num );
963 ok( items[0].a.eScript == Script_Surrogates, "got script %x\n", items[0].a.eScript );
964 }
965
966 static inline void _test_shape_ok(int valid, HDC hdc, LPCWSTR string,
967 DWORD cchString, SCRIPT_CONTROL *Control,
968 SCRIPT_STATE *State, DWORD item, DWORD nGlyphs,
969 const shapeTest_char *charItems,
970 const shapeTest_glyph *glyphItems,
971 const SCRIPT_GLYPHPROP *props2)
972 {
973 HRESULT hr;
974 int x, outnItems = 0, outnGlyphs = 0, outnGlyphs2 = 0;
975 const SCRIPT_PROPERTIES **script_properties;
976 SCRIPT_ITEM outpItems[15];
977 SCRIPT_CACHE sc = NULL;
978 WORD *glyphs, *glyphs2;
979 WORD *logclust, *logclust2;
980 int maxGlyphs = cchString * 1.5;
981 SCRIPT_GLYPHPROP *glyphProp, *glyphProp2;
982 SCRIPT_CHARPROP *charProp, *charProp2;
983 int script_count;
984 WCHAR *string2;
985 ULONG tags[15];
986
987 hr = ScriptGetProperties(&script_properties, &script_count);
988 winetest_ok(SUCCEEDED(hr), "Failed to get script properties, hr %#x.\n", hr);
989
990 hr = pScriptItemizeOpenType(string, cchString, 15, Control, State, outpItems, tags, &outnItems);
991 if (valid > 0)
992 winetest_ok(hr == S_OK, "ScriptItemizeOpenType should return S_OK not %08x\n", hr);
993 else if (hr != S_OK)
994 winetest_trace("ScriptItemizeOpenType should return S_OK not %08x\n", hr);
995
996 if (outnItems <= item)
997 {
998 if (valid > 0)
999 winetest_win_skip("Did not get enough items\n");
1000 else
1001 winetest_trace("Did not get enough items\n");
1002 return;
1003 }
1004
1005 logclust = HeapAlloc(GetProcessHeap(), 0, sizeof(WORD) * cchString);
1006 memset(logclust,'a',sizeof(WORD) * cchString);
1007 charProp = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPT_CHARPROP) * cchString);
1008 memset(charProp,'a',sizeof(SCRIPT_CHARPROP) * cchString);
1009 glyphs = HeapAlloc(GetProcessHeap(), 0, sizeof(WORD) * maxGlyphs);
1010 memset(glyphs,'a',sizeof(WORD) * cchString);
1011 glyphProp = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPT_GLYPHPROP) * maxGlyphs);
1012 memset(glyphProp,'a',sizeof(SCRIPT_GLYPHPROP) * cchString);
1013
1014 string2 = HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(*string2));
1015 logclust2 = HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(*logclust2));
1016 memset(logclust2, 'a', cchString * sizeof(*logclust2));
1017 charProp2 = HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(*charProp2));
1018 memset(charProp2, 'a', cchString * sizeof(*charProp2));
1019 glyphs2 = HeapAlloc(GetProcessHeap(), 0, maxGlyphs * sizeof(*glyphs2));
1020 memset(glyphs2, 'a', maxGlyphs * sizeof(*glyphs2));
1021 glyphProp2 = HeapAlloc(GetProcessHeap(), 0, maxGlyphs * sizeof(*glyphProp2));
1022 memset(glyphProp2, 'a', maxGlyphs * sizeof(*glyphProp2));
1023
1024 winetest_ok(!outpItems[item].a.fLogicalOrder, "Got unexpected fLogicalOrder %#x.\n",
1025 outpItems[item].a.fLogicalOrder);
1026 hr = pScriptShapeOpenType(hdc, &sc, &outpItems[item].a, tags[item], 0x00000000, NULL, NULL, 0, string, cchString, maxGlyphs, logclust, charProp, glyphs, glyphProp, &outnGlyphs);
1027 if (valid > 0)
1028 winetest_ok(hr == S_OK, "ScriptShapeOpenType failed (%x)\n",hr);
1029 else if (hr != S_OK)
1030 winetest_trace("ScriptShapeOpenType failed (%x)\n",hr);
1031 if (FAILED(hr))
1032 goto cleanup;
1033
1034 for (x = 0; x < cchString; x++)
1035 {
1036 if (valid > 0)
1037 winetest_ok(logclust[x] == charItems[x].wLogClust, "%i: invalid LogClust(%i)\n",x,logclust[x]);
1038 else if (logclust[x] != charItems[x].wLogClust)
1039 winetest_trace("%i: invalid LogClust(%i)\n",x,logclust[x]);
1040 if (valid > 0)
1041 winetest_ok(charProp[x].fCanGlyphAlone == charItems[x].CharProp.fCanGlyphAlone, "%i: invalid fCanGlyphAlone\n",x);
1042 else if (charProp[x].fCanGlyphAlone != charItems[x].CharProp.fCanGlyphAlone)
1043 winetest_trace("%i: invalid fCanGlyphAlone\n",x);
1044 }
1045
1046 if (valid > 0)
1047 winetest_ok(nGlyphs == outnGlyphs, "got incorrect number of glyphs (%i)\n",outnGlyphs);
1048 else if (nGlyphs != outnGlyphs)
1049 winetest_trace("got incorrect number of glyphs (%i)\n",outnGlyphs);
1050 for (x = 0; x < outnGlyphs; x++)
1051 {
1052 if (glyphItems[x].Glyph)
1053 {
1054 if (valid > 0)
1055 winetest_ok(glyphs[x]!=0, "%i: Glyph not present when it should be\n",x);
1056 else if (glyphs[x]==0)
1057 winetest_trace("%i: Glyph not present when it should be\n",x);
1058 }
1059 else
1060 {
1061 if (valid > 0)
1062 winetest_ok(glyphs[x]==0, "%i: Glyph present when it should not be\n",x);
1063 else if (glyphs[x]!=0)
1064 winetest_trace("%i: Glyph present when it should not be\n",x);
1065 }
1066 if (valid > 0)
1067 {
1068 todo_wine_if(tags[item] == syrc_tag && !x)
1069 winetest_ok(glyphProp[x].sva.uJustification == glyphItems[x].GlyphProp.sva.uJustification ||
1070 (props2 && glyphProp[x].sva.uJustification == props2[x].sva.uJustification),
1071 "%i: uJustification incorrect (%i)\n",x,glyphProp[x].sva.uJustification);
1072 }
1073 else if (glyphProp[x].sva.uJustification != glyphItems[x].GlyphProp.sva.uJustification)
1074 {
1075 winetest_trace("%i: uJustification incorrect (%i)\n",x,glyphProp[x].sva.uJustification);
1076 }
1077 if (valid > 0)
1078 winetest_ok(glyphProp[x].sva.fClusterStart == glyphItems[x].GlyphProp.sva.fClusterStart ||
1079 (props2 && glyphProp[x].sva.fClusterStart == props2[x].sva.fClusterStart),
1080 "%i: fClusterStart incorrect (%i)\n",x,glyphProp[x].sva.fClusterStart);
1081 else if (glyphProp[x].sva.fClusterStart != glyphItems[x].GlyphProp.sva.fClusterStart)
1082 winetest_trace("%i: fClusterStart incorrect (%i)\n",x,glyphProp[x].sva.fClusterStart);
1083 if (valid > 0)
1084 winetest_ok(glyphProp[x].sva.fDiacritic == glyphItems[x].GlyphProp.sva.fDiacritic ||
1085 (props2 && glyphProp[x].sva.fDiacritic == props2[x].sva.fDiacritic),
1086 "%i: fDiacritic incorrect (%i)\n",x,glyphProp[x].sva.fDiacritic);
1087 else if (glyphProp[x].sva.fDiacritic != glyphItems[x].GlyphProp.sva.fDiacritic)
1088 winetest_trace("%i: fDiacritic incorrect (%i)\n",x,glyphProp[x].sva.fDiacritic);
1089 if (valid > 0)
1090 winetest_ok(glyphProp[x].sva.fZeroWidth == glyphItems[x].GlyphProp.sva.fZeroWidth ||
1091 (props2 && glyphProp[x].sva.fZeroWidth == props2[x].sva.fZeroWidth),
1092 "%i: fZeroWidth incorrect (%i)\n",x,glyphProp[x].sva.fZeroWidth);
1093 else if (glyphProp[x].sva.fZeroWidth != glyphItems[x].GlyphProp.sva.fZeroWidth)
1094 winetest_trace("%i: fZeroWidth incorrect (%i)\n",x,glyphProp[x].sva.fZeroWidth);
1095 }
1096
1097 outpItems[item].a.fLogicalOrder = 1;
1098 hr = pScriptShapeOpenType(hdc, &sc, &outpItems[item].a, tags[item], 0x00000000, NULL, NULL, 0,
1099 string, cchString, maxGlyphs, logclust2, charProp2, glyphs2, glyphProp2, &outnGlyphs2);
1100 winetest_ok(hr == S_OK, "ScriptShapeOpenType failed (%x)\n",hr);
1101 /* Cluster maps are hard. */
1102 if (tags[item] != thaa_tag && tags[item] != syrc_tag)
1103 {
1104 for (x = 0; x < cchString; ++x)
1105 {
1106 unsigned int compare_idx = outpItems[item].a.fRTL ? cchString - x - 1 : x;
1107 winetest_ok(logclust2[x] == logclust[compare_idx],
1108 "Got unexpected logclust2[%u] %#x, expected %#x.\n",
1109 x, logclust2[x], logclust[compare_idx]);
1110 winetest_ok(charProp2[x].fCanGlyphAlone == charProp[compare_idx].fCanGlyphAlone,
1111 "Got unexpected charProp2[%u].fCanGlyphAlone %#x, expected %#x.\n",
1112 x, charProp2[x].fCanGlyphAlone, charProp[compare_idx].fCanGlyphAlone);
1113 }
1114 }
1115 winetest_ok(outnGlyphs2 == outnGlyphs, "Got unexpected glyph count %u.\n", outnGlyphs2);
1116 for (x = 0; x < outnGlyphs2; ++x)
1117 {
1118 unsigned int compare_idx = outpItems[item].a.fRTL ? outnGlyphs2 - x - 1 : x;
1119 winetest_ok(glyphs2[x] == glyphs[compare_idx], "Got unexpected glyphs2[%u] %#x, expected %#x.\n",
1120 x, glyphs2[x], glyphs[compare_idx]);
1121 winetest_ok(glyphProp2[x].sva.uJustification == glyphProp[compare_idx].sva.uJustification,
1122 "Got unexpected glyphProp2[%u].sva.uJustification %#x, expected %#x.\n",
1123 x, glyphProp2[x].sva.uJustification, glyphProp[compare_idx].sva.uJustification);
1124 winetest_ok(glyphProp2[x].sva.fClusterStart == glyphProp[compare_idx].sva.fClusterStart,
1125 "Got unexpected glyphProp2[%u].sva.fClusterStart %#x, expected %#x.\n",
1126 x, glyphProp2[x].sva.fClusterStart, glyphProp[compare_idx].sva.fClusterStart);
1127 winetest_ok(glyphProp2[x].sva.fDiacritic == glyphProp[compare_idx].sva.fDiacritic,
1128 "Got unexpected glyphProp2[%u].sva.fDiacritic %#x, expected %#x.\n",
1129 x, glyphProp2[x].sva.fDiacritic, glyphProp[compare_idx].sva.fDiacritic);
1130 winetest_ok(glyphProp2[x].sva.fZeroWidth == glyphProp[compare_idx].sva.fZeroWidth,
1131 "Got unexpected glyphProp2[%u].sva.fZeroWidth %#x, expected %#x.\n",
1132 x, glyphProp2[x].sva.fZeroWidth, glyphProp[compare_idx].sva.fZeroWidth);
1133 }
1134
1135 /* Most scripts get this wrong. For example, when the font has the
1136 * appropriate ligatures, "ttfffi" get rendered as "<ttf><ffi>", but
1137 * "<RLO>iffftt" gets rendered as "t<ft><ff>i". Arabic gets it right,
1138 * and there exist applications that depend on that. */
1139 if (tags[item] == arab_tag && broken(script_count <= 75))
1140 {
1141 winetest_win_skip("Test broken on this platform, skipping.\n");
1142 }
1143 else if (tags[item] == arab_tag)
1144 {
1145 for (x = 0; x < cchString; ++x)
1146 {
1147 string2[x] = string[cchString - x - 1];
1148 }
1149 outpItems[item].a.fLogicalOrder = 0;
1150 outpItems[item].a.fRTL = !outpItems[item].a.fRTL;
1151 hr = pScriptShapeOpenType(hdc, &sc, &outpItems[item].a, tags[item], 0x00000000, NULL, NULL, 0,
1152 string2, cchString, maxGlyphs, logclust2, charProp2, glyphs2, glyphProp2, &outnGlyphs2);
1153 winetest_ok(hr == S_OK, "ScriptShapeOpenType failed (%x)\n",hr);
1154 for (x = 0; x < cchString; ++x)
1155 {
1156 unsigned int compare_idx = cchString - x - 1;
1157 winetest_ok(logclust2[x] == logclust[compare_idx],
1158 "Got unexpected logclust2[%u] %#x, expected %#x.\n",
1159 x, logclust2[x], logclust[compare_idx]);
1160 winetest_ok(charProp2[x].fCanGlyphAlone == charProp[compare_idx].fCanGlyphAlone,
1161 "Got unexpected charProp2[%u].fCanGlyphAlone %#x, expected %#x.\n",
1162 x, charProp2[x].fCanGlyphAlone, charProp[compare_idx].fCanGlyphAlone);
1163 }
1164 winetest_ok(outnGlyphs2 == outnGlyphs, "Got unexpected glyph count %u.\n", outnGlyphs2);
1165 for (x = 0; x < outnGlyphs2; ++x)
1166 {
1167 winetest_ok(glyphs2[x] == glyphs[x], "Got unexpected glyphs2[%u] %#x, expected %#x.\n",
1168 x, glyphs2[x], glyphs[x]);
1169 winetest_ok(glyphProp2[x].sva.uJustification == glyphProp[x].sva.uJustification,
1170 "Got unexpected glyphProp2[%u].sva.uJustification %#x, expected %#x.\n",
1171 x, glyphProp2[x].sva.uJustification, glyphProp[x].sva.uJustification);
1172 winetest_ok(glyphProp2[x].sva.fClusterStart == glyphProp[x].sva.fClusterStart,
1173 "Got unexpected glyphProp2[%u].sva.fClusterStart %#x, expected %#x.\n",
1174 x, glyphProp2[x].sva.fClusterStart, glyphProp[x].sva.fClusterStart);
1175 winetest_ok(glyphProp2[x].sva.fDiacritic == glyphProp[x].sva.fDiacritic,
1176 "Got unexpected glyphProp2[%u].sva.fDiacritic %#x, expected %#x.\n",
1177 x, glyphProp2[x].sva.fDiacritic, glyphProp[x].sva.fDiacritic);
1178 winetest_ok(glyphProp2[x].sva.fZeroWidth == glyphProp[x].sva.fZeroWidth,
1179 "Got unexpected glyphProp2[%u].sva.fZeroWidth %#x, expected %#x.\n",
1180 x, glyphProp2[x].sva.fZeroWidth, glyphProp[x].sva.fZeroWidth);
1181 }
1182 outpItems[item].a.fLogicalOrder = 1;
1183 hr = pScriptShapeOpenType(hdc, &sc, &outpItems[item].a, tags[item], 0x00000000, NULL, NULL, 0,
1184 string2, cchString, maxGlyphs, logclust2, charProp2, glyphs2, glyphProp2, &outnGlyphs2);
1185 winetest_ok(hr == S_OK, "ScriptShapeOpenType failed (%x)\n",hr);
1186 for (x = 0; x < cchString; ++x)
1187 {
1188 unsigned int compare_idx = outpItems[item].a.fRTL ? x : cchString - x - 1;
1189 winetest_ok(logclust2[x] == logclust[compare_idx], "Got unexpected logclust2[%u] %#x, expected %#x.\n",
1190 x, logclust2[x], logclust[compare_idx]);
1191 winetest_ok(charProp2[x].fCanGlyphAlone == charProp[compare_idx].fCanGlyphAlone,
1192 "Got unexpected charProp2[%u].fCanGlyphAlone %#x, expected %#x.\n",
1193 x, charProp2[x].fCanGlyphAlone, charProp[compare_idx].fCanGlyphAlone);
1194 }
1195 winetest_ok(outnGlyphs2 == outnGlyphs, "Got unexpected glyph count %u.\n", outnGlyphs2);
1196 for (x = 0; x < outnGlyphs2; ++x)
1197 {
1198 unsigned int compare_idx = outpItems[item].a.fRTL ? outnGlyphs2 - x - 1 : x;
1199 winetest_ok(glyphs2[x] == glyphs[compare_idx], "Got unexpected glyphs2[%u] %#x, expected %#x.\n",
1200 x, glyphs2[x], glyphs[compare_idx]);
1201 winetest_ok(glyphProp2[x].sva.uJustification == glyphProp[compare_idx].sva.uJustification,
1202 "Got unexpected glyphProp2[%u].sva.uJustification %#x, expected %#x.\n",
1203 x, glyphProp2[x].sva.uJustification, glyphProp[compare_idx].sva.uJustification);
1204 winetest_ok(glyphProp2[x].sva.fClusterStart == glyphProp[compare_idx].sva.fClusterStart,
1205 "Got unexpected glyphProp2[%u].sva.fClusterStart %#x, expected %#x.\n",
1206 x, glyphProp2[x].sva.fClusterStart, glyphProp[compare_idx].sva.fClusterStart);
1207 winetest_ok(glyphProp2[x].sva.fDiacritic == glyphProp[compare_idx].sva.fDiacritic,
1208 "Got unexpected glyphProp2[%u].sva.fDiacritic %#x, expected %#x.\n",
1209 x, glyphProp2[x].sva.fDiacritic, glyphProp[compare_idx].sva.fDiacritic);
1210 winetest_ok(glyphProp2[x].sva.fZeroWidth == glyphProp[compare_idx].sva.fZeroWidth,
1211 "Got unexpected glyphProp2[%u].sva.fZeroWidth %#x, expected %#x.\n",
1212 x, glyphProp2[x].sva.fZeroWidth, glyphProp[compare_idx].sva.fZeroWidth);
1213 }
1214 }
1215
1216 cleanup:
1217 HeapFree(GetProcessHeap(),0,string2);
1218 HeapFree(GetProcessHeap(),0,logclust2);
1219 HeapFree(GetProcessHeap(),0,charProp2);
1220 HeapFree(GetProcessHeap(),0,glyphs2);
1221 HeapFree(GetProcessHeap(),0,glyphProp2);
1222
1223 HeapFree(GetProcessHeap(),0,logclust);
1224 HeapFree(GetProcessHeap(),0,charProp);
1225 HeapFree(GetProcessHeap(),0,glyphs);
1226 HeapFree(GetProcessHeap(),0,glyphProp);
1227 ScriptFreeCache(&sc);
1228 }
1229
1230 #define test_shape_ok(a,b,c,d,e,f,g,h,i) \
1231 (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _test_shape_ok(1,a,b,c,d,e,f,g,h,i,NULL)
1232
1233 #define test_shape_ok_valid(v,a,b,c,d,e,f,g,h,i) \
1234 (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _test_shape_ok(v,a,b,c,d,e,f,g,h,i,NULL)
1235
1236 #define test_shape_ok_valid_props2(v,a,b,c,d,e,f,g,h,i,j) \
1237 (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _test_shape_ok(v,a,b,c,d,e,f,g,h,i,j)
1238
1239 typedef struct tagRangeP {
1240 BYTE range;
1241 LOGFONTA lf;
1242 } fontEnumParam;
1243
1244 static int CALLBACK enumFontProc( const LOGFONTA *lpelfe, const TEXTMETRICA *lpntme, DWORD FontType, LPARAM lParam )
1245 {
1246 NEWTEXTMETRICEXA *ntme = (NEWTEXTMETRICEXA*)lpntme;
1247 fontEnumParam *rp = (fontEnumParam*) lParam;
1248 int idx = 0;
1249 DWORD i;
1250 DWORD mask = 0;
1251
1252 if (FontType != TRUETYPE_FONTTYPE)
1253 return 1;
1254
1255 i = rp->range;
1256 while (i >= sizeof(DWORD)*8)
1257 {
1258 idx++;
1259 i -= (sizeof(DWORD)*8);
1260 }
1261 if (idx > 3)
1262 return 0;
1263
1264 mask = 1 << i;
1265
1266 if (ntme->ntmFontSig.fsUsb[idx] & mask)
1267 {
1268 memcpy(&(rp->lf),lpelfe,sizeof(LOGFONTA));
1269 return 0;
1270 }
1271 return 1;
1272 }
1273
1274 static int _find_font_for_range(HDC hdc, const CHAR *recommended, BYTE range, const WCHAR check, HFONT *hfont, HFONT *origFont, const font_fingerprint *fingerprint)
1275 {
1276 int rc = 0;
1277 fontEnumParam lParam;
1278
1279 lParam.range = range;
1280 memset(&lParam.lf,0,sizeof(LOGFONTA));
1281 *hfont = NULL;
1282
1283 if (recommended)
1284 {
1285 lstrcpyA(lParam.lf.lfFaceName, recommended);
1286 if (!EnumFontFamiliesExA(hdc, &lParam.lf, enumFontProc, (LPARAM)&lParam, 0))
1287 {
1288 *hfont = CreateFontIndirectA(&lParam.lf);
1289 if (*hfont)
1290 {
1291 winetest_trace("using font %s\n",lParam.lf.lfFaceName);
1292 if (fingerprint)
1293 {
1294 WORD output[10];
1295 int i;
1296
1297 *origFont = SelectObject(hdc,*hfont);
1298 if (GetGlyphIndicesW(hdc, fingerprint->check, 10, output, 0) != GDI_ERROR)
1299 {
1300 for (i=0; i < 10; i++)
1301 if (output[i] != fingerprint->result[i])
1302 {
1303 winetest_trace("found font does not match fingerprint\n");
1304 SelectObject(hdc,*origFont);
1305 DeleteObject(*hfont);
1306 *hfont = NULL;
1307 break;
1308 }
1309 if (i == 10) rc = 1;
1310 }
1311 SelectObject(hdc, *origFont);
1312 }
1313 else rc = 1;
1314 }
1315 }
1316 if (!rc)
1317 winetest_skip("Font %s is not available.\n", recommended);
1318 }
1319
1320 if (!*hfont)
1321 {
1322 memset(&lParam.lf,0,sizeof(LOGFONTA));
1323 lParam.lf.lfCharSet = DEFAULT_CHARSET;
1324
1325 if (!EnumFontFamiliesExA(hdc, &lParam.lf, enumFontProc, (LPARAM)&lParam, 0) && lParam.lf.lfFaceName[0])
1326 {
1327 *hfont = CreateFontIndirectA(&lParam.lf);
1328 if (*hfont)
1329 winetest_trace("trying font %s: failures will only be warnings\n",lParam.lf.lfFaceName);
1330 }
1331 }
1332
1333 if (*hfont)
1334 {
1335 WORD glyph = 0;
1336
1337 *origFont = SelectObject(hdc,*hfont);
1338 if (GetGlyphIndicesW(hdc, &check, 1, &glyph, 0) == GDI_ERROR || glyph == 0)
1339 {
1340 winetest_trace(" Font fails to contain required glyphs\n");
1341 SelectObject(hdc,*origFont);
1342 DeleteObject(*hfont);
1343 *hfont=NULL;
1344 rc = 0;
1345 }
1346 else if (!rc)
1347 rc = -1;
1348 }
1349 else
1350 winetest_trace("Failed to find usable font\n");
1351
1352 return rc;
1353 }
1354
1355 #define find_font_for_range(a,b,c,d,e,f,g) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _find_font_for_range(a,b,c,d,e,f,g)
1356
1357 static void test_ScriptShapeOpenType(HDC hdc)
1358 {
1359 HRESULT hr;
1360 SCRIPT_CACHE sc = NULL;
1361 WORD glyphs[4], logclust[4];
1362 SCRIPT_GLYPHPROP glyphProp[4];
1363 SCRIPT_ITEM items[2];
1364 ULONG tags[2];
1365 SCRIPT_CONTROL Control;
1366 SCRIPT_STATE State;
1367 int nb, outnItems;
1368 HFONT hfont, hfont_orig;
1369 int test_valid;
1370 shapeTest_glyph glyph_test[4];
1371
1372 static const WCHAR test1[] = {'w', 'i', 'n', 'e',0};
1373 static const shapeTest_char t1_c[] = {{0,{0,0}},{1,{0,0}},{2,{0,0}},{3,{0,0}}};
1374 static const shapeTest_glyph t1_g[] = {
1375 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1376 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1377 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1378 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}} };
1379
1380 static const WCHAR test2[] = {0x202B, 'i', 'n', 0x202C,0};
1381 static const shapeTest_char t2_c[] = {{0,{0,0}},{1,{0,0}},{2,{0,0}},{3,{0,0}}};
1382 static const shapeTest_glyph t2_g[] = {
1383 {0,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1384 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1385 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1386 {0,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}} };
1387
1388 static const WCHAR test3[] = {'t', 't', 'f', 'f', 'f', 'i', 0};
1389 static const shapeTest_char t3_c[] = {{0, {0, 0}}, {0, {0, 0}}, {0, {0, 0}},
1390 {1, {0, 0}}, {1, {0, 0}}, {1, {0, 0}}};
1391 static const shapeTest_glyph t3_g[] = {
1392 {1, {{SCRIPT_JUSTIFY_CHARACTER, 1, 0, 0, 0, 0}, 0}},
1393 {1, {{SCRIPT_JUSTIFY_CHARACTER, 1, 0, 0, 0, 0}, 0}}};
1394
1395 /* Hebrew */
1396 static const WCHAR test_hebrew[] = {0x05e9, 0x05dc, 0x05d5, 0x05dd,0};
1397 static const shapeTest_char hebrew_c[] = {{3,{0,0}},{2,{0,0}},{1,{0,0}},{0,{0,0}}};
1398 static const shapeTest_glyph hebrew_g[] = {
1399 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1400 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1401 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1402 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}} };
1403
1404 /* Arabic */
1405 static const WCHAR test_arabic[] = {0x0633,0x0644,0x0627,0x0645,0};
1406 static const shapeTest_char arabic_c[] = {{2,{0,0}},{1,{0,0}},{1,{0,0}},{0,{0,0}}};
1407 static const shapeTest_glyph arabic_g[] = {
1408 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1409 {1,{{SCRIPT_JUSTIFY_ARABIC_NORMAL,1,0,0,0,0},0}},
1410 {1,{{SCRIPT_JUSTIFY_ARABIC_SEEN,1,0,0,0,0},0}} };
1411
1412 /* Thai */
1413 static const WCHAR test_thai[] = {0x0e2a, 0x0e04, 0x0e23, 0x0e34, 0x0e1b, 0x0e15, 0x0e4c, 0x0e44, 0x0e17, 0x0e22,};
1414 static const shapeTest_char thai_c[] = {{0,{0,0}},{1,{0,0}},{2,{0,0}},{2,{0,0}},{4,{0,0}},{5,{0,0}},{5,{0,0}},{7,{0,0}},{8,{0,0}},{9,{0,0}}};
1415 static const shapeTest_glyph thai_g[] = {
1416 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1417 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1418 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1419 {1,{{SCRIPT_JUSTIFY_CHARACTER,0,1,1,0,0},0}},
1420 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1421 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1422 {1,{{SCRIPT_JUSTIFY_CHARACTER,0,1,1,0,0},0}},
1423 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1424 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1425 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}}};
1426
1427 /* Syriac */
1428 static const WCHAR test_syriac[] = {0x0710, 0x072c, 0x0728, 0x0742, 0x0718, 0x0723, 0x0720, 0x0710, 0};
1429 static const shapeTest_char syriac_c[] = {{6, {0, 0}}, {5, {0, 0}}, {4, {0, 0}},
1430 {4, {0, 0}}, {2, {0, 0}}, {1, {0, 0}}, {0, {0, 0}}, {0, {0, 0}}};
1431 static const shapeTest_glyph syriac_g[] = {
1432 {1,{{SCRIPT_JUSTIFY_ARABIC_NORMAL,1,0,0,0,0},0}},
1433 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1434 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1435 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1436 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1437 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1438 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}} };
1439
1440 /* Thaana */
1441 static const WCHAR test_thaana[] = {0x078a, 0x07ae, 0x0792, 0x07b0, 0x0020, 0x0796, 0x07aa, 0x0789, 0x07b0, 0x0795, 0x07ac, 0x0791, 0x07b0};
1442 static const shapeTest_char thaana_c[] = {{12,{0,0}},{12,{0,0}},{10,{0,0}},{10,{0,0}},{8,{1,0}},{7,{0,0}},{7,{0,0}},{5,{0,0}},{5,{0,0}},{3,{0,0}},{3,{0,0}},{1,{0,0}},{1,{0,0}}};
1443 static const shapeTest_glyph thaana_g[] = {
1444 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1445 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1446 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1447 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1448 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1449 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1450 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1451 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1452 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1453 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1454 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}},
1455 {1,{{SCRIPT_JUSTIFY_NONE,0,1,1,0,0},0}},
1456 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}} };
1457
1458 /* Phags-pa */
1459 static const WCHAR test_phagspa[] = {0xa84f, 0xa861, 0xa843, 0x0020, 0xa863, 0xa861, 0xa859, 0x0020, 0xa850, 0xa85c, 0xa85e};
1460 static const shapeTest_char phagspa_c[] = {{0,{0,0}},{1,{0,0}},{2,{0,0}},{3,{1,0}},{4,{0,0}},{5,{0,0}},{6,{0,0}},{7,{1,0}},{8,{0,0}},{9,{0,0}},{10,{0,0}}};
1461 static const shapeTest_glyph phagspa_g[] = {
1462 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1463 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1464 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1465 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1466 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1467 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1468 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1469 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1470 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1471 {1,{{SCRIPT_JUSTIFY_CHARACTER,1,0,0,0,0},0}},
1472 {1,{{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0}} };
1473 static const SCRIPT_GLYPHPROP phagspa_win10_props[] = {
1474 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1475 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1476 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1477 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1478 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1479 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1480 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1481 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1482 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1483 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0},
1484 {{SCRIPT_JUSTIFY_NONE,1,0,0,0,0},0} };
1485
1486 /* Lao */
1487 static const WCHAR test_lao[] = {0x0ead, 0x0eb1, 0x0e81, 0x0eaa, 0x0ead, 0x0e99, 0x0ea5, 0x0eb2, 0x0ea7, 0};
1488 static const shapeTest_char lao_c[] = {{0,{0,0}},{0,{0,0}},{2,{0,0}},{3,{0,0}},{4,{0,0}},{5,{0,0}},{6,{