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"
23 #include "connpt.h" /* for CreateConnectionPoint */
25 DEFAULT_DEBUG_CHANNEL(ole);
27 /***********************************************************************
28 * Declaration of constants used when serializing the font object.
30 #define FONTPERSIST_ITALIC 0x02
31 #define FONTPERSIST_UNDERLINE 0x04
32 #define FONTPERSIST_STRIKETHROUGH 0x08
34 /***********************************************************************
35 * Declaration of the implementation class for the IFont interface
37 typedef struct OLEFontImpl OLEFontImpl;
42 * This class supports many interfaces. IUnknown, IFont,
43 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
44 * The first two are supported by the first vtable, the next two are
45 * supported by the second table and the last two have their own.
47 ICOM_VTABLE(IFont)* lpvtbl1;
48 ICOM_VTABLE(IDispatch)* lpvtbl2;
49 ICOM_VTABLE(IPersistStream)* lpvtbl3;
50 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
52 * Reference count for that instance of the class.
57 * This structure contains the description of the class.
62 * Contain the font associated with this object.
77 IConnectionPoint *pCP;
81 * Here, I define utility macros to help with the casting of the
83 * There is a version to accomodate all of the VTables implemented
86 #define _ICOM_THIS(class,name) class* this = (class*)name;
87 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
88 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
89 #define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
92 /***********************************************************************
93 * Prototypes for the implementation functions for the IFont
96 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
97 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
98 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
99 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
100 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
101 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
102 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
103 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
104 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
105 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
106 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
107 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
108 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
109 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
110 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
111 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
112 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
113 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
114 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
115 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
116 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
117 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
118 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
119 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
120 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
121 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
122 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
123 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
124 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
126 /***********************************************************************
127 * Prototypes for the implementation functions for the IDispatch
130 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
133 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
134 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
135 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
136 unsigned int* pctinfo);
137 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
140 ITypeInfo** ppTInfo);
141 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
147 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
152 DISPPARAMS* pDispParams,
154 EXCEPINFO* pExepInfo,
157 /***********************************************************************
158 * Prototypes for the implementation functions for the IPersistStream
161 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
164 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
165 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
166 static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
168 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
169 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
170 IStream* pLoadStream);
171 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
174 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
175 ULARGE_INTEGER* pcbSize);
177 /***********************************************************************
178 * Prototypes for the implementation functions for the
179 * IConnectionPointContainer interface
181 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
182 IConnectionPointContainer* iface,
185 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
186 IConnectionPointContainer* iface);
187 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
188 IConnectionPointContainer* iface);
189 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
190 IConnectionPointContainer* iface,
191 IEnumConnectionPoints **ppEnum);
192 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
193 IConnectionPointContainer* iface,
195 IConnectionPoint **ppCp);
198 * Virtual function tables for the OLEFontImpl class.
200 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
202 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
203 OLEFontImpl_QueryInterface,
206 OLEFontImpl_get_Name,
207 OLEFontImpl_put_Name,
208 OLEFontImpl_get_Size,
209 OLEFontImpl_put_Size,
210 OLEFontImpl_get_Bold,
211 OLEFontImpl_put_Bold,
212 OLEFontImpl_get_Italic,
213 OLEFontImpl_put_Italic,
214 OLEFontImpl_get_Underline,
215 OLEFontImpl_put_Underline,
216 OLEFontImpl_get_Strikethrough,
217 OLEFontImpl_put_Strikethrough,
218 OLEFontImpl_get_Weight,
219 OLEFontImpl_put_Weight,
220 OLEFontImpl_get_Charset,
221 OLEFontImpl_put_Charset,
222 OLEFontImpl_get_hFont,
225 OLEFontImpl_SetRatio,
226 OLEFontImpl_QueryTextMetrics,
227 OLEFontImpl_AddRefHfont,
228 OLEFontImpl_ReleaseHfont,
232 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
234 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
235 OLEFontImpl_IDispatch_QueryInterface,
236 OLEFontImpl_IDispatch_AddRef,
237 OLEFontImpl_IDispatch_Release,
238 OLEFontImpl_GetTypeInfoCount,
239 OLEFontImpl_GetTypeInfo,
240 OLEFontImpl_GetIDsOfNames,
244 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
246 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
247 OLEFontImpl_IPersistStream_QueryInterface,
248 OLEFontImpl_IPersistStream_AddRef,
249 OLEFontImpl_IPersistStream_Release,
250 OLEFontImpl_GetClassID,
254 OLEFontImpl_GetSizeMax
257 static ICOM_VTABLE(IConnectionPointContainer)
258 OLEFontImpl_IConnectionPointContainer_VTable =
260 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
261 OLEFontImpl_IConnectionPointContainer_QueryInterface,
262 OLEFontImpl_IConnectionPointContainer_AddRef,
263 OLEFontImpl_IConnectionPointContainer_Release,
264 OLEFontImpl_EnumConnectionPoints,
265 OLEFontImpl_FindConnectionPoint
268 /******************************************************************************
269 * OleCreateFontIndirect [OLEAUT32.420]
271 HRESULT WINAPI OleCreateFontIndirect(
272 LPFONTDESC lpFontDesc,
276 OLEFontImpl* newFont = 0;
279 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
289 return NO_ERROR; /* MSDN Oct 2001 */
292 * Try to construct a new instance of the class.
294 newFont = OLEFontImpl_Construct(lpFontDesc);
297 return E_OUTOFMEMORY;
300 * Make sure it supports the interface required by the caller.
302 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
305 * Release the reference obtained in the constructor. If
306 * the QueryInterface was unsuccessful, it will free the class.
308 IFont_Release((IFont*)newFont);
314 /***********************************************************************
315 * Implementation of the OLEFontImpl class.
318 /***********************************************************************
319 * OLEFont_SendNotify (internal)
321 * Sends notification messages of changed properties to any interested
324 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
326 IEnumConnections *pEnum;
329 IConnectionPoint_EnumConnections(this->pCP, &pEnum);
331 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
332 IPropertyNotifySink *sink;
334 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
335 IPropertyNotifySink_OnChanged(sink, dispID);
336 IPropertyNotifySink_Release(sink);
337 IUnknown_Release(CD.pUnk);
339 IEnumConnections_Release(pEnum);
343 /************************************************************************
344 * OLEFontImpl_Construct
346 * This method will construct a new instance of the OLEFontImpl
349 * The caller of this method must release the object when it's
352 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
354 OLEFontImpl* newObject = 0;
357 * Allocate space for the object.
359 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
365 * Initialize the virtual function table.
367 newObject->lpvtbl1 = &OLEFontImpl_VTable;
368 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
369 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
370 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
373 * Start with one reference count. The caller of this function
374 * must release the interface pointer when it is done.
379 * Copy the description of the font in the object.
381 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
383 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
384 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
386 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
387 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
388 newObject->description.cySize = fontDesc->cySize;
389 newObject->description.sWeight = fontDesc->sWeight;
390 newObject->description.sCharset = fontDesc->sCharset;
391 newObject->description.fItalic = fontDesc->fItalic;
392 newObject->description.fUnderline = fontDesc->fUnderline;
393 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
396 * Initializing all the other members.
398 newObject->gdiFont = 0;
399 newObject->fontLock = 0;
400 newObject->cyHimetric = 1;
401 newObject->cyLogical = 1;
403 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
405 TRACE("returning %p\n", newObject);
409 /************************************************************************
410 * OLEFontImpl_Destroy
412 * This method is called by the Release method when the reference
413 * count goes down to 0. It will free all resources used by
416 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
418 TRACE("(%p)\n", fontDesc);
420 if (fontDesc->description.lpstrName!=0)
421 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
423 if (fontDesc->gdiFont!=0)
424 DeleteObject(fontDesc->gdiFont);
426 HeapFree(GetProcessHeap(), 0, fontDesc);
429 /************************************************************************
430 * OLEFontImpl_QueryInterface (IUnknown)
432 * See Windows documentation for more details on IUnknown methods.
434 HRESULT WINAPI OLEFontImpl_QueryInterface(
439 _ICOM_THIS(OLEFontImpl, iface);
440 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
443 * Perform a sanity check on the parameters.
445 if ( (this==0) || (ppvObject==0) )
449 * Initialize the return parameter.
454 * Compare the riid with the interface IDs implemented by this object.
456 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
458 *ppvObject = (IFont*)this;
460 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
462 *ppvObject = (IFont*)this;
464 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
466 *ppvObject = (IDispatch*)&(this->lpvtbl2);
468 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
470 *ppvObject = (IDispatch*)&(this->lpvtbl2);
472 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
474 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
476 else if (memcmp(&IID_IConnectionPointContainer, riid,
477 sizeof(IID_IConnectionPointContainer)) == 0)
479 *ppvObject = (IPersistStream*)&(this->lpvtbl4);
483 * Check that we obtained an interface.
487 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
488 return E_NOINTERFACE;
492 * Query Interface always increases the reference count by one when it is
495 OLEFontImpl_AddRef((IFont*)this);
500 /************************************************************************
501 * OLEFontImpl_AddRef (IUnknown)
503 * See Windows documentation for more details on IUnknown methods.
505 ULONG WINAPI OLEFontImpl_AddRef(
508 _ICOM_THIS(OLEFontImpl, iface);
509 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
515 /************************************************************************
516 * OLEFontImpl_Release (IUnknown)
518 * See Windows documentation for more details on IUnknown methods.
520 ULONG WINAPI OLEFontImpl_Release(
523 _ICOM_THIS(OLEFontImpl, iface);
524 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
527 * Decrease the reference count on this object.
532 * If the reference count goes down to 0, perform suicide.
536 OLEFontImpl_Destroy(this);
544 /************************************************************************
545 * OLEFontImpl_get_Name (IFont)
547 * See Windows documentation for more details on IFont methods.
549 static HRESULT WINAPI OLEFontImpl_get_Name(
553 _ICOM_THIS(OLEFontImpl, iface);
554 TRACE("(%p)->(%p)\n", this, pname);
561 if (this->description.lpstrName!=0)
562 *pname = SysAllocString(this->description.lpstrName);
569 /************************************************************************
570 * OLEFontImpl_put_Name (IFont)
572 * See Windows documentation for more details on IFont methods.
574 static HRESULT WINAPI OLEFontImpl_put_Name(
578 _ICOM_THIS(OLEFontImpl, iface);
579 TRACE("(%p)->(%p)\n", this, name);
581 if (this->description.lpstrName==0)
583 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
585 (lstrlenW(name)+1) * sizeof(WCHAR));
589 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
591 this->description.lpstrName,
592 (lstrlenW(name)+1) * sizeof(WCHAR));
595 if (this->description.lpstrName==0)
596 return E_OUTOFMEMORY;
598 strcpyW(this->description.lpstrName, name);
599 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
600 OLEFont_SendNotify(this, DISPID_FONT_NAME);
604 /************************************************************************
605 * OLEFontImpl_get_Size (IFont)
607 * See Windows documentation for more details on IFont methods.
609 static HRESULT WINAPI OLEFontImpl_get_Size(
613 _ICOM_THIS(OLEFontImpl, iface);
614 TRACE("(%p)->(%p)\n", this, psize);
623 psize->s.Lo = this->description.cySize.s.Lo;
628 /************************************************************************
629 * OLEFontImpl_put_Size (IFont)
631 * See Windows documentation for more details on IFont methods.
633 static HRESULT WINAPI OLEFontImpl_put_Size(
637 _ICOM_THIS(OLEFontImpl, iface);
638 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
639 this->description.cySize.s.Hi = 0;
640 this->description.cySize.s.Lo = size.s.Lo;
641 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
646 /************************************************************************
647 * OLEFontImpl_get_Bold (IFont)
649 * See Windows documentation for more details on IFont methods.
651 static HRESULT WINAPI OLEFontImpl_get_Bold(
655 _ICOM_THIS(OLEFontImpl, iface);
656 TRACE("(%p)->(%p)\n", this, pbold);
663 *pbold = this->description.sWeight > 550;
668 /************************************************************************
669 * OLEFontImpl_put_Bold (IFont)
671 * See Windows documentation for more details on IFont methods.
673 static HRESULT WINAPI OLEFontImpl_put_Bold(
677 _ICOM_THIS(OLEFontImpl, iface);
678 TRACE("(%p)->(%d)\n", this, bold);
679 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
680 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
685 /************************************************************************
686 * OLEFontImpl_get_Italic (IFont)
688 * See Windows documentation for more details on IFont methods.
690 static HRESULT WINAPI OLEFontImpl_get_Italic(
694 _ICOM_THIS(OLEFontImpl, iface);
695 TRACE("(%p)->(%p)\n", this, pitalic);
702 *pitalic = this->description.fItalic;
707 /************************************************************************
708 * OLEFontImpl_put_Italic (IFont)
710 * See Windows documentation for more details on IFont methods.
712 static HRESULT WINAPI OLEFontImpl_put_Italic(
716 _ICOM_THIS(OLEFontImpl, iface);
717 TRACE("(%p)->(%d)\n", this, italic);
719 this->description.fItalic = italic;
721 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
725 /************************************************************************
726 * OLEFontImpl_get_Underline (IFont)
728 * See Windows documentation for more details on IFont methods.
730 static HRESULT WINAPI OLEFontImpl_get_Underline(
734 _ICOM_THIS(OLEFontImpl, iface);
735 TRACE("(%p)->(%p)\n", this, punderline);
743 *punderline = this->description.fUnderline;
748 /************************************************************************
749 * OLEFontImpl_put_Underline (IFont)
751 * See Windows documentation for more details on IFont methods.
753 static HRESULT WINAPI OLEFontImpl_put_Underline(
757 _ICOM_THIS(OLEFontImpl, iface);
758 TRACE("(%p)->(%d)\n", this, underline);
760 this->description.fUnderline = underline;
762 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
766 /************************************************************************
767 * OLEFontImpl_get_Strikethrough (IFont)
769 * See Windows documentation for more details on IFont methods.
771 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
773 BOOL* pstrikethrough)
775 _ICOM_THIS(OLEFontImpl, iface);
776 TRACE("(%p)->(%p)\n", this, pstrikethrough);
781 if (pstrikethrough==0)
784 *pstrikethrough = this->description.fStrikethrough;
789 /************************************************************************
790 * OLEFontImpl_put_Strikethrough (IFont)
792 * See Windows documentation for more details on IFont methods.
794 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
798 _ICOM_THIS(OLEFontImpl, iface);
799 TRACE("(%p)->(%d)\n", this, strikethrough);
801 this->description.fStrikethrough = strikethrough;
802 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
807 /************************************************************************
808 * OLEFontImpl_get_Weight (IFont)
810 * See Windows documentation for more details on IFont methods.
812 static HRESULT WINAPI OLEFontImpl_get_Weight(
816 _ICOM_THIS(OLEFontImpl, iface);
817 TRACE("(%p)->(%p)\n", this, pweight);
825 *pweight = this->description.sWeight;
830 /************************************************************************
831 * OLEFontImpl_put_Weight (IFont)
833 * See Windows documentation for more details on IFont methods.
835 static HRESULT WINAPI OLEFontImpl_put_Weight(
839 _ICOM_THIS(OLEFontImpl, iface);
840 TRACE("(%p)->(%d)\n", this, weight);
842 this->description.sWeight = weight;
844 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
848 /************************************************************************
849 * OLEFontImpl_get_Charset (IFont)
851 * See Windows documentation for more details on IFont methods.
853 static HRESULT WINAPI OLEFontImpl_get_Charset(
857 _ICOM_THIS(OLEFontImpl, iface);
858 TRACE("(%p)->(%p)\n", this, pcharset);
866 *pcharset = this->description.sCharset;
871 /************************************************************************
872 * OLEFontImpl_put_Charset (IFont)
874 * See Windows documentation for more details on IFont methods.
876 static HRESULT WINAPI OLEFontImpl_put_Charset(
880 _ICOM_THIS(OLEFontImpl, iface);
881 TRACE("(%p)->(%d)\n", this, charset);
883 this->description.sCharset = charset;
884 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
889 /************************************************************************
890 * OLEFontImpl_get_hFont (IFont)
892 * See Windows documentation for more details on IFont methods.
894 static HRESULT WINAPI OLEFontImpl_get_hFont(
898 _ICOM_THIS(OLEFontImpl, iface);
899 TRACE("(%p)->(%p)\n", this, phfont);
904 * Realize the font if necessary
906 if (this->gdiFont==0)
913 * The height of the font returned by the get_Size property is the
914 * height of the font in points multiplied by 10000... Using some
915 * simple conversions and the ratio given by the application, it can
916 * be converted to a height in pixels.
918 IFont_get_Size(iface, &cySize);
920 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
921 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
923 memset(&logFont, 0, sizeof(LOGFONTW));
925 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
926 (-fontHeight/10000L);
927 logFont.lfItalic = this->description.fItalic;
928 logFont.lfUnderline = this->description.fUnderline;
929 logFont.lfStrikeOut = this->description.fStrikethrough;
930 logFont.lfWeight = this->description.sWeight;
931 logFont.lfCharSet = this->description.sCharset;
932 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
933 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
934 logFont.lfQuality = DEFAULT_QUALITY;
935 logFont.lfPitchAndFamily = DEFAULT_PITCH;
936 strcpyW(logFont.lfFaceName,this->description.lpstrName);
938 this->gdiFont = CreateFontIndirectW(&logFont);
941 *phfont = this->gdiFont;
942 TRACE("Returning %08x\n", *phfont);
946 /************************************************************************
947 * OLEFontImpl_Clone (IFont)
949 * See Windows documentation for more details on IFont methods.
951 static HRESULT WINAPI OLEFontImpl_Clone(
955 OLEFontImpl* newObject = 0;
959 _ICOM_THIS(OLEFontImpl, iface);
960 TRACE("(%p)->(%p)\n", this, ppfont);
968 * Allocate space for the object.
970 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
973 return E_OUTOFMEMORY;
977 /* We need to alloc new memory for the string, otherwise
978 * we free memory twice.
980 newObject->description.lpstrName = HeapAlloc(
982 (1+strlenW(this->description.lpstrName))*2
984 /* We need to clone the HFONT too. This is just cut & paste from above */
985 IFont_get_Size(iface, &cySize);
987 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
988 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
990 memset(&logFont, 0, sizeof(LOGFONTW));
992 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
993 (-fontHeight/10000L);
994 logFont.lfItalic = this->description.fItalic;
995 logFont.lfUnderline = this->description.fUnderline;
996 logFont.lfStrikeOut = this->description.fStrikethrough;
997 logFont.lfWeight = this->description.sWeight;
998 logFont.lfCharSet = this->description.sCharset;
999 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
1000 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1001 logFont.lfQuality = DEFAULT_QUALITY;
1002 logFont.lfPitchAndFamily = DEFAULT_PITCH;
1003 strcpyW(logFont.lfFaceName,this->description.lpstrName);
1005 newObject->gdiFont = CreateFontIndirectW(&logFont);
1008 /* The cloned object starts with a reference count of 1 */
1011 *ppfont = (IFont*)newObject;
1016 /************************************************************************
1017 * OLEFontImpl_IsEqual (IFont)
1019 * See Windows documentation for more details on IFont methods.
1021 static HRESULT WINAPI OLEFontImpl_IsEqual(
1029 /************************************************************************
1030 * OLEFontImpl_SetRatio (IFont)
1032 * See Windows documentation for more details on IFont methods.
1034 static HRESULT WINAPI OLEFontImpl_SetRatio(
1039 _ICOM_THIS(OLEFontImpl, iface);
1040 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1042 this->cyLogical = cyLogical;
1043 this->cyHimetric = cyHimetric;
1048 /************************************************************************
1049 * OLEFontImpl_QueryTextMetrics (IFont)
1051 * See Windows documentation for more details on IFont methods.
1053 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1061 /************************************************************************
1062 * OLEFontImpl_AddRefHfont (IFont)
1064 * See Windows documentation for more details on IFont methods.
1066 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1070 _ICOM_THIS(OLEFontImpl, iface);
1071 TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
1073 if ( (hfont == 0) ||
1074 (hfont != this->gdiFont) )
1075 return E_INVALIDARG;
1082 /************************************************************************
1083 * OLEFontImpl_ReleaseHfont (IFont)
1085 * See Windows documentation for more details on IFont methods.
1087 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1091 _ICOM_THIS(OLEFontImpl, iface);
1092 TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
1094 if ( (hfont == 0) ||
1095 (hfont != this->gdiFont) )
1096 return E_INVALIDARG;
1101 * If we just released our last font reference, destroy it.
1103 if (this->fontLock==0)
1105 DeleteObject(this->gdiFont);
1112 /************************************************************************
1113 * OLEFontImpl_SetHdc (IFont)
1115 * See Windows documentation for more details on IFont methods.
1117 static HRESULT WINAPI OLEFontImpl_SetHdc(
1121 _ICOM_THIS(OLEFontImpl, iface);
1122 FIXME("(%p)->(%08x): Stub\n", this, hdc);
1126 /************************************************************************
1127 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1129 * See Windows documentation for more details on IUnknown methods.
1131 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1136 _ICOM_THIS_From_IDispatch(IFont, iface);
1138 return IFont_QueryInterface(this, riid, ppvoid);
1141 /************************************************************************
1142 * OLEFontImpl_IDispatch_Release (IUnknown)
1144 * See Windows documentation for more details on IUnknown methods.
1146 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1149 _ICOM_THIS_From_IDispatch(IFont, iface);
1151 return IFont_Release(this);
1154 /************************************************************************
1155 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1157 * See Windows documentation for more details on IUnknown methods.
1159 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1162 _ICOM_THIS_From_IDispatch(IFont, iface);
1164 return IFont_AddRef(this);
1167 /************************************************************************
1168 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1170 * See Windows documentation for more details on IDispatch methods.
1172 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1174 unsigned int* pctinfo)
1176 _ICOM_THIS_From_IDispatch(IFont, iface);
1177 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1182 /************************************************************************
1183 * OLEFontImpl_GetTypeInfo (IDispatch)
1185 * See Windows documentation for more details on IDispatch methods.
1187 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1191 ITypeInfo** ppTInfo)
1193 _ICOM_THIS_From_IDispatch(IFont, iface);
1194 FIXME("(%p):Stub\n", this);
1199 /************************************************************************
1200 * OLEFontImpl_GetIDsOfNames (IDispatch)
1202 * See Windows documentation for more details on IDispatch methods.
1204 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1207 LPOLESTR* rgszNames,
1212 _ICOM_THIS_From_IDispatch(IFont, iface);
1213 FIXME("(%p):Stub\n", this);
1218 /************************************************************************
1219 * OLEFontImpl_Invoke (IDispatch)
1221 * See Windows documentation for more details on IDispatch methods.
1223 static HRESULT WINAPI OLEFontImpl_Invoke(
1225 DISPID dispIdMember,
1229 DISPPARAMS* pDispParams,
1230 VARIANT* pVarResult,
1231 EXCEPINFO* pExepInfo,
1234 _ICOM_THIS_From_IDispatch(IFont, iface);
1235 FIXME("%p->(%ld,%s,%lx,%x), stub!\n", this,dispIdMember,debugstr_guid(riid),lcid,
1241 /************************************************************************
1242 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1244 * See Windows documentation for more details on IUnknown methods.
1246 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1247 IPersistStream* iface,
1251 _ICOM_THIS_From_IPersistStream(IFont, iface);
1253 return IFont_QueryInterface(this, riid, ppvoid);
1256 /************************************************************************
1257 * OLEFontImpl_IPersistStream_Release (IUnknown)
1259 * See Windows documentation for more details on IUnknown methods.
1261 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1262 IPersistStream* iface)
1264 _ICOM_THIS_From_IPersistStream(IFont, iface);
1266 return IFont_Release(this);
1269 /************************************************************************
1270 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1272 * See Windows documentation for more details on IUnknown methods.
1274 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1275 IPersistStream* iface)
1277 _ICOM_THIS_From_IPersistStream(IFont, iface);
1279 return IFont_AddRef(this);
1282 /************************************************************************
1283 * OLEFontImpl_GetClassID (IPersistStream)
1285 * See Windows documentation for more details on IPersistStream methods.
1287 static HRESULT WINAPI OLEFontImpl_GetClassID(
1288 IPersistStream* iface,
1294 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1299 /************************************************************************
1300 * OLEFontImpl_IsDirty (IPersistStream)
1302 * See Windows documentation for more details on IPersistStream methods.
1304 static HRESULT WINAPI OLEFontImpl_IsDirty(
1305 IPersistStream* iface)
1310 /************************************************************************
1311 * OLEFontImpl_Load (IPersistStream)
1313 * See Windows documentation for more details on IPersistStream methods.
1315 * This is the format of the standard font serialization as far as I
1318 * Offset Type Value Comment
1319 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1320 * 0x0001 Short Charset Charset value from the FONTDESC structure
1321 * 0x0003 Byte Attributes Flags defined as follows:
1323 * 00000100 - Underline
1324 * 00001000 - Strikethrough
1325 * 0x0004 Short Weight Weight value from FONTDESC structure
1326 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1328 * 0x000A Byte name length Length of the font name string (no null character)
1329 * 0x000B String name Name of the font (ASCII, no nul character)
1331 static HRESULT WINAPI OLEFontImpl_Load(
1332 IPersistStream* iface,
1333 IStream* pLoadStream)
1335 char readBuffer[0x100];
1342 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1345 * Read the version byte
1347 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1356 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1364 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1369 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1370 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1371 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1376 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1384 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1389 this->description.cySize.s.Hi = 0;
1394 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1399 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1401 if (cbRead!=bStringSize)
1404 if (this->description.lpstrName!=0)
1405 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1407 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1408 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1409 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1410 this->description.lpstrName[len] = 0;
1415 /************************************************************************
1416 * OLEFontImpl_Save (IPersistStream)
1418 * See Windows documentation for more details on IPersistStream methods.
1420 static HRESULT WINAPI OLEFontImpl_Save(
1421 IPersistStream* iface,
1422 IStream* pOutStream,
1425 char* writeBuffer = NULL;
1427 BYTE bVersion = 0x01;
1431 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1434 * Read the version byte
1436 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1444 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1454 if (this->description.fItalic)
1455 bAttributes |= FONTPERSIST_ITALIC;
1457 if (this->description.fStrikethrough)
1458 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1460 if (this->description.fUnderline)
1461 bAttributes |= FONTPERSIST_UNDERLINE;
1463 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1471 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1479 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1487 if (this->description.lpstrName!=0)
1488 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1489 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1493 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1500 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1501 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1502 strlenW(this->description.lpstrName),
1503 writeBuffer, bStringSize, NULL, NULL );
1505 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1506 HeapFree(GetProcessHeap(), 0, writeBuffer);
1508 if (cbWritten!=bStringSize)
1515 /************************************************************************
1516 * OLEFontImpl_GetSizeMax (IPersistStream)
1518 * See Windows documentation for more details on IPersistStream methods.
1520 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1521 IPersistStream* iface,
1522 ULARGE_INTEGER* pcbSize)
1524 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1529 pcbSize->s.HighPart = 0;
1530 pcbSize->s.LowPart = 0;
1532 pcbSize->s.LowPart += sizeof(BYTE); /* Version */
1533 pcbSize->s.LowPart += sizeof(WORD); /* Lang code */
1534 pcbSize->s.LowPart += sizeof(BYTE); /* Flags */
1535 pcbSize->s.LowPart += sizeof(WORD); /* Weight */
1536 pcbSize->s.LowPart += sizeof(DWORD); /* Size */
1537 pcbSize->s.LowPart += sizeof(BYTE); /* StrLength */
1539 if (this->description.lpstrName!=0)
1540 pcbSize->s.LowPart += lstrlenW(this->description.lpstrName);
1545 /************************************************************************
1546 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1548 * See Windows documentation for more details on IUnknown methods.
1550 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1551 IConnectionPointContainer* iface,
1555 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1557 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1560 /************************************************************************
1561 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1563 * See Windows documentation for more details on IUnknown methods.
1565 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1566 IConnectionPointContainer* iface)
1568 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1570 return IFont_Release((IFont*)this);
1573 /************************************************************************
1574 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1576 * See Windows documentation for more details on IUnknown methods.
1578 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1579 IConnectionPointContainer* iface)
1581 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1583 return IFont_AddRef((IFont*)this);
1586 /************************************************************************
1587 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1589 * See Windows documentation for more details on IConnectionPointContainer
1592 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1593 IConnectionPointContainer* iface,
1594 IEnumConnectionPoints **ppEnum)
1596 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1598 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1602 /************************************************************************
1603 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1605 * See Windows documentation for more details on IConnectionPointContainer
1608 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1609 IConnectionPointContainer* iface,
1611 IConnectionPoint **ppCp)
1613 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1614 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1616 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1617 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1620 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1621 return E_NOINTERFACE;
1625 /*******************************************************************************
1626 * StdFont ClassFactory
1630 /* IUnknown fields */
1631 ICOM_VFIELD(IClassFactory);
1633 } IClassFactoryImpl;
1635 static HRESULT WINAPI
1636 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1637 ICOM_THIS(IClassFactoryImpl,iface);
1639 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1640 return E_NOINTERFACE;
1644 SFCF_AddRef(LPCLASSFACTORY iface) {
1645 ICOM_THIS(IClassFactoryImpl,iface);
1646 return ++(This->ref);
1649 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
1650 ICOM_THIS(IClassFactoryImpl,iface);
1651 /* static class, won't be freed */
1652 return --(This->ref);
1655 static HRESULT WINAPI SFCF_CreateInstance(
1656 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1660 WCHAR fname[] = { 'S','y','s','t','e','m',0 };
1662 fd.cbSizeofstruct = sizeof(fd);
1663 fd.lpstrName = fname;
1664 fd.cySize.s.Lo = 80000;
1670 fd.fStrikethrough = 0;
1671 return OleCreateFontIndirect(&fd,riid,ppobj);
1675 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1676 ICOM_THIS(IClassFactoryImpl,iface);
1677 FIXME("(%p)->(%d),stub!\n",This,dolock);
1681 static ICOM_VTABLE(IClassFactory) SFCF_Vtbl = {
1682 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1683 SFCF_QueryInterface,
1686 SFCF_CreateInstance,
1689 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
1691 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }