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
14 #include "wine/unicode.h"
15 #include "oleauto.h" /* for SysAllocString(....) */
16 #include "wine/obj_olefont.h"
17 #include "wine/obj_storage.h"
19 #include "debugtools.h"
21 #include "connpt.h" /* for CreateConnectionPoint */
23 DEFAULT_DEBUG_CHANNEL(ole);
25 /***********************************************************************
26 * Declaration of constants used when serializing the font object.
28 #define FONTPERSIST_ITALIC 0x02
29 #define FONTPERSIST_UNDERLINE 0x04
30 #define FONTPERSIST_STRIKETHROUGH 0x08
32 /***********************************************************************
33 * Declaration of the implementation class for the IFont interface
35 typedef struct OLEFontImpl OLEFontImpl;
40 * This class supports many interfaces. IUnknown, IFont,
41 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
42 * The first two are supported by the first vtable, the next two are
43 * supported by the second table and the last two have their own.
45 ICOM_VTABLE(IFont)* lpvtbl1;
46 ICOM_VTABLE(IDispatch)* lpvtbl2;
47 ICOM_VTABLE(IPersistStream)* lpvtbl3;
48 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
50 * Reference count for that instance of the class.
55 * This structure contains the description of the class.
60 * Contain the font associated with this object.
75 IConnectionPoint *pCP;
79 * Here, I define utility macros to help with the casting of the
81 * There is a version to accomodate all of the VTables implemented
84 #define _ICOM_THIS(class,name) class* this = (class*)name;
85 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
86 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
87 #define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
90 /***********************************************************************
91 * Prototypes for the implementation functions for the IFont
94 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
95 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
96 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
97 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
98 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
99 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
100 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
101 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
102 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
103 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
104 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
105 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
106 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
107 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
108 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
109 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
110 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
111 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
112 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
113 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
114 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
115 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
116 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
117 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
118 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
119 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
120 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
121 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
122 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
124 /***********************************************************************
125 * Prototypes for the implementation functions for the IDispatch
128 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
131 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
132 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
133 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
134 unsigned int* pctinfo);
135 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
138 ITypeInfo** ppTInfo);
139 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
145 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
150 DISPPARAMS* pDispParams,
152 EXCEPINFO* pExepInfo,
155 /***********************************************************************
156 * Prototypes for the implementation functions for the IPersistStream
159 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
162 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
163 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
164 static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
166 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
167 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
168 IStream* pLoadStream);
169 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
172 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
173 ULARGE_INTEGER* pcbSize);
175 /***********************************************************************
176 * Prototypes for the implementation functions for the
177 * IConnectionPointContainer interface
179 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
180 IConnectionPointContainer* iface,
183 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
184 IConnectionPointContainer* iface);
185 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
186 IConnectionPointContainer* iface);
187 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
188 IConnectionPointContainer* iface,
189 IEnumConnectionPoints **ppEnum);
190 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
191 IConnectionPointContainer* iface,
193 IConnectionPoint **ppCp);
196 * Virtual function tables for the OLEFontImpl class.
198 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
200 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
201 OLEFontImpl_QueryInterface,
204 OLEFontImpl_get_Name,
205 OLEFontImpl_put_Name,
206 OLEFontImpl_get_Size,
207 OLEFontImpl_put_Size,
208 OLEFontImpl_get_Bold,
209 OLEFontImpl_put_Bold,
210 OLEFontImpl_get_Italic,
211 OLEFontImpl_put_Italic,
212 OLEFontImpl_get_Underline,
213 OLEFontImpl_put_Underline,
214 OLEFontImpl_get_Strikethrough,
215 OLEFontImpl_put_Strikethrough,
216 OLEFontImpl_get_Weight,
217 OLEFontImpl_put_Weight,
218 OLEFontImpl_get_Charset,
219 OLEFontImpl_put_Charset,
220 OLEFontImpl_get_hFont,
223 OLEFontImpl_SetRatio,
224 OLEFontImpl_QueryTextMetrics,
225 OLEFontImpl_AddRefHfont,
226 OLEFontImpl_ReleaseHfont,
230 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
232 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
233 OLEFontImpl_IDispatch_QueryInterface,
234 OLEFontImpl_IDispatch_AddRef,
235 OLEFontImpl_IDispatch_Release,
236 OLEFontImpl_GetTypeInfoCount,
237 OLEFontImpl_GetTypeInfo,
238 OLEFontImpl_GetIDsOfNames,
242 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
244 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
245 OLEFontImpl_IPersistStream_QueryInterface,
246 OLEFontImpl_IPersistStream_AddRef,
247 OLEFontImpl_IPersistStream_Release,
248 OLEFontImpl_GetClassID,
252 OLEFontImpl_GetSizeMax
255 static ICOM_VTABLE(IConnectionPointContainer)
256 OLEFontImpl_IConnectionPointContainer_VTable =
258 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
259 OLEFontImpl_IConnectionPointContainer_QueryInterface,
260 OLEFontImpl_IConnectionPointContainer_AddRef,
261 OLEFontImpl_IConnectionPointContainer_Release,
262 OLEFontImpl_EnumConnectionPoints,
263 OLEFontImpl_FindConnectionPoint
266 /******************************************************************************
267 * OleCreateFontIndirect [OLEAUT32.420]
269 HRESULT WINAPI OleCreateFontIndirect(
270 LPFONTDESC lpFontDesc,
274 OLEFontImpl* newFont = 0;
277 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
287 * Try to construct a new instance of the class.
289 newFont = OLEFontImpl_Construct(lpFontDesc);
292 return E_OUTOFMEMORY;
295 * Make sure it supports the interface required by the caller.
297 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
300 * Release the reference obtained in the constructor. If
301 * the QueryInterface was unsuccessful, it will free the class.
303 IFont_Release((IFont*)newFont);
309 /***********************************************************************
310 * Implementation of the OLEFontImpl class.
313 /***********************************************************************
314 * OLEFont_SendNotify (internal)
316 * Sends notification messages of changed properties to any interested
319 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
321 IEnumConnections *pEnum;
324 IConnectionPoint_EnumConnections(this->pCP, &pEnum);
326 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
327 IPropertyNotifySink *sink;
329 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
330 IPropertyNotifySink_OnChanged(sink, dispID);
331 IPropertyNotifySink_Release(sink);
332 IUnknown_Release(CD.pUnk);
334 IEnumConnections_Release(pEnum);
338 /************************************************************************
339 * OLEFontImpl_Construct
341 * This method will construct a new instance of the OLEFontImpl
344 * The caller of this method must release the object when it's
347 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
349 OLEFontImpl* newObject = 0;
352 * Allocate space for the object.
354 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
360 * Initialize the virtual function table.
362 newObject->lpvtbl1 = &OLEFontImpl_VTable;
363 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
364 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
365 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
368 * Start with one reference count. The caller of this function
369 * must release the interface pointer when it is done.
374 * Copy the description of the font in the object.
376 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
378 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
379 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
381 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
382 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
383 newObject->description.cySize = fontDesc->cySize;
384 newObject->description.sWeight = fontDesc->sWeight;
385 newObject->description.sCharset = fontDesc->sCharset;
386 newObject->description.fItalic = fontDesc->fItalic;
387 newObject->description.fUnderline = fontDesc->fUnderline;
388 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
391 * Initializing all the other members.
393 newObject->gdiFont = 0;
394 newObject->fontLock = 0;
395 newObject->cyHimetric = 1;
396 newObject->cyLogical = 1;
398 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
400 TRACE("returning %p\n", newObject);
404 /************************************************************************
405 * OLEFontImpl_Destroy
407 * This method is called by the Release method when the reference
408 * count goes down to 0. It will free all resources used by
411 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
413 TRACE("(%p)\n", fontDesc);
415 if (fontDesc->description.lpstrName!=0)
416 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
418 if (fontDesc->gdiFont!=0)
419 DeleteObject(fontDesc->gdiFont);
421 HeapFree(GetProcessHeap(), 0, fontDesc);
424 /************************************************************************
425 * OLEFontImpl_QueryInterface (IUnknown)
427 * See Windows documentation for more details on IUnknown methods.
429 HRESULT WINAPI OLEFontImpl_QueryInterface(
434 _ICOM_THIS(OLEFontImpl, iface);
435 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
438 * Perform a sanity check on the parameters.
440 if ( (this==0) || (ppvObject==0) )
444 * Initialize the return parameter.
449 * Compare the riid with the interface IDs implemented by this object.
451 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
453 *ppvObject = (IFont*)this;
455 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
457 *ppvObject = (IFont*)this;
459 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
461 *ppvObject = (IDispatch*)&(this->lpvtbl2);
463 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
465 *ppvObject = (IDispatch*)&(this->lpvtbl2);
467 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
469 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
471 else if (memcmp(&IID_IConnectionPointContainer, riid,
472 sizeof(IID_IConnectionPointContainer)) == 0)
474 *ppvObject = (IPersistStream*)&(this->lpvtbl4);
478 * Check that we obtained an interface.
482 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
483 return E_NOINTERFACE;
487 * Query Interface always increases the reference count by one when it is
490 OLEFontImpl_AddRef((IFont*)this);
495 /************************************************************************
496 * OLEFontImpl_AddRef (IUnknown)
498 * See Windows documentation for more details on IUnknown methods.
500 ULONG WINAPI OLEFontImpl_AddRef(
503 _ICOM_THIS(OLEFontImpl, iface);
504 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
510 /************************************************************************
511 * OLEFontImpl_Release (IUnknown)
513 * See Windows documentation for more details on IUnknown methods.
515 ULONG WINAPI OLEFontImpl_Release(
518 _ICOM_THIS(OLEFontImpl, iface);
519 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
522 * Decrease the reference count on this object.
527 * If the reference count goes down to 0, perform suicide.
531 OLEFontImpl_Destroy(this);
539 /************************************************************************
540 * OLEFontImpl_get_Name (IFont)
542 * See Windows documentation for more details on IFont methods.
544 static HRESULT WINAPI OLEFontImpl_get_Name(
548 _ICOM_THIS(OLEFontImpl, iface);
549 TRACE("(%p)->(%p)\n", this, pname);
556 if (this->description.lpstrName!=0)
557 *pname = SysAllocString(this->description.lpstrName);
564 /************************************************************************
565 * OLEFontImpl_put_Name (IFont)
567 * See Windows documentation for more details on IFont methods.
569 static HRESULT WINAPI OLEFontImpl_put_Name(
573 _ICOM_THIS(OLEFontImpl, iface);
574 TRACE("(%p)->(%p)\n", this, name);
576 if (this->description.lpstrName==0)
578 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
580 (lstrlenW(name)+1) * sizeof(WCHAR));
584 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
586 this->description.lpstrName,
587 (lstrlenW(name)+1) * sizeof(WCHAR));
590 if (this->description.lpstrName==0)
591 return E_OUTOFMEMORY;
593 strcpyW(this->description.lpstrName, name);
594 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
595 OLEFont_SendNotify(this, DISPID_FONT_NAME);
599 /************************************************************************
600 * OLEFontImpl_get_Size (IFont)
602 * See Windows documentation for more details on IFont methods.
604 static HRESULT WINAPI OLEFontImpl_get_Size(
608 _ICOM_THIS(OLEFontImpl, iface);
609 TRACE("(%p)->(%p)\n", this, psize);
618 psize->s.Lo = this->description.cySize.s.Lo;
623 /************************************************************************
624 * OLEFontImpl_put_Size (IFont)
626 * See Windows documentation for more details on IFont methods.
628 static HRESULT WINAPI OLEFontImpl_put_Size(
632 _ICOM_THIS(OLEFontImpl, iface);
633 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
634 this->description.cySize.s.Hi = 0;
635 this->description.cySize.s.Lo = size.s.Lo;
636 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
641 /************************************************************************
642 * OLEFontImpl_get_Bold (IFont)
644 * See Windows documentation for more details on IFont methods.
646 static HRESULT WINAPI OLEFontImpl_get_Bold(
650 _ICOM_THIS(OLEFontImpl, iface);
651 TRACE("(%p)->(%p)\n", this, pbold);
658 *pbold = this->description.sWeight > 550;
663 /************************************************************************
664 * OLEFontImpl_put_Bold (IFont)
666 * See Windows documentation for more details on IFont methods.
668 static HRESULT WINAPI OLEFontImpl_put_Bold(
672 _ICOM_THIS(OLEFontImpl, iface);
673 TRACE("(%p)->(%d)\n", this, bold);
674 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
675 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
680 /************************************************************************
681 * OLEFontImpl_get_Italic (IFont)
683 * See Windows documentation for more details on IFont methods.
685 static HRESULT WINAPI OLEFontImpl_get_Italic(
689 _ICOM_THIS(OLEFontImpl, iface);
690 TRACE("(%p)->(%p)\n", this, pitalic);
697 *pitalic = this->description.fItalic;
702 /************************************************************************
703 * OLEFontImpl_put_Italic (IFont)
705 * See Windows documentation for more details on IFont methods.
707 static HRESULT WINAPI OLEFontImpl_put_Italic(
711 _ICOM_THIS(OLEFontImpl, iface);
712 TRACE("(%p)->(%d)\n", this, italic);
714 this->description.fItalic = italic;
716 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
720 /************************************************************************
721 * OLEFontImpl_get_Underline (IFont)
723 * See Windows documentation for more details on IFont methods.
725 static HRESULT WINAPI OLEFontImpl_get_Underline(
729 _ICOM_THIS(OLEFontImpl, iface);
730 TRACE("(%p)->(%p)\n", this, punderline);
738 *punderline = this->description.fUnderline;
743 /************************************************************************
744 * OLEFontImpl_put_Underline (IFont)
746 * See Windows documentation for more details on IFont methods.
748 static HRESULT WINAPI OLEFontImpl_put_Underline(
752 _ICOM_THIS(OLEFontImpl, iface);
753 TRACE("(%p)->(%d)\n", this, underline);
755 this->description.fUnderline = underline;
757 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
761 /************************************************************************
762 * OLEFontImpl_get_Strikethrough (IFont)
764 * See Windows documentation for more details on IFont methods.
766 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
768 BOOL* pstrikethrough)
770 _ICOM_THIS(OLEFontImpl, iface);
771 TRACE("(%p)->(%p)\n", this, pstrikethrough);
776 if (pstrikethrough==0)
779 *pstrikethrough = this->description.fStrikethrough;
784 /************************************************************************
785 * OLEFontImpl_put_Strikethrough (IFont)
787 * See Windows documentation for more details on IFont methods.
789 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
793 _ICOM_THIS(OLEFontImpl, iface);
794 TRACE("(%p)->(%d)\n", this, strikethrough);
796 this->description.fStrikethrough = strikethrough;
797 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
802 /************************************************************************
803 * OLEFontImpl_get_Weight (IFont)
805 * See Windows documentation for more details on IFont methods.
807 static HRESULT WINAPI OLEFontImpl_get_Weight(
811 _ICOM_THIS(OLEFontImpl, iface);
812 TRACE("(%p)->(%p)\n", this, pweight);
820 *pweight = this->description.sWeight;
825 /************************************************************************
826 * OLEFontImpl_put_Weight (IFont)
828 * See Windows documentation for more details on IFont methods.
830 static HRESULT WINAPI OLEFontImpl_put_Weight(
834 _ICOM_THIS(OLEFontImpl, iface);
835 TRACE("(%p)->(%d)\n", this, weight);
837 this->description.sWeight = weight;
839 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
843 /************************************************************************
844 * OLEFontImpl_get_Charset (IFont)
846 * See Windows documentation for more details on IFont methods.
848 static HRESULT WINAPI OLEFontImpl_get_Charset(
852 _ICOM_THIS(OLEFontImpl, iface);
853 TRACE("(%p)->(%p)\n", this, pcharset);
861 *pcharset = this->description.sCharset;
866 /************************************************************************
867 * OLEFontImpl_put_Charset (IFont)
869 * See Windows documentation for more details on IFont methods.
871 static HRESULT WINAPI OLEFontImpl_put_Charset(
875 _ICOM_THIS(OLEFontImpl, iface);
876 TRACE("(%p)->(%d)\n", this, charset);
878 this->description.sCharset = charset;
879 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
884 /************************************************************************
885 * OLEFontImpl_get_hFont (IFont)
887 * See Windows documentation for more details on IFont methods.
889 static HRESULT WINAPI OLEFontImpl_get_hFont(
893 _ICOM_THIS(OLEFontImpl, iface);
894 TRACE("(%p)->(%p)\n", this, phfont);
899 * Realize the font if necessary
901 if (this->gdiFont==0)
908 * The height of the font returned by the get_Size property is the
909 * height of the font in points multiplied by 10000... Using some
910 * simple conversions and the ratio given by the application, it can
911 * be converted to a height in pixels.
913 IFont_get_Size(iface, &cySize);
915 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
916 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
918 memset(&logFont, 0, sizeof(LOGFONTW));
920 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
921 (-fontHeight/10000L);
922 logFont.lfItalic = this->description.fItalic;
923 logFont.lfUnderline = this->description.fUnderline;
924 logFont.lfStrikeOut = this->description.fStrikethrough;
925 logFont.lfWeight = this->description.sWeight;
926 logFont.lfCharSet = this->description.sCharset;
927 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
928 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
929 logFont.lfQuality = DEFAULT_QUALITY;
930 logFont.lfPitchAndFamily = DEFAULT_PITCH;
931 strcpyW(logFont.lfFaceName,this->description.lpstrName);
933 this->gdiFont = CreateFontIndirectW(&logFont);
936 *phfont = this->gdiFont;
937 TRACE("Returning %08x\n", *phfont);
941 /************************************************************************
942 * OLEFontImpl_Clone (IFont)
944 * See Windows documentation for more details on IFont methods.
946 static HRESULT WINAPI OLEFontImpl_Clone(
950 OLEFontImpl* newObject = 0;
951 _ICOM_THIS(OLEFontImpl, iface);
952 TRACE("(%p)->(%p)\n", this, ppfont);
960 * Allocate space for the object.
962 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
965 return E_OUTOFMEMORY;
970 * That new object starts with a reference count of 1
974 *ppfont = (IFont*)newObject;
979 /************************************************************************
980 * OLEFontImpl_IsEqual (IFont)
982 * See Windows documentation for more details on IFont methods.
984 static HRESULT WINAPI OLEFontImpl_IsEqual(
992 /************************************************************************
993 * OLEFontImpl_SetRatio (IFont)
995 * See Windows documentation for more details on IFont methods.
997 static HRESULT WINAPI OLEFontImpl_SetRatio(
1002 _ICOM_THIS(OLEFontImpl, iface);
1003 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1005 this->cyLogical = cyLogical;
1006 this->cyHimetric = cyHimetric;
1011 /************************************************************************
1012 * OLEFontImpl_QueryTextMetrics (IFont)
1014 * See Windows documentation for more details on IFont methods.
1016 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1024 /************************************************************************
1025 * OLEFontImpl_AddRefHfont (IFont)
1027 * See Windows documentation for more details on IFont methods.
1029 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1033 _ICOM_THIS(OLEFontImpl, iface);
1034 TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
1036 if ( (hfont == 0) ||
1037 (hfont != this->gdiFont) )
1038 return E_INVALIDARG;
1045 /************************************************************************
1046 * OLEFontImpl_ReleaseHfont (IFont)
1048 * See Windows documentation for more details on IFont methods.
1050 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1054 _ICOM_THIS(OLEFontImpl, iface);
1055 TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
1057 if ( (hfont == 0) ||
1058 (hfont != this->gdiFont) )
1059 return E_INVALIDARG;
1064 * If we just released our last font reference, destroy it.
1066 if (this->fontLock==0)
1068 DeleteObject(this->gdiFont);
1075 /************************************************************************
1076 * OLEFontImpl_SetHdc (IFont)
1078 * See Windows documentation for more details on IFont methods.
1080 static HRESULT WINAPI OLEFontImpl_SetHdc(
1084 _ICOM_THIS(OLEFontImpl, iface);
1085 FIXME("(%p)->(%08x): Stub\n", this, hdc);
1089 /************************************************************************
1090 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1092 * See Windows documentation for more details on IUnknown methods.
1094 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1099 _ICOM_THIS_From_IDispatch(IFont, iface);
1101 return IFont_QueryInterface(this, riid, ppvoid);
1104 /************************************************************************
1105 * OLEFontImpl_IDispatch_Release (IUnknown)
1107 * See Windows documentation for more details on IUnknown methods.
1109 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1112 _ICOM_THIS_From_IDispatch(IFont, iface);
1114 return IFont_Release(this);
1117 /************************************************************************
1118 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1120 * See Windows documentation for more details on IUnknown methods.
1122 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1125 _ICOM_THIS_From_IDispatch(IFont, iface);
1127 return IFont_AddRef(this);
1130 /************************************************************************
1131 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1133 * See Windows documentation for more details on IDispatch methods.
1135 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1137 unsigned int* pctinfo)
1139 _ICOM_THIS_From_IDispatch(IFont, iface);
1140 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1145 /************************************************************************
1146 * OLEFontImpl_GetTypeInfo (IDispatch)
1148 * See Windows documentation for more details on IDispatch methods.
1150 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1154 ITypeInfo** ppTInfo)
1156 _ICOM_THIS_From_IDispatch(IFont, iface);
1157 FIXME("(%p):Stub\n", this);
1162 /************************************************************************
1163 * OLEFontImpl_GetIDsOfNames (IDispatch)
1165 * See Windows documentation for more details on IDispatch methods.
1167 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1170 LPOLESTR* rgszNames,
1175 _ICOM_THIS_From_IDispatch(IFont, iface);
1176 FIXME("(%p):Stub\n", this);
1181 /************************************************************************
1182 * OLEFontImpl_Invoke (IDispatch)
1184 * See Windows documentation for more details on IDispatch methods.
1186 static HRESULT WINAPI OLEFontImpl_Invoke(
1188 DISPID dispIdMember,
1192 DISPPARAMS* pDispParams,
1193 VARIANT* pVarResult,
1194 EXCEPINFO* pExepInfo,
1197 _ICOM_THIS_From_IDispatch(IFont, iface);
1198 FIXME("(%p):Stub\n", this);
1203 /************************************************************************
1204 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1206 * See Windows documentation for more details on IUnknown methods.
1208 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1209 IPersistStream* iface,
1213 _ICOM_THIS_From_IPersistStream(IFont, iface);
1215 return IFont_QueryInterface(this, riid, ppvoid);
1218 /************************************************************************
1219 * OLEFontImpl_IPersistStream_Release (IUnknown)
1221 * See Windows documentation for more details on IUnknown methods.
1223 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1224 IPersistStream* iface)
1226 _ICOM_THIS_From_IPersistStream(IFont, iface);
1228 return IFont_Release(this);
1231 /************************************************************************
1232 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1234 * See Windows documentation for more details on IUnknown methods.
1236 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1237 IPersistStream* iface)
1239 _ICOM_THIS_From_IPersistStream(IFont, iface);
1241 return IFont_AddRef(this);
1244 /************************************************************************
1245 * OLEFontImpl_GetClassID (IPersistStream)
1247 * See Windows documentation for more details on IPersistStream methods.
1249 static HRESULT WINAPI OLEFontImpl_GetClassID(
1250 IPersistStream* iface,
1256 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1261 /************************************************************************
1262 * OLEFontImpl_IsDirty (IPersistStream)
1264 * See Windows documentation for more details on IPersistStream methods.
1266 static HRESULT WINAPI OLEFontImpl_IsDirty(
1267 IPersistStream* iface)
1272 /************************************************************************
1273 * OLEFontImpl_Load (IPersistStream)
1275 * See Windows documentation for more details on IPersistStream methods.
1277 * This is the format of the standard font serialization as far as I
1280 * Offset Type Value Comment
1281 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1282 * 0x0001 Short Charset Charset value from the FONTDESC structure
1283 * 0x0003 Byte Attributes Flags defined as follows:
1285 * 00000100 - Underline
1286 * 00001000 - Strikethrough
1287 * 0x0004 Short Weight Weight value from FONTDESC structure
1288 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1290 * 0x000A Byte name length Length of the font name string (no null character)
1291 * 0x000B String name Name of the font (ASCII, no nul character)
1293 static HRESULT WINAPI OLEFontImpl_Load(
1294 IPersistStream* iface,
1295 IStream* pLoadStream)
1297 char readBuffer[0x100];
1303 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1306 * Read the version byte
1308 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1317 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1325 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1330 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1331 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1332 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1337 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1345 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1350 this->description.cySize.s.Hi = 0;
1355 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1360 memset(readBuffer, 0, 0x100);
1361 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1363 if (cbRead!=bStringSize)
1366 if (this->description.lpstrName!=0)
1367 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1369 this->description.lpstrName = HEAP_strdupAtoW(GetProcessHeap(),
1376 /************************************************************************
1377 * OLEFontImpl_Save (IPersistStream)
1379 * See Windows documentation for more details on IPersistStream methods.
1381 static HRESULT WINAPI OLEFontImpl_Save(
1382 IPersistStream* iface,
1383 IStream* pOutStream,
1386 char* writeBuffer = NULL;
1388 BYTE bVersion = 0x01;
1392 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1395 * Read the version byte
1397 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1405 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1415 if (this->description.fItalic)
1416 bAttributes |= FONTPERSIST_ITALIC;
1418 if (this->description.fStrikethrough)
1419 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1421 if (this->description.fUnderline)
1422 bAttributes |= FONTPERSIST_UNDERLINE;
1424 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1432 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1440 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1448 if (this->description.lpstrName!=0)
1449 bStringSize = lstrlenW(this->description.lpstrName);
1453 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1460 writeBuffer = HEAP_strdupWtoA(GetProcessHeap(),
1462 this->description.lpstrName);
1465 return E_OUTOFMEMORY;
1467 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1469 HeapFree(GetProcessHeap(), 0, writeBuffer);
1471 if (cbWritten!=bStringSize)
1478 /************************************************************************
1479 * OLEFontImpl_GetSizeMax (IPersistStream)
1481 * See Windows documentation for more details on IPersistStream methods.
1483 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1484 IPersistStream* iface,
1485 ULARGE_INTEGER* pcbSize)
1487 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1492 pcbSize->s.HighPart = 0;
1493 pcbSize->s.LowPart = 0;
1495 pcbSize->s.LowPart += sizeof(BYTE); /* Version */
1496 pcbSize->s.LowPart += sizeof(WORD); /* Lang code */
1497 pcbSize->s.LowPart += sizeof(BYTE); /* Flags */
1498 pcbSize->s.LowPart += sizeof(WORD); /* Weight */
1499 pcbSize->s.LowPart += sizeof(DWORD); /* Size */
1500 pcbSize->s.LowPart += sizeof(BYTE); /* StrLength */
1502 if (this->description.lpstrName!=0)
1503 pcbSize->s.LowPart += lstrlenW(this->description.lpstrName);
1508 /************************************************************************
1509 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1511 * See Windows documentation for more details on IUnknown methods.
1513 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1514 IConnectionPointContainer* iface,
1518 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1520 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1523 /************************************************************************
1524 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1526 * See Windows documentation for more details on IUnknown methods.
1528 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1529 IConnectionPointContainer* iface)
1531 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1533 return IFont_Release((IFont*)this);
1536 /************************************************************************
1537 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1539 * See Windows documentation for more details on IUnknown methods.
1541 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1542 IConnectionPointContainer* iface)
1544 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1546 return IFont_AddRef((IFont*)this);
1549 /************************************************************************
1550 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1552 * See Windows documentation for more details on IConnectionPointContainer
1555 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1556 IConnectionPointContainer* iface,
1557 IEnumConnectionPoints **ppEnum)
1559 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1561 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1565 /************************************************************************
1566 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1568 * See Windows documentation for more details on IConnectionPointContainer
1571 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1572 IConnectionPointContainer* iface,
1574 IConnectionPoint **ppCp)
1576 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1577 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1579 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1580 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1583 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1584 return E_NOINTERFACE;