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