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
15 #include "wine/unicode.h"
16 #include "oleauto.h" /* for SysAllocString(....) */
17 #include "wine/obj_base.h"
18 #include "wine/obj_olefont.h"
19 #include "wine/obj_storage.h"
22 #include "debugtools.h"
24 #include "connpt.h" /* for CreateConnectionPoint */
26 DEFAULT_DEBUG_CHANNEL(ole);
28 /***********************************************************************
29 * Declaration of constants used when serializing the font object.
31 #define FONTPERSIST_ITALIC 0x02
32 #define FONTPERSIST_UNDERLINE 0x04
33 #define FONTPERSIST_STRIKETHROUGH 0x08
35 /***********************************************************************
36 * Declaration of the implementation class for the IFont interface
38 typedef struct OLEFontImpl OLEFontImpl;
43 * This class supports many interfaces. IUnknown, IFont,
44 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
45 * The first two are supported by the first vtable, the next two are
46 * supported by the second table and the last two have their own.
48 ICOM_VTABLE(IFont)* lpvtbl1;
49 ICOM_VTABLE(IDispatch)* lpvtbl2;
50 ICOM_VTABLE(IPersistStream)* lpvtbl3;
51 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
53 * Reference count for that instance of the class.
58 * This structure contains the description of the class.
63 * Contain the font associated with this object.
78 IConnectionPoint *pCP;
82 * Here, I define utility macros to help with the casting of the
84 * There is a version to accomodate all of the VTables implemented
87 #define _ICOM_THIS(class,name) class* this = (class*)name;
88 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
89 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
90 #define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
93 /***********************************************************************
94 * Prototypes for the implementation functions for the IFont
97 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
98 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
99 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
100 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
101 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
102 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
103 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
104 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
105 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
106 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
107 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
108 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
109 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
110 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
111 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
112 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
113 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
114 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
115 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
116 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
117 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
118 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
119 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
120 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
121 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
122 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
123 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
124 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
125 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
127 /***********************************************************************
128 * Prototypes for the implementation functions for the IDispatch
131 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
134 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
135 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
136 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
137 unsigned int* pctinfo);
138 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
141 ITypeInfo** ppTInfo);
142 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
148 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
153 DISPPARAMS* pDispParams,
155 EXCEPINFO* pExepInfo,
158 /***********************************************************************
159 * Prototypes for the implementation functions for the IPersistStream
162 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
165 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
166 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
167 static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
169 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
170 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
171 IStream* pLoadStream);
172 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
175 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
176 ULARGE_INTEGER* pcbSize);
178 /***********************************************************************
179 * Prototypes for the implementation functions for the
180 * IConnectionPointContainer interface
182 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
183 IConnectionPointContainer* iface,
186 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
187 IConnectionPointContainer* iface);
188 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
189 IConnectionPointContainer* iface);
190 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
191 IConnectionPointContainer* iface,
192 IEnumConnectionPoints **ppEnum);
193 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
194 IConnectionPointContainer* iface,
196 IConnectionPoint **ppCp);
199 * Virtual function tables for the OLEFontImpl class.
201 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
203 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
204 OLEFontImpl_QueryInterface,
207 OLEFontImpl_get_Name,
208 OLEFontImpl_put_Name,
209 OLEFontImpl_get_Size,
210 OLEFontImpl_put_Size,
211 OLEFontImpl_get_Bold,
212 OLEFontImpl_put_Bold,
213 OLEFontImpl_get_Italic,
214 OLEFontImpl_put_Italic,
215 OLEFontImpl_get_Underline,
216 OLEFontImpl_put_Underline,
217 OLEFontImpl_get_Strikethrough,
218 OLEFontImpl_put_Strikethrough,
219 OLEFontImpl_get_Weight,
220 OLEFontImpl_put_Weight,
221 OLEFontImpl_get_Charset,
222 OLEFontImpl_put_Charset,
223 OLEFontImpl_get_hFont,
226 OLEFontImpl_SetRatio,
227 OLEFontImpl_QueryTextMetrics,
228 OLEFontImpl_AddRefHfont,
229 OLEFontImpl_ReleaseHfont,
233 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
235 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
236 OLEFontImpl_IDispatch_QueryInterface,
237 OLEFontImpl_IDispatch_AddRef,
238 OLEFontImpl_IDispatch_Release,
239 OLEFontImpl_GetTypeInfoCount,
240 OLEFontImpl_GetTypeInfo,
241 OLEFontImpl_GetIDsOfNames,
245 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
247 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
248 OLEFontImpl_IPersistStream_QueryInterface,
249 OLEFontImpl_IPersistStream_AddRef,
250 OLEFontImpl_IPersistStream_Release,
251 OLEFontImpl_GetClassID,
255 OLEFontImpl_GetSizeMax
258 static ICOM_VTABLE(IConnectionPointContainer)
259 OLEFontImpl_IConnectionPointContainer_VTable =
261 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
262 OLEFontImpl_IConnectionPointContainer_QueryInterface,
263 OLEFontImpl_IConnectionPointContainer_AddRef,
264 OLEFontImpl_IConnectionPointContainer_Release,
265 OLEFontImpl_EnumConnectionPoints,
266 OLEFontImpl_FindConnectionPoint
269 /******************************************************************************
270 * OleCreateFontIndirect [OLEAUT32.420]
272 HRESULT WINAPI OleCreateFontIndirect(
273 LPFONTDESC lpFontDesc,
277 OLEFontImpl* newFont = 0;
280 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
290 * Try to construct a new instance of the class.
292 newFont = OLEFontImpl_Construct(lpFontDesc);
295 return E_OUTOFMEMORY;
298 * Make sure it supports the interface required by the caller.
300 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
303 * Release the reference obtained in the constructor. If
304 * the QueryInterface was unsuccessful, it will free the class.
306 IFont_Release((IFont*)newFont);
312 /***********************************************************************
313 * Implementation of the OLEFontImpl class.
316 /***********************************************************************
317 * OLEFont_SendNotify (internal)
319 * Sends notification messages of changed properties to any interested
322 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
324 IEnumConnections *pEnum;
327 IConnectionPoint_EnumConnections(this->pCP, &pEnum);
329 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
330 IPropertyNotifySink *sink;
332 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
333 IPropertyNotifySink_OnChanged(sink, dispID);
334 IPropertyNotifySink_Release(sink);
335 IUnknown_Release(CD.pUnk);
337 IEnumConnections_Release(pEnum);
341 /************************************************************************
342 * OLEFontImpl_Construct
344 * This method will construct a new instance of the OLEFontImpl
347 * The caller of this method must release the object when it's
350 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
352 OLEFontImpl* newObject = 0;
355 * Allocate space for the object.
357 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
363 * Initialize the virtual function table.
365 newObject->lpvtbl1 = &OLEFontImpl_VTable;
366 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
367 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
368 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
371 * Start with one reference count. The caller of this function
372 * must release the interface pointer when it is done.
377 * Copy the description of the font in the object.
379 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
381 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
382 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
384 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
385 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
386 newObject->description.cySize = fontDesc->cySize;
387 newObject->description.sWeight = fontDesc->sWeight;
388 newObject->description.sCharset = fontDesc->sCharset;
389 newObject->description.fItalic = fontDesc->fItalic;
390 newObject->description.fUnderline = fontDesc->fUnderline;
391 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
394 * Initializing all the other members.
396 newObject->gdiFont = 0;
397 newObject->fontLock = 0;
398 newObject->cyHimetric = 1;
399 newObject->cyLogical = 1;
401 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
403 TRACE("returning %p\n", newObject);
407 /************************************************************************
408 * OLEFontImpl_Destroy
410 * This method is called by the Release method when the reference
411 * count goes down to 0. It will free all resources used by
414 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
416 TRACE("(%p)\n", fontDesc);
418 if (fontDesc->description.lpstrName!=0)
419 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
421 if (fontDesc->gdiFont!=0)
422 DeleteObject(fontDesc->gdiFont);
424 HeapFree(GetProcessHeap(), 0, fontDesc);
427 /************************************************************************
428 * OLEFontImpl_QueryInterface (IUnknown)
430 * See Windows documentation for more details on IUnknown methods.
432 HRESULT WINAPI OLEFontImpl_QueryInterface(
437 _ICOM_THIS(OLEFontImpl, iface);
438 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
441 * Perform a sanity check on the parameters.
443 if ( (this==0) || (ppvObject==0) )
447 * Initialize the return parameter.
452 * Compare the riid with the interface IDs implemented by this object.
454 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
456 *ppvObject = (IFont*)this;
458 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
460 *ppvObject = (IFont*)this;
462 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
464 *ppvObject = (IDispatch*)&(this->lpvtbl2);
466 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
468 *ppvObject = (IDispatch*)&(this->lpvtbl2);
470 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
472 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
474 else if (memcmp(&IID_IConnectionPointContainer, riid,
475 sizeof(IID_IConnectionPointContainer)) == 0)
477 *ppvObject = (IPersistStream*)&(this->lpvtbl4);
481 * Check that we obtained an interface.
485 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
486 return E_NOINTERFACE;
490 * Query Interface always increases the reference count by one when it is
493 OLEFontImpl_AddRef((IFont*)this);
498 /************************************************************************
499 * OLEFontImpl_AddRef (IUnknown)
501 * See Windows documentation for more details on IUnknown methods.
503 ULONG WINAPI OLEFontImpl_AddRef(
506 _ICOM_THIS(OLEFontImpl, iface);
507 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
513 /************************************************************************
514 * OLEFontImpl_Release (IUnknown)
516 * See Windows documentation for more details on IUnknown methods.
518 ULONG WINAPI OLEFontImpl_Release(
521 _ICOM_THIS(OLEFontImpl, iface);
522 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
525 * Decrease the reference count on this object.
530 * If the reference count goes down to 0, perform suicide.
534 OLEFontImpl_Destroy(this);
542 /************************************************************************
543 * OLEFontImpl_get_Name (IFont)
545 * See Windows documentation for more details on IFont methods.
547 static HRESULT WINAPI OLEFontImpl_get_Name(
551 _ICOM_THIS(OLEFontImpl, iface);
552 TRACE("(%p)->(%p)\n", this, pname);
559 if (this->description.lpstrName!=0)
560 *pname = SysAllocString(this->description.lpstrName);
567 /************************************************************************
568 * OLEFontImpl_put_Name (IFont)
570 * See Windows documentation for more details on IFont methods.
572 static HRESULT WINAPI OLEFontImpl_put_Name(
576 _ICOM_THIS(OLEFontImpl, iface);
577 TRACE("(%p)->(%p)\n", this, name);
579 if (this->description.lpstrName==0)
581 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
583 (lstrlenW(name)+1) * sizeof(WCHAR));
587 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
589 this->description.lpstrName,
590 (lstrlenW(name)+1) * sizeof(WCHAR));
593 if (this->description.lpstrName==0)
594 return E_OUTOFMEMORY;
596 strcpyW(this->description.lpstrName, name);
597 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
598 OLEFont_SendNotify(this, DISPID_FONT_NAME);
602 /************************************************************************
603 * OLEFontImpl_get_Size (IFont)
605 * See Windows documentation for more details on IFont methods.
607 static HRESULT WINAPI OLEFontImpl_get_Size(
611 _ICOM_THIS(OLEFontImpl, iface);
612 TRACE("(%p)->(%p)\n", this, psize);
621 psize->s.Lo = this->description.cySize.s.Lo;
626 /************************************************************************
627 * OLEFontImpl_put_Size (IFont)
629 * See Windows documentation for more details on IFont methods.
631 static HRESULT WINAPI OLEFontImpl_put_Size(
635 _ICOM_THIS(OLEFontImpl, iface);
636 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
637 this->description.cySize.s.Hi = 0;
638 this->description.cySize.s.Lo = size.s.Lo;
639 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
644 /************************************************************************
645 * OLEFontImpl_get_Bold (IFont)
647 * See Windows documentation for more details on IFont methods.
649 static HRESULT WINAPI OLEFontImpl_get_Bold(
653 _ICOM_THIS(OLEFontImpl, iface);
654 TRACE("(%p)->(%p)\n", this, pbold);
661 *pbold = this->description.sWeight > 550;
666 /************************************************************************
667 * OLEFontImpl_put_Bold (IFont)
669 * See Windows documentation for more details on IFont methods.
671 static HRESULT WINAPI OLEFontImpl_put_Bold(
675 _ICOM_THIS(OLEFontImpl, iface);
676 TRACE("(%p)->(%d)\n", this, bold);
677 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
678 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
683 /************************************************************************
684 * OLEFontImpl_get_Italic (IFont)
686 * See Windows documentation for more details on IFont methods.
688 static HRESULT WINAPI OLEFontImpl_get_Italic(
692 _ICOM_THIS(OLEFontImpl, iface);
693 TRACE("(%p)->(%p)\n", this, pitalic);
700 *pitalic = this->description.fItalic;
705 /************************************************************************
706 * OLEFontImpl_put_Italic (IFont)
708 * See Windows documentation for more details on IFont methods.
710 static HRESULT WINAPI OLEFontImpl_put_Italic(
714 _ICOM_THIS(OLEFontImpl, iface);
715 TRACE("(%p)->(%d)\n", this, italic);
717 this->description.fItalic = italic;
719 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
723 /************************************************************************
724 * OLEFontImpl_get_Underline (IFont)
726 * See Windows documentation for more details on IFont methods.
728 static HRESULT WINAPI OLEFontImpl_get_Underline(
732 _ICOM_THIS(OLEFontImpl, iface);
733 TRACE("(%p)->(%p)\n", this, punderline);
741 *punderline = this->description.fUnderline;
746 /************************************************************************
747 * OLEFontImpl_put_Underline (IFont)
749 * See Windows documentation for more details on IFont methods.
751 static HRESULT WINAPI OLEFontImpl_put_Underline(
755 _ICOM_THIS(OLEFontImpl, iface);
756 TRACE("(%p)->(%d)\n", this, underline);
758 this->description.fUnderline = underline;
760 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
764 /************************************************************************
765 * OLEFontImpl_get_Strikethrough (IFont)
767 * See Windows documentation for more details on IFont methods.
769 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
771 BOOL* pstrikethrough)
773 _ICOM_THIS(OLEFontImpl, iface);
774 TRACE("(%p)->(%p)\n", this, pstrikethrough);
779 if (pstrikethrough==0)
782 *pstrikethrough = this->description.fStrikethrough;
787 /************************************************************************
788 * OLEFontImpl_put_Strikethrough (IFont)
790 * See Windows documentation for more details on IFont methods.
792 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
796 _ICOM_THIS(OLEFontImpl, iface);
797 TRACE("(%p)->(%d)\n", this, strikethrough);
799 this->description.fStrikethrough = strikethrough;
800 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
805 /************************************************************************
806 * OLEFontImpl_get_Weight (IFont)
808 * See Windows documentation for more details on IFont methods.
810 static HRESULT WINAPI OLEFontImpl_get_Weight(
814 _ICOM_THIS(OLEFontImpl, iface);
815 TRACE("(%p)->(%p)\n", this, pweight);
823 *pweight = this->description.sWeight;
828 /************************************************************************
829 * OLEFontImpl_put_Weight (IFont)
831 * See Windows documentation for more details on IFont methods.
833 static HRESULT WINAPI OLEFontImpl_put_Weight(
837 _ICOM_THIS(OLEFontImpl, iface);
838 TRACE("(%p)->(%d)\n", this, weight);
840 this->description.sWeight = weight;
842 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
846 /************************************************************************
847 * OLEFontImpl_get_Charset (IFont)
849 * See Windows documentation for more details on IFont methods.
851 static HRESULT WINAPI OLEFontImpl_get_Charset(
855 _ICOM_THIS(OLEFontImpl, iface);
856 TRACE("(%p)->(%p)\n", this, pcharset);
864 *pcharset = this->description.sCharset;
869 /************************************************************************
870 * OLEFontImpl_put_Charset (IFont)
872 * See Windows documentation for more details on IFont methods.
874 static HRESULT WINAPI OLEFontImpl_put_Charset(
878 _ICOM_THIS(OLEFontImpl, iface);
879 TRACE("(%p)->(%d)\n", this, charset);
881 this->description.sCharset = charset;
882 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
887 /************************************************************************
888 * OLEFontImpl_get_hFont (IFont)
890 * See Windows documentation for more details on IFont methods.
892 static HRESULT WINAPI OLEFontImpl_get_hFont(
896 _ICOM_THIS(OLEFontImpl, iface);
897 TRACE("(%p)->(%p)\n", this, phfont);
902 * Realize the font if necessary
904 if (this->gdiFont==0)
911 * The height of the font returned by the get_Size property is the
912 * height of the font in points multiplied by 10000... Using some
913 * simple conversions and the ratio given by the application, it can
914 * be converted to a height in pixels.
916 IFont_get_Size(iface, &cySize);
918 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
919 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
921 memset(&logFont, 0, sizeof(LOGFONTW));
923 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
924 (-fontHeight/10000L);
925 logFont.lfItalic = this->description.fItalic;
926 logFont.lfUnderline = this->description.fUnderline;
927 logFont.lfStrikeOut = this->description.fStrikethrough;
928 logFont.lfWeight = this->description.sWeight;
929 logFont.lfCharSet = this->description.sCharset;
930 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
931 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
932 logFont.lfQuality = DEFAULT_QUALITY;
933 logFont.lfPitchAndFamily = DEFAULT_PITCH;
934 strcpyW(logFont.lfFaceName,this->description.lpstrName);
936 this->gdiFont = CreateFontIndirectW(&logFont);
939 *phfont = this->gdiFont;
940 TRACE("Returning %08x\n", *phfont);
944 /************************************************************************
945 * OLEFontImpl_Clone (IFont)
947 * See Windows documentation for more details on IFont methods.
949 static HRESULT WINAPI OLEFontImpl_Clone(
953 OLEFontImpl* newObject = 0;
957 _ICOM_THIS(OLEFontImpl, iface);
958 TRACE("(%p)->(%p)\n", this, ppfont);
966 * Allocate space for the object.
968 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
971 return E_OUTOFMEMORY;
975 /* We need to alloc new memory for the string, otherwise
976 * we free memory twice.
978 newObject->description.lpstrName = HeapAlloc(
980 (1+strlenW(this->description.lpstrName))*2
982 /* We need to clone the HFONT too. This is just cut & paste from above */
983 IFont_get_Size(iface, &cySize);
985 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
986 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
988 memset(&logFont, 0, sizeof(LOGFONTW));
990 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
991 (-fontHeight/10000L);
992 logFont.lfItalic = this->description.fItalic;
993 logFont.lfUnderline = this->description.fUnderline;
994 logFont.lfStrikeOut = this->description.fStrikethrough;
995 logFont.lfWeight = this->description.sWeight;
996 logFont.lfCharSet = this->description.sCharset;
997 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
998 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
999 logFont.lfQuality = DEFAULT_QUALITY;
1000 logFont.lfPitchAndFamily = DEFAULT_PITCH;
1001 strcpyW(logFont.lfFaceName,this->description.lpstrName);
1003 newObject->gdiFont = CreateFontIndirectW(&logFont);
1006 /* The cloned object starts with a reference count of 1 */
1009 *ppfont = (IFont*)newObject;
1014 /************************************************************************
1015 * OLEFontImpl_IsEqual (IFont)
1017 * See Windows documentation for more details on IFont methods.
1019 static HRESULT WINAPI OLEFontImpl_IsEqual(
1027 /************************************************************************
1028 * OLEFontImpl_SetRatio (IFont)
1030 * See Windows documentation for more details on IFont methods.
1032 static HRESULT WINAPI OLEFontImpl_SetRatio(
1037 _ICOM_THIS(OLEFontImpl, iface);
1038 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1040 this->cyLogical = cyLogical;
1041 this->cyHimetric = cyHimetric;
1046 /************************************************************************
1047 * OLEFontImpl_QueryTextMetrics (IFont)
1049 * See Windows documentation for more details on IFont methods.
1051 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1059 /************************************************************************
1060 * OLEFontImpl_AddRefHfont (IFont)
1062 * See Windows documentation for more details on IFont methods.
1064 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1068 _ICOM_THIS(OLEFontImpl, iface);
1069 TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
1071 if ( (hfont == 0) ||
1072 (hfont != this->gdiFont) )
1073 return E_INVALIDARG;
1080 /************************************************************************
1081 * OLEFontImpl_ReleaseHfont (IFont)
1083 * See Windows documentation for more details on IFont methods.
1085 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1089 _ICOM_THIS(OLEFontImpl, iface);
1090 TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
1092 if ( (hfont == 0) ||
1093 (hfont != this->gdiFont) )
1094 return E_INVALIDARG;
1099 * If we just released our last font reference, destroy it.
1101 if (this->fontLock==0)
1103 DeleteObject(this->gdiFont);
1110 /************************************************************************
1111 * OLEFontImpl_SetHdc (IFont)
1113 * See Windows documentation for more details on IFont methods.
1115 static HRESULT WINAPI OLEFontImpl_SetHdc(
1119 _ICOM_THIS(OLEFontImpl, iface);
1120 FIXME("(%p)->(%08x): Stub\n", this, hdc);
1124 /************************************************************************
1125 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1127 * See Windows documentation for more details on IUnknown methods.
1129 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1134 _ICOM_THIS_From_IDispatch(IFont, iface);
1136 return IFont_QueryInterface(this, riid, ppvoid);
1139 /************************************************************************
1140 * OLEFontImpl_IDispatch_Release (IUnknown)
1142 * See Windows documentation for more details on IUnknown methods.
1144 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1147 _ICOM_THIS_From_IDispatch(IFont, iface);
1149 return IFont_Release(this);
1152 /************************************************************************
1153 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1155 * See Windows documentation for more details on IUnknown methods.
1157 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1160 _ICOM_THIS_From_IDispatch(IFont, iface);
1162 return IFont_AddRef(this);
1165 /************************************************************************
1166 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1168 * See Windows documentation for more details on IDispatch methods.
1170 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1172 unsigned int* pctinfo)
1174 _ICOM_THIS_From_IDispatch(IFont, iface);
1175 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1180 /************************************************************************
1181 * OLEFontImpl_GetTypeInfo (IDispatch)
1183 * See Windows documentation for more details on IDispatch methods.
1185 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1189 ITypeInfo** ppTInfo)
1191 _ICOM_THIS_From_IDispatch(IFont, iface);
1192 FIXME("(%p):Stub\n", this);
1197 /************************************************************************
1198 * OLEFontImpl_GetIDsOfNames (IDispatch)
1200 * See Windows documentation for more details on IDispatch methods.
1202 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1205 LPOLESTR* rgszNames,
1210 _ICOM_THIS_From_IDispatch(IFont, iface);
1211 FIXME("(%p):Stub\n", this);
1216 /************************************************************************
1217 * OLEFontImpl_Invoke (IDispatch)
1219 * See Windows documentation for more details on IDispatch methods.
1221 static HRESULT WINAPI OLEFontImpl_Invoke(
1223 DISPID dispIdMember,
1227 DISPPARAMS* pDispParams,
1228 VARIANT* pVarResult,
1229 EXCEPINFO* pExepInfo,
1232 _ICOM_THIS_From_IDispatch(IFont, iface);
1233 FIXME("%p->(%ld,%s,%lx,%x), stub!\n", this,dispIdMember,debugstr_guid(riid),lcid,
1239 /************************************************************************
1240 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1242 * See Windows documentation for more details on IUnknown methods.
1244 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1245 IPersistStream* iface,
1249 _ICOM_THIS_From_IPersistStream(IFont, iface);
1251 return IFont_QueryInterface(this, riid, ppvoid);
1254 /************************************************************************
1255 * OLEFontImpl_IPersistStream_Release (IUnknown)
1257 * See Windows documentation for more details on IUnknown methods.
1259 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1260 IPersistStream* iface)
1262 _ICOM_THIS_From_IPersistStream(IFont, iface);
1264 return IFont_Release(this);
1267 /************************************************************************
1268 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1270 * See Windows documentation for more details on IUnknown methods.
1272 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1273 IPersistStream* iface)
1275 _ICOM_THIS_From_IPersistStream(IFont, iface);
1277 return IFont_AddRef(this);
1280 /************************************************************************
1281 * OLEFontImpl_GetClassID (IPersistStream)
1283 * See Windows documentation for more details on IPersistStream methods.
1285 static HRESULT WINAPI OLEFontImpl_GetClassID(
1286 IPersistStream* iface,
1292 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1297 /************************************************************************
1298 * OLEFontImpl_IsDirty (IPersistStream)
1300 * See Windows documentation for more details on IPersistStream methods.
1302 static HRESULT WINAPI OLEFontImpl_IsDirty(
1303 IPersistStream* iface)
1308 /************************************************************************
1309 * OLEFontImpl_Load (IPersistStream)
1311 * See Windows documentation for more details on IPersistStream methods.
1313 * This is the format of the standard font serialization as far as I
1316 * Offset Type Value Comment
1317 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1318 * 0x0001 Short Charset Charset value from the FONTDESC structure
1319 * 0x0003 Byte Attributes Flags defined as follows:
1321 * 00000100 - Underline
1322 * 00001000 - Strikethrough
1323 * 0x0004 Short Weight Weight value from FONTDESC structure
1324 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1326 * 0x000A Byte name length Length of the font name string (no null character)
1327 * 0x000B String name Name of the font (ASCII, no nul character)
1329 static HRESULT WINAPI OLEFontImpl_Load(
1330 IPersistStream* iface,
1331 IStream* pLoadStream)
1333 char readBuffer[0x100];
1339 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1342 * Read the version byte
1344 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1353 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1361 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1366 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1367 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1368 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1373 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1381 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1386 this->description.cySize.s.Hi = 0;
1391 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1396 memset(readBuffer, 0, 0x100);
1397 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1399 if (cbRead!=bStringSize)
1402 if (this->description.lpstrName!=0)
1403 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1405 this->description.lpstrName = HEAP_strdupAtoW(GetProcessHeap(),
1412 /************************************************************************
1413 * OLEFontImpl_Save (IPersistStream)
1415 * See Windows documentation for more details on IPersistStream methods.
1417 static HRESULT WINAPI OLEFontImpl_Save(
1418 IPersistStream* iface,
1419 IStream* pOutStream,
1422 char* writeBuffer = NULL;
1424 BYTE bVersion = 0x01;
1428 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1431 * Read the version byte
1433 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1441 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1451 if (this->description.fItalic)
1452 bAttributes |= FONTPERSIST_ITALIC;
1454 if (this->description.fStrikethrough)
1455 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1457 if (this->description.fUnderline)
1458 bAttributes |= FONTPERSIST_UNDERLINE;
1460 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1468 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1476 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1484 if (this->description.lpstrName!=0)
1485 bStringSize = lstrlenW(this->description.lpstrName);
1489 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1496 writeBuffer = HEAP_strdupWtoA(GetProcessHeap(),
1498 this->description.lpstrName);
1501 return E_OUTOFMEMORY;
1503 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1505 HeapFree(GetProcessHeap(), 0, writeBuffer);
1507 if (cbWritten!=bStringSize)
1514 /************************************************************************
1515 * OLEFontImpl_GetSizeMax (IPersistStream)
1517 * See Windows documentation for more details on IPersistStream methods.
1519 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1520 IPersistStream* iface,
1521 ULARGE_INTEGER* pcbSize)
1523 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1528 pcbSize->s.HighPart = 0;
1529 pcbSize->s.LowPart = 0;
1531 pcbSize->s.LowPart += sizeof(BYTE); /* Version */
1532 pcbSize->s.LowPart += sizeof(WORD); /* Lang code */
1533 pcbSize->s.LowPart += sizeof(BYTE); /* Flags */
1534 pcbSize->s.LowPart += sizeof(WORD); /* Weight */
1535 pcbSize->s.LowPart += sizeof(DWORD); /* Size */
1536 pcbSize->s.LowPart += sizeof(BYTE); /* StrLength */
1538 if (this->description.lpstrName!=0)
1539 pcbSize->s.LowPart += lstrlenW(this->description.lpstrName);
1544 /************************************************************************
1545 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1547 * See Windows documentation for more details on IUnknown methods.
1549 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1550 IConnectionPointContainer* iface,
1554 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1556 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1559 /************************************************************************
1560 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1562 * See Windows documentation for more details on IUnknown methods.
1564 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1565 IConnectionPointContainer* iface)
1567 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1569 return IFont_Release((IFont*)this);
1572 /************************************************************************
1573 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1575 * See Windows documentation for more details on IUnknown methods.
1577 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1578 IConnectionPointContainer* iface)
1580 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1582 return IFont_AddRef((IFont*)this);
1585 /************************************************************************
1586 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1588 * See Windows documentation for more details on IConnectionPointContainer
1591 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1592 IConnectionPointContainer* iface,
1593 IEnumConnectionPoints **ppEnum)
1595 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1597 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1601 /************************************************************************
1602 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1604 * See Windows documentation for more details on IConnectionPointContainer
1607 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1608 IConnectionPointContainer* iface,
1610 IConnectionPoint **ppCp)
1612 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1613 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1615 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1616 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1619 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1620 return E_NOINTERFACE;
1624 /*******************************************************************************
1625 * StdFont ClassFactory
1629 /* IUnknown fields */
1630 ICOM_VFIELD(IClassFactory);
1632 } IClassFactoryImpl;
1634 static HRESULT WINAPI
1635 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1636 ICOM_THIS(IClassFactoryImpl,iface);
1638 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1639 return E_NOINTERFACE;
1643 SFCF_AddRef(LPCLASSFACTORY iface) {
1644 ICOM_THIS(IClassFactoryImpl,iface);
1645 return ++(This->ref);
1648 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
1649 ICOM_THIS(IClassFactoryImpl,iface);
1650 /* static class, won't be freed */
1651 return --(This->ref);
1654 static HRESULT WINAPI SFCF_CreateInstance(
1655 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1657 ICOM_THIS(IClassFactoryImpl,iface);
1659 if (IsEqualGUID(riid,&IID_IFont)) {
1662 WCHAR fname[] = { 'S','y','s','t','e','m',0 };
1664 fd.cbSizeofstruct = sizeof(fd);
1665 fd.lpstrName = fname;
1666 fd.cySize.s.Lo = 80000;
1672 fd.fStrikethrough = 0;
1673 return OleCreateFontIndirect(&fd,riid,ppobj);
1676 FIXME("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
1677 return E_NOINTERFACE;
1680 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1681 ICOM_THIS(IClassFactoryImpl,iface);
1682 FIXME("(%p)->(%d),stub!\n",This,dolock);
1686 static ICOM_VTABLE(IClassFactory) SFCF_Vtbl = {
1687 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1688 SFCF_QueryInterface,
1691 SFCF_CreateInstance,
1694 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
1696 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }