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
27 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
29 /***********************************************************************
30 * Declaration of constants used when serializing the font object.
32 #define FONTPERSIST_ITALIC 0x02
33 #define FONTPERSIST_UNDERLINE 0x04
34 #define FONTPERSIST_STRIKETHROUGH 0x08
36 static HDC olefont_hdc
;
38 /***********************************************************************
39 * List of the HFONTs it has given out, with each one having a separate
42 typedef struct _HFONTItem
46 /* Reference count of any IFont objects that own this hfont */
49 /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
52 /* The font associated with this object. */
55 } HFONTItem
, *PHFONTItem
;
57 static struct list OLEFontImpl_hFontList
= LIST_INIT(OLEFontImpl_hFontList
);
59 /* Counts how many fonts contain at least one lock */
60 static LONG ifont_cnt
= 0;
62 /***********************************************************************
63 * Critical section for OLEFontImpl_hFontList
65 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST
;
66 static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug
=
68 0, 0, &OLEFontImpl_csHFONTLIST
,
69 { &OLEFontImpl_csHFONTLIST_debug
.ProcessLocksList
,
70 &OLEFontImpl_csHFONTLIST_debug
.ProcessLocksList
},
71 0, 0, { (DWORD_PTR
)(__FILE__
": OLEFontImpl_csHFONTLIST") }
73 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST
= { &OLEFontImpl_csHFONTLIST_debug
, -1, 0, 0, 0, 0 };
75 static HDC
get_dc(void)
78 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
80 olefont_hdc
= CreateCompatibleDC(NULL
);
82 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
86 static void delete_dc(void)
88 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
91 DeleteDC(olefont_hdc
);
94 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
97 static void HFONTItem_Delete(PHFONTItem item
)
99 DeleteObject(item
->gdiFont
);
100 list_remove(&item
->entry
);
101 HeapFree(GetProcessHeap(), 0, item
);
104 /* Find hfont item entry in the list. Should be called while holding the crit sect */
105 static HFONTItem
*find_hfontitem(HFONT hfont
)
109 LIST_FOR_EACH_ENTRY(item
, &OLEFontImpl_hFontList
, HFONTItem
, entry
)
111 if (item
->gdiFont
== hfont
)
117 /* Add an item to the list with one internal reference */
118 static HRESULT
add_hfontitem(HFONT hfont
)
120 HFONTItem
*new_item
= HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item
));
122 if(!new_item
) return E_OUTOFMEMORY
;
124 new_item
->int_refs
= 1;
125 new_item
->total_refs
= 1;
126 new_item
->gdiFont
= hfont
;
127 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
128 list_add_tail(&OLEFontImpl_hFontList
,&new_item
->entry
);
129 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
133 static HRESULT
inc_int_ref(HFONT hfont
)
136 HRESULT hr
= S_FALSE
;
138 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
139 item
= find_hfontitem(hfont
);
147 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
152 /* decrements the internal ref of a hfont item. If both refs are zero it'll
153 remove the item from the list and delete the hfont */
154 static HRESULT
dec_int_ref(HFONT hfont
)
157 HRESULT hr
= S_FALSE
;
159 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
160 item
= find_hfontitem(hfont
);
166 if(item
->int_refs
== 0 && item
->total_refs
== 0)
167 HFONTItem_Delete(item
);
170 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
175 static HRESULT
inc_ext_ref(HFONT hfont
)
178 HRESULT hr
= S_FALSE
;
180 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
182 item
= find_hfontitem(hfont
);
188 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
193 static HRESULT
dec_ext_ref(HFONT hfont
)
196 HRESULT hr
= S_FALSE
;
198 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
200 item
= find_hfontitem(hfont
);
203 if(--item
->total_refs
>= 0) hr
= S_OK
;
205 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
210 static WCHAR
*strdupW(const WCHAR
* str
)
213 DWORD size
= (strlenW(str
) + 1) * sizeof(WCHAR
);
215 ret
= HeapAlloc(GetProcessHeap(), 0, size
);
217 memcpy(ret
, str
, size
);
221 /***********************************************************************
222 * Declaration of the implementation class for the IFont interface
224 typedef struct OLEFontImpl OLEFontImpl
;
229 * This class supports many interfaces. IUnknown, IFont,
230 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
231 * The first two are supported by the first vtable, the next two are
232 * supported by the second table and the last two have their own.
235 IDispatch IDispatch_iface
;
236 IPersistStream IPersistStream_iface
;
237 IConnectionPointContainer IConnectionPointContainer_iface
;
238 IPersistPropertyBag IPersistPropertyBag_iface
;
239 IPersistStreamInit IPersistStreamInit_iface
;
241 * Reference count for that instance of the class.
246 * This structure contains the description of the class.
248 FONTDESC description
;
251 * Contain the font associated with this object.
262 * Stash realized height (pixels) from TEXTMETRIC - used in get_Size()
266 IConnectionPoint
*pPropertyNotifyCP
;
267 IConnectionPoint
*pFontEventsCP
;
270 static inline OLEFontImpl
*impl_from_IFont(IFont
*iface
)
272 return CONTAINING_RECORD(iface
, OLEFontImpl
, IFont_iface
);
275 static inline OLEFontImpl
*impl_from_IDispatch( IDispatch
*iface
)
277 return CONTAINING_RECORD(iface
, OLEFontImpl
, IDispatch_iface
);
280 static inline OLEFontImpl
*impl_from_IPersistStream( IPersistStream
*iface
)
282 return CONTAINING_RECORD(iface
, OLEFontImpl
, IPersistStream_iface
);
285 static inline OLEFontImpl
*impl_from_IConnectionPointContainer( IConnectionPointContainer
*iface
)
287 return CONTAINING_RECORD(iface
, OLEFontImpl
, IConnectionPointContainer_iface
);
290 static inline OLEFontImpl
*impl_from_IPersistPropertyBag( IPersistPropertyBag
*iface
)
292 return CONTAINING_RECORD(iface
, OLEFontImpl
, IPersistPropertyBag_iface
);
295 static inline OLEFontImpl
*impl_from_IPersistStreamInit( IPersistStreamInit
*iface
)
297 return CONTAINING_RECORD(iface
, OLEFontImpl
, IPersistStreamInit_iface
);
301 /***********************************************************************
302 * Prototypes for the implementation functions for the IFont
305 static OLEFontImpl
* OLEFontImpl_Construct(const FONTDESC
*fontDesc
);
306 static void OLEFontImpl_Destroy(OLEFontImpl
* fontDesc
);
307 static ULONG WINAPI
OLEFontImpl_AddRef(IFont
* iface
);
309 /******************************************************************************
310 * OleCreateFontIndirect [OLEAUT32.420]
312 HRESULT WINAPI
OleCreateFontIndirect(
313 LPFONTDESC lpFontDesc
,
317 OLEFontImpl
* newFont
;
321 TRACE("(%p, %s, %p)\n", lpFontDesc
, debugstr_guid(riid
), ppvObj
);
323 if (!ppvObj
) return E_POINTER
;
328 static WCHAR fname
[] = { 'S','y','s','t','e','m',0 };
330 fd
.cbSizeofstruct
= sizeof(fd
);
331 fd
.lpstrName
= fname
;
332 fd
.cySize
.s
.Lo
= 80000;
338 fd
.fStrikethrough
= 0;
342 newFont
= OLEFontImpl_Construct(lpFontDesc
);
343 if (!newFont
) return E_OUTOFMEMORY
;
345 hr
= IFont_QueryInterface(&newFont
->IFont_iface
, riid
, ppvObj
);
346 IFont_Release(&newFont
->IFont_iface
);
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 IFontEventsDisp_Invoke(disp
, DISPID_FONT_CHANGED
, &IID_NULL
,
425 LOCALE_NEUTRAL
, INVOKE_FUNC
, &dispparams
, NULL
,
428 IFontEventsDisp_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 = impl_from_IFont(iface
);
448 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid
), ppvObject
);
452 if (IsEqualGUID(&IID_IUnknown
, riid
) ||
453 IsEqualGUID(&IID_IFont
, riid
))
457 else if (IsEqualGUID(&IID_IDispatch
, riid
) ||
458 IsEqualGUID(&IID_IFontDisp
, riid
))
460 *ppvObject
= &this->IDispatch_iface
;
462 else if (IsEqualGUID(&IID_IPersist
, riid
) ||
463 IsEqualGUID(&IID_IPersistStream
, riid
))
465 *ppvObject
= &this->IPersistStream_iface
;
467 else if (IsEqualGUID(&IID_IConnectionPointContainer
, riid
))
469 *ppvObject
= &this->IConnectionPointContainer_iface
;
471 else if (IsEqualGUID(&IID_IPersistPropertyBag
, riid
))
473 *ppvObject
= &this->IPersistPropertyBag_iface
;
475 else if (IsEqualGUID(&IID_IPersistStreamInit
, riid
))
477 *ppvObject
= &this->IPersistStreamInit_iface
;
482 FIXME("() : asking for unsupported interface %s\n", debugstr_guid(riid
));
483 return E_NOINTERFACE
;
491 /************************************************************************
492 * OLEFontImpl_AddRef (IUnknown)
494 static ULONG WINAPI
OLEFontImpl_AddRef(
497 OLEFontImpl
*this = impl_from_IFont(iface
);
498 TRACE("(%p)->(ref=%d)\n", this, this->ref
);
499 return InterlockedIncrement(&this->ref
);
502 /************************************************************************
503 * OLEFontImpl_Release (IUnknown)
505 static ULONG WINAPI
OLEFontImpl_Release(IFont
* iface
)
507 OLEFontImpl
*this = impl_from_IFont(iface
);
510 TRACE("(%p)->(ref=%d)\n", this, this->ref
);
512 ref
= InterlockedDecrement(&this->ref
);
516 ULONG fontlist_refs
= InterlockedDecrement(&ifont_cnt
);
518 /* Final IFont object so destroy font cache */
519 if (fontlist_refs
== 0)
521 HFONTItem
*item
, *cursor2
;
523 EnterCriticalSection(&OLEFontImpl_csHFONTLIST
);
524 LIST_FOR_EACH_ENTRY_SAFE(item
, cursor2
, &OLEFontImpl_hFontList
, HFONTItem
, entry
)
525 HFONTItem_Delete(item
);
526 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST
);
531 dec_int_ref(this->gdiFont
);
533 OLEFontImpl_Destroy(this);
545 static int CALLBACK
font_enum_proc(const LOGFONTW
*elf
, const TEXTMETRICW
*ntm
, DWORD type
, LPARAM lp
)
547 enum_data
*data
= (enum_data
*)lp
;
549 if(elf
->lfCharSet
== data
->orig_cs
)
551 data
->avail_cs
= data
->orig_cs
;
554 if(data
->avail_cs
== -1) data
->avail_cs
= elf
->lfCharSet
;
558 static void realize_font(OLEFontImpl
*This
)
562 WCHAR text_face
[LF_FACESIZE
];
567 if (!This
->dirty
) return;
573 old_font
= SelectObject(hdc
, This
->gdiFont
);
574 GetTextFaceW(hdc
, sizeof(text_face
) / sizeof(text_face
[0]), text_face
);
575 SelectObject(hdc
, old_font
);
576 dec_int_ref(This
->gdiFont
);
580 memset(&logFont
, 0, sizeof(LOGFONTW
));
582 lstrcpynW(logFont
.lfFaceName
, This
->description
.lpstrName
, LF_FACESIZE
);
583 logFont
.lfCharSet
= This
->description
.sCharset
;
585 /* If the font name has been changed then enumerate all charsets
586 and pick one that'll result in the font specified being selected */
587 if(text_face
[0] && lstrcmpiW(text_face
, This
->description
.lpstrName
))
590 data
.orig_cs
= This
->description
.sCharset
;
592 logFont
.lfCharSet
= DEFAULT_CHARSET
;
593 EnumFontFamiliesExW(get_dc(), &logFont
, font_enum_proc
, (LPARAM
)&data
, 0);
594 if(data
.avail_cs
!= -1) logFont
.lfCharSet
= data
.avail_cs
;
598 * The height of the font returned by the get_Size property is the
599 * height of the font in points multiplied by 10000... Using some
600 * simple conversions and the ratio given by the application, it can
601 * be converted to a height in pixels.
603 * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
604 * Ratio is applied here relative to the standard.
607 fontHeight
= MulDiv( This
->description
.cySize
.s
.Lo
, This
->cyLogical
*635, This
->cyHimetric
*18 );
609 logFont
.lfHeight
= ((fontHeight
%10000L)>5000L) ? (-fontHeight
/10000L) - 1 :
610 (-fontHeight
/10000L);
611 logFont
.lfItalic
= This
->description
.fItalic
;
612 logFont
.lfUnderline
= This
->description
.fUnderline
;
613 logFont
.lfStrikeOut
= This
->description
.fStrikethrough
;
614 logFont
.lfWeight
= This
->description
.sWeight
;
615 logFont
.lfOutPrecision
= OUT_CHARACTER_PRECIS
;
616 logFont
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
617 logFont
.lfQuality
= DEFAULT_QUALITY
;
618 logFont
.lfPitchAndFamily
= DEFAULT_PITCH
;
620 This
->gdiFont
= CreateFontIndirectW(&logFont
);
623 add_hfontitem(This
->gdiFont
);
625 /* Fixup the name and charset properties so that they match the
627 old_font
= SelectObject(get_dc(), This
->gdiFont
);
628 GetTextFaceW(hdc
, sizeof(text_face
) / sizeof(text_face
[0]), text_face
);
629 if(lstrcmpiW(text_face
, This
->description
.lpstrName
))
631 HeapFree(GetProcessHeap(), 0, This
->description
.lpstrName
);
632 This
->description
.lpstrName
= strdupW(text_face
);
634 GetTextMetricsW(hdc
, &tm
);
635 This
->description
.sCharset
= tm
.tmCharSet
;
636 /* While we have it handy, stash the realized font height for use by get_Size() */
637 This
->nRealHeight
= tm
.tmHeight
- tm
.tmInternalLeading
; /* corresponds to LOGFONT lfHeight */
638 SelectObject(hdc
, old_font
);
641 /************************************************************************
642 * OLEFontImpl_get_Name (IFont)
644 * See Windows documentation for more details on IFont methods.
646 static HRESULT WINAPI
OLEFontImpl_get_Name(
650 OLEFontImpl
*this = impl_from_IFont(iface
);
651 TRACE("(%p)->(%p)\n", this, pname
);
658 if (this->description
.lpstrName
!=0)
659 *pname
= SysAllocString(this->description
.lpstrName
);
666 /************************************************************************
667 * OLEFontImpl_put_Name (IFont)
669 static HRESULT WINAPI
OLEFontImpl_put_Name(
673 OLEFontImpl
*This
= impl_from_IFont(iface
);
674 TRACE("(%p)->(%p)\n", This
, name
);
677 return CTL_E_INVALIDPROPERTYVALUE
;
679 HeapFree(GetProcessHeap(), 0, This
->description
.lpstrName
);
680 This
->description
.lpstrName
= strdupW(name
);
681 if (!This
->description
.lpstrName
) return E_OUTOFMEMORY
;
683 TRACE("new name %s\n", debugstr_w(This
->description
.lpstrName
));
684 OLEFont_SendNotify(This
, DISPID_FONT_NAME
);
688 /************************************************************************
689 * OLEFontImpl_get_Size (IFont)
691 static HRESULT WINAPI
OLEFontImpl_get_Size(
695 OLEFontImpl
*this = impl_from_IFont(iface
);
696 TRACE("(%p)->(%p)\n", this, psize
);
698 if (!psize
) return E_POINTER
;
703 * Convert realized font height in pixels to points descaled by current
704 * scaling ratio then scaled up by 10000.
706 psize
->s
.Lo
= MulDiv(this->nRealHeight
,
707 this->cyHimetric
* 72 * 10000,
708 this->cyLogical
* 2540);
714 /************************************************************************
715 * OLEFontImpl_put_Size (IFont)
717 static HRESULT WINAPI
OLEFontImpl_put_Size(
721 OLEFontImpl
*this = impl_from_IFont(iface
);
722 TRACE("(%p)->(%d)\n", this, size
.s
.Lo
);
723 this->description
.cySize
.s
.Hi
= 0;
724 this->description
.cySize
.s
.Lo
= size
.s
.Lo
;
725 OLEFont_SendNotify(this, DISPID_FONT_SIZE
);
730 /************************************************************************
731 * OLEFontImpl_get_Bold (IFont)
733 * See Windows documentation for more details on IFont methods.
735 static HRESULT WINAPI
OLEFontImpl_get_Bold(
739 OLEFontImpl
*this = impl_from_IFont(iface
);
740 TRACE("(%p)->(%p)\n", this, pbold
);
742 if (!pbold
) return E_POINTER
;
746 *pbold
= this->description
.sWeight
> 550;
751 /************************************************************************
752 * OLEFontImpl_put_Bold (IFont)
754 static HRESULT WINAPI
OLEFontImpl_put_Bold(
758 OLEFontImpl
*this = impl_from_IFont(iface
);
759 TRACE("(%p)->(%d)\n", this, bold
);
760 this->description
.sWeight
= bold
? FW_BOLD
: FW_NORMAL
;
761 OLEFont_SendNotify(this, DISPID_FONT_BOLD
);
766 /************************************************************************
767 * OLEFontImpl_get_Italic (IFont)
769 static HRESULT WINAPI
OLEFontImpl_get_Italic(
773 OLEFontImpl
*this = impl_from_IFont(iface
);
774 TRACE("(%p)->(%p)\n", this, pitalic
);
781 *pitalic
= this->description
.fItalic
;
786 /************************************************************************
787 * OLEFontImpl_put_Italic (IFont)
789 static HRESULT WINAPI
OLEFontImpl_put_Italic(
793 OLEFontImpl
*this = impl_from_IFont(iface
);
794 TRACE("(%p)->(%d)\n", this, italic
);
796 this->description
.fItalic
= italic
;
798 OLEFont_SendNotify(this, DISPID_FONT_ITALIC
);
802 /************************************************************************
803 * OLEFontImpl_get_Underline (IFont)
805 static HRESULT WINAPI
OLEFontImpl_get_Underline(
809 OLEFontImpl
*this = impl_from_IFont(iface
);
810 TRACE("(%p)->(%p)\n", this, punderline
);
817 *punderline
= this->description
.fUnderline
;
822 /************************************************************************
823 * OLEFontImpl_put_Underline (IFont)
825 static HRESULT WINAPI
OLEFontImpl_put_Underline(
829 OLEFontImpl
*this = impl_from_IFont(iface
);
830 TRACE("(%p)->(%d)\n", this, underline
);
832 this->description
.fUnderline
= underline
;
834 OLEFont_SendNotify(this, DISPID_FONT_UNDER
);
838 /************************************************************************
839 * OLEFontImpl_get_Strikethrough (IFont)
841 static HRESULT WINAPI
OLEFontImpl_get_Strikethrough(
843 BOOL
* pstrikethrough
)
845 OLEFontImpl
*this = impl_from_IFont(iface
);
846 TRACE("(%p)->(%p)\n", this, pstrikethrough
);
848 if (pstrikethrough
==0)
853 *pstrikethrough
= this->description
.fStrikethrough
;
858 /************************************************************************
859 * OLEFontImpl_put_Strikethrough (IFont)
861 static HRESULT WINAPI
OLEFontImpl_put_Strikethrough(
865 OLEFontImpl
*this = impl_from_IFont(iface
);
866 TRACE("(%p)->(%d)\n", this, strikethrough
);
868 this->description
.fStrikethrough
= strikethrough
;
869 OLEFont_SendNotify(this, DISPID_FONT_STRIKE
);
874 /************************************************************************
875 * OLEFontImpl_get_Weight (IFont)
877 static HRESULT WINAPI
OLEFontImpl_get_Weight(
881 OLEFontImpl
*this = impl_from_IFont(iface
);
882 TRACE("(%p)->(%p)\n", this, pweight
);
889 *pweight
= this->description
.sWeight
;
894 /************************************************************************
895 * OLEFontImpl_put_Weight (IFont)
897 static HRESULT WINAPI
OLEFontImpl_put_Weight(
901 OLEFontImpl
*this = impl_from_IFont(iface
);
902 TRACE("(%p)->(%d)\n", this, weight
);
904 this->description
.sWeight
= weight
;
906 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT
);
910 /************************************************************************
911 * OLEFontImpl_get_Charset (IFont)
913 static HRESULT WINAPI
OLEFontImpl_get_Charset(
917 OLEFontImpl
*this = impl_from_IFont(iface
);
918 TRACE("(%p)->(%p)\n", this, pcharset
);
925 *pcharset
= this->description
.sCharset
;
930 /************************************************************************
931 * OLEFontImpl_put_Charset (IFont)
933 static HRESULT WINAPI
OLEFontImpl_put_Charset(
937 OLEFontImpl
*this = impl_from_IFont(iface
);
938 TRACE("(%p)->(%d)\n", this, charset
);
940 this->description
.sCharset
= charset
;
941 OLEFont_SendNotify(this, DISPID_FONT_CHARSET
);
946 /************************************************************************
947 * OLEFontImpl_get_hFont (IFont)
949 static HRESULT WINAPI
OLEFontImpl_get_hFont(
953 OLEFontImpl
*this = impl_from_IFont(iface
);
954 TRACE("(%p)->(%p)\n", this, phfont
);
960 *phfont
= this->gdiFont
;
961 TRACE("Returning %p\n", *phfont
);
965 /************************************************************************
966 * OLEFontImpl_Clone (IFont)
968 static HRESULT WINAPI
OLEFontImpl_Clone(
972 OLEFontImpl
*this = impl_from_IFont(iface
);
973 OLEFontImpl
* newObject
;
975 TRACE("(%p)->(%p)\n", this, ppfont
);
982 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl
));
984 return E_OUTOFMEMORY
;
987 /* allocate separate buffer */
988 newObject
->description
.lpstrName
= strdupW(this->description
.lpstrName
);
990 /* Increment internal ref in hfont item list */
991 if(newObject
->gdiFont
) inc_int_ref(newObject
->gdiFont
);
993 InterlockedIncrement(&ifont_cnt
);
995 newObject
->pPropertyNotifyCP
= NULL
;
996 newObject
->pFontEventsCP
= NULL
;
997 CreateConnectionPoint((IUnknown
*)newObject
, &IID_IPropertyNotifySink
, &newObject
->pPropertyNotifyCP
);
998 CreateConnectionPoint((IUnknown
*)newObject
, &IID_IFontEventsDisp
, &newObject
->pFontEventsCP
);
1000 if (!newObject
->pPropertyNotifyCP
|| !newObject
->pFontEventsCP
)
1002 OLEFontImpl_Destroy(newObject
);
1003 return E_OUTOFMEMORY
;
1006 /* The cloned object starts with a reference count of 1 */
1009 *ppfont
= &newObject
->IFont_iface
;
1014 /************************************************************************
1015 * OLEFontImpl_IsEqual (IFont)
1017 static HRESULT WINAPI
OLEFontImpl_IsEqual(
1021 OLEFontImpl
*left
= impl_from_IFont(iface
);
1022 OLEFontImpl
*right
= impl_from_IFont(pFontOther
);
1024 INT left_len
,right_len
;
1026 if(pFontOther
== NULL
)
1028 else if (left
->description
.cySize
.s
.Lo
!= right
->description
.cySize
.s
.Lo
)
1030 else if (left
->description
.cySize
.s
.Hi
!= right
->description
.cySize
.s
.Hi
)
1032 else if (left
->description
.sWeight
!= right
->description
.sWeight
)
1034 else if (left
->description
.sCharset
!= right
->description
.sCharset
)
1036 else if (left
->description
.fItalic
!= right
->description
.fItalic
)
1038 else if (left
->description
.fUnderline
!= right
->description
.fUnderline
)
1040 else if (left
->description
.fStrikethrough
!= right
->description
.fStrikethrough
)
1043 /* Check from string */
1044 left_len
= strlenW(left
->description
.lpstrName
);
1045 right_len
= strlenW(right
->description
.lpstrName
);
1046 ret
= CompareStringW(0,0,left
->description
.lpstrName
, left_len
,
1047 right
->description
.lpstrName
, right_len
);
1048 if (ret
!= CSTR_EQUAL
)
1054 /************************************************************************
1055 * OLEFontImpl_SetRatio (IFont)
1057 static HRESULT WINAPI
OLEFontImpl_SetRatio(
1062 OLEFontImpl
*this = impl_from_IFont(iface
);
1063 TRACE("(%p)->(%d, %d)\n", this, cyLogical
, cyHimetric
);
1065 if(cyLogical
== 0 || cyHimetric
== 0)
1066 return E_INVALIDARG
;
1068 this->cyLogical
= cyLogical
;
1069 this->cyHimetric
= cyHimetric
;
1075 /************************************************************************
1076 * OLEFontImpl_QueryTextMetrics (IFont)
1078 static HRESULT WINAPI
OLEFontImpl_QueryTextMetrics(
1083 HFONT hOldFont
, hNewFont
;
1086 IFont_get_hFont(iface
, &hNewFont
);
1087 hOldFont
= SelectObject(hdcRef
, hNewFont
);
1088 GetTextMetricsW(hdcRef
, ptm
);
1089 SelectObject(hdcRef
, hOldFont
);
1090 ReleaseDC(0, hdcRef
);
1094 /************************************************************************
1095 * OLEFontImpl_AddRefHfont (IFont)
1097 static HRESULT WINAPI
OLEFontImpl_AddRefHfont(
1101 OLEFontImpl
*this = impl_from_IFont(iface
);
1103 TRACE("(%p)->(%p)\n", this, hfont
);
1105 if (!hfont
) return E_INVALIDARG
;
1107 return inc_ext_ref(hfont
);
1110 /************************************************************************
1111 * OLEFontImpl_ReleaseHfont (IFont)
1113 static HRESULT WINAPI
OLEFontImpl_ReleaseHfont(
1117 OLEFontImpl
*this = impl_from_IFont(iface
);
1119 TRACE("(%p)->(%p)\n", this, hfont
);
1121 if (!hfont
) return E_INVALIDARG
;
1123 return dec_ext_ref(hfont
);
1126 /************************************************************************
1127 * OLEFontImpl_SetHdc (IFont)
1129 static HRESULT WINAPI
OLEFontImpl_SetHdc(
1133 OLEFontImpl
*this = impl_from_IFont(iface
);
1134 FIXME("(%p)->(%p): Stub\n", this, hdc
);
1138 static const IFontVtbl OLEFontImpl_VTable
=
1140 OLEFontImpl_QueryInterface
,
1142 OLEFontImpl_Release
,
1143 OLEFontImpl_get_Name
,
1144 OLEFontImpl_put_Name
,
1145 OLEFontImpl_get_Size
,
1146 OLEFontImpl_put_Size
,
1147 OLEFontImpl_get_Bold
,
1148 OLEFontImpl_put_Bold
,
1149 OLEFontImpl_get_Italic
,
1150 OLEFontImpl_put_Italic
,
1151 OLEFontImpl_get_Underline
,
1152 OLEFontImpl_put_Underline
,
1153 OLEFontImpl_get_Strikethrough
,
1154 OLEFontImpl_put_Strikethrough
,
1155 OLEFontImpl_get_Weight
,
1156 OLEFontImpl_put_Weight
,
1157 OLEFontImpl_get_Charset
,
1158 OLEFontImpl_put_Charset
,
1159 OLEFontImpl_get_hFont
,
1161 OLEFontImpl_IsEqual
,
1162 OLEFontImpl_SetRatio
,
1163 OLEFontImpl_QueryTextMetrics
,
1164 OLEFontImpl_AddRefHfont
,
1165 OLEFontImpl_ReleaseHfont
,
1169 /************************************************************************
1170 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1172 static HRESULT WINAPI
OLEFontImpl_IDispatch_QueryInterface(
1177 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1178 return IFont_QueryInterface(&this->IFont_iface
, riid
, ppvoid
);
1181 /************************************************************************
1182 * OLEFontImpl_IDispatch_Release (IUnknown)
1184 static ULONG WINAPI
OLEFontImpl_IDispatch_Release(
1187 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1188 return IFont_Release(&this->IFont_iface
);
1191 /************************************************************************
1192 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1194 static ULONG WINAPI
OLEFontImpl_IDispatch_AddRef(
1197 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1198 return IFont_AddRef(&this->IFont_iface
);
1201 /************************************************************************
1202 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1204 static HRESULT WINAPI
OLEFontImpl_GetTypeInfoCount(
1206 unsigned int* pctinfo
)
1208 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1209 TRACE("(%p)->(%p)\n", this, pctinfo
);
1215 /************************************************************************
1216 * OLEFontImpl_GetTypeInfo (IDispatch)
1218 static HRESULT WINAPI
OLEFontImpl_GetTypeInfo(
1222 ITypeInfo
** ppTInfo
)
1224 static const WCHAR stdole2tlb
[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
1228 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1229 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo
, (int)lcid
, ppTInfo
);
1232 hres
= LoadTypeLib(stdole2tlb
, &tl
);
1234 ERR("Could not load the stdole2.tlb?\n");
1237 hres
= ITypeLib_GetTypeInfoOfGuid(tl
, &IID_IFontDisp
, ppTInfo
);
1238 ITypeLib_Release(tl
);
1240 FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres
);
1245 /************************************************************************
1246 * OLEFontImpl_GetIDsOfNames (IDispatch)
1248 static HRESULT WINAPI
OLEFontImpl_GetIDsOfNames(
1251 LPOLESTR
* rgszNames
,
1259 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1261 TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid
),
1262 rgszNames
, cNames
, (int)lcid
, rgDispId
);
1264 if (cNames
== 0) return E_INVALIDARG
;
1266 hres
= IDispatch_GetTypeInfo(iface
, 0, lcid
, &pTInfo
);
1269 ERR("GetTypeInfo failed.\n");
1273 /* convert names to DISPIDs */
1274 hres
= DispGetIDsOfNames (pTInfo
, rgszNames
, cNames
, rgDispId
);
1275 ITypeInfo_Release(pTInfo
);
1280 /************************************************************************
1281 * OLEFontImpl_Invoke (IDispatch)
1283 * Note: Do not call _put_Xxx methods, since setting things here
1284 * should not call notify functions as I found out debugging the generic
1287 static HRESULT WINAPI
OLEFontImpl_Invoke(
1289 DISPID dispIdMember
,
1293 DISPPARAMS
* pDispParams
,
1294 VARIANT
* pVarResult
,
1295 EXCEPINFO
* pExepInfo
,
1298 OLEFontImpl
*this = impl_from_IDispatch(iface
);
1301 TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember
,
1302 debugstr_guid(riid
), lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
,
1305 /* validate parameters */
1307 if (!IsEqualIID(riid
, &IID_NULL
))
1309 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid
));
1310 return DISP_E_UNKNOWNINTERFACE
;
1313 if (wFlags
& DISPATCH_PROPERTYGET
)
1317 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1318 return DISP_E_PARAMNOTOPTIONAL
;
1321 else if (wFlags
& DISPATCH_PROPERTYPUT
)
1325 ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n");
1326 return DISP_E_PARAMNOTOPTIONAL
;
1328 if (pDispParams
->cArgs
!= 1)
1330 ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams
->cArgs
);
1331 return DISP_E_BADPARAMCOUNT
;
1336 ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n");
1337 return DISP_E_MEMBERNOTFOUND
;
1340 switch (dispIdMember
) {
1341 case DISPID_FONT_NAME
:
1342 if (wFlags
& DISPATCH_PROPERTYGET
) {
1343 V_VT(pVarResult
) = VT_BSTR
;
1344 return IFont_get_Name(&this->IFont_iface
, &V_BSTR(pVarResult
));
1348 VariantInit(&vararg
);
1349 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BSTR
);
1353 hr
= IFont_put_Name(&this->IFont_iface
, V_BSTR(&vararg
));
1355 VariantClear(&vararg
);
1359 case DISPID_FONT_BOLD
:
1360 if (wFlags
& DISPATCH_PROPERTYGET
) {
1362 hr
= IFont_get_Bold(&this->IFont_iface
, &value
);
1363 V_VT(pVarResult
) = VT_BOOL
;
1364 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1369 VariantInit(&vararg
);
1370 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1374 hr
= IFont_put_Bold(&this->IFont_iface
, V_BOOL(&vararg
));
1376 VariantClear(&vararg
);
1380 case DISPID_FONT_ITALIC
:
1381 if (wFlags
& DISPATCH_PROPERTYGET
) {
1383 hr
= IFont_get_Italic(&this->IFont_iface
, &value
);
1384 V_VT(pVarResult
) = VT_BOOL
;
1385 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1390 VariantInit(&vararg
);
1391 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1395 hr
= IFont_put_Italic(&this->IFont_iface
, V_BOOL(&vararg
));
1397 VariantClear(&vararg
);
1401 case DISPID_FONT_UNDER
:
1402 if (wFlags
& DISPATCH_PROPERTYGET
) {
1404 hr
= IFont_get_Underline(&this->IFont_iface
, &value
);
1405 V_VT(pVarResult
) = VT_BOOL
;
1406 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1411 VariantInit(&vararg
);
1412 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1416 hr
= IFont_put_Underline(&this->IFont_iface
, V_BOOL(&vararg
));
1418 VariantClear(&vararg
);
1422 case DISPID_FONT_STRIKE
:
1423 if (wFlags
& DISPATCH_PROPERTYGET
) {
1425 hr
= IFont_get_Strikethrough(&this->IFont_iface
, &value
);
1426 V_VT(pVarResult
) = VT_BOOL
;
1427 V_BOOL(pVarResult
) = value
? VARIANT_TRUE
: VARIANT_FALSE
;
1432 VariantInit(&vararg
);
1433 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_BOOL
);
1437 hr
= IFont_put_Strikethrough(&this->IFont_iface
, V_BOOL(&vararg
));
1439 VariantClear(&vararg
);
1443 case DISPID_FONT_SIZE
:
1444 if (wFlags
& DISPATCH_PROPERTYGET
) {
1445 V_VT(pVarResult
) = VT_CY
;
1446 return IFont_get_Size(&this->IFont_iface
, &V_CY(pVarResult
));
1450 VariantInit(&vararg
);
1451 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_CY
);
1455 hr
= IFont_put_Size(&this->IFont_iface
, V_CY(&vararg
));
1457 VariantClear(&vararg
);
1461 case DISPID_FONT_WEIGHT
:
1462 if (wFlags
& DISPATCH_PROPERTYGET
) {
1463 V_VT(pVarResult
) = VT_I2
;
1464 return IFont_get_Weight(&this->IFont_iface
, &V_I2(pVarResult
));
1468 VariantInit(&vararg
);
1469 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_I2
);
1473 hr
= IFont_put_Weight(&this->IFont_iface
, V_I2(&vararg
));
1475 VariantClear(&vararg
);
1479 case DISPID_FONT_CHARSET
:
1480 if (wFlags
& DISPATCH_PROPERTYGET
) {
1481 V_VT(pVarResult
) = VT_I2
;
1482 return OLEFontImpl_get_Charset(&this->IFont_iface
, &V_I2(pVarResult
));
1486 VariantInit(&vararg
);
1487 hr
= VariantChangeTypeEx(&vararg
, &pDispParams
->rgvarg
[0], lcid
, 0, VT_I2
);
1491 hr
= IFont_put_Charset(&this->IFont_iface
, V_I2(&vararg
));
1493 VariantClear(&vararg
);
1498 ERR("member not found for dispid 0x%x\n", dispIdMember
);
1499 return DISP_E_MEMBERNOTFOUND
;
1503 static const IDispatchVtbl OLEFontImpl_IDispatch_VTable
=
1505 OLEFontImpl_IDispatch_QueryInterface
,
1506 OLEFontImpl_IDispatch_AddRef
,
1507 OLEFontImpl_IDispatch_Release
,
1508 OLEFontImpl_GetTypeInfoCount
,
1509 OLEFontImpl_GetTypeInfo
,
1510 OLEFontImpl_GetIDsOfNames
,
1514 /************************************************************************
1515 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1517 static HRESULT WINAPI
OLEFontImpl_IPersistStream_QueryInterface(
1518 IPersistStream
* iface
,
1522 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1524 return IFont_QueryInterface(&this->IFont_iface
, riid
, ppvoid
);
1527 /************************************************************************
1528 * OLEFontImpl_IPersistStream_Release (IUnknown)
1530 static ULONG WINAPI
OLEFontImpl_IPersistStream_Release(
1531 IPersistStream
* iface
)
1533 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1535 return IFont_Release(&this->IFont_iface
);
1538 /************************************************************************
1539 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1541 static ULONG WINAPI
OLEFontImpl_IPersistStream_AddRef(
1542 IPersistStream
* iface
)
1544 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1546 return IFont_AddRef(&this->IFont_iface
);
1549 /************************************************************************
1550 * OLEFontImpl_GetClassID (IPersistStream)
1552 static HRESULT WINAPI
OLEFontImpl_GetClassID(
1553 IPersistStream
* iface
,
1556 TRACE("(%p,%p)\n",iface
,pClassID
);
1560 *pClassID
= CLSID_StdFont
;
1565 /************************************************************************
1566 * OLEFontImpl_IsDirty (IPersistStream)
1568 * See Windows documentation for more details on IPersistStream methods.
1570 static HRESULT WINAPI
OLEFontImpl_IsDirty(
1571 IPersistStream
* iface
)
1573 TRACE("(%p)\n",iface
);
1577 /************************************************************************
1578 * OLEFontImpl_Load (IPersistStream)
1580 * See Windows documentation for more details on IPersistStream methods.
1582 * This is the format of the standard font serialization as far as I
1585 * Offset Type Value Comment
1586 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1587 * 0x0001 Short Charset Charset value from the FONTDESC structure
1588 * 0x0003 Byte Attributes Flags defined as follows:
1590 * 00000100 - Underline
1591 * 00001000 - Strikethrough
1592 * 0x0004 Short Weight Weight value from FONTDESC structure
1593 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1595 * 0x000A Byte name length Length of the font name string (no null character)
1596 * 0x000B String name Name of the font (ASCII, no nul character)
1598 static HRESULT WINAPI
OLEFontImpl_Load(
1599 IPersistStream
* iface
,
1600 IStream
* pLoadStream
)
1602 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1603 BYTE version
, attributes
, string_size
;
1604 char readBuffer
[0x100];
1609 IStream_Read(pLoadStream
, &version
, sizeof(BYTE
), &cbRead
);
1610 if ((cbRead
!= sizeof(BYTE
)) || (version
!= 0x01)) return E_FAIL
;
1613 IStream_Read(pLoadStream
, &this->description
.sCharset
, sizeof(WORD
), &cbRead
);
1614 if (cbRead
!= sizeof(WORD
)) return E_FAIL
;
1617 IStream_Read(pLoadStream
, &attributes
, sizeof(BYTE
), &cbRead
);
1618 if (cbRead
!= sizeof(BYTE
)) return E_FAIL
;
1620 this->description
.fItalic
= (attributes
& FONTPERSIST_ITALIC
) != 0;
1621 this->description
.fStrikethrough
= (attributes
& FONTPERSIST_STRIKETHROUGH
) != 0;
1622 this->description
.fUnderline
= (attributes
& FONTPERSIST_UNDERLINE
) != 0;
1625 IStream_Read(pLoadStream
, &this->description
.sWeight
, sizeof(WORD
), &cbRead
);
1626 if (cbRead
!= sizeof(WORD
)) return E_FAIL
;
1629 IStream_Read(pLoadStream
, &this->description
.cySize
.s
.Lo
, sizeof(DWORD
), &cbRead
);
1630 if (cbRead
!= sizeof(DWORD
)) return E_FAIL
;
1632 this->description
.cySize
.s
.Hi
= 0;
1635 IStream_Read(pLoadStream
, &string_size
, sizeof(BYTE
), &cbRead
);
1636 if (cbRead
!= sizeof(BYTE
)) return E_FAIL
;
1638 IStream_Read(pLoadStream
, readBuffer
, string_size
, &cbRead
);
1639 if (cbRead
!= string_size
) return E_FAIL
;
1641 HeapFree(GetProcessHeap(), 0, this->description
.lpstrName
);
1643 len
= MultiByteToWideChar( CP_ACP
, 0, readBuffer
, string_size
, NULL
, 0 );
1644 this->description
.lpstrName
= HeapAlloc( GetProcessHeap(), 0, (len
+1) * sizeof(WCHAR
) );
1645 MultiByteToWideChar( CP_ACP
, 0, readBuffer
, string_size
, this->description
.lpstrName
, len
);
1646 this->description
.lpstrName
[len
] = 0;
1648 /* Ensure use of this font causes a new one to be created */
1649 dec_int_ref(this->gdiFont
);
1656 /************************************************************************
1657 * OLEFontImpl_Save (IPersistStream)
1659 static HRESULT WINAPI
OLEFontImpl_Save(
1660 IPersistStream
* iface
,
1661 IStream
* pOutStream
,
1664 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1665 BYTE attributes
, string_size
;
1666 const BYTE version
= 0x01;
1667 char* writeBuffer
= NULL
;
1670 TRACE("(%p)->(%p %d)\n", this, pOutStream
, fClearDirty
);
1673 IStream_Write(pOutStream
, &version
, sizeof(BYTE
), &written
);
1674 if (written
!= sizeof(BYTE
)) return E_FAIL
;
1677 IStream_Write(pOutStream
, &this->description
.sCharset
, sizeof(WORD
), &written
);
1678 if (written
!= sizeof(WORD
)) return E_FAIL
;
1683 if (this->description
.fItalic
)
1684 attributes
|= FONTPERSIST_ITALIC
;
1686 if (this->description
.fStrikethrough
)
1687 attributes
|= FONTPERSIST_STRIKETHROUGH
;
1689 if (this->description
.fUnderline
)
1690 attributes
|= FONTPERSIST_UNDERLINE
;
1692 IStream_Write(pOutStream
, &attributes
, sizeof(BYTE
), &written
);
1693 if (written
!= sizeof(BYTE
)) return E_FAIL
;
1696 IStream_Write(pOutStream
, &this->description
.sWeight
, sizeof(WORD
), &written
);
1697 if (written
!= sizeof(WORD
)) return E_FAIL
;
1700 IStream_Write(pOutStream
, &this->description
.cySize
.s
.Lo
, sizeof(DWORD
), &written
);
1701 if (written
!= sizeof(DWORD
)) return E_FAIL
;
1704 if (this->description
.lpstrName
)
1705 string_size
= WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1706 strlenW(this->description
.lpstrName
), NULL
, 0, NULL
, NULL
);
1710 IStream_Write(pOutStream
, &string_size
, sizeof(BYTE
), &written
);
1711 if (written
!= sizeof(BYTE
)) return E_FAIL
;
1715 if (!(writeBuffer
= HeapAlloc( GetProcessHeap(), 0, string_size
))) return E_OUTOFMEMORY
;
1716 WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1717 strlenW(this->description
.lpstrName
),
1718 writeBuffer
, string_size
, NULL
, NULL
);
1720 IStream_Write(pOutStream
, writeBuffer
, string_size
, &written
);
1721 HeapFree(GetProcessHeap(), 0, writeBuffer
);
1723 if (written
!= string_size
) return E_FAIL
;
1729 /************************************************************************
1730 * OLEFontImpl_GetSizeMax (IPersistStream)
1732 static HRESULT WINAPI
OLEFontImpl_GetSizeMax(
1733 IPersistStream
* iface
,
1734 ULARGE_INTEGER
* pcbSize
)
1736 OLEFontImpl
*this = impl_from_IPersistStream(iface
);
1741 pcbSize
->u
.HighPart
= 0;
1742 pcbSize
->u
.LowPart
= 0;
1744 pcbSize
->u
.LowPart
+= sizeof(BYTE
); /* Version */
1745 pcbSize
->u
.LowPart
+= sizeof(WORD
); /* Lang code */
1746 pcbSize
->u
.LowPart
+= sizeof(BYTE
); /* Flags */
1747 pcbSize
->u
.LowPart
+= sizeof(WORD
); /* Weight */
1748 pcbSize
->u
.LowPart
+= sizeof(DWORD
); /* Size */
1749 pcbSize
->u
.LowPart
+= sizeof(BYTE
); /* StrLength */
1751 if (this->description
.lpstrName
!=0)
1752 pcbSize
->u
.LowPart
+= WideCharToMultiByte( CP_ACP
, 0, this->description
.lpstrName
,
1753 strlenW(this->description
.lpstrName
),
1754 NULL
, 0, NULL
, NULL
);
1759 static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable
=
1761 OLEFontImpl_IPersistStream_QueryInterface
,
1762 OLEFontImpl_IPersistStream_AddRef
,
1763 OLEFontImpl_IPersistStream_Release
,
1764 OLEFontImpl_GetClassID
,
1765 OLEFontImpl_IsDirty
,
1768 OLEFontImpl_GetSizeMax
1771 /************************************************************************
1772 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1774 static HRESULT WINAPI
OLEFontImpl_IConnectionPointContainer_QueryInterface(
1775 IConnectionPointContainer
* iface
,
1779 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1781 return IFont_QueryInterface(&this->IFont_iface
, riid
, ppvoid
);
1784 /************************************************************************
1785 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1787 static ULONG WINAPI
OLEFontImpl_IConnectionPointContainer_Release(
1788 IConnectionPointContainer
* iface
)
1790 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1792 return IFont_Release(&this->IFont_iface
);
1795 /************************************************************************
1796 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1798 static ULONG WINAPI
OLEFontImpl_IConnectionPointContainer_AddRef(
1799 IConnectionPointContainer
* iface
)
1801 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1803 return IFont_AddRef(&this->IFont_iface
);
1806 /************************************************************************
1807 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1809 static HRESULT WINAPI
OLEFontImpl_EnumConnectionPoints(
1810 IConnectionPointContainer
* iface
,
1811 IEnumConnectionPoints
**ppEnum
)
1813 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1815 FIXME("(%p)->(%p): stub\n", this, ppEnum
);
1819 /************************************************************************
1820 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1822 static HRESULT WINAPI
OLEFontImpl_FindConnectionPoint(
1823 IConnectionPointContainer
* iface
,
1825 IConnectionPoint
**ppCp
)
1827 OLEFontImpl
*this = impl_from_IConnectionPointContainer(iface
);
1828 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid
), ppCp
);
1830 if(IsEqualIID(riid
, &IID_IPropertyNotifySink
)) {
1831 return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP
,
1832 &IID_IConnectionPoint
,
1834 } else if(IsEqualIID(riid
, &IID_IFontEventsDisp
)) {
1835 return IConnectionPoint_QueryInterface(this->pFontEventsCP
,
1836 &IID_IConnectionPoint
,
1839 FIXME("no connection point for %s\n", debugstr_guid(riid
));
1840 return CONNECT_E_NOCONNECTION
;
1844 static const IConnectionPointContainerVtbl
1845 OLEFontImpl_IConnectionPointContainer_VTable
=
1847 OLEFontImpl_IConnectionPointContainer_QueryInterface
,
1848 OLEFontImpl_IConnectionPointContainer_AddRef
,
1849 OLEFontImpl_IConnectionPointContainer_Release
,
1850 OLEFontImpl_EnumConnectionPoints
,
1851 OLEFontImpl_FindConnectionPoint
1854 /************************************************************************
1855 * OLEFontImpl implementation of IPersistPropertyBag.
1857 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_QueryInterface(
1858 IPersistPropertyBag
*iface
, REFIID riid
, LPVOID
*ppvObj
1860 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1861 return IFont_QueryInterface(&this->IFont_iface
,riid
,ppvObj
);
1864 static ULONG WINAPI
OLEFontImpl_IPersistPropertyBag_AddRef(
1865 IPersistPropertyBag
*iface
1867 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1868 return IFont_AddRef(&this->IFont_iface
);
1871 static ULONG WINAPI
OLEFontImpl_IPersistPropertyBag_Release(
1872 IPersistPropertyBag
*iface
1874 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1875 return IFont_Release(&this->IFont_iface
);
1878 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_GetClassID(
1879 IPersistPropertyBag
*iface
, CLSID
*classid
1881 FIXME("(%p,%p), stub!\n", iface
, classid
);
1885 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_InitNew(
1886 IPersistPropertyBag
*iface
1888 FIXME("(%p), stub!\n", iface
);
1892 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_Load(
1893 IPersistPropertyBag
*iface
, IPropertyBag
* pPropBag
, IErrorLog
* pErrorLog
1895 /* (from Visual Basic 6 property bag)
1896 Name = "MS Sans Serif"
1900 Underline = 0 'False
1902 Strikethrough = 0 'False
1904 static const WCHAR sAttrName
[] = {'N','a','m','e',0};
1905 static const WCHAR sAttrSize
[] = {'S','i','z','e',0};
1906 static const WCHAR sAttrCharset
[] = {'C','h','a','r','s','e','t',0};
1907 static const WCHAR sAttrWeight
[] = {'W','e','i','g','h','t',0};
1908 static const WCHAR sAttrUnderline
[] = {'U','n','d','e','r','l','i','n','e',0};
1909 static const WCHAR sAttrItalic
[] = {'I','t','a','l','i','c',0};
1910 static const WCHAR sAttrStrikethrough
[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
1911 OLEFontImpl
*this = impl_from_IPersistPropertyBag(iface
);
1915 VariantInit(&value
);
1917 iRes
= IPropertyBag_Read(pPropBag
, sAttrName
, &value
, pErrorLog
);
1920 iRes
= VariantChangeType(&value
, &value
, 0, VT_BSTR
);
1922 iRes
= IFont_put_Name(&this->IFont_iface
, V_BSTR(&value
));
1924 else if (iRes
== E_INVALIDARG
)
1927 VariantClear(&value
);
1930 iRes
= IPropertyBag_Read(pPropBag
, sAttrSize
, &value
, pErrorLog
);
1933 iRes
= VariantChangeType(&value
, &value
, 0, VT_CY
);
1935 iRes
= IFont_put_Size(&this->IFont_iface
, V_CY(&value
));
1937 else if (iRes
== E_INVALIDARG
)
1940 VariantClear(&value
);
1944 iRes
= IPropertyBag_Read(pPropBag
, sAttrCharset
, &value
, pErrorLog
);
1947 iRes
= VariantChangeType(&value
, &value
, 0, VT_I2
);
1949 iRes
= IFont_put_Charset(&this->IFont_iface
, V_I2(&value
));
1951 else if (iRes
== E_INVALIDARG
)
1954 VariantClear(&value
);
1958 iRes
= IPropertyBag_Read(pPropBag
, sAttrWeight
, &value
, pErrorLog
);
1961 iRes
= VariantChangeType(&value
, &value
, 0, VT_I2
);
1963 iRes
= IFont_put_Weight(&this->IFont_iface
, V_I2(&value
));
1965 else if (iRes
== E_INVALIDARG
)
1968 VariantClear(&value
);
1972 iRes
= IPropertyBag_Read(pPropBag
, sAttrUnderline
, &value
, pErrorLog
);
1975 iRes
= VariantChangeType(&value
, &value
, 0, VT_BOOL
);
1977 iRes
= IFont_put_Underline(&this->IFont_iface
, V_BOOL(&value
));
1979 else if (iRes
== E_INVALIDARG
)
1982 VariantClear(&value
);
1986 iRes
= IPropertyBag_Read(pPropBag
, sAttrItalic
, &value
, pErrorLog
);
1989 iRes
= VariantChangeType(&value
, &value
, 0, VT_BOOL
);
1991 iRes
= IFont_put_Italic(&this->IFont_iface
, V_BOOL(&value
));
1993 else if (iRes
== E_INVALIDARG
)
1996 VariantClear(&value
);
2000 iRes
= IPropertyBag_Read(pPropBag
, sAttrStrikethrough
, &value
, pErrorLog
);
2003 iRes
= VariantChangeType(&value
, &value
, 0, VT_BOOL
);
2005 IFont_put_Strikethrough(&this->IFont_iface
, V_BOOL(&value
));
2007 else if (iRes
== E_INVALIDARG
)
2010 VariantClear(&value
);
2014 WARN("-- 0x%08x\n", iRes
);
2018 static HRESULT WINAPI
OLEFontImpl_IPersistPropertyBag_Save(
2019 IPersistPropertyBag
*iface
, IPropertyBag
* pPropBag
, BOOL fClearDirty
,
2020 BOOL fSaveAllProperties
2022 FIXME("(%p,%p,%d,%d), stub!\n", iface
, pPropBag
, fClearDirty
, fSaveAllProperties
);
2026 static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable
=
2028 OLEFontImpl_IPersistPropertyBag_QueryInterface
,
2029 OLEFontImpl_IPersistPropertyBag_AddRef
,
2030 OLEFontImpl_IPersistPropertyBag_Release
,
2032 OLEFontImpl_IPersistPropertyBag_GetClassID
,
2033 OLEFontImpl_IPersistPropertyBag_InitNew
,
2034 OLEFontImpl_IPersistPropertyBag_Load
,
2035 OLEFontImpl_IPersistPropertyBag_Save
2038 /************************************************************************
2039 * OLEFontImpl implementation of IPersistStreamInit.
2041 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_QueryInterface(
2042 IPersistStreamInit
*iface
, REFIID riid
, LPVOID
*ppvObj
2044 OLEFontImpl
*this = impl_from_IPersistStreamInit(iface
);
2045 return IFont_QueryInterface(&this->IFont_iface
,riid
,ppvObj
);
2048 static ULONG WINAPI
OLEFontImpl_IPersistStreamInit_AddRef(
2049 IPersistStreamInit
*iface
2051 OLEFontImpl
*this = impl_from_IPersistStreamInit(iface
);
2052 return IFont_AddRef(&this->IFont_iface
);
2055 static ULONG WINAPI
OLEFontImpl_IPersistStreamInit_Release(
2056 IPersistStreamInit
*iface
2058 OLEFontImpl
*this = impl_from_IPersistStreamInit(iface
);
2059 return IFont_Release(&this->IFont_iface
);
2062 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_GetClassID(
2063 IPersistStreamInit
*iface
, CLSID
*classid
2065 FIXME("(%p,%p), stub!\n", iface
, classid
);
2069 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_IsDirty(
2070 IPersistStreamInit
*iface
2072 FIXME("(%p), stub!\n", iface
);
2076 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_Load(
2077 IPersistStreamInit
*iface
, LPSTREAM pStm
2079 FIXME("(%p,%p), stub!\n", iface
, pStm
);
2083 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_Save(
2084 IPersistStreamInit
*iface
, LPSTREAM pStm
, BOOL fClearDirty
2086 FIXME("(%p,%p,%d), stub!\n", iface
, pStm
, fClearDirty
);
2090 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_GetSizeMax(
2091 IPersistStreamInit
*iface
, ULARGE_INTEGER
*pcbSize
2093 FIXME("(%p,%p), stub!\n", iface
, pcbSize
);
2097 static HRESULT WINAPI
OLEFontImpl_IPersistStreamInit_InitNew(
2098 IPersistStreamInit
*iface
2100 FIXME("(%p), stub!\n", iface
);
2104 static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable
=
2106 OLEFontImpl_IPersistStreamInit_QueryInterface
,
2107 OLEFontImpl_IPersistStreamInit_AddRef
,
2108 OLEFontImpl_IPersistStreamInit_Release
,
2110 OLEFontImpl_IPersistStreamInit_GetClassID
,
2111 OLEFontImpl_IPersistStreamInit_IsDirty
,
2112 OLEFontImpl_IPersistStreamInit_Load
,
2113 OLEFontImpl_IPersistStreamInit_Save
,
2114 OLEFontImpl_IPersistStreamInit_GetSizeMax
,
2115 OLEFontImpl_IPersistStreamInit_InitNew
2118 /************************************************************************
2119 * OLEFontImpl_Construct
2121 * This method will construct a new instance of the OLEFontImpl
2124 * The caller of this method must release the object when it's
2127 static OLEFontImpl
* OLEFontImpl_Construct(const FONTDESC
*fontDesc
)
2129 OLEFontImpl
* newObject
;
2131 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl
));
2136 newObject
->IFont_iface
.lpVtbl
= &OLEFontImpl_VTable
;
2137 newObject
->IDispatch_iface
.lpVtbl
= &OLEFontImpl_IDispatch_VTable
;
2138 newObject
->IPersistStream_iface
.lpVtbl
= &OLEFontImpl_IPersistStream_VTable
;
2139 newObject
->IConnectionPointContainer_iface
.lpVtbl
= &OLEFontImpl_IConnectionPointContainer_VTable
;
2140 newObject
->IPersistPropertyBag_iface
.lpVtbl
= &OLEFontImpl_IPersistPropertyBag_VTable
;
2141 newObject
->IPersistStreamInit_iface
.lpVtbl
= &OLEFontImpl_IPersistStreamInit_VTable
;
2145 newObject
->description
.cbSizeofstruct
= sizeof(FONTDESC
);
2146 newObject
->description
.lpstrName
= strdupW(fontDesc
->lpstrName
);
2147 newObject
->description
.cySize
= fontDesc
->cySize
;
2148 newObject
->description
.sWeight
= fontDesc
->sWeight
;
2149 newObject
->description
.sCharset
= fontDesc
->sCharset
;
2150 newObject
->description
.fItalic
= fontDesc
->fItalic
;
2151 newObject
->description
.fUnderline
= fontDesc
->fUnderline
;
2152 newObject
->description
.fStrikethrough
= fontDesc
->fStrikethrough
;
2154 newObject
->gdiFont
= 0;
2155 newObject
->dirty
= TRUE
;
2156 newObject
->cyLogical
= GetDeviceCaps(get_dc(), LOGPIXELSY
);
2157 newObject
->cyHimetric
= 2540L;
2158 newObject
->pPropertyNotifyCP
= NULL
;
2159 newObject
->pFontEventsCP
= NULL
;
2161 CreateConnectionPoint((IUnknown
*)&newObject
->IFont_iface
, &IID_IPropertyNotifySink
, &newObject
->pPropertyNotifyCP
);
2162 CreateConnectionPoint((IUnknown
*)&newObject
->IFont_iface
, &IID_IFontEventsDisp
, &newObject
->pFontEventsCP
);
2164 if (!newObject
->pPropertyNotifyCP
|| !newObject
->pFontEventsCP
)
2166 OLEFontImpl_Destroy(newObject
);
2170 InterlockedIncrement(&ifont_cnt
);
2172 TRACE("returning %p\n", newObject
);
2176 /************************************************************************
2177 * OLEFontImpl_Destroy
2179 * This method is called by the Release method when the reference
2180 * count goes down to 0. It will free all resources used by
2183 static void OLEFontImpl_Destroy(OLEFontImpl
* fontDesc
)
2185 TRACE("(%p)\n", fontDesc
);
2187 HeapFree(GetProcessHeap(), 0, fontDesc
->description
.lpstrName
);
2189 if (fontDesc
->pPropertyNotifyCP
)
2190 IConnectionPoint_Release(fontDesc
->pPropertyNotifyCP
);
2191 if (fontDesc
->pFontEventsCP
)
2192 IConnectionPoint_Release(fontDesc
->pFontEventsCP
);
2194 HeapFree(GetProcessHeap(), 0, fontDesc
);
2197 /*******************************************************************************
2198 * StdFont ClassFactory
2202 /* IUnknown fields */
2203 IClassFactory IClassFactory_iface
;
2205 } IClassFactoryImpl
;
2207 static inline IClassFactoryImpl
*impl_from_IClassFactory(IClassFactory
*iface
)
2209 return CONTAINING_RECORD(iface
, IClassFactoryImpl
, IClassFactory_iface
);
2212 static HRESULT WINAPI
2213 SFCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
2214 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2216 FIXME("(%p)->(%s,%p),stub!\n",This
,debugstr_guid(riid
),ppobj
);
2217 return E_NOINTERFACE
;
2221 SFCF_AddRef(LPCLASSFACTORY iface
) {
2222 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2223 return InterlockedIncrement(&This
->ref
);
2226 static ULONG WINAPI
SFCF_Release(LPCLASSFACTORY iface
) {
2227 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2228 /* static class, won't be freed */
2229 return InterlockedDecrement(&This
->ref
);
2232 static HRESULT WINAPI
SFCF_CreateInstance(
2233 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
2235 return OleCreateFontIndirect(NULL
,riid
,ppobj
);
2239 static HRESULT WINAPI
SFCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
2240 IClassFactoryImpl
*This
= impl_from_IClassFactory(iface
);
2241 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
2245 static const IClassFactoryVtbl SFCF_Vtbl
= {
2246 SFCF_QueryInterface
,
2249 SFCF_CreateInstance
,
2252 static IClassFactoryImpl STDFONT_CF
= {{&SFCF_Vtbl
}, 1 };
2254 void _get_STDFONT_CF(LPVOID
*ppv
) { *ppv
= &STDFONT_CF
; }