1 /*
2  * Unit test suite for string format
3  *
4  * Copyright (C) 2007 Google (Evan Stade)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "precomp.h"
22 
23 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
24 #define expectf(expected, got) ok(got == expected, "Expected %.2f, got %.2f\n", expected, got)
25 
26 static void test_constructor(void)
27 {
28     GpStringFormat *format;
29     GpStatus stat;
30     INT n, count;
31     StringAlignment align, line_align;
32     StringTrimming trimming;
33     StringDigitSubstitute digitsub;
34     LANGID digitlang;
35 
36     stat = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
37     expect(Ok, stat);
38 
39     GdipGetStringFormatAlign(format, &align);
40     GdipGetStringFormatLineAlign(format, &line_align);
41     GdipGetStringFormatHotkeyPrefix(format, &n);
42     GdipGetStringFormatTrimming(format, &trimming);
43     GdipGetStringFormatDigitSubstitution(format, &digitlang, &digitsub);
44     GdipGetStringFormatMeasurableCharacterRangeCount(format, &count);
45 
46     expect(HotkeyPrefixNone, n);
47     expect(StringAlignmentNear, align);
48     expect(StringAlignmentNear, line_align);
49     expect(StringTrimmingCharacter, trimming);
50     expect(StringDigitSubstituteUser, digitsub);
51     expect(LANG_NEUTRAL, digitlang);
52     expect(0, count);
53 
54     stat = GdipDeleteStringFormat(format);
55     expect(Ok, stat);
56 }
57 
58 static void test_characterrange(void)
59 {
60     CharacterRange ranges[3];
61     INT count;
62     GpStringFormat* format;
63     GpStatus stat;
64 
65     stat = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
66     expect(Ok, stat);
67     stat = GdipSetStringFormatMeasurableCharacterRanges(NULL, 3, ranges);
68     expect(InvalidParameter, stat);
69     stat = GdipSetStringFormatMeasurableCharacterRanges(format, 0, ranges);
70     expect(Ok, stat);
71     stat = GdipSetStringFormatMeasurableCharacterRanges(format, 3, NULL);
72     expect(InvalidParameter, stat);
73 
74     stat = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges);
75     expect(Ok, stat);
76     stat = GdipGetStringFormatMeasurableCharacterRangeCount(format, &count);
77     expect(Ok, stat);
78     if (stat == Ok) expect(3, count);
79 
80     stat= GdipDeleteStringFormat(format);
81     expect(Ok, stat);
82 }
83 
84 static void test_digitsubstitution(void)
85 {
86     GpStringFormat *format;
87     GpStatus stat;
88     StringDigitSubstitute digitsub;
89     LANGID digitlang;
90 
91     stat = GdipCreateStringFormat(0, LANG_RUSSIAN, &format);
92     expect(Ok, stat);
93 
94     /* NULL arguments */
95     stat = GdipGetStringFormatDigitSubstitution(NULL, NULL, NULL);
96     expect(InvalidParameter, stat);
97     stat = GdipGetStringFormatDigitSubstitution(format, NULL, NULL);
98     expect(Ok, stat);
99     stat = GdipGetStringFormatDigitSubstitution(NULL, &digitlang, NULL);
100     expect(InvalidParameter, stat);
101     stat = GdipGetStringFormatDigitSubstitution(NULL, NULL, &digitsub);
102     expect(InvalidParameter, stat);
103     stat = GdipGetStringFormatDigitSubstitution(NULL, &digitlang, &digitsub);
104     expect(InvalidParameter, stat);
105     stat = GdipSetStringFormatDigitSubstitution(NULL, LANG_NEUTRAL, StringDigitSubstituteNone);
106     expect(InvalidParameter, stat);
107 
108     /* try to get both and one by one */
109     stat = GdipGetStringFormatDigitSubstitution(format, &digitlang, &digitsub);
110     expect(Ok, stat);
111     expect(StringDigitSubstituteUser, digitsub);
112     expect(LANG_NEUTRAL, digitlang);
113 
114     digitsub  = StringDigitSubstituteNone;
115     stat = GdipGetStringFormatDigitSubstitution(format, NULL, &digitsub);
116     expect(Ok, stat);
117     expect(StringDigitSubstituteUser, digitsub);
118 
119     digitlang = LANG_RUSSIAN;
120     stat = GdipGetStringFormatDigitSubstitution(format, &digitlang, NULL);
121     expect(Ok, stat);
122     expect(LANG_NEUTRAL, digitlang);
123 
124     /* set/get */
125     stat = GdipSetStringFormatDigitSubstitution(format, MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL),
126                                                         StringDigitSubstituteUser);
127     expect(Ok, stat);
128     digitsub  = StringDigitSubstituteNone;
129     digitlang = LANG_RUSSIAN;
130     stat = GdipGetStringFormatDigitSubstitution(format, &digitlang, &digitsub);
131     expect(Ok, stat);
132     expect(StringDigitSubstituteUser, digitsub);
133     expect(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL), digitlang);
134 
135     stat = GdipDeleteStringFormat(format);
136     expect(Ok, stat);
137 }
138 
139 static void test_getgenerictypographic(void)
140 {
141     GpStringFormat *format, *format2;
142     GpStatus stat;
143     INT flags;
144     INT n;
145     StringAlignment align, line_align;
146     StringTrimming trimming;
147     StringDigitSubstitute digitsub;
148     LANGID digitlang;
149     INT tabcount;
150 
151     /* NULL arg */
152     stat = GdipStringFormatGetGenericTypographic(NULL);
153     expect(InvalidParameter, stat);
154 
155     stat = GdipStringFormatGetGenericTypographic(&format);
156     expect(Ok, stat);
157 
158     stat = GdipStringFormatGetGenericTypographic(&format2);
159     expect(Ok, stat);
160     ok(format == format2, "expected same format object\n");
161     stat = GdipDeleteStringFormat(format2);
162     expect(Ok, stat);
163 
164     GdipGetStringFormatFlags(format, &flags);
165     GdipGetStringFormatAlign(format, &align);
166     GdipGetStringFormatLineAlign(format, &line_align);
167     GdipGetStringFormatHotkeyPrefix(format, &n);
168     GdipGetStringFormatTrimming(format, &trimming);
169     GdipGetStringFormatDigitSubstitution(format, &digitlang, &digitsub);
170     GdipGetStringFormatTabStopCount(format, &tabcount);
171 
172     expect((StringFormatFlagsNoFitBlackBox |StringFormatFlagsLineLimit | StringFormatFlagsNoClip),
173             flags);
174     expect(HotkeyPrefixNone, n);
175     expect(StringAlignmentNear, align);
176     expect(StringAlignmentNear, line_align);
177     expect(StringTrimmingNone, trimming);
178     expect(StringDigitSubstituteUser, digitsub);
179     expect(LANG_NEUTRAL, digitlang);
180     expect(0, tabcount);
181 
182     /* Change format parameters, release, get format object again. */
183     stat = GdipSetStringFormatFlags(format, StringFormatFlagsNoWrap);
184     expect(Ok, stat);
185 
186     stat = GdipGetStringFormatFlags(format, &flags);
187     expect(Ok, stat);
188     expect(StringFormatFlagsNoWrap, flags);
189 
190     stat = GdipDeleteStringFormat(format);
191     expect(Ok, stat);
192 
193     stat = GdipStringFormatGetGenericTypographic(&format);
194     expect(Ok, stat);
195 
196     stat = GdipGetStringFormatFlags(format, &flags);
197     expect(Ok, stat);
198     expect(StringFormatFlagsNoWrap, flags);
199 
200     stat = GdipDeleteStringFormat(format);
201     expect(Ok, stat);
202 }
203 
204 static REAL tabstops[] = {0.0, 10.0, 2.0};
205 static void test_tabstops(void)
206 {
207     GpStringFormat *format;
208     GpStatus stat;
209     INT count;
210     REAL tabs[3];
211     REAL firsttab;
212 
213     stat = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
214     expect(Ok, stat);
215 
216     /* NULL */
217     stat = GdipGetStringFormatTabStopCount(NULL, NULL);
218     expect(InvalidParameter, stat);
219     stat = GdipGetStringFormatTabStopCount(NULL, &count);
220     expect(InvalidParameter, stat);
221     stat = GdipGetStringFormatTabStopCount(format, NULL);
222     expect(InvalidParameter, stat);
223 
224     stat = GdipSetStringFormatTabStops(NULL, 0.0, 0, NULL);
225     expect(InvalidParameter, stat);
226     stat = GdipSetStringFormatTabStops(format, 0.0, 0, NULL);
227     expect(InvalidParameter, stat);
228     stat = GdipSetStringFormatTabStops(NULL, 0.0, 0, tabstops);
229     expect(InvalidParameter, stat);
230 
231     stat = GdipGetStringFormatTabStops(NULL, 0, NULL, NULL);
232     expect(InvalidParameter, stat);
233     stat = GdipGetStringFormatTabStops(format, 0, NULL, NULL);
234     expect(InvalidParameter, stat);
235     stat = GdipGetStringFormatTabStops(NULL, 0, &firsttab, NULL);
236     expect(InvalidParameter, stat);
237     stat = GdipGetStringFormatTabStops(NULL, 0, NULL, tabs);
238     expect(InvalidParameter, stat);
239     stat = GdipGetStringFormatTabStops(format, 0, &firsttab, NULL);
240     expect(InvalidParameter, stat);
241     stat = GdipGetStringFormatTabStops(format, 0, NULL, tabs);
242     expect(InvalidParameter, stat);
243 
244     /* not NULL */
245     stat = GdipGetStringFormatTabStopCount(format, &count);
246     expect(Ok, stat);
247     expect(0, count);
248     /* negative tabcount */
249     stat = GdipSetStringFormatTabStops(format, 0.0, -1, tabstops);
250     expect(Ok, stat);
251     count = -1;
252     stat = GdipGetStringFormatTabStopCount(format, &count);
253     expect(Ok, stat);
254     expect(0, count);
255 
256     stat = GdipSetStringFormatTabStops(format, -10.0, 0, tabstops);
257     expect(Ok, stat);
258     stat = GdipSetStringFormatTabStops(format, -10.0, 1, tabstops);
259     expect(NotImplemented, stat);
260 
261     firsttab = -1.0;
262     tabs[0] = tabs[1] = tabs[2] = -1.0;
263     stat = GdipGetStringFormatTabStops(format, 0, &firsttab, tabs);
264     expect(Ok, stat);
265     expectf(-1.0, tabs[0]);
266     expectf(-1.0, tabs[1]);
267     expectf(-1.0, tabs[2]);
268     expectf(0.0, firsttab);
269 
270     stat = GdipSetStringFormatTabStops(format, +0.0, 3, tabstops);
271     expect(Ok, stat);
272     count = 0;
273     stat = GdipGetStringFormatTabStopCount(format, &count);
274     expect(Ok, stat);
275     expect(3, count);
276 
277     firsttab = -1.0;
278     tabs[0] = tabs[1] = tabs[2] = -1.0;
279     stat = GdipGetStringFormatTabStops(format, 3, &firsttab, tabs);
280     expect(Ok, stat);
281     expectf(0.0,  tabs[0]);
282     expectf(10.0, tabs[1]);
283     expectf(2.0,  tabs[2]);
284     expectf(0.0,  firsttab);
285 
286     stat = GdipSetStringFormatTabStops(format, 10.0, 3, tabstops);
287     expect(Ok, stat);
288     firsttab = -1.0;
289     tabs[0] = tabs[1] = tabs[2] = -1.0;
290     stat = GdipGetStringFormatTabStops(format, 0, &firsttab, tabs);
291     expect(Ok, stat);
292     expectf(-1.0, tabs[0]);
293     expectf(-1.0, tabs[1]);
294     expectf(-1.0, tabs[2]);
295     expectf(10.0, firsttab);
296 
297     /* zero tabcount, after valid setting to 3 */
298     stat = GdipSetStringFormatTabStops(format, 0.0, 0, tabstops);
299     expect(Ok, stat);
300     count = 0;
301     stat = GdipGetStringFormatTabStopCount(format, &count);
302     expect(Ok, stat);
303     expect(3, count);
304 
305     stat = GdipDeleteStringFormat(format);
306     expect(Ok, stat);
307 }
308 
309 static void test_getgenericdefault(void)
310 {
311     GpStringFormat *format, *format2;
312     GpStatus stat;
313 
314     INT flags;
315     INT n;
316     StringAlignment align, line_align;
317     StringTrimming trimming;
318     StringDigitSubstitute digitsub;
319     LANGID digitlang;
320     INT tabcount;
321 
322     /* NULL arg */
323     stat = GdipStringFormatGetGenericDefault(NULL);
324     expect(InvalidParameter, stat);
325 
326     stat = GdipStringFormatGetGenericDefault(&format);
327     expect(Ok, stat);
328 
329     stat = GdipStringFormatGetGenericDefault(&format2);
330     expect(Ok, stat);
331     ok(format == format2, "expected same format object\n");
332     stat = GdipDeleteStringFormat(format2);
333     expect(Ok, stat);
334 
335     GdipGetStringFormatFlags(format, &flags);
336     GdipGetStringFormatAlign(format, &align);
337     GdipGetStringFormatLineAlign(format, &line_align);
338     GdipGetStringFormatHotkeyPrefix(format, &n);
339     GdipGetStringFormatTrimming(format, &trimming);
340     GdipGetStringFormatDigitSubstitution(format, &digitlang, &digitsub);
341     GdipGetStringFormatTabStopCount(format, &tabcount);
342 
343     expect(0, flags);
344     expect(HotkeyPrefixNone, n);
345     expect(StringAlignmentNear, align);
346     expect(StringAlignmentNear, line_align);
347     expect(StringTrimmingCharacter, trimming);
348     expect(StringDigitSubstituteUser, digitsub);
349     expect(LANG_NEUTRAL, digitlang);
350     expect(0, tabcount);
351 
352     /* Change default format parameters, release, get format object again. */
353     stat = GdipSetStringFormatFlags(format, StringFormatFlagsNoWrap);
354     expect(Ok, stat);
355 
356     stat = GdipGetStringFormatFlags(format, &flags);
357     expect(Ok, stat);
358     expect(StringFormatFlagsNoWrap, flags);
359 
360     stat = GdipDeleteStringFormat(format);
361     expect(Ok, stat);
362 
363     stat = GdipStringFormatGetGenericDefault(&format);
364     expect(Ok, stat);
365 
366     stat = GdipGetStringFormatFlags(format, &flags);
367     expect(Ok, stat);
368     expect(StringFormatFlagsNoWrap, flags);
369 
370     stat = GdipDeleteStringFormat(format);
371     expect(Ok, stat);
372 }
373 
374 static void test_stringformatflags(void)
375 {
376     GpStringFormat *format;
377     GpStatus stat;
378 
379     INT flags;
380 
381     stat = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
382     expect(Ok, stat);
383 
384     /* NULL args */
385     stat = GdipSetStringFormatFlags(NULL, 0);
386     expect(InvalidParameter, stat);
387 
388     stat = GdipSetStringFormatFlags(format, 0);
389     expect(Ok, stat);
390     stat = GdipGetStringFormatFlags(format, &flags);
391     expect(Ok, stat);
392     expect(0, flags);
393 
394     /* Check some valid flags */
395     stat = GdipSetStringFormatFlags(format, StringFormatFlagsDirectionRightToLeft);
396     expect(Ok, stat);
397     stat = GdipGetStringFormatFlags(format, &flags);
398     expect(Ok, stat);
399     expect(StringFormatFlagsDirectionRightToLeft, flags);
400 
401     stat = GdipSetStringFormatFlags(format, StringFormatFlagsNoFontFallback);
402     expect(Ok, stat);
403     stat = GdipGetStringFormatFlags(format, &flags);
404     expect(Ok, stat);
405     expect(StringFormatFlagsNoFontFallback, flags);
406 
407     /* Check some flag combinations */
408     stat = GdipSetStringFormatFlags(format, StringFormatFlagsDirectionVertical
409         | StringFormatFlagsNoFitBlackBox);
410     expect(Ok, stat);
411     stat = GdipGetStringFormatFlags(format, &flags);
412     expect(Ok, stat);
413     expect((StringFormatFlagsDirectionVertical
414         | StringFormatFlagsNoFitBlackBox), flags);
415 
416     stat = GdipSetStringFormatFlags(format, StringFormatFlagsDisplayFormatControl
417         | StringFormatFlagsMeasureTrailingSpaces);
418     expect(Ok, stat);
419     stat = GdipGetStringFormatFlags(format, &flags);
420     expect(Ok, stat);
421     expect((StringFormatFlagsDisplayFormatControl
422         | StringFormatFlagsMeasureTrailingSpaces), flags);
423 
424     /* Check invalid flags */
425     stat = GdipSetStringFormatFlags(format, 0xdeadbeef);
426     expect(Ok, stat);
427     stat = GdipGetStringFormatFlags(format, &flags);
428     expect(Ok, stat);
429     expect(0xdeadbeef, flags);
430 
431     stat = GdipDeleteStringFormat(format);
432     expect(Ok, stat);
433 }
434 
435 START_TEST(stringformat)
436 {
437     struct GdiplusStartupInput gdiplusStartupInput;
438     ULONG_PTR gdiplusToken;
439     HMODULE hmsvcrt;
440     int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
441 
442     /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
443     hmsvcrt = LoadLibraryA("msvcrt");
444     _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
445     if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
446 
447     gdiplusStartupInput.GdiplusVersion              = 1;
448     gdiplusStartupInput.DebugEventCallback          = NULL;
449     gdiplusStartupInput.SuppressBackgroundThread    = 0;
450     gdiplusStartupInput.SuppressExternalCodecs      = 0;
451 
452     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
453 
454     test_constructor();
455     test_characterrange();
456     test_digitsubstitution();
457     test_getgenerictypographic();
458     test_tabstops();
459     test_getgenericdefault();
460     test_stringformatflags();
461 
462     GdiplusShutdown(gdiplusToken);
463 }
464