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
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 #include "wine/unicode.h"
30 #include "oleauto.h" /* for SysAllocString(....) */
34 #include "wine/debug.h"
35 #include "connpt.h" /* for CreateConnectionPoint */
37 WINE_DEFAULT_DEBUG_CHANNEL(ole);
39 /***********************************************************************
40 * Declaration of constants used when serializing the font object.
42 #define FONTPERSIST_ITALIC 0x02
43 #define FONTPERSIST_UNDERLINE 0x04
44 #define FONTPERSIST_STRIKETHROUGH 0x08
46 /***********************************************************************
47 * Declaration of the implementation class for the IFont interface
49 typedef struct OLEFontImpl OLEFontImpl;
54 * This class supports many interfaces. IUnknown, IFont,
55 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
56 * The first two are supported by the first vtable, the next two are
57 * supported by the second table and the last two have their own.
59 ICOM_VTABLE(IFont)* lpvtbl1;
60 ICOM_VTABLE(IDispatch)* lpvtbl2;
61 ICOM_VTABLE(IPersistStream)* lpvtbl3;
62 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
64 * Reference count for that instance of the class.
69 * This structure contains the description of the class.
74 * Contain the font associated with this object.
89 IConnectionPoint *pCP;
93 * Here, I define utility macros to help with the casting of the
95 * There is a version to accomodate all of the VTables implemented
98 #define _ICOM_THIS(class,name) class* this = (class*)name;
99 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
100 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
101 #define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
104 /***********************************************************************
105 * Prototypes for the implementation functions for the IFont
108 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
109 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
110 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
111 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
112 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
113 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
114 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
115 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
116 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
117 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
118 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
119 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
120 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
121 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
122 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
123 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
124 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
125 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
126 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
127 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
128 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
129 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
130 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
131 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
132 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
133 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
134 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
135 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
136 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
138 /***********************************************************************
139 * Prototypes for the implementation functions for the IDispatch
142 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
145 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
146 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
147 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
148 unsigned int* pctinfo);
149 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
152 ITypeInfo** ppTInfo);
153 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
159 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
164 DISPPARAMS* pDispParams,
166 EXCEPINFO* pExepInfo,
169 /***********************************************************************
170 * Prototypes for the implementation functions for the IPersistStream
173 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
176 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
177 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
178 static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
180 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
181 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
182 IStream* pLoadStream);
183 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
186 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
187 ULARGE_INTEGER* pcbSize);
189 /***********************************************************************
190 * Prototypes for the implementation functions for the
191 * IConnectionPointContainer interface
193 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
194 IConnectionPointContainer* iface,
197 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
198 IConnectionPointContainer* iface);
199 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
200 IConnectionPointContainer* iface);
201 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
202 IConnectionPointContainer* iface,
203 IEnumConnectionPoints **ppEnum);
204 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
205 IConnectionPointContainer* iface,
207 IConnectionPoint **ppCp);
210 * Virtual function tables for the OLEFontImpl class.
212 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
214 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
215 OLEFontImpl_QueryInterface,
218 OLEFontImpl_get_Name,
219 OLEFontImpl_put_Name,
220 OLEFontImpl_get_Size,
221 OLEFontImpl_put_Size,
222 OLEFontImpl_get_Bold,
223 OLEFontImpl_put_Bold,
224 OLEFontImpl_get_Italic,
225 OLEFontImpl_put_Italic,
226 OLEFontImpl_get_Underline,
227 OLEFontImpl_put_Underline,
228 OLEFontImpl_get_Strikethrough,
229 OLEFontImpl_put_Strikethrough,
230 OLEFontImpl_get_Weight,
231 OLEFontImpl_put_Weight,
232 OLEFontImpl_get_Charset,
233 OLEFontImpl_put_Charset,
234 OLEFontImpl_get_hFont,
237 OLEFontImpl_SetRatio,
238 OLEFontImpl_QueryTextMetrics,
239 OLEFontImpl_AddRefHfont,
240 OLEFontImpl_ReleaseHfont,
244 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
246 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
247 OLEFontImpl_IDispatch_QueryInterface,
248 OLEFontImpl_IDispatch_AddRef,
249 OLEFontImpl_IDispatch_Release,
250 OLEFontImpl_GetTypeInfoCount,
251 OLEFontImpl_GetTypeInfo,
252 OLEFontImpl_GetIDsOfNames,
256 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
258 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
259 OLEFontImpl_IPersistStream_QueryInterface,
260 OLEFontImpl_IPersistStream_AddRef,
261 OLEFontImpl_IPersistStream_Release,
262 OLEFontImpl_GetClassID,
266 OLEFontImpl_GetSizeMax
269 static ICOM_VTABLE(IConnectionPointContainer)
270 OLEFontImpl_IConnectionPointContainer_VTable =
272 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
273 OLEFontImpl_IConnectionPointContainer_QueryInterface,
274 OLEFontImpl_IConnectionPointContainer_AddRef,
275 OLEFontImpl_IConnectionPointContainer_Release,
276 OLEFontImpl_EnumConnectionPoints,
277 OLEFontImpl_FindConnectionPoint
280 /******************************************************************************
281 * OleCreateFontIndirect [OLEAUT32.420]
283 HRESULT WINAPI OleCreateFontIndirect(
284 LPFONTDESC lpFontDesc,
288 OLEFontImpl* newFont = 0;
291 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
301 return NO_ERROR; /* MSDN Oct 2001 */
304 * Try to construct a new instance of the class.
306 newFont = OLEFontImpl_Construct(lpFontDesc);
309 return E_OUTOFMEMORY;
312 * Make sure it supports the interface required by the caller.
314 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
317 * Release the reference obtained in the constructor. If
318 * the QueryInterface was unsuccessful, it will free the class.
320 IFont_Release((IFont*)newFont);
326 /***********************************************************************
327 * Implementation of the OLEFontImpl class.
330 /***********************************************************************
331 * OLEFont_SendNotify (internal)
333 * Sends notification messages of changed properties to any interested
336 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
338 IEnumConnections *pEnum;
341 IConnectionPoint_EnumConnections(this->pCP, &pEnum);
343 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
344 IPropertyNotifySink *sink;
346 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
347 IPropertyNotifySink_OnChanged(sink, dispID);
348 IPropertyNotifySink_Release(sink);
349 IUnknown_Release(CD.pUnk);
351 IEnumConnections_Release(pEnum);
355 /************************************************************************
356 * OLEFontImpl_Construct
358 * This method will construct a new instance of the OLEFontImpl
361 * The caller of this method must release the object when it's
364 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
366 OLEFontImpl* newObject = 0;
369 * Allocate space for the object.
371 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
377 * Initialize the virtual function table.
379 newObject->lpvtbl1 = &OLEFontImpl_VTable;
380 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
381 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
382 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
385 * Start with one reference count. The caller of this function
386 * must release the interface pointer when it is done.
391 * Copy the description of the font in the object.
393 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
395 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
396 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
398 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
399 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
400 newObject->description.cySize = fontDesc->cySize;
401 newObject->description.sWeight = fontDesc->sWeight;
402 newObject->description.sCharset = fontDesc->sCharset;
403 newObject->description.fItalic = fontDesc->fItalic;
404 newObject->description.fUnderline = fontDesc->fUnderline;
405 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
408 * Initializing all the other members.
410 newObject->gdiFont = 0;
411 newObject->fontLock = 0;
412 newObject->cyHimetric = 1;
413 newObject->cyLogical = 1;
415 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
417 TRACE("returning %p\n", newObject);
421 /************************************************************************
422 * OLEFontImpl_Destroy
424 * This method is called by the Release method when the reference
425 * count goes down to 0. It will free all resources used by
428 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
430 TRACE("(%p)\n", fontDesc);
432 if (fontDesc->description.lpstrName!=0)
433 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
435 if (fontDesc->gdiFont!=0)
436 DeleteObject(fontDesc->gdiFont);
438 HeapFree(GetProcessHeap(), 0, fontDesc);
441 /************************************************************************
442 * OLEFontImpl_QueryInterface (IUnknown)
444 * See Windows documentation for more details on IUnknown methods.
446 HRESULT WINAPI OLEFontImpl_QueryInterface(
451 _ICOM_THIS(OLEFontImpl, iface);
452 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
455 * Perform a sanity check on the parameters.
457 if ( (this==0) || (ppvObject==0) )
461 * Initialize the return parameter.
466 * Compare the riid with the interface IDs implemented by this object.
468 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
470 *ppvObject = (IFont*)this;
472 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
474 *ppvObject = (IFont*)this;
476 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
478 *ppvObject = (IDispatch*)&(this->lpvtbl2);
480 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
482 *ppvObject = (IDispatch*)&(this->lpvtbl2);
484 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
486 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
488 else if (memcmp(&IID_IConnectionPointContainer, riid,
489 sizeof(IID_IConnectionPointContainer)) == 0)
491 *ppvObject = (IPersistStream*)&(this->lpvtbl4);
495 * Check that we obtained an interface.
499 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
500 return E_NOINTERFACE;
504 * Query Interface always increases the reference count by one when it is
507 OLEFontImpl_AddRef((IFont*)this);
512 /************************************************************************
513 * OLEFontImpl_AddRef (IUnknown)
515 * See Windows documentation for more details on IUnknown methods.
517 ULONG WINAPI OLEFontImpl_AddRef(
520 _ICOM_THIS(OLEFontImpl, iface);
521 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
527 /************************************************************************
528 * OLEFontImpl_Release (IUnknown)
530 * See Windows documentation for more details on IUnknown methods.
532 ULONG WINAPI OLEFontImpl_Release(
535 _ICOM_THIS(OLEFontImpl, iface);
536 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
539 * Decrease the reference count on this object.
544 * If the reference count goes down to 0, perform suicide.
548 OLEFontImpl_Destroy(this);
556 /************************************************************************
557 * OLEFontImpl_get_Name (IFont)
559 * See Windows documentation for more details on IFont methods.
561 static HRESULT WINAPI OLEFontImpl_get_Name(
565 _ICOM_THIS(OLEFontImpl, iface);
566 TRACE("(%p)->(%p)\n", this, pname);
573 if (this->description.lpstrName!=0)
574 *pname = SysAllocString(this->description.lpstrName);
581 /************************************************************************
582 * OLEFontImpl_put_Name (IFont)
584 * See Windows documentation for more details on IFont methods.
586 static HRESULT WINAPI OLEFontImpl_put_Name(
590 _ICOM_THIS(OLEFontImpl, iface);
591 TRACE("(%p)->(%p)\n", this, name);
593 if (this->description.lpstrName==0)
595 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
597 (lstrlenW(name)+1) * sizeof(WCHAR));
601 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
603 this->description.lpstrName,
604 (lstrlenW(name)+1) * sizeof(WCHAR));
607 if (this->description.lpstrName==0)
608 return E_OUTOFMEMORY;
610 strcpyW(this->description.lpstrName, name);
611 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
612 OLEFont_SendNotify(this, DISPID_FONT_NAME);
616 /************************************************************************
617 * OLEFontImpl_get_Size (IFont)
619 * See Windows documentation for more details on IFont methods.
621 static HRESULT WINAPI OLEFontImpl_get_Size(
625 _ICOM_THIS(OLEFontImpl, iface);
626 TRACE("(%p)->(%p)\n", this, psize);
635 psize->s.Lo = this->description.cySize.s.Lo;
640 /************************************************************************
641 * OLEFontImpl_put_Size (IFont)
643 * See Windows documentation for more details on IFont methods.
645 static HRESULT WINAPI OLEFontImpl_put_Size(
649 _ICOM_THIS(OLEFontImpl, iface);
650 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
651 this->description.cySize.s.Hi = 0;
652 this->description.cySize.s.Lo = size.s.Lo;
653 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
658 /************************************************************************
659 * OLEFontImpl_get_Bold (IFont)
661 * See Windows documentation for more details on IFont methods.
663 static HRESULT WINAPI OLEFontImpl_get_Bold(
667 _ICOM_THIS(OLEFontImpl, iface);
668 TRACE("(%p)->(%p)\n", this, pbold);
675 *pbold = this->description.sWeight > 550;
680 /************************************************************************
681 * OLEFontImpl_put_Bold (IFont)
683 * See Windows documentation for more details on IFont methods.
685 static HRESULT WINAPI OLEFontImpl_put_Bold(
689 _ICOM_THIS(OLEFontImpl, iface);
690 TRACE("(%p)->(%d)\n", this, bold);
691 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
692 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
697 /************************************************************************
698 * OLEFontImpl_get_Italic (IFont)
700 * See Windows documentation for more details on IFont methods.
702 static HRESULT WINAPI OLEFontImpl_get_Italic(
706 _ICOM_THIS(OLEFontImpl, iface);
707 TRACE("(%p)->(%p)\n", this, pitalic);
714 *pitalic = this->description.fItalic;
719 /************************************************************************
720 * OLEFontImpl_put_Italic (IFont)
722 * See Windows documentation for more details on IFont methods.
724 static HRESULT WINAPI OLEFontImpl_put_Italic(
728 _ICOM_THIS(OLEFontImpl, iface);
729 TRACE("(%p)->(%d)\n", this, italic);
731 this->description.fItalic = italic;
733 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
737 /************************************************************************
738 * OLEFontImpl_get_Underline (IFont)
740 * See Windows documentation for more details on IFont methods.
742 static HRESULT WINAPI OLEFontImpl_get_Underline(
746 _ICOM_THIS(OLEFontImpl, iface);
747 TRACE("(%p)->(%p)\n", this, punderline);
755 *punderline = this->description.fUnderline;
760 /************************************************************************
761 * OLEFontImpl_put_Underline (IFont)
763 * See Windows documentation for more details on IFont methods.
765 static HRESULT WINAPI OLEFontImpl_put_Underline(
769 _ICOM_THIS(OLEFontImpl, iface);
770 TRACE("(%p)->(%d)\n", this, underline);
772 this->description.fUnderline = underline;
774 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
778 /************************************************************************
779 * OLEFontImpl_get_Strikethrough (IFont)
781 * See Windows documentation for more details on IFont methods.
783 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
785 BOOL* pstrikethrough)
787 _ICOM_THIS(OLEFontImpl, iface);
788 TRACE("(%p)->(%p)\n", this, pstrikethrough);
793 if (pstrikethrough==0)
796 *pstrikethrough = this->description.fStrikethrough;
801 /************************************************************************
802 * OLEFontImpl_put_Strikethrough (IFont)
804 * See Windows documentation for more details on IFont methods.
806 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
810 _ICOM_THIS(OLEFontImpl, iface);
811 TRACE("(%p)->(%d)\n", this, strikethrough);
813 this->description.fStrikethrough = strikethrough;
814 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
819 /************************************************************************
820 * OLEFontImpl_get_Weight (IFont)
822 * See Windows documentation for more details on IFont methods.
824 static HRESULT WINAPI OLEFontImpl_get_Weight(
828 _ICOM_THIS(OLEFontImpl, iface);
829 TRACE("(%p)->(%p)\n", this, pweight);
837 *pweight = this->description.sWeight;
842 /************************************************************************
843 * OLEFontImpl_put_Weight (IFont)
845 * See Windows documentation for more details on IFont methods.
847 static HRESULT WINAPI OLEFontImpl_put_Weight(
851 _ICOM_THIS(OLEFontImpl, iface);
852 TRACE("(%p)->(%d)\n", this, weight);
854 this->description.sWeight = weight;
856 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
860 /************************************************************************
861 * OLEFontImpl_get_Charset (IFont)
863 * See Windows documentation for more details on IFont methods.
865 static HRESULT WINAPI OLEFontImpl_get_Charset(
869 _ICOM_THIS(OLEFontImpl, iface);
870 TRACE("(%p)->(%p)\n", this, pcharset);
878 *pcharset = this->description.sCharset;
883 /************************************************************************
884 * OLEFontImpl_put_Charset (IFont)
886 * See Windows documentation for more details on IFont methods.
888 static HRESULT WINAPI OLEFontImpl_put_Charset(
892 _ICOM_THIS(OLEFontImpl, iface);
893 TRACE("(%p)->(%d)\n", this, charset);
895 this->description.sCharset = charset;
896 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
901 /************************************************************************
902 * OLEFontImpl_get_hFont (IFont)
904 * See Windows documentation for more details on IFont methods.
906 static HRESULT WINAPI OLEFontImpl_get_hFont(
910 _ICOM_THIS(OLEFontImpl, iface);
911 TRACE("(%p)->(%p)\n", this, phfont);
916 * Realize the font if necessary
918 if (this->gdiFont==0)
925 * The height of the font returned by the get_Size property is the
926 * height of the font in points multiplied by 10000... Using some
927 * simple conversions and the ratio given by the application, it can
928 * be converted to a height in pixels.
930 IFont_get_Size(iface, &cySize);
932 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
933 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
935 memset(&logFont, 0, sizeof(LOGFONTW));
937 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
938 (-fontHeight/10000L);
939 logFont.lfItalic = this->description.fItalic;
940 logFont.lfUnderline = this->description.fUnderline;
941 logFont.lfStrikeOut = this->description.fStrikethrough;
942 logFont.lfWeight = this->description.sWeight;
943 logFont.lfCharSet = this->description.sCharset;
944 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
945 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
946 logFont.lfQuality = DEFAULT_QUALITY;
947 logFont.lfPitchAndFamily = DEFAULT_PITCH;
948 strcpyW(logFont.lfFaceName,this->description.lpstrName);
950 this->gdiFont = CreateFontIndirectW(&logFont);
953 *phfont = this->gdiFont;
954 TRACE("Returning %p\n", *phfont);
958 /************************************************************************
959 * OLEFontImpl_Clone (IFont)
961 * See Windows documentation for more details on IFont methods.
963 static HRESULT WINAPI OLEFontImpl_Clone(
967 OLEFontImpl* newObject = 0;
971 _ICOM_THIS(OLEFontImpl, iface);
972 TRACE("(%p)->(%p)\n", this, ppfont);
980 * Allocate space for the object.
982 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
985 return E_OUTOFMEMORY;
989 /* We need to alloc new memory for the string, otherwise
990 * we free memory twice.
992 newObject->description.lpstrName = HeapAlloc(
994 (1+strlenW(this->description.lpstrName))*2
996 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
997 /* We need to clone the HFONT too. This is just cut & paste from above */
998 IFont_get_Size(iface, &cySize);
1000 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
1001 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
1003 memset(&logFont, 0, sizeof(LOGFONTW));
1005 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
1006 (-fontHeight/10000L);
1007 logFont.lfItalic = this->description.fItalic;
1008 logFont.lfUnderline = this->description.fUnderline;
1009 logFont.lfStrikeOut = this->description.fStrikethrough;
1010 logFont.lfWeight = this->description.sWeight;
1011 logFont.lfCharSet = this->description.sCharset;
1012 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
1013 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1014 logFont.lfQuality = DEFAULT_QUALITY;
1015 logFont.lfPitchAndFamily = DEFAULT_PITCH;
1016 strcpyW(logFont.lfFaceName,this->description.lpstrName);
1018 newObject->gdiFont = CreateFontIndirectW(&logFont);
1021 /* The cloned object starts with a reference count of 1 */
1024 *ppfont = (IFont*)newObject;
1029 /************************************************************************
1030 * OLEFontImpl_IsEqual (IFont)
1032 * See Windows documentation for more details on IFont methods.
1034 static HRESULT WINAPI OLEFontImpl_IsEqual(
1042 /************************************************************************
1043 * OLEFontImpl_SetRatio (IFont)
1045 * See Windows documentation for more details on IFont methods.
1047 static HRESULT WINAPI OLEFontImpl_SetRatio(
1052 _ICOM_THIS(OLEFontImpl, iface);
1053 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1055 this->cyLogical = cyLogical;
1056 this->cyHimetric = cyHimetric;
1061 /************************************************************************
1062 * OLEFontImpl_QueryTextMetrics (IFont)
1064 * See Windows documentation for more details on IFont methods.
1066 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1074 /************************************************************************
1075 * OLEFontImpl_AddRefHfont (IFont)
1077 * See Windows documentation for more details on IFont methods.
1079 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1083 _ICOM_THIS(OLEFontImpl, iface);
1084 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1086 if ( (hfont == 0) ||
1087 (hfont != this->gdiFont) )
1088 return E_INVALIDARG;
1095 /************************************************************************
1096 * OLEFontImpl_ReleaseHfont (IFont)
1098 * See Windows documentation for more details on IFont methods.
1100 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1104 _ICOM_THIS(OLEFontImpl, iface);
1105 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1107 if ( (hfont == 0) ||
1108 (hfont != this->gdiFont) )
1109 return E_INVALIDARG;
1114 * If we just released our last font reference, destroy it.
1116 if (this->fontLock==0)
1118 DeleteObject(this->gdiFont);
1125 /************************************************************************
1126 * OLEFontImpl_SetHdc (IFont)
1128 * See Windows documentation for more details on IFont methods.
1130 static HRESULT WINAPI OLEFontImpl_SetHdc(
1134 _ICOM_THIS(OLEFontImpl, iface);
1135 FIXME("(%p)->(%p): Stub\n", this, hdc);
1139 /************************************************************************
1140 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1142 * See Windows documentation for more details on IUnknown methods.
1144 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1149 _ICOM_THIS_From_IDispatch(IFont, iface);
1151 return IFont_QueryInterface(this, riid, ppvoid);
1154 /************************************************************************
1155 * OLEFontImpl_IDispatch_Release (IUnknown)
1157 * See Windows documentation for more details on IUnknown methods.
1159 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1162 _ICOM_THIS_From_IDispatch(IFont, iface);
1164 return IFont_Release(this);
1167 /************************************************************************
1168 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1170 * See Windows documentation for more details on IUnknown methods.
1172 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1175 _ICOM_THIS_From_IDispatch(IFont, iface);
1177 return IFont_AddRef(this);
1180 /************************************************************************
1181 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1183 * See Windows documentation for more details on IDispatch methods.
1185 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1187 unsigned int* pctinfo)
1189 _ICOM_THIS_From_IDispatch(IFont, iface);
1190 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1195 /************************************************************************
1196 * OLEFontImpl_GetTypeInfo (IDispatch)
1198 * See Windows documentation for more details on IDispatch methods.
1200 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1204 ITypeInfo** ppTInfo)
1206 _ICOM_THIS_From_IDispatch(IFont, iface);
1207 FIXME("(%p):Stub\n", this);
1212 /************************************************************************
1213 * OLEFontImpl_GetIDsOfNames (IDispatch)
1215 * See Windows documentation for more details on IDispatch methods.
1217 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1220 LPOLESTR* rgszNames,
1225 _ICOM_THIS_From_IDispatch(IFont, iface);
1226 FIXME("(%p):Stub\n", this);
1231 /************************************************************************
1232 * OLEFontImpl_Invoke (IDispatch)
1234 * See Windows documentation for more details on IDispatch methods.
1236 static HRESULT WINAPI OLEFontImpl_Invoke(
1238 DISPID dispIdMember,
1242 DISPPARAMS* pDispParams,
1243 VARIANT* pVarResult,
1244 EXCEPINFO* pExepInfo,
1247 _ICOM_THIS_From_IDispatch(IFont, iface);
1248 FIXME("%p->(%ld,%s,%lx,%x), stub!\n", this,dispIdMember,debugstr_guid(riid),lcid,
1254 /************************************************************************
1255 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1257 * See Windows documentation for more details on IUnknown methods.
1259 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1260 IPersistStream* iface,
1264 _ICOM_THIS_From_IPersistStream(IFont, iface);
1266 return IFont_QueryInterface(this, riid, ppvoid);
1269 /************************************************************************
1270 * OLEFontImpl_IPersistStream_Release (IUnknown)
1272 * See Windows documentation for more details on IUnknown methods.
1274 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1275 IPersistStream* iface)
1277 _ICOM_THIS_From_IPersistStream(IFont, iface);
1279 return IFont_Release(this);
1282 /************************************************************************
1283 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1285 * See Windows documentation for more details on IUnknown methods.
1287 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1288 IPersistStream* iface)
1290 _ICOM_THIS_From_IPersistStream(IFont, iface);
1292 return IFont_AddRef(this);
1295 /************************************************************************
1296 * OLEFontImpl_GetClassID (IPersistStream)
1298 * See Windows documentation for more details on IPersistStream methods.
1300 static HRESULT WINAPI OLEFontImpl_GetClassID(
1301 IPersistStream* iface,
1307 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1312 /************************************************************************
1313 * OLEFontImpl_IsDirty (IPersistStream)
1315 * See Windows documentation for more details on IPersistStream methods.
1317 static HRESULT WINAPI OLEFontImpl_IsDirty(
1318 IPersistStream* iface)
1323 /************************************************************************
1324 * OLEFontImpl_Load (IPersistStream)
1326 * See Windows documentation for more details on IPersistStream methods.
1328 * This is the format of the standard font serialization as far as I
1331 * Offset Type Value Comment
1332 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1333 * 0x0001 Short Charset Charset value from the FONTDESC structure
1334 * 0x0003 Byte Attributes Flags defined as follows:
1336 * 00000100 - Underline
1337 * 00001000 - Strikethrough
1338 * 0x0004 Short Weight Weight value from FONTDESC structure
1339 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1341 * 0x000A Byte name length Length of the font name string (no null character)
1342 * 0x000B String name Name of the font (ASCII, no nul character)
1344 static HRESULT WINAPI OLEFontImpl_Load(
1345 IPersistStream* iface,
1346 IStream* pLoadStream)
1348 char readBuffer[0x100];
1355 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1358 * Read the version byte
1360 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1369 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1377 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1382 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1383 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1384 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1389 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1397 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1402 this->description.cySize.s.Hi = 0;
1407 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1412 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1414 if (cbRead!=bStringSize)
1417 if (this->description.lpstrName!=0)
1418 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1420 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1421 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1422 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1423 this->description.lpstrName[len] = 0;
1425 /* Ensure use of this font causes a new one to be created @@@@ */
1426 DeleteObject(this->gdiFont);
1432 /************************************************************************
1433 * OLEFontImpl_Save (IPersistStream)
1435 * See Windows documentation for more details on IPersistStream methods.
1437 static HRESULT WINAPI OLEFontImpl_Save(
1438 IPersistStream* iface,
1439 IStream* pOutStream,
1442 char* writeBuffer = NULL;
1444 BYTE bVersion = 0x01;
1448 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1451 * Read the version byte
1453 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1461 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1471 if (this->description.fItalic)
1472 bAttributes |= FONTPERSIST_ITALIC;
1474 if (this->description.fStrikethrough)
1475 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1477 if (this->description.fUnderline)
1478 bAttributes |= FONTPERSIST_UNDERLINE;
1480 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1488 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1496 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1504 if (this->description.lpstrName!=0)
1505 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1506 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1510 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1517 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1518 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1519 strlenW(this->description.lpstrName),
1520 writeBuffer, bStringSize, NULL, NULL );
1522 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1523 HeapFree(GetProcessHeap(), 0, writeBuffer);
1525 if (cbWritten!=bStringSize)
1532 /************************************************************************
1533 * OLEFontImpl_GetSizeMax (IPersistStream)
1535 * See Windows documentation for more details on IPersistStream methods.
1537 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1538 IPersistStream* iface,
1539 ULARGE_INTEGER* pcbSize)
1541 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1546 pcbSize->s.HighPart = 0;
1547 pcbSize->s.LowPart = 0;
1549 pcbSize->s.LowPart += sizeof(BYTE); /* Version */
1550 pcbSize->s.LowPart += sizeof(WORD); /* Lang code */
1551 pcbSize->s.LowPart += sizeof(BYTE); /* Flags */
1552 pcbSize->s.LowPart += sizeof(WORD); /* Weight */
1553 pcbSize->s.LowPart += sizeof(DWORD); /* Size */
1554 pcbSize->s.LowPart += sizeof(BYTE); /* StrLength */
1556 if (this->description.lpstrName!=0)
1557 pcbSize->s.LowPart += lstrlenW(this->description.lpstrName);
1562 /************************************************************************
1563 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1565 * See Windows documentation for more details on IUnknown methods.
1567 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1568 IConnectionPointContainer* iface,
1572 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1574 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1577 /************************************************************************
1578 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1580 * See Windows documentation for more details on IUnknown methods.
1582 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1583 IConnectionPointContainer* iface)
1585 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1587 return IFont_Release((IFont*)this);
1590 /************************************************************************
1591 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1593 * See Windows documentation for more details on IUnknown methods.
1595 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1596 IConnectionPointContainer* iface)
1598 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1600 return IFont_AddRef((IFont*)this);
1603 /************************************************************************
1604 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1606 * See Windows documentation for more details on IConnectionPointContainer
1609 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1610 IConnectionPointContainer* iface,
1611 IEnumConnectionPoints **ppEnum)
1613 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1615 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1619 /************************************************************************
1620 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1622 * See Windows documentation for more details on IConnectionPointContainer
1625 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1626 IConnectionPointContainer* iface,
1628 IConnectionPoint **ppCp)
1630 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1631 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1633 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1634 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1637 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1638 return E_NOINTERFACE;
1642 /*******************************************************************************
1643 * StdFont ClassFactory
1647 /* IUnknown fields */
1648 ICOM_VFIELD(IClassFactory);
1650 } IClassFactoryImpl;
1652 static HRESULT WINAPI
1653 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1654 ICOM_THIS(IClassFactoryImpl,iface);
1656 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1657 return E_NOINTERFACE;
1661 SFCF_AddRef(LPCLASSFACTORY iface) {
1662 ICOM_THIS(IClassFactoryImpl,iface);
1663 return ++(This->ref);
1666 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
1667 ICOM_THIS(IClassFactoryImpl,iface);
1668 /* static class, won't be freed */
1669 return --(This->ref);
1672 static HRESULT WINAPI SFCF_CreateInstance(
1673 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1677 WCHAR fname[] = { 'S','y','s','t','e','m',0 };
1679 fd.cbSizeofstruct = sizeof(fd);
1680 fd.lpstrName = fname;
1681 fd.cySize.s.Lo = 80000;
1687 fd.fStrikethrough = 0;
1688 return OleCreateFontIndirect(&fd,riid,ppobj);
1692 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1693 ICOM_THIS(IClassFactoryImpl,iface);
1694 FIXME("(%p)->(%d),stub!\n",This,dolock);
1698 static ICOM_VTABLE(IClassFactory) SFCF_Vtbl = {
1699 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1700 SFCF_QueryInterface,
1703 SFCF_CreateInstance,
1706 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
1708 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }