jscript: Get rid of BSTR in date.c.
[wine] / dlls / dwrite / tests / font.c
1 /*
2  *    Font related tests
3  *
4  * Copyright 2012 Nikolay Sivov for CodeWeavers
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 COBJMACROS
22
23 #include "windows.h"
24
25 #include "initguid.h"
26 #include "dwrite.h"
27
28 #include "wine/test.h"
29
30 #define EXPECT_HR(hr,hr_exp) \
31     ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
32
33 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
34 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
35 {
36     ULONG rc = IUnknown_AddRef(obj);
37     IUnknown_Release(obj);
38     ok_(__FILE__,line)(rc-1 == ref, "expected refcount %d, got %d\n", ref, rc-1);
39 }
40
41 static IDWriteFactory *factory;
42
43 static void test_CreateFontFromLOGFONT(void)
44 {
45     static const WCHAR arialW[] = {'A','r','i','a','l',0};
46     static const WCHAR arialspW[] = {'A','r','i','a','l',' ',0};
47     static const WCHAR blahW[]  = {'B','l','a','h','!',0};
48     IDWriteGdiInterop *interop;
49     DWRITE_FONT_WEIGHT weight;
50     DWRITE_FONT_STYLE style;
51     IDWriteFont *font;
52     LOGFONTW logfont;
53     LONG weights[][2] = {
54         {FW_NORMAL, DWRITE_FONT_WEIGHT_NORMAL},
55         {FW_BOLD, DWRITE_FONT_WEIGHT_BOLD},
56         {  0, DWRITE_FONT_WEIGHT_NORMAL},
57         { 50, DWRITE_FONT_WEIGHT_NORMAL},
58         {150, DWRITE_FONT_WEIGHT_NORMAL},
59         {250, DWRITE_FONT_WEIGHT_NORMAL},
60         {350, DWRITE_FONT_WEIGHT_NORMAL},
61         {450, DWRITE_FONT_WEIGHT_NORMAL},
62         {650, DWRITE_FONT_WEIGHT_BOLD},
63         {750, DWRITE_FONT_WEIGHT_BOLD},
64         {850, DWRITE_FONT_WEIGHT_BOLD},
65         {950, DWRITE_FONT_WEIGHT_BOLD},
66         {960, DWRITE_FONT_WEIGHT_BOLD},
67     };
68     HRESULT hr;
69     BOOL ret;
70     int i;
71
72     hr = IDWriteFactory_GetGdiInterop(factory, &interop);
73     EXPECT_HR(hr, S_OK);
74
75 if (0)
76     /* null out parameter crashes this call */
77     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, NULL);
78
79     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, NULL, &font);
80     EXPECT_HR(hr, E_INVALIDARG);
81
82     memset(&logfont, 0, sizeof(logfont));
83     logfont.lfHeight = 12;
84     logfont.lfWidth  = 12;
85     logfont.lfWeight = FW_NORMAL;
86     logfont.lfItalic = 1;
87     lstrcpyW(logfont.lfFaceName, arialW);
88
89     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
90     EXPECT_HR(hr, S_OK);
91
92     /* now check properties */
93     weight = IDWriteFont_GetWeight(font);
94 todo_wine
95     ok(weight == DWRITE_FONT_WEIGHT_NORMAL, "got %d\n", weight);
96
97     style = IDWriteFont_GetStyle(font);
98     ok(style == DWRITE_FONT_STYLE_ITALIC, "got %d\n", style);
99
100     ret = IDWriteFont_IsSymbolFont(font);
101     ok(!ret, "got %d\n", ret);
102
103     IDWriteFont_Release(font);
104
105     /* weight values */
106     for (i = 0; i < sizeof(weights)/(2*sizeof(LONG)); i++)
107     {
108         memset(&logfont, 0, sizeof(logfont));
109         logfont.lfHeight = 12;
110         logfont.lfWidth  = 12;
111         logfont.lfWeight = weights[i][0];
112         lstrcpyW(logfont.lfFaceName, arialW);
113
114         hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
115         EXPECT_HR(hr, S_OK);
116
117         weight = IDWriteFont_GetWeight(font);
118     todo_wine
119         ok(weight == weights[i][1],
120             "%d: got %d, expected %d\n", i, weight, weights[i][1]);
121         IDWriteFont_Release(font);
122     }
123
124     /* weight not from enum */
125     memset(&logfont, 0, sizeof(logfont));
126     logfont.lfHeight = 12;
127     logfont.lfWidth  = 12;
128     logfont.lfWeight = 550;
129     lstrcpyW(logfont.lfFaceName, arialW);
130
131     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
132     EXPECT_HR(hr, S_OK);
133
134     weight = IDWriteFont_GetWeight(font);
135 todo_wine
136     ok(weight == DWRITE_FONT_WEIGHT_NORMAL || broken(weight == DWRITE_FONT_WEIGHT_BOLD) /* win7 w/o SP */,
137         "got %d\n", weight);
138     IDWriteFont_Release(font);
139
140     /* empty or nonexistent face name */
141     memset(&logfont, 0, sizeof(logfont));
142     logfont.lfHeight = 12;
143     logfont.lfWidth  = 12;
144     logfont.lfWeight = FW_NORMAL;
145     lstrcpyW(logfont.lfFaceName, blahW);
146
147     font = (void*)0xdeadbeef;
148     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
149 todo_wine {
150     EXPECT_HR(hr, DWRITE_E_NOFONT);
151     ok(font == NULL, "got %p\n", font);
152     if(font) IDWriteFont_Release(font);
153 }
154
155     memset(&logfont, 0, sizeof(logfont));
156     logfont.lfHeight = 12;
157     logfont.lfWidth  = 12;
158     logfont.lfWeight = FW_NORMAL;
159     lstrcpyW(logfont.lfFaceName, arialspW);
160
161     font = (void*)0xdeadbeef;
162     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
163 todo_wine {
164     EXPECT_HR(hr, DWRITE_E_NOFONT);
165     ok(font == NULL, "got %p\n", font);
166     if(font) IDWriteFont_Release(font);
167 }
168
169     memset(&logfont, 0, sizeof(logfont));
170     logfont.lfHeight = 12;
171     logfont.lfWidth  = 12;
172     logfont.lfWeight = FW_NORMAL;
173
174     font = (void*)0xdeadbeef;
175     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
176 todo_wine {
177     EXPECT_HR(hr, DWRITE_E_NOFONT);
178     ok(font == NULL, "got %p\n", font);
179     if(font) IDWriteFont_Release(font);
180 }
181
182     IDWriteGdiInterop_Release(interop);
183 }
184
185 static void test_CreateBitmapRenderTarget(void)
186 {
187     IDWriteBitmapRenderTarget *target, *target2;
188     IDWriteGdiInterop *interop;
189     DIBSECTION ds;
190     HBITMAP hbm;
191     HRESULT hr;
192     SIZE size;
193     HDC hdc;
194     int ret;
195
196     hr = IDWriteFactory_GetGdiInterop(factory, &interop);
197     EXPECT_HR(hr, S_OK);
198
199     target = NULL;
200     hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 0, 0, &target);
201     EXPECT_HR(hr, S_OK);
202
203 if (0) /* crashes on native */
204     hr = IDWriteBitmapRenderTarget_GetSize(target, NULL);
205
206     size.cx = size.cy = -1;
207     hr = IDWriteBitmapRenderTarget_GetSize(target, &size);
208     EXPECT_HR(hr, S_OK);
209     ok(size.cx == 0, "got %d\n", size.cx);
210     ok(size.cy == 0, "got %d\n", size.cy);
211
212     target2 = NULL;
213     hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 0, 0, &target2);
214     EXPECT_HR(hr, S_OK);
215     ok(target != target2, "got %p, %p\n", target2, target);
216     IDWriteBitmapRenderTarget_Release(target2);
217
218     hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target);
219     ok(hdc != NULL, "got %p\n", hdc);
220
221     hbm = GetCurrentObject(hdc, OBJ_BITMAP);
222     ok(hbm != NULL, "got %p\n", hbm);
223
224     /* check DIB properties */
225     ret = GetObjectW(hbm, sizeof(ds), &ds);
226     ok(ret == sizeof(BITMAP), "got %d\n", ret);
227     ok(ds.dsBm.bmWidth == 1, "got %d\n", ds.dsBm.bmWidth);
228     ok(ds.dsBm.bmHeight == 1, "got %d\n", ds.dsBm.bmHeight);
229     ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
230     ok(ds.dsBm.bmBitsPixel == 1, "got %d\n", ds.dsBm.bmBitsPixel);
231     ok(!ds.dsBm.bmBits, "got %p\n", ds.dsBm.bmBits);
232
233     IDWriteBitmapRenderTarget_Release(target);
234
235     hbm = GetCurrentObject(hdc, OBJ_BITMAP);
236     ok(!hbm, "got %p\n", hbm);
237
238     target = NULL;
239     hr = IDWriteGdiInterop_CreateBitmapRenderTarget(interop, NULL, 10, 5, &target);
240     EXPECT_HR(hr, S_OK);
241
242     hdc = IDWriteBitmapRenderTarget_GetMemoryDC(target);
243     ok(hdc != NULL, "got %p\n", hdc);
244
245     hbm = GetCurrentObject(hdc, OBJ_BITMAP);
246     ok(hbm != NULL, "got %p\n", hbm);
247
248     /* check DIB properties */
249     ret = GetObjectW(hbm, sizeof(ds), &ds);
250     ok(ret == sizeof(ds), "got %d\n", ret);
251     ok(ds.dsBm.bmWidth == 10, "got %d\n", ds.dsBm.bmWidth);
252     ok(ds.dsBm.bmHeight == 5, "got %d\n", ds.dsBm.bmHeight);
253     ok(ds.dsBm.bmPlanes == 1, "got %d\n", ds.dsBm.bmPlanes);
254     ok(ds.dsBm.bmBitsPixel == 32, "got %d\n", ds.dsBm.bmBitsPixel);
255     ok(ds.dsBm.bmBits != NULL, "got %p\n", ds.dsBm.bmBits);
256
257     size.cx = size.cy = -1;
258     hr = IDWriteBitmapRenderTarget_GetSize(target, &size);
259     EXPECT_HR(hr, S_OK);
260     ok(size.cx == 10, "got %d\n", size.cx);
261     ok(size.cy == 5, "got %d\n", size.cy);
262
263     IDWriteBitmapRenderTarget_Release(target);
264
265     IDWriteGdiInterop_Release(interop);
266 }
267
268 static void test_GetFontFamily(void)
269 {
270     static const WCHAR arialW[] = {'A','r','i','a','l',0};
271     IDWriteFontFamily *family, *family2;
272     IDWriteGdiInterop *interop;
273     IDWriteFont *font;
274     LOGFONTW logfont;
275     HRESULT hr;
276
277     hr = IDWriteFactory_GetGdiInterop(factory, &interop);
278     EXPECT_HR(hr, S_OK);
279
280     memset(&logfont, 0, sizeof(logfont));
281     logfont.lfHeight = 12;
282     logfont.lfWidth  = 12;
283     logfont.lfWeight = FW_NORMAL;
284     logfont.lfItalic = 1;
285     lstrcpyW(logfont.lfFaceName, arialW);
286
287     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
288     EXPECT_HR(hr, S_OK);
289
290 if (0) /* crashes on native */
291     hr = IDWriteFont_GetFontFamily(font, NULL);
292
293     EXPECT_REF(font, 1);
294     hr = IDWriteFont_GetFontFamily(font, &family);
295     EXPECT_HR(hr, S_OK);
296     EXPECT_REF(font, 1);
297     EXPECT_REF(family, 2);
298
299     hr = IDWriteFont_GetFontFamily(font, &family2);
300     EXPECT_HR(hr, S_OK);
301     ok(family2 == family, "got %p, previous %p\n", family2, family);
302     EXPECT_REF(font, 1);
303     EXPECT_REF(family, 3);
304     IDWriteFontFamily_Release(family2);
305
306     hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFontFamily, (void**)&family2);
307     EXPECT_HR(hr, E_NOINTERFACE);
308     ok(family2 == NULL, "got %p\n", family2);
309
310     IDWriteFontFamily_Release(family);
311     IDWriteFont_Release(font);
312     IDWriteGdiInterop_Release(interop);
313 }
314
315 static void test_GetFamilyNames(void)
316 {
317     static const WCHAR arialW[] = {'A','r','i','a','l',0};
318     IDWriteFontFamily *family;
319     IDWriteLocalizedStrings *names, *names2;
320     IDWriteGdiInterop *interop;
321     IDWriteFont *font;
322     LOGFONTW logfont;
323     WCHAR buffer[100];
324     HRESULT hr;
325     UINT32 len;
326
327     hr = IDWriteFactory_GetGdiInterop(factory, &interop);
328     EXPECT_HR(hr, S_OK);
329
330     memset(&logfont, 0, sizeof(logfont));
331     logfont.lfHeight = 12;
332     logfont.lfWidth  = 12;
333     logfont.lfWeight = FW_NORMAL;
334     logfont.lfItalic = 1;
335     lstrcpyW(logfont.lfFaceName, arialW);
336
337     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
338     EXPECT_HR(hr, S_OK);
339
340     hr = IDWriteFont_GetFontFamily(font, &family);
341     EXPECT_HR(hr, S_OK);
342
343 if (0) /* crashes on native */
344     hr = IDWriteFontFamily_GetFamilyNames(family, NULL);
345
346     hr = IDWriteFontFamily_GetFamilyNames(family, &names);
347     ok(hr == S_OK, "got 0x%08x\n", hr);
348     EXPECT_REF(names, 1);
349
350     hr = IDWriteFontFamily_GetFamilyNames(family, &names2);
351     ok(hr == S_OK, "got 0x%08x\n", hr);
352     EXPECT_REF(names2, 1);
353     ok(names != names2, "got %p, was %p\n", names2, names);
354
355     IDWriteLocalizedStrings_Release(names2);
356
357     /* GetStringLength */
358 if (0) /* crashes on native */
359     hr = IDWriteLocalizedStrings_GetStringLength(names, 0, NULL);
360
361     len = 100;
362     hr = IDWriteLocalizedStrings_GetStringLength(names, 10, &len);
363     ok(hr == E_FAIL, "got 0x%08x\n", hr);
364     ok(len == (UINT32)-1, "got %u\n", len);
365
366     len = 0;
367     hr = IDWriteLocalizedStrings_GetStringLength(names, 0, &len);
368     ok(hr == S_OK, "got 0x%08x\n", hr);
369     ok(len > 0, "got %u\n", len);
370
371     /* GetString */
372     hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 0);
373     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
374
375     hr = IDWriteLocalizedStrings_GetString(names, 10, NULL, 0);
376     ok(hr == E_FAIL, "got 0x%08x\n", hr);
377
378 if (0)
379     hr = IDWriteLocalizedStrings_GetString(names, 0, NULL, 100);
380
381     buffer[0] = 1;
382     hr = IDWriteLocalizedStrings_GetString(names, 10, buffer, 100);
383     ok(hr == E_FAIL, "got 0x%08x\n", hr);
384     ok(buffer[0] == 0, "got %x\n", buffer[0]);
385
386     buffer[0] = 1;
387     hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len-1);
388     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
389     ok(buffer[0] == 0, "got %x\n", buffer[0]);
390
391     buffer[0] = 1;
392     hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len);
393     ok(hr == E_NOT_SUFFICIENT_BUFFER, "got 0x%08x\n", hr);
394     ok(buffer[0] == 0, "got %x\n", buffer[0]);
395
396     buffer[0] = 0;
397     hr = IDWriteLocalizedStrings_GetString(names, 0, buffer, len+1);
398     ok(hr == S_OK, "got 0x%08x\n", hr);
399     ok(buffer[0] != 0, "got %x\n", buffer[0]);
400
401     IDWriteLocalizedStrings_Release(names);
402
403     IDWriteFontFamily_Release(family);
404     IDWriteFont_Release(font);
405     IDWriteGdiInterop_Release(interop);
406 }
407
408 static void test_CreateFontFace(void)
409 {
410     static const WCHAR arialW[] = {'A','r','i','a','l',0};
411     IDWriteFontFace *fontface, *fontface2;
412     IDWriteGdiInterop *interop;
413     IDWriteFont *font;
414     LOGFONTW logfont;
415     HRESULT hr;
416
417     hr = IDWriteFactory_GetGdiInterop(factory, &interop);
418     EXPECT_HR(hr, S_OK);
419
420     memset(&logfont, 0, sizeof(logfont));
421     logfont.lfHeight = 12;
422     logfont.lfWidth  = 12;
423     logfont.lfWeight = FW_NORMAL;
424     logfont.lfItalic = 1;
425     lstrcpyW(logfont.lfFaceName, arialW);
426
427     hr = IDWriteGdiInterop_CreateFontFromLOGFONT(interop, &logfont, &font);
428     ok(hr == S_OK, "got 0x%08x\n", hr);
429
430     hr = IDWriteFont_QueryInterface(font, &IID_IDWriteFontFace, (void**)&fontface);
431     ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr);
432
433 if (0) /* crashes on native */
434     hr = IDWriteFont_CreateFontFace(font, NULL);
435
436     hr = IDWriteFont_CreateFontFace(font, &fontface);
437     ok(hr == S_OK, "got 0x%08x\n", hr);
438     EXPECT_REF(font, 1);
439     EXPECT_REF(fontface, 1);
440
441     hr = IDWriteFont_CreateFontFace(font, &fontface2);
442     ok(hr == S_OK, "got 0x%08x\n", hr);
443     ok(fontface == fontface2, "got %p, was %p\n", fontface2, fontface);
444     EXPECT_REF(fontface, 2);
445     EXPECT_REF(font, 1);
446
447     IDWriteFontFace_AddRef(fontface);
448     EXPECT_REF(font, 1);
449     EXPECT_REF(fontface, 3);
450     IDWriteFontFace_Release(fontface);
451     IDWriteFontFace_Release(fontface);
452
453     IDWriteFontFace_Release(fontface);
454     IDWriteFont_Release(font);
455     IDWriteGdiInterop_Release(interop);
456 }
457
458 START_TEST(font)
459 {
460     HRESULT hr;
461
462     hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, &IID_IDWriteFactory, (IUnknown**)&factory);
463     ok(hr == S_OK, "got 0x%08x\n", hr);
464     if (hr != S_OK)
465     {
466         win_skip("failed to create factory\n");
467         return;
468     }
469
470     test_CreateFontFromLOGFONT();
471     test_CreateBitmapRenderTarget();
472     test_GetFontFamily();
473     test_GetFamilyNames();
474     test_CreateFontFace();
475
476     IDWriteFactory_Release(factory);
477 }