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"
39 #include "oleauto.h" /* for SysAllocString(....) */
42 #include "wine/debug.h"
43 #include "connpt.h" /* for CreateConnectionPoint */
46 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
48 /***********************************************************************
49 * Declaration of constants used when serializing the font object.
51 #define FONTPERSIST_ITALIC 0x02
52 #define FONTPERSIST_UNDERLINE 0x04
53 #define FONTPERSIST_STRIKETHROUGH 0x08
55 static HDC olefont_hdc
;
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 HDC
get_dc(void)
97 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
99 olefont_hdc
= CreateCompatibleDC(NULL
);
101 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
105 static void delete_dc(void)
107 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
110 DeleteDC(olefont_hdc
);
113 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
116 static void HFONTItem_Delete(PHFONTItem item
)
118 DeleteObject(item
->gdiFont
);
119 list_remove(&item
->entry
);
120 HeapFree(GetProcessHeap(), 0, item
);
123 /* Find hfont item entry in the list. Should be called while holding the crit sect */
124 static HFONTItem
*find_hfontitem(HFONT hfont
)
128 LIST_FOR_EACH_ENTRY(item
, &OLEFontImpl_hFontList
, HFONTItem
, entry
)
130 if (item
->gdiFont
== hfont
)
136 /* Add an item to the list with one internal reference */
137 static HRESULT
add_hfontitem(HFONT hfont
)
139 HFONTItem
*new_item
= HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item
));
141 if(!new_item
) return E_OUTOFMEMORY
;
143 new_item
->int_refs
= 1;
144 new_item
->total_refs
= 1;
145 new_item
->gdiFont
= hfont
;
146 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
147 list_add_tail(&OLEFontImpl_hFontList
,&new_item
->entry
);
148 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
152 static HRESULT
inc_int_ref(HFONT hfont
)
155 HRESULT hr
= S_FALSE
;
157 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
158 item
= find_hfontitem(hfont
);
166 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
171 /* decrements the internal ref of a hfont item. If both refs are zero it'll
172 remove the item from the list and delete the hfont */
173 static HRESULT
dec_int_ref(HFONT hfont
)
176 HRESULT hr
= S_FALSE
;
178 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
179 item
= find_hfontitem(hfont
);
185 if(item
->int_refs
== 0 && item
->total_refs
== 0)
186 HFONTItem_Delete(item
);
189 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
194 static HRESULT
inc_ext_ref(HFONT hfont
)
197 HRESULT hr
= S_FALSE
;
199 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
201 item
= find_hfontitem(hfont
);
207 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
212 static HRESULT
dec_ext_ref(HFONT hfont
)
215 HRESULT hr
= S_FALSE
;
217 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
219 item
= find_hfontitem(hfont
);
222 if(--item
->total_refs
>= 0) hr
= S_OK
;
224 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
229 static WCHAR
*strdupW(const WCHAR
* str
)
232 DWORD size
= (lstrlenW(str
) + 1) * sizeof(WCHAR
);
234 ret
= HeapAlloc(GetProcessHeap(), 0, size
);
236 memcpy(ret
, str
, size
);
240 /***********************************************************************
241 * Declaration of the implementation class for the IFont interface
243 typedef struct OLEFontImpl OLEFontImpl
;
248 * This class supports many interfaces. IUnknown, IFont,
249 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
250 * The first two are supported by the first vtable, the next two are
251 * supported by the second table and the last two have their own.
254 IDispatch IDispatch_iface
;
255 IPersistStream IPersistStream_iface
;
256 IConnectionPointContainer IConnectionPointContainer_iface
;
257 IPersistPropertyBag IPersistPropertyBag_iface
;
259 * Reference count for that instance of the class.
264 * This structure contains the description of the class.
266 FONTDESC description
;
269 * Contain the font associated with this object.
280 * Stash realized height (pixels) from TEXTMETRIC - used in get_Size()
284 IConnectionPoint
*pPropertyNotifyCP
;
285 IConnectionPoint
*pFontEventsCP
;
288 static inline OLEFontImpl
*impl_from_IFont(IFont
*iface
)
290 return CONTAINING_RECORD(iface
, OLEFontImpl
, IFont_iface
);
293 static inline OLEFontImpl
*impl_from_IDispatch( IDispatch
*iface
)
295 return CONTAINING_RECORD(iface
, OLEFontImpl
, IDispatch_iface
);
298 static inline OLEFontImpl
*impl_from_IPersistStream( IPersistStream
*iface
)
300 return CONTAINING_RECORD(iface
, OLEFontImpl
, IPersistStream_iface
);
303 static inline OLEFontImpl
*impl_from_IConnectionPointContainer( IConnectionPointContainer
*iface
)
305 return CONTAINING_RECORD(iface
, OLEFontImpl
, IConnectionPointContainer_iface
);
308 static inline OLEFontImpl
*impl_from_IPersistPropertyBag( IPersistPropertyBag
*iface
)
310 return CONTAINING_RECORD(iface
, OLEFontImpl
, IPersistPropertyBag_iface
);
314 /***********************************************************************
315 * Prototypes for the implementation functions for the IFont
318 static OLEFontImpl
* OLEFontImpl_Construct(const FONTDESC
*fontDesc
);
319 static void OLEFontImpl_Destroy(OLEFontImpl
* fontDesc
);
320 static ULONG WINAPI
OLEFontImpl_AddRef(IFont
* iface
);
322 /******************************************************************************
323 * OleCreateFontIndirect [OLEAUT32.420]
325 HRESULT WINAPI
OleCreateFontIndirect(
326 LPFONTDESC lpFontDesc
,
330 OLEFontImpl
* newFont
;
334 TRACE("(%p, %s, %p)\n", lpFontDesc
, debugstr_guid(riid
), ppvObj
);
336 if (!ppvObj
) return E_POINTER
;
341 static WCHAR fname
[] = L
"System";
343 fd
.cbSizeofstruct
= sizeof(fd
);
344 fd
.lpstrName
= fname
;
345 fd
.cySize
.s
.Lo
= 80000;
350 fd
.fUnderline
= FALSE
;
351 fd
.fStrikethrough
= FALSE
;
355 newFont
= OLEFontImpl_Construct(lpFontDesc
);
356 if (!newFont
) return E_OUTOFMEMORY
;
358 hr
= IFont_QueryInterface(&newFont
->IFont_iface
, riid
, ppvObj
);
359 IFont_Release(&newFont
->IFont_iface
);
365 /***********************************************************************
366 * Implementation of the OLEFontImpl class.
369 /***********************************************************************
370 * OLEFont_SendNotify (internal)
372 * Sends notification messages of changed properties to any interested
375 static void OLEFont_SendNotify(OLEFontImpl
* this, DISPID dispID
)
377 static const LPCWSTR dispid_mapping
[] =
390 IEnumConnections
*pEnum
;
396 hres
= IConnectionPoint_EnumConnections(this->pPropertyNotifyCP
, &pEnum
);
399 while(IEnumConnections_Next(pEnum
, 1, &CD
, NULL
) == S_OK
) {
400 IPropertyNotifySink
*sink
;
402 IUnknown_QueryInterface(CD
.pUnk
, &IID_IPropertyNotifySink
, (void**)&sink
);
403 IPropertyNotifySink_OnChanged(sink
, dispID
);
404 IPropertyNotifySink_Release(sink
);
405 IUnknown_Release(CD
.pUnk
);
407 IEnumConnections_Release(pEnum
);
410 hres
= IConnectionPoint_EnumConnections(this->pFontEventsCP
, &pEnum
);
413 DISPPARAMS dispparams
;
416 VariantInit(&vararg
);
417 V_VT(&vararg
) = VT_BSTR
;
418 V_BSTR(&vararg
) = SysAllocString(dispid_mapping
[dispID
]);
420 dispparams
.cArgs
= 1;
421 dispparams
.cNamedArgs
= 0;
422 dispparams
.rgdispidNamedArgs
= NULL
;
423 dispparams
.rgvarg
= &vararg
;
425 while(IEnumConnections_Next(pEnum
, 1, &CD
, NULL
) == S_OK
) {
426 IFontEventsDisp
*disp
;
428 IUnknown_QueryInterface(CD
.pUnk
, &IID_IFontEventsDisp
, (void**)&disp
);
429 IFontEventsDisp_Invoke(disp
, DISPID_FONT_CHANGED
, &IID_NULL
,
430 LOCALE_NEUTRAL
, INVOKE_FUNC
, &dispparams
, NULL
,
433 IFontEventsDisp_Release(disp
);
434 IUnknown_Release(CD
.pUnk
);
436 VariantClear(&vararg
);
437 IEnumConnections_Release(pEnum
);
441 /************************************************************************
442 * OLEFontImpl_QueryInterface (IUnknown)
444 * See Windows documentation for more details on IUnknown methods.
446 static HRESULT WINAPI
OLEFontImpl_QueryInterface(
451 OLEFontImpl
*this = impl_from_IFont(iface
);
453 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid
), ppvObject
);
457 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
458 IsEqualGUID(&IID_IFont
, riid
))
462 else if (IsEqualGUID(&IID_IDispatch
, riid
) ||
463 IsEqualGUID(&IID_IFontDisp
, riid
))
465 *ppvObject
= &this->IDispatch_iface
;
467 else if (IsEqualGUID(&IID_IPersist
, riid
) ||
468 IsEqualGUID(&IID_IPersistStream
, riid
))
470 *ppvObject
= &this->IPersistStream_iface
;
472 else if (IsEqualGUID(&IID_IConnectionPointContainer
, riid
))
474 *ppvObject
= &this->IConnectionPointContainer_iface
;
476 else if (IsEqualGUID(&IID_IPersistPropertyBag
, riid
))
478 *ppvObject
= &this->IPersistPropertyBag_iface
;
483 FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid
));
484 return E_NOINTERFACE
;
492 static ULONG WINAPI
OLEFontImpl_AddRef(IFont
* iface
)
494 OLEFontImpl
*this = impl_from_IFont(iface
);
495 ULONG ref
= InterlockedIncrement(&this->ref
);
496 TRACE("%p, refcount %lu.\n", iface
, ref
);
500 static ULONG WINAPI
OLEFontImpl_Release(IFont
* iface
)
502 OLEFontImpl
*this = impl_from_IFont(iface
);
503 ULONG ref
= InterlockedDecrement(&this->ref
);
505 TRACE("%p, refcount %lu.\n", iface
, ref
);
509 ULONG fontlist_refs
= InterlockedDecrement(&ifont_cnt
);
511 /* Final IFont object so destroy font cache */
512 if (fontlist_refs
== 0)
514 HFONTItem
*item
, *cursor2
;
516 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
517 LIST_FOR_EACH_ENTRY_SAFE(item
, cursor2
, &OLEFontImpl_hFontList
, HFONTItem
, entry
)
518 HFONTItem_Delete(item
);
519 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
524 dec_int_ref(this->gdiFont
);
526 OLEFontImpl_Destroy(this);
538 static int CALLBACK
font_enum_proc(const LOGFONTW
*elf
, const TEXTMETRICW
*ntm
, DWORD type
, LPARAM lp
)
540 enum_data
*data
= (enum_data
*)lp
;
542 if(elf
->lfCharSet
== data
->orig_cs
)
544 data
->avail_cs
= data
->orig_cs
;
547 if(data
->avail_cs
== -1) data
->avail_cs
= elf
->lfCharSet
;
551 static void realize_font(OLEFontImpl
*This
)
555 WCHAR text_face
[LF_FACESIZE
];
560 if (!This
->dirty
) return;
566 old_font
= SelectObject(hdc
, This
->gdiFont
);
567 GetTextFaceW(hdc
, ARRAY_SIZE(text_face
), text_face
);
568 SelectObject(hdc
, old_font
);
569 dec_int_ref(This
->gdiFont
);
573 memset(&logFont
, 0, sizeof(LOGFONTW
));
575 lstrcpynW(logFont
.lfFaceName
, This
->description
.lpstrName
, LF_FACESIZE
);
576 logFont
.lfCharSet
= This
->description
.sCharset
;
578 /* If the font name has been changed then enumerate all charsets
579 and pick one that'll result in the font specified being selected */
580 if(text_face
[0] && lstrcmpiW(text_face
, This
->description
.lpstrName
))
583 data
.orig_cs
= This
->description
.sCharset
;
585 logFont
.lfCharSet
= DEFAULT_CHARSET
;
586 EnumFontFamiliesExW(get_dc(), &logFont
, font_enum_proc
, (LPARAM
)&data
, 0);
587 if(data
.avail_cs
!= -1) logFont
.lfCharSet
= data
.avail_cs
;
591 * The height of the font returned by the get_Size property is the
592 * height of the font in points multiplied by 10000... Using some
593 * simple conversions and the ratio given by the application, it can
594 * be converted to a height in pixels.
596 * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
597 * Ratio is applied here relative to the standard.
600 fontHeight
= MulDiv( This
->description
.cySize
.s
.Lo
, This
->cyLogical
*635, This
->cyHimetric
*18 );
602 logFont
.lfHeight
= ((fontHeight
%10000L)>5000L) ? (-fontHeight
/10000L) - 1 :
603 (-fontHeight
/10000L);
604 logFont
.lfItalic
= This
->description
.fItalic
;
605 logFont
.lfUnderline
= This
->description
.fUnderline
;
606 logFont
.lfStrikeOut
= This
->description
.fStrikethrough
;
607 logFont
.lfWeight
= This
->description
.sWeight
;
608 logFont
.lfOutPrecision
= OUT_CHARACTER_PRECIS
;
609 logFont
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
610 logFont
.lfQuality
= DEFAULT_QUALITY
;
611 logFont
.lfPitchAndFamily
= DEFAULT_PITCH
;
613 This
->gdiFont
= CreateFontIndirectW(&logFont
);
616 add_hfontitem(This
->gdiFont
);
618 /* Fixup the name and charset properties so that they match the
620 old_font
= SelectObject(get_dc(), This
->gdiFont
);
621 GetTextFaceW(hdc
, ARRAY_SIZE(text_face
), text_face
);
622 if(lstrcmpiW(text_face
, This
->description
.lpstrName
))
624 HeapFree(GetProcessHeap(), 0, This
->description
.lpstrName
);
625 This
->description
.lpstrName
= strdupW(text_face
);
627 GetTextMetricsW(hdc
, &tm
);
628 This
->description
.sCharset
= tm
.tmCharSet
;
629 /* While we have it handy, stash the realized font height for use by get_Size() */
630 This
->nRealHeight
= tm
.tmHeight
- tm
.tmInternalLeading
; /* corresponds to LOGFONT lfHeight */
631 SelectObject(hdc
, old_font
);
634 /************************************************************************
635 * OLEFontImpl_get_Name (IFont)
637 * See Windows documentation for more details on IFont methods.
639 static HRESULT WINAPI
OLEFontImpl_get_Name(
643 OLEFontImpl
*this = impl_from_IFont(iface
);
644 TRACE("(%p)->(%p)\n", this, pname
);
651 if (this->description
.lpstrName
!=0)
652 *pname
= SysAllocString(this->description
.lpstrName
);
659 /************************************************************************
660 * OLEFontImpl_put_Name (IFont)
662 static HRESULT WINAPI
OLEFontImpl_put_Name(
666 OLEFontImpl
*This
= impl_from_IFont(iface
);
667 TRACE("(%p)->(%p)\n", This
, name
);
670 return CTL_E_INVALIDPROPERTYVALUE
;
672 HeapFree(GetProcessHeap(), 0, This
->description
.lpstrName
);
673 This
->description
.lpstrName
= strdupW(name
);
674 if (!This
->description
.lpstrName
) return E_OUTOFMEMORY
;
676 TRACE("new name %s\n", debugstr_w(This
->description
.lpstrName
));
677 OLEFont_SendNotify(This
, DISPID_FONT_NAME
);
681 /************************************************************************
682 * OLEFontImpl_get_Size (IFont)
684 static HRESULT WINAPI
OLEFontImpl_get_Size(
688 OLEFontImpl
*this = impl_from_IFont(iface
);
689 TRACE("(%p)->(%p)\n", this, psize
);
691 if (!psize
) return E_POINTER
;
696 * Convert realized font height in pixels to points descaled by current
697 * scaling ratio then scaled up by 10000.
699 psize
->s
.Lo
= MulDiv(this->nRealHeight
,
700 this->cyHimetric
* 72 * 10000,
701 this->cyLogical
* 2540);
707 static HRESULT WINAPI
OLEFontImpl_put_Size(IFont
*iface
, CY size
)
709 OLEFontImpl
*this = impl_from_IFont(iface
);
710 TRACE("%p, %ld.\n", iface
, size
.s
.Lo
);
711 this->description
.cySize
.s
.Hi
= 0;
712 this->description
.cySize
.s
.Lo
= size
.s
.Lo
;
713 OLEFont_SendNotify(this, DISPID_FONT_SIZE
);
718 static HRESULT WINAPI
OLEFontImpl_get_Bold(IFont
*iface
, BOOL
*pbold
)
720 OLEFontImpl
*this = impl_from_IFont(iface
);
721 TRACE("(%p)->(%p)\n", this, pbold
);
723 if (!pbold
) return E_POINTER
;
727 *pbold
= this->description
.sWeight
> 550;
732 /************************************************************************
733 * OLEFontImpl_put_Bold (IFont)
735 static HRESULT WINAPI
OLEFontImpl_put_Bold(
739 OLEFontImpl
*this = impl_from_IFont(iface
);
740 TRACE("(%p)->(%d)\n", this, bold
);
741 this->description
.sWeight
= bold
? FW_BOLD
: FW_NORMAL
;
742 OLEFont_SendNotify(this, DISPID_FONT_BOLD
);
747 /************************************************************************
748 * OLEFontImpl_get_Italic (IFont)
750 static HRESULT WINAPI
OLEFontImpl_get_Italic(
754 OLEFontImpl
*this = impl_from_IFont(iface
);
755 TRACE("(%p)->(%p)\n", this, pitalic
);
762 *pitalic
= this->description
.fItalic
;
767 /************************************************************************
768 * OLEFontImpl_put_Italic (IFont)
770 static HRESULT WINAPI
OLEFontImpl_put_Italic(
774 OLEFontImpl
*this = impl_from_IFont(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 static HRESULT WINAPI
OLEFontImpl_get_Underline(
790 OLEFontImpl
*this = impl_from_IFont(iface
);
791 TRACE("(%p)->(%p)\n", this, punderline
);
798 *punderline
= this->description
.fUnderline
;
803 /************************************************************************
804 * OLEFontImpl_put_Underline (IFont)
806 static HRESULT WINAPI
OLEFontImpl_put_Underline(
810 OLEFontImpl
*this = impl_from_IFont(iface
);
811 TRACE("(%p)->(%d)\n", this, underline
);
813 this->description
.fUnderline
= underline
;
815 OLEFont_SendNotify(this, DISPID_FONT_UNDER
);
819 /************************************************************************
820 * OLEFontImpl_get_Strikethrough (IFont)
822 static HRESULT WINAPI
OLEFontImpl_get_Strikethrough(
824 BOOL
* pstrikethrough
)
826 OLEFontImpl
*this = impl_from_IFont(iface
);
827 TRACE("(%p)->(%p)\n", this, pstrikethrough
);
829 if (pstrikethrough
==0)
834 *pstrikethrough
= this->description
.fStrikethrough
;
839 /************************************************************************
840 * OLEFontImpl_put_Strikethrough (IFont)
842 static HRESULT WINAPI
OLEFontImpl_put_Strikethrough(
846 OLEFontImpl
*this = impl_from_IFont(iface
);
847 TRACE("(%p)->(%d)\n", this, strikethrough
);
849 this->description
.fStrikethrough
= strikethrough
;
850 OLEFont_SendNotify(this, DISPID_FONT_STRIKE
);
855 /************************************************************************
856 * OLEFontImpl_get_Weight (IFont)
858 static HRESULT WINAPI
OLEFontImpl_get_Weight(
862 OLEFontImpl
*this = impl_from_IFont(iface
);
863 TRACE("(%p)->(%p)\n", this, pweight
);
870 *pweight
= this->description
.sWeight
;
875 /************************************************************************
876 * OLEFontImpl_put_Weight (IFont)
878 static HRESULT WINAPI
OLEFontImpl_put_Weight(
882 OLEFontImpl
*this = impl_from_IFont(iface
);
883 TRACE("(%p)->(%d)\n", this, weight
);
885 this->description
.sWeight
= weight
;
887 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT
);
891 /************************************************************************
892 * OLEFontImpl_get_Charset (IFont)
894 static HRESULT WINAPI
OLEFontImpl_get_Charset(
898 OLEFontImpl
*this = impl_from_IFont(iface
);
899 TRACE("(%p)->(%p)\n", this, pcharset
);
906 *pcharset
= this->description
.sCharset
;
911 /************************************************************************
912 * OLEFontImpl_put_Charset (IFont)
914 static HRESULT WINAPI
OLEFontImpl_put_Charset(
918 OLEFontImpl
*this = impl_from_IFont(iface
);
919 TRACE("(%p)->(%d)\n", this, charset
);
921 this->description
.sCharset
= charset
;
922 OLEFont_SendNotify(this, DISPID_FONT_CHARSET
);
927 /************************************************************************
928 * OLEFontImpl_get_hFont (IFont)
930 static HRESULT WINAPI
OLEFontImpl_get_hFont(
934 OLEFontImpl
*this = impl_from_IFont(iface
);
935 TRACE("(%p)->(%p)\n", this, phfont
);
941 *phfont
= this->gdiFont
;
942 TRACE("Returning %p\n", *phfont
);
946 /************************************************************************
947 * OLEFontImpl_Clone (IFont)
949 static HRESULT WINAPI
OLEFontImpl_Clone(
953 OLEFontImpl
*this = impl_from_IFont(iface
);
954 OLEFontImpl
* newObject
;
956 TRACE("(%p)->(%p)\n", this, ppfont
);
963 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl
));
965 return E_OUTOFMEMORY
;
968 /* allocate separate buffer */
969 newObject
->description
.lpstrName
= strdupW(this->description
.lpstrName
);
971 /* Increment internal ref in hfont item list */
972 if(newObject
->gdiFont
) inc_int_ref(newObject
->gdiFont
);
974 InterlockedIncrement(&ifont_cnt
);
976 newObject
->pPropertyNotifyCP
= NULL
;
977 newObject
->pFontEventsCP
= NULL
;
978 CreateConnectionPoint((IUnknown
*)&newObject
->IFont_iface
, &IID_IPropertyNotifySink
,
979 &newObject
->pPropertyNotifyCP
);
980 CreateConnectionPoint((IUnknown
*)&newObject
->IFont_iface
, &IID_IFontEventsDisp
,
981 &newObject
->pFontEventsCP
);
983 if (!newObject
->pPropertyNotifyCP
|| !newObject
->pFontEventsCP
)
985 OLEFontImpl_Destroy(newObject
);
986 return E_OUTOFMEMORY
;
989 /* The cloned object starts with a reference count of 1 */
992 *ppfont
= &newObject
->IFont_iface
;
997 /************************************************************************
998 * OLEFontImpl_IsEqual (IFont)
1000 static HRESULT WINAPI
OLEFontImpl_IsEqual(
1004 OLEFontImpl
*left
= impl_from_IFont(iface
);
1005 OLEFontImpl
*right
= impl_from_IFont(pFontOther
);
1007 INT left_len
,right_len
;
1009 if(pFontOther
== NULL
)
1011 else if (left
->description
.cySize
.s
.Lo
!= right
->description
.cySize
.s
.Lo
)
1013 else if (left
->description
.cySize
.s
.Hi
!= right
->description
.cySize
.s
.Hi
)
1015 else if (left
->description
.sWeight
!= right
->description
.sWeight
)
1017 else if (left
->description
.sCharset
!= right
->description
.sCharset
)
1019 else if (left
->description
.fItalic
!= right
->description
.fItalic
)
1021 else if (left
->description
.fUnderline
!= right
->description
.fUnderline
)
1023 else if (left
->description
.fStrikethrough
!= right
->description
.fStrikethrough
)
1026 /* Check from string */
1027 left_len
= lstrlenW(left
->description
.lpstrName
);
1028 right_len
= lstrlenW(right
->description
.lpstrName
);
1029 ret
= CompareStringW(0,0,left
->description
.lpstrName
, left_len
,
1030 right
->description
.lpstrName
, right_len
);
1031 if (ret
!= CSTR_EQUAL
)
1037 /************************************************************************
1038 * OLEFontImpl_SetRatio (IFont)
1040 static HRESULT WINAPI
OLEFontImpl_SetRatio(
1045 OLEFontImpl
*this = impl_from_IFont(iface
);
1047 TRACE("%p, %ld, %ld.\n", iface
, cyLogical
, cyHimetric
);
1049 if(cyLogical
== 0 || cyHimetric
== 0)
1052 /* cyLogical and cyHimetric both set to 1 is a special case that
1053 does not change the scaling but also does not fail */
1054 if(cyLogical
== 1 && cyHimetric
== 1)
1057 this->cyLogical
= cyLogical
;
1058 this->cyHimetric
= cyHimetric
;
1064 /************************************************************************
1065 * OLEFontImpl_QueryTextMetrics (IFont)
1067 static HRESULT WINAPI
OLEFontImpl_QueryTextMetrics(
1072 HFONT hOldFont
, hNewFont
;
1075 IFont_get_hFont(iface
, &hNewFont
);
1076 hOldFont
= SelectObject(hdcRef
, hNewFont
);
1077 GetTextMetricsW(hdcRef
, ptm
);
1078 SelectObject(hdcRef
, hOldFont
);
1079 ReleaseDC(0, hdcRef
);
1083 /************************************************************************
1084 * OLEFontImpl_AddRefHfont (IFont)
1086 static HRESULT WINAPI
OLEFontImpl_AddRefHfont(
1090 OLEFontImpl
*this = impl_from_IFont(iface
);
1092 TRACE("(%p)->(%p)\n", this, hfont
);
1094 if (!hfont
) return E_INVALIDARG
;
1096 return inc_ext_ref(hfont
);
1099 /************************************************************************
1100 * OLEFontImpl_ReleaseHfont (IFont)
1102 static HRESULT WINAPI
OLEFontImpl_ReleaseHfont(
1106 OLEFontImpl
*this = impl_from_IFont(iface
);
1108 TRACE("(%p)->(%p)\n", this, hfont
);
1110 if (!hfont
) return E_INVALIDARG
;
1112 return dec_ext_ref(hfont
);
1115 /************************************************************************
1116 * OLEFontImpl_SetHdc (IFont)
1118 static HRESULT WINAPI
OLEFontImpl_SetHdc(
1122 OLEFontImpl
*this = impl_from_IFont(iface
);
1123 FIXME("(%p)->(%p): Stub\n", this, hdc
);
1127 static const IFontVtbl OLEFontImpl_VTable
=
1129 OLEFontImpl_QueryInterface
,
1131 OLEFontImpl_Release
,
1132 OLEFontImpl_get_Name
,
1133 OLEFontImpl_put_Name
,
1134 OLEFontImpl_get_Size
,
1135 OLEFontImpl_put_Size
,
1136 OLEFontImpl_get_Bold
,
1137 OLEFontImpl_put_Bold
,
1138 OLEFontImpl_get_Italic
,
1139 OLEFontImpl_put_Italic
,
1140 OLEFontImpl_get_Underline
,
1141 OLEFontImpl_put_Underline
,
1142 OLEFontImpl_get_Strikethrough
,
1143 OLEFontImpl_put_Strikethrough
,
1144 OLEFontImpl_get_Weight
,
1145 OLEFontImpl_put_Weight
,
1146 OLEFontImpl_get_Charset
,
1147 OLEFontImpl_put_Charset
,
1148 OLEFontImpl_get_hFont
,
1150 OLEFontImpl_IsEqual
,
1151 OLEFontImpl_SetRatio
,
1152 OLEFontImpl_QueryTextMetrics
,
1153 OLEFontImpl_AddRefHfont
,
1154 OLEFontImpl_ReleaseHfont
,
1158 /************************************************************************
1159 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1161 static HRESULT WINAPI
OLEFontImpl_IDispatch_QueryInterface(
1166 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1167 return IFont_QueryInterface(&this->IFont_iface
, riid
, ppvoid
);
1170 /************************************************************************
1171 * OLEFontImpl_IDispatch_Release (IUnknown)
1173 static ULONG WINAPI
OLEFontImpl_IDispatch_Release(
1176 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1177 return IFont_Release(&this->IFont_iface
);
1180 /************************************************************************
1181 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1183 static ULONG WINAPI
OLEFontImpl_IDispatch_AddRef(
1186 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1187 return IFont_AddRef(&this->IFont_iface
);
1190 /************************************************************************
1191 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1193 static HRESULT WINAPI
OLEFontImpl_GetTypeInfoCount(
1195 unsigned int* pctinfo
)
1197 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1198 TRACE("(%p)->(%p)\n", this, pctinfo
);
1204 /************************************************************************
1205 * OLEFontImpl_GetTypeInfo (IDispatch)
1207 static HRESULT WINAPI
OLEFontImpl_GetTypeInfo(
1211 ITypeInfo
** ppTInfo
)
1216 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1217 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo
, (int)lcid
, ppTInfo
);
1220 hres
= LoadTypeLib(L
"stdole2.tlb", &tl
);
1222 ERR("Could not load the stdole2.tlb?\n");
1225 hres
= ITypeLib_GetTypeInfoOfGuid(tl
, &IID_IFontDisp
, ppTInfo
);
1226 ITypeLib_Release(tl
);
1228 FIXME("Did not IDispatch typeinfo from typelib, hres %#lx.\n", hres
);
1233 /************************************************************************
1234 * OLEFontImpl_GetIDsOfNames (IDispatch)
1236 static HRESULT WINAPI
OLEFontImpl_GetIDsOfNames(
1239 LPOLESTR
* rgszNames
,
1247 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1249 TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid
),
1250 rgszNames
, cNames
, (int)lcid
, rgDispId
);
1252 if (cNames
== 0) return E_INVALIDARG
;
1254 hres
= IDispatch_GetTypeInfo(iface
, 0, lcid
, &pTInfo
);
1257 ERR("GetTypeInfo failed.\n");
1261 /* convert names to DISPIDs */
1262 hres
= DispGetIDsOfNames (pTInfo
, rgszNames
, cNames
, rgDispId
);
1263 ITypeInfo_Release(pTInfo
);
1268 /************************************************************************
1269 * OLEFontImpl_Invoke (IDispatch)
1272 static HRESULT WINAPI
OLEFontImpl_Invoke(
1274 DISPID dispIdMember
,
1278 DISPPARAMS
* pDispParams
,
1279 VARIANT
* pVarResult
,
1280 EXCEPINFO
* pExepInfo
,
1283 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1286 TRACE("%p, %ld, %s, %#lx, %#x, %p, %p, %p, %p.\n", iface
, dispIdMember
,
1287 debugstr_guid(riid
), lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
,
1290 /* validate parameters */
1292 if (!IsEqualIID(riid
, &IID_NULL
))
1294 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid
));
1295 return DISP_E_UNKNOWNINTERFACE
;
1298 if (wFlags
& DISPATCH_PROPERTYGET
)
1302 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1303 return DISP_E_PARAMNOTOPTIONAL
;
1306 else if (wFlags
& DISPATCH_PROPERTYPUT
)
1310 ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n");
1311 return DISP_E_PARAMNOTOPTIONAL
;
1313 if (pDispParams
->cArgs
!= 1)
1315 ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams
->cArgs
);
1316 return DISP_E_BADPARAMCOUNT
;
1321 ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n");
1322 return DISP_E_MEMBERNOTFOUND
;
1325 switch (dispIdMember
) {
1326 case DISPID_FONT_NAME
:
1327 if (wFlags
& DISPATCH_PROPERTYGET
) {
1328 V_VT(pVarResult
) = VT_BSTR
;
1329 return IFont_get_Name(&this->IFont_iface
, &V_BSTR(pVarResult
));
1333 VariantInit(&vararg
);
1334 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BSTR
);
1338 hr
= IFont_put_Name(&this->IFont_iface
, V_BSTR(&vararg
));
1340 VariantClear(&vararg
);
1344 case DISPID_FONT_BOLD
:
1345 if (wFlags
& DISPATCH_PROPERTYGET
) {
1347 hr
= IFont_get_Bold(&this->IFont_iface
, &value
);
1348 V_VT(pVarResult
) = VT_BOOL
;
1349 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1354 VariantInit(&vararg
);
1355 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1359 hr
= IFont_put_Bold(&this->IFont_iface
, V_BOOL(&vararg
));
1361 VariantClear(&vararg
);
1365 case DISPID_FONT_ITALIC
:
1366 if (wFlags
& DISPATCH_PROPERTYGET
) {
1368 hr
= IFont_get_Italic(&this->IFont_iface
, &value
);
1369 V_VT(pVarResult
) = VT_BOOL
;
1370 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1375 VariantInit(&vararg
);
1376 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1380 hr
= IFont_put_Italic(&this->IFont_iface
, V_BOOL(&vararg
));
1382 VariantClear(&vararg
);
1386 case DISPID_FONT_UNDER
:
1387 if (wFlags
& DISPATCH_PROPERTYGET
) {
1389 hr
= IFont_get_Underline(&this->IFont_iface
, &value
);
1390 V_VT(pVarResult
) = VT_BOOL
;
1391 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1396 VariantInit(&vararg
);
1397 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1401 hr
= IFont_put_Underline(&this->IFont_iface
, V_BOOL(&vararg
));
1403 VariantClear(&vararg
);
1407 case DISPID_FONT_STRIKE
:
1408 if (wFlags
& DISPATCH_PROPERTYGET
) {
1410 hr
= IFont_get_Strikethrough(&this->IFont_iface
, &value
);
1411 V_VT(pVarResult
) = VT_BOOL
;
1412 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1417 VariantInit(&vararg
);
1418 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1422 hr
= IFont_put_Strikethrough(&this->IFont_iface
, V_BOOL(&vararg
));
1424 VariantClear(&vararg
);
1428 case DISPID_FONT_SIZE
:
1429 if (wFlags
& DISPATCH_PROPERTYGET
) {
1430 V_VT(pVarResult
) = VT_CY
;
1431 return IFont_get_Size(&this->IFont_iface
, &V_CY(pVarResult
));
1435 VariantInit(&vararg
);
1436 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_CY
);
1440 hr
= IFont_put_Size(&this->IFont_iface
, V_CY(&vararg
));
1442 VariantClear(&vararg
);
1446 case DISPID_FONT_WEIGHT
:
1447 if (wFlags
& DISPATCH_PROPERTYGET
) {
1448 V_VT(pVarResult
) = VT_I2
;
1449 return IFont_get_Weight(&this->IFont_iface
, &V_I2(pVarResult
));
1453 VariantInit(&vararg
);
1454 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_I2
);
1458 hr
= IFont_put_Weight(&this->IFont_iface
, V_I2(&vararg
));
1460 VariantClear(&vararg
);
1464 case DISPID_FONT_CHARSET
:
1465 if (wFlags
& DISPATCH_PROPERTYGET
) {
1466 V_VT(pVarResult
) = VT_I2
;
1467 return OLEFontImpl_get_Charset(&this->IFont_iface
, &V_I2(pVarResult
));
1471 VariantInit(&vararg
);
1472 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_I2
);
1476 hr
= IFont_put_Charset(&this->IFont_iface
, V_I2(&vararg
));
1478 VariantClear(&vararg
);
1483 ERR("member not found for dispid %#lx.\n", dispIdMember
);
1484 return DISP_E_MEMBERNOTFOUND
;
1488 static const IDispatchVtbl OLEFontImpl_IDispatch_VTable
=
1490 OLEFontImpl_IDispatch_QueryInterface
,
1491 OLEFontImpl_IDispatch_AddRef
,
1492 OLEFontImpl_IDispatch_Release
,
1493 OLEFontImpl_GetTypeInfoCount
,
1494 OLEFontImpl_GetTypeInfo
,
1495 OLEFontImpl_GetIDsOfNames
,
1499 /************************************************************************
1500 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1502 static HRESULT WINAPI
OLEFontImpl_IPersistStream_QueryInterface(
1503 IPersistStream
* iface
,
1507 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1509 return IFont_QueryInterface(&this->IFont_iface
, riid
, ppvoid
);
1512 /************************************************************************
1513 * OLEFontImpl_IPersistStream_Release (IUnknown)
1515 static ULONG WINAPI
OLEFontImpl_IPersistStream_Release(
1516 IPersistStream
* iface
)
1518 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1520 return IFont_Release(&this->IFont_iface
);
1523 /************************************************************************
1524 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1526 static ULONG WINAPI
OLEFontImpl_IPersistStream_AddRef(
1527 IPersistStream
* iface
)
1529 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1531 return IFont_AddRef(&this->IFont_iface
);
1534 /************************************************************************
1535 * OLEFontImpl_GetClassID (IPersistStream)
1537 static HRESULT WINAPI
OLEFontImpl_GetClassID(
1538 IPersistStream
* iface
,
1541 TRACE("(%p,%p)\n",iface
,pClassID
);
1545 *pClassID
= CLSID_StdFont
;
1550 /************************************************************************
1551 * OLEFontImpl_IsDirty (IPersistStream)
1553 * See Windows documentation for more details on IPersistStream methods.
1555 static HRESULT WINAPI
OLEFontImpl_IsDirty(
1556 IPersistStream
* iface
)
1558 TRACE("(%p)\n",iface
);
1562 /************************************************************************
1563 * OLEFontImpl_Load (IPersistStream)
1565 * See Windows documentation for more details on IPersistStream methods.
1567 * This is the format of the standard font serialization as far as I
1570 * Offset Type Value Comment
1571 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1572 * 0x0001 Short Charset Charset value from the FONTDESC structure
1573 * 0x0003 Byte Attributes Flags defined as follows:
1575 * 00000100 - Underline
1576 * 00001000 - Strikethrough
1577 * 0x0004 Short Weight Weight value from FONTDESC structure
1578 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1580 * 0x000A Byte name length Length of the font name string (no null character)
1581 * 0x000B String name Name of the font (ASCII, no nul character)
1583 static HRESULT WINAPI
OLEFontImpl_Load(
1584 IPersistStream
* iface
,
1585 IStream
* pLoadStream
)
1587 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1588 BYTE version
, attributes
, string_size
;
1589 char readBuffer
[0x100];
1594 IStream_Read(pLoadStream
, &version
, sizeof(BYTE
), &cbRead
);
1595 if ((cbRead
!= sizeof(BYTE
)) || (version
!= 0x01)) return E_FAIL
;
1598 IStream_Read(pLoadStream
, &this->description
.sCharset
, sizeof(WORD
), &cbRead
);
1599 if (cbRead
!= sizeof(WORD
)) return E_FAIL
;
1602 IStream_Read(pLoadStream
, &attributes
, sizeof(BYTE
), &cbRead
);
1603 if (cbRead
!= sizeof(BYTE
)) return E_FAIL
;
1605 this->description
.fItalic
= (attributes
& FONTPERSIST_ITALIC
) != 0;
1606 this->description
.fStrikethrough
= (attributes
& FONTPERSIST_STRIKETHROUGH
) != 0;
1607 this->description
.fUnderline
= (attributes
& FONTPERSIST_UNDERLINE
) != 0;
1610 IStream_Read(pLoadStream
, &this->description
.sWeight
, sizeof(WORD
), &cbRead
);
1611 if (cbRead
!= sizeof(WORD
)) return E_FAIL
;
1614 IStream_Read(pLoadStream
, &this->description
.cySize
.s
.Lo
, sizeof(DWORD
), &cbRead
);
1615 if (cbRead
!= sizeof(DWORD
)) return E_FAIL
;
1617 this->description
.cySize
.s
.Hi
= 0;
1620 IStream_Read(pLoadStream
, &string_size
, sizeof(BYTE
), &cbRead
);
1621 if (cbRead
!= sizeof(BYTE
)) return E_FAIL
;
1623 IStream_Read(pLoadStream
, readBuffer
, string_size
, &cbRead
);
1624 if (cbRead
!= string_size
) return E_FAIL
;
1626 HeapFree(GetProcessHeap(), 0, this->description
.lpstrName
);
1628 len
= MultiByteToWideChar( CP_ACP
, 0, readBuffer
, string_size
, NULL
, 0 );
1629 this->description
.lpstrName
= HeapAlloc( GetProcessHeap(), 0, (len
+1) * sizeof(WCHAR
) );
1630 MultiByteToWideChar( CP_ACP
, 0, readBuffer
, string_size
, this->description
.lpstrName
, len
);
1631 this->description
.lpstrName
[len
] = 0;
1633 /* Ensure use of this font causes a new one to be created */
1634 dec_int_ref(this->gdiFont
);
1641 /************************************************************************
1642 * OLEFontImpl_Save (IPersistStream)
1644 static HRESULT WINAPI
OLEFontImpl_Save(
1645 IPersistStream
* iface
,
1646 IStream
* pOutStream
,
1649 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1650 BYTE attributes
, string_size
;
1651 const BYTE version
= 0x01;
1652 char* writeBuffer
= NULL
;
1655 TRACE("(%p)->(%p %d)\n", this, pOutStream
, fClearDirty
);
1658 IStream_Write(pOutStream
, &version
, sizeof(BYTE
), &written
);
1659 if (written
!= sizeof(BYTE
)) return E_FAIL
;
1662 IStream_Write(pOutStream
, &this->description
.sCharset
, sizeof(WORD
), &written
);
1663 if (written
!= sizeof(WORD
)) return E_FAIL
;
1668 if (this->description
.fItalic
)
1669 attributes
|= FONTPERSIST_ITALIC
;
1671 if (this->description
.fStrikethrough
)
1672 attributes
|= FONTPERSIST_STRIKETHROUGH
;
1674 if (this->description
.fUnderline
)
1675 attributes
|= FONTPERSIST_UNDERLINE
;
1677 IStream_Write(pOutStream
, &attributes
, sizeof(BYTE
), &written
);
1678 if (written
!= sizeof(BYTE
)) return E_FAIL
;
1681 IStream_Write(pOutStream
, &this->description
.sWeight
, sizeof(WORD
), &written
);
1682 if (written
!= sizeof(WORD
)) return E_FAIL
;
1685 IStream_Write(pOutStream
, &this->description
.cySize
.s
.Lo
, sizeof(DWORD
), &written
);
1686 if (written
!= sizeof(DWORD
)) return E_FAIL
;
1689 if (this->description
.lpstrName
)
1690 string_size
= WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1691 lstrlenW(this->description
.lpstrName
), NULL
, 0, NULL
, NULL
);
1695 IStream_Write(pOutStream
, &string_size
, sizeof(BYTE
), &written
);
1696 if (written
!= sizeof(BYTE
)) return E_FAIL
;
1700 if (!(writeBuffer
= HeapAlloc( GetProcessHeap(), 0, string_size
))) return E_OUTOFMEMORY
;
1701 WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1702 lstrlenW(this->description
.lpstrName
),
1703 writeBuffer
, string_size
, NULL
, NULL
);
1705 IStream_Write(pOutStream
, writeBuffer
, string_size
, &written
);
1706 HeapFree(GetProcessHeap(), 0, writeBuffer
);
1708 if (written
!= string_size
) return E_FAIL
;
1714 /************************************************************************
1715 * OLEFontImpl_GetSizeMax (IPersistStream)
1717 static HRESULT WINAPI
OLEFontImpl_GetSizeMax(
1718 IPersistStream
* iface
,
1719 ULARGE_INTEGER
* pcbSize
)
1721 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1726 pcbSize
->u
.HighPart
= 0;
1727 pcbSize
->u
.LowPart
= 0;
1729 pcbSize
->u
.LowPart
+= sizeof(BYTE
); /* Version */
1730 pcbSize
->u
.LowPart
+= sizeof(WORD
); /* Lang code */
1731 pcbSize
->u
.LowPart
+= sizeof(BYTE
); /* Flags */
1732 pcbSize
->u
.LowPart
+= sizeof(WORD
); /* Weight */
1733 pcbSize
->u
.LowPart
+= sizeof(DWORD
); /* Size */
1734 pcbSize
->u
.LowPart
+= sizeof(BYTE
); /* StrLength */
1736 if (this->description
.lpstrName
!=0)
1737 pcbSize
->u
.LowPart
+= WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1738 lstrlenW(this->description
.lpstrName
),
1739 NULL
, 0, NULL
, NULL
);
1744 static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable
=
1746 OLEFontImpl_IPersistStream_QueryInterface
,
1747 OLEFontImpl_IPersistStream_AddRef
,
1748 OLEFontImpl_IPersistStream_Release
,
1749 OLEFontImpl_GetClassID
,
1750 OLEFontImpl_IsDirty
,
1753 OLEFontImpl_GetSizeMax
1756 /************************************************************************
1757 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1759 static HRESULT WINAPI
OLEFontImpl_IConnectionPointContainer_QueryInterface(
1760 IConnectionPointContainer
* iface
,
1764 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1766 return IFont_QueryInterface(&this->IFont_iface
, riid
, ppvoid
);
1769 /************************************************************************
1770 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1772 static ULONG WINAPI
OLEFontImpl_IConnectionPointContainer_Release(
1773 IConnectionPointContainer
* iface
)
1775 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1777 return IFont_Release(&this->IFont_iface
);
1780 /************************************************************************
1781 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1783 static ULONG WINAPI
OLEFontImpl_IConnectionPointContainer_AddRef(
1784 IConnectionPointContainer
* iface
)
1786 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1788 return IFont_AddRef(&this->IFont_iface
);
1791 /************************************************************************
1792 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1794 static HRESULT WINAPI
OLEFontImpl_EnumConnectionPoints(
1795 IConnectionPointContainer
* iface
,
1796 IEnumConnectionPoints
**ppEnum
)
1798 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1800 FIXME("(%p)->(%p): stub\n", this, ppEnum
);
1804 /************************************************************************
1805 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1807 static HRESULT WINAPI
OLEFontImpl_FindConnectionPoint(
1808 IConnectionPointContainer
* iface
,
1810 IConnectionPoint
**ppCp
)
1812 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1813 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid
), ppCp
);
1815 if(IsEqualIID(riid
, &IID_IPropertyNotifySink
)) {
1816 return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP
, &IID_IConnectionPoint
,
1818 } else if(IsEqualIID(riid
, &IID_IFontEventsDisp
)) {
1819 return IConnectionPoint_QueryInterface(this->pFontEventsCP
, &IID_IConnectionPoint
,
1822 FIXME("no connection point for %s\n", debugstr_guid(riid
));
1823 return CONNECT_E_NOCONNECTION
;
1827 static const IConnectionPointContainerVtbl
1828 OLEFontImpl_IConnectionPointContainer_VTable
=
1830 OLEFontImpl_IConnectionPointContainer_QueryInterface
,
1831 OLEFontImpl_IConnectionPointContainer_AddRef
,
1832 OLEFontImpl_IConnectionPointContainer_Release
,
1833 OLEFontImpl_EnumConnectionPoints
,
1834 OLEFontImpl_FindConnectionPoint
1837 /************************************************************************
1838 * OLEFontImpl implementation of IPersistPropertyBag.
1840 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_QueryInterface(
1841 IPersistPropertyBag
*iface
, REFIID riid
, LPVOID
*ppvObj
1843 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1844 return IFont_QueryInterface(&this->IFont_iface
,riid
,ppvObj
);
1847 static ULONG WINAPI
OLEFontImpl_IPersistPropertyBag_AddRef(
1848 IPersistPropertyBag
*iface
1850 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1851 return IFont_AddRef(&this->IFont_iface
);
1854 static ULONG WINAPI
OLEFontImpl_IPersistPropertyBag_Release(
1855 IPersistPropertyBag
*iface
1857 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1858 return IFont_Release(&this->IFont_iface
);
1861 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_GetClassID(
1862 IPersistPropertyBag
*iface
, CLSID
*classid
1864 FIXME("(%p,%p), stub!\n", iface
, classid
);
1868 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_InitNew(
1869 IPersistPropertyBag
*iface
1871 FIXME("(%p), stub!\n", iface
);
1875 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_Load(
1876 IPersistPropertyBag
*iface
, IPropertyBag
* pPropBag
, IErrorLog
* pErrorLog
1878 /* (from Visual Basic 6 property bag)
1879 Name = "MS Sans Serif"
1883 Underline = 0 'False
1885 Strikethrough = 0 'False
1887 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1891 VariantInit(&value
);
1893 iRes
= IPropertyBag_Read(pPropBag
, L
"Name", &value
, pErrorLog
);
1896 iRes
= VariantChangeType(&value
, &value
, 0, VT_BSTR
);
1898 iRes
= IFont_put_Name(&this->IFont_iface
, V_BSTR(&value
));
1900 else if (iRes
== E_INVALIDARG
)
1903 VariantClear(&value
);
1906 iRes
= IPropertyBag_Read(pPropBag
, L
"Size", &value
, pErrorLog
);
1909 iRes
= VariantChangeType(&value
, &value
, 0, VT_CY
);
1911 iRes
= IFont_put_Size(&this->IFont_iface
, V_CY(&value
));
1913 else if (iRes
== E_INVALIDARG
)
1916 VariantClear(&value
);
1920 iRes
= IPropertyBag_Read(pPropBag
, L
"Charset", &value
, pErrorLog
);
1923 iRes
= VariantChangeType(&value
, &value
, 0, VT_I2
);
1925 iRes
= IFont_put_Charset(&this->IFont_iface
, V_I2(&value
));
1927 else if (iRes
== E_INVALIDARG
)
1930 VariantClear(&value
);
1934 iRes
= IPropertyBag_Read(pPropBag
, L
"Weight", &value
, pErrorLog
);
1937 iRes
= VariantChangeType(&value
, &value
, 0, VT_I2
);
1939 iRes
= IFont_put_Weight(&this->IFont_iface
, V_I2(&value
));
1941 else if (iRes
== E_INVALIDARG
)
1944 VariantClear(&value
);
1948 iRes
= IPropertyBag_Read(pPropBag
, L
"Underline", &value
, pErrorLog
);
1951 iRes
= VariantChangeType(&value
, &value
, 0, VT_BOOL
);
1953 iRes
= IFont_put_Underline(&this->IFont_iface
, V_BOOL(&value
));
1955 else if (iRes
== E_INVALIDARG
)
1958 VariantClear(&value
);
1962 iRes
= IPropertyBag_Read(pPropBag
, L
"Italic", &value
, pErrorLog
);
1965 iRes
= VariantChangeType(&value
, &value
, 0, VT_BOOL
);
1967 iRes
= IFont_put_Italic(&this->IFont_iface
, V_BOOL(&value
));
1969 else if (iRes
== E_INVALIDARG
)
1972 VariantClear(&value
);
1976 iRes
= IPropertyBag_Read(pPropBag
, L
"Strikethrough", &value
, pErrorLog
);
1979 iRes
= VariantChangeType(&value
, &value
, 0, VT_BOOL
);
1981 IFont_put_Strikethrough(&this->IFont_iface
, V_BOOL(&value
));
1983 else if (iRes
== E_INVALIDARG
)
1986 VariantClear(&value
);
1990 WARN("-- %#lx.\n", iRes
);
1994 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_Save(
1995 IPersistPropertyBag
*iface
, IPropertyBag
* pPropBag
, BOOL fClearDirty
,
1996 BOOL fSaveAllProperties
1998 FIXME("(%p,%p,%d,%d), stub!\n", iface
, pPropBag
, fClearDirty
, fSaveAllProperties
);
2002 static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable
=
2004 OLEFontImpl_IPersistPropertyBag_QueryInterface
,
2005 OLEFontImpl_IPersistPropertyBag_AddRef
,
2006 OLEFontImpl_IPersistPropertyBag_Release
,
2008 OLEFontImpl_IPersistPropertyBag_GetClassID
,
2009 OLEFontImpl_IPersistPropertyBag_InitNew
,
2010 OLEFontImpl_IPersistPropertyBag_Load
,
2011 OLEFontImpl_IPersistPropertyBag_Save
2014 /************************************************************************
2015 * OLEFontImpl_Construct
2017 * This method will construct a new instance of the OLEFontImpl
2020 * The caller of this method must release the object when it's
2023 static OLEFontImpl
* OLEFontImpl_Construct(const FONTDESC
*fontDesc
)
2025 OLEFontImpl
* newObject
;
2027 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl
));
2032 newObject
->IFont_iface
.lpVtbl
= &OLEFontImpl_VTable
;
2033 newObject
->IDispatch_iface
.lpVtbl
= &OLEFontImpl_IDispatch_VTable
;
2034 newObject
->IPersistStream_iface
.lpVtbl
= &OLEFontImpl_IPersistStream_VTable
;
2035 newObject
->IConnectionPointContainer_iface
.lpVtbl
= &OLEFontImpl_IConnectionPointContainer_VTable
;
2036 newObject
->IPersistPropertyBag_iface
.lpVtbl
= &OLEFontImpl_IPersistPropertyBag_VTable
;
2040 newObject
->description
.cbSizeofstruct
= sizeof(FONTDESC
);
2041 newObject
->description
.lpstrName
= strdupW(fontDesc
->lpstrName
);
2042 newObject
->description
.cySize
= fontDesc
->cySize
;
2043 newObject
->description
.sWeight
= fontDesc
->sWeight
;
2044 newObject
->description
.sCharset
= fontDesc
->sCharset
;
2045 newObject
->description
.fItalic
= fontDesc
->fItalic
;
2046 newObject
->description
.fUnderline
= fontDesc
->fUnderline
;
2047 newObject
->description
.fStrikethrough
= fontDesc
->fStrikethrough
;
2049 newObject
->gdiFont
= 0;
2050 newObject
->dirty
= TRUE
;
2051 newObject
->cyLogical
= GetDeviceCaps(get_dc(), LOGPIXELSY
);
2052 newObject
->cyHimetric
= 2540L;
2053 newObject
->pPropertyNotifyCP
= NULL
;
2054 newObject
->pFontEventsCP
= NULL
;
2056 CreateConnectionPoint((IUnknown
*)&newObject
->IFont_iface
, &IID_IPropertyNotifySink
, &newObject
->pPropertyNotifyCP
);
2057 CreateConnectionPoint((IUnknown
*)&newObject
->IFont_iface
, &IID_IFontEventsDisp
, &newObject
->pFontEventsCP
);
2059 if (!newObject
->pPropertyNotifyCP
|| !newObject
->pFontEventsCP
)
2061 OLEFontImpl_Destroy(newObject
);
2065 InterlockedIncrement(&ifont_cnt
);
2067 TRACE("returning %p\n", newObject
);
2071 /************************************************************************
2072 * OLEFontImpl_Destroy
2074 * This method is called by the Release method when the reference
2075 * count goes down to 0. It will free all resources used by
2078 static void OLEFontImpl_Destroy(OLEFontImpl
* fontDesc
)
2080 TRACE("(%p)\n", fontDesc
);
2082 HeapFree(GetProcessHeap(), 0, fontDesc
->description
.lpstrName
);
2084 if (fontDesc
->pPropertyNotifyCP
)
2085 IConnectionPoint_Release(fontDesc
->pPropertyNotifyCP
);
2086 if (fontDesc
->pFontEventsCP
)
2087 IConnectionPoint_Release(fontDesc
->pFontEventsCP
);
2089 HeapFree(GetProcessHeap(), 0, fontDesc
);
2092 /*******************************************************************************
2093 * StdFont ClassFactory
2097 /* IUnknown fields */
2098 IClassFactory IClassFactory_iface
;
2100 } IClassFactoryImpl
;
2102 static inline IClassFactoryImpl
*impl_from_IClassFactory(IClassFactory
*iface
)
2104 return CONTAINING_RECORD(iface
, IClassFactoryImpl
, IClassFactory_iface
);
2107 static HRESULT WINAPI
SFCF_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **obj
)
2109 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2111 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), obj
);
2115 if (IsEqualIID(&IID_IClassFactory
, riid
) || IsEqualIID(&IID_IUnknown
, riid
))
2118 IClassFactory_AddRef(iface
);
2122 return E_NOINTERFACE
;
2126 SFCF_AddRef(LPCLASSFACTORY iface
) {
2127 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2128 return InterlockedIncrement(&This
->ref
);
2131 static ULONG WINAPI
SFCF_Release(LPCLASSFACTORY iface
) {
2132 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2133 /* static class, won't be freed */
2134 return InterlockedDecrement(&This
->ref
);
2137 static HRESULT WINAPI
SFCF_CreateInstance(
2138 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
2140 return OleCreateFontIndirect(NULL
,riid
,ppobj
);
2144 static HRESULT WINAPI
SFCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
2145 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2146 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
2150 static const IClassFactoryVtbl SFCF_Vtbl
= {
2151 SFCF_QueryInterface
,
2154 SFCF_CreateInstance
,
2157 static IClassFactoryImpl STDFONT_CF
= {{&SFCF_Vtbl
}, 1 };
2159 void _get_STDFONT_CF(LPVOID
*ppv
) { *ppv
= &STDFONT_CF
; }