oleaut32: Realize the font in getter functions.
[wine/hramrach.git] / dlls / oleaut32 / olefont.c
blobc0d9b66a7f6c4bd1dd6139463926aa1c4eb9a474
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
57 /***********************************************************************
58 * List of the HFONTs it has given out, with each one having a separate
59 * ref count.
61 typedef struct _HFONTItem
63 struct list entry;
65 /* Reference count of any IFont objects that own this hfont */
66 LONG int_refs;
68 /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
69 LONG total_refs;
71 /* The font associated with this object. */
72 HFONT gdiFont;
74 } HFONTItem, *PHFONTItem;
76 static struct list OLEFontImpl_hFontList = LIST_INIT(OLEFontImpl_hFontList);
78 /* Counts how many fonts contain at least one lock */
79 static LONG ifont_cnt = 0;
81 /***********************************************************************
82 * Critical section for OLEFontImpl_hFontList
84 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST;
85 static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
87 0, 0, &OLEFontImpl_csHFONTLIST,
88 { &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList,
89 &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList },
90 0, 0, { (DWORD_PTR)(__FILE__ ": OLEFontImpl_csHFONTLIST") }
92 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
94 static void HFONTItem_Delete(PHFONTItem item)
96 DeleteObject(item->gdiFont);
97 list_remove(&item->entry);
98 HeapFree(GetProcessHeap(), 0, item);
101 /* Find hfont item entry in the list. Should be called while holding the crit sect */
102 static HFONTItem *find_hfontitem(HFONT hfont)
104 HFONTItem *item;
106 LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry)
108 if (item->gdiFont == hfont)
109 return item;
111 return NULL;
114 /* Add an item to the list with one internal reference */
115 static HRESULT add_hfontitem(HFONT hfont)
117 HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item));
119 if(!new_item) return E_OUTOFMEMORY;
121 new_item->int_refs = 1;
122 new_item->total_refs = 1;
123 new_item->gdiFont = hfont;
124 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
125 list_add_tail(&OLEFontImpl_hFontList,&new_item->entry);
126 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
127 return S_OK;
130 static HRESULT inc_int_ref(HFONT hfont)
132 HFONTItem *item;
133 HRESULT hr = S_FALSE;
135 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
136 item = find_hfontitem(hfont);
138 if(item)
140 item->int_refs++;
141 item->total_refs++;
142 hr = S_OK;
144 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
146 return hr;
149 /* decrements the internal ref of a hfont item. If both refs are zero it'll
150 remove the item from the list and delete the hfont */
151 static HRESULT dec_int_ref(HFONT hfont)
153 HFONTItem *item;
154 HRESULT hr = S_FALSE;
156 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
157 item = find_hfontitem(hfont);
159 if(item)
161 item->int_refs--;
162 item->total_refs--;
163 if(item->int_refs == 0 && item->total_refs == 0)
164 HFONTItem_Delete(item);
165 hr = S_OK;
167 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
169 return hr;
172 static HRESULT inc_ext_ref(HFONT hfont)
174 HFONTItem *item;
175 HRESULT hr = S_FALSE;
177 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
179 item = find_hfontitem(hfont);
180 if(item)
182 item->total_refs++;
183 hr = S_OK;
185 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
187 return hr;
190 static HRESULT dec_ext_ref(HFONT hfont)
192 HFONTItem *item;
193 HRESULT hr = S_FALSE;
195 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
197 item = find_hfontitem(hfont);
198 if(item)
200 if(--item->total_refs >= 0) hr = S_OK;
202 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
204 return hr;
207 /***********************************************************************
208 * Declaration of the implementation class for the IFont interface
210 typedef struct OLEFontImpl OLEFontImpl;
212 struct OLEFontImpl
215 * This class supports many interfaces. IUnknown, IFont,
216 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
217 * The first two are supported by the first vtable, the next two are
218 * supported by the second table and the last two have their own.
220 const IFontVtbl* lpVtbl;
221 const IDispatchVtbl* lpvtblIDispatch;
222 const IPersistStreamVtbl* lpvtblIPersistStream;
223 const IConnectionPointContainerVtbl* lpvtblIConnectionPointContainer;
224 const IPersistPropertyBagVtbl* lpvtblIPersistPropertyBag;
225 const IPersistStreamInitVtbl* lpvtblIPersistStreamInit;
227 * Reference count for that instance of the class.
229 LONG ref;
232 * This structure contains the description of the class.
234 FONTDESC description;
237 * Contain the font associated with this object.
239 HFONT gdiFont;
240 BOOL dirty;
242 * Size ratio
244 LONG cyLogical;
245 LONG cyHimetric;
247 IConnectionPoint *pPropertyNotifyCP;
248 IConnectionPoint *pFontEventsCP;
252 * Here, I define utility macros to help with the casting of the
253 * "this" parameter.
254 * There is a version to accommodate all of the VTables implemented
255 * by this object.
258 static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface )
260 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIDispatch));
263 static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface )
265 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStream));
268 static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
270 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIConnectionPointContainer));
273 static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface )
275 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistPropertyBag));
278 static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface )
280 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStreamInit));
284 /***********************************************************************
285 * Prototypes for the implementation functions for the IFont
286 * interface
288 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc);
289 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
290 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
292 /******************************************************************************
293 * OleCreateFontIndirect [OLEAUT32.420]
295 HRESULT WINAPI OleCreateFontIndirect(
296 LPFONTDESC lpFontDesc,
297 REFIID riid,
298 LPVOID* ppvObj)
300 OLEFontImpl* newFont = 0;
301 HRESULT hr = S_OK;
303 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
305 * Sanity check
307 if (ppvObj==0)
308 return E_POINTER;
310 *ppvObj = 0;
312 if (!lpFontDesc) {
313 FONTDESC fd;
315 static WCHAR fname[] = { 'S','y','s','t','e','m',0 };
317 fd.cbSizeofstruct = sizeof(fd);
318 fd.lpstrName = fname;
319 fd.cySize.s.Lo = 80000;
320 fd.cySize.s.Hi = 0;
321 fd.sWeight = 0;
322 fd.sCharset = 0;
323 fd.fItalic = 0;
324 fd.fUnderline = 0;
325 fd.fStrikethrough = 0;
326 lpFontDesc = &fd;
330 * Try to construct a new instance of the class.
332 newFont = OLEFontImpl_Construct(lpFontDesc);
334 if (newFont == 0)
335 return E_OUTOFMEMORY;
338 * Make sure it supports the interface required by the caller.
340 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
343 * Release the reference obtained in the constructor. If
344 * the QueryInterface was unsuccessful, it will free the class.
346 IFont_Release((IFont*)newFont);
348 return hr;
352 /***********************************************************************
353 * Implementation of the OLEFontImpl class.
356 /***********************************************************************
357 * OLEFont_SendNotify (internal)
359 * Sends notification messages of changed properties to any interested
360 * connections.
362 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
364 static const WCHAR wszName[] = {'N','a','m','e',0};
365 static const WCHAR wszSize[] = {'S','i','z','e',0};
366 static const WCHAR wszBold[] = {'B','o','l','d',0};
367 static const WCHAR wszItalic[] = {'I','t','a','l','i','c',0};
368 static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0};
369 static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
370 static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0};
371 static const WCHAR wszCharset[] = {'C','h','a','r','s','s','e','t',0};
372 static const LPCWSTR dispid_mapping[] =
374 wszName,
375 NULL,
376 wszSize,
377 wszBold,
378 wszItalic,
379 wszUnder,
380 wszStrike,
381 wszWeight,
382 wszCharset
385 IEnumConnections *pEnum;
386 CONNECTDATA CD;
387 HRESULT hres;
389 this->dirty = TRUE;
391 hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
392 if (SUCCEEDED(hres))
394 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
395 IPropertyNotifySink *sink;
397 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
398 IPropertyNotifySink_OnChanged(sink, dispID);
399 IPropertyNotifySink_Release(sink);
400 IUnknown_Release(CD.pUnk);
402 IEnumConnections_Release(pEnum);
405 hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum);
406 if (SUCCEEDED(hres))
408 DISPPARAMS dispparams;
409 VARIANTARG vararg;
411 VariantInit(&vararg);
412 V_VT(&vararg) = VT_BSTR;
413 V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]);
415 dispparams.cArgs = 1;
416 dispparams.cNamedArgs = 0;
417 dispparams.rgdispidNamedArgs = NULL;
418 dispparams.rgvarg = &vararg;
420 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
421 IFontEventsDisp *disp;
423 IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp);
424 IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
425 LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
426 NULL, NULL);
428 IDispatch_Release(disp);
429 IUnknown_Release(CD.pUnk);
431 VariantClear(&vararg);
432 IEnumConnections_Release(pEnum);
436 /************************************************************************
437 * OLEFontImpl_QueryInterface (IUnknown)
439 * See Windows documentation for more details on IUnknown methods.
441 static HRESULT WINAPI OLEFontImpl_QueryInterface(
442 IFont* iface,
443 REFIID riid,
444 void** ppvObject)
446 OLEFontImpl *this = (OLEFontImpl *)iface;
447 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
450 * Perform a sanity check on the parameters.
452 if ( (this==0) || (ppvObject==0) )
453 return E_INVALIDARG;
456 * Initialize the return parameter.
458 *ppvObject = 0;
461 * Compare the riid with the interface IDs implemented by this object.
463 if (IsEqualGUID(&IID_IUnknown, riid))
464 *ppvObject = this;
465 if (IsEqualGUID(&IID_IFont, riid))
466 *ppvObject = this;
467 if (IsEqualGUID(&IID_IDispatch, riid))
468 *ppvObject = &this->lpvtblIDispatch;
469 if (IsEqualGUID(&IID_IFontDisp, riid))
470 *ppvObject = &this->lpvtblIDispatch;
471 if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid))
472 *ppvObject = &this->lpvtblIPersistStream;
473 if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
474 *ppvObject = &this->lpvtblIConnectionPointContainer;
475 if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
476 *ppvObject = &this->lpvtblIPersistPropertyBag;
477 if (IsEqualGUID(&IID_IPersistStreamInit, riid))
478 *ppvObject = &this->lpvtblIPersistStreamInit;
481 * Check that we obtained an interface.
483 if ((*ppvObject)==0)
485 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
486 return E_NOINTERFACE;
488 OLEFontImpl_AddRef((IFont*)this);
489 return S_OK;
492 /************************************************************************
493 * OLEFontImpl_AddRef (IUnknown)
495 * See Windows documentation for more details on IUnknown methods.
497 static ULONG WINAPI OLEFontImpl_AddRef(
498 IFont* iface)
500 OLEFontImpl *this = (OLEFontImpl *)iface;
501 TRACE("(%p)->(ref=%d)\n", this, this->ref);
502 return InterlockedIncrement(&this->ref);
505 /************************************************************************
506 * OLEFontImpl_Release (IUnknown)
508 * See Windows documentation for more details on IUnknown methods.
510 static ULONG WINAPI OLEFontImpl_Release(
511 IFont* iface)
513 OLEFontImpl *this = (OLEFontImpl *)iface;
514 ULONG ret;
515 TRACE("(%p)->(ref=%d)\n", this, this->ref);
517 /* Decrease the reference count for current interface */
518 ret = InterlockedDecrement(&this->ref);
520 /* If the reference count goes down to 0, destroy. */
521 if (ret == 0)
523 ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
525 /* Final IFont object so destroy font cache */
526 if (fontlist_refs == 0)
528 HFONTItem *item, *cursor2;
530 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
531 LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry)
532 HFONTItem_Delete(item);
533 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
535 else
537 dec_int_ref(this->gdiFont);
539 OLEFontImpl_Destroy(this);
542 return ret;
545 static void realize_font(OLEFontImpl *This)
547 if (This->dirty)
549 LOGFONTW logFont;
550 INT fontHeight;
552 if(This->gdiFont)
554 dec_int_ref(This->gdiFont);
555 This->gdiFont = 0;
559 * The height of the font returned by the get_Size property is the
560 * height of the font in points multiplied by 10000... Using some
561 * simple conversions and the ratio given by the application, it can
562 * be converted to a height in pixels.
565 /* Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. */
566 /* Ratio is applied here relative to the standard. */
567 fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
569 memset(&logFont, 0, sizeof(LOGFONTW));
571 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
572 (-fontHeight/10000L);
573 logFont.lfItalic = This->description.fItalic;
574 logFont.lfUnderline = This->description.fUnderline;
575 logFont.lfStrikeOut = This->description.fStrikethrough;
576 logFont.lfWeight = This->description.sWeight;
577 logFont.lfCharSet = This->description.sCharset;
578 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
579 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
580 logFont.lfQuality = DEFAULT_QUALITY;
581 logFont.lfPitchAndFamily = DEFAULT_PITCH;
582 lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
584 This->gdiFont = CreateFontIndirectW(&logFont);
585 This->dirty = FALSE;
587 add_hfontitem(This->gdiFont);
591 /************************************************************************
592 * OLEFontImpl_get_Name (IFont)
594 * See Windows documentation for more details on IFont methods.
596 static HRESULT WINAPI OLEFontImpl_get_Name(
597 IFont* iface,
598 BSTR* pname)
600 OLEFontImpl *this = (OLEFontImpl *)iface;
601 TRACE("(%p)->(%p)\n", this, pname);
603 * Sanity check.
605 if (pname==0)
606 return E_POINTER;
608 if(this->dirty) realize_font(this);
610 if (this->description.lpstrName!=0)
611 *pname = SysAllocString(this->description.lpstrName);
612 else
613 *pname = 0;
615 return S_OK;
618 /************************************************************************
619 * OLEFontImpl_put_Name (IFont)
621 * See Windows documentation for more details on IFont methods.
623 static HRESULT WINAPI OLEFontImpl_put_Name(
624 IFont* iface,
625 BSTR name)
627 OLEFontImpl *this = (OLEFontImpl *)iface;
628 TRACE("(%p)->(%p)\n", this, name);
630 if (!name)
631 return CTL_E_INVALIDPROPERTYVALUE;
633 if (this->description.lpstrName==0)
635 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
637 (lstrlenW(name)+1) * sizeof(WCHAR));
639 else
641 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
643 this->description.lpstrName,
644 (lstrlenW(name)+1) * sizeof(WCHAR));
647 if (this->description.lpstrName==0)
648 return E_OUTOFMEMORY;
650 strcpyW(this->description.lpstrName, name);
651 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
652 OLEFont_SendNotify(this, DISPID_FONT_NAME);
653 return S_OK;
656 /************************************************************************
657 * OLEFontImpl_get_Size (IFont)
659 * See Windows documentation for more details on IFont methods.
661 static HRESULT WINAPI OLEFontImpl_get_Size(
662 IFont* iface,
663 CY* psize)
665 OLEFontImpl *this = (OLEFontImpl *)iface;
666 TRACE("(%p)->(%p)\n", this, psize);
669 * Sanity check
671 if (psize==0)
672 return E_POINTER;
674 if(this->dirty) realize_font(this);
676 psize->s.Hi = 0;
677 psize->s.Lo = this->description.cySize.s.Lo;
679 return S_OK;
682 /************************************************************************
683 * OLEFontImpl_put_Size (IFont)
685 * See Windows documentation for more details on IFont methods.
687 static HRESULT WINAPI OLEFontImpl_put_Size(
688 IFont* iface,
689 CY size)
691 OLEFontImpl *this = (OLEFontImpl *)iface;
692 TRACE("(%p)->(%d)\n", this, size.s.Lo);
693 this->description.cySize.s.Hi = 0;
694 this->description.cySize.s.Lo = size.s.Lo;
695 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
697 return S_OK;
700 /************************************************************************
701 * OLEFontImpl_get_Bold (IFont)
703 * See Windows documentation for more details on IFont methods.
705 static HRESULT WINAPI OLEFontImpl_get_Bold(
706 IFont* iface,
707 BOOL* pbold)
709 OLEFontImpl *this = (OLEFontImpl *)iface;
710 TRACE("(%p)->(%p)\n", this, pbold);
712 * Sanity check
714 if (pbold==0)
715 return E_POINTER;
717 if(this->dirty) realize_font(this);
719 *pbold = this->description.sWeight > 550;
721 return S_OK;
724 /************************************************************************
725 * OLEFontImpl_put_Bold (IFont)
727 * See Windows documentation for more details on IFont methods.
729 static HRESULT WINAPI OLEFontImpl_put_Bold(
730 IFont* iface,
731 BOOL bold)
733 OLEFontImpl *this = (OLEFontImpl *)iface;
734 TRACE("(%p)->(%d)\n", this, bold);
735 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
736 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
738 return S_OK;
741 /************************************************************************
742 * OLEFontImpl_get_Italic (IFont)
744 * See Windows documentation for more details on IFont methods.
746 static HRESULT WINAPI OLEFontImpl_get_Italic(
747 IFont* iface,
748 BOOL* pitalic)
750 OLEFontImpl *this = (OLEFontImpl *)iface;
751 TRACE("(%p)->(%p)\n", this, pitalic);
753 * Sanity check
755 if (pitalic==0)
756 return E_POINTER;
758 if(this->dirty) realize_font(this);
760 *pitalic = this->description.fItalic;
762 return S_OK;
765 /************************************************************************
766 * OLEFontImpl_put_Italic (IFont)
768 * See Windows documentation for more details on IFont methods.
770 static HRESULT WINAPI OLEFontImpl_put_Italic(
771 IFont* iface,
772 BOOL italic)
774 OLEFontImpl *this = (OLEFontImpl *)iface;
775 TRACE("(%p)->(%d)\n", this, italic);
777 this->description.fItalic = italic;
779 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
780 return S_OK;
783 /************************************************************************
784 * OLEFontImpl_get_Underline (IFont)
786 * See Windows documentation for more details on IFont methods.
788 static HRESULT WINAPI OLEFontImpl_get_Underline(
789 IFont* iface,
790 BOOL* punderline)
792 OLEFontImpl *this = (OLEFontImpl *)iface;
793 TRACE("(%p)->(%p)\n", this, punderline);
796 * Sanity check
798 if (punderline==0)
799 return E_POINTER;
801 if(this->dirty) realize_font(this);
803 *punderline = this->description.fUnderline;
805 return S_OK;
808 /************************************************************************
809 * OLEFontImpl_put_Underline (IFont)
811 * See Windows documentation for more details on IFont methods.
813 static HRESULT WINAPI OLEFontImpl_put_Underline(
814 IFont* iface,
815 BOOL underline)
817 OLEFontImpl *this = (OLEFontImpl *)iface;
818 TRACE("(%p)->(%d)\n", this, underline);
820 this->description.fUnderline = underline;
822 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
823 return S_OK;
826 /************************************************************************
827 * OLEFontImpl_get_Strikethrough (IFont)
829 * See Windows documentation for more details on IFont methods.
831 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
832 IFont* iface,
833 BOOL* pstrikethrough)
835 OLEFontImpl *this = (OLEFontImpl *)iface;
836 TRACE("(%p)->(%p)\n", this, pstrikethrough);
839 * Sanity check
841 if (pstrikethrough==0)
842 return E_POINTER;
844 if(this->dirty) realize_font(this);
846 *pstrikethrough = this->description.fStrikethrough;
848 return S_OK;
851 /************************************************************************
852 * OLEFontImpl_put_Strikethrough (IFont)
854 * See Windows documentation for more details on IFont methods.
856 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
857 IFont* iface,
858 BOOL strikethrough)
860 OLEFontImpl *this = (OLEFontImpl *)iface;
861 TRACE("(%p)->(%d)\n", this, strikethrough);
863 this->description.fStrikethrough = strikethrough;
864 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
866 return S_OK;
869 /************************************************************************
870 * OLEFontImpl_get_Weight (IFont)
872 * See Windows documentation for more details on IFont methods.
874 static HRESULT WINAPI OLEFontImpl_get_Weight(
875 IFont* iface,
876 short* pweight)
878 OLEFontImpl *this = (OLEFontImpl *)iface;
879 TRACE("(%p)->(%p)\n", this, pweight);
882 * Sanity check
884 if (pweight==0)
885 return E_POINTER;
887 if(this->dirty) realize_font(this);
889 *pweight = this->description.sWeight;
891 return S_OK;
894 /************************************************************************
895 * OLEFontImpl_put_Weight (IFont)
897 * See Windows documentation for more details on IFont methods.
899 static HRESULT WINAPI OLEFontImpl_put_Weight(
900 IFont* iface,
901 short weight)
903 OLEFontImpl *this = (OLEFontImpl *)iface;
904 TRACE("(%p)->(%d)\n", this, weight);
906 this->description.sWeight = weight;
908 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
909 return S_OK;
912 /************************************************************************
913 * OLEFontImpl_get_Charset (IFont)
915 * See Windows documentation for more details on IFont methods.
917 static HRESULT WINAPI OLEFontImpl_get_Charset(
918 IFont* iface,
919 short* pcharset)
921 OLEFontImpl *this = (OLEFontImpl *)iface;
922 TRACE("(%p)->(%p)\n", this, pcharset);
925 * Sanity check
927 if (pcharset==0)
928 return E_POINTER;
930 if(this->dirty) realize_font(this);
932 *pcharset = this->description.sCharset;
934 return S_OK;
937 /************************************************************************
938 * OLEFontImpl_put_Charset (IFont)
940 * See Windows documentation for more details on IFont methods.
942 static HRESULT WINAPI OLEFontImpl_put_Charset(
943 IFont* iface,
944 short charset)
946 OLEFontImpl *this = (OLEFontImpl *)iface;
947 TRACE("(%p)->(%d)\n", this, charset);
949 this->description.sCharset = charset;
950 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
952 return S_OK;
955 /************************************************************************
956 * OLEFontImpl_get_hFont (IFont)
958 * See Windows documentation for more details on IFont methods.
960 static HRESULT WINAPI OLEFontImpl_get_hFont(
961 IFont* iface,
962 HFONT* phfont)
964 OLEFontImpl *this = (OLEFontImpl *)iface;
965 TRACE("(%p)->(%p)\n", this, phfont);
966 if (phfont==NULL)
967 return E_POINTER;
969 if(this->dirty) realize_font(this);
971 *phfont = this->gdiFont;
972 TRACE("Returning %p\n", *phfont);
973 return S_OK;
976 /************************************************************************
977 * OLEFontImpl_Clone (IFont)
979 * See Windows documentation for more details on IFont methods.
981 static HRESULT WINAPI OLEFontImpl_Clone(
982 IFont* iface,
983 IFont** ppfont)
985 OLEFontImpl* newObject = 0;
986 OLEFontImpl *this = (OLEFontImpl *)iface;
988 TRACE("(%p)->(%p)\n", this, ppfont);
990 if (ppfont == NULL)
991 return E_POINTER;
993 *ppfont = NULL;
996 * Allocate space for the object.
998 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
1000 if (newObject==NULL)
1001 return E_OUTOFMEMORY;
1003 *newObject = *this;
1005 /* We need to alloc new memory for the string, otherwise
1006 * we free memory twice.
1008 newObject->description.lpstrName = HeapAlloc(
1009 GetProcessHeap(),0,
1010 (1+strlenW(this->description.lpstrName))*2
1012 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
1015 /* Increment internal ref in hfont item list */
1016 if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
1018 InterlockedIncrement(&ifont_cnt);
1020 /* create new connection points */
1021 newObject->pPropertyNotifyCP = NULL;
1022 newObject->pFontEventsCP = NULL;
1023 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
1024 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
1026 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
1028 OLEFontImpl_Destroy(newObject);
1029 return E_OUTOFMEMORY;
1032 /* The cloned object starts with a reference count of 1 */
1033 newObject->ref = 1;
1035 *ppfont = (IFont*)newObject;
1037 return S_OK;
1040 /************************************************************************
1041 * OLEFontImpl_IsEqual (IFont)
1043 * See Windows documentation for more details on IFont methods.
1045 static HRESULT WINAPI OLEFontImpl_IsEqual(
1046 IFont* iface,
1047 IFont* pFontOther)
1049 OLEFontImpl *left = (OLEFontImpl *)iface;
1050 OLEFontImpl *right = (OLEFontImpl *)pFontOther;
1051 INT ret;
1052 INT left_len,right_len;
1054 if((iface == NULL) || (pFontOther == NULL))
1055 return E_POINTER;
1056 else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo)
1057 return S_FALSE;
1058 else if (left->description.cySize.s.Hi != right->description.cySize.s.Hi)
1059 return S_FALSE;
1060 else if (left->description.sWeight != right->description.sWeight)
1061 return S_FALSE;
1062 else if (left->description.sCharset != right->description.sCharset)
1063 return S_FALSE;
1064 else if (left->description.fItalic != right->description.fItalic)
1065 return S_FALSE;
1066 else if (left->description.fUnderline != right->description.fUnderline)
1067 return S_FALSE;
1068 else if (left->description.fStrikethrough != right->description.fStrikethrough)
1069 return S_FALSE;
1071 /* Check from string */
1072 left_len = strlenW(left->description.lpstrName);
1073 right_len = strlenW(right->description.lpstrName);
1074 ret = CompareStringW(0,0,left->description.lpstrName, left_len,
1075 right->description.lpstrName, right_len);
1076 if (ret != CSTR_EQUAL)
1077 return S_FALSE;
1079 return S_OK;
1082 /************************************************************************
1083 * OLEFontImpl_SetRatio (IFont)
1085 * See Windows documentation for more details on IFont methods.
1087 static HRESULT WINAPI OLEFontImpl_SetRatio(
1088 IFont* iface,
1089 LONG cyLogical,
1090 LONG cyHimetric)
1092 OLEFontImpl *this = (OLEFontImpl *)iface;
1093 TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric);
1095 this->cyLogical = cyLogical;
1096 this->cyHimetric = cyHimetric;
1098 return S_OK;
1101 /************************************************************************
1102 * OLEFontImpl_QueryTextMetrics (IFont)
1104 * See Windows documentation for more details on IFont methods.
1106 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1107 IFont* iface,
1108 TEXTMETRICOLE* ptm)
1110 HDC hdcRef;
1111 HFONT hOldFont, hNewFont;
1113 hdcRef = GetDC(0);
1114 OLEFontImpl_get_hFont(iface, &hNewFont);
1115 hOldFont = SelectObject(hdcRef, hNewFont);
1116 GetTextMetricsW(hdcRef, ptm);
1117 SelectObject(hdcRef, hOldFont);
1118 ReleaseDC(0, hdcRef);
1119 return S_OK;
1122 /************************************************************************
1123 * OLEFontImpl_AddRefHfont (IFont)
1125 * See Windows documentation for more details on IFont methods.
1127 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1128 IFont* iface,
1129 HFONT hfont)
1131 OLEFontImpl *this = (OLEFontImpl *)iface;
1133 TRACE("(%p)->(%p)\n", this, hfont);
1135 if (!hfont) return E_INVALIDARG;
1137 return inc_ext_ref(hfont);
1140 /************************************************************************
1141 * OLEFontImpl_ReleaseHfont (IFont)
1143 * See Windows documentation for more details on IFont methods.
1145 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1146 IFont* iface,
1147 HFONT hfont)
1149 OLEFontImpl *this = (OLEFontImpl *)iface;
1151 TRACE("(%p)->(%p)\n", this, hfont);
1153 if (!hfont) return E_INVALIDARG;
1155 return dec_ext_ref(hfont);
1158 /************************************************************************
1159 * OLEFontImpl_SetHdc (IFont)
1161 * See Windows documentation for more details on IFont methods.
1163 static HRESULT WINAPI OLEFontImpl_SetHdc(
1164 IFont* iface,
1165 HDC hdc)
1167 OLEFontImpl *this = (OLEFontImpl *)iface;
1168 FIXME("(%p)->(%p): Stub\n", this, hdc);
1169 return E_NOTIMPL;
1173 * Virtual function tables for the OLEFontImpl class.
1175 static const IFontVtbl OLEFontImpl_VTable =
1177 OLEFontImpl_QueryInterface,
1178 OLEFontImpl_AddRef,
1179 OLEFontImpl_Release,
1180 OLEFontImpl_get_Name,
1181 OLEFontImpl_put_Name,
1182 OLEFontImpl_get_Size,
1183 OLEFontImpl_put_Size,
1184 OLEFontImpl_get_Bold,
1185 OLEFontImpl_put_Bold,
1186 OLEFontImpl_get_Italic,
1187 OLEFontImpl_put_Italic,
1188 OLEFontImpl_get_Underline,
1189 OLEFontImpl_put_Underline,
1190 OLEFontImpl_get_Strikethrough,
1191 OLEFontImpl_put_Strikethrough,
1192 OLEFontImpl_get_Weight,
1193 OLEFontImpl_put_Weight,
1194 OLEFontImpl_get_Charset,
1195 OLEFontImpl_put_Charset,
1196 OLEFontImpl_get_hFont,
1197 OLEFontImpl_Clone,
1198 OLEFontImpl_IsEqual,
1199 OLEFontImpl_SetRatio,
1200 OLEFontImpl_QueryTextMetrics,
1201 OLEFontImpl_AddRefHfont,
1202 OLEFontImpl_ReleaseHfont,
1203 OLEFontImpl_SetHdc
1206 /************************************************************************
1207 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1209 * See Windows documentation for more details on IUnknown methods.
1211 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1212 IDispatch* iface,
1213 REFIID riid,
1214 VOID** ppvoid)
1216 OLEFontImpl *this = impl_from_IDispatch(iface);
1218 return IFont_QueryInterface((IFont *)this, riid, ppvoid);
1221 /************************************************************************
1222 * OLEFontImpl_IDispatch_Release (IUnknown)
1224 * See Windows documentation for more details on IUnknown methods.
1226 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1227 IDispatch* iface)
1229 OLEFontImpl *this = impl_from_IDispatch(iface);
1231 return IFont_Release((IFont *)this);
1234 /************************************************************************
1235 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1237 * See Windows documentation for more details on IUnknown methods.
1239 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1240 IDispatch* iface)
1242 OLEFontImpl *this = impl_from_IDispatch(iface);
1244 return IFont_AddRef((IFont *)this);
1247 /************************************************************************
1248 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1250 * See Windows documentation for more details on IDispatch methods.
1252 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1253 IDispatch* iface,
1254 unsigned int* pctinfo)
1256 OLEFontImpl *this = impl_from_IDispatch(iface);
1257 TRACE("(%p)->(%p)\n", this, pctinfo);
1258 *pctinfo = 1;
1260 return S_OK;
1263 /************************************************************************
1264 * OLEFontImpl_GetTypeInfo (IDispatch)
1266 * See Windows documentation for more details on IDispatch methods.
1268 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1269 IDispatch* iface,
1270 UINT iTInfo,
1271 LCID lcid,
1272 ITypeInfo** ppTInfo)
1274 static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
1275 ITypeLib *tl;
1276 HRESULT hres;
1278 OLEFontImpl *this = impl_from_IDispatch(iface);
1279 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);
1280 if (iTInfo != 0)
1281 return E_FAIL;
1282 hres = LoadTypeLib(stdole2tlb, &tl);
1283 if (FAILED(hres)) {
1284 ERR("Could not load the stdole2.tlb?\n");
1285 return hres;
1287 hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IFontDisp, ppTInfo);
1288 ITypeLib_Release(tl);
1289 if (FAILED(hres)) {
1290 FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres);
1292 return hres;
1295 /************************************************************************
1296 * OLEFontImpl_GetIDsOfNames (IDispatch)
1298 * See Windows documentation for more details on IDispatch methods.
1300 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1301 IDispatch* iface,
1302 REFIID riid,
1303 LPOLESTR* rgszNames,
1304 UINT cNames,
1305 LCID lcid,
1306 DISPID* rgDispId)
1308 ITypeInfo * pTInfo;
1309 HRESULT hres;
1311 OLEFontImpl *this = impl_from_IDispatch(iface);
1313 TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid),
1314 rgszNames, cNames, (int)lcid, rgDispId);
1316 if (cNames == 0)
1318 return E_INVALIDARG;
1320 else
1322 /* retrieve type information */
1323 hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo);
1325 if (FAILED(hres))
1327 ERR("GetTypeInfo failed.\n");
1328 return hres;
1331 /* convert names to DISPIDs */
1332 hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId);
1333 ITypeInfo_Release(pTInfo);
1335 return hres;
1339 /************************************************************************
1340 * OLEFontImpl_Invoke (IDispatch)
1342 * See Windows documentation for more details on IDispatch methods.
1344 * Note: Do not call _put_Xxx methods, since setting things here
1345 * should not call notify functions as I found out debugging the generic
1346 * MS VB5 installer.
1348 static HRESULT WINAPI OLEFontImpl_Invoke(
1349 IDispatch* iface,
1350 DISPID dispIdMember,
1351 REFIID riid,
1352 LCID lcid,
1353 WORD wFlags,
1354 DISPPARAMS* pDispParams,
1355 VARIANT* pVarResult,
1356 EXCEPINFO* pExepInfo,
1357 UINT* puArgErr)
1359 OLEFontImpl *this = impl_from_IDispatch(iface);
1360 HRESULT hr;
1362 TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember,
1363 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExepInfo,
1364 puArgErr);
1366 /* validate parameters */
1368 if (!IsEqualIID(riid, &IID_NULL))
1370 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
1371 return DISP_E_UNKNOWNINTERFACE;
1374 if (wFlags & DISPATCH_PROPERTYGET)
1376 if (!pVarResult)
1378 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1379 return DISP_E_PARAMNOTOPTIONAL;
1382 else if (wFlags & DISPATCH_PROPERTYPUT)
1384 if (!pDispParams)
1386 ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n");
1387 return DISP_E_PARAMNOTOPTIONAL;
1389 if (pDispParams->cArgs != 1)
1391 ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs);
1392 return DISP_E_BADPARAMCOUNT;
1395 else
1397 ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n");
1398 return DISP_E_MEMBERNOTFOUND;
1401 switch (dispIdMember) {
1402 case DISPID_FONT_NAME:
1403 if (wFlags & DISPATCH_PROPERTYGET) {
1404 V_VT(pVarResult) = VT_BSTR;
1405 return IFont_get_Name((IFont *)this, &V_BSTR(pVarResult));
1406 } else {
1407 VARIANTARG vararg;
1409 VariantInit(&vararg);
1410 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BSTR);
1411 if (FAILED(hr))
1412 return hr;
1414 hr = IFont_put_Name((IFont *)this, V_BSTR(&vararg));
1416 VariantClear(&vararg);
1417 return hr;
1419 break;
1420 case DISPID_FONT_BOLD:
1421 if (wFlags & DISPATCH_PROPERTYGET) {
1422 BOOL value;
1423 hr = IFont_get_Bold((IFont *)this, &value);
1424 V_VT(pVarResult) = VT_BOOL;
1425 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1426 return hr;
1427 } else {
1428 VARIANTARG vararg;
1430 VariantInit(&vararg);
1431 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1432 if (FAILED(hr))
1433 return hr;
1435 hr = IFont_put_Bold((IFont *)this, V_BOOL(&vararg));
1437 VariantClear(&vararg);
1438 return hr;
1440 break;
1441 case DISPID_FONT_ITALIC:
1442 if (wFlags & DISPATCH_PROPERTYGET) {
1443 BOOL value;
1444 hr = IFont_get_Italic((IFont *)this, &value);
1445 V_VT(pVarResult) = VT_BOOL;
1446 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1447 return hr;
1448 } else {
1449 VARIANTARG vararg;
1451 VariantInit(&vararg);
1452 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1453 if (FAILED(hr))
1454 return hr;
1456 hr = IFont_put_Italic((IFont *)this, V_BOOL(&vararg));
1458 VariantClear(&vararg);
1459 return hr;
1461 break;
1462 case DISPID_FONT_UNDER:
1463 if (wFlags & DISPATCH_PROPERTYGET) {
1464 BOOL value;
1465 hr = IFont_get_Underline((IFont *)this, &value);
1466 V_VT(pVarResult) = VT_BOOL;
1467 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1468 return hr;
1469 } else {
1470 VARIANTARG vararg;
1472 VariantInit(&vararg);
1473 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1474 if (FAILED(hr))
1475 return hr;
1477 hr = IFont_put_Underline((IFont *)this, V_BOOL(&vararg));
1479 VariantClear(&vararg);
1480 return hr;
1482 break;
1483 case DISPID_FONT_STRIKE:
1484 if (wFlags & DISPATCH_PROPERTYGET) {
1485 BOOL value;
1486 hr = IFont_get_Strikethrough((IFont *)this, &value);
1487 V_VT(pVarResult) = VT_BOOL;
1488 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1489 return hr;
1490 } else {
1491 VARIANTARG vararg;
1493 VariantInit(&vararg);
1494 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1495 if (FAILED(hr))
1496 return hr;
1498 hr = IFont_put_Strikethrough((IFont *)this, V_BOOL(&vararg));
1500 VariantClear(&vararg);
1501 return hr;
1503 break;
1504 case DISPID_FONT_SIZE:
1505 if (wFlags & DISPATCH_PROPERTYGET) {
1506 V_VT(pVarResult) = VT_CY;
1507 return OLEFontImpl_get_Size((IFont *)this, &V_CY(pVarResult));
1508 } else {
1509 VARIANTARG vararg;
1511 VariantInit(&vararg);
1512 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_CY);
1513 if (FAILED(hr))
1514 return hr;
1516 hr = IFont_put_Size((IFont *)this, V_CY(&vararg));
1518 VariantClear(&vararg);
1519 return hr;
1521 break;
1522 case DISPID_FONT_WEIGHT:
1523 if (wFlags & DISPATCH_PROPERTYGET) {
1524 V_VT(pVarResult) = VT_I2;
1525 return OLEFontImpl_get_Weight((IFont *)this, &V_I2(pVarResult));
1526 } else {
1527 VARIANTARG vararg;
1529 VariantInit(&vararg);
1530 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1531 if (FAILED(hr))
1532 return hr;
1534 hr = IFont_put_Weight((IFont *)this, V_I2(&vararg));
1536 VariantClear(&vararg);
1537 return hr;
1539 break;
1540 case DISPID_FONT_CHARSET:
1541 if (wFlags & DISPATCH_PROPERTYGET) {
1542 V_VT(pVarResult) = VT_I2;
1543 return OLEFontImpl_get_Charset((IFont *)this, &V_I2(pVarResult));
1544 } else {
1545 VARIANTARG vararg;
1547 VariantInit(&vararg);
1548 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1549 if (FAILED(hr))
1550 return hr;
1552 hr = IFont_put_Charset((IFont *)this, V_I2(&vararg));
1554 VariantClear(&vararg);
1555 return hr;
1557 break;
1558 default:
1559 ERR("member not found for dispid 0x%x\n", dispIdMember);
1560 return DISP_E_MEMBERNOTFOUND;
1564 static const IDispatchVtbl OLEFontImpl_IDispatch_VTable =
1566 OLEFontImpl_IDispatch_QueryInterface,
1567 OLEFontImpl_IDispatch_AddRef,
1568 OLEFontImpl_IDispatch_Release,
1569 OLEFontImpl_GetTypeInfoCount,
1570 OLEFontImpl_GetTypeInfo,
1571 OLEFontImpl_GetIDsOfNames,
1572 OLEFontImpl_Invoke
1575 /************************************************************************
1576 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1578 * See Windows documentation for more details on IUnknown methods.
1580 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1581 IPersistStream* iface,
1582 REFIID riid,
1583 VOID** ppvoid)
1585 OLEFontImpl *this = impl_from_IPersistStream(iface);
1587 return IFont_QueryInterface((IFont *)this, riid, ppvoid);
1590 /************************************************************************
1591 * OLEFontImpl_IPersistStream_Release (IUnknown)
1593 * See Windows documentation for more details on IUnknown methods.
1595 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1596 IPersistStream* iface)
1598 OLEFontImpl *this = impl_from_IPersistStream(iface);
1600 return IFont_Release((IFont *)this);
1603 /************************************************************************
1604 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1606 * See Windows documentation for more details on IUnknown methods.
1608 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1609 IPersistStream* iface)
1611 OLEFontImpl *this = impl_from_IPersistStream(iface);
1613 return IFont_AddRef((IFont *)this);
1616 /************************************************************************
1617 * OLEFontImpl_GetClassID (IPersistStream)
1619 * See Windows documentation for more details on IPersistStream methods.
1621 static HRESULT WINAPI OLEFontImpl_GetClassID(
1622 IPersistStream* iface,
1623 CLSID* pClassID)
1625 TRACE("(%p,%p)\n",iface,pClassID);
1626 if (pClassID==0)
1627 return E_POINTER;
1629 *pClassID = CLSID_StdFont;
1631 return S_OK;
1634 /************************************************************************
1635 * OLEFontImpl_IsDirty (IPersistStream)
1637 * See Windows documentation for more details on IPersistStream methods.
1639 static HRESULT WINAPI OLEFontImpl_IsDirty(
1640 IPersistStream* iface)
1642 TRACE("(%p)\n",iface);
1643 return S_OK;
1646 /************************************************************************
1647 * OLEFontImpl_Load (IPersistStream)
1649 * See Windows documentation for more details on IPersistStream methods.
1651 * This is the format of the standard font serialization as far as I
1652 * know
1654 * Offset Type Value Comment
1655 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1656 * 0x0001 Short Charset Charset value from the FONTDESC structure
1657 * 0x0003 Byte Attributes Flags defined as follows:
1658 * 00000010 - Italic
1659 * 00000100 - Underline
1660 * 00001000 - Strikethrough
1661 * 0x0004 Short Weight Weight value from FONTDESC structure
1662 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1663 * structure/
1664 * 0x000A Byte name length Length of the font name string (no null character)
1665 * 0x000B String name Name of the font (ASCII, no nul character)
1667 static HRESULT WINAPI OLEFontImpl_Load(
1668 IPersistStream* iface,
1669 IStream* pLoadStream)
1671 char readBuffer[0x100];
1672 ULONG cbRead;
1673 BYTE bVersion;
1674 BYTE bAttributes;
1675 BYTE bStringSize;
1676 INT len;
1678 OLEFontImpl *this = impl_from_IPersistStream(iface);
1681 * Read the version byte
1683 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1685 if ( (cbRead!=1) ||
1686 (bVersion!=0x01) )
1687 return E_FAIL;
1690 * Charset
1692 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1694 if (cbRead!=2)
1695 return E_FAIL;
1698 * Attributes
1700 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1702 if (cbRead!=1)
1703 return E_FAIL;
1705 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1706 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1707 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1710 * Weight
1712 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1714 if (cbRead!=2)
1715 return E_FAIL;
1718 * Size
1720 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1722 if (cbRead!=4)
1723 return E_FAIL;
1725 this->description.cySize.s.Hi = 0;
1728 * FontName
1730 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1732 if (cbRead!=1)
1733 return E_FAIL;
1735 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1737 if (cbRead!=bStringSize)
1738 return E_FAIL;
1740 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1742 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1743 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1744 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1745 this->description.lpstrName[len] = 0;
1747 /* Ensure use of this font causes a new one to be created @@@@ */
1748 dec_int_ref(this->gdiFont);
1749 this->gdiFont = 0;
1751 return S_OK;
1754 /************************************************************************
1755 * OLEFontImpl_Save (IPersistStream)
1757 * See Windows documentation for more details on IPersistStream methods.
1759 static HRESULT WINAPI OLEFontImpl_Save(
1760 IPersistStream* iface,
1761 IStream* pOutStream,
1762 BOOL fClearDirty)
1764 char* writeBuffer = NULL;
1765 ULONG cbWritten;
1766 BYTE bVersion = 0x01;
1767 BYTE bAttributes;
1768 BYTE bStringSize;
1770 OLEFontImpl *this = impl_from_IPersistStream(iface);
1773 * Read the version byte
1775 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1777 if (cbWritten!=1)
1778 return E_FAIL;
1781 * Charset
1783 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1785 if (cbWritten!=2)
1786 return E_FAIL;
1789 * Attributes
1791 bAttributes = 0;
1793 if (this->description.fItalic)
1794 bAttributes |= FONTPERSIST_ITALIC;
1796 if (this->description.fStrikethrough)
1797 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1799 if (this->description.fUnderline)
1800 bAttributes |= FONTPERSIST_UNDERLINE;
1802 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1804 if (cbWritten!=1)
1805 return E_FAIL;
1808 * Weight
1810 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1812 if (cbWritten!=2)
1813 return E_FAIL;
1816 * Size
1818 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1820 if (cbWritten!=4)
1821 return E_FAIL;
1824 * FontName
1826 if (this->description.lpstrName!=0)
1827 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1828 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1829 else
1830 bStringSize = 0;
1832 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1834 if (cbWritten!=1)
1835 return E_FAIL;
1837 if (bStringSize!=0)
1839 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1840 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1841 strlenW(this->description.lpstrName),
1842 writeBuffer, bStringSize, NULL, NULL );
1844 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1845 HeapFree(GetProcessHeap(), 0, writeBuffer);
1847 if (cbWritten!=bStringSize)
1848 return E_FAIL;
1851 return S_OK;
1854 /************************************************************************
1855 * OLEFontImpl_GetSizeMax (IPersistStream)
1857 * See Windows documentation for more details on IPersistStream methods.
1859 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1860 IPersistStream* iface,
1861 ULARGE_INTEGER* pcbSize)
1863 OLEFontImpl *this = impl_from_IPersistStream(iface);
1865 if (pcbSize==NULL)
1866 return E_POINTER;
1868 pcbSize->u.HighPart = 0;
1869 pcbSize->u.LowPart = 0;
1871 pcbSize->u.LowPart += sizeof(BYTE); /* Version */
1872 pcbSize->u.LowPart += sizeof(WORD); /* Lang code */
1873 pcbSize->u.LowPart += sizeof(BYTE); /* Flags */
1874 pcbSize->u.LowPart += sizeof(WORD); /* Weight */
1875 pcbSize->u.LowPart += sizeof(DWORD); /* Size */
1876 pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */
1878 if (this->description.lpstrName!=0)
1879 pcbSize->u.LowPart += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1880 strlenW(this->description.lpstrName),
1881 NULL, 0, NULL, NULL );
1883 return S_OK;
1886 static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =
1888 OLEFontImpl_IPersistStream_QueryInterface,
1889 OLEFontImpl_IPersistStream_AddRef,
1890 OLEFontImpl_IPersistStream_Release,
1891 OLEFontImpl_GetClassID,
1892 OLEFontImpl_IsDirty,
1893 OLEFontImpl_Load,
1894 OLEFontImpl_Save,
1895 OLEFontImpl_GetSizeMax
1898 /************************************************************************
1899 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1901 * See Windows documentation for more details on IUnknown methods.
1903 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1904 IConnectionPointContainer* iface,
1905 REFIID riid,
1906 VOID** ppvoid)
1908 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1910 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1913 /************************************************************************
1914 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1916 * See Windows documentation for more details on IUnknown methods.
1918 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1919 IConnectionPointContainer* iface)
1921 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1923 return IFont_Release((IFont*)this);
1926 /************************************************************************
1927 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1929 * See Windows documentation for more details on IUnknown methods.
1931 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1932 IConnectionPointContainer* iface)
1934 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1936 return IFont_AddRef((IFont*)this);
1939 /************************************************************************
1940 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1942 * See Windows documentation for more details on IConnectionPointContainer
1943 * methods.
1945 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1946 IConnectionPointContainer* iface,
1947 IEnumConnectionPoints **ppEnum)
1949 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1951 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1952 return E_NOTIMPL;
1955 /************************************************************************
1956 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1958 * See Windows documentation for more details on IConnectionPointContainer
1959 * methods.
1961 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1962 IConnectionPointContainer* iface,
1963 REFIID riid,
1964 IConnectionPoint **ppCp)
1966 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
1967 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp);
1969 if(IsEqualIID(riid, &IID_IPropertyNotifySink)) {
1970 return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP,
1971 &IID_IConnectionPoint,
1972 (LPVOID)ppCp);
1973 } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) {
1974 return IConnectionPoint_QueryInterface(this->pFontEventsCP,
1975 &IID_IConnectionPoint,
1976 (LPVOID)ppCp);
1977 } else {
1978 FIXME("no connection point for %s\n", debugstr_guid(riid));
1979 return CONNECT_E_NOCONNECTION;
1983 static const IConnectionPointContainerVtbl
1984 OLEFontImpl_IConnectionPointContainer_VTable =
1986 OLEFontImpl_IConnectionPointContainer_QueryInterface,
1987 OLEFontImpl_IConnectionPointContainer_AddRef,
1988 OLEFontImpl_IConnectionPointContainer_Release,
1989 OLEFontImpl_EnumConnectionPoints,
1990 OLEFontImpl_FindConnectionPoint
1993 /************************************************************************
1994 * OLEFontImpl implementation of IPersistPropertyBag.
1996 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
1997 IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
1999 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2000 return IFont_QueryInterface((IFont *)this,riid,ppvObj);
2003 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
2004 IPersistPropertyBag *iface
2006 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2007 return IFont_AddRef((IFont *)this);
2010 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
2011 IPersistPropertyBag *iface
2013 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2014 return IFont_Release((IFont *)this);
2017 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
2018 IPersistPropertyBag *iface, CLSID *classid
2020 FIXME("(%p,%p), stub!\n", iface, classid);
2021 return E_FAIL;
2024 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
2025 IPersistPropertyBag *iface
2027 FIXME("(%p), stub!\n", iface);
2028 return S_OK;
2031 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
2032 IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
2034 /* (from Visual Basic 6 property bag)
2035 Name = "MS Sans Serif"
2036 Size = 13.8
2037 Charset = 0
2038 Weight = 400
2039 Underline = 0 'False
2040 Italic = 0 'False
2041 Strikethrough = 0 'False
2043 static const WCHAR sAttrName[] = {'N','a','m','e',0};
2044 static const WCHAR sAttrSize[] = {'S','i','z','e',0};
2045 static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0};
2046 static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0};
2047 static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};
2048 static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};
2049 static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
2050 VARIANT rawAttr;
2051 VARIANT valueAttr;
2052 HRESULT iRes = S_OK;
2053 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2055 VariantInit(&rawAttr);
2056 VariantInit(&valueAttr);
2058 if (iRes == S_OK) {
2059 iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog);
2060 if (iRes == S_OK)
2062 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR);
2063 if (iRes == S_OK)
2064 iRes = IFont_put_Name((IFont *)this, V_BSTR(&valueAttr));
2066 else if (iRes == E_INVALIDARG)
2067 iRes = S_OK;
2068 VariantClear(&rawAttr);
2069 VariantClear(&valueAttr);
2072 if (iRes == S_OK) {
2073 iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog);
2074 if (iRes == S_OK)
2076 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY);
2077 if (iRes == S_OK)
2078 iRes = IFont_put_Size((IFont *)this, V_CY(&valueAttr));
2080 else if (iRes == E_INVALIDARG)
2081 iRes = S_OK;
2082 VariantClear(&rawAttr);
2083 VariantClear(&valueAttr);
2086 if (iRes == S_OK) {
2087 iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog);
2088 if (iRes == S_OK)
2090 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
2091 if (iRes == S_OK)
2092 iRes = IFont_put_Charset((IFont *)this, V_I2(&valueAttr));
2094 else if (iRes == E_INVALIDARG)
2095 iRes = S_OK;
2096 VariantClear(&rawAttr);
2097 VariantClear(&valueAttr);
2100 if (iRes == S_OK) {
2101 iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog);
2102 if (iRes == S_OK)
2104 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
2105 if (iRes == S_OK)
2106 iRes = IFont_put_Weight((IFont *)this, V_I2(&valueAttr));
2108 else if (iRes == E_INVALIDARG)
2109 iRes = S_OK;
2110 VariantClear(&rawAttr);
2111 VariantClear(&valueAttr);
2115 if (iRes == S_OK) {
2116 iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog);
2117 if (iRes == S_OK)
2119 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
2120 if (iRes == S_OK)
2121 iRes = IFont_put_Underline((IFont *)this, V_BOOL(&valueAttr));
2123 else if (iRes == E_INVALIDARG)
2124 iRes = S_OK;
2125 VariantClear(&rawAttr);
2126 VariantClear(&valueAttr);
2129 if (iRes == S_OK) {
2130 iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog);
2131 if (iRes == S_OK)
2133 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
2134 if (iRes == S_OK)
2135 iRes = IFont_put_Italic((IFont *)this, V_BOOL(&valueAttr));
2137 else if (iRes == E_INVALIDARG)
2138 iRes = S_OK;
2139 VariantClear(&rawAttr);
2140 VariantClear(&valueAttr);
2143 if (iRes == S_OK) {
2144 iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog);
2145 if (iRes == S_OK)
2147 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
2148 if (iRes == S_OK)
2149 IFont_put_Strikethrough((IFont *)this, V_BOOL(&valueAttr));
2151 else if (iRes == E_INVALIDARG)
2152 iRes = S_OK;
2153 VariantClear(&rawAttr);
2154 VariantClear(&valueAttr);
2157 if (FAILED(iRes))
2158 WARN("-- 0x%08x\n", iRes);
2159 return iRes;
2162 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
2163 IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
2164 BOOL fSaveAllProperties
2166 FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
2167 return E_FAIL;
2170 static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable =
2172 OLEFontImpl_IPersistPropertyBag_QueryInterface,
2173 OLEFontImpl_IPersistPropertyBag_AddRef,
2174 OLEFontImpl_IPersistPropertyBag_Release,
2176 OLEFontImpl_IPersistPropertyBag_GetClassID,
2177 OLEFontImpl_IPersistPropertyBag_InitNew,
2178 OLEFontImpl_IPersistPropertyBag_Load,
2179 OLEFontImpl_IPersistPropertyBag_Save
2182 /************************************************************************
2183 * OLEFontImpl implementation of IPersistStreamInit.
2185 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
2186 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
2188 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2189 return IFont_QueryInterface((IFont *)this,riid,ppvObj);
2192 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
2193 IPersistStreamInit *iface
2195 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2196 return IFont_AddRef((IFont *)this);
2199 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
2200 IPersistStreamInit *iface
2202 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
2203 return IFont_Release((IFont *)this);
2206 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
2207 IPersistStreamInit *iface, CLSID *classid
2209 FIXME("(%p,%p), stub!\n", iface, classid);
2210 return E_FAIL;
2213 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
2214 IPersistStreamInit *iface
2216 FIXME("(%p), stub!\n", iface);
2217 return E_FAIL;
2220 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
2221 IPersistStreamInit *iface, LPSTREAM pStm
2223 FIXME("(%p,%p), stub!\n", iface, pStm);
2224 return E_FAIL;
2227 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
2228 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
2230 FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
2231 return E_FAIL;
2234 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
2235 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
2237 FIXME("(%p,%p), stub!\n", iface, pcbSize);
2238 return E_FAIL;
2241 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
2242 IPersistStreamInit *iface
2244 FIXME("(%p), stub!\n", iface);
2245 return S_OK;
2248 static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable =
2250 OLEFontImpl_IPersistStreamInit_QueryInterface,
2251 OLEFontImpl_IPersistStreamInit_AddRef,
2252 OLEFontImpl_IPersistStreamInit_Release,
2254 OLEFontImpl_IPersistStreamInit_GetClassID,
2255 OLEFontImpl_IPersistStreamInit_IsDirty,
2256 OLEFontImpl_IPersistStreamInit_Load,
2257 OLEFontImpl_IPersistStreamInit_Save,
2258 OLEFontImpl_IPersistStreamInit_GetSizeMax,
2259 OLEFontImpl_IPersistStreamInit_InitNew
2262 /************************************************************************
2263 * OLEFontImpl_Construct
2265 * This method will construct a new instance of the OLEFontImpl
2266 * class.
2268 * The caller of this method must release the object when it's
2269 * done with it.
2271 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
2273 OLEFontImpl* newObject = 0;
2276 * Allocate space for the object.
2278 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
2280 if (newObject==0)
2281 return newObject;
2284 * Initialize the virtual function table.
2286 newObject->lpVtbl = &OLEFontImpl_VTable;
2287 newObject->lpvtblIDispatch = &OLEFontImpl_IDispatch_VTable;
2288 newObject->lpvtblIPersistStream = &OLEFontImpl_IPersistStream_VTable;
2289 newObject->lpvtblIConnectionPointContainer = &OLEFontImpl_IConnectionPointContainer_VTable;
2290 newObject->lpvtblIPersistPropertyBag = &OLEFontImpl_IPersistPropertyBag_VTable;
2291 newObject->lpvtblIPersistStreamInit = &OLEFontImpl_IPersistStreamInit_VTable;
2294 * Start with one reference count. The caller of this function
2295 * must release the interface pointer when it is done.
2297 newObject->ref = 1;
2300 * Copy the description of the font in the object.
2302 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
2304 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
2305 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
2307 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
2308 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
2309 newObject->description.cySize = fontDesc->cySize;
2310 newObject->description.sWeight = fontDesc->sWeight;
2311 newObject->description.sCharset = fontDesc->sCharset;
2312 newObject->description.fItalic = fontDesc->fItalic;
2313 newObject->description.fUnderline = fontDesc->fUnderline;
2314 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
2317 * Initializing all the other members.
2319 newObject->gdiFont = 0;
2320 newObject->dirty = TRUE;
2321 newObject->cyLogical = 72L;
2322 newObject->cyHimetric = 2540L;
2323 newObject->pPropertyNotifyCP = NULL;
2324 newObject->pFontEventsCP = NULL;
2326 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
2327 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
2329 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
2331 OLEFontImpl_Destroy(newObject);
2332 return NULL;
2335 InterlockedIncrement(&ifont_cnt);
2337 TRACE("returning %p\n", newObject);
2338 return newObject;
2341 /************************************************************************
2342 * OLEFontImpl_Destroy
2344 * This method is called by the Release method when the reference
2345 * count goes down to 0. It will free all resources used by
2346 * this object.
2348 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
2350 TRACE("(%p)\n", fontDesc);
2352 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
2354 if (fontDesc->pPropertyNotifyCP)
2355 IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
2356 if (fontDesc->pFontEventsCP)
2357 IConnectionPoint_Release(fontDesc->pFontEventsCP);
2359 HeapFree(GetProcessHeap(), 0, fontDesc);
2362 /*******************************************************************************
2363 * StdFont ClassFactory
2365 typedef struct
2367 /* IUnknown fields */
2368 const IClassFactoryVtbl *lpVtbl;
2369 LONG ref;
2370 } IClassFactoryImpl;
2372 static HRESULT WINAPI
2373 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
2374 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2376 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
2377 return E_NOINTERFACE;
2380 static ULONG WINAPI
2381 SFCF_AddRef(LPCLASSFACTORY iface) {
2382 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2383 return InterlockedIncrement(&This->ref);
2386 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
2387 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2388 /* static class, won't be freed */
2389 return InterlockedDecrement(&This->ref);
2392 static HRESULT WINAPI SFCF_CreateInstance(
2393 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
2395 return OleCreateFontIndirect(NULL,riid,ppobj);
2399 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
2400 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
2401 FIXME("(%p)->(%d),stub!\n",This,dolock);
2402 return S_OK;
2405 static const IClassFactoryVtbl SFCF_Vtbl = {
2406 SFCF_QueryInterface,
2407 SFCF_AddRef,
2408 SFCF_Release,
2409 SFCF_CreateInstance,
2410 SFCF_LockServer
2412 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
2414 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; }