xref: /reactos/dll/win32/oleaut32/olefont.c (revision ae24453e)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * OLE Font encapsulation implementation
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This file contains an implementation of the IFont
5c2c66affSColin Finck  * interface and the OleCreateFontIndirect API call.
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * Copyright 1999 Francis Beaudet
8c2c66affSColin Finck  * Copyright 2006 (Google) Benjamin Arai
9c2c66affSColin Finck  *
10c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
11c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
12c2c66affSColin Finck  * License as published by the Free Software Foundation; either
13c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
14c2c66affSColin Finck  *
15c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
16c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18c2c66affSColin Finck  * Lesser General Public License for more details.
19c2c66affSColin Finck  *
20c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
21c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
22c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23c2c66affSColin Finck  */
24d506c2afSAmine Khaldi #include <assert.h>
25d506c2afSAmine Khaldi #include <stdarg.h>
26d506c2afSAmine Khaldi #include <string.h>
27c2c66affSColin Finck 
28d506c2afSAmine Khaldi #define COBJMACROS
29d506c2afSAmine Khaldi #define NONAMELESSUNION
30d506c2afSAmine Khaldi #define NONAMELESSSTRUCT
31d506c2afSAmine Khaldi 
32d506c2afSAmine Khaldi #include "winerror.h"
33d506c2afSAmine Khaldi #include "windef.h"
34d506c2afSAmine Khaldi #include "winbase.h"
35d506c2afSAmine Khaldi #include "wingdi.h"
36d506c2afSAmine Khaldi #include "winuser.h"
37d506c2afSAmine Khaldi #include "wine/list.h"
38d506c2afSAmine Khaldi #include "objbase.h"
39d506c2afSAmine Khaldi #include "oleauto.h"    /* for SysAllocString(....) */
40d506c2afSAmine Khaldi #include "ole2.h"
41d506c2afSAmine Khaldi #include "olectl.h"
42d506c2afSAmine Khaldi #include "wine/debug.h"
43d506c2afSAmine Khaldi #include "connpt.h" /* for CreateConnectionPoint */
44d506c2afSAmine Khaldi #include "oaidl.h"
45c2c66affSColin Finck 
46c2c66affSColin Finck WINE_DEFAULT_DEBUG_CHANNEL(ole);
47c2c66affSColin Finck 
48c2c66affSColin Finck /***********************************************************************
49c2c66affSColin Finck  * Declaration of constants used when serializing the font object.
50c2c66affSColin Finck  */
51c2c66affSColin Finck #define FONTPERSIST_ITALIC        0x02
52c2c66affSColin Finck #define FONTPERSIST_UNDERLINE     0x04
53c2c66affSColin Finck #define FONTPERSIST_STRIKETHROUGH 0x08
54c2c66affSColin Finck 
55c2c66affSColin Finck static HDC olefont_hdc;
56c2c66affSColin Finck 
57c2c66affSColin Finck /***********************************************************************
58c2c66affSColin Finck  * List of the HFONTs it has given out, with each one having a separate
59c2c66affSColin Finck  * ref count.
60c2c66affSColin Finck  */
61c2c66affSColin Finck typedef struct _HFONTItem
62c2c66affSColin Finck {
63c2c66affSColin Finck   struct list entry;
64c2c66affSColin Finck 
65c2c66affSColin Finck   /* Reference count of any IFont objects that own this hfont */
66c2c66affSColin Finck   LONG int_refs;
67c2c66affSColin Finck 
68c2c66affSColin Finck   /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
69c2c66affSColin Finck   LONG total_refs;
70c2c66affSColin Finck 
71c2c66affSColin Finck   /* The font associated with this object. */
72c2c66affSColin Finck   HFONT gdiFont;
73c2c66affSColin Finck 
74c2c66affSColin Finck } HFONTItem, *PHFONTItem;
75c2c66affSColin Finck 
76c2c66affSColin Finck static struct list OLEFontImpl_hFontList = LIST_INIT(OLEFontImpl_hFontList);
77c2c66affSColin Finck 
78c2c66affSColin Finck /* Counts how many fonts contain at least one lock */
79c2c66affSColin Finck static LONG ifont_cnt = 0;
80c2c66affSColin Finck 
81c2c66affSColin Finck /***********************************************************************
82c2c66affSColin Finck  * Critical section for OLEFontImpl_hFontList
83c2c66affSColin Finck  */
84c2c66affSColin Finck static CRITICAL_SECTION OLEFontImpl_csHFONTLIST;
85c2c66affSColin Finck static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
86c2c66affSColin Finck {
87c2c66affSColin Finck   0, 0, &OLEFontImpl_csHFONTLIST,
88c2c66affSColin Finck   { &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList,
89c2c66affSColin Finck     &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList },
90c2c66affSColin Finck     0, 0, { (DWORD_PTR)(__FILE__ ": OLEFontImpl_csHFONTLIST") }
91c2c66affSColin Finck };
92c2c66affSColin Finck static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
93c2c66affSColin Finck 
get_dc(void)94c2c66affSColin Finck static HDC get_dc(void)
95c2c66affSColin Finck {
96c2c66affSColin Finck     HDC hdc;
97c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
98c2c66affSColin Finck     if(!olefont_hdc)
99c2c66affSColin Finck         olefont_hdc = CreateCompatibleDC(NULL);
100c2c66affSColin Finck     hdc = olefont_hdc;
101c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
102c2c66affSColin Finck     return hdc;
103c2c66affSColin Finck }
104c2c66affSColin Finck 
delete_dc(void)105c2c66affSColin Finck static void delete_dc(void)
106c2c66affSColin Finck {
107c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
108c2c66affSColin Finck     if(olefont_hdc)
109c2c66affSColin Finck     {
110c2c66affSColin Finck         DeleteDC(olefont_hdc);
111c2c66affSColin Finck         olefont_hdc = NULL;
112c2c66affSColin Finck     }
113c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
114c2c66affSColin Finck }
115c2c66affSColin Finck 
HFONTItem_Delete(PHFONTItem item)116c2c66affSColin Finck static void HFONTItem_Delete(PHFONTItem item)
117c2c66affSColin Finck {
118c2c66affSColin Finck   DeleteObject(item->gdiFont);
119c2c66affSColin Finck   list_remove(&item->entry);
120c2c66affSColin Finck   HeapFree(GetProcessHeap(), 0, item);
121c2c66affSColin Finck }
122c2c66affSColin Finck 
123c2c66affSColin Finck /* Find hfont item entry in the list.  Should be called while holding the crit sect */
find_hfontitem(HFONT hfont)124c2c66affSColin Finck static HFONTItem *find_hfontitem(HFONT hfont)
125c2c66affSColin Finck {
126c2c66affSColin Finck     HFONTItem *item;
127c2c66affSColin Finck 
128c2c66affSColin Finck     LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry)
129c2c66affSColin Finck     {
130c2c66affSColin Finck         if (item->gdiFont == hfont)
131c2c66affSColin Finck             return item;
132c2c66affSColin Finck     }
133c2c66affSColin Finck     return NULL;
134c2c66affSColin Finck }
135c2c66affSColin Finck 
136c2c66affSColin Finck /* Add an item to the list with one internal reference */
add_hfontitem(HFONT hfont)137c2c66affSColin Finck static HRESULT add_hfontitem(HFONT hfont)
138c2c66affSColin Finck {
139c2c66affSColin Finck     HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item));
140c2c66affSColin Finck 
141c2c66affSColin Finck     if(!new_item) return E_OUTOFMEMORY;
142c2c66affSColin Finck 
143c2c66affSColin Finck     new_item->int_refs = 1;
144c2c66affSColin Finck     new_item->total_refs = 1;
145c2c66affSColin Finck     new_item->gdiFont = hfont;
146c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
147c2c66affSColin Finck     list_add_tail(&OLEFontImpl_hFontList,&new_item->entry);
148c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
149c2c66affSColin Finck     return S_OK;
150c2c66affSColin Finck }
151c2c66affSColin Finck 
inc_int_ref(HFONT hfont)152c2c66affSColin Finck static HRESULT inc_int_ref(HFONT hfont)
153c2c66affSColin Finck {
154c2c66affSColin Finck     HFONTItem *item;
155c2c66affSColin Finck     HRESULT hr = S_FALSE;
156c2c66affSColin Finck 
157c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
158c2c66affSColin Finck     item = find_hfontitem(hfont);
159c2c66affSColin Finck 
160c2c66affSColin Finck     if(item)
161c2c66affSColin Finck     {
162c2c66affSColin Finck         item->int_refs++;
163c2c66affSColin Finck         item->total_refs++;
164c2c66affSColin Finck         hr = S_OK;
165c2c66affSColin Finck     }
166c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
167c2c66affSColin Finck 
168c2c66affSColin Finck     return hr;
169c2c66affSColin Finck }
170c2c66affSColin Finck 
171c2c66affSColin Finck /* decrements the internal ref of a hfont item.  If both refs are zero it'll
172c2c66affSColin Finck    remove the item from the list and delete the hfont */
dec_int_ref(HFONT hfont)173c2c66affSColin Finck static HRESULT dec_int_ref(HFONT hfont)
174c2c66affSColin Finck {
175c2c66affSColin Finck     HFONTItem *item;
176c2c66affSColin Finck     HRESULT hr = S_FALSE;
177c2c66affSColin Finck 
178c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
179c2c66affSColin Finck     item = find_hfontitem(hfont);
180c2c66affSColin Finck 
181c2c66affSColin Finck     if(item)
182c2c66affSColin Finck     {
183c2c66affSColin Finck         item->int_refs--;
184c2c66affSColin Finck         item->total_refs--;
185c2c66affSColin Finck         if(item->int_refs == 0 && item->total_refs == 0)
186c2c66affSColin Finck             HFONTItem_Delete(item);
187c2c66affSColin Finck         hr = S_OK;
188c2c66affSColin Finck     }
189c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
190c2c66affSColin Finck 
191c2c66affSColin Finck     return hr;
192c2c66affSColin Finck }
193c2c66affSColin Finck 
inc_ext_ref(HFONT hfont)194c2c66affSColin Finck static HRESULT inc_ext_ref(HFONT hfont)
195c2c66affSColin Finck {
196c2c66affSColin Finck     HFONTItem *item;
197c2c66affSColin Finck     HRESULT hr = S_FALSE;
198c2c66affSColin Finck 
199c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
200c2c66affSColin Finck 
201c2c66affSColin Finck     item = find_hfontitem(hfont);
202c2c66affSColin Finck     if(item)
203c2c66affSColin Finck     {
204c2c66affSColin Finck         item->total_refs++;
205c2c66affSColin Finck         hr = S_OK;
206c2c66affSColin Finck     }
207c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
208c2c66affSColin Finck 
209c2c66affSColin Finck     return hr;
210c2c66affSColin Finck }
211c2c66affSColin Finck 
dec_ext_ref(HFONT hfont)212c2c66affSColin Finck static HRESULT dec_ext_ref(HFONT hfont)
213c2c66affSColin Finck {
214c2c66affSColin Finck     HFONTItem *item;
215c2c66affSColin Finck     HRESULT hr = S_FALSE;
216c2c66affSColin Finck 
217c2c66affSColin Finck     EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
218c2c66affSColin Finck 
219c2c66affSColin Finck     item = find_hfontitem(hfont);
220c2c66affSColin Finck     if(item)
221c2c66affSColin Finck     {
222c2c66affSColin Finck         if(--item->total_refs >= 0) hr = S_OK;
223c2c66affSColin Finck     }
224c2c66affSColin Finck     LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
225c2c66affSColin Finck 
226c2c66affSColin Finck     return hr;
227c2c66affSColin Finck }
228c2c66affSColin Finck 
strdupW(const WCHAR * str)229c2c66affSColin Finck static WCHAR *strdupW(const WCHAR* str)
230c2c66affSColin Finck {
231c2c66affSColin Finck     WCHAR *ret;
232*ae24453eSAmine Khaldi     DWORD size = (lstrlenW(str) + 1) * sizeof(WCHAR);
233c2c66affSColin Finck 
234c2c66affSColin Finck     ret = HeapAlloc(GetProcessHeap(), 0, size);
235c2c66affSColin Finck     if(ret)
236c2c66affSColin Finck         memcpy(ret, str, size);
237c2c66affSColin Finck     return ret;
238c2c66affSColin Finck }
239c2c66affSColin Finck 
240c2c66affSColin Finck /***********************************************************************
241c2c66affSColin Finck  * Declaration of the implementation class for the IFont interface
242c2c66affSColin Finck  */
243c2c66affSColin Finck typedef struct OLEFontImpl OLEFontImpl;
244c2c66affSColin Finck 
245c2c66affSColin Finck struct OLEFontImpl
246c2c66affSColin Finck {
247c2c66affSColin Finck   /*
248c2c66affSColin Finck    * This class supports many interfaces. IUnknown, IFont,
249c2c66affSColin Finck    * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
250c2c66affSColin Finck    * The first two are supported by the first vtable, the next two are
251c2c66affSColin Finck    * supported by the second table and the last two have their own.
252c2c66affSColin Finck    */
253c2c66affSColin Finck   IFont                       IFont_iface;
254c2c66affSColin Finck   IDispatch                   IDispatch_iface;
255c2c66affSColin Finck   IPersistStream              IPersistStream_iface;
256c2c66affSColin Finck   IConnectionPointContainer   IConnectionPointContainer_iface;
257c2c66affSColin Finck   IPersistPropertyBag         IPersistPropertyBag_iface;
258c2c66affSColin Finck   IPersistStreamInit          IPersistStreamInit_iface;
259c2c66affSColin Finck   /*
260c2c66affSColin Finck    * Reference count for that instance of the class.
261c2c66affSColin Finck    */
262c2c66affSColin Finck   LONG ref;
263c2c66affSColin Finck 
264c2c66affSColin Finck   /*
265c2c66affSColin Finck    * This structure contains the description of the class.
266c2c66affSColin Finck    */
267c2c66affSColin Finck   FONTDESC description;
268c2c66affSColin Finck 
269c2c66affSColin Finck   /*
270c2c66affSColin Finck    * Contain the font associated with this object.
271c2c66affSColin Finck    */
272c2c66affSColin Finck   HFONT gdiFont;
273c2c66affSColin Finck   BOOL dirty;
274c2c66affSColin Finck   /*
275c2c66affSColin Finck    * Size ratio
276c2c66affSColin Finck    */
277c2c66affSColin Finck   LONG cyLogical;
278c2c66affSColin Finck   LONG cyHimetric;
279c2c66affSColin Finck 
280c2c66affSColin Finck   /*
281c2c66affSColin Finck    * Stash realized height (pixels) from TEXTMETRIC - used in get_Size()
282c2c66affSColin Finck    */
283c2c66affSColin Finck   LONG nRealHeight;
284c2c66affSColin Finck 
285c2c66affSColin Finck   IConnectionPoint *pPropertyNotifyCP;
286c2c66affSColin Finck   IConnectionPoint *pFontEventsCP;
287c2c66affSColin Finck };
288c2c66affSColin Finck 
impl_from_IFont(IFont * iface)289c2c66affSColin Finck static inline OLEFontImpl *impl_from_IFont(IFont *iface)
290c2c66affSColin Finck {
291c2c66affSColin Finck     return CONTAINING_RECORD(iface, OLEFontImpl, IFont_iface);
292c2c66affSColin Finck }
293c2c66affSColin Finck 
impl_from_IDispatch(IDispatch * iface)294c2c66affSColin Finck static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface )
295c2c66affSColin Finck {
296c2c66affSColin Finck     return CONTAINING_RECORD(iface, OLEFontImpl, IDispatch_iface);
297c2c66affSColin Finck }
298c2c66affSColin Finck 
impl_from_IPersistStream(IPersistStream * iface)299c2c66affSColin Finck static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface )
300c2c66affSColin Finck {
301c2c66affSColin Finck     return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStream_iface);
302c2c66affSColin Finck }
303c2c66affSColin Finck 
impl_from_IConnectionPointContainer(IConnectionPointContainer * iface)304c2c66affSColin Finck static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
305c2c66affSColin Finck {
306c2c66affSColin Finck     return CONTAINING_RECORD(iface, OLEFontImpl, IConnectionPointContainer_iface);
307c2c66affSColin Finck }
308c2c66affSColin Finck 
impl_from_IPersistPropertyBag(IPersistPropertyBag * iface)309c2c66affSColin Finck static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface )
310c2c66affSColin Finck {
311c2c66affSColin Finck     return CONTAINING_RECORD(iface, OLEFontImpl, IPersistPropertyBag_iface);
312c2c66affSColin Finck }
313c2c66affSColin Finck 
impl_from_IPersistStreamInit(IPersistStreamInit * iface)314c2c66affSColin Finck static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface )
315c2c66affSColin Finck {
316c2c66affSColin Finck     return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStreamInit_iface);
317c2c66affSColin Finck }
318c2c66affSColin Finck 
319c2c66affSColin Finck 
320c2c66affSColin Finck /***********************************************************************
321c2c66affSColin Finck  * Prototypes for the implementation functions for the IFont
322c2c66affSColin Finck  * interface
323c2c66affSColin Finck  */
324c2c66affSColin Finck static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc);
325c2c66affSColin Finck static void         OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
326c2c66affSColin Finck static ULONG        WINAPI OLEFontImpl_AddRef(IFont* iface);
327c2c66affSColin Finck 
328c2c66affSColin Finck /******************************************************************************
329c2c66affSColin Finck  *		OleCreateFontIndirect	[OLEAUT32.420]
330c2c66affSColin Finck  */
OleCreateFontIndirect(LPFONTDESC lpFontDesc,REFIID riid,LPVOID * ppvObj)331c2c66affSColin Finck HRESULT WINAPI OleCreateFontIndirect(
332c2c66affSColin Finck   LPFONTDESC lpFontDesc,
333c2c66affSColin Finck   REFIID     riid,
334c2c66affSColin Finck   LPVOID*     ppvObj)
335c2c66affSColin Finck {
336c2c66affSColin Finck   OLEFontImpl* newFont;
337c2c66affSColin Finck   HRESULT      hr;
338c2c66affSColin Finck   FONTDESC     fd;
339c2c66affSColin Finck 
340c2c66affSColin Finck   TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
341c2c66affSColin Finck 
342c2c66affSColin Finck   if (!ppvObj) return E_POINTER;
343c2c66affSColin Finck 
344c2c66affSColin Finck   *ppvObj = 0;
345c2c66affSColin Finck 
346c2c66affSColin Finck   if (!lpFontDesc) {
347c2c66affSColin Finck     static WCHAR fname[] = { 'S','y','s','t','e','m',0 };
348c2c66affSColin Finck 
349c2c66affSColin Finck     fd.cbSizeofstruct = sizeof(fd);
350c2c66affSColin Finck     fd.lpstrName      = fname;
351c2c66affSColin Finck     fd.cySize.s.Lo    = 80000;
352c2c66affSColin Finck     fd.cySize.s.Hi    = 0;
353c2c66affSColin Finck     fd.sWeight 	      = 0;
354c2c66affSColin Finck     fd.sCharset       = 0;
355c2c66affSColin Finck     fd.fItalic        = FALSE;
356c2c66affSColin Finck     fd.fUnderline     = FALSE;
357c2c66affSColin Finck     fd.fStrikethrough = FALSE;
358c2c66affSColin Finck     lpFontDesc = &fd;
359c2c66affSColin Finck   }
360c2c66affSColin Finck 
361c2c66affSColin Finck   newFont = OLEFontImpl_Construct(lpFontDesc);
362c2c66affSColin Finck   if (!newFont) return E_OUTOFMEMORY;
363c2c66affSColin Finck 
364c2c66affSColin Finck   hr = IFont_QueryInterface(&newFont->IFont_iface, riid, ppvObj);
365c2c66affSColin Finck   IFont_Release(&newFont->IFont_iface);
366c2c66affSColin Finck 
367c2c66affSColin Finck   return hr;
368c2c66affSColin Finck }
369c2c66affSColin Finck 
370c2c66affSColin Finck 
371c2c66affSColin Finck /***********************************************************************
372c2c66affSColin Finck  * Implementation of the OLEFontImpl class.
373c2c66affSColin Finck  */
374c2c66affSColin Finck 
375c2c66affSColin Finck /***********************************************************************
376c2c66affSColin Finck  *    OLEFont_SendNotify (internal)
377c2c66affSColin Finck  *
378c2c66affSColin Finck  * Sends notification messages of changed properties to any interested
379c2c66affSColin Finck  * connections.
380c2c66affSColin Finck  */
OLEFont_SendNotify(OLEFontImpl * this,DISPID dispID)381c2c66affSColin Finck static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
382c2c66affSColin Finck {
383c2c66affSColin Finck   static const WCHAR wszName[] = {'N','a','m','e',0};
384c2c66affSColin Finck   static const WCHAR wszSize[] = {'S','i','z','e',0};
385c2c66affSColin Finck   static const WCHAR wszBold[] = {'B','o','l','d',0};
386c2c66affSColin Finck   static const WCHAR wszItalic[] = {'I','t','a','l','i','c',0};
387c2c66affSColin Finck   static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0};
388c2c66affSColin Finck   static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
389c2c66affSColin Finck   static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0};
390c2c66affSColin Finck   static const WCHAR wszCharset[] = {'C','h','a','r','s','e','t',0};
391c2c66affSColin Finck   static const LPCWSTR dispid_mapping[] =
392c2c66affSColin Finck   {
393c2c66affSColin Finck     wszName,
394c2c66affSColin Finck     NULL,
395c2c66affSColin Finck     wszSize,
396c2c66affSColin Finck     wszBold,
397c2c66affSColin Finck     wszItalic,
398c2c66affSColin Finck     wszUnder,
399c2c66affSColin Finck     wszStrike,
400c2c66affSColin Finck     wszWeight,
401c2c66affSColin Finck     wszCharset
402c2c66affSColin Finck   };
403c2c66affSColin Finck 
404c2c66affSColin Finck   IEnumConnections *pEnum;
405c2c66affSColin Finck   CONNECTDATA CD;
406c2c66affSColin Finck   HRESULT hres;
407c2c66affSColin Finck 
408c2c66affSColin Finck   this->dirty = TRUE;
409c2c66affSColin Finck 
410c2c66affSColin Finck   hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
411c2c66affSColin Finck   if (SUCCEEDED(hres))
412c2c66affSColin Finck   {
413c2c66affSColin Finck     while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
414c2c66affSColin Finck       IPropertyNotifySink *sink;
415c2c66affSColin Finck 
416c2c66affSColin Finck       IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (void**)&sink);
417c2c66affSColin Finck       IPropertyNotifySink_OnChanged(sink, dispID);
418c2c66affSColin Finck       IPropertyNotifySink_Release(sink);
419c2c66affSColin Finck       IUnknown_Release(CD.pUnk);
420c2c66affSColin Finck     }
421c2c66affSColin Finck     IEnumConnections_Release(pEnum);
422c2c66affSColin Finck   }
423c2c66affSColin Finck 
424c2c66affSColin Finck   hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum);
425c2c66affSColin Finck   if (SUCCEEDED(hres))
426c2c66affSColin Finck   {
427c2c66affSColin Finck     DISPPARAMS dispparams;
428c2c66affSColin Finck     VARIANTARG vararg;
429c2c66affSColin Finck 
430c2c66affSColin Finck     VariantInit(&vararg);
431c2c66affSColin Finck     V_VT(&vararg) = VT_BSTR;
432c2c66affSColin Finck     V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]);
433c2c66affSColin Finck 
434c2c66affSColin Finck     dispparams.cArgs = 1;
435c2c66affSColin Finck     dispparams.cNamedArgs = 0;
436c2c66affSColin Finck     dispparams.rgdispidNamedArgs = NULL;
437c2c66affSColin Finck     dispparams.rgvarg = &vararg;
438c2c66affSColin Finck 
439c2c66affSColin Finck     while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
440c2c66affSColin Finck         IFontEventsDisp *disp;
441c2c66affSColin Finck 
442c2c66affSColin Finck         IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (void**)&disp);
443c2c66affSColin Finck         IFontEventsDisp_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
444c2c66affSColin Finck                                LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
445c2c66affSColin Finck                                NULL, NULL);
446c2c66affSColin Finck 
447c2c66affSColin Finck         IFontEventsDisp_Release(disp);
448c2c66affSColin Finck         IUnknown_Release(CD.pUnk);
449c2c66affSColin Finck     }
450c2c66affSColin Finck     VariantClear(&vararg);
451c2c66affSColin Finck     IEnumConnections_Release(pEnum);
452c2c66affSColin Finck   }
453c2c66affSColin Finck }
454c2c66affSColin Finck 
455c2c66affSColin Finck /************************************************************************
456c2c66affSColin Finck  * OLEFontImpl_QueryInterface (IUnknown)
457c2c66affSColin Finck  *
458c2c66affSColin Finck  * See Windows documentation for more details on IUnknown methods.
459c2c66affSColin Finck  */
OLEFontImpl_QueryInterface(IFont * iface,REFIID riid,void ** ppvObject)460c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_QueryInterface(
461c2c66affSColin Finck   IFont*  iface,
462c2c66affSColin Finck   REFIID  riid,
463c2c66affSColin Finck   void**  ppvObject)
464c2c66affSColin Finck {
465c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
466c2c66affSColin Finck 
467c2c66affSColin Finck   TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
468c2c66affSColin Finck 
469c2c66affSColin Finck   *ppvObject = 0;
470c2c66affSColin Finck 
471c2c66affSColin Finck   if (IsEqualGUID(&IID_IUnknown, riid) ||
472c2c66affSColin Finck       IsEqualGUID(&IID_IFont, riid))
473c2c66affSColin Finck   {
474c2c66affSColin Finck     *ppvObject = this;
475c2c66affSColin Finck   }
476c2c66affSColin Finck   else if (IsEqualGUID(&IID_IDispatch, riid) ||
477c2c66affSColin Finck            IsEqualGUID(&IID_IFontDisp, riid))
478c2c66affSColin Finck   {
479c2c66affSColin Finck     *ppvObject = &this->IDispatch_iface;
480c2c66affSColin Finck   }
481c2c66affSColin Finck   else if (IsEqualGUID(&IID_IPersist, riid) ||
482c2c66affSColin Finck            IsEqualGUID(&IID_IPersistStream, riid))
483c2c66affSColin Finck   {
484c2c66affSColin Finck     *ppvObject = &this->IPersistStream_iface;
485c2c66affSColin Finck   }
486c2c66affSColin Finck   else if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
487c2c66affSColin Finck   {
488c2c66affSColin Finck     *ppvObject = &this->IConnectionPointContainer_iface;
489c2c66affSColin Finck   }
490c2c66affSColin Finck   else if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
491c2c66affSColin Finck   {
492c2c66affSColin Finck     *ppvObject = &this->IPersistPropertyBag_iface;
493c2c66affSColin Finck   }
494c2c66affSColin Finck   else if (IsEqualGUID(&IID_IPersistStreamInit, riid))
495c2c66affSColin Finck   {
496c2c66affSColin Finck     *ppvObject = &this->IPersistStreamInit_iface;
497c2c66affSColin Finck   }
498c2c66affSColin Finck 
499c2c66affSColin Finck   if (!*ppvObject)
500c2c66affSColin Finck   {
501c2c66affSColin Finck     FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid));
502c2c66affSColin Finck     return E_NOINTERFACE;
503c2c66affSColin Finck   }
504c2c66affSColin Finck 
505c2c66affSColin Finck   IFont_AddRef(iface);
506c2c66affSColin Finck 
507c2c66affSColin Finck   return S_OK;
508c2c66affSColin Finck }
509c2c66affSColin Finck 
510c2c66affSColin Finck /************************************************************************
511c2c66affSColin Finck  * OLEFontImpl_AddRef (IUnknown)
512c2c66affSColin Finck  */
OLEFontImpl_AddRef(IFont * iface)513c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_AddRef(
514c2c66affSColin Finck   IFont* iface)
515c2c66affSColin Finck {
516c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
517c2c66affSColin Finck   TRACE("(%p)->(ref=%d)\n", this, this->ref);
518c2c66affSColin Finck   return InterlockedIncrement(&this->ref);
519c2c66affSColin Finck }
520c2c66affSColin Finck 
521c2c66affSColin Finck /************************************************************************
522c2c66affSColin Finck  * OLEFontImpl_Release (IUnknown)
523c2c66affSColin Finck  */
OLEFontImpl_Release(IFont * iface)524c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_Release(IFont* iface)
525c2c66affSColin Finck {
526c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
527c2c66affSColin Finck   ULONG ref;
528c2c66affSColin Finck 
529c2c66affSColin Finck   TRACE("(%p)->(ref=%d)\n", this, this->ref);
530c2c66affSColin Finck 
531c2c66affSColin Finck   ref = InterlockedDecrement(&this->ref);
532c2c66affSColin Finck 
533c2c66affSColin Finck   if (ref == 0)
534c2c66affSColin Finck   {
535c2c66affSColin Finck     ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
536c2c66affSColin Finck 
537c2c66affSColin Finck     /* Final IFont object so destroy font cache */
538c2c66affSColin Finck     if (fontlist_refs == 0)
539c2c66affSColin Finck     {
540c2c66affSColin Finck       HFONTItem *item, *cursor2;
541c2c66affSColin Finck 
542c2c66affSColin Finck       EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
543c2c66affSColin Finck       LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry)
544c2c66affSColin Finck         HFONTItem_Delete(item);
545c2c66affSColin Finck       LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
546c2c66affSColin Finck       delete_dc();
547c2c66affSColin Finck     }
548c2c66affSColin Finck     else
549c2c66affSColin Finck     {
550c2c66affSColin Finck       dec_int_ref(this->gdiFont);
551c2c66affSColin Finck     }
552c2c66affSColin Finck     OLEFontImpl_Destroy(this);
553c2c66affSColin Finck   }
554c2c66affSColin Finck 
555c2c66affSColin Finck   return ref;
556c2c66affSColin Finck }
557c2c66affSColin Finck 
558c2c66affSColin Finck typedef struct
559c2c66affSColin Finck {
560c2c66affSColin Finck     short orig_cs;
561c2c66affSColin Finck     short avail_cs;
562c2c66affSColin Finck } enum_data;
563c2c66affSColin Finck 
font_enum_proc(const LOGFONTW * elf,const TEXTMETRICW * ntm,DWORD type,LPARAM lp)564c2c66affSColin Finck static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp)
565c2c66affSColin Finck {
566c2c66affSColin Finck     enum_data *data = (enum_data*)lp;
567c2c66affSColin Finck 
568c2c66affSColin Finck     if(elf->lfCharSet == data->orig_cs)
569c2c66affSColin Finck     {
570c2c66affSColin Finck         data->avail_cs = data->orig_cs;
571c2c66affSColin Finck         return 0;
572c2c66affSColin Finck     }
573c2c66affSColin Finck     if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet;
574c2c66affSColin Finck     return 1;
575c2c66affSColin Finck }
576c2c66affSColin Finck 
realize_font(OLEFontImpl * This)577c2c66affSColin Finck static void realize_font(OLEFontImpl *This)
578c2c66affSColin Finck {
579c2c66affSColin Finck     LOGFONTW logFont;
580c2c66affSColin Finck     INT fontHeight;
581c2c66affSColin Finck     WCHAR text_face[LF_FACESIZE];
582c2c66affSColin Finck     HDC hdc = get_dc();
583c2c66affSColin Finck     HFONT old_font;
584c2c66affSColin Finck     TEXTMETRICW tm;
585c2c66affSColin Finck 
586c2c66affSColin Finck     if (!This->dirty) return;
587c2c66affSColin Finck 
588c2c66affSColin Finck     text_face[0] = 0;
589c2c66affSColin Finck 
590c2c66affSColin Finck     if(This->gdiFont)
591c2c66affSColin Finck     {
592c2c66affSColin Finck         old_font = SelectObject(hdc, This->gdiFont);
5935db885caSAmine Khaldi         GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face);
594c2c66affSColin Finck         SelectObject(hdc, old_font);
595c2c66affSColin Finck         dec_int_ref(This->gdiFont);
596c2c66affSColin Finck         This->gdiFont = 0;
597c2c66affSColin Finck     }
598c2c66affSColin Finck 
599c2c66affSColin Finck     memset(&logFont, 0, sizeof(LOGFONTW));
600c2c66affSColin Finck 
601c2c66affSColin Finck     lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
602c2c66affSColin Finck     logFont.lfCharSet = This->description.sCharset;
603c2c66affSColin Finck 
604c2c66affSColin Finck     /* If the font name has been changed then enumerate all charsets
605c2c66affSColin Finck        and pick one that'll result in the font specified being selected */
606c2c66affSColin Finck     if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
607c2c66affSColin Finck     {
608c2c66affSColin Finck         enum_data data;
609c2c66affSColin Finck         data.orig_cs = This->description.sCharset;
610c2c66affSColin Finck         data.avail_cs = -1;
611c2c66affSColin Finck         logFont.lfCharSet = DEFAULT_CHARSET;
612c2c66affSColin Finck         EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
613c2c66affSColin Finck         if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
614c2c66affSColin Finck     }
615c2c66affSColin Finck 
616c2c66affSColin Finck     /*
617c2c66affSColin Finck      * The height of the font returned by the get_Size property is the
618c2c66affSColin Finck      * height of the font in points multiplied by 10000... Using some
619c2c66affSColin Finck      * simple conversions and the ratio given by the application, it can
620c2c66affSColin Finck      * be converted to a height in pixels.
621c2c66affSColin Finck      *
622c2c66affSColin Finck      * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
623c2c66affSColin Finck      * Ratio is applied here relative to the standard.
624c2c66affSColin Finck      */
625c2c66affSColin Finck 
626c2c66affSColin Finck     fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
627c2c66affSColin Finck 
628c2c66affSColin Finck     logFont.lfHeight          = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
629c2c66affSColin Finck                                                                   (-fontHeight/10000L);
630c2c66affSColin Finck     logFont.lfItalic          = This->description.fItalic;
631c2c66affSColin Finck     logFont.lfUnderline       = This->description.fUnderline;
632c2c66affSColin Finck     logFont.lfStrikeOut       = This->description.fStrikethrough;
633c2c66affSColin Finck     logFont.lfWeight          = This->description.sWeight;
634c2c66affSColin Finck     logFont.lfOutPrecision    = OUT_CHARACTER_PRECIS;
635c2c66affSColin Finck     logFont.lfClipPrecision   = CLIP_DEFAULT_PRECIS;
636c2c66affSColin Finck     logFont.lfQuality         = DEFAULT_QUALITY;
637c2c66affSColin Finck     logFont.lfPitchAndFamily  = DEFAULT_PITCH;
638c2c66affSColin Finck 
639c2c66affSColin Finck     This->gdiFont = CreateFontIndirectW(&logFont);
640c2c66affSColin Finck     This->dirty = FALSE;
641c2c66affSColin Finck 
642c2c66affSColin Finck     add_hfontitem(This->gdiFont);
643c2c66affSColin Finck 
644c2c66affSColin Finck     /* Fixup the name and charset properties so that they match the
645c2c66affSColin Finck        selected font */
646c2c66affSColin Finck     old_font = SelectObject(get_dc(), This->gdiFont);
6475db885caSAmine Khaldi     GetTextFaceW(hdc, ARRAY_SIZE(text_face), text_face);
648c2c66affSColin Finck     if(lstrcmpiW(text_face, This->description.lpstrName))
649c2c66affSColin Finck     {
650c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
651c2c66affSColin Finck         This->description.lpstrName = strdupW(text_face);
652c2c66affSColin Finck     }
653c2c66affSColin Finck     GetTextMetricsW(hdc, &tm);
654c2c66affSColin Finck     This->description.sCharset = tm.tmCharSet;
655c2c66affSColin Finck     /* While we have it handy, stash the realized font height for use by get_Size() */
656c2c66affSColin Finck     This->nRealHeight = tm.tmHeight - tm.tmInternalLeading; /* corresponds to LOGFONT lfHeight */
657c2c66affSColin Finck     SelectObject(hdc, old_font);
658c2c66affSColin Finck }
659c2c66affSColin Finck 
660c2c66affSColin Finck /************************************************************************
661c2c66affSColin Finck  * OLEFontImpl_get_Name (IFont)
662c2c66affSColin Finck  *
663c2c66affSColin Finck  * See Windows documentation for more details on IFont methods.
664c2c66affSColin Finck  */
OLEFontImpl_get_Name(IFont * iface,BSTR * pname)665c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Name(
666c2c66affSColin Finck   IFont*  iface,
667c2c66affSColin Finck   BSTR* pname)
668c2c66affSColin Finck {
669c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
670c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pname);
671c2c66affSColin Finck 
672c2c66affSColin Finck   if (pname==0)
673c2c66affSColin Finck     return E_POINTER;
674c2c66affSColin Finck 
675c2c66affSColin Finck   realize_font(this);
676c2c66affSColin Finck 
677c2c66affSColin Finck   if (this->description.lpstrName!=0)
678c2c66affSColin Finck     *pname = SysAllocString(this->description.lpstrName);
679c2c66affSColin Finck   else
680c2c66affSColin Finck     *pname = 0;
681c2c66affSColin Finck 
682c2c66affSColin Finck   return S_OK;
683c2c66affSColin Finck }
684c2c66affSColin Finck 
685c2c66affSColin Finck /************************************************************************
686c2c66affSColin Finck  * OLEFontImpl_put_Name (IFont)
687c2c66affSColin Finck  */
OLEFontImpl_put_Name(IFont * iface,BSTR name)688c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Name(
689c2c66affSColin Finck   IFont* iface,
690c2c66affSColin Finck   BSTR name)
691c2c66affSColin Finck {
692c2c66affSColin Finck   OLEFontImpl *This = impl_from_IFont(iface);
693c2c66affSColin Finck   TRACE("(%p)->(%p)\n", This, name);
694c2c66affSColin Finck 
695c2c66affSColin Finck   if (!name)
696c2c66affSColin Finck     return CTL_E_INVALIDPROPERTYVALUE;
697c2c66affSColin Finck 
698c2c66affSColin Finck   HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
699c2c66affSColin Finck   This->description.lpstrName = strdupW(name);
700c2c66affSColin Finck   if (!This->description.lpstrName) return E_OUTOFMEMORY;
701c2c66affSColin Finck 
702c2c66affSColin Finck   TRACE("new name %s\n", debugstr_w(This->description.lpstrName));
703c2c66affSColin Finck   OLEFont_SendNotify(This, DISPID_FONT_NAME);
704c2c66affSColin Finck   return S_OK;
705c2c66affSColin Finck }
706c2c66affSColin Finck 
707c2c66affSColin Finck /************************************************************************
708c2c66affSColin Finck  * OLEFontImpl_get_Size (IFont)
709c2c66affSColin Finck  */
OLEFontImpl_get_Size(IFont * iface,CY * psize)710c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Size(
711c2c66affSColin Finck   IFont* iface,
712c2c66affSColin Finck   CY*    psize)
713c2c66affSColin Finck {
714c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
715c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, psize);
716c2c66affSColin Finck 
717c2c66affSColin Finck   if (!psize) return E_POINTER;
718c2c66affSColin Finck 
719c2c66affSColin Finck   realize_font(this);
720c2c66affSColin Finck 
721c2c66affSColin Finck   /*
722c2c66affSColin Finck    * Convert realized font height in pixels to points descaled by current
723c2c66affSColin Finck    * scaling ratio then scaled up by 10000.
724c2c66affSColin Finck    */
725c2c66affSColin Finck   psize->s.Lo = MulDiv(this->nRealHeight,
726c2c66affSColin Finck                        this->cyHimetric * 72 * 10000,
727c2c66affSColin Finck                        this->cyLogical * 2540);
728c2c66affSColin Finck   psize->s.Hi = 0;
729c2c66affSColin Finck 
730c2c66affSColin Finck   return S_OK;
731c2c66affSColin Finck }
732c2c66affSColin Finck 
733c2c66affSColin Finck /************************************************************************
734c2c66affSColin Finck  * OLEFontImpl_put_Size (IFont)
735c2c66affSColin Finck  */
OLEFontImpl_put_Size(IFont * iface,CY size)736c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Size(
737c2c66affSColin Finck   IFont* iface,
738c2c66affSColin Finck   CY     size)
739c2c66affSColin Finck {
740c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
741c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, size.s.Lo);
742c2c66affSColin Finck   this->description.cySize.s.Hi = 0;
743c2c66affSColin Finck   this->description.cySize.s.Lo = size.s.Lo;
744c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_SIZE);
745c2c66affSColin Finck 
746c2c66affSColin Finck   return S_OK;
747c2c66affSColin Finck }
748c2c66affSColin Finck 
749c2c66affSColin Finck /************************************************************************
750c2c66affSColin Finck  * OLEFontImpl_get_Bold (IFont)
751c2c66affSColin Finck  *
752c2c66affSColin Finck  * See Windows documentation for more details on IFont methods.
753c2c66affSColin Finck  */
OLEFontImpl_get_Bold(IFont * iface,BOOL * pbold)754c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Bold(
755c2c66affSColin Finck   IFont*  iface,
756c2c66affSColin Finck   BOOL* pbold)
757c2c66affSColin Finck {
758c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
759c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pbold);
760c2c66affSColin Finck 
761c2c66affSColin Finck   if (!pbold) return E_POINTER;
762c2c66affSColin Finck 
763c2c66affSColin Finck   realize_font(this);
764c2c66affSColin Finck 
765c2c66affSColin Finck   *pbold = this->description.sWeight > 550;
766c2c66affSColin Finck 
767c2c66affSColin Finck   return S_OK;
768c2c66affSColin Finck }
769c2c66affSColin Finck 
770c2c66affSColin Finck /************************************************************************
771c2c66affSColin Finck  * OLEFontImpl_put_Bold (IFont)
772c2c66affSColin Finck  */
OLEFontImpl_put_Bold(IFont * iface,BOOL bold)773c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Bold(
774c2c66affSColin Finck   IFont* iface,
775c2c66affSColin Finck   BOOL bold)
776c2c66affSColin Finck {
777c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
778c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, bold);
779c2c66affSColin Finck   this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
780c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_BOLD);
781c2c66affSColin Finck 
782c2c66affSColin Finck   return S_OK;
783c2c66affSColin Finck }
784c2c66affSColin Finck 
785c2c66affSColin Finck /************************************************************************
786c2c66affSColin Finck  * OLEFontImpl_get_Italic (IFont)
787c2c66affSColin Finck  */
OLEFontImpl_get_Italic(IFont * iface,BOOL * pitalic)788c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Italic(
789c2c66affSColin Finck   IFont*  iface,
790c2c66affSColin Finck   BOOL* pitalic)
791c2c66affSColin Finck {
792c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
793c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pitalic);
794c2c66affSColin Finck 
795c2c66affSColin Finck   if (pitalic==0)
796c2c66affSColin Finck     return E_POINTER;
797c2c66affSColin Finck 
798c2c66affSColin Finck   realize_font(this);
799c2c66affSColin Finck 
800c2c66affSColin Finck   *pitalic = this->description.fItalic;
801c2c66affSColin Finck 
802c2c66affSColin Finck   return S_OK;
803c2c66affSColin Finck }
804c2c66affSColin Finck 
805c2c66affSColin Finck /************************************************************************
806c2c66affSColin Finck  * OLEFontImpl_put_Italic (IFont)
807c2c66affSColin Finck  */
OLEFontImpl_put_Italic(IFont * iface,BOOL italic)808c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Italic(
809c2c66affSColin Finck   IFont* iface,
810c2c66affSColin Finck   BOOL italic)
811c2c66affSColin Finck {
812c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
813c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, italic);
814c2c66affSColin Finck 
815c2c66affSColin Finck   this->description.fItalic = italic;
816c2c66affSColin Finck 
817c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
818c2c66affSColin Finck   return S_OK;
819c2c66affSColin Finck }
820c2c66affSColin Finck 
821c2c66affSColin Finck /************************************************************************
822c2c66affSColin Finck  * OLEFontImpl_get_Underline (IFont)
823c2c66affSColin Finck  */
OLEFontImpl_get_Underline(IFont * iface,BOOL * punderline)824c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Underline(
825c2c66affSColin Finck   IFont*  iface,
826c2c66affSColin Finck   BOOL* punderline)
827c2c66affSColin Finck {
828c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
829c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, punderline);
830c2c66affSColin Finck 
831c2c66affSColin Finck   if (punderline==0)
832c2c66affSColin Finck     return E_POINTER;
833c2c66affSColin Finck 
834c2c66affSColin Finck   realize_font(this);
835c2c66affSColin Finck 
836c2c66affSColin Finck   *punderline = this->description.fUnderline;
837c2c66affSColin Finck 
838c2c66affSColin Finck   return S_OK;
839c2c66affSColin Finck }
840c2c66affSColin Finck 
841c2c66affSColin Finck /************************************************************************
842c2c66affSColin Finck  * OLEFontImpl_put_Underline (IFont)
843c2c66affSColin Finck  */
OLEFontImpl_put_Underline(IFont * iface,BOOL underline)844c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Underline(
845c2c66affSColin Finck   IFont* iface,
846c2c66affSColin Finck   BOOL underline)
847c2c66affSColin Finck {
848c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
849c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, underline);
850c2c66affSColin Finck 
851c2c66affSColin Finck   this->description.fUnderline = underline;
852c2c66affSColin Finck 
853c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_UNDER);
854c2c66affSColin Finck   return S_OK;
855c2c66affSColin Finck }
856c2c66affSColin Finck 
857c2c66affSColin Finck /************************************************************************
858c2c66affSColin Finck  * OLEFontImpl_get_Strikethrough (IFont)
859c2c66affSColin Finck  */
OLEFontImpl_get_Strikethrough(IFont * iface,BOOL * pstrikethrough)860c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
861c2c66affSColin Finck   IFont*  iface,
862c2c66affSColin Finck   BOOL* pstrikethrough)
863c2c66affSColin Finck {
864c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
865c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pstrikethrough);
866c2c66affSColin Finck 
867c2c66affSColin Finck   if (pstrikethrough==0)
868c2c66affSColin Finck     return E_POINTER;
869c2c66affSColin Finck 
870c2c66affSColin Finck   realize_font(this);
871c2c66affSColin Finck 
872c2c66affSColin Finck   *pstrikethrough = this->description.fStrikethrough;
873c2c66affSColin Finck 
874c2c66affSColin Finck   return S_OK;
875c2c66affSColin Finck }
876c2c66affSColin Finck 
877c2c66affSColin Finck /************************************************************************
878c2c66affSColin Finck  * OLEFontImpl_put_Strikethrough (IFont)
879c2c66affSColin Finck  */
OLEFontImpl_put_Strikethrough(IFont * iface,BOOL strikethrough)880c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
881c2c66affSColin Finck  IFont* iface,
882c2c66affSColin Finck  BOOL strikethrough)
883c2c66affSColin Finck {
884c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
885c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, strikethrough);
886c2c66affSColin Finck 
887c2c66affSColin Finck   this->description.fStrikethrough = strikethrough;
888c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
889c2c66affSColin Finck 
890c2c66affSColin Finck   return S_OK;
891c2c66affSColin Finck }
892c2c66affSColin Finck 
893c2c66affSColin Finck /************************************************************************
894c2c66affSColin Finck  * OLEFontImpl_get_Weight (IFont)
895c2c66affSColin Finck  */
OLEFontImpl_get_Weight(IFont * iface,short * pweight)896c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Weight(
897c2c66affSColin Finck   IFont* iface,
898c2c66affSColin Finck   short* pweight)
899c2c66affSColin Finck {
900c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
901c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pweight);
902c2c66affSColin Finck 
903c2c66affSColin Finck   if (pweight==0)
904c2c66affSColin Finck     return E_POINTER;
905c2c66affSColin Finck 
906c2c66affSColin Finck   realize_font(this);
907c2c66affSColin Finck 
908c2c66affSColin Finck   *pweight = this->description.sWeight;
909c2c66affSColin Finck 
910c2c66affSColin Finck   return S_OK;
911c2c66affSColin Finck }
912c2c66affSColin Finck 
913c2c66affSColin Finck /************************************************************************
914c2c66affSColin Finck  * OLEFontImpl_put_Weight (IFont)
915c2c66affSColin Finck  */
OLEFontImpl_put_Weight(IFont * iface,short weight)916c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Weight(
917c2c66affSColin Finck   IFont* iface,
918c2c66affSColin Finck   short  weight)
919c2c66affSColin Finck {
920c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
921c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, weight);
922c2c66affSColin Finck 
923c2c66affSColin Finck   this->description.sWeight = weight;
924c2c66affSColin Finck 
925c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
926c2c66affSColin Finck   return S_OK;
927c2c66affSColin Finck }
928c2c66affSColin Finck 
929c2c66affSColin Finck /************************************************************************
930c2c66affSColin Finck  * OLEFontImpl_get_Charset (IFont)
931c2c66affSColin Finck  */
OLEFontImpl_get_Charset(IFont * iface,short * pcharset)932c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_Charset(
933c2c66affSColin Finck   IFont* iface,
934c2c66affSColin Finck   short* pcharset)
935c2c66affSColin Finck {
936c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
937c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pcharset);
938c2c66affSColin Finck 
939c2c66affSColin Finck   if (pcharset==0)
940c2c66affSColin Finck     return E_POINTER;
941c2c66affSColin Finck 
942c2c66affSColin Finck   realize_font(this);
943c2c66affSColin Finck 
944c2c66affSColin Finck   *pcharset = this->description.sCharset;
945c2c66affSColin Finck 
946c2c66affSColin Finck   return S_OK;
947c2c66affSColin Finck }
948c2c66affSColin Finck 
949c2c66affSColin Finck /************************************************************************
950c2c66affSColin Finck  * OLEFontImpl_put_Charset (IFont)
951c2c66affSColin Finck  */
OLEFontImpl_put_Charset(IFont * iface,short charset)952c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_put_Charset(
953c2c66affSColin Finck   IFont* iface,
954c2c66affSColin Finck   short charset)
955c2c66affSColin Finck {
956c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
957c2c66affSColin Finck   TRACE("(%p)->(%d)\n", this, charset);
958c2c66affSColin Finck 
959c2c66affSColin Finck   this->description.sCharset = charset;
960c2c66affSColin Finck   OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
961c2c66affSColin Finck 
962c2c66affSColin Finck   return S_OK;
963c2c66affSColin Finck }
964c2c66affSColin Finck 
965c2c66affSColin Finck /************************************************************************
966c2c66affSColin Finck  * OLEFontImpl_get_hFont (IFont)
967c2c66affSColin Finck  */
OLEFontImpl_get_hFont(IFont * iface,HFONT * phfont)968c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_get_hFont(
969c2c66affSColin Finck   IFont*   iface,
970c2c66affSColin Finck   HFONT* phfont)
971c2c66affSColin Finck {
972c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
973c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, phfont);
974c2c66affSColin Finck   if (phfont==NULL)
975c2c66affSColin Finck     return E_POINTER;
976c2c66affSColin Finck 
977c2c66affSColin Finck   realize_font(this);
978c2c66affSColin Finck 
979c2c66affSColin Finck   *phfont = this->gdiFont;
980c2c66affSColin Finck   TRACE("Returning %p\n", *phfont);
981c2c66affSColin Finck   return S_OK;
982c2c66affSColin Finck }
983c2c66affSColin Finck 
984c2c66affSColin Finck /************************************************************************
985c2c66affSColin Finck  * OLEFontImpl_Clone (IFont)
986c2c66affSColin Finck  */
OLEFontImpl_Clone(IFont * iface,IFont ** ppfont)987c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_Clone(
988c2c66affSColin Finck   IFont*  iface,
989c2c66affSColin Finck   IFont** ppfont)
990c2c66affSColin Finck {
991c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
992c2c66affSColin Finck   OLEFontImpl* newObject;
993c2c66affSColin Finck 
994c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, ppfont);
995c2c66affSColin Finck 
996c2c66affSColin Finck   if (ppfont == NULL)
997c2c66affSColin Finck     return E_POINTER;
998c2c66affSColin Finck 
999c2c66affSColin Finck   *ppfont = NULL;
1000c2c66affSColin Finck 
1001c2c66affSColin Finck   newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
1002c2c66affSColin Finck   if (newObject==NULL)
1003c2c66affSColin Finck     return E_OUTOFMEMORY;
1004c2c66affSColin Finck 
1005c2c66affSColin Finck   *newObject = *this;
1006c2c66affSColin Finck   /* allocate separate buffer */
1007c2c66affSColin Finck   newObject->description.lpstrName = strdupW(this->description.lpstrName);
1008c2c66affSColin Finck 
1009c2c66affSColin Finck   /* Increment internal ref in hfont item list */
1010c2c66affSColin Finck   if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
1011c2c66affSColin Finck 
1012c2c66affSColin Finck   InterlockedIncrement(&ifont_cnt);
1013c2c66affSColin Finck 
1014c2c66affSColin Finck   newObject->pPropertyNotifyCP = NULL;
1015c2c66affSColin Finck   newObject->pFontEventsCP = NULL;
1016c2c66affSColin Finck   CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IPropertyNotifySink,
1017c2c66affSColin Finck                          &newObject->pPropertyNotifyCP);
1018c2c66affSColin Finck   CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IFontEventsDisp,
1019c2c66affSColin Finck                          &newObject->pFontEventsCP);
1020c2c66affSColin Finck 
1021c2c66affSColin Finck   if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
1022c2c66affSColin Finck   {
1023c2c66affSColin Finck     OLEFontImpl_Destroy(newObject);
1024c2c66affSColin Finck     return E_OUTOFMEMORY;
1025c2c66affSColin Finck   }
1026c2c66affSColin Finck 
1027c2c66affSColin Finck   /* The cloned object starts with a reference count of 1 */
1028c2c66affSColin Finck   newObject->ref = 1;
1029c2c66affSColin Finck 
1030c2c66affSColin Finck   *ppfont = &newObject->IFont_iface;
1031c2c66affSColin Finck 
1032c2c66affSColin Finck   return S_OK;
1033c2c66affSColin Finck }
1034c2c66affSColin Finck 
1035c2c66affSColin Finck /************************************************************************
1036c2c66affSColin Finck  * OLEFontImpl_IsEqual (IFont)
1037c2c66affSColin Finck  */
OLEFontImpl_IsEqual(IFont * iface,IFont * pFontOther)1038c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IsEqual(
1039c2c66affSColin Finck   IFont* iface,
1040c2c66affSColin Finck   IFont* pFontOther)
1041c2c66affSColin Finck {
1042c2c66affSColin Finck   OLEFontImpl *left = impl_from_IFont(iface);
1043c2c66affSColin Finck   OLEFontImpl *right = impl_from_IFont(pFontOther);
1044c2c66affSColin Finck   INT ret;
1045c2c66affSColin Finck   INT left_len,right_len;
1046c2c66affSColin Finck 
1047c2c66affSColin Finck   if(pFontOther == NULL)
1048c2c66affSColin Finck     return E_POINTER;
1049c2c66affSColin Finck   else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo)
1050c2c66affSColin Finck     return S_FALSE;
1051c2c66affSColin Finck   else if (left->description.cySize.s.Hi != right->description.cySize.s.Hi)
1052c2c66affSColin Finck     return S_FALSE;
1053c2c66affSColin Finck   else if (left->description.sWeight != right->description.sWeight)
1054c2c66affSColin Finck     return S_FALSE;
1055c2c66affSColin Finck   else if (left->description.sCharset != right->description.sCharset)
1056c2c66affSColin Finck     return S_FALSE;
1057c2c66affSColin Finck   else if (left->description.fItalic != right->description.fItalic)
1058c2c66affSColin Finck     return S_FALSE;
1059c2c66affSColin Finck   else if (left->description.fUnderline != right->description.fUnderline)
1060c2c66affSColin Finck     return S_FALSE;
1061c2c66affSColin Finck   else if (left->description.fStrikethrough != right->description.fStrikethrough)
1062c2c66affSColin Finck     return S_FALSE;
1063c2c66affSColin Finck 
1064c2c66affSColin Finck   /* Check from string */
1065*ae24453eSAmine Khaldi   left_len = lstrlenW(left->description.lpstrName);
1066*ae24453eSAmine Khaldi   right_len = lstrlenW(right->description.lpstrName);
1067c2c66affSColin Finck   ret = CompareStringW(0,0,left->description.lpstrName, left_len,
1068c2c66affSColin Finck     right->description.lpstrName, right_len);
1069c2c66affSColin Finck   if (ret != CSTR_EQUAL)
1070c2c66affSColin Finck     return S_FALSE;
1071c2c66affSColin Finck 
1072c2c66affSColin Finck   return S_OK;
1073c2c66affSColin Finck }
1074c2c66affSColin Finck 
1075c2c66affSColin Finck /************************************************************************
1076c2c66affSColin Finck  * OLEFontImpl_SetRatio (IFont)
1077c2c66affSColin Finck  */
OLEFontImpl_SetRatio(IFont * iface,LONG cyLogical,LONG cyHimetric)1078c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_SetRatio(
1079c2c66affSColin Finck   IFont* iface,
1080c2c66affSColin Finck   LONG   cyLogical,
1081c2c66affSColin Finck   LONG   cyHimetric)
1082c2c66affSColin Finck {
1083c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
1084c2c66affSColin Finck   TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric);
1085c2c66affSColin Finck 
1086c2c66affSColin Finck   if(cyLogical == 0 || cyHimetric == 0)
1087c2c66affSColin Finck     return E_FAIL;
1088c2c66affSColin Finck 
1089c2c66affSColin Finck   /* cyLogical and cyHimetric both set to 1 is a special case that
1090c2c66affSColin Finck      does not change the scaling but also does not fail */
1091c2c66affSColin Finck   if(cyLogical == 1 && cyHimetric == 1)
1092c2c66affSColin Finck     return S_OK;
1093c2c66affSColin Finck 
1094c2c66affSColin Finck   this->cyLogical  = cyLogical;
1095c2c66affSColin Finck   this->cyHimetric = cyHimetric;
1096c2c66affSColin Finck   this->dirty = TRUE;
1097c2c66affSColin Finck 
1098c2c66affSColin Finck   return S_OK;
1099c2c66affSColin Finck }
1100c2c66affSColin Finck 
1101c2c66affSColin Finck /************************************************************************
1102c2c66affSColin Finck  * OLEFontImpl_QueryTextMetrics (IFont)
1103c2c66affSColin Finck  */
OLEFontImpl_QueryTextMetrics(IFont * iface,TEXTMETRICOLE * ptm)1104c2c66affSColin Finck static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(
1105c2c66affSColin Finck   IFont*         iface,
1106c2c66affSColin Finck   TEXTMETRICOLE* ptm)
1107c2c66affSColin Finck {
1108c2c66affSColin Finck   HDC hdcRef;
1109c2c66affSColin Finck   HFONT hOldFont, hNewFont;
1110c2c66affSColin Finck 
1111c2c66affSColin Finck   hdcRef = GetDC(0);
1112c2c66affSColin Finck   IFont_get_hFont(iface, &hNewFont);
1113c2c66affSColin Finck   hOldFont = SelectObject(hdcRef, hNewFont);
1114c2c66affSColin Finck   GetTextMetricsW(hdcRef, ptm);
1115c2c66affSColin Finck   SelectObject(hdcRef, hOldFont);
1116c2c66affSColin Finck   ReleaseDC(0, hdcRef);
1117c2c66affSColin Finck   return S_OK;
1118c2c66affSColin Finck }
1119c2c66affSColin Finck 
1120c2c66affSColin Finck /************************************************************************
1121c2c66affSColin Finck  * OLEFontImpl_AddRefHfont (IFont)
1122c2c66affSColin Finck  */
OLEFontImpl_AddRefHfont(IFont * iface,HFONT hfont)1123c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1124c2c66affSColin Finck   IFont*  iface,
1125c2c66affSColin Finck   HFONT hfont)
1126c2c66affSColin Finck {
1127c2c66affSColin Finck     OLEFontImpl *this = impl_from_IFont(iface);
1128c2c66affSColin Finck 
1129c2c66affSColin Finck     TRACE("(%p)->(%p)\n", this, hfont);
1130c2c66affSColin Finck 
1131c2c66affSColin Finck     if (!hfont) return E_INVALIDARG;
1132c2c66affSColin Finck 
1133c2c66affSColin Finck     return inc_ext_ref(hfont);
1134c2c66affSColin Finck }
1135c2c66affSColin Finck 
1136c2c66affSColin Finck /************************************************************************
1137c2c66affSColin Finck  * OLEFontImpl_ReleaseHfont (IFont)
1138c2c66affSColin Finck  */
OLEFontImpl_ReleaseHfont(IFont * iface,HFONT hfont)1139c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1140c2c66affSColin Finck   IFont*  iface,
1141c2c66affSColin Finck   HFONT hfont)
1142c2c66affSColin Finck {
1143c2c66affSColin Finck     OLEFontImpl *this = impl_from_IFont(iface);
1144c2c66affSColin Finck 
1145c2c66affSColin Finck     TRACE("(%p)->(%p)\n", this, hfont);
1146c2c66affSColin Finck 
1147c2c66affSColin Finck     if (!hfont) return E_INVALIDARG;
1148c2c66affSColin Finck 
1149c2c66affSColin Finck     return dec_ext_ref(hfont);
1150c2c66affSColin Finck }
1151c2c66affSColin Finck 
1152c2c66affSColin Finck /************************************************************************
1153c2c66affSColin Finck  * OLEFontImpl_SetHdc (IFont)
1154c2c66affSColin Finck  */
OLEFontImpl_SetHdc(IFont * iface,HDC hdc)1155c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_SetHdc(
1156c2c66affSColin Finck   IFont* iface,
1157c2c66affSColin Finck   HDC  hdc)
1158c2c66affSColin Finck {
1159c2c66affSColin Finck   OLEFontImpl *this = impl_from_IFont(iface);
1160c2c66affSColin Finck   FIXME("(%p)->(%p): Stub\n", this, hdc);
1161c2c66affSColin Finck   return E_NOTIMPL;
1162c2c66affSColin Finck }
1163c2c66affSColin Finck 
1164c2c66affSColin Finck static const IFontVtbl OLEFontImpl_VTable =
1165c2c66affSColin Finck {
1166c2c66affSColin Finck   OLEFontImpl_QueryInterface,
1167c2c66affSColin Finck   OLEFontImpl_AddRef,
1168c2c66affSColin Finck   OLEFontImpl_Release,
1169c2c66affSColin Finck   OLEFontImpl_get_Name,
1170c2c66affSColin Finck   OLEFontImpl_put_Name,
1171c2c66affSColin Finck   OLEFontImpl_get_Size,
1172c2c66affSColin Finck   OLEFontImpl_put_Size,
1173c2c66affSColin Finck   OLEFontImpl_get_Bold,
1174c2c66affSColin Finck   OLEFontImpl_put_Bold,
1175c2c66affSColin Finck   OLEFontImpl_get_Italic,
1176c2c66affSColin Finck   OLEFontImpl_put_Italic,
1177c2c66affSColin Finck   OLEFontImpl_get_Underline,
1178c2c66affSColin Finck   OLEFontImpl_put_Underline,
1179c2c66affSColin Finck   OLEFontImpl_get_Strikethrough,
1180c2c66affSColin Finck   OLEFontImpl_put_Strikethrough,
1181c2c66affSColin Finck   OLEFontImpl_get_Weight,
1182c2c66affSColin Finck   OLEFontImpl_put_Weight,
1183c2c66affSColin Finck   OLEFontImpl_get_Charset,
1184c2c66affSColin Finck   OLEFontImpl_put_Charset,
1185c2c66affSColin Finck   OLEFontImpl_get_hFont,
1186c2c66affSColin Finck   OLEFontImpl_Clone,
1187c2c66affSColin Finck   OLEFontImpl_IsEqual,
1188c2c66affSColin Finck   OLEFontImpl_SetRatio,
1189c2c66affSColin Finck   OLEFontImpl_QueryTextMetrics,
1190c2c66affSColin Finck   OLEFontImpl_AddRefHfont,
1191c2c66affSColin Finck   OLEFontImpl_ReleaseHfont,
1192c2c66affSColin Finck   OLEFontImpl_SetHdc
1193c2c66affSColin Finck };
1194c2c66affSColin Finck 
1195c2c66affSColin Finck /************************************************************************
1196c2c66affSColin Finck  * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1197c2c66affSColin Finck  */
OLEFontImpl_IDispatch_QueryInterface(IDispatch * iface,REFIID riid,VOID ** ppvoid)1198c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1199c2c66affSColin Finck   IDispatch* iface,
1200c2c66affSColin Finck   REFIID     riid,
1201c2c66affSColin Finck   VOID**     ppvoid)
1202c2c66affSColin Finck {
1203c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1204c2c66affSColin Finck   return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
1205c2c66affSColin Finck }
1206c2c66affSColin Finck 
1207c2c66affSColin Finck /************************************************************************
1208c2c66affSColin Finck  * OLEFontImpl_IDispatch_Release (IUnknown)
1209c2c66affSColin Finck  */
OLEFontImpl_IDispatch_Release(IDispatch * iface)1210c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1211c2c66affSColin Finck   IDispatch* iface)
1212c2c66affSColin Finck {
1213c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1214c2c66affSColin Finck   return IFont_Release(&this->IFont_iface);
1215c2c66affSColin Finck }
1216c2c66affSColin Finck 
1217c2c66affSColin Finck /************************************************************************
1218c2c66affSColin Finck  * OLEFontImpl_IDispatch_AddRef (IUnknown)
1219c2c66affSColin Finck  */
OLEFontImpl_IDispatch_AddRef(IDispatch * iface)1220c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1221c2c66affSColin Finck   IDispatch* iface)
1222c2c66affSColin Finck {
1223c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1224c2c66affSColin Finck   return IFont_AddRef(&this->IFont_iface);
1225c2c66affSColin Finck }
1226c2c66affSColin Finck 
1227c2c66affSColin Finck /************************************************************************
1228c2c66affSColin Finck  * OLEFontImpl_GetTypeInfoCount (IDispatch)
1229c2c66affSColin Finck  */
OLEFontImpl_GetTypeInfoCount(IDispatch * iface,unsigned int * pctinfo)1230c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1231c2c66affSColin Finck   IDispatch*    iface,
1232c2c66affSColin Finck   unsigned int* pctinfo)
1233c2c66affSColin Finck {
1234c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1235c2c66affSColin Finck   TRACE("(%p)->(%p)\n", this, pctinfo);
1236c2c66affSColin Finck   *pctinfo = 1;
1237c2c66affSColin Finck 
1238c2c66affSColin Finck   return S_OK;
1239c2c66affSColin Finck }
1240c2c66affSColin Finck 
1241c2c66affSColin Finck /************************************************************************
1242c2c66affSColin Finck  * OLEFontImpl_GetTypeInfo (IDispatch)
1243c2c66affSColin Finck  */
OLEFontImpl_GetTypeInfo(IDispatch * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1244c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1245c2c66affSColin Finck   IDispatch*  iface,
1246c2c66affSColin Finck   UINT      iTInfo,
1247c2c66affSColin Finck   LCID        lcid,
1248c2c66affSColin Finck   ITypeInfo** ppTInfo)
1249c2c66affSColin Finck {
1250c2c66affSColin Finck   static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
1251c2c66affSColin Finck   ITypeLib *tl;
1252c2c66affSColin Finck   HRESULT hres;
1253c2c66affSColin Finck 
1254c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1255c2c66affSColin Finck   TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);
1256c2c66affSColin Finck   if (iTInfo != 0)
1257c2c66affSColin Finck     return E_FAIL;
1258c2c66affSColin Finck   hres = LoadTypeLib(stdole2tlb, &tl);
1259c2c66affSColin Finck   if (FAILED(hres)) {
1260c2c66affSColin Finck     ERR("Could not load the stdole2.tlb?\n");
1261c2c66affSColin Finck     return hres;
1262c2c66affSColin Finck   }
1263c2c66affSColin Finck   hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IFontDisp, ppTInfo);
1264c2c66affSColin Finck   ITypeLib_Release(tl);
1265c2c66affSColin Finck   if (FAILED(hres)) {
1266c2c66affSColin Finck     FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres);
1267c2c66affSColin Finck   }
1268c2c66affSColin Finck   return hres;
1269c2c66affSColin Finck }
1270c2c66affSColin Finck 
1271c2c66affSColin Finck /************************************************************************
1272c2c66affSColin Finck  * OLEFontImpl_GetIDsOfNames (IDispatch)
1273c2c66affSColin Finck  */
OLEFontImpl_GetIDsOfNames(IDispatch * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)1274c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1275c2c66affSColin Finck   IDispatch*  iface,
1276c2c66affSColin Finck   REFIID      riid,
1277c2c66affSColin Finck   LPOLESTR* rgszNames,
1278c2c66affSColin Finck   UINT      cNames,
1279c2c66affSColin Finck   LCID        lcid,
1280c2c66affSColin Finck   DISPID*     rgDispId)
1281c2c66affSColin Finck {
1282c2c66affSColin Finck   ITypeInfo * pTInfo;
1283c2c66affSColin Finck   HRESULT hres;
1284c2c66affSColin Finck 
1285c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1286c2c66affSColin Finck 
1287c2c66affSColin Finck   TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid),
1288c2c66affSColin Finck         rgszNames, cNames, (int)lcid, rgDispId);
1289c2c66affSColin Finck 
1290c2c66affSColin Finck   if (cNames == 0) return E_INVALIDARG;
1291c2c66affSColin Finck 
1292c2c66affSColin Finck   hres = IDispatch_GetTypeInfo(iface, 0, lcid, &pTInfo);
1293c2c66affSColin Finck   if (FAILED(hres))
1294c2c66affSColin Finck   {
1295c2c66affSColin Finck     ERR("GetTypeInfo failed.\n");
1296c2c66affSColin Finck     return hres;
1297c2c66affSColin Finck   }
1298c2c66affSColin Finck 
1299c2c66affSColin Finck   /* convert names to DISPIDs */
1300c2c66affSColin Finck   hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId);
1301c2c66affSColin Finck   ITypeInfo_Release(pTInfo);
1302c2c66affSColin Finck 
1303c2c66affSColin Finck   return hres;
1304c2c66affSColin Finck }
1305c2c66affSColin Finck 
1306c2c66affSColin Finck /************************************************************************
1307c2c66affSColin Finck  * OLEFontImpl_Invoke (IDispatch)
1308c2c66affSColin Finck  *
1309c2c66affSColin Finck  */
OLEFontImpl_Invoke(IDispatch * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExepInfo,UINT * puArgErr)1310c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_Invoke(
1311c2c66affSColin Finck   IDispatch*  iface,
1312c2c66affSColin Finck   DISPID      dispIdMember,
1313c2c66affSColin Finck   REFIID      riid,
1314c2c66affSColin Finck   LCID        lcid,
1315c2c66affSColin Finck   WORD        wFlags,
1316c2c66affSColin Finck   DISPPARAMS* pDispParams,
1317c2c66affSColin Finck   VARIANT*    pVarResult,
1318c2c66affSColin Finck   EXCEPINFO*  pExepInfo,
1319c2c66affSColin Finck   UINT*     puArgErr)
1320c2c66affSColin Finck {
1321c2c66affSColin Finck   OLEFontImpl *this = impl_from_IDispatch(iface);
1322c2c66affSColin Finck   HRESULT hr;
1323c2c66affSColin Finck 
1324c2c66affSColin Finck   TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember,
1325c2c66affSColin Finck     debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExepInfo,
1326c2c66affSColin Finck     puArgErr);
1327c2c66affSColin Finck 
1328c2c66affSColin Finck   /* validate parameters */
1329c2c66affSColin Finck 
1330c2c66affSColin Finck   if (!IsEqualIID(riid, &IID_NULL))
1331c2c66affSColin Finck   {
1332c2c66affSColin Finck     ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
1333c2c66affSColin Finck     return DISP_E_UNKNOWNINTERFACE;
1334c2c66affSColin Finck   }
1335c2c66affSColin Finck 
1336c2c66affSColin Finck   if (wFlags & DISPATCH_PROPERTYGET)
1337c2c66affSColin Finck   {
1338c2c66affSColin Finck     if (!pVarResult)
1339c2c66affSColin Finck     {
1340c2c66affSColin Finck       ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1341c2c66affSColin Finck       return DISP_E_PARAMNOTOPTIONAL;
1342c2c66affSColin Finck     }
1343c2c66affSColin Finck   }
1344c2c66affSColin Finck   else if (wFlags & DISPATCH_PROPERTYPUT)
1345c2c66affSColin Finck   {
1346c2c66affSColin Finck     if (!pDispParams)
1347c2c66affSColin Finck     {
1348c2c66affSColin Finck       ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n");
1349c2c66affSColin Finck       return DISP_E_PARAMNOTOPTIONAL;
1350c2c66affSColin Finck     }
1351c2c66affSColin Finck     if (pDispParams->cArgs != 1)
1352c2c66affSColin Finck     {
1353c2c66affSColin Finck       ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs);
1354c2c66affSColin Finck       return DISP_E_BADPARAMCOUNT;
1355c2c66affSColin Finck     }
1356c2c66affSColin Finck   }
1357c2c66affSColin Finck   else
1358c2c66affSColin Finck   {
1359c2c66affSColin Finck     ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n");
1360c2c66affSColin Finck     return DISP_E_MEMBERNOTFOUND;
1361c2c66affSColin Finck   }
1362c2c66affSColin Finck 
1363c2c66affSColin Finck   switch (dispIdMember) {
1364c2c66affSColin Finck   case DISPID_FONT_NAME:
1365c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1366c2c66affSColin Finck       V_VT(pVarResult) = VT_BSTR;
1367c2c66affSColin Finck       return IFont_get_Name(&this->IFont_iface, &V_BSTR(pVarResult));
1368c2c66affSColin Finck     } else {
1369c2c66affSColin Finck       VARIANTARG vararg;
1370c2c66affSColin Finck 
1371c2c66affSColin Finck       VariantInit(&vararg);
1372c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BSTR);
1373c2c66affSColin Finck       if (FAILED(hr))
1374c2c66affSColin Finck         return hr;
1375c2c66affSColin Finck 
1376c2c66affSColin Finck       hr = IFont_put_Name(&this->IFont_iface, V_BSTR(&vararg));
1377c2c66affSColin Finck 
1378c2c66affSColin Finck       VariantClear(&vararg);
1379c2c66affSColin Finck       return hr;
1380c2c66affSColin Finck     }
1381c2c66affSColin Finck     break;
1382c2c66affSColin Finck   case DISPID_FONT_BOLD:
1383c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1384c2c66affSColin Finck       BOOL value;
1385c2c66affSColin Finck       hr = IFont_get_Bold(&this->IFont_iface, &value);
1386c2c66affSColin Finck       V_VT(pVarResult) = VT_BOOL;
1387c2c66affSColin Finck       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1388c2c66affSColin Finck       return hr;
1389c2c66affSColin Finck     } else {
1390c2c66affSColin Finck       VARIANTARG vararg;
1391c2c66affSColin Finck 
1392c2c66affSColin Finck       VariantInit(&vararg);
1393c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1394c2c66affSColin Finck       if (FAILED(hr))
1395c2c66affSColin Finck         return hr;
1396c2c66affSColin Finck 
1397c2c66affSColin Finck       hr = IFont_put_Bold(&this->IFont_iface, V_BOOL(&vararg));
1398c2c66affSColin Finck 
1399c2c66affSColin Finck       VariantClear(&vararg);
1400c2c66affSColin Finck       return hr;
1401c2c66affSColin Finck     }
1402c2c66affSColin Finck     break;
1403c2c66affSColin Finck   case DISPID_FONT_ITALIC:
1404c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1405c2c66affSColin Finck       BOOL value;
1406c2c66affSColin Finck       hr = IFont_get_Italic(&this->IFont_iface, &value);
1407c2c66affSColin Finck       V_VT(pVarResult) = VT_BOOL;
1408c2c66affSColin Finck       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1409c2c66affSColin Finck       return hr;
1410c2c66affSColin Finck     } else {
1411c2c66affSColin Finck       VARIANTARG vararg;
1412c2c66affSColin Finck 
1413c2c66affSColin Finck       VariantInit(&vararg);
1414c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1415c2c66affSColin Finck       if (FAILED(hr))
1416c2c66affSColin Finck         return hr;
1417c2c66affSColin Finck 
1418c2c66affSColin Finck       hr = IFont_put_Italic(&this->IFont_iface, V_BOOL(&vararg));
1419c2c66affSColin Finck 
1420c2c66affSColin Finck       VariantClear(&vararg);
1421c2c66affSColin Finck       return hr;
1422c2c66affSColin Finck     }
1423c2c66affSColin Finck     break;
1424c2c66affSColin Finck   case DISPID_FONT_UNDER:
1425c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1426c2c66affSColin Finck       BOOL value;
1427c2c66affSColin Finck       hr = IFont_get_Underline(&this->IFont_iface, &value);
1428c2c66affSColin Finck       V_VT(pVarResult) = VT_BOOL;
1429c2c66affSColin Finck       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1430c2c66affSColin Finck       return hr;
1431c2c66affSColin Finck     } else {
1432c2c66affSColin Finck       VARIANTARG vararg;
1433c2c66affSColin Finck 
1434c2c66affSColin Finck       VariantInit(&vararg);
1435c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1436c2c66affSColin Finck       if (FAILED(hr))
1437c2c66affSColin Finck         return hr;
1438c2c66affSColin Finck 
1439c2c66affSColin Finck       hr = IFont_put_Underline(&this->IFont_iface, V_BOOL(&vararg));
1440c2c66affSColin Finck 
1441c2c66affSColin Finck       VariantClear(&vararg);
1442c2c66affSColin Finck       return hr;
1443c2c66affSColin Finck     }
1444c2c66affSColin Finck     break;
1445c2c66affSColin Finck   case DISPID_FONT_STRIKE:
1446c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1447c2c66affSColin Finck       BOOL value;
1448c2c66affSColin Finck       hr = IFont_get_Strikethrough(&this->IFont_iface, &value);
1449c2c66affSColin Finck       V_VT(pVarResult) = VT_BOOL;
1450c2c66affSColin Finck       V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1451c2c66affSColin Finck       return hr;
1452c2c66affSColin Finck     } else {
1453c2c66affSColin Finck       VARIANTARG vararg;
1454c2c66affSColin Finck 
1455c2c66affSColin Finck       VariantInit(&vararg);
1456c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1457c2c66affSColin Finck       if (FAILED(hr))
1458c2c66affSColin Finck         return hr;
1459c2c66affSColin Finck 
1460c2c66affSColin Finck       hr = IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&vararg));
1461c2c66affSColin Finck 
1462c2c66affSColin Finck       VariantClear(&vararg);
1463c2c66affSColin Finck       return hr;
1464c2c66affSColin Finck     }
1465c2c66affSColin Finck     break;
1466c2c66affSColin Finck   case DISPID_FONT_SIZE:
1467c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1468c2c66affSColin Finck       V_VT(pVarResult) = VT_CY;
1469c2c66affSColin Finck       return IFont_get_Size(&this->IFont_iface, &V_CY(pVarResult));
1470c2c66affSColin Finck     } else {
1471c2c66affSColin Finck       VARIANTARG vararg;
1472c2c66affSColin Finck 
1473c2c66affSColin Finck       VariantInit(&vararg);
1474c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_CY);
1475c2c66affSColin Finck       if (FAILED(hr))
1476c2c66affSColin Finck         return hr;
1477c2c66affSColin Finck 
1478c2c66affSColin Finck       hr = IFont_put_Size(&this->IFont_iface, V_CY(&vararg));
1479c2c66affSColin Finck 
1480c2c66affSColin Finck       VariantClear(&vararg);
1481c2c66affSColin Finck       return hr;
1482c2c66affSColin Finck     }
1483c2c66affSColin Finck     break;
1484c2c66affSColin Finck   case DISPID_FONT_WEIGHT:
1485c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1486c2c66affSColin Finck       V_VT(pVarResult) = VT_I2;
1487c2c66affSColin Finck       return IFont_get_Weight(&this->IFont_iface, &V_I2(pVarResult));
1488c2c66affSColin Finck     } else {
1489c2c66affSColin Finck       VARIANTARG vararg;
1490c2c66affSColin Finck 
1491c2c66affSColin Finck       VariantInit(&vararg);
1492c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1493c2c66affSColin Finck       if (FAILED(hr))
1494c2c66affSColin Finck         return hr;
1495c2c66affSColin Finck 
1496c2c66affSColin Finck       hr = IFont_put_Weight(&this->IFont_iface, V_I2(&vararg));
1497c2c66affSColin Finck 
1498c2c66affSColin Finck       VariantClear(&vararg);
1499c2c66affSColin Finck       return hr;
1500c2c66affSColin Finck     }
1501c2c66affSColin Finck     break;
1502c2c66affSColin Finck   case DISPID_FONT_CHARSET:
1503c2c66affSColin Finck     if (wFlags & DISPATCH_PROPERTYGET) {
1504c2c66affSColin Finck       V_VT(pVarResult) = VT_I2;
1505c2c66affSColin Finck       return OLEFontImpl_get_Charset(&this->IFont_iface, &V_I2(pVarResult));
1506c2c66affSColin Finck     } else {
1507c2c66affSColin Finck       VARIANTARG vararg;
1508c2c66affSColin Finck 
1509c2c66affSColin Finck       VariantInit(&vararg);
1510c2c66affSColin Finck       hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1511c2c66affSColin Finck       if (FAILED(hr))
1512c2c66affSColin Finck         return hr;
1513c2c66affSColin Finck 
1514c2c66affSColin Finck       hr = IFont_put_Charset(&this->IFont_iface, V_I2(&vararg));
1515c2c66affSColin Finck 
1516c2c66affSColin Finck       VariantClear(&vararg);
1517c2c66affSColin Finck       return hr;
1518c2c66affSColin Finck     }
1519c2c66affSColin Finck     break;
1520c2c66affSColin Finck   default:
1521c2c66affSColin Finck     ERR("member not found for dispid 0x%x\n", dispIdMember);
1522c2c66affSColin Finck     return DISP_E_MEMBERNOTFOUND;
1523c2c66affSColin Finck   }
1524c2c66affSColin Finck }
1525c2c66affSColin Finck 
1526c2c66affSColin Finck static const IDispatchVtbl OLEFontImpl_IDispatch_VTable =
1527c2c66affSColin Finck {
1528c2c66affSColin Finck   OLEFontImpl_IDispatch_QueryInterface,
1529c2c66affSColin Finck   OLEFontImpl_IDispatch_AddRef,
1530c2c66affSColin Finck   OLEFontImpl_IDispatch_Release,
1531c2c66affSColin Finck   OLEFontImpl_GetTypeInfoCount,
1532c2c66affSColin Finck   OLEFontImpl_GetTypeInfo,
1533c2c66affSColin Finck   OLEFontImpl_GetIDsOfNames,
1534c2c66affSColin Finck   OLEFontImpl_Invoke
1535c2c66affSColin Finck };
1536c2c66affSColin Finck 
1537c2c66affSColin Finck /************************************************************************
1538c2c66affSColin Finck  * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1539c2c66affSColin Finck  */
OLEFontImpl_IPersistStream_QueryInterface(IPersistStream * iface,REFIID riid,VOID ** ppvoid)1540c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1541c2c66affSColin Finck   IPersistStream* iface,
1542c2c66affSColin Finck   REFIID     riid,
1543c2c66affSColin Finck   VOID**     ppvoid)
1544c2c66affSColin Finck {
1545c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStream(iface);
1546c2c66affSColin Finck 
1547c2c66affSColin Finck   return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
1548c2c66affSColin Finck }
1549c2c66affSColin Finck 
1550c2c66affSColin Finck /************************************************************************
1551c2c66affSColin Finck  * OLEFontImpl_IPersistStream_Release (IUnknown)
1552c2c66affSColin Finck  */
OLEFontImpl_IPersistStream_Release(IPersistStream * iface)1553c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1554c2c66affSColin Finck   IPersistStream* iface)
1555c2c66affSColin Finck {
1556c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStream(iface);
1557c2c66affSColin Finck 
1558c2c66affSColin Finck   return IFont_Release(&this->IFont_iface);
1559c2c66affSColin Finck }
1560c2c66affSColin Finck 
1561c2c66affSColin Finck /************************************************************************
1562c2c66affSColin Finck  * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1563c2c66affSColin Finck  */
OLEFontImpl_IPersistStream_AddRef(IPersistStream * iface)1564c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1565c2c66affSColin Finck   IPersistStream* iface)
1566c2c66affSColin Finck {
1567c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStream(iface);
1568c2c66affSColin Finck 
1569c2c66affSColin Finck   return IFont_AddRef(&this->IFont_iface);
1570c2c66affSColin Finck }
1571c2c66affSColin Finck 
1572c2c66affSColin Finck /************************************************************************
1573c2c66affSColin Finck  * OLEFontImpl_GetClassID (IPersistStream)
1574c2c66affSColin Finck  */
OLEFontImpl_GetClassID(IPersistStream * iface,CLSID * pClassID)1575c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_GetClassID(
1576c2c66affSColin Finck   IPersistStream* iface,
1577c2c66affSColin Finck   CLSID*                pClassID)
1578c2c66affSColin Finck {
1579c2c66affSColin Finck   TRACE("(%p,%p)\n",iface,pClassID);
1580c2c66affSColin Finck   if (pClassID==0)
1581c2c66affSColin Finck     return E_POINTER;
1582c2c66affSColin Finck 
1583c2c66affSColin Finck   *pClassID = CLSID_StdFont;
1584c2c66affSColin Finck 
1585c2c66affSColin Finck   return S_OK;
1586c2c66affSColin Finck }
1587c2c66affSColin Finck 
1588c2c66affSColin Finck /************************************************************************
1589c2c66affSColin Finck  * OLEFontImpl_IsDirty (IPersistStream)
1590c2c66affSColin Finck  *
1591c2c66affSColin Finck  * See Windows documentation for more details on IPersistStream methods.
1592c2c66affSColin Finck  */
OLEFontImpl_IsDirty(IPersistStream * iface)1593c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IsDirty(
1594c2c66affSColin Finck   IPersistStream*  iface)
1595c2c66affSColin Finck {
1596c2c66affSColin Finck   TRACE("(%p)\n",iface);
1597c2c66affSColin Finck   return S_OK;
1598c2c66affSColin Finck }
1599c2c66affSColin Finck 
1600c2c66affSColin Finck /************************************************************************
1601c2c66affSColin Finck  * OLEFontImpl_Load (IPersistStream)
1602c2c66affSColin Finck  *
1603c2c66affSColin Finck  * See Windows documentation for more details on IPersistStream methods.
1604c2c66affSColin Finck  *
1605c2c66affSColin Finck  * This is the format of the standard font serialization as far as I
1606c2c66affSColin Finck  * know
1607c2c66affSColin Finck  *
1608c2c66affSColin Finck  * Offset   Type   Value           Comment
1609c2c66affSColin Finck  * 0x0000   Byte   Unknown         Probably a version number, contains 0x01
1610c2c66affSColin Finck  * 0x0001   Short  Charset         Charset value from the FONTDESC structure
1611c2c66affSColin Finck  * 0x0003   Byte   Attributes      Flags defined as follows:
1612c2c66affSColin Finck  *                                     00000010 - Italic
1613c2c66affSColin Finck  *                                     00000100 - Underline
1614c2c66affSColin Finck  *                                     00001000 - Strikethrough
1615c2c66affSColin Finck  * 0x0004   Short  Weight          Weight value from FONTDESC structure
1616c2c66affSColin Finck  * 0x0006   DWORD  size            "Low" portion of the cySize member of the FONTDESC
1617c2c66affSColin Finck  *                                 structure/
1618c2c66affSColin Finck  * 0x000A   Byte   name length     Length of the font name string (no null character)
1619c2c66affSColin Finck  * 0x000B   String name            Name of the font (ASCII, no nul character)
1620c2c66affSColin Finck  */
OLEFontImpl_Load(IPersistStream * iface,IStream * pLoadStream)1621c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_Load(
1622c2c66affSColin Finck   IPersistStream*  iface,
1623c2c66affSColin Finck   IStream*         pLoadStream)
1624c2c66affSColin Finck {
1625c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStream(iface);
1626c2c66affSColin Finck   BYTE  version, attributes, string_size;
1627c2c66affSColin Finck   char readBuffer[0x100];
1628c2c66affSColin Finck   ULONG cbRead;
1629c2c66affSColin Finck   INT len;
1630c2c66affSColin Finck 
1631c2c66affSColin Finck   /* Version */
1632c2c66affSColin Finck   IStream_Read(pLoadStream, &version, sizeof(BYTE), &cbRead);
1633c2c66affSColin Finck   if ((cbRead != sizeof(BYTE)) || (version != 0x01)) return E_FAIL;
1634c2c66affSColin Finck 
1635c2c66affSColin Finck   /* Charset */
1636c2c66affSColin Finck   IStream_Read(pLoadStream, &this->description.sCharset, sizeof(WORD), &cbRead);
1637c2c66affSColin Finck   if (cbRead != sizeof(WORD)) return E_FAIL;
1638c2c66affSColin Finck 
1639c2c66affSColin Finck   /* Attributes */
1640c2c66affSColin Finck   IStream_Read(pLoadStream, &attributes, sizeof(BYTE), &cbRead);
1641c2c66affSColin Finck   if (cbRead != sizeof(BYTE)) return E_FAIL;
1642c2c66affSColin Finck 
1643c2c66affSColin Finck   this->description.fItalic        = (attributes & FONTPERSIST_ITALIC) != 0;
1644c2c66affSColin Finck   this->description.fStrikethrough = (attributes & FONTPERSIST_STRIKETHROUGH) != 0;
1645c2c66affSColin Finck   this->description.fUnderline     = (attributes & FONTPERSIST_UNDERLINE) != 0;
1646c2c66affSColin Finck 
1647c2c66affSColin Finck   /* Weight */
1648c2c66affSColin Finck   IStream_Read(pLoadStream, &this->description.sWeight, sizeof(WORD), &cbRead);
1649c2c66affSColin Finck   if (cbRead != sizeof(WORD)) return E_FAIL;
1650c2c66affSColin Finck 
1651c2c66affSColin Finck   /* Size */
1652c2c66affSColin Finck   IStream_Read(pLoadStream, &this->description.cySize.s.Lo, sizeof(DWORD), &cbRead);
1653c2c66affSColin Finck   if (cbRead != sizeof(DWORD)) return E_FAIL;
1654c2c66affSColin Finck 
1655c2c66affSColin Finck   this->description.cySize.s.Hi = 0;
1656c2c66affSColin Finck 
1657c2c66affSColin Finck   /* Name */
1658c2c66affSColin Finck   IStream_Read(pLoadStream, &string_size, sizeof(BYTE), &cbRead);
1659c2c66affSColin Finck   if (cbRead != sizeof(BYTE)) return E_FAIL;
1660c2c66affSColin Finck 
1661c2c66affSColin Finck   IStream_Read(pLoadStream, readBuffer, string_size, &cbRead);
1662c2c66affSColin Finck   if (cbRead != string_size) return E_FAIL;
1663c2c66affSColin Finck 
1664c2c66affSColin Finck   HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1665c2c66affSColin Finck 
1666c2c66affSColin Finck   len = MultiByteToWideChar( CP_ACP, 0, readBuffer, string_size, NULL, 0 );
1667c2c66affSColin Finck   this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1668c2c66affSColin Finck   MultiByteToWideChar( CP_ACP, 0, readBuffer, string_size, this->description.lpstrName, len );
1669c2c66affSColin Finck   this->description.lpstrName[len] = 0;
1670c2c66affSColin Finck 
1671c2c66affSColin Finck   /* Ensure use of this font causes a new one to be created */
1672c2c66affSColin Finck   dec_int_ref(this->gdiFont);
1673c2c66affSColin Finck   this->gdiFont = 0;
1674c2c66affSColin Finck   this->dirty = TRUE;
1675c2c66affSColin Finck 
1676c2c66affSColin Finck   return S_OK;
1677c2c66affSColin Finck }
1678c2c66affSColin Finck 
1679c2c66affSColin Finck /************************************************************************
1680c2c66affSColin Finck  * OLEFontImpl_Save (IPersistStream)
1681c2c66affSColin Finck  */
OLEFontImpl_Save(IPersistStream * iface,IStream * pOutStream,BOOL fClearDirty)1682c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_Save(
1683c2c66affSColin Finck   IPersistStream*  iface,
1684c2c66affSColin Finck   IStream*         pOutStream,
1685c2c66affSColin Finck   BOOL             fClearDirty)
1686c2c66affSColin Finck {
1687c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStream(iface);
1688c2c66affSColin Finck   BYTE  attributes, string_size;
1689c2c66affSColin Finck   const BYTE version = 0x01;
1690c2c66affSColin Finck   char* writeBuffer = NULL;
1691c2c66affSColin Finck   ULONG written;
1692c2c66affSColin Finck 
1693c2c66affSColin Finck   TRACE("(%p)->(%p %d)\n", this, pOutStream, fClearDirty);
1694c2c66affSColin Finck 
1695c2c66affSColin Finck   /* Version */
1696c2c66affSColin Finck   IStream_Write(pOutStream, &version, sizeof(BYTE), &written);
1697c2c66affSColin Finck   if (written != sizeof(BYTE)) return E_FAIL;
1698c2c66affSColin Finck 
1699c2c66affSColin Finck   /* Charset */
1700c2c66affSColin Finck   IStream_Write(pOutStream, &this->description.sCharset, sizeof(WORD), &written);
1701c2c66affSColin Finck   if (written != sizeof(WORD)) return E_FAIL;
1702c2c66affSColin Finck 
1703c2c66affSColin Finck   /* Attributes */
1704c2c66affSColin Finck   attributes = 0;
1705c2c66affSColin Finck 
1706c2c66affSColin Finck   if (this->description.fItalic)
1707c2c66affSColin Finck     attributes |= FONTPERSIST_ITALIC;
1708c2c66affSColin Finck 
1709c2c66affSColin Finck   if (this->description.fStrikethrough)
1710c2c66affSColin Finck     attributes |= FONTPERSIST_STRIKETHROUGH;
1711c2c66affSColin Finck 
1712c2c66affSColin Finck   if (this->description.fUnderline)
1713c2c66affSColin Finck     attributes |= FONTPERSIST_UNDERLINE;
1714c2c66affSColin Finck 
1715c2c66affSColin Finck   IStream_Write(pOutStream, &attributes, sizeof(BYTE), &written);
1716c2c66affSColin Finck   if (written != sizeof(BYTE)) return E_FAIL;
1717c2c66affSColin Finck 
1718c2c66affSColin Finck   /* Weight */
1719c2c66affSColin Finck   IStream_Write(pOutStream, &this->description.sWeight, sizeof(WORD), &written);
1720c2c66affSColin Finck   if (written != sizeof(WORD)) return E_FAIL;
1721c2c66affSColin Finck 
1722c2c66affSColin Finck   /* Size */
1723c2c66affSColin Finck   IStream_Write(pOutStream, &this->description.cySize.s.Lo, sizeof(DWORD), &written);
1724c2c66affSColin Finck   if (written != sizeof(DWORD)) return E_FAIL;
1725c2c66affSColin Finck 
1726c2c66affSColin Finck   /* FontName */
1727c2c66affSColin Finck   if (this->description.lpstrName)
1728c2c66affSColin Finck     string_size = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1729*ae24453eSAmine Khaldi                                        lstrlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1730c2c66affSColin Finck   else
1731c2c66affSColin Finck     string_size = 0;
1732c2c66affSColin Finck 
1733c2c66affSColin Finck   IStream_Write(pOutStream, &string_size, sizeof(BYTE), &written);
1734c2c66affSColin Finck   if (written != sizeof(BYTE)) return E_FAIL;
1735c2c66affSColin Finck 
1736c2c66affSColin Finck   if (string_size)
1737c2c66affSColin Finck   {
1738c2c66affSColin Finck       if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, string_size ))) return E_OUTOFMEMORY;
1739c2c66affSColin Finck       WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1740*ae24453eSAmine Khaldi                            lstrlenW(this->description.lpstrName),
1741c2c66affSColin Finck                            writeBuffer, string_size, NULL, NULL );
1742c2c66affSColin Finck 
1743c2c66affSColin Finck       IStream_Write(pOutStream, writeBuffer, string_size, &written);
1744c2c66affSColin Finck       HeapFree(GetProcessHeap(), 0, writeBuffer);
1745c2c66affSColin Finck 
1746c2c66affSColin Finck       if (written != string_size) return E_FAIL;
1747c2c66affSColin Finck   }
1748c2c66affSColin Finck 
1749c2c66affSColin Finck   return S_OK;
1750c2c66affSColin Finck }
1751c2c66affSColin Finck 
1752c2c66affSColin Finck /************************************************************************
1753c2c66affSColin Finck  * OLEFontImpl_GetSizeMax (IPersistStream)
1754c2c66affSColin Finck  */
OLEFontImpl_GetSizeMax(IPersistStream * iface,ULARGE_INTEGER * pcbSize)1755c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1756c2c66affSColin Finck   IPersistStream*  iface,
1757c2c66affSColin Finck   ULARGE_INTEGER*  pcbSize)
1758c2c66affSColin Finck {
1759c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStream(iface);
1760c2c66affSColin Finck 
1761c2c66affSColin Finck   if (pcbSize==NULL)
1762c2c66affSColin Finck     return E_POINTER;
1763c2c66affSColin Finck 
1764c2c66affSColin Finck   pcbSize->u.HighPart = 0;
1765c2c66affSColin Finck   pcbSize->u.LowPart = 0;
1766c2c66affSColin Finck 
1767c2c66affSColin Finck   pcbSize->u.LowPart += sizeof(BYTE);  /* Version */
1768c2c66affSColin Finck   pcbSize->u.LowPart += sizeof(WORD);  /* Lang code */
1769c2c66affSColin Finck   pcbSize->u.LowPart += sizeof(BYTE);  /* Flags */
1770c2c66affSColin Finck   pcbSize->u.LowPart += sizeof(WORD);  /* Weight */
1771c2c66affSColin Finck   pcbSize->u.LowPart += sizeof(DWORD); /* Size */
1772c2c66affSColin Finck   pcbSize->u.LowPart += sizeof(BYTE);  /* StrLength */
1773c2c66affSColin Finck 
1774c2c66affSColin Finck   if (this->description.lpstrName!=0)
1775c2c66affSColin Finck       pcbSize->u.LowPart += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1776*ae24453eSAmine Khaldi                                                  lstrlenW(this->description.lpstrName),
1777c2c66affSColin Finck                                                  NULL, 0, NULL, NULL );
1778c2c66affSColin Finck 
1779c2c66affSColin Finck   return S_OK;
1780c2c66affSColin Finck }
1781c2c66affSColin Finck 
1782c2c66affSColin Finck static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =
1783c2c66affSColin Finck {
1784c2c66affSColin Finck   OLEFontImpl_IPersistStream_QueryInterface,
1785c2c66affSColin Finck   OLEFontImpl_IPersistStream_AddRef,
1786c2c66affSColin Finck   OLEFontImpl_IPersistStream_Release,
1787c2c66affSColin Finck   OLEFontImpl_GetClassID,
1788c2c66affSColin Finck   OLEFontImpl_IsDirty,
1789c2c66affSColin Finck   OLEFontImpl_Load,
1790c2c66affSColin Finck   OLEFontImpl_Save,
1791c2c66affSColin Finck   OLEFontImpl_GetSizeMax
1792c2c66affSColin Finck };
1793c2c66affSColin Finck 
1794c2c66affSColin Finck /************************************************************************
1795c2c66affSColin Finck  * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1796c2c66affSColin Finck  */
OLEFontImpl_IConnectionPointContainer_QueryInterface(IConnectionPointContainer * iface,REFIID riid,VOID ** ppvoid)1797c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1798c2c66affSColin Finck   IConnectionPointContainer* iface,
1799c2c66affSColin Finck   REFIID     riid,
1800c2c66affSColin Finck   VOID**     ppvoid)
1801c2c66affSColin Finck {
1802c2c66affSColin Finck   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1803c2c66affSColin Finck 
1804c2c66affSColin Finck   return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
1805c2c66affSColin Finck }
1806c2c66affSColin Finck 
1807c2c66affSColin Finck /************************************************************************
1808c2c66affSColin Finck  * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1809c2c66affSColin Finck  */
OLEFontImpl_IConnectionPointContainer_Release(IConnectionPointContainer * iface)1810c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1811c2c66affSColin Finck   IConnectionPointContainer* iface)
1812c2c66affSColin Finck {
1813c2c66affSColin Finck   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1814c2c66affSColin Finck 
1815c2c66affSColin Finck   return IFont_Release(&this->IFont_iface);
1816c2c66affSColin Finck }
1817c2c66affSColin Finck 
1818c2c66affSColin Finck /************************************************************************
1819c2c66affSColin Finck  * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1820c2c66affSColin Finck  */
OLEFontImpl_IConnectionPointContainer_AddRef(IConnectionPointContainer * iface)1821c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1822c2c66affSColin Finck   IConnectionPointContainer* iface)
1823c2c66affSColin Finck {
1824c2c66affSColin Finck   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1825c2c66affSColin Finck 
1826c2c66affSColin Finck   return IFont_AddRef(&this->IFont_iface);
1827c2c66affSColin Finck }
1828c2c66affSColin Finck 
1829c2c66affSColin Finck /************************************************************************
1830c2c66affSColin Finck  * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1831c2c66affSColin Finck  */
OLEFontImpl_EnumConnectionPoints(IConnectionPointContainer * iface,IEnumConnectionPoints ** ppEnum)1832c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1833c2c66affSColin Finck   IConnectionPointContainer* iface,
1834c2c66affSColin Finck   IEnumConnectionPoints **ppEnum)
1835c2c66affSColin Finck {
1836c2c66affSColin Finck   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1837c2c66affSColin Finck 
1838c2c66affSColin Finck   FIXME("(%p)->(%p): stub\n", this, ppEnum);
1839c2c66affSColin Finck   return E_NOTIMPL;
1840c2c66affSColin Finck }
1841c2c66affSColin Finck 
1842c2c66affSColin Finck /************************************************************************
1843c2c66affSColin Finck  * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1844c2c66affSColin Finck  */
OLEFontImpl_FindConnectionPoint(IConnectionPointContainer * iface,REFIID riid,IConnectionPoint ** ppCp)1845c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1846c2c66affSColin Finck    IConnectionPointContainer* iface,
1847c2c66affSColin Finck    REFIID riid,
1848c2c66affSColin Finck    IConnectionPoint **ppCp)
1849c2c66affSColin Finck {
1850c2c66affSColin Finck   OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1851c2c66affSColin Finck   TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp);
1852c2c66affSColin Finck 
1853c2c66affSColin Finck   if(IsEqualIID(riid, &IID_IPropertyNotifySink)) {
1854c2c66affSColin Finck     return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP, &IID_IConnectionPoint,
1855c2c66affSColin Finck                                            (void**)ppCp);
1856c2c66affSColin Finck   } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) {
1857c2c66affSColin Finck     return IConnectionPoint_QueryInterface(this->pFontEventsCP, &IID_IConnectionPoint,
1858c2c66affSColin Finck                                            (void**)ppCp);
1859c2c66affSColin Finck   } else {
1860c2c66affSColin Finck     FIXME("no connection point for %s\n", debugstr_guid(riid));
1861c2c66affSColin Finck     return CONNECT_E_NOCONNECTION;
1862c2c66affSColin Finck   }
1863c2c66affSColin Finck }
1864c2c66affSColin Finck 
1865c2c66affSColin Finck static const IConnectionPointContainerVtbl
1866c2c66affSColin Finck      OLEFontImpl_IConnectionPointContainer_VTable =
1867c2c66affSColin Finck {
1868c2c66affSColin Finck   OLEFontImpl_IConnectionPointContainer_QueryInterface,
1869c2c66affSColin Finck   OLEFontImpl_IConnectionPointContainer_AddRef,
1870c2c66affSColin Finck   OLEFontImpl_IConnectionPointContainer_Release,
1871c2c66affSColin Finck   OLEFontImpl_EnumConnectionPoints,
1872c2c66affSColin Finck   OLEFontImpl_FindConnectionPoint
1873c2c66affSColin Finck };
1874c2c66affSColin Finck 
1875c2c66affSColin Finck /************************************************************************
1876c2c66affSColin Finck  * OLEFontImpl implementation of IPersistPropertyBag.
1877c2c66affSColin Finck  */
OLEFontImpl_IPersistPropertyBag_QueryInterface(IPersistPropertyBag * iface,REFIID riid,LPVOID * ppvObj)1878c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
1879c2c66affSColin Finck    IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
1880c2c66affSColin Finck ) {
1881c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1882c2c66affSColin Finck   return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj);
1883c2c66affSColin Finck }
1884c2c66affSColin Finck 
OLEFontImpl_IPersistPropertyBag_AddRef(IPersistPropertyBag * iface)1885c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
1886c2c66affSColin Finck    IPersistPropertyBag *iface
1887c2c66affSColin Finck ) {
1888c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1889c2c66affSColin Finck   return IFont_AddRef(&this->IFont_iface);
1890c2c66affSColin Finck }
1891c2c66affSColin Finck 
OLEFontImpl_IPersistPropertyBag_Release(IPersistPropertyBag * iface)1892c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
1893c2c66affSColin Finck    IPersistPropertyBag *iface
1894c2c66affSColin Finck ) {
1895c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1896c2c66affSColin Finck   return IFont_Release(&this->IFont_iface);
1897c2c66affSColin Finck }
1898c2c66affSColin Finck 
OLEFontImpl_IPersistPropertyBag_GetClassID(IPersistPropertyBag * iface,CLSID * classid)1899c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
1900c2c66affSColin Finck    IPersistPropertyBag *iface, CLSID *classid
1901c2c66affSColin Finck ) {
1902c2c66affSColin Finck   FIXME("(%p,%p), stub!\n", iface, classid);
1903c2c66affSColin Finck   return E_FAIL;
1904c2c66affSColin Finck }
1905c2c66affSColin Finck 
OLEFontImpl_IPersistPropertyBag_InitNew(IPersistPropertyBag * iface)1906c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
1907c2c66affSColin Finck    IPersistPropertyBag *iface
1908c2c66affSColin Finck ) {
1909c2c66affSColin Finck   FIXME("(%p), stub!\n", iface);
1910c2c66affSColin Finck   return S_OK;
1911c2c66affSColin Finck }
1912c2c66affSColin Finck 
OLEFontImpl_IPersistPropertyBag_Load(IPersistPropertyBag * iface,IPropertyBag * pPropBag,IErrorLog * pErrorLog)1913c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
1914c2c66affSColin Finck    IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
1915c2c66affSColin Finck ) {
1916c2c66affSColin Finck /* (from Visual Basic 6 property bag)
1917c2c66affSColin Finck          Name            =   "MS Sans Serif"
1918c2c66affSColin Finck          Size            =   13.8
1919c2c66affSColin Finck          Charset         =   0
1920c2c66affSColin Finck          Weight          =   400
1921c2c66affSColin Finck          Underline       =   0   'False
1922c2c66affSColin Finck          Italic          =   0   'False
1923c2c66affSColin Finck          Strikethrough   =   0   'False
1924c2c66affSColin Finck */
1925c2c66affSColin Finck     static const WCHAR sAttrName[] = {'N','a','m','e',0};
1926c2c66affSColin Finck     static const WCHAR sAttrSize[] = {'S','i','z','e',0};
1927c2c66affSColin Finck     static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0};
1928c2c66affSColin Finck     static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0};
1929c2c66affSColin Finck     static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};
1930c2c66affSColin Finck     static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};
1931c2c66affSColin Finck     static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
1932c2c66affSColin Finck     OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1933c2c66affSColin Finck     VARIANT value;
1934c2c66affSColin Finck     HRESULT iRes;
1935c2c66affSColin Finck 
1936c2c66affSColin Finck     VariantInit(&value);
1937c2c66affSColin Finck 
1938c2c66affSColin Finck     iRes = IPropertyBag_Read(pPropBag, sAttrName, &value, pErrorLog);
1939c2c66affSColin Finck     if (iRes == S_OK)
1940c2c66affSColin Finck     {
1941c2c66affSColin Finck         iRes = VariantChangeType(&value, &value, 0, VT_BSTR);
1942c2c66affSColin Finck         if (iRes == S_OK)
1943c2c66affSColin Finck             iRes = IFont_put_Name(&this->IFont_iface, V_BSTR(&value));
1944c2c66affSColin Finck     }
1945c2c66affSColin Finck     else if (iRes == E_INVALIDARG)
1946c2c66affSColin Finck         iRes = S_OK;
1947c2c66affSColin Finck 
1948c2c66affSColin Finck     VariantClear(&value);
1949c2c66affSColin Finck 
1950c2c66affSColin Finck     if (iRes == S_OK) {
1951c2c66affSColin Finck         iRes = IPropertyBag_Read(pPropBag, sAttrSize, &value, pErrorLog);
1952c2c66affSColin Finck         if (iRes == S_OK)
1953c2c66affSColin Finck         {
1954c2c66affSColin Finck             iRes = VariantChangeType(&value, &value, 0, VT_CY);
1955c2c66affSColin Finck             if (iRes == S_OK)
1956c2c66affSColin Finck                 iRes = IFont_put_Size(&this->IFont_iface, V_CY(&value));
1957c2c66affSColin Finck         }
1958c2c66affSColin Finck         else if (iRes == E_INVALIDARG)
1959c2c66affSColin Finck             iRes = S_OK;
1960c2c66affSColin Finck 
1961c2c66affSColin Finck         VariantClear(&value);
1962c2c66affSColin Finck     }
1963c2c66affSColin Finck 
1964c2c66affSColin Finck     if (iRes == S_OK) {
1965c2c66affSColin Finck         iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &value, pErrorLog);
1966c2c66affSColin Finck         if (iRes == S_OK)
1967c2c66affSColin Finck         {
1968c2c66affSColin Finck             iRes = VariantChangeType(&value, &value, 0, VT_I2);
1969c2c66affSColin Finck             if (iRes == S_OK)
1970c2c66affSColin Finck                 iRes = IFont_put_Charset(&this->IFont_iface, V_I2(&value));
1971c2c66affSColin Finck         }
1972c2c66affSColin Finck         else if (iRes == E_INVALIDARG)
1973c2c66affSColin Finck             iRes = S_OK;
1974c2c66affSColin Finck 
1975c2c66affSColin Finck         VariantClear(&value);
1976c2c66affSColin Finck     }
1977c2c66affSColin Finck 
1978c2c66affSColin Finck     if (iRes == S_OK) {
1979c2c66affSColin Finck         iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &value, pErrorLog);
1980c2c66affSColin Finck         if (iRes == S_OK)
1981c2c66affSColin Finck         {
1982c2c66affSColin Finck             iRes = VariantChangeType(&value, &value, 0, VT_I2);
1983c2c66affSColin Finck             if (iRes == S_OK)
1984c2c66affSColin Finck                 iRes = IFont_put_Weight(&this->IFont_iface, V_I2(&value));
1985c2c66affSColin Finck         }
1986c2c66affSColin Finck         else if (iRes == E_INVALIDARG)
1987c2c66affSColin Finck             iRes = S_OK;
1988c2c66affSColin Finck 
1989c2c66affSColin Finck         VariantClear(&value);
1990c2c66affSColin Finck     }
1991c2c66affSColin Finck 
1992c2c66affSColin Finck     if (iRes == S_OK) {
1993c2c66affSColin Finck         iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &value, pErrorLog);
1994c2c66affSColin Finck         if (iRes == S_OK)
1995c2c66affSColin Finck         {
1996c2c66affSColin Finck             iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
1997c2c66affSColin Finck             if (iRes == S_OK)
1998c2c66affSColin Finck                 iRes = IFont_put_Underline(&this->IFont_iface, V_BOOL(&value));
1999c2c66affSColin Finck         }
2000c2c66affSColin Finck         else if (iRes == E_INVALIDARG)
2001c2c66affSColin Finck             iRes = S_OK;
2002c2c66affSColin Finck 
2003c2c66affSColin Finck         VariantClear(&value);
2004c2c66affSColin Finck     }
2005c2c66affSColin Finck 
2006c2c66affSColin Finck     if (iRes == S_OK) {
2007c2c66affSColin Finck         iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &value, pErrorLog);
2008c2c66affSColin Finck         if (iRes == S_OK)
2009c2c66affSColin Finck         {
2010c2c66affSColin Finck             iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
2011c2c66affSColin Finck             if (iRes == S_OK)
2012c2c66affSColin Finck                 iRes = IFont_put_Italic(&this->IFont_iface, V_BOOL(&value));
2013c2c66affSColin Finck         }
2014c2c66affSColin Finck         else if (iRes == E_INVALIDARG)
2015c2c66affSColin Finck             iRes = S_OK;
2016c2c66affSColin Finck 
2017c2c66affSColin Finck         VariantClear(&value);
2018c2c66affSColin Finck     }
2019c2c66affSColin Finck 
2020c2c66affSColin Finck     if (iRes == S_OK) {
2021c2c66affSColin Finck         iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &value, pErrorLog);
2022c2c66affSColin Finck         if (iRes == S_OK)
2023c2c66affSColin Finck         {
2024c2c66affSColin Finck             iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
2025c2c66affSColin Finck             if (iRes == S_OK)
2026c2c66affSColin Finck                 IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&value));
2027c2c66affSColin Finck         }
2028c2c66affSColin Finck         else if (iRes == E_INVALIDARG)
2029c2c66affSColin Finck             iRes = S_OK;
2030c2c66affSColin Finck 
2031c2c66affSColin Finck         VariantClear(&value);
2032c2c66affSColin Finck     }
2033c2c66affSColin Finck 
2034c2c66affSColin Finck     if (FAILED(iRes))
2035c2c66affSColin Finck         WARN("-- 0x%08x\n", iRes);
2036c2c66affSColin Finck     return iRes;
2037c2c66affSColin Finck }
2038c2c66affSColin Finck 
OLEFontImpl_IPersistPropertyBag_Save(IPersistPropertyBag * iface,IPropertyBag * pPropBag,BOOL fClearDirty,BOOL fSaveAllProperties)2039c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
2040c2c66affSColin Finck    IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
2041c2c66affSColin Finck    BOOL fSaveAllProperties
2042c2c66affSColin Finck ) {
2043c2c66affSColin Finck   FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
2044c2c66affSColin Finck   return E_FAIL;
2045c2c66affSColin Finck }
2046c2c66affSColin Finck 
2047c2c66affSColin Finck static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable =
2048c2c66affSColin Finck {
2049c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_QueryInterface,
2050c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_AddRef,
2051c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_Release,
2052c2c66affSColin Finck 
2053c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_GetClassID,
2054c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_InitNew,
2055c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_Load,
2056c2c66affSColin Finck   OLEFontImpl_IPersistPropertyBag_Save
2057c2c66affSColin Finck };
2058c2c66affSColin Finck 
2059c2c66affSColin Finck /************************************************************************
2060c2c66affSColin Finck  * OLEFontImpl implementation of IPersistStreamInit.
2061c2c66affSColin Finck  */
OLEFontImpl_IPersistStreamInit_QueryInterface(IPersistStreamInit * iface,REFIID riid,LPVOID * ppvObj)2062c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
2063c2c66affSColin Finck    IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
2064c2c66affSColin Finck ) {
2065c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2066c2c66affSColin Finck   return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj);
2067c2c66affSColin Finck }
2068c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_AddRef(IPersistStreamInit * iface)2069c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
2070c2c66affSColin Finck    IPersistStreamInit *iface
2071c2c66affSColin Finck ) {
2072c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2073c2c66affSColin Finck   return IFont_AddRef(&this->IFont_iface);
2074c2c66affSColin Finck }
2075c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_Release(IPersistStreamInit * iface)2076c2c66affSColin Finck static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
2077c2c66affSColin Finck    IPersistStreamInit *iface
2078c2c66affSColin Finck ) {
2079c2c66affSColin Finck   OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2080c2c66affSColin Finck   return IFont_Release(&this->IFont_iface);
2081c2c66affSColin Finck }
2082c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_GetClassID(IPersistStreamInit * iface,CLSID * classid)2083c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
2084c2c66affSColin Finck    IPersistStreamInit *iface, CLSID *classid
2085c2c66affSColin Finck ) {
2086c2c66affSColin Finck   FIXME("(%p,%p), stub!\n", iface, classid);
2087c2c66affSColin Finck   return E_FAIL;
2088c2c66affSColin Finck }
2089c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_IsDirty(IPersistStreamInit * iface)2090c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
2091c2c66affSColin Finck    IPersistStreamInit *iface
2092c2c66affSColin Finck ) {
2093c2c66affSColin Finck   FIXME("(%p), stub!\n", iface);
2094c2c66affSColin Finck   return E_FAIL;
2095c2c66affSColin Finck }
2096c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_Load(IPersistStreamInit * iface,LPSTREAM pStm)2097c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
2098c2c66affSColin Finck    IPersistStreamInit *iface, LPSTREAM pStm
2099c2c66affSColin Finck ) {
2100c2c66affSColin Finck   FIXME("(%p,%p), stub!\n", iface, pStm);
2101c2c66affSColin Finck   return E_FAIL;
2102c2c66affSColin Finck }
2103c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_Save(IPersistStreamInit * iface,LPSTREAM pStm,BOOL fClearDirty)2104c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
2105c2c66affSColin Finck    IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
2106c2c66affSColin Finck ) {
2107c2c66affSColin Finck   FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
2108c2c66affSColin Finck   return E_FAIL;
2109c2c66affSColin Finck }
2110c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_GetSizeMax(IPersistStreamInit * iface,ULARGE_INTEGER * pcbSize)2111c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
2112c2c66affSColin Finck    IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
2113c2c66affSColin Finck ) {
2114c2c66affSColin Finck   FIXME("(%p,%p), stub!\n", iface, pcbSize);
2115c2c66affSColin Finck   return E_FAIL;
2116c2c66affSColin Finck }
2117c2c66affSColin Finck 
OLEFontImpl_IPersistStreamInit_InitNew(IPersistStreamInit * iface)2118c2c66affSColin Finck static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
2119c2c66affSColin Finck    IPersistStreamInit *iface
2120c2c66affSColin Finck ) {
2121c2c66affSColin Finck   FIXME("(%p), stub!\n", iface);
2122c2c66affSColin Finck   return S_OK;
2123c2c66affSColin Finck }
2124c2c66affSColin Finck 
2125c2c66affSColin Finck static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable =
2126c2c66affSColin Finck {
2127c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_QueryInterface,
2128c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_AddRef,
2129c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_Release,
2130c2c66affSColin Finck 
2131c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_GetClassID,
2132c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_IsDirty,
2133c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_Load,
2134c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_Save,
2135c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_GetSizeMax,
2136c2c66affSColin Finck   OLEFontImpl_IPersistStreamInit_InitNew
2137c2c66affSColin Finck };
2138c2c66affSColin Finck 
2139c2c66affSColin Finck /************************************************************************
2140c2c66affSColin Finck  * OLEFontImpl_Construct
2141c2c66affSColin Finck  *
2142c2c66affSColin Finck  * This method will construct a new instance of the OLEFontImpl
2143c2c66affSColin Finck  * class.
2144c2c66affSColin Finck  *
2145c2c66affSColin Finck  * The caller of this method must release the object when it's
2146c2c66affSColin Finck  * done with it.
2147c2c66affSColin Finck  */
OLEFontImpl_Construct(const FONTDESC * fontDesc)2148c2c66affSColin Finck static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
2149c2c66affSColin Finck {
2150c2c66affSColin Finck   OLEFontImpl* newObject;
2151c2c66affSColin Finck 
2152c2c66affSColin Finck   newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
2153c2c66affSColin Finck 
2154c2c66affSColin Finck   if (newObject==0)
2155c2c66affSColin Finck     return newObject;
2156c2c66affSColin Finck 
2157c2c66affSColin Finck   newObject->IFont_iface.lpVtbl = &OLEFontImpl_VTable;
2158c2c66affSColin Finck   newObject->IDispatch_iface.lpVtbl = &OLEFontImpl_IDispatch_VTable;
2159c2c66affSColin Finck   newObject->IPersistStream_iface.lpVtbl = &OLEFontImpl_IPersistStream_VTable;
2160c2c66affSColin Finck   newObject->IConnectionPointContainer_iface.lpVtbl = &OLEFontImpl_IConnectionPointContainer_VTable;
2161c2c66affSColin Finck   newObject->IPersistPropertyBag_iface.lpVtbl = &OLEFontImpl_IPersistPropertyBag_VTable;
2162c2c66affSColin Finck   newObject->IPersistStreamInit_iface.lpVtbl = &OLEFontImpl_IPersistStreamInit_VTable;
2163c2c66affSColin Finck 
2164c2c66affSColin Finck   newObject->ref = 1;
2165c2c66affSColin Finck 
2166c2c66affSColin Finck   newObject->description.cbSizeofstruct = sizeof(FONTDESC);
2167c2c66affSColin Finck   newObject->description.lpstrName      = strdupW(fontDesc->lpstrName);
2168c2c66affSColin Finck   newObject->description.cySize         = fontDesc->cySize;
2169c2c66affSColin Finck   newObject->description.sWeight        = fontDesc->sWeight;
2170c2c66affSColin Finck   newObject->description.sCharset       = fontDesc->sCharset;
2171c2c66affSColin Finck   newObject->description.fItalic        = fontDesc->fItalic;
2172c2c66affSColin Finck   newObject->description.fUnderline     = fontDesc->fUnderline;
2173c2c66affSColin Finck   newObject->description.fStrikethrough = fontDesc->fStrikethrough;
2174c2c66affSColin Finck 
2175c2c66affSColin Finck   newObject->gdiFont  = 0;
2176c2c66affSColin Finck   newObject->dirty = TRUE;
2177c2c66affSColin Finck   newObject->cyLogical  = GetDeviceCaps(get_dc(), LOGPIXELSY);
2178c2c66affSColin Finck   newObject->cyHimetric = 2540L;
2179c2c66affSColin Finck   newObject->pPropertyNotifyCP = NULL;
2180c2c66affSColin Finck   newObject->pFontEventsCP = NULL;
2181c2c66affSColin Finck 
2182c2c66affSColin Finck   CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
2183c2c66affSColin Finck   CreateConnectionPoint((IUnknown*)&newObject->IFont_iface, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
2184c2c66affSColin Finck 
2185c2c66affSColin Finck   if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
2186c2c66affSColin Finck   {
2187c2c66affSColin Finck     OLEFontImpl_Destroy(newObject);
2188c2c66affSColin Finck     return NULL;
2189c2c66affSColin Finck   }
2190c2c66affSColin Finck 
2191c2c66affSColin Finck   InterlockedIncrement(&ifont_cnt);
2192c2c66affSColin Finck 
2193c2c66affSColin Finck   TRACE("returning %p\n", newObject);
2194c2c66affSColin Finck   return newObject;
2195c2c66affSColin Finck }
2196c2c66affSColin Finck 
2197c2c66affSColin Finck /************************************************************************
2198c2c66affSColin Finck  * OLEFontImpl_Destroy
2199c2c66affSColin Finck  *
2200c2c66affSColin Finck  * This method is called by the Release method when the reference
2201c2c66affSColin Finck  * count goes down to 0. It will free all resources used by
2202c2c66affSColin Finck  * this object.
2203c2c66affSColin Finck  */
OLEFontImpl_Destroy(OLEFontImpl * fontDesc)2204c2c66affSColin Finck static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
2205c2c66affSColin Finck {
2206c2c66affSColin Finck   TRACE("(%p)\n", fontDesc);
2207c2c66affSColin Finck 
2208c2c66affSColin Finck   HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
2209c2c66affSColin Finck 
2210c2c66affSColin Finck   if (fontDesc->pPropertyNotifyCP)
2211c2c66affSColin Finck       IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
2212c2c66affSColin Finck   if (fontDesc->pFontEventsCP)
2213c2c66affSColin Finck       IConnectionPoint_Release(fontDesc->pFontEventsCP);
2214c2c66affSColin Finck 
2215c2c66affSColin Finck   HeapFree(GetProcessHeap(), 0, fontDesc);
2216c2c66affSColin Finck }
2217c2c66affSColin Finck 
2218c2c66affSColin Finck /*******************************************************************************
2219c2c66affSColin Finck  * StdFont ClassFactory
2220c2c66affSColin Finck  */
2221c2c66affSColin Finck typedef struct
2222c2c66affSColin Finck {
2223c2c66affSColin Finck     /* IUnknown fields */
2224c2c66affSColin Finck     IClassFactory IClassFactory_iface;
2225c2c66affSColin Finck     LONG          ref;
2226c2c66affSColin Finck } IClassFactoryImpl;
2227c2c66affSColin Finck 
impl_from_IClassFactory(IClassFactory * iface)2228c2c66affSColin Finck static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
2229c2c66affSColin Finck {
2230c2c66affSColin Finck         return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
2231c2c66affSColin Finck }
2232c2c66affSColin Finck 
SFCF_QueryInterface(IClassFactory * iface,REFIID riid,void ** obj)2233c2c66affSColin Finck static HRESULT WINAPI SFCF_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
2234c2c66affSColin Finck {
2235c2c66affSColin Finck     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
2236c2c66affSColin Finck 
2237c2c66affSColin Finck     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), obj);
2238c2c66affSColin Finck 
2239c2c66affSColin Finck     *obj = NULL;
2240c2c66affSColin Finck 
2241c2c66affSColin Finck     if (IsEqualIID(&IID_IClassFactory, riid) || IsEqualIID(&IID_IUnknown, riid))
2242c2c66affSColin Finck     {
2243c2c66affSColin Finck         *obj = iface;
2244c2c66affSColin Finck         IClassFactory_AddRef(iface);
2245c2c66affSColin Finck         return S_OK;
2246c2c66affSColin Finck     }
2247c2c66affSColin Finck 
2248c2c66affSColin Finck     return E_NOINTERFACE;
2249c2c66affSColin Finck }
2250c2c66affSColin Finck 
2251c2c66affSColin Finck static ULONG WINAPI
SFCF_AddRef(LPCLASSFACTORY iface)2252c2c66affSColin Finck SFCF_AddRef(LPCLASSFACTORY iface) {
2253c2c66affSColin Finck 	IClassFactoryImpl *This = impl_from_IClassFactory(iface);
2254c2c66affSColin Finck 	return InterlockedIncrement(&This->ref);
2255c2c66affSColin Finck }
2256c2c66affSColin Finck 
SFCF_Release(LPCLASSFACTORY iface)2257c2c66affSColin Finck static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
2258c2c66affSColin Finck 	IClassFactoryImpl *This = impl_from_IClassFactory(iface);
2259c2c66affSColin Finck 	/* static class, won't be  freed */
2260c2c66affSColin Finck 	return InterlockedDecrement(&This->ref);
2261c2c66affSColin Finck }
2262c2c66affSColin Finck 
SFCF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID * ppobj)2263c2c66affSColin Finck static HRESULT WINAPI SFCF_CreateInstance(
2264c2c66affSColin Finck 	LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
2265c2c66affSColin Finck ) {
2266c2c66affSColin Finck 	return OleCreateFontIndirect(NULL,riid,ppobj);
2267c2c66affSColin Finck 
2268c2c66affSColin Finck }
2269c2c66affSColin Finck 
SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)2270c2c66affSColin Finck static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
2271c2c66affSColin Finck 	IClassFactoryImpl *This = impl_from_IClassFactory(iface);
2272c2c66affSColin Finck 	FIXME("(%p)->(%d),stub!\n",This,dolock);
2273c2c66affSColin Finck 	return S_OK;
2274c2c66affSColin Finck }
2275c2c66affSColin Finck 
2276c2c66affSColin Finck static const IClassFactoryVtbl SFCF_Vtbl = {
2277c2c66affSColin Finck 	SFCF_QueryInterface,
2278c2c66affSColin Finck 	SFCF_AddRef,
2279c2c66affSColin Finck 	SFCF_Release,
2280c2c66affSColin Finck 	SFCF_CreateInstance,
2281c2c66affSColin Finck 	SFCF_LockServer
2282c2c66affSColin Finck };
2283c2c66affSColin Finck static IClassFactoryImpl STDFONT_CF = {{&SFCF_Vtbl}, 1 };
2284c2c66affSColin Finck 
_get_STDFONT_CF(LPVOID * ppv)2285c2c66affSColin Finck void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; }
2286