wined3d: Merge the various resource desc structures.
[wine] / dlls / oleaut32 / tests / olefont.c
1 /*
2  * OLEFONT test program
3  *
4  * Copyright 2003 Marcus Meissner
5  * Copyright 2006 (Google) Benjamin Arai
6  *
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
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <math.h>
26 #include <float.h>
27
28 #define COBJMACROS
29
30 #include <wine/test.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winuser.h>
34 #include <wingdi.h>
35 #include <winnls.h>
36 #include <winerror.h>
37 #include <winnt.h>
38 #include <initguid.h>
39 #include <wtypes.h>
40 #include <olectl.h>
41 #include <ocidl.h>
42
43 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
44
45 static WCHAR MSSansSerif_font[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};
46 static WCHAR system_font[] = { 'S','y','s','t','e','m',0 };
47 static WCHAR arial_font[] = { 'A','r','i','a','l',0 };
48 static WCHAR marlett_font[] = { 'M','a','r','l','e','t','t',0 };
49
50 static HMODULE hOleaut32;
51
52 static HRESULT (WINAPI *pOleCreateFontIndirect)(LPFONTDESC,REFIID,LPVOID*);
53
54 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
55
56 /* Create a font with cySize given by lo_size, hi_size,  */
57 /* SetRatio to ratio_logical, ratio_himetric,            */
58 /* check that resulting hfont has height hfont_height.   */
59 /* Various checks along the way.                         */
60
61 static void test_ifont_sizes(LONG lo_size, LONG hi_size,
62         LONG ratio_logical, LONG ratio_himetric,
63         LONG hfont_height, const char * test_name)
64 {
65         FONTDESC fd;
66         LPVOID pvObj = NULL;
67         IFont* ifnt = NULL;
68         HFONT hfont;
69         LOGFONT lf;
70         CY psize;
71         HRESULT hres;
72
73         fd.cbSizeofstruct = sizeof(FONTDESC);
74         fd.lpstrName      = system_font;
75         S(fd.cySize).Lo   = lo_size;
76         S(fd.cySize).Hi   = hi_size;
77         fd.sWeight        = 0;
78         fd.sCharset       = 0;
79         fd.fItalic        = 0;
80         fd.fUnderline     = 0;
81         fd.fStrikethrough = 0;
82
83         /* Create font, test that it worked. */
84         hres = pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj);
85         ifnt = pvObj;
86         ok(hres == S_OK,"%s: OCFI returns 0x%08x instead of S_OK.\n",
87                 test_name, hres);
88         ok(pvObj != NULL,"%s: OCFI returns NULL.\n", test_name);
89
90         /* Read back size.  Hi part was ignored. */
91         hres = IFont_get_Size(ifnt, &psize);
92         ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
93                 test_name, hres);
94         ok(S(psize).Lo == lo_size && S(psize).Hi == 0,
95                 "%s: get_Size: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n",
96                 test_name, S(psize).Lo, S(psize).Hi, lo_size);
97
98         /* Change ratio, check size unchanged.  Standard is 72, 2540. */
99         hres = IFont_SetRatio(ifnt, ratio_logical, ratio_himetric);
100         ok(hres == S_OK,"%s: IFont_SR returns 0x%08x instead of S_OK.\n",
101                 test_name, hres);
102         hres = IFont_get_Size(ifnt, &psize);
103         ok(hres == S_OK,"%s: IFont_get_size returns 0x%08x instead of S_OK.\n",
104                 test_name, hres);
105         ok(S(psize).Lo == lo_size && S(psize).Hi == 0,
106                 "%s: gS after SR: Lo=%d, Hi=%d; expected Lo=%d, Hi=0.\n",
107                 test_name, S(psize).Lo, S(psize).Hi, lo_size);
108
109         /* Check hFont size with this ratio.  This tests an important   */
110         /* conversion for which MSDN is very wrong.                     */
111         hres = IFont_get_hFont (ifnt, &hfont);
112         ok(hres == S_OK, "%s: IFont_get_hFont returns 0x%08x instead of S_OK.\n",
113                 test_name, hres);
114         hres = GetObject (hfont, sizeof(LOGFONT), &lf);
115         ok(hres == OBJ_FONT, "got obj type %d\n", hres);
116         ok(lf.lfHeight == hfont_height,
117                 "%s: hFont has lf.lfHeight=%d, expected %d.\n",
118                 test_name, lf.lfHeight, hfont_height);
119
120         /* Free IFont. */
121         IFont_Release(ifnt);
122 }
123
124 static void test_QueryInterface(void)
125 {
126         LPVOID pvObj = NULL;
127         HRESULT hres;
128         IFont*  font = NULL;
129         LONG ret;
130
131         hres = pOleCreateFontIndirect(NULL, &IID_IFont, NULL);
132         ok(hres == E_POINTER, "got 0x%08x\n", hres);
133
134         hres = pOleCreateFontIndirect(NULL, &IID_IFont, &pvObj);
135         font = pvObj;
136
137         ok(hres == S_OK,"OCFI (NULL,..) does not return 0, but 0x%08x\n",hres);
138         ok(font != NULL,"OCFI (NULL,..) returns NULL, instead of !NULL\n");
139
140         pvObj = NULL;
141         hres = IFont_QueryInterface( font, &IID_IFont, &pvObj);
142
143         /* Test if QueryInterface increments ref counter for IFONTs */
144         ret = IFont_AddRef(font);
145         ok(ret == 3 ||
146            broken(ret == 1), /* win95 */
147            "IFont_QI expected ref value 3 but instead got %d\n",ret);
148         IFont_Release(font);
149
150         ok(hres == S_OK,"IFont_QI does not return S_OK, but 0x%08x\n", hres);
151         ok(pvObj != NULL,"IFont_QI does return NULL, instead of a ptr\n");
152
153         /* Original ref and QueryInterface ref both have to be released */
154         IFont_Release(font);
155         IFont_Release(font);
156 }
157
158 static void test_type_info(void)
159 {
160         LPVOID pvObj = NULL;
161         HRESULT hres;
162         IFontDisp*  fontdisp = NULL;
163         ITypeInfo* pTInfo;
164         WCHAR name_Name[] = {'N','a','m','e',0};
165         BSTR names[3];
166         UINT n;
167         LCID en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
168                 SORT_DEFAULT);
169         DISPPARAMS dispparams;
170         VARIANT varresult;
171
172         pOleCreateFontIndirect(NULL, &IID_IFontDisp, &pvObj);
173         fontdisp = pvObj;
174
175         hres = IFontDisp_GetTypeInfo(fontdisp, 0, en_us, &pTInfo);
176         ok(hres == S_OK, "GTI returned 0x%08x instead of S_OK.\n", hres);
177         ok(pTInfo != NULL, "GTI returned NULL.\n");
178
179         hres = ITypeInfo_GetNames(pTInfo, DISPID_FONT_NAME, names, 3, &n);
180         ok(hres == S_OK, "GetNames returned 0x%08x instead of S_OK.\n", hres);
181         ok(n == 1, "GetNames returned %d names instead of 1.\n", n);
182         ok(!lstrcmpiW(names[0],name_Name), "DISPID_FONT_NAME doesn't get 'Names'.\n");
183         SysFreeString(names[0]);
184
185         ITypeInfo_Release(pTInfo);
186
187         dispparams.cNamedArgs = 0;
188         dispparams.rgdispidNamedArgs = NULL;
189         dispparams.cArgs = 0;
190         dispparams.rgvarg = NULL;
191         VariantInit(&varresult);
192         hres = IFontDisp_Invoke(fontdisp, DISPID_FONT_NAME, &IID_NULL,
193             LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult,
194             NULL, NULL);
195         ok(hres == S_OK, "IFontDisp_Invoke return 0x%08x instead of S_OK.\n", hres);
196         VariantClear(&varresult);
197
198         IFontDisp_Release(fontdisp);
199 }
200
201 static HRESULT WINAPI FontEventsDisp_QueryInterface(
202         IFontEventsDisp *iface,
203     /* [in] */ REFIID riid,
204     /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
205 {
206     if (IsEqualIID(riid, &IID_IFontEventsDisp) || IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDispatch))
207     {
208         IUnknown_AddRef(iface);
209         *ppvObject = iface;
210         return S_OK;
211     }
212     else
213     {
214         *ppvObject = NULL;
215         return E_NOINTERFACE;
216     }
217 }
218
219 static ULONG WINAPI FontEventsDisp_AddRef(
220     IFontEventsDisp *iface)
221 {
222     return 2;
223 }
224
225 static ULONG WINAPI FontEventsDisp_Release(
226         IFontEventsDisp *iface)
227 {
228     return 1;
229 }
230
231 static int fonteventsdisp_invoke_called = 0;
232
233 static HRESULT WINAPI FontEventsDisp_Invoke(
234         IFontEventsDisp __RPC_FAR * iface,
235     /* [in] */ DISPID dispIdMember,
236     /* [in] */ REFIID riid,
237     /* [in] */ LCID lcid,
238     /* [in] */ WORD wFlags,
239     /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
240     /* [out] */ VARIANT __RPC_FAR *pVarResult,
241     /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
242     /* [out] */ UINT __RPC_FAR *puArgErr)
243 {
244     static const WCHAR wszBold[] = {'B','o','l','d',0};
245     ok(wFlags == INVOKE_FUNC, "invoke flags should have been INVOKE_FUNC instead of 0x%x\n", wFlags);
246     ok(dispIdMember == DISPID_FONT_CHANGED, "dispIdMember should have been DISPID_FONT_CHANGED instead of 0x%x\n", dispIdMember);
247     ok(pDispParams->cArgs == 1, "pDispParams->cArgs should have been 1 instead of %d\n", pDispParams->cArgs);
248     ok(V_VT(&pDispParams->rgvarg[0]) == VT_BSTR, "VT of first param should have been VT_BSTR instead of %d\n", V_VT(&pDispParams->rgvarg[0]));
249     ok(!lstrcmpW(V_BSTR(&pDispParams->rgvarg[0]), wszBold), "String in first param should have been \"Bold\"\n");
250
251     fonteventsdisp_invoke_called++;
252     return S_OK;
253 }
254
255 static IFontEventsDispVtbl FontEventsDisp_Vtbl =
256 {
257     FontEventsDisp_QueryInterface,
258     FontEventsDisp_AddRef,
259     FontEventsDisp_Release,
260     NULL,
261     NULL,
262     NULL,
263     FontEventsDisp_Invoke
264 };
265
266 static IFontEventsDisp FontEventsDisp = { &FontEventsDisp_Vtbl };
267
268 static void test_font_events_disp(void)
269 {
270     IFont *pFont;
271     IFont *pFont2;
272     IConnectionPointContainer *pCPC;
273     IConnectionPoint *pCP;
274     FONTDESC fontdesc;
275     HRESULT hr;
276     DWORD dwCookie;
277     IFontDisp *pFontDisp;
278     DISPPARAMS dispparams;
279     VARIANTARG vararg;
280
281     fontdesc.cbSizeofstruct = sizeof(fontdesc);
282     fontdesc.lpstrName = MSSansSerif_font;
283     fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
284     fontdesc.sWeight = FW_NORMAL;
285     fontdesc.sCharset = 0;
286     fontdesc.fItalic = FALSE;
287     fontdesc.fUnderline = FALSE;
288     fontdesc.fStrikethrough = FALSE;
289
290     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
291     ok_ole_success(hr, "OleCreateFontIndirect");
292
293     hr = IFont_QueryInterface(pFont, &IID_IConnectionPointContainer, (void **)&pCPC);
294     ok_ole_success(hr, "IFont_QueryInterface");
295
296     hr = IConnectionPointContainer_FindConnectionPoint(pCPC, &IID_IFontEventsDisp, &pCP);
297     ok_ole_success(hr, "IConnectionPointContainer_FindConnectionPoint");
298     IConnectionPointContainer_Release(pCPC);
299
300     hr = IConnectionPoint_Advise(pCP, (IUnknown *)&FontEventsDisp, &dwCookie);
301     ok_ole_success(hr, "IConnectionPoint_Advise");
302     IConnectionPoint_Release(pCP);
303
304     hr = IFont_put_Bold(pFont, TRUE);
305     ok_ole_success(hr, "IFont_put_Bold");
306
307     ok(fonteventsdisp_invoke_called == 1, "IFontEventDisp::Invoke wasn't called once\n");
308
309     hr = IFont_QueryInterface(pFont, &IID_IFontDisp, (void **)&pFontDisp);
310     ok_ole_success(hr, "IFont_QueryInterface");
311
312     V_VT(&vararg) = VT_BOOL;
313     V_BOOL(&vararg) = VARIANT_FALSE;
314     dispparams.cNamedArgs = 0;
315     dispparams.rgdispidNamedArgs = NULL;
316     dispparams.cArgs = 1;
317     dispparams.rgvarg = &vararg;
318     hr = IFontDisp_Invoke(pFontDisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
319     ok(hr == S_OK, "IFontDisp_Invoke return 0x%08x instead of S_OK.\n", hr);
320
321     IFontDisp_Release(pFontDisp);
322
323     ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n",
324         fonteventsdisp_invoke_called);
325
326     hr = IFont_Clone(pFont, &pFont2);
327     ok_ole_success(hr, "IFont_Clone");
328     IFont_Release(pFont);
329
330     hr = IFont_put_Bold(pFont2, FALSE);
331     ok_ole_success(hr, "IFont_put_Bold");
332
333     /* this test shows that the notification routine isn't called again */
334     ok(fonteventsdisp_invoke_called == 2, "IFontEventDisp::Invoke was called %d times instead of twice\n",
335         fonteventsdisp_invoke_called);
336
337     IFont_Release(pFont2);
338 }
339
340 static void test_names_ids(WCHAR* w_name_1, const char* a_name_1,
341                     WCHAR* w_name_2, const char* a_name_2,
342                     LCID lcid, DISPID id_1, DISPID id_2,
343                     HRESULT hres_expect, int numnames)
344 {
345     LPVOID pvObj = NULL;
346     IFontDisp *fontdisp = NULL;
347     HRESULT hres;
348     DISPID rgDispId[2] = {0xdeadbeef, 0xdeadbeef};
349     LPOLESTR names[2] = {w_name_1, w_name_2};
350
351     pOleCreateFontIndirect(NULL, &IID_IFontDisp, &pvObj);
352     fontdisp = pvObj;
353
354     hres = IFontDisp_GetIDsOfNames(fontdisp, &IID_NULL, names, numnames,
355                                    lcid, rgDispId);
356
357     /* test hres */
358     ok(hres == hres_expect,
359         "GetIDsOfNames: \"%s\", \"%s\" returns 0x%08x, expected 0x%08x.\n",
360         a_name_1, a_name_2, hres, hres_expect);
361
362     /* test first DISPID */
363     ok(rgDispId[0]==id_1,
364         "GetIDsOfNames: \"%s\" gets DISPID 0x%08x, expected 0x%08x.\n",
365         a_name_1, rgDispId[0], id_1);
366
367     /* test second DISPID is present */
368     if (numnames == 2)
369     {
370         ok(rgDispId[1]==id_2,
371             "GetIDsOfNames: ..., \"%s\" gets DISPID 0x%08x, expected 0x%08x.\n",
372             a_name_2, rgDispId[1], id_2);
373     }
374
375    IFontDisp_Release(fontdisp);
376 }
377
378 static void test_GetIDsOfNames(void)
379 {
380     WCHAR name_Name[] = {'N','a','m','e',0};
381     WCHAR name_Italic[] = {'I','t','a','l','i','c',0};
382     WCHAR name_Size[] = {'S','i','z','e',0};
383     WCHAR name_Bold[] = {'B','o','l','d',0};
384     WCHAR name_Underline[] = {'U','n','d','e','r','l','i','n','e',0};
385     WCHAR name_Strikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
386     WCHAR name_Weight[] = {'W','e','i','g','h','t',0};
387     WCHAR name_Charset[] = {'C','h','a','r','s','e','t',0};
388     WCHAR name_Foo[] = {'F','o','o',0};
389     WCHAR name_nAmE[] = {'n','A','m','E',0};
390     WCHAR name_Nom[] = {'N','o','m',0};
391
392     LCID en_us = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
393                           SORT_DEFAULT);
394     LCID fr_fr = MAKELCID(MAKELANGID(LANG_FRENCH,SUBLANG_FRENCH),
395                           SORT_DEFAULT);
396
397     /* Test DISPID_FONTs for the various properties. */
398     test_names_ids(name_Name, "Name", NULL, "", en_us,
399                    DISPID_FONT_NAME, 0, S_OK,1);
400     test_names_ids(name_Size, "Size", NULL, "", en_us,
401                    DISPID_FONT_SIZE, 0, S_OK,1);
402     test_names_ids(name_Bold, "Bold", NULL, "", en_us,
403                    DISPID_FONT_BOLD, 0, S_OK,1);
404     test_names_ids(name_Italic, "Italic", NULL, "", en_us,
405                    DISPID_FONT_ITALIC, 0, S_OK,1);
406     test_names_ids(name_Underline, "Underline", NULL, "", en_us,
407                    DISPID_FONT_UNDER, 0, S_OK,1);
408     test_names_ids(name_Strikethrough, "Strikethrough", NULL, "", en_us,
409                    DISPID_FONT_STRIKE, 0, S_OK,1);
410     test_names_ids(name_Weight, "Weight", NULL, "", en_us,
411                    DISPID_FONT_WEIGHT, 0, S_OK,1);
412     test_names_ids(name_Charset, "Charset", NULL, "", en_us,
413                    DISPID_FONT_CHARSET, 0, S_OK,1);
414
415     /* Capitalization doesn't matter. */
416     test_names_ids(name_nAmE, "nAmE", NULL, "", en_us,
417                    DISPID_FONT_NAME, 0, S_OK,1);
418
419     /* Unknown name. */
420     test_names_ids(name_Foo, "Foo", NULL, "", en_us,
421                    DISPID_UNKNOWN, 0, DISP_E_UNKNOWNNAME,1);
422
423     /* Pass several names: first is processed,                */
424     /* second gets DISPID_UNKNOWN and doesn't affect retval.  */
425     test_names_ids(name_Italic, "Italic", name_Name, "Name", en_us,
426                    DISPID_FONT_ITALIC, DISPID_UNKNOWN, S_OK,2);
427     test_names_ids(name_Italic, "Italic", name_Foo, "Foo", en_us,
428                    DISPID_FONT_ITALIC, DISPID_UNKNOWN, S_OK,2);
429
430     /* Locale ID has no effect. */
431     test_names_ids(name_Name, "Name", NULL, "", fr_fr,
432                    DISPID_FONT_NAME, 0, S_OK,1);
433     test_names_ids(name_Nom, "This is not a font", NULL, "", fr_fr,
434                    DISPID_UNKNOWN, 0, DISP_E_UNKNOWNNAME,1);
435
436     /* One of the arguments are invalid */
437     test_names_ids(name_Name, "Name", NULL, "", en_us,
438                    0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
439     test_names_ids(name_Italic, "Italic", NULL, "", en_us,
440                    0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
441     test_names_ids(name_Foo, "Foo", NULL, "", en_us,
442                    0xdeadbeef, 0xdeadbeef, E_INVALIDARG,0);
443
444     /* Crazy locale ID? */
445     test_names_ids(name_Name, "Name", NULL, "", -1,
446                    DISPID_FONT_NAME, 0, S_OK,1);
447 }
448
449 static void test_Invoke(void)
450 {
451     IFontDisp *fontdisp;
452     HRESULT hr;
453     VARIANTARG vararg;
454     DISPPARAMS dispparams;
455     VARIANT varresult;
456
457     hr = pOleCreateFontIndirect(NULL, &IID_IFontDisp, (void **)&fontdisp);
458     ok_ole_success(hr, "OleCreateFontIndirect");
459
460     V_VT(&vararg) = VT_BOOL;
461     V_BOOL(&vararg) = VARIANT_FALSE;
462     dispparams.cNamedArgs = 0;
463     dispparams.rgdispidNamedArgs = NULL;
464     dispparams.cArgs = 1;
465     dispparams.rgvarg = &vararg;
466     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_IFontDisp, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
467     ok(hr == DISP_E_UNKNOWNINTERFACE, "IFontDisp_Invoke should have returned DISP_E_UNKNOWNINTERFACE instead of 0x%08x\n", hr);
468
469     dispparams.cArgs = 0;
470     dispparams.rgvarg = NULL;
471     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL);
472     ok(hr == DISP_E_BADPARAMCOUNT, "IFontDisp_Invoke should have returned DISP_E_BADPARAMCOUNT instead of 0x%08x\n", hr);
473
474     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, NULL, NULL, NULL);
475     ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
476
477     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, NULL, NULL, NULL);
478     ok(hr == DISP_E_PARAMNOTOPTIONAL, "IFontDisp_Invoke should have returned DISP_E_PARAMNOTOPTIONAL instead of 0x%08x\n", hr);
479
480     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
481     ok_ole_success(hr, "IFontDisp_Invoke");
482
483     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_METHOD, NULL, &varresult, NULL, NULL);
484     ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
485
486     hr = IFontDisp_Invoke(fontdisp, 0xdeadbeef, &IID_NULL, 0, DISPATCH_PROPERTYGET, NULL, &varresult, NULL, NULL);
487     ok(hr == DISP_E_MEMBERNOTFOUND, "IFontDisp_Invoke should have returned DISP_E_MEMBERNOTFOUND instead of 0x%08x\n", hr);
488
489     dispparams.cArgs = 1;
490     dispparams.rgvarg = &vararg;
491     hr = IFontDisp_Invoke(fontdisp, DISPID_FONT_BOLD, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dispparams, &varresult, NULL, NULL);
492     ok_ole_success(hr, "IFontDisp_Invoke");
493
494     IFontDisp_Release(fontdisp);
495 }
496
497 static void test_IsEqual(void)
498 {
499     FONTDESC fd;
500     IFont* ifnt = NULL;
501     IFont* ifnt2 = NULL;
502     HRESULT hres;
503
504     /* Basic font description */
505     fd.cbSizeofstruct = sizeof(FONTDESC);
506     fd.lpstrName      = system_font;
507     S(fd.cySize).Lo   = 100;
508     S(fd.cySize).Hi   = 100;
509     fd.sWeight        = 0;
510     fd.sCharset       = 0;
511     fd.fItalic        = 0;
512     fd.fUnderline     = 0;
513     fd.fStrikethrough = 0;
514
515     /* Create font */
516     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt);
517
518     /* Test equal fonts */
519     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
520     hres = IFont_IsEqual(ifnt,ifnt2);
521     ok(hres == S_OK,
522         "IFont_IsEqual: (EQUAL) Expected S_OK but got 0x%08x\n",hres);
523     IFont_Release(ifnt2);
524
525     /* Check for bad pointer */
526     hres = IFont_IsEqual(ifnt,NULL);
527     ok(hres == E_POINTER,
528         "IFont_IsEqual: (NULL) Expected 0x80004003 but got 0x%08x\n",hres);
529
530     /* Test strName */
531     fd.lpstrName = arial_font;
532     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
533     hres = IFont_IsEqual(ifnt,ifnt2);
534     ok(hres == S_FALSE,
535         "IFont_IsEqual: (strName) Expected S_FALSE but got 0x%08x\n",hres);
536     fd.lpstrName = system_font;
537     IFont_Release(ifnt2);
538
539     /* Test lo font size */
540     S(fd.cySize).Lo = 10000;
541     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
542     hres = IFont_IsEqual(ifnt,ifnt2);
543     ok(hres == S_FALSE,
544         "IFont_IsEqual: (Lo font size) Expected S_FALSE but got 0x%08x\n",hres);
545     S(fd.cySize).Lo = 100;
546     IFont_Release(ifnt2);
547
548     /* Test hi font size */
549     S(fd.cySize).Hi = 10000;
550     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
551     hres = IFont_IsEqual(ifnt,ifnt2);
552     ok(hres == S_FALSE,
553         "IFont_IsEqual: (Hi font size) Expected S_FALSE but got 0x%08x\n",hres);
554     S(fd.cySize).Hi = 100;
555     IFont_Release(ifnt2);
556
557     /* Test font weight  */
558     fd.sWeight = 100;
559     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
560     hres = IFont_IsEqual(ifnt,ifnt2);
561     ok(hres == S_FALSE,
562         "IFont_IsEqual: (Weight) Expected S_FALSE but got 0x%08x\n",hres);
563     fd.sWeight = 0;
564     IFont_Release(ifnt2);
565
566     /* Test charset */
567     fd.sCharset = 1;
568     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
569     hres = IFont_IsEqual(ifnt,ifnt2);
570     ok(hres == S_FALSE,
571         "IFont_IsEqual: (Charset) Expected S_FALSE but got 0x%08x\n",hres);
572     fd.sCharset = 0;
573     IFont_Release(ifnt2);
574
575     /* Test italic setting */
576     fd.fItalic = 1;
577     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
578     hres = IFont_IsEqual(ifnt,ifnt2);
579     ok(hres == S_FALSE,
580         "IFont_IsEqual: (Italic) Expected S_FALSE but got 0x%08x\n",hres);
581     fd.fItalic = 0;
582     IFont_Release(ifnt2);
583
584     /* Test underline setting */
585     fd.fUnderline = 1;
586     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
587     hres = IFont_IsEqual(ifnt,ifnt2);
588     ok(hres == S_FALSE,
589         "IFont_IsEqual: (Underline) Expected S_FALSE but got 0x%08x\n",hres);
590     fd.fUnderline = 0;
591     IFont_Release(ifnt2);
592
593     /* Test strikethrough setting */
594     fd.fStrikethrough = 1;
595     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
596     hres = IFont_IsEqual(ifnt,ifnt2);
597     ok(hres == S_FALSE,
598         "IFont_IsEqual: (Strikethrough) Expected S_FALSE but got 0x%08x\n",hres);
599     fd.fStrikethrough = 0;
600     IFont_Release(ifnt2);
601
602     /* Free IFont. */
603     IFont_Release(ifnt);
604 }
605
606 static void test_ReleaseHfont(void)
607 {
608     FONTDESC fd;
609     LPVOID pvObj1 = NULL;
610     LPVOID pvObj2 = NULL;
611     IFont* ifnt1 = NULL;
612     IFont* ifnt2 = NULL;
613     HFONT hfnt1 = 0;
614     HFONT hfnt2 = 0;
615     HRESULT hres;
616
617     /* Basic font description */
618     fd.cbSizeofstruct = sizeof(FONTDESC);
619     fd.lpstrName      = system_font;
620     S(fd.cySize).Lo   = 100;
621     S(fd.cySize).Hi   = 100;
622     fd.sWeight        = 0;
623     fd.sCharset       = 0;
624     fd.fItalic        = 0;
625     fd.fUnderline     = 0;
626     fd.fStrikethrough = 0;
627
628     /* Create HFONTs and IFONTs */
629     pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj1);
630     ifnt1 = pvObj1;
631     IFont_get_hFont(ifnt1,&hfnt1);
632     fd.lpstrName = arial_font;
633     pOleCreateFontIndirect(&fd, &IID_IFont, &pvObj2);
634     ifnt2 = pvObj2;
635     IFont_get_hFont(ifnt2,&hfnt2);
636
637     /* Try invalid HFONT */
638     hres = IFont_ReleaseHfont(ifnt1,NULL);
639     ok(hres == E_INVALIDARG,
640         "IFont_ReleaseHfont: (Bad HFONT) Expected E_INVALIDARG but got 0x%08x\n",
641         hres);
642
643     /* Try to add a bad HFONT */
644     hres = IFont_ReleaseHfont(ifnt1,(HFONT)32);
645     ok(hres == S_FALSE,
646         "IFont_ReleaseHfont: (Bad HFONT) Expected S_FALSE but got 0x%08x\n",
647         hres);
648
649     /* Release all refs */
650     hres = IFont_ReleaseHfont(ifnt1,hfnt1);
651     ok(hres == S_OK,
652         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
653         hres);
654
655     hres = IFont_ReleaseHfont(ifnt2,hfnt2);
656     ok(hres == S_OK,
657         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
658         hres);
659
660     /* Check that both lists are empty */
661     hres = IFont_ReleaseHfont(ifnt1,hfnt1);
662     ok(hres == S_FALSE,
663         "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
664         hres);
665
666     /* The list should be empty */
667     hres = IFont_ReleaseHfont(ifnt2,hfnt2);
668     ok(hres == S_FALSE,
669         "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
670         hres);
671
672     IFont_Release(ifnt1);
673     IFont_Release(ifnt2);
674 }
675
676 static void test_AddRefHfont(void)
677 {
678     FONTDESC fd;
679     IFont* ifnt1 = NULL;
680     IFont* ifnt2 = NULL;
681     IFont* ifnt3 = NULL;
682     HFONT hfnt1 = 0;
683     HFONT hfnt2 = 0;
684     HFONT hfnt3 = 0;
685     HRESULT hres;
686
687     /* Basic font description */
688     fd.cbSizeofstruct = sizeof(FONTDESC);
689     fd.lpstrName      = system_font;
690     S(fd.cySize).Lo   = 100;
691     S(fd.cySize).Hi   = 100;
692     fd.sWeight        = 0;
693     fd.sCharset       = 0;
694     fd.fItalic        = 0;
695     fd.fUnderline     = 0;
696     fd.fStrikethrough = 0;
697
698     /* Create HFONTs and IFONTs */
699     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt1);
700     IFont_get_hFont(ifnt1,&hfnt1);
701     fd.lpstrName = arial_font;
702     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt2);
703     IFont_get_hFont(ifnt2,&hfnt2);
704
705     /* Try invalid HFONT */
706     hres = IFont_AddRefHfont(ifnt1,NULL);
707     ok(hres == E_INVALIDARG,
708         "IFont_AddRefHfont: (Bad HFONT) Expected E_INVALIDARG but got 0x%08x\n",
709         hres);
710
711     /* Try to add a bad HFONT */
712     hres = IFont_AddRefHfont(ifnt1,(HFONT)32);
713     ok(hres == S_FALSE,
714         "IFont_AddRefHfont: (Bad HFONT) Expected S_FALSE but got 0x%08x\n",
715         hres);
716
717     /* Add simple IFONT HFONT pair */
718     hres = IFont_AddRefHfont(ifnt1,hfnt1);
719     ok(hres == S_OK,
720         "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
721         hres);
722
723     /* IFONT and HFONT do not have to be the same (always looks at HFONT) */
724     hres = IFont_AddRefHfont(ifnt2,hfnt1);
725     ok(hres == S_OK,
726         "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
727         hres);
728
729     /* Release all hfnt1 refs */
730     hres = IFont_ReleaseHfont(ifnt1,hfnt1);
731     ok(hres == S_OK,
732         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
733         hres);
734
735     hres = IFont_ReleaseHfont(ifnt1,hfnt1);
736     ok(hres == S_OK,
737         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
738         hres);
739
740     hres = IFont_ReleaseHfont(ifnt1,hfnt1);
741     ok(hres == S_OK,
742         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
743         hres);
744
745     /* Check if hfnt1 is empty */
746     hres = IFont_ReleaseHfont(ifnt1,hfnt1);
747     ok(hres == S_FALSE,
748         "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
749         hres);
750
751     /* Release all hfnt2 refs */
752     hres = IFont_ReleaseHfont(ifnt2,hfnt2);
753     ok(hres == S_OK,
754         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
755         hres);
756
757     /* Check if hfnt2 is empty */
758     hres = IFont_ReleaseHfont(ifnt2,hfnt2);
759     ok(hres == S_FALSE,
760         "IFont_AddRefHfont: (Release ref) Expected S_FALSE but got 0x%08x\n",
761         hres);
762
763     /* Show that releasing an IFONT does not always release it from the HFONT cache. */
764
765     IFont_Release(ifnt1);
766
767     /* Add a reference for destroyed hfnt1 */
768     hres = IFont_AddRefHfont(ifnt2,hfnt1);
769     ok(hres == S_OK,
770         "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
771         hres);
772
773     /* Decrement reference for destroyed hfnt1 */
774     hres = IFont_ReleaseHfont(ifnt2,hfnt1);
775     ok(hres == S_OK ||
776        hres == S_FALSE, /* <= win2k */
777         "IFont_AddRefHfont: (Release ref) Expected S_OK or S_FALSE but got 0x%08x\n",
778         hres);
779
780     /* Shows that releasing all IFONT's does clear the HFONT cache. */
781
782     IFont_Release(ifnt2);
783
784     /* Need to make a new IFONT for testing */
785     fd.fUnderline = 1;
786     pOleCreateFontIndirect(&fd, &IID_IFont, (void **)&ifnt3);
787     IFont_get_hFont(ifnt3,&hfnt3);
788
789     /* Add a reference for destroyed hfnt1 */
790     hres = IFont_AddRefHfont(ifnt3,hfnt1);
791     ok(hres == S_FALSE,
792         "IFont_AddRefHfont: (Add ref) Expected S_OK but got 0x%08x\n",
793         hres);
794
795     /* Decrement reference for destroyed hfnt1 */
796     hres = IFont_ReleaseHfont(ifnt3,hfnt1);
797     ok(hres == S_FALSE,
798         "IFont_AddRefHfont: (Release ref) Expected S_OK but got 0x%08x\n",
799         hres);
800
801     IFont_Release(ifnt3);
802 }
803
804 static void test_returns(void)
805 {
806     IFont *pFont;
807     FONTDESC fontdesc;
808     HRESULT hr;
809
810     fontdesc.cbSizeofstruct = sizeof(fontdesc);
811     fontdesc.lpstrName = MSSansSerif_font;
812     fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
813     fontdesc.sWeight = FW_NORMAL;
814     fontdesc.sCharset = 0;
815     fontdesc.fItalic = FALSE;
816     fontdesc.fUnderline = FALSE;
817     fontdesc.fStrikethrough = FALSE;
818
819     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&pFont);
820     ok_ole_success(hr, "OleCreateFontIndirect");
821
822     hr = IFont_put_Name(pFont, NULL);
823     ok(hr == CTL_E_INVALIDPROPERTYVALUE,
824        "IFont::put_Name: Expected CTL_E_INVALIDPROPERTYVALUE got 0x%08x\n",
825        hr);
826
827     hr = IFont_get_Name(pFont, NULL);
828     ok(hr == E_POINTER,
829        "IFont::get_Name: Expected E_POINTER got 0x%08x\n",
830        hr);
831
832     hr = IFont_get_Size(pFont, NULL);
833     ok(hr == E_POINTER,
834        "IFont::get_Size: Expected E_POINTER got 0x%08x\n",
835        hr);
836
837     hr = IFont_get_Bold(pFont, NULL);
838     ok(hr == E_POINTER,
839        "IFont::get_Bold: Expected E_POINTER got 0x%08x\n",
840        hr);
841
842     IFont_Release(pFont);
843 }
844
845 static void test_hfont_lifetime(void)
846 {
847     IFont *font, *font2;
848     FONTDESC fontdesc;
849     HRESULT hr;
850     HFONT hfont, first_hfont = NULL;
851     CY size;
852     DWORD obj_type;
853     int i;
854
855     fontdesc.cbSizeofstruct = sizeof(fontdesc);
856     fontdesc.lpstrName = arial_font;
857     fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
858     fontdesc.sWeight = FW_NORMAL;
859     fontdesc.sCharset = ANSI_CHARSET;
860     fontdesc.fItalic = FALSE;
861     fontdesc.fUnderline = FALSE;
862     fontdesc.fStrikethrough = FALSE;
863
864     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
865     ok_ole_success(hr, "OleCreateFontIndirect");
866
867     hr = IFont_get_hFont(font, &hfont);
868     ok_ole_success(hr, "get_hFont");
869
870     /* show that if the font is updated the old hfont is deleted when the
871        new font is realized */
872     for(i = 0; i < 100; i++)
873     {
874         HFONT last_hfont = hfont;
875
876         size.int64 = (i + 10) * 20000;
877
878         obj_type = GetObjectType(hfont);
879         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
880
881         hr = IFont_put_Size(font, size);
882         ok_ole_success(hr, "put_Size");
883
884         /* put_Size doesn't cause the new font to be realized */
885         obj_type = GetObjectType(last_hfont);
886         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
887
888         hr = IFont_get_hFont(font, &hfont);
889         ok_ole_success(hr, "get_hFont");
890
891         obj_type = GetObjectType(last_hfont);
892         ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
893     }
894
895     /* now show that if we take a reference on the hfont, it persists
896        until the font object is released */
897     for(i = 0; i < 100; i++)
898     {
899
900         size.int64 = (i + 10) * 20000;
901
902         obj_type = GetObjectType(hfont);
903         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
904
905         hr = IFont_put_Size(font, size);
906         ok_ole_success(hr, "put_Size");
907
908         hr = IFont_get_hFont(font, &hfont);
909         ok_ole_success(hr, "get_hFont");
910
911         hr = IFont_AddRefHfont(font, hfont);
912         ok_ole_success(hr, "AddRefHfont");
913
914         if(i == 0) first_hfont = hfont;
915         obj_type = GetObjectType(first_hfont);
916         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
917     }
918
919     IFont_Release(font);
920
921     obj_type = GetObjectType(first_hfont);
922     ok(obj_type == 0, "got obj type %d\n", obj_type);
923
924     /* An AddRefHfont followed by a ReleaseHfont means the font doesn't not persist
925        through re-realization */
926
927     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
928     ok_ole_success(hr, "OleCreateFontIndirect");
929
930     hr = IFont_get_hFont(font, &hfont);
931     ok_ole_success(hr, "get_hFont");
932
933     for(i = 0; i < 100; i++)
934     {
935         HFONT last_hfont = hfont;
936
937         size.int64 = (i + 10) * 20000;
938
939         obj_type = GetObjectType(hfont);
940         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
941
942         hr = IFont_put_Size(font, size);
943         ok_ole_success(hr, "put_Size");
944
945         /* put_Size doesn't cause the new font to be realized */
946         obj_type = GetObjectType(last_hfont);
947         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
948
949         hr = IFont_get_hFont(font, &hfont);
950         ok_ole_success(hr, "get_hFont");
951
952         hr = IFont_AddRefHfont(font, hfont);
953         ok_ole_success(hr, "AddRefHfont");
954
955         hr = IFont_ReleaseHfont(font, hfont);
956         ok_ole_success(hr, "ReleaseHfont");
957
958         obj_type = GetObjectType(last_hfont);
959         ok(obj_type == 0, "%d: got obj type %d\n", i, obj_type);
960     }
961
962     /* Interestingly if we release a nonexistent reference on the hfont,
963      * it persists until the font object is released
964      */
965     for(i = 0; i < 100; i++)
966     {
967         size.int64 = (i + 10) * 20000;
968
969         obj_type = GetObjectType(hfont);
970         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
971
972         hr = IFont_put_Size(font, size);
973         ok_ole_success(hr, "put_Size");
974
975         hr = IFont_get_hFont(font, &hfont);
976         ok_ole_success(hr, "get_hFont");
977
978         hr = IFont_ReleaseHfont(font, hfont);
979         ok_ole_success(hr, "ReleaseHfont");
980
981         if(i == 0) first_hfont = hfont;
982         obj_type = GetObjectType(first_hfont);
983         ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
984     }
985
986     IFont_Release(font);
987
988     obj_type = GetObjectType(first_hfont);
989     ok(obj_type == 0, "got obj type %d\n", obj_type);
990
991     /* If we take two internal references on a hfont then we can release
992        it twice.  So it looks like there's a total reference count
993        that includes internal and external references */
994
995     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
996     ok_ole_success(hr, "OleCreateFontIndirect");
997     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font2);
998     ok_ole_success(hr, "OleCreateFontIndirect");
999
1000     hr = IFont_get_hFont(font, &hfont);
1001     ok_ole_success(hr, "get_hFont");
1002     hr = IFont_get_hFont(font2, &first_hfont);
1003     ok_ole_success(hr, "get_hFont");
1004 todo_wine
1005     ok(hfont == first_hfont, "fonts differ\n");
1006     hr = IFont_ReleaseHfont(font, hfont);
1007     ok(hr == S_OK, "got %08x\n", hr);
1008     hr = IFont_ReleaseHfont(font, hfont);
1009 todo_wine
1010     ok(hr == S_OK, "got %08x\n", hr);
1011     hr = IFont_ReleaseHfont(font, hfont);
1012     ok(hr == S_FALSE, "got %08x\n", hr);
1013
1014     obj_type = GetObjectType(hfont);
1015     ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1016
1017     IFont_Release(font);
1018
1019     obj_type = GetObjectType(hfont);
1020     ok(obj_type == OBJ_FONT, "got obj type %d\n", obj_type);
1021
1022     IFont_Release(font2);
1023
1024     obj_type = GetObjectType(hfont);
1025     ok(obj_type == 0, "got obj type %d\n", obj_type);
1026 }
1027
1028 static void test_realization(void)
1029 {
1030     IFont *font;
1031     FONTDESC fontdesc;
1032     HRESULT hr;
1033     BSTR name;
1034     SHORT cs;
1035
1036     /* Try to create a symbol only font (marlett) with charset
1037        set to ANSI.  This will result in another, ANSI, font
1038        being selected */
1039     fontdesc.cbSizeofstruct = sizeof(fontdesc);
1040     fontdesc.lpstrName = marlett_font;
1041     fontdesc.cySize.int64 = 12 * 10000; /* 12 pt */
1042     fontdesc.sWeight = FW_NORMAL;
1043     fontdesc.sCharset = ANSI_CHARSET;
1044     fontdesc.fItalic = FALSE;
1045     fontdesc.fUnderline = FALSE;
1046     fontdesc.fStrikethrough = FALSE;
1047
1048     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1049     ok_ole_success(hr, "OleCreateFontIndirect");
1050
1051     hr = IFont_get_Charset(font, &cs);
1052     ok_ole_success(hr, "get_Charset");
1053     ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
1054
1055     IFont_Release(font);
1056
1057     /* Now create an ANSI font and change the name to marlett */
1058
1059     fontdesc.lpstrName = arial_font;
1060
1061     hr = pOleCreateFontIndirect(&fontdesc, &IID_IFont, (void **)&font);
1062     ok_ole_success(hr, "OleCreateFontIndirect");
1063
1064     hr = IFont_get_Charset(font, &cs);
1065     ok_ole_success(hr, "get_Charset");
1066     ok(cs == ANSI_CHARSET, "got charset %d\n", cs);
1067
1068     name = SysAllocString(marlett_font);
1069     hr = IFont_put_Name(font, name);
1070     ok_ole_success(hr, "put_Name");
1071     SysFreeString(name);
1072
1073     hr = IFont_get_Name(font, &name);
1074     ok_ole_success(hr, "get_Name");
1075     ok(!lstrcmpiW(name, marlett_font), "got name %s\n", wine_dbgstr_w(name));
1076     SysFreeString(name);
1077
1078     hr = IFont_get_Charset(font, &cs);
1079     ok_ole_success(hr, "get_Charset");
1080     ok(cs == SYMBOL_CHARSET, "got charset %d\n", cs);
1081
1082     IFont_Release(font);
1083 }
1084
1085 START_TEST(olefont)
1086 {
1087         hOleaut32 = GetModuleHandleA("oleaut32.dll");
1088         pOleCreateFontIndirect = (void*)GetProcAddress(hOleaut32, "OleCreateFontIndirect");
1089         if (!pOleCreateFontIndirect)
1090         {
1091             win_skip("OleCreateFontIndirect not available\n");
1092             return;
1093         }
1094
1095         test_QueryInterface();
1096         test_type_info();
1097
1098         /* Test various size operations and conversions. */
1099         /* Add more as needed. */
1100         if (0) /* FIXME: failing tests */
1101         {
1102             test_ifont_sizes(180000, 0, 72, 2540, -18, "default");
1103             test_ifont_sizes(180000, 0, 144, 2540, -36, "ratio1");              /* change ratio */
1104             test_ifont_sizes(180000, 0, 72, 1270, -36, "ratio2");               /* 2nd part of ratio */
1105
1106             /* These depend on details of how IFont rounds sizes internally. */
1107             test_ifont_sizes(0, 0, 72, 2540, 0, "zero size");          /* zero size */
1108             test_ifont_sizes(186000, 0, 72, 2540, -19, "rounding");   /* test rounding */
1109         }
1110
1111         test_font_events_disp();
1112         test_GetIDsOfNames();
1113         test_Invoke();
1114         test_IsEqual();
1115         test_ReleaseHfont();
1116         test_AddRefHfont();
1117         test_returns();
1118         test_hfont_lifetime();
1119         test_realization();
1120 }