comctl32/tests: Add NULL terminator to unicode string constant.
[wine/hramrach.git] / dlls / oleaut32 / olefont.c
blobdf7de87bfc23bfc3cf0d7f0a9f4ad5a02822a4dd
1 /*
2 * OLE Font encapsulation implementation
4 * This file contains an implementation of the IFont
5 * interface and the OleCreateFontIndirect API call.
7 * Copyright 1999 Francis Beaudet
8 * Copyright 2006 (Google) Benjamin Arai
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <assert.h>
25 #include <stdarg.h>
26 #include <string.h>
28 #define COBJMACROS
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
32 #include "winerror.h"
33 #include "windef.h"
34 #include "winbase.h"
35 #include "wingdi.h"
36 #include "winuser.h"
37 #include "wine/list.h"
38 #include "wine/unicode.h"
39 #include "objbase.h"
40 #include "oleauto.h" /* for SysAllocString(....) */
41 #include "ole2.h"
42 #include "olectl.h"
43 #include "wine/debug.h"
44 #include "connpt.h" /* for CreateConnectionPoint */
45 #include "oaidl.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole);
49 /***********************************************************************
50 * Declaration of constants used when serializing the font object.
52 #define FONTPERSIST_ITALIC 0x02
53 #define FONTPERSIST_UNDERLINE 0x04
54 #define FONTPERSIST_STRIKETHROUGH 0x08
56 static HDC olefont_hdc;
58 /***********************************************************************
59 * List of the HFONTs it has given out, with each one having a separate
60 * ref count.
62 typedef struct _HFONTItem
64 struct list entry;
66 /* Reference count of any IFont objects that own this hfont */
67 LONG int_refs;
69 /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
70 LONG total_refs;
72 /* The font associated with this object. */
73 HFONT gdiFont;
75 } HFONTItem, *PHFONTItem;
77 static struct list OLEFontImpl_hFontList = LIST_INIT(OLEFontImpl_hFontList);
79 /* Counts how many fonts contain at least one lock */
80 static LONG ifont_cnt = 0;
82 /***********************************************************************
83 * Critical section for OLEFontImpl_hFontList
85 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST;
86 static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
88 0, 0, &OLEFontImpl_csHFONTLIST,
89 { &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList,
90 &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList },
91 0, 0, { (DWORD_PTR)(__FILE__ ": OLEFontImpl_csHFONTLIST") }
93 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
95 static HDC get_dc(void)
97 HDC hdc;
98 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
99 if(!olefont_hdc)
100 olefont_hdc = CreateCompatibleDC(NULL);
101 hdc = olefont_hdc;
102 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
103 return hdc;
106 static void delete_dc(void)
108 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
109 if(olefont_hdc)
111 DeleteDC(olefont_hdc);
112 olefont_hdc = NULL;
114 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
117 static void HFONTItem_Delete(PHFONTItem item)
119 DeleteObject(item->gdiFont);
120 list_remove(&item->entry);
121 HeapFree(GetProcessHeap(), 0, item);
124 /* Find hfont item entry in the list. Should be called while holding the crit sect */
125 static HFONTItem *find_hfontitem(HFONT hfont)
127 HFONTItem *item;
129 LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry)
131 if (item->gdiFont == hfont)
132 return item;
134 return NULL;
137 /* Add an item to the list with one internal reference */
138 static HRESULT add_hfontitem(HFONT hfont)
140 HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item));
142 if(!new_item) return E_OUTOFMEMORY;
144 new_item->int_refs = 1;
145 new_item->total_refs = 1;
146 new_item->gdiFont = hfont;
147 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
148 list_add_tail(&OLEFontImpl_hFontList,&new_item->entry);
149 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
150 return S_OK;
153 static HRESULT inc_int_ref(HFONT hfont)
155 HFONTItem *item;
156 HRESULT hr = S_FALSE;
158 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
159 item = find_hfontitem(hfont);
161 if(item)
163 item->int_refs++;
164 item->total_refs++;
165 hr = S_OK;
167 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
169 return hr;
172 /* decrements the internal ref of a hfont item. If both refs are zero it'll
173 remove the item from the list and delete the hfont */
174 static HRESULT dec_int_ref(HFONT hfont)
176 HFONTItem *item;
177 HRESULT hr = S_FALSE;
179 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
180 item = find_hfontitem(hfont);
182 if(item)
184 item->int_refs--;
185 item->total_refs--;
186 if(item->int_refs == 0 && item->total_refs == 0)
187 HFONTItem_Delete(item);
188 hr = S_OK;
190 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
192 return hr;
195 static HRESULT inc_ext_ref(HFONT hfont)
197 HFONTItem *item;
198 HRESULT hr = S_FALSE;
200 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
202 item = find_hfontitem(hfont);
203 if(item)
205 item->total_refs++;
206 hr = S_OK;
208 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
210 return hr;
213 static HRESULT dec_ext_ref(HFONT hfont)
215 HFONTItem *item;
216 HRESULT hr = S_FALSE;
218 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
220 item = find_hfontitem(hfont);
221 if(item)
223 if(--item->total_refs >= 0) hr = S_OK;
225 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
227 return hr;
230 static WCHAR *strdupW(const WCHAR* str)
232 WCHAR *ret;
233 DWORD size = (strlenW(str) + 1) * sizeof(WCHAR);
235 ret = HeapAlloc(GetProcessHeap(), 0, size);
236 if(ret)
237 memcpy(ret, str, size);
238 return ret;
241 /***********************************************************************
242 * Declaration of the implementation class for the IFont interface
244 typedef struct OLEFontImpl OLEFontImpl;
246 struct OLEFontImpl
249 * This class supports many interfaces. IUnknown, IFont,
250 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
251 * The first two are supported by the first vtable, the next two are
252 * supported by the second table and the last two have their own.
254 const IFontVtbl* lpVtbl;
255 const IDispatchVtbl* lpvtblIDispatch;
256 const IPersistStreamVtbl* lpvtblIPersistStream;
257 const IConnectionPointContainerVtbl* lpvtblIConnectionPointContainer;
258 const IPersistPropertyBagVtbl* lpvtblIPersistPropertyBag;
259 const IPersistStreamInitVtbl* lpvtblIPersistStreamInit;
261 * Reference count for that instance of the class.
263 LONG ref;
266 * This structure contains the description of the class.
268 FONTDESC description;
271 * Contain the font associated with this object.
273 HFONT gdiFont;
274 BOOL dirty;
276 * Size ratio
278 LONG cyLogical;
279 LONG cyHimetric;
281 IConnectionPoint *pPropertyNotifyCP;
282 IConnectionPoint *pFontEventsCP;
286 * Here, I define utility macros to help with the casting of the
287 * "this" parameter.
288 * There is a version to accommodate all of the VTables implemented
289 * by this object.
292 static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface )
294 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIDispatch));
297 static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface )
299 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStream));
302 static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
304 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIConnectionPointContainer));
307 static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface )
309 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistPropertyBag));
312 static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface )
314 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStreamInit));
318 /***********************************************************************
319 * Prototypes for the implementation functions for the IFont
320 * interface
322 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc);
323 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
324 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
326 /******************************************************************************
327 * OleCreateFontIndirect [OLEAUT32.420]
329 HRESULT WINAPI OleCreateFontIndirect(
330 LPFONTDESC lpFontDesc,
331 REFIID riid,
332 LPVOID* ppvObj)
334 OLEFontImpl* newFont = 0;
335 HRESULT hr = S_OK;
337 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
339 * Sanity check
341 if (ppvObj==0)
342 return E_POINTER;
344 *ppvObj = 0;
346 if (!lpFontDesc) {
347 FONTDESC fd;
349 static WCHAR fname[] = { 'S','y','s','t','e','m',0 };
351 fd.cbSizeofstruct = sizeof(fd);
352 fd.lpstrName = fname;
353 fd.cySize.s.Lo = 80000;
354 fd.cySize.s.Hi = 0;
355 fd.sWeight = 0;
356 fd.sCharset = 0;
357 fd.fItalic = 0;
358 fd.fUnderline = 0;
359 fd.fStrikethrough = 0;
360 lpFontDesc = &fd;
364 * Try to construct a new instance of the class.
366 newFont = OLEFontImpl_Construct(lpFontDesc);
368 if (newFont == 0)
369 return E_OUTOFMEMORY;
372 * Make sure it supports the interface required by the caller.
374 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
377 * Release the reference obtained in the constructor. If
378 * the QueryInterface was unsuccessful, it will free the class.
380 IFont_Release((IFont*)newFont);
382 return hr;
386 /***********************************************************************
387 * Implementation of the OLEFontImpl class.
390 /***********************************************************************
391 * OLEFont_SendNotify (internal)
393 * Sends notification messages of changed properties to any interested
394 * connections.
396 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
398 static const WCHAR wszName[] = {'N','a','m','e',0};
399 static const WCHAR wszSize[] = {'S','i','z','e',0};
400 static const WCHAR wszBold[] = {'B','o','l','d',0};
401 static const WCHAR wszItalic[] = {'I','t','a','l','i','c',0};
402 static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0};
403 static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
404 static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0};
405 static const WCHAR wszCharset[] = {'C','h','a','r','s','s','e','t',0};
406 static const LPCWSTR dispid_mapping[] =
408 wszName,
409 NULL,
410 wszSize,
411 wszBold,
412 wszItalic,
413 wszUnder,
414 wszStrike,
415 wszWeight,
416 wszCharset
419 IEnumConnections *pEnum;
420 CONNECTDATA CD;
421 HRESULT hres;
423 this->dirty = TRUE;
425 hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
426 if (SUCCEEDED(hres))
428 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
429 IPropertyNotifySink *sink;
431 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
432 IPropertyNotifySink_OnChanged(sink, dispID);
433 IPropertyNotifySink_Release(sink);
434 IUnknown_Release(CD.pUnk);
436 IEnumConnections_Release(pEnum);
439 hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum);
440 if (SUCCEEDED(hres))
442 DISPPARAMS dispparams;
443 VARIANTARG vararg;
445 VariantInit(&vararg);
446 V_VT(&vararg) = VT_BSTR;
447 V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]);
449 dispparams.cArgs = 1;
450 dispparams.cNamedArgs = 0;
451 dispparams.rgdispidNamedArgs = NULL;
452 dispparams.rgvarg = &vararg;
454 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
455 IFontEventsDisp *disp;
457 IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp);
458 IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
459 LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
460 NULL, NULL);
462 IDispatch_Release(disp);
463 IUnknown_Release(CD.pUnk);
465 VariantClear(&vararg);
466 IEnumConnections_Release(pEnum);
470 /************************************************************************
471 * OLEFontImpl_QueryInterface (IUnknown)
473 * See Windows documentation for more details on IUnknown methods.
475 static HRESULT WINAPI OLEFontImpl_QueryInterface(
476 IFont* iface,
477 REFIID riid,
478 void** ppvObject)
480 OLEFontImpl *this = (OLEFontImpl *)iface;
481 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
484 * Perform a sanity check on the parameters.
486 if ( (this==0) || (ppvObject==0) )
487 return E_INVALIDARG;
490 * Initialize the return parameter.
492 *ppvObject = 0;
495 * Compare the riid with the interface IDs implemented by this object.
497 if (IsEqualGUID(&IID_IUnknown, riid))
498 *ppvObject = this;
499 if (IsEqualGUID(&IID_IFont, riid))
500 *ppvObject = this;
501 if (IsEqualGUID(&IID_IDispatch, riid))
502 *ppvObject = &this->lpvtblIDispatch;
503 if (IsEqualGUID(&IID_IFontDisp, riid))
504 *ppvObject = &this->lpvtblIDispatch;
505 if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid))
506 *ppvObject = &this->lpvtblIPersistStream;
507 if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
508 *ppvObject = &this->lpvtblIConnectionPointContainer;
509 if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
510 *ppvObject = &this->lpvtblIPersistPropertyBag;
511 if (IsEqualGUID(&IID_IPersistStreamInit, riid))
512 *ppvObject = &this->lpvtblIPersistStreamInit;
515 * Check that we obtained an interface.
517 if ((*ppvObject)==0)
519 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
520 return E_NOINTERFACE;
522 OLEFontImpl_AddRef((IFont*)this);
523 return S_OK;
526 /************************************************************************
527 * OLEFontImpl_AddRef (IUnknown)
529 * See Windows documentation for more details on IUnknown methods.
531 static ULONG WINAPI OLEFontImpl_AddRef(
532 IFont* iface)
534 OLEFontImpl *this = (OLEFontImpl *)iface;
535 TRACE("(%p)->(ref=%d)\n", this, this->ref);
536 return InterlockedIncrement(&this->ref);
539 /************************************************************************
540 * OLEFontImpl_Release (IUnknown)
542 * See Windows documentation for more details on IUnknown methods.
544 static ULONG WINAPI OLEFontImpl_Release(
545 IFont* iface)
547 OLEFontImpl *this = (OLEFontImpl *)iface;
548 ULONG ret;
549 TRACE("(%p)->(ref=%d)\n", this, this->ref);
551 /* Decrease the reference count for current interface */
552 ret = InterlockedDecrement(&this->ref);
554 /* If the reference count goes down to 0, destroy. */
555 if (ret == 0)
557 ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
559 /* Final IFont object so destroy font cache */
560 if (fontlist_refs == 0)
562 HFONTItem *item, *cursor2;
564 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
565 LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry)
566 HFONTItem_Delete(item);
567 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
568 delete_dc();
570 else
572 dec_int_ref(this->gdiFont);
574 OLEFontImpl_Destroy(this);
577 return ret;
580 typedef struct
582 short orig_cs;
583 short avail_cs;
584 } enum_data;
586 static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp)
588 enum_data *data = (enum_data*)lp;
590 if(elf->lfCharSet == data->orig_cs)
592 data->avail_cs = data->orig_cs;
593 return 0;
595 if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet;
596 return 1;
599 static void realize_font(OLEFontImpl *This)
601 if (This->dirty)
603 LOGFONTW logFont;
604 INT fontHeight;
605 WCHAR text_face[LF_FACESIZE];
606 HDC hdc = get_dc();
607 HFONT old_font;
608 TEXTMETRICW tm;
610 text_face[0] = 0;
612 if(This->gdiFont)
614 old_font = SelectObject(hdc, This->gdiFont);
615 GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
616 SelectObject(hdc, old_font);
617 dec_int_ref(This->gdiFont);
618 This->gdiFont = 0;
621 memset(&logFont, 0, sizeof(LOGFONTW));
623 lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
624 logFont.lfCharSet = This->description.sCharset;
626 /* If the font name has been changed then enumerate all charsets
627 and pick one that'll result in the font specified being selected */
628 if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
630 enum_data data;
631 data.orig_cs = This->description.sCharset;
632 data.avail_cs = -1;
633 logFont.lfCharSet = DEFAULT_CHARSET;
634 EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
635 if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
640 * The height of the font returned by the get_Size property is the
641 * height of the font in points multiplied by 10000... Using some
642 * simple conversions and the ratio given by the application, it can
643 * be converted to a height in pixels.
645 * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
646 * Ratio is applied here relative to the standard.
649 fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
652 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
653 (-fontHeight/10000L);
654 logFont.lfItalic = This->description.fItalic;
655 logFont.lfUnderline = This->description.fUnderline;
656 logFont.lfStrikeOut = This->description.fStrikethrough;
657 logFont.lfWeight = This->description.sWeight;
658 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
659 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
660 logFont.lfQuality = DEFAULT_QUALITY;
661 logFont.lfPitchAndFamily = DEFAULT_PITCH;
663 This->gdiFont = CreateFontIndirectW(&logFont);
664 This->dirty = FALSE;
666 add_hfontitem(This->gdiFont);
668 /* Fixup the name and charset properties so that they match the
669 selected font */
670 old_font = SelectObject(get_dc(), This->gdiFont);
671 GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
672 if(lstrcmpiW(text_face, This->description.lpstrName))
674 HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
675 This->description.lpstrName = strdupW(text_face);
677 GetTextMetricsW(hdc, &tm);
678 This->description.sCharset = tm.tmCharSet;
679 SelectObject(hdc, old_font);
683 /************************************************************************
684 * OLEFontImpl_get_Name (IFont)
686 * See Windows documentation for more details on IFont methods.
688 static HRESULT WINAPI OLEFontImpl_get_Name(
689 IFont* iface,
690 BSTR* pname)
692 OLEFontImpl *this = (OLEFontImpl *)iface;
693 TRACE("(%p)->(%p)\n", this, pname);
695 * Sanity check.
697 if (pname==0)
698 return E_POINTER;
700 if(this->dirty) realize_font(this);
702 if (this->description.lpstrName!=0)
703 *pname = SysAllocString(this->description.lpstrName);
704 else
705 *pname = 0;
707 return S_OK;
710 /************************************************************************
711 * OLEFontImpl_put_Name (IFont)
713 * See Windows documentation for more details on IFont methods.
715 static HRESULT WINAPI OLEFontImpl_put_Name(
716 IFont* iface,
717 BSTR name)
719 OLEFontImpl *this = (OLEFontImpl *)iface;
720 TRACE("(%p)->(%p)\n", this, name);
722 if (!name)
723 return CTL_E_INVALIDPROPERTYVALUE;
725 if (this->description.lpstrName==0)
727 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
729 (lstrlenW(name)+1) * sizeof(WCHAR));
731 else
733 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
735 this->description.lpstrName,
736 (lstrlenW(name)+1) * sizeof(WCHAR));
739 if (this->description.lpstrName==0)
740 return E_OUTOFMEMORY;
742 strcpyW(this->description.lpstrName, name);
743 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
744 OLEFont_SendNotify(this, DISPID_FONT_NAME);
745 return S_OK;
748 /************************************************************************
749 * OLEFontImpl_get_Size (IFont)
751 * See Windows documentation for more details on IFont methods.
753 static HRESULT WINAPI OLEFontImpl_get_Size(
754 IFont* iface,
755 CY* psize)
757 OLEFontImpl *this = (OLEFontImpl *)iface;
758 TRACE("(%p)->(%p)\n", this, psize);
761 * Sanity check
763 if (psize==0)
764 return E_POINTER;
766 if(this->dirty) realize_font(this);
768 psize->s.Hi = 0;
769 psize->s.Lo = this->description.cySize.s.Lo;
771 return S_OK;
774 /************************************************************************
775 * OLEFontImpl_put_Size (IFont)
777 * See Windows documentation for more details on IFont methods.
779 static HRESULT WINAPI OLEFontImpl_put_Size(
780 IFont* iface,
781 CY size)
783 OLEFontImpl *this = (OLEFontImpl *)iface;
784 TRACE("(%p)->(%d)\n", this, size.s.Lo);
785 this->description.cySize.s.Hi = 0;
786 this->description.cySize.s.Lo = size.s.Lo;
787 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
789 return S_OK;
792 /************************************************************************
793 * OLEFontImpl_get_Bold (IFont)
795 * See Windows documentation for more details on IFont methods.
797 static HRESULT WINAPI OLEFontImpl_get_Bold(
798 IFont* iface,
799 BOOL* pbold)
801 OLEFontImpl *this = (OLEFontImpl *)iface;
802 TRACE("(%p)->(%p)\n", this, pbold);
804 * Sanity check
806 if (pbold==0)
807 return E_POINTER;
809 if(this->dirty) realize_font(this);
811 *pbold = this->description.sWeight > 550;
813 return S_OK;
816 /************************************************************************
817 * OLEFontImpl_put_Bold (IFont)
819 * See Windows documentation for more details on IFont methods.
821 static HRESULT WINAPI OLEFontImpl_put_Bold(
822 IFont* iface,
823 BOOL bold)
825 OLEFontImpl *this = (OLEFontImpl *)iface;
826 TRACE("(%p)->(%d)\n", this, bold);
827 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
828 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
830 return S_OK;
833 /************************************************************************
834 * OLEFontImpl_get_Italic (IFont)
836 * See Windows documentation for more details on IFont methods.
838 static HRESULT WINAPI OLEFontImpl_get_Italic(
839 IFont* iface,
840 BOOL* pitalic)
842 OLEFontImpl *this = (OLEFontImpl *)iface;
843 TRACE("(%p)->(%p)\n", this, pitalic);
845 * Sanity check
847 if (pitalic==0)
848 return E_POINTER;
850 if(this->dirty) realize_font(this);
852 *pitalic = this->description.fItalic;
854 return S_OK;
857 /************************************************************************
858 * OLEFontImpl_put_Italic (IFont)
860 * See Windows documentation for more details on IFont methods.
862 static HRESULT WINAPI OLEFontImpl_put_Italic(
863 IFont* iface,
864 BOOL italic)
866 OLEFontImpl *this = (OLEFontImpl *)iface;
867 TRACE("(%p)->(%d)\n", this, italic);
869 this->description.fItalic = italic;
871 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
872 return S_OK;
875 /************************************************************************
876 * OLEFontImpl_get_Underline (IFont)
878 * See Windows documentation for more details on IFont methods.
880 static HRESULT WINAPI OLEFontImpl_get_Underline(
881 IFont* iface,
882 BOOL* punderline)
884 OLEFontImpl *this = (OLEFontImpl *)iface;
885 TRACE("(%p)->(%p)\n", this, punderline);
888 * Sanity check
890 if (punderline==0)
891 return E_POINTER;
893 if(this->dirty) realize_font(this);
895 *punderline = this->description.fUnderline;
897 return S_OK;
900 /************************************************************************
901 * OLEFontImpl_put_Underline (IFont)
903 * See Windows documentation for more details on IFont methods.
905 static HRESULT WINAPI OLEFontImpl_put_Underline(
906 IFont* iface,
907 BOOL underline)
909 OLEFontImpl *this = (OLEFontImpl *)iface;
910 TRACE("(%p)->(%d)\n", this, underline);
912 this->description.fUnderline = underline;
914 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
915 return S_OK;
918 /************************************************************************
919 * OLEFontImpl_get_Strikethrough (IFont)
921 * See Windows documentation for more details on IFont methods.
923 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
924 IFont* iface,
925 BOOL* pstrikethrough)
927 OLEFontImpl *this = (OLEFontImpl *)iface;
928 TRACE("(%p)->(%p)\n", this, pstrikethrough);
931 * Sanity check
933 if (pstrikethrough==0)
934 return E_POINTER;
936 if(this->dirty) realize_font(this);
938 *pstrikethrough = this->description.fStrikethrough;
940 return S_OK;
943 /************************************************************************
944 * OLEFontImpl_put_Strikethrough (IFont)
946 * See Windows documentation for more details on IFont methods.
948 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
949 IFont* iface,
950 BOOL strikethrough)
952 OLEFontImpl *this = (OLEFontImpl *)iface;
953 TRACE("(%p)->(%d)\n", this, strikethrough);
955 this->description.fStrikethrough = strikethrough;
956 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
958 return S_OK;
961 /************************************************************************
962 * OLEFontImpl_get_Weight (IFont)
964 * See Windows documentation for more details on IFont methods.
966 static HRESULT WINAPI OLEFontImpl_get_Weight(
967 IFont* iface,
968 short* pweight)
970 OLEFontImpl *this = (OLEFontImpl *)iface;
971 TRACE("(%p)->(%p)\n", this, pweight);
974 * Sanity check
976 if (pweight==0)
977 return E_POINTER;
979 if(this->dirty) realize_font(this);
981 *pweight = this->description.sWeight;
983 return S_OK;
986 /************************************************************************
987 * OLEFontImpl_put_Weight (IFont)
989 * See Windows documentation for more details on IFont methods.
991 static HRESULT WINAPI OLEFontImpl_put_Weight(
992 IFont* iface,
993 short weight)
995 OLEFontImpl *this = (OLEFontImpl *)iface;
996 TRACE("(%p)->(%d)\n", this, weight);
998 this->description.sWeight = weight;
1000 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
1001 return S_OK;
1004 /************************************************************************
1005 * OLEFontImpl_get_Charset (IFont)
1007 * See Windows documentation for more details on IFont methods.
1009 static HRESULT WINAPI OLEFontImpl_get_Charset(
1010 IFont* iface,
1011 short* pcharset)
1013 OLEFontImpl *this = (OLEFontImpl *)iface;
1014 TRACE("(%p)->(%p)\n", this, pcharset);
1017 * Sanity check
1019 if (pcharset==0)
1020 return E_POINTER;
1022 if(this->dirty) realize_font(this);
1024 *pcharset = this->description.sCharset;
1026 return S_OK;
1029 /************************************************************************
1030 * OLEFontImpl_put_Charset (IFont)
1032 * See Windows documentation for more details on IFont methods.
1034 static HRESULT WINAPI OLEFontImpl_put_Charset(
1035 IFont* iface,
1036 short charset)
1038 OLEFontImpl *this = (OLEFontImpl *)iface;
1039 TRACE("(%p)->(%d)\n", this, charset);
1041 this->description.sCharset = charset;
1042 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
1044 return S_OK;
1047 /************************************************************************
1048 * OLEFontImpl_get_hFont (IFont)
1050 * See Windows documentation for more details on IFont methods.
1052 static HRESULT WINAPI OLEFontImpl_get_hFont(
1053 IFont* iface,
1054 HFONT* phfont)
1056 OLEFontImpl *this = (OLEFontImpl *)iface;
1057 TRACE("(%p)->(%p)\n", this, phfont);
1058 if (phfont==NULL)
1059 return E_POINTER;
1061 if(this->dirty) realize_font(this);
1063 *phfont = this->gdiFont;
1064 TRACE("Returning %p\n", *phfont);
1065 return S_OK;
1068 /************************************************************************
1069 * OLEFontImpl_Clone (IFont)
1071 * See Windows documentation for more details on IFont methods.
1073 static HRESULT WINAPI OLEFontImpl_Clone(
1074 IFont* iface,
1075 IFont** ppfont)
1077 OLEFontImpl* newObject = 0;
1078 OLEFontImpl *this = (OLEFontImpl *)iface;
1080 TRACE("(%p)->(%p)\n", this, ppfont);
1082 if (ppfont == NULL)
1083 return E_POINTER;
1085 *ppfont = NULL;
1088 * Allocate space for the object.
1090 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
1092 if (newObject==NULL)
1093 return E_OUTOFMEMORY;
1095 *newObject = *this;
1097 /* We need to alloc new memory for the string, otherwise
1098 * we free memory twice.
1100 newObject->description.lpstrName = HeapAlloc(
1101 GetProcessHeap(),0,
1102 (1+strlenW(this->description.lpstrName))*2
1104 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
1107 /* Increment internal ref in hfont item list */
1108 if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
1110 InterlockedIncrement(&ifont_cnt);
1112 /* create new connection points */
1113 newObject->pPropertyNotifyCP = NULL;
1114 newObject->pFontEventsCP = NULL;
1115 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
1116 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
1118 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
1120 OLEFontImpl_Destroy(newObject);
1121 return E_OUTOFMEMORY;
1124 /* The cloned object starts with a reference count of 1 */
1125 newObject->ref = 1;
1127 *ppfont = (IFont*)newObject;
1129 return S_OK;
1132 /************************************************************************
1133 * OLEFontImpl_IsEqual (IFont)
1135 * See Windows documentation for more details on IFont methods.
1137 static HRESULT WINAPI OLEFontImpl_IsEqual(
1138 IFont* iface,
1139 IFont* pFontOther)
1141 OLEFontImpl *left = (OLEFontImpl *)iface;
1142 OLEFontImpl *right = (OLEFontImpl *)pFontOther;
1143 INT ret;
1144 INT left_len,right_len;
1146 if((iface == NULL) || (pFontOther == NULL))
1147 return E_POINTER;
1148 else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo)
1149 return S_FALSE;
1150 else if (left->description.cySize.s.Hi != right->description.cySize.s.Hi)
1151 return S_FALSE;
1152 else if (left->description.sWeight != right->description.sWeight)
1153 return S_FALSE;
1154 else if (left->description.sCharset != right->description.sCharset)
1155 return S_FALSE;
1156 else if (left->description.fItalic != right->description.fItalic)
1157 return S_FALSE;
1158 else if (left->description.fUnderline != right->description.fUnderline)
1159 return S_FALSE;
1160 else if (left->description.fStrikethrough != right->description.fStrikethrough)
1161 return S_FALSE;
1163 /* Check from string */
1164 left_len = strlenW(left->description.lpstrName);
1165 right_len = strlenW(right->description.lpstrName);
1166 ret = CompareStringW(0,0,left->description.lpstrName, left_len,
1167 right->description.lpstrName, right_len);
1168 if (ret != CSTR_EQUAL)
1169 return S_FALSE;
1171 return S_OK;
1174 /************************************************************************
1175 * OLEFontImpl_SetRatio (IFont)
1177 * See Windows documentation for more details on IFont methods.
1179 static HRESULT WINAPI OLEFontImpl_SetRatio(
1180 IFont* iface,
1181 LONG cyLogical,
1182 LONG cyHimetric)
1184 OLEFontImpl *this = (OLEFontImpl *)iface;
1185 TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric);
1187 this->cyLogical = cyLogical;
1188 this->cyHimetric = cyHimetric;
1190 return S_OK;
1193 /************************************************************************
1194 * OLEFontImpl_QueryTextMetrics (IFont)
1196 * See Windows documentation for more details on IFont methods.
1198 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1199 IFont* iface,
1200 TEXTMETRICOLE* ptm)
1202 HDC hdcRef;
1203 HFONT hOldFont, hNewFont;
1205 hdcRef = GetDC(0);
1206 OLEFontImpl_get_hFont(iface, &hNewFont);
1207 hOldFont = SelectObject(hdcRef, hNewFont);
1208 GetTextMetricsW(hdcRef, ptm);
1209 SelectObject(hdcRef, hOldFont);
1210 ReleaseDC(0, hdcRef);
1211 return S_OK;
1214 /************************************************************************
1215 * OLEFontImpl_AddRefHfont (IFont)
1217 * See Windows documentation for more details on IFont methods.
1219 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1220 IFont* iface,
1221 HFONT hfont)
1223 OLEFontImpl *this = (OLEFontImpl *)iface;
1225 TRACE("(%p)->(%p)\n", this, hfont);
1227 if (!hfont) return E_INVALIDARG;
1229 return inc_ext_ref(hfont);
1232 /************************************************************************
1233 * OLEFontImpl_ReleaseHfont (IFont)
1235 * See Windows documentation for more details on IFont methods.
1237 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1238 IFont* iface,
1239 HFONT hfont)
1241 OLEFontImpl *this = (OLEFontImpl *)iface;
1243 TRACE("(%p)->(%p)\n", this, hfont);
1245 if (!hfont) return E_INVALIDARG;
1247 return dec_ext_ref(hfont);
1250 /************************************************************************
1251 * OLEFontImpl_SetHdc (IFont)
1253 * See Windows documentation for more details on IFont methods.
1255 static HRESULT WINAPI OLEFontImpl_SetHdc(
1256 IFont* iface,
1257 HDC hdc)
1259 OLEFontImpl *this = (OLEFontImpl *)iface;
1260 FIXME("(%p)->(%p): Stub\n", this, hdc);
1261 return E_NOTIMPL;
1265 * Virtual function tables for the OLEFontImpl class.
1267 static const IFontVtbl OLEFontImpl_VTable =
1269 OLEFontImpl_QueryInterface,
1270 OLEFontImpl_AddRef,
1271 OLEFontImpl_Release,
1272 OLEFontImpl_get_Name,
1273 OLEFontImpl_put_Name,
1274 OLEFontImpl_get_Size,
1275 OLEFontImpl_put_Size,
1276 OLEFontImpl_get_Bold,
1277 OLEFontImpl_put_Bold,
1278 OLEFontImpl_get_Italic,
1279 OLEFontImpl_put_Italic,
1280 OLEFontImpl_get_Underline,
1281 OLEFontImpl_put_Underline,
1282 OLEFontImpl_get_Strikethrough,
1283 OLEFontImpl_put_Strikethrough,
1284 OLEFontImpl_get_Weight,
1285 OLEFontImpl_put_Weight,
1286 OLEFontImpl_get_Charset,
1287 OLEFontImpl_put_Charset,
1288 OLEFontImpl_get_hFont,
1289 OLEFontImpl_Clone,
1290 OLEFontImpl_IsEqual,
1291 OLEFontImpl_SetRatio,
1292 OLEFontImpl_QueryTextMetrics,
1293 OLEFontImpl_AddRefHfont,
1294 OLEFontImpl_ReleaseHfont,
1295 OLEFontImpl_SetHdc
1298 /************************************************************************
1299 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1301 * See Windows documentation for more details on IUnknown methods.
1303 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1304 IDispatch* iface,
1305 REFIID riid,
1306 VOID** ppvoid)
1308 OLEFontImpl *this = impl_from_IDispatch(iface);
1310 return IFont_QueryInterface((IFont *)this, riid, ppvoid);
1313 /************************************************************************
1314 * OLEFontImpl_IDispatch_Release (IUnknown)
1316 * See Windows documentation for more details on IUnknown methods.
1318 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1319 IDispatch* iface)
1321 OLEFontImpl *this = impl_from_IDispatch(iface);
1323 return IFont_Release((IFont *)this);
1326 /************************************************************************
1327 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1329 * See Windows documentation for more details on IUnknown methods.
1331 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1332 IDispatch* iface)
1334 OLEFontImpl *this = impl_from_IDispatch(iface);
1336 return IFont_AddRef((IFont *)this);
1339 /************************************************************************
1340 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1342 * See Windows documentation for more details on IDispatch methods.
1344 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1345 IDispatch* iface,
1346 unsigned int* pctinfo)
1348 OLEFontImpl *this = impl_from_IDispatch(iface);
1349 TRACE("(%p)->(%p)\n", this, pctinfo);
1350 *pctinfo = 1;
1352 return S_OK;
1355 /************************************************************************
1356 * OLEFontImpl_GetTypeInfo (IDispatch)
1358 * See Windows documentation for more details on IDispatch methods.
1360 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1361 IDispatch* iface,
1362 UINT iTInfo,
1363 LCID lcid,
1364 ITypeInfo** ppTInfo)
1366 static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
1367 ITypeLib *tl;
1368 HRESULT hres;
1370 OLEFontImpl *this = impl_from_IDispatch(iface);
1371 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);
1372 if (iTInfo != 0)
1373 return E_FAIL;
1374 hres = LoadTypeLib(stdole2tlb, &tl);
1375 if (FAILED(hres)) {
1376 ERR("Could not load the stdole2.tlb?\n");
1377 return hres;
1379 hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IFontDisp, ppTInfo);
1380 ITypeLib_Release(tl);
1381 if (FAILED(hres)) {
1382 FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres);
1384 return hres;
1387 /************************************************************************
1388 * OLEFontImpl_GetIDsOfNames (IDispatch)
1390 * See Windows documentation for more details on IDispatch methods.
1392 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1393 IDispatch* iface,
1394 REFIID riid,
1395 LPOLESTR* rgszNames,
1396 UINT cNames,
1397 LCID lcid,
1398 DISPID* rgDispId)
1400 ITypeInfo * pTInfo;
1401 HRESULT hres;
1403 OLEFontImpl *this = impl_from_IDispatch(iface);
1405 TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid),
1406 rgszNames, cNames, (int)lcid, rgDispId);
1408 if (cNames == 0)
1410 return E_INVALIDARG;
1412 else
1414 /* retrieve type information */
1415 hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo);
1417 if (FAILED(hres))
1419 ERR("GetTypeInfo failed.\n");
1420 return hres;
1423 /* convert names to DISPIDs */
1424 hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId);
1425 ITypeInfo_Release(pTInfo);
1427 return hres;
1431 /************************************************************************
1432 * OLEFontImpl_Invoke (IDispatch)
1434 * See Windows documentation for more details on IDispatch methods.
1436 * Note: Do not call _put_Xxx methods, since setting things here
1437 * should not call notify functions as I found out debugging the generic
1438 * MS VB5 installer.
1440 static HRESULT WINAPI OLEFontImpl_Invoke(
1441 IDispatch* iface,
1442 DISPID dispIdMember,
1443 REFIID riid,
1444 LCID lcid,
1445 WORD wFlags,
1446 DISPPARAMS* pDispParams,
1447 VARIANT* pVarResult,
1448 EXCEPINFO* pExepInfo,
1449 UINT* puArgErr)
1451 OLEFontImpl *this = impl_from_IDispatch(iface);
1452 HRESULT hr;
1454 TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember,
1455 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExepInfo,
1456 puArgErr);
1458 /* validate parameters */
1460 if (!IsEqualIID(riid, &IID_NULL))
1462 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
1463 return DISP_E_UNKNOWNINTERFACE;
1466 if (wFlags & DISPATCH_PROPERTYGET)
1468 if (!pVarResult)
1470 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1471 return DISP_E_PARAMNOTOPTIONAL;
1474 else if (wFlags & DISPATCH_PROPERTYPUT)
1476 if (!pDispParams)
1478 ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n");
1479 return DISP_E_PARAMNOTOPTIONAL;
1481 if (pDispParams->cArgs != 1)
1483 ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs);
1484 return DISP_E_BADPARAMCOUNT;
1487 else
1489 ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n");
1490 return DISP_E_MEMBERNOTFOUND;
1493 switch (dispIdMember) {
1494 case DISPID_FONT_NAME:
1495 if (wFlags & DISPATCH_PROPERTYGET) {
1496 V_VT(pVarResult) = VT_BSTR;
1497 return IFont_get_Name((IFont *)this, &V_BSTR(pVarResult));
1498 } else {
1499 VARIANTARG vararg;
1501 VariantInit(&vararg);
1502 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BSTR);
1503 if (FAILED(hr))
1504 return hr;
1506 hr = IFont_put_Name((IFont *)this, V_BSTR(&vararg));
1508 VariantClear(&vararg);
1509 return hr;
1511 break;
1512 case DISPID_FONT_BOLD:
1513 if (wFlags & DISPATCH_PROPERTYGET) {
1514 BOOL value;
1515 hr = IFont_get_Bold((IFont *)this, &value);
1516 V_VT(pVarResult) = VT_BOOL;
1517 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1518 return hr;
1519 } else {
1520 VARIANTARG vararg;
1522 VariantInit(&vararg);
1523 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1524 if (FAILED(hr))
1525 return hr;
1527 hr = IFont_put_Bold((IFont *)this, V_BOOL(&vararg));
1529 VariantClear(&vararg);
1530 return hr;
1532 break;
1533 case DISPID_FONT_ITALIC:
1534 if (wFlags & DISPATCH_PROPERTYGET) {
1535 BOOL value;
1536 hr = IFont_get_Italic((IFont *)this, &value);
1537 V_VT(pVarResult) = VT_BOOL;
1538 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1539 return hr;
1540 } else {
1541 VARIANTARG vararg;
1543 VariantInit(&vararg);
1544 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1545 if (FAILED(hr))
1546 return hr;
1548 hr = IFont_put_Italic((IFont *)this, V_BOOL(&vararg));
1550 VariantClear(&vararg);
1551 return hr;
1553 break;
1554 case DISPID_FONT_UNDER:
1555 if (wFlags & DISPATCH_PROPERTYGET) {
1556 BOOL value;
1557 hr = IFont_get_Underline((IFont *)this, &value);
1558 V_VT(pVarResult) = VT_BOOL;
1559 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1560 return hr;
1561 } else {
1562 VARIANTARG vararg;
1564 VariantInit(&vararg);
1565 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1566 if (FAILED(hr))
1567 return hr;
1569 hr = IFont_put_Underline((IFont *)this, V_BOOL(&vararg));
1571 VariantClear(&vararg);
1572 return hr;
1574 break;
1575 case DISPID_FONT_STRIKE:
1576 if (wFlags & DISPATCH_PROPERTYGET) {
1577 BOOL value;
1578 hr = IFont_get_Strikethrough((IFont *)this, &value);
1579 V_VT(pVarResult) = VT_BOOL;
1580 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1581 return hr;
1582 } else {
1583 VARIANTARG vararg;
1585 VariantInit(&vararg);
1586 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1587 if (FAILED(hr))
1588 return hr;
1590 hr = IFont_put_Strikethrough((IFont *)this, V_BOOL(&vararg));
1592 VariantClear(&vararg);
1593 return hr;
1595 break;
1596 case DISPID_FONT_SIZE:
1597 if (wFlags & DISPATCH_PROPERTYGET) {
1598 V_VT(pVarResult) = VT_CY;
1599 return OLEFontImpl_get_Size((IFont *)this, &V_CY(pVarResult));
1600 } else {
1601 VARIANTARG vararg;
1603 VariantInit(&vararg);
1604 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_CY);
1605 if (FAILED(hr))
1606 return hr;
1608 hr = IFont_put_Size((IFont *)this, V_CY(&vararg));
1610 VariantClear(&vararg);
1611 return hr;
1613 break;
1614 case DISPID_FONT_WEIGHT:
1615 if (wFlags & DISPATCH_PROPERTYGET) {
1616 V_VT(pVarResult) = VT_I2;
1617 return OLEFontImpl_get_Weight((IFont *)this, &V_I2(pVarResult));
1618 } else {
1619 VARIANTARG vararg;
1621 VariantInit(&vararg);
1622 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1623 if (FAILED(hr))
1624 return hr;
1626 hr = IFont_put_Weight((IFont *)this, V_I2(&vararg));
1628 VariantClear(&vararg);
1629 return hr;
1631 break;
1632 case DISPID_FONT_CHARSET:
1633 if (wFlags & DISPATCH_PROPERTYGET) {
1634 V_VT(pVarResult) = VT_I2;
1635 return OLEFontImpl_get_Charset((IFont *)this, &V_I2(pVarResult));
1636 } else {
1637 VARIANTARG vararg;
1639 VariantInit(&vararg);
1640 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1641 if (FAILED(hr))
1642 return hr;
1644 hr = IFont_put_Charset((IFont *)this, V_I2(&vararg));
1646 VariantClear(&vararg);
1647 return hr;
1649 break;
1650 default:
1651 ERR("member not found for dispid 0x%x\n", dispIdMember);
1652 return DISP_E_MEMBERNOTFOUND;
1656 static const IDispatchVtbl OLEFontImpl_IDispatch_VTable =
1658 OLEFontImpl_IDispatch_QueryInterface,
1659 OLEFontImpl_IDispatch_AddRef,
1660 OLEFontImpl_IDispatch_Release,
1661 OLEFontImpl_GetTypeInfoCount,
1662 OLEFontImpl_GetTypeInfo,
1663 OLEFontImpl_GetIDsOfNames,
1664 OLEFontImpl_Invoke
1667 /************************************************************************
1668 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1670 * See Windows documentation for more details on IUnknown methods.
1672 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1673 IPersistStream* iface,
1674 REFIID riid,
1675 VOID** ppvoid)
1677 OLEFontImpl *this = impl_from_IPersistStream(iface);
1679 return IFont_QueryInterface((IFont *)this, riid, ppvoid);
1682 /************************************************************************
1683 * OLEFontImpl_IPersistStream_Release (IUnknown)
1685 * See Windows documentation for more details on IUnknown methods.
1687 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1688 IPersistStream* iface)
1690 OLEFontImpl *this = impl_from_IPersistStream(iface);
1692 return IFont_Release((IFont *)this);
1695 /************************************************************************
1696 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1698 * See Windows documentation for more details on IUnknown methods.
1700 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1701 IPersistStream* iface)
1703 OLEFontImpl *this = impl_from_IPersistStream(iface);
1705 return IFont_AddRef((IFont *)this);
1708 /************************************************************************
1709 * OLEFontImpl_GetClassID (IPersistStream)
1711 * See Windows documentation for more details on IPersistStream methods.
1713 static HRESULT WINAPI OLEFontImpl_GetClassID(
1714 IPersistStream* iface,
1715 CLSID* pClassID)
1717 TRACE("(%p,%p)\n",iface,pClassID);
1718 if (pClassID==0)
1719 return E_POINTER;
1721 *pClassID = CLSID_StdFont;
1723 return S_OK;
1726 /************************************************************************
1727 * OLEFontImpl_IsDirty (IPersistStream)
1729 * See Windows documentation for more details on IPersistStream methods.
1731 static HRESULT WINAPI OLEFontImpl_IsDirty(
1732 IPersistStream* iface)
1734 TRACE("(%p)\n",iface);
1735 return S_OK;
1738 /************************************************************************
1739 * OLEFontImpl_Load (IPersistStream)
1741 * See Windows documentation for more details on IPersistStream methods.
1743 * This is the format of the standard font serialization as far as I
1744 * know
1746 * Offset Type Value Comment
1747 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1748 * 0x0001 Short Charset Charset value from the FONTDESC structure
1749 * 0x0003 Byte Attributes Flags defined as follows:
1750 * 00000010 - Italic
1751 * 00000100 - Underline
1752 * 00001000 - Strikethrough
1753 * 0x0004 Short Weight Weight value from FONTDESC structure
1754 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1755 * structure/
1756 * 0x000A Byte name length Length of the font name string (no null character)
1757 * 0x000B String name Name of the font (ASCII, no nul character)
1759 static HRESULT WINAPI OLEFontImpl_Load(
1760 IPersistStream* iface,
1761 IStream* pLoadStream)
1763 char readBuffer[0x100];
1764 ULONG cbRead;
1765 BYTE bVersion;
1766 BYTE bAttributes;
1767 BYTE bStringSize;
1768 INT len;
1770 OLEFontImpl *this = impl_from_IPersistStream(iface);
1773 * Read the version byte
1775 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1777 if ( (cbRead!=1) ||
1778 (bVersion!=0x01) )
1779 return E_FAIL;
1782 * Charset
1784 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1786 if (cbRead!=2)
1787 return E_FAIL;
1790 * Attributes
1792 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1794 if (cbRead!=1)
1795 return E_FAIL;
1797 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1798 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1799 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1802 * Weight
1804 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1806 if (cbRead!=2)
1807 return E_FAIL;
1810 * Size
1812 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1814 if (cbRead!=4)
1815 return E_FAIL;
1817 this->description.cySize.s.Hi = 0;
1820 * FontName
1822 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1824 if (cbRead!=1)
1825 return E_FAIL;
1827 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1829 if (cbRead!=bStringSize)
1830 return E_FAIL;
1832 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1834 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1835 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1836 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1837 this->description.lpstrName[len] = 0;
1839 /* Ensure use of this font causes a new one to be created @@@@ */
1840 dec_int_ref(this->gdiFont);
1841 this->gdiFont = 0;
1843 return S_OK;
1846 /************************************************************************
1847 * OLEFontImpl_Save (IPersistStream)
1849 * See Windows documentation for more details on IPersistStream methods.
1851 static HRESULT WINAPI OLEFontImpl_Save(
1852 IPersistStream* iface,
1853 IStream* pOutStream,
1854 BOOL fClearDirty)
1856 char* writeBuffer = NULL;
1857 ULONG cbWritten;
1858 BYTE bVersion = 0x01;
1859 BYTE bAttributes;
1860 BYTE bStringSize;
1862 OLEFontImpl *this = impl_from_IPersistStream(iface);
1865 * Read the version byte
1867 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1869 if (cbWritten!=1)
1870 return E_FAIL;
1873 * Charset
1875 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1877 if (cbWritten!=2)
1878 return E_FAIL;
1881 * Attributes
1883 bAttributes = 0;
1885 if (this->description.fItalic)
1886 bAttributes |= FONTPERSIST_ITALIC;
1888 if (this->description.fStrikethrough)
1889 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1891 if (this->description.fUnderline)
1892 bAttributes |= FONTPERSIST_UNDERLINE;
1894 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1896 if (cbWritten!=1)
1897 return E_FAIL;
1900 * Weight
1902 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1904 if (cbWritten!=2)
1905 return E_FAIL;
1908 * Size
1910 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1912 if (cbWritten!=4)
1913 return E_FAIL;
1916 * FontName
1918 if (this->description.lpstrName!=0)
1919 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1920 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1921 else
1922 bStringSize = 0;
1924 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1926 if (cbWritten!=1)
1927 return E_FAIL;
1929 if (bStringSize!=0)
1931 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1932 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1933 strlenW(this->description.lpstrName),
1934 writeBuffer, bStringSize, NULL, NULL );
1936 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1937 HeapFree(GetProcessHeap(), 0, writeBuffer);
1939 if (cbWritten!=bStringSize)
1940 return E_FAIL;
1943 return S_OK;
1946 /************************************************************************
1947 * OLEFontImpl_GetSizeMax (IPersistStream)
1949 * See Windows documentation for more details on IPersistStream methods.
1951 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1952 IPersistStream* iface,
1953 ULARGE_INTEGER* pcbSize)
1955 OLEFontImpl *this = impl_from_IPersistStream(iface);
1957 if (pcbSize==NULL)
1958 return E_POINTER;
1960 pcbSize->u.HighPart = 0;
1961 pcbSize->u.LowPart = 0;
1963 pcbSize->u.LowPart += sizeof(BYTE); /* Version */
1964 pcbSize->u.LowPart += sizeof(WORD); /* Lang code */
1965 pcbSize->u.LowPart += sizeof(BYTE); /* Flags */
1966 pcbSize->u.LowPart += sizeof(WORD); /* Weight */
1967 pcbSize->u.LowPart += sizeof(DWORD); /* Size */
1968 pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */
1970 if (this->description.lpstrName!=0)
1971 pcbSize->u.LowPart += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1972 strlenW(this->description.lpstrName),
1973 NULL, 0, NULL, NULL );
1975 return S_OK;
1978 static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =
1980 OLEFontImpl_IPersistStream_QueryInterface,
1981 OLEFontImpl_IPersistStream_AddRef,
1982 OLEFontImpl_IPersistStream_Release,
1983 OLEFontImpl_GetClassID,
1984 OLEFontImpl_IsDirty,
1985 OLEFontImpl_Load,
1986 OLEFontImpl_Save,
1987 OLEFontImpl_GetSizeMax
1990 /************************************************************************
1991 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1993 * See Windows documentation for more details on IUnknown methods.
1995 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1996 IConnectionPointContainer* iface,
1997 REFIID riid,
1998 VOID** ppvoid)
2000 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
2002 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
2005 /************************************************************************
2006 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
2008 * See Windows documentation for more details on IUnknown methods.
2010 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
2011 IConnectionPointContainer* iface)
2013 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
2015 return IFont_Release((IFont*)this);
2018 /************************************************************************
2019 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
2021 * See Windows documentation for more details on IUnknown methods.
2023 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
2024 IConnectionPointContainer* iface)
2026 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
2028 return IFont_AddRef((IFont*)this);
2031 /************************************************************************
2032 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
2034 * See Windows documentation for more details on IConnectionPointContainer
2035 * methods.
2037 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
2038 IConnectionPointContainer* iface,
2039 IEnumConnectionPoints **ppEnum)
2041 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
2043 FIXME("(%p)->(%p): stub\n", this, ppEnum);
2044 return E_NOTIMPL;
2047 /************************************************************************
2048 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
2050 * See Windows documentation for more details on IConnectionPointContainer
2051 * methods.
2053 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
2054 IConnectionPointContainer* iface,
2055 REFIID riid,
2056 IConnectionPoint **ppCp)
2058 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
2059 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp);
2061 if(IsEqualIID(riid, &IID_IPropertyNotifySink)) {
2062 return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP,
2063 &IID_IConnectionPoint,
2064 (LPVOID)ppCp);
2065 } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) {
2066 return IConnectionPoint_QueryInterface(this->pFontEventsCP,
2067 &IID_IConnectionPoint,
2068 (LPVOID)ppCp);
2069 } else {
2070 FIXME("no connection point for %s\n", debugstr_guid(riid));
2071 return CONNECT_E_NOCONNECTION;
2075 static const IConnectionPointContainerVtbl
2076 OLEFontImpl_IConnectionPointContainer_VTable =
2078 OLEFontImpl_IConnectionPointContainer_QueryInterface,
2079 OLEFontImpl_IConnectionPointContainer_AddRef,
2080 OLEFontImpl_IConnectionPointContainer_Release,
2081 OLEFontImpl_EnumConnectionPoints,
2082 OLEFontImpl_FindConnectionPoint
2085 /************************************************************************
2086 * OLEFontImpl implementation of IPersistPropertyBag.
2088 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
2089 IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
2091 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2092 return IFont_QueryInterface((IFont *)this,riid,ppvObj);
2095 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
2096 IPersistPropertyBag *iface
2098 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2099 return IFont_AddRef((IFont *)this);
2102 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
2103 IPersistPropertyBag *iface
2105 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2106 return IFont_Release((IFont *)this);
2109 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
2110 IPersistPropertyBag *iface, CLSID *classid
2112 FIXME("(%p,%p), stub!\n", iface, classid);
2113 return E_FAIL;
2116 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
2117 IPersistPropertyBag *iface
2119 FIXME("(%p), stub!\n", iface);
2120 return S_OK;
2123 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
2124 IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
2126 /* (from Visual Basic 6 property bag)
2127 Name = "MS Sans Serif"
2128 Size = 13.8
2129 Charset = 0
2130 Weight = 400
2131 Underline = 0 'False
2132 Italic = 0 'False
2133 Strikethrough = 0 'False
2135 static const WCHAR sAttrName[] = {'N','a','m','e',0};
2136 static const WCHAR sAttrSize[] = {'S','i','z','e',0};
2137 static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0};
2138 static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0};
2139 static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};
2140 static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};
2141 static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
2142 VARIANT rawAttr;
2143 VARIANT valueAttr;
2144 HRESULT iRes = S_OK;
2145 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2147 VariantInit(&rawAttr);
2148 VariantInit(&valueAttr);
2150 if (iRes == S_OK) {
2151 iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog);
2152 if (iRes == S_OK)
2154 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR);
2155 if (iRes == S_OK)
2156 iRes = IFont_put_Name((IFont *)this, V_BSTR(&valueAttr));
2158 else if (iRes == E_INVALIDARG)
2159 iRes = S_OK;
2160 VariantClear(&rawAttr);
2161 VariantClear(&valueAttr);
2164 if (iRes == S_OK) {
2165 iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog);
2166 if (iRes == S_OK)
2168 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY);
2169 if (iRes == S_OK)
2170 iRes = IFont_put_Size((IFont *)this, V_CY(&valueAttr));
2172 else if (iRes == E_INVALIDARG)
2173 iRes = S_OK;
2174 VariantClear(&rawAttr);
2175 VariantClear(&valueAttr);
2178 if (iRes == S_OK) {
2179 iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog);
2180 if (iRes == S_OK)
2182 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
2183 if (iRes == S_OK)
2184 iRes = IFont_put_Charset((IFont *)this, V_I2(&valueAttr));
2186 else if (iRes == E_INVALIDARG)
2187 iRes = S_OK;
2188 VariantClear(&rawAttr);
2189 VariantClear(&valueAttr);
2192 if (iRes == S_OK) {
2193 iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog);
2194 if (iRes == S_OK)
2196 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
2197 if (iRes == S_OK)
2198 iRes = IFont_put_Weight((IFont *)this, V_I2(&valueAttr));
2200 else if (iRes == E_INVALIDARG)
2201 iRes = S_OK;
2202 VariantClear(&rawAttr);
2203 VariantClear(&valueAttr);
2207 if (iRes == S_OK) {
2208 iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog);
2209 if (iRes == S_OK)
2211 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
2212 if (iRes == S_OK)
2213 iRes = IFont_put_Underline((IFont *)this, V_BOOL(&valueAttr));
2215 else if (iRes == E_INVALIDARG)
2216 iRes = S_OK;
2217 VariantClear(&rawAttr);
2218 VariantClear(&valueAttr);
2221 if (iRes == S_OK) {
2222 iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog);
2223 if (iRes == S_OK)
2225 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
2226 if (iRes == S_OK)
2227 iRes = IFont_put_Italic((IFont *)this, V_BOOL(&valueAttr));
2229 else if (iRes == E_INVALIDARG)
2230 iRes = S_OK;
2231 VariantClear(&rawAttr);
2232 VariantClear(&valueAttr);
2235 if (iRes == S_OK) {
2236 iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog);
2237 if (iRes == S_OK)
2239 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
2240 if (iRes == S_OK)
2241 IFont_put_Strikethrough((IFont *)this, V_BOOL(&valueAttr));
2243 else if (iRes == E_INVALIDARG)
2244 iRes = S_OK;
2245 VariantClear(&rawAttr);
2246 VariantClear(&valueAttr);
2249 if (FAILED(iRes))
2250 WARN("-- 0x%08x\n", iRes);
2251 return iRes;
2254 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
2255 IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
2256 BOOL fSaveAllProperties
2258 FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
2259 return E_FAIL;
2262 static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable =
2264 OLEFontImpl_IPersistPropertyBag_QueryInterface,
2265 OLEFontImpl_IPersistPropertyBag_AddRef,
2266 OLEFontImpl_IPersistPropertyBag_Release,
2268 OLEFontImpl_IPersistPropertyBag_GetClassID,
2269 OLEFontImpl_IPersistPropertyBag_InitNew,
2270 OLEFontImpl_IPersistPropertyBag_Load,
2271 OLEFontImpl_IPersistPropertyBag_Save
2274 /************************************************************************
2275 * OLEFontImpl implementation of IPersistStreamInit.
2277 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
2278 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
2280 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2281 return IFont_QueryInterface((IFont *)this,riid,ppvObj);
2284 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
2285 IPersistStreamInit *iface
2287 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2288 return IFont_AddRef((IFont *)this);
2291 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
2292 IPersistStreamInit *iface
2294 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2295 return IFont_Release((IFont *)this);
2298 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
2299 IPersistStreamInit *iface, CLSID *classid
2301 FIXME("(%p,%p), stub!\n", iface, classid);
2302 return E_FAIL;
2305 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
2306 IPersistStreamInit *iface
2308 FIXME("(%p), stub!\n", iface);
2309 return E_FAIL;
2312 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
2313 IPersistStreamInit *iface, LPSTREAM pStm
2315 FIXME("(%p,%p), stub!\n", iface, pStm);
2316 return E_FAIL;
2319 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
2320 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
2322 FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
2323 return E_FAIL;
2326 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
2327 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
2329 FIXME("(%p,%p), stub!\n", iface, pcbSize);
2330 return E_FAIL;
2333 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
2334 IPersistStreamInit *iface
2336 FIXME("(%p), stub!\n", iface);
2337 return S_OK;
2340 static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable =
2342 OLEFontImpl_IPersistStreamInit_QueryInterface,
2343 OLEFontImpl_IPersistStreamInit_AddRef,
2344 OLEFontImpl_IPersistStreamInit_Release,
2346 OLEFontImpl_IPersistStreamInit_GetClassID,
2347 OLEFontImpl_IPersistStreamInit_IsDirty,
2348 OLEFontImpl_IPersistStreamInit_Load,
2349 OLEFontImpl_IPersistStreamInit_Save,
2350 OLEFontImpl_IPersistStreamInit_GetSizeMax,
2351 OLEFontImpl_IPersistStreamInit_InitNew
2354 /************************************************************************
2355 * OLEFontImpl_Construct
2357 * This method will construct a new instance of the OLEFontImpl
2358 * class.
2360 * The caller of this method must release the object when it's
2361 * done with it.
2363 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
2365 OLEFontImpl* newObject = 0;
2368 * Allocate space for the object.
2370 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
2372 if (newObject==0)
2373 return newObject;
2376 * Initialize the virtual function table.
2378 newObject->lpVtbl = &OLEFontImpl_VTable;
2379 newObject->lpvtblIDispatch = &OLEFontImpl_IDispatch_VTable;
2380 newObject->lpvtblIPersistStream = &OLEFontImpl_IPersistStream_VTable;
2381 newObject->lpvtblIConnectionPointContainer = &OLEFontImpl_IConnectionPointContainer_VTable;
2382 newObject->lpvtblIPersistPropertyBag = &OLEFontImpl_IPersistPropertyBag_VTable;
2383 newObject->lpvtblIPersistStreamInit = &OLEFontImpl_IPersistStreamInit_VTable;
2386 * Start with one reference count. The caller of this function
2387 * must release the interface pointer when it is done.
2389 newObject->ref = 1;
2392 * Copy the description of the font in the object.
2394 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
2396 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
2397 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
2399 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
2400 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
2401 newObject->description.cySize = fontDesc->cySize;
2402 newObject->description.sWeight = fontDesc->sWeight;
2403 newObject->description.sCharset = fontDesc->sCharset;
2404 newObject->description.fItalic = fontDesc->fItalic;
2405 newObject->description.fUnderline = fontDesc->fUnderline;
2406 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
2409 * Initializing all the other members.
2411 newObject->gdiFont = 0;
2412 newObject->dirty = TRUE;
2413 newObject->cyLogical = 72L;
2414 newObject->cyHimetric = 2540L;
2415 newObject->pPropertyNotifyCP = NULL;
2416 newObject->pFontEventsCP = NULL;
2418 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
2419 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
2421 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
2423 OLEFontImpl_Destroy(newObject);
2424 return NULL;
2427 InterlockedIncrement(&ifont_cnt);
2429 TRACE("returning %p\n", newObject);
2430 return newObject;
2433 /************************************************************************
2434 * OLEFontImpl_Destroy
2436 * This method is called by the Release method when the reference
2437 * count goes down to 0. It will free all resources used by
2438 * this object.
2440 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
2442 TRACE("(%p)\n", fontDesc);
2444 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
2446 if (fontDesc->pPropertyNotifyCP)
2447 IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
2448 if (fontDesc->pFontEventsCP)
2449 IConnectionPoint_Release(fontDesc->pFontEventsCP);
2451 HeapFree(GetProcessHeap(), 0, fontDesc);
2454 /*******************************************************************************
2455 * StdFont ClassFactory
2457 typedef struct
2459 /* IUnknown fields */
2460 const IClassFactoryVtbl *lpVtbl;
2461 LONG ref;
2462 } IClassFactoryImpl;
2464 static HRESULT WINAPI
2465 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
2466 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2468 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
2469 return E_NOINTERFACE;
2472 static ULONG WINAPI
2473 SFCF_AddRef(LPCLASSFACTORY iface) {
2474 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2475 return InterlockedIncrement(&This->ref);
2478 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
2479 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2480 /* static class, won't be freed */
2481 return InterlockedDecrement(&This->ref);
2484 static HRESULT WINAPI SFCF_CreateInstance(
2485 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
2487 return OleCreateFontIndirect(NULL,riid,ppobj);
2491 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
2492 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2493 FIXME("(%p)->(%d),stub!\n",This,dolock);
2494 return S_OK;
2497 static const IClassFactoryVtbl SFCF_Vtbl = {
2498 SFCF_QueryInterface,
2499 SFCF_AddRef,
2500 SFCF_Release,
2501 SFCF_CreateInstance,
2502 SFCF_LockServer
2504 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
2506 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; }