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
29 #define NONAMELESSUNION
30 #define NONAMELESSSTRUCT
37 #include "wine/list.h"
38 #include "wine/unicode.h"
40 #include "oleauto.h" /* for SysAllocString(....) */
43 #include "wine/debug.h"
44 #include "connpt.h" /* for CreateConnectionPoint */
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
61 typedef struct _HFONTItem
65 /* Reference count of any IFont objects that own this hfont */
68 /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
71 /* The font associated with this object. */
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
)
106 LIST_FOR_EACH_ENTRY(item
, &OLEFontImpl_hFontList
, HFONTItem
, entry
)
108 if (item
->gdiFont
== hfont
)
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
);
130 static HRESULT
inc_int_ref(HFONT hfont
)
133 HRESULT hr
= S_FALSE
;
135 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
136 item
= find_hfontitem(hfont
);
144 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
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
)
154 HRESULT hr
= S_FALSE
;
156 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
157 item
= find_hfontitem(hfont
);
163 if(item
->int_refs
== 0 && item
->total_refs
== 0)
164 HFONTItem_Delete(item
);
167 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
172 static HRESULT
inc_ext_ref(HFONT hfont
)
175 HRESULT hr
= S_FALSE
;
177 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
179 item
= find_hfontitem(hfont
);
185 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
190 static HRESULT
dec_ext_ref(HFONT hfont
)
193 HRESULT hr
= S_FALSE
;
195 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
197 item
= find_hfontitem(hfont
);
200 if(--item
->total_refs
>= 0) hr
= S_OK
;
202 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
207 /***********************************************************************
208 * Declaration of the implementation class for the IFont interface
210 typedef struct OLEFontImpl 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.
232 * This structure contains the description of the class.
234 FONTDESC description
;
237 * Contain the font associated with this object.
247 IConnectionPoint
*pPropertyNotifyCP
;
248 IConnectionPoint
*pFontEventsCP
;
252 * Here, I define utility macros to help with the casting of the
254 * There is a version to accommodate all of the VTables implemented
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
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
,
300 OLEFontImpl
* newFont
= 0;
303 TRACE("(%p, %s, %p)\n", lpFontDesc
, debugstr_guid(riid
), ppvObj
);
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;
325 fd
.fStrikethrough
= 0;
330 * Try to construct a new instance of the class.
332 newFont
= OLEFontImpl_Construct(lpFontDesc
);
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
);
352 /***********************************************************************
353 * Implementation of the OLEFontImpl class.
356 /***********************************************************************
357 * OLEFont_SendNotify (internal)
359 * Sends notification messages of changed properties to any interested
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
[] =
385 IEnumConnections
*pEnum
;
391 hres
= IConnectionPoint_EnumConnections(this->pPropertyNotifyCP
, &pEnum
);
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
);
408 DISPPARAMS dispparams
;
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
,
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(
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) )
456 * Initialize the return parameter.
461 * Compare the riid with the interface IDs implemented by this object.
463 if (IsEqualGUID(&IID_IUnknown
, riid
))
465 if (IsEqualGUID(&IID_IFont
, riid
))
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.
485 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid
));
486 return E_NOINTERFACE
;
488 OLEFontImpl_AddRef((IFont
*)this);
492 /************************************************************************
493 * OLEFontImpl_AddRef (IUnknown)
495 * See Windows documentation for more details on IUnknown methods.
497 static ULONG WINAPI
OLEFontImpl_AddRef(
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(
513 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
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. */
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
);
537 dec_int_ref(this->gdiFont
);
539 OLEFontImpl_Destroy(this);
545 static void realize_font(OLEFontImpl
*This
)
554 dec_int_ref(This
->gdiFont
);
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
);
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(
600 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
601 TRACE("(%p)->(%p)\n", this, pname
);
608 if(this->dirty
) realize_font(this);
610 if (this->description
.lpstrName
!=0)
611 *pname
= SysAllocString(this->description
.lpstrName
);
618 /************************************************************************
619 * OLEFontImpl_put_Name (IFont)
621 * See Windows documentation for more details on IFont methods.
623 static HRESULT WINAPI
OLEFontImpl_put_Name(
627 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
628 TRACE("(%p)->(%p)\n", this, name
);
631 return CTL_E_INVALIDPROPERTYVALUE
;
633 if (this->description
.lpstrName
==0)
635 this->description
.lpstrName
= HeapAlloc(GetProcessHeap(),
637 (lstrlenW(name
)+1) * sizeof(WCHAR
));
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
);
656 /************************************************************************
657 * OLEFontImpl_get_Size (IFont)
659 * See Windows documentation for more details on IFont methods.
661 static HRESULT WINAPI
OLEFontImpl_get_Size(
665 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
666 TRACE("(%p)->(%p)\n", this, psize
);
674 if(this->dirty
) realize_font(this);
677 psize
->s
.Lo
= this->description
.cySize
.s
.Lo
;
682 /************************************************************************
683 * OLEFontImpl_put_Size (IFont)
685 * See Windows documentation for more details on IFont methods.
687 static HRESULT WINAPI
OLEFontImpl_put_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
);
700 /************************************************************************
701 * OLEFontImpl_get_Bold (IFont)
703 * See Windows documentation for more details on IFont methods.
705 static HRESULT WINAPI
OLEFontImpl_get_Bold(
709 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
710 TRACE("(%p)->(%p)\n", this, pbold
);
717 if(this->dirty
) realize_font(this);
719 *pbold
= this->description
.sWeight
> 550;
724 /************************************************************************
725 * OLEFontImpl_put_Bold (IFont)
727 * See Windows documentation for more details on IFont methods.
729 static HRESULT WINAPI
OLEFontImpl_put_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
);
741 /************************************************************************
742 * OLEFontImpl_get_Italic (IFont)
744 * See Windows documentation for more details on IFont methods.
746 static HRESULT WINAPI
OLEFontImpl_get_Italic(
750 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
751 TRACE("(%p)->(%p)\n", this, pitalic
);
758 if(this->dirty
) realize_font(this);
760 *pitalic
= this->description
.fItalic
;
765 /************************************************************************
766 * OLEFontImpl_put_Italic (IFont)
768 * See Windows documentation for more details on IFont methods.
770 static HRESULT WINAPI
OLEFontImpl_put_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
);
783 /************************************************************************
784 * OLEFontImpl_get_Underline (IFont)
786 * See Windows documentation for more details on IFont methods.
788 static HRESULT WINAPI
OLEFontImpl_get_Underline(
792 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
793 TRACE("(%p)->(%p)\n", this, punderline
);
801 if(this->dirty
) realize_font(this);
803 *punderline
= this->description
.fUnderline
;
808 /************************************************************************
809 * OLEFontImpl_put_Underline (IFont)
811 * See Windows documentation for more details on IFont methods.
813 static HRESULT WINAPI
OLEFontImpl_put_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
);
826 /************************************************************************
827 * OLEFontImpl_get_Strikethrough (IFont)
829 * See Windows documentation for more details on IFont methods.
831 static HRESULT WINAPI
OLEFontImpl_get_Strikethrough(
833 BOOL
* pstrikethrough
)
835 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
836 TRACE("(%p)->(%p)\n", this, pstrikethrough
);
841 if (pstrikethrough
==0)
844 if(this->dirty
) realize_font(this);
846 *pstrikethrough
= this->description
.fStrikethrough
;
851 /************************************************************************
852 * OLEFontImpl_put_Strikethrough (IFont)
854 * See Windows documentation for more details on IFont methods.
856 static HRESULT WINAPI
OLEFontImpl_put_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
);
869 /************************************************************************
870 * OLEFontImpl_get_Weight (IFont)
872 * See Windows documentation for more details on IFont methods.
874 static HRESULT WINAPI
OLEFontImpl_get_Weight(
878 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
879 TRACE("(%p)->(%p)\n", this, pweight
);
887 if(this->dirty
) realize_font(this);
889 *pweight
= this->description
.sWeight
;
894 /************************************************************************
895 * OLEFontImpl_put_Weight (IFont)
897 * See Windows documentation for more details on IFont methods.
899 static HRESULT WINAPI
OLEFontImpl_put_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
);
912 /************************************************************************
913 * OLEFontImpl_get_Charset (IFont)
915 * See Windows documentation for more details on IFont methods.
917 static HRESULT WINAPI
OLEFontImpl_get_Charset(
921 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
922 TRACE("(%p)->(%p)\n", this, pcharset
);
930 if(this->dirty
) realize_font(this);
932 *pcharset
= this->description
.sCharset
;
937 /************************************************************************
938 * OLEFontImpl_put_Charset (IFont)
940 * See Windows documentation for more details on IFont methods.
942 static HRESULT WINAPI
OLEFontImpl_put_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
);
955 /************************************************************************
956 * OLEFontImpl_get_hFont (IFont)
958 * See Windows documentation for more details on IFont methods.
960 static HRESULT WINAPI
OLEFontImpl_get_hFont(
964 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
965 TRACE("(%p)->(%p)\n", this, phfont
);
969 if(this->dirty
) realize_font(this);
971 *phfont
= this->gdiFont
;
972 TRACE("Returning %p\n", *phfont
);
976 /************************************************************************
977 * OLEFontImpl_Clone (IFont)
979 * See Windows documentation for more details on IFont methods.
981 static HRESULT WINAPI
OLEFontImpl_Clone(
985 OLEFontImpl
* newObject
= 0;
986 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
988 TRACE("(%p)->(%p)\n", this, ppfont
);
996 * Allocate space for the object.
998 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl
));
1000 if (newObject
==NULL
)
1001 return E_OUTOFMEMORY
;
1005 /* We need to alloc new memory for the string, otherwise
1006 * we free memory twice.
1008 newObject
->description
.lpstrName
= HeapAlloc(
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 */
1035 *ppfont
= (IFont
*)newObject
;
1040 /************************************************************************
1041 * OLEFontImpl_IsEqual (IFont)
1043 * See Windows documentation for more details on IFont methods.
1045 static HRESULT WINAPI
OLEFontImpl_IsEqual(
1049 OLEFontImpl
*left
= (OLEFontImpl
*)iface
;
1050 OLEFontImpl
*right
= (OLEFontImpl
*)pFontOther
;
1052 INT left_len
,right_len
;
1054 if((iface
== NULL
) || (pFontOther
== NULL
))
1056 else if (left
->description
.cySize
.s
.Lo
!= right
->description
.cySize
.s
.Lo
)
1058 else if (left
->description
.cySize
.s
.Hi
!= right
->description
.cySize
.s
.Hi
)
1060 else if (left
->description
.sWeight
!= right
->description
.sWeight
)
1062 else if (left
->description
.sCharset
!= right
->description
.sCharset
)
1064 else if (left
->description
.fItalic
!= right
->description
.fItalic
)
1066 else if (left
->description
.fUnderline
!= right
->description
.fUnderline
)
1068 else if (left
->description
.fStrikethrough
!= right
->description
.fStrikethrough
)
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
)
1082 /************************************************************************
1083 * OLEFontImpl_SetRatio (IFont)
1085 * See Windows documentation for more details on IFont methods.
1087 static HRESULT WINAPI
OLEFontImpl_SetRatio(
1092 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
1093 TRACE("(%p)->(%d, %d)\n", this, cyLogical
, cyHimetric
);
1095 this->cyLogical
= cyLogical
;
1096 this->cyHimetric
= cyHimetric
;
1101 /************************************************************************
1102 * OLEFontImpl_QueryTextMetrics (IFont)
1104 * See Windows documentation for more details on IFont methods.
1106 static HRESULT WINAPI
OLEFontImpl_QueryTextMetrics(
1111 HFONT hOldFont
, hNewFont
;
1114 OLEFontImpl_get_hFont(iface
, &hNewFont
);
1115 hOldFont
= SelectObject(hdcRef
, hNewFont
);
1116 GetTextMetricsW(hdcRef
, ptm
);
1117 SelectObject(hdcRef
, hOldFont
);
1118 ReleaseDC(0, hdcRef
);
1122 /************************************************************************
1123 * OLEFontImpl_AddRefHfont (IFont)
1125 * See Windows documentation for more details on IFont methods.
1127 static HRESULT WINAPI
OLEFontImpl_AddRefHfont(
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(
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(
1167 OLEFontImpl
*this = (OLEFontImpl
*)iface
;
1168 FIXME("(%p)->(%p): Stub\n", this, hdc
);
1173 * Virtual function tables for the OLEFontImpl class.
1175 static const IFontVtbl OLEFontImpl_VTable
=
1177 OLEFontImpl_QueryInterface
,
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
,
1198 OLEFontImpl_IsEqual
,
1199 OLEFontImpl_SetRatio
,
1200 OLEFontImpl_QueryTextMetrics
,
1201 OLEFontImpl_AddRefHfont
,
1202 OLEFontImpl_ReleaseHfont
,
1206 /************************************************************************
1207 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1209 * See Windows documentation for more details on IUnknown methods.
1211 static HRESULT WINAPI
OLEFontImpl_IDispatch_QueryInterface(
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(
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(
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(
1254 unsigned int* pctinfo
)
1256 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1257 TRACE("(%p)->(%p)\n", this, pctinfo
);
1263 /************************************************************************
1264 * OLEFontImpl_GetTypeInfo (IDispatch)
1266 * See Windows documentation for more details on IDispatch methods.
1268 static HRESULT WINAPI
OLEFontImpl_GetTypeInfo(
1272 ITypeInfo
** ppTInfo
)
1274 static const WCHAR stdole2tlb
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
1278 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1279 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo
, (int)lcid
, ppTInfo
);
1282 hres
= LoadTypeLib(stdole2tlb
, &tl
);
1284 ERR("Could not load the stdole2.tlb?\n");
1287 hres
= ITypeLib_GetTypeInfoOfGuid(tl
, &IID_IFontDisp
, ppTInfo
);
1288 ITypeLib_Release(tl
);
1290 FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres
);
1295 /************************************************************************
1296 * OLEFontImpl_GetIDsOfNames (IDispatch)
1298 * See Windows documentation for more details on IDispatch methods.
1300 static HRESULT WINAPI
OLEFontImpl_GetIDsOfNames(
1303 LPOLESTR
* rgszNames
,
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
);
1318 return E_INVALIDARG
;
1322 /* retrieve type information */
1323 hres
= OLEFontImpl_GetTypeInfo(iface
, 0, lcid
, &pTInfo
);
1327 ERR("GetTypeInfo failed.\n");
1331 /* convert names to DISPIDs */
1332 hres
= DispGetIDsOfNames (pTInfo
, rgszNames
, cNames
, rgDispId
);
1333 ITypeInfo_Release(pTInfo
);
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
1348 static HRESULT WINAPI
OLEFontImpl_Invoke(
1350 DISPID dispIdMember
,
1354 DISPPARAMS
* pDispParams
,
1355 VARIANT
* pVarResult
,
1356 EXCEPINFO
* pExepInfo
,
1359 OLEFontImpl
*this = impl_from_IDispatch(iface
);
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
,
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
)
1378 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1379 return DISP_E_PARAMNOTOPTIONAL
;
1382 else if (wFlags
& DISPATCH_PROPERTYPUT
)
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
;
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
));
1409 VariantInit(&vararg
);
1410 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BSTR
);
1414 hr
= IFont_put_Name((IFont
*)this, V_BSTR(&vararg
));
1416 VariantClear(&vararg
);
1420 case DISPID_FONT_BOLD
:
1421 if (wFlags
& DISPATCH_PROPERTYGET
) {
1423 hr
= IFont_get_Bold((IFont
*)this, &value
);
1424 V_VT(pVarResult
) = VT_BOOL
;
1425 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1430 VariantInit(&vararg
);
1431 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1435 hr
= IFont_put_Bold((IFont
*)this, V_BOOL(&vararg
));
1437 VariantClear(&vararg
);
1441 case DISPID_FONT_ITALIC
:
1442 if (wFlags
& DISPATCH_PROPERTYGET
) {
1444 hr
= IFont_get_Italic((IFont
*)this, &value
);
1445 V_VT(pVarResult
) = VT_BOOL
;
1446 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1451 VariantInit(&vararg
);
1452 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1456 hr
= IFont_put_Italic((IFont
*)this, V_BOOL(&vararg
));
1458 VariantClear(&vararg
);
1462 case DISPID_FONT_UNDER
:
1463 if (wFlags
& DISPATCH_PROPERTYGET
) {
1465 hr
= IFont_get_Underline((IFont
*)this, &value
);
1466 V_VT(pVarResult
) = VT_BOOL
;
1467 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1472 VariantInit(&vararg
);
1473 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1477 hr
= IFont_put_Underline((IFont
*)this, V_BOOL(&vararg
));
1479 VariantClear(&vararg
);
1483 case DISPID_FONT_STRIKE
:
1484 if (wFlags
& DISPATCH_PROPERTYGET
) {
1486 hr
= IFont_get_Strikethrough((IFont
*)this, &value
);
1487 V_VT(pVarResult
) = VT_BOOL
;
1488 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1493 VariantInit(&vararg
);
1494 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1498 hr
= IFont_put_Strikethrough((IFont
*)this, V_BOOL(&vararg
));
1500 VariantClear(&vararg
);
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
));
1511 VariantInit(&vararg
);
1512 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_CY
);
1516 hr
= IFont_put_Size((IFont
*)this, V_CY(&vararg
));
1518 VariantClear(&vararg
);
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
));
1529 VariantInit(&vararg
);
1530 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_I2
);
1534 hr
= IFont_put_Weight((IFont
*)this, V_I2(&vararg
));
1536 VariantClear(&vararg
);
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
));
1547 VariantInit(&vararg
);
1548 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_I2
);
1552 hr
= IFont_put_Charset((IFont
*)this, V_I2(&vararg
));
1554 VariantClear(&vararg
);
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
,
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
,
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
,
1625 TRACE("(%p,%p)\n",iface
,pClassID
);
1629 *pClassID
= CLSID_StdFont
;
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
);
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
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:
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
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];
1678 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1681 * Read the version byte
1683 IStream_Read(pLoadStream
, &bVersion
, 1, &cbRead
);
1692 IStream_Read(pLoadStream
, &this->description
.sCharset
, 2, &cbRead
);
1700 IStream_Read(pLoadStream
, &bAttributes
, 1, &cbRead
);
1705 this->description
.fItalic
= (bAttributes
& FONTPERSIST_ITALIC
) != 0;
1706 this->description
.fStrikethrough
= (bAttributes
& FONTPERSIST_STRIKETHROUGH
) != 0;
1707 this->description
.fUnderline
= (bAttributes
& FONTPERSIST_UNDERLINE
) != 0;
1712 IStream_Read(pLoadStream
, &this->description
.sWeight
, 2, &cbRead
);
1720 IStream_Read(pLoadStream
, &this->description
.cySize
.s
.Lo
, 4, &cbRead
);
1725 this->description
.cySize
.s
.Hi
= 0;
1730 IStream_Read(pLoadStream
, &bStringSize
, 1, &cbRead
);
1735 IStream_Read(pLoadStream
, readBuffer
, bStringSize
, &cbRead
);
1737 if (cbRead
!=bStringSize
)
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
);
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
,
1764 char* writeBuffer
= NULL
;
1766 BYTE bVersion
= 0x01;
1770 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1773 * Read the version byte
1775 IStream_Write(pOutStream
, &bVersion
, 1, &cbWritten
);
1783 IStream_Write(pOutStream
, &this->description
.sCharset
, 2, &cbWritten
);
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
);
1810 IStream_Write(pOutStream
, &this->description
.sWeight
, 2, &cbWritten
);
1818 IStream_Write(pOutStream
, &this->description
.cySize
.s
.Lo
, 4, &cbWritten
);
1826 if (this->description
.lpstrName
!=0)
1827 bStringSize
= WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1828 strlenW(this->description
.lpstrName
), NULL
, 0, NULL
, NULL
);
1832 IStream_Write(pOutStream
, &bStringSize
, 1, &cbWritten
);
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
)
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
);
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
);
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
,
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
,
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
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
);
1955 /************************************************************************
1956 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1958 * See Windows documentation for more details on IConnectionPointContainer
1961 static HRESULT WINAPI
OLEFontImpl_FindConnectionPoint(
1962 IConnectionPointContainer
* iface
,
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
,
1973 } else if(IsEqualIID(riid
, &IID_IFontEventsDisp
)) {
1974 return IConnectionPoint_QueryInterface(this->pFontEventsCP
,
1975 &IID_IConnectionPoint
,
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
);
2024 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_InitNew(
2025 IPersistPropertyBag
*iface
2027 FIXME("(%p), stub!\n", iface
);
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"
2039 Underline = 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};
2052 HRESULT iRes
= S_OK
;
2053 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
2055 VariantInit(&rawAttr
);
2056 VariantInit(&valueAttr
);
2059 iRes
= IPropertyBag_Read(pPropBag
, sAttrName
, &rawAttr
, pErrorLog
);
2062 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_BSTR
);
2064 iRes
= IFont_put_Name((IFont
*)this, V_BSTR(&valueAttr
));
2066 else if (iRes
== E_INVALIDARG
)
2068 VariantClear(&rawAttr
);
2069 VariantClear(&valueAttr
);
2073 iRes
= IPropertyBag_Read(pPropBag
, sAttrSize
, &rawAttr
, pErrorLog
);
2076 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_CY
);
2078 iRes
= IFont_put_Size((IFont
*)this, V_CY(&valueAttr
));
2080 else if (iRes
== E_INVALIDARG
)
2082 VariantClear(&rawAttr
);
2083 VariantClear(&valueAttr
);
2087 iRes
= IPropertyBag_Read(pPropBag
, sAttrCharset
, &rawAttr
, pErrorLog
);
2090 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_I2
);
2092 iRes
= IFont_put_Charset((IFont
*)this, V_I2(&valueAttr
));
2094 else if (iRes
== E_INVALIDARG
)
2096 VariantClear(&rawAttr
);
2097 VariantClear(&valueAttr
);
2101 iRes
= IPropertyBag_Read(pPropBag
, sAttrWeight
, &rawAttr
, pErrorLog
);
2104 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_I2
);
2106 iRes
= IFont_put_Weight((IFont
*)this, V_I2(&valueAttr
));
2108 else if (iRes
== E_INVALIDARG
)
2110 VariantClear(&rawAttr
);
2111 VariantClear(&valueAttr
);
2116 iRes
= IPropertyBag_Read(pPropBag
, sAttrUnderline
, &rawAttr
, pErrorLog
);
2119 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_BOOL
);
2121 iRes
= IFont_put_Underline((IFont
*)this, V_BOOL(&valueAttr
));
2123 else if (iRes
== E_INVALIDARG
)
2125 VariantClear(&rawAttr
);
2126 VariantClear(&valueAttr
);
2130 iRes
= IPropertyBag_Read(pPropBag
, sAttrItalic
, &rawAttr
, pErrorLog
);
2133 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_BOOL
);
2135 iRes
= IFont_put_Italic((IFont
*)this, V_BOOL(&valueAttr
));
2137 else if (iRes
== E_INVALIDARG
)
2139 VariantClear(&rawAttr
);
2140 VariantClear(&valueAttr
);
2144 iRes
= IPropertyBag_Read(pPropBag
, sAttrStrikethrough
, &rawAttr
, pErrorLog
);
2147 iRes
= VariantChangeType(&rawAttr
, &valueAttr
, 0, VT_BOOL
);
2149 IFont_put_Strikethrough((IFont
*)this, V_BOOL(&valueAttr
));
2151 else if (iRes
== E_INVALIDARG
)
2153 VariantClear(&rawAttr
);
2154 VariantClear(&valueAttr
);
2158 WARN("-- 0x%08x\n", 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
);
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
);
2213 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_IsDirty(
2214 IPersistStreamInit
*iface
2216 FIXME("(%p), stub!\n", iface
);
2220 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_Load(
2221 IPersistStreamInit
*iface
, LPSTREAM pStm
2223 FIXME("(%p,%p), stub!\n", iface
, pStm
);
2227 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_Save(
2228 IPersistStreamInit
*iface
, LPSTREAM pStm
, BOOL fClearDirty
2230 FIXME("(%p,%p,%d), stub!\n", iface
, pStm
, fClearDirty
);
2234 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_GetSizeMax(
2235 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
2237 FIXME("(%p,%p), stub!\n", iface
, pcbSize
);
2241 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_InitNew(
2242 IPersistStreamInit
*iface
2244 FIXME("(%p), stub!\n", iface
);
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
2268 * The caller of this method must release the object when it's
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
));
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.
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
);
2335 InterlockedIncrement(&ifont_cnt
);
2337 TRACE("returning %p\n", 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
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
2367 /* IUnknown fields */
2368 const IClassFactoryVtbl
*lpVtbl
;
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
;
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
);
2405 static const IClassFactoryVtbl SFCF_Vtbl
= {
2406 SFCF_QueryInterface
,
2409 SFCF_CreateInstance
,
2412 static IClassFactoryImpl STDFONT_CF
= {&SFCF_Vtbl
, 1 };
2414 void _get_STDFONT_CF(LPVOID
*ppv
) { *ppv
= &STDFONT_CF
; }