Implemented localeconv() with libc function.
[wine.git] / dlls / oleaut32 / olefont.c
blob7421b177aa419a803d389fb8e906ffa7ffe9b557
1 /*
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
23 #include <assert.h>
24 #include <string.h>
26 #define NONAMELESSUNION
27 #define NONAMELESSSTRUCT
28 #include "winerror.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "wine/unicode.h"
33 #include "oleauto.h" /* for SysAllocString(....) */
34 #include "objbase.h"
35 #include "ole2.h"
36 #include "olectl.h"
37 #include "wine/debug.h"
38 #include "connpt.h" /* for CreateConnectionPoint */
40 WINE_DEFAULT_DEBUG_CHANNEL(ole);
42 /***********************************************************************
43 * Declaration of constants used when serializing the font object.
45 #define FONTPERSIST_ITALIC 0x02
46 #define FONTPERSIST_UNDERLINE 0x04
47 #define FONTPERSIST_STRIKETHROUGH 0x08
49 /***********************************************************************
50 * Declaration of the implementation class for the IFont interface
52 typedef struct OLEFontImpl OLEFontImpl;
54 struct OLEFontImpl
57 * This class supports many interfaces. IUnknown, IFont,
58 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
59 * The first two are supported by the first vtable, the next two are
60 * supported by the second table and the last two have their own.
62 ICOM_VTABLE(IFont)* lpvtbl1;
63 ICOM_VTABLE(IDispatch)* lpvtbl2;
64 ICOM_VTABLE(IPersistStream)* lpvtbl3;
65 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
66 ICOM_VTABLE(IPersistPropertyBag)* lpvtbl5;
67 ICOM_VTABLE(IPersistStreamInit)* lpvtbl6;
69 * Reference count for that instance of the class.
71 ULONG ref;
74 * This structure contains the description of the class.
76 FONTDESC description;
79 * Contain the font associated with this object.
81 HFONT gdiFont;
84 * Font lock count.
86 DWORD fontLock;
89 * Size ratio
91 long cyLogical;
92 long cyHimetric;
94 IConnectionPoint *pCP;
98 * Here, I define utility macros to help with the casting of the
99 * "this" parameter.
100 * There is a version to accomodate all of the VTables implemented
101 * by this object.
103 #define _ICOM_THIS(class,name) class* this = (class*)name
104 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*))
105 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*))
106 #define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*))
107 #define _ICOM_THIS_From_IPersistPropertyBag(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*))
108 #define _ICOM_THIS_From_IPersistStreamInit(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*))
111 /***********************************************************************
112 * Prototypes for the implementation functions for the IFont
113 * interface
115 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
116 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
117 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
118 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
119 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
120 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
121 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
122 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
123 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
124 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
125 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
126 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
127 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
128 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
129 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
130 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
131 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
132 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
133 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
134 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
135 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
136 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
137 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
138 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
139 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
140 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
141 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
142 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
143 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
145 /***********************************************************************
146 * Prototypes for the implementation functions for the IDispatch
147 * interface
149 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
150 REFIID riid,
151 VOID** ppvoid);
152 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
153 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
154 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
155 unsigned int* pctinfo);
156 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
157 UINT iTInfo,
158 LCID lcid,
159 ITypeInfo** ppTInfo);
160 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
161 REFIID riid,
162 LPOLESTR* rgszNames,
163 UINT cNames,
164 LCID lcid,
165 DISPID* rgDispId);
166 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
167 DISPID dispIdMember,
168 REFIID riid,
169 LCID lcid,
170 WORD wFlags,
171 DISPPARAMS* pDispParams,
172 VARIANT* pVarResult,
173 EXCEPINFO* pExepInfo,
174 UINT* puArgErr);
176 /***********************************************************************
177 * Prototypes for the implementation functions for the IPersistStream
178 * interface
180 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
181 REFIID riid,
182 VOID** ppvoid);
183 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
184 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
185 static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
186 CLSID* pClassID);
187 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
188 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
189 IStream* pLoadStream);
190 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
191 IStream* pOutStream,
192 BOOL fClearDirty);
193 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
194 ULARGE_INTEGER* pcbSize);
196 /***********************************************************************
197 * Prototypes for the implementation functions for the
198 * IConnectionPointContainer interface
200 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
201 IConnectionPointContainer* iface,
202 REFIID riid,
203 VOID** ppvoid);
204 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
205 IConnectionPointContainer* iface);
206 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
207 IConnectionPointContainer* iface);
208 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
209 IConnectionPointContainer* iface,
210 IEnumConnectionPoints **ppEnum);
211 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
212 IConnectionPointContainer* iface,
213 REFIID riid,
214 IConnectionPoint **ppCp);
217 * Virtual function tables for the OLEFontImpl class.
219 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
221 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
222 OLEFontImpl_QueryInterface,
223 OLEFontImpl_AddRef,
224 OLEFontImpl_Release,
225 OLEFontImpl_get_Name,
226 OLEFontImpl_put_Name,
227 OLEFontImpl_get_Size,
228 OLEFontImpl_put_Size,
229 OLEFontImpl_get_Bold,
230 OLEFontImpl_put_Bold,
231 OLEFontImpl_get_Italic,
232 OLEFontImpl_put_Italic,
233 OLEFontImpl_get_Underline,
234 OLEFontImpl_put_Underline,
235 OLEFontImpl_get_Strikethrough,
236 OLEFontImpl_put_Strikethrough,
237 OLEFontImpl_get_Weight,
238 OLEFontImpl_put_Weight,
239 OLEFontImpl_get_Charset,
240 OLEFontImpl_put_Charset,
241 OLEFontImpl_get_hFont,
242 OLEFontImpl_Clone,
243 OLEFontImpl_IsEqual,
244 OLEFontImpl_SetRatio,
245 OLEFontImpl_QueryTextMetrics,
246 OLEFontImpl_AddRefHfont,
247 OLEFontImpl_ReleaseHfont,
248 OLEFontImpl_SetHdc
251 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
253 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
254 OLEFontImpl_IDispatch_QueryInterface,
255 OLEFontImpl_IDispatch_AddRef,
256 OLEFontImpl_IDispatch_Release,
257 OLEFontImpl_GetTypeInfoCount,
258 OLEFontImpl_GetTypeInfo,
259 OLEFontImpl_GetIDsOfNames,
260 OLEFontImpl_Invoke
263 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
265 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
266 OLEFontImpl_IPersistStream_QueryInterface,
267 OLEFontImpl_IPersistStream_AddRef,
268 OLEFontImpl_IPersistStream_Release,
269 OLEFontImpl_GetClassID,
270 OLEFontImpl_IsDirty,
271 OLEFontImpl_Load,
272 OLEFontImpl_Save,
273 OLEFontImpl_GetSizeMax
276 static ICOM_VTABLE(IConnectionPointContainer)
277 OLEFontImpl_IConnectionPointContainer_VTable =
279 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
280 OLEFontImpl_IConnectionPointContainer_QueryInterface,
281 OLEFontImpl_IConnectionPointContainer_AddRef,
282 OLEFontImpl_IConnectionPointContainer_Release,
283 OLEFontImpl_EnumConnectionPoints,
284 OLEFontImpl_FindConnectionPoint
287 static ICOM_VTABLE(IPersistPropertyBag) OLEFontImpl_IPersistPropertyBag_VTable;
288 static ICOM_VTABLE(IPersistStreamInit) OLEFontImpl_IPersistStreamInit_VTable;
289 /******************************************************************************
290 * OleCreateFontIndirect [OLEAUT32.420]
292 HRESULT WINAPI OleCreateFontIndirect(
293 LPFONTDESC lpFontDesc,
294 REFIID riid,
295 LPVOID* ppvObj)
297 OLEFontImpl* newFont = 0;
298 HRESULT hr = S_OK;
300 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
302 * Sanity check
304 if (ppvObj==0)
305 return E_POINTER;
307 *ppvObj = 0;
309 if (lpFontDesc == 0)
310 return NO_ERROR; /* MSDN Oct 2001 */
313 * Try to construct a new instance of the class.
315 newFont = OLEFontImpl_Construct(lpFontDesc);
317 if (newFont == 0)
318 return E_OUTOFMEMORY;
321 * Make sure it supports the interface required by the caller.
323 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
326 * Release the reference obtained in the constructor. If
327 * the QueryInterface was unsuccessful, it will free the class.
329 IFont_Release((IFont*)newFont);
331 return hr;
335 /***********************************************************************
336 * Implementation of the OLEFontImpl class.
339 /***********************************************************************
340 * OLEFont_SendNotify (internal)
342 * Sends notification messages of changed properties to any interested
343 * connections.
345 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
347 IEnumConnections *pEnum;
348 CONNECTDATA CD;
349 HRESULT hres;
351 hres = IConnectionPoint_EnumConnections(this->pCP, &pEnum);
352 if (FAILED(hres)) /* When we have 0 connections. */
353 return;
355 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
356 IPropertyNotifySink *sink;
358 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
359 IPropertyNotifySink_OnChanged(sink, dispID);
360 IPropertyNotifySink_Release(sink);
361 IUnknown_Release(CD.pUnk);
363 IEnumConnections_Release(pEnum);
364 return;
367 /************************************************************************
368 * OLEFontImpl_Construct
370 * This method will construct a new instance of the OLEFontImpl
371 * class.
373 * The caller of this method must release the object when it's
374 * done with it.
376 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
378 OLEFontImpl* newObject = 0;
381 * Allocate space for the object.
383 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
385 if (newObject==0)
386 return newObject;
389 * Initialize the virtual function table.
391 newObject->lpvtbl1 = &OLEFontImpl_VTable;
392 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
393 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
394 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
395 newObject->lpvtbl5 = &OLEFontImpl_IPersistPropertyBag_VTable;
396 newObject->lpvtbl6 = &OLEFontImpl_IPersistStreamInit_VTable;
399 * Start with one reference count. The caller of this function
400 * must release the interface pointer when it is done.
402 newObject->ref = 1;
405 * Copy the description of the font in the object.
407 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
409 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
410 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
412 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
413 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
414 newObject->description.cySize = fontDesc->cySize;
415 newObject->description.sWeight = fontDesc->sWeight;
416 newObject->description.sCharset = fontDesc->sCharset;
417 newObject->description.fItalic = fontDesc->fItalic;
418 newObject->description.fUnderline = fontDesc->fUnderline;
419 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
422 * Initializing all the other members.
424 newObject->gdiFont = 0;
425 newObject->fontLock = 0;
426 newObject->cyLogical = 72L;
427 newObject->cyHimetric = 2540L;
428 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
429 TRACE("returning %p\n", newObject);
430 return newObject;
433 /************************************************************************
434 * OLEFontImpl_Destroy
436 * This method is called by the Release method when the reference
437 * count goes down to 0. It will free all resources used by
438 * this object.
440 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
442 TRACE("(%p)\n", fontDesc);
444 if (fontDesc->description.lpstrName!=0)
445 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
447 if (fontDesc->gdiFont!=0)
448 DeleteObject(fontDesc->gdiFont);
450 HeapFree(GetProcessHeap(), 0, fontDesc);
453 /************************************************************************
454 * OLEFontImpl_QueryInterface (IUnknown)
456 * See Windows documentation for more details on IUnknown methods.
458 HRESULT WINAPI OLEFontImpl_QueryInterface(
459 IFont* iface,
460 REFIID riid,
461 void** ppvObject)
463 _ICOM_THIS(OLEFontImpl, iface);
464 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
467 * Perform a sanity check on the parameters.
469 if ( (this==0) || (ppvObject==0) )
470 return E_INVALIDARG;
473 * Initialize the return parameter.
475 *ppvObject = 0;
478 * Compare the riid with the interface IDs implemented by this object.
480 if (IsEqualGUID(&IID_IUnknown, riid))
481 *ppvObject = (IFont*)this;
482 if (IsEqualGUID(&IID_IFont, riid))
483 *ppvObject = (IFont*)this;
484 if (IsEqualGUID(&IID_IDispatch, riid))
485 *ppvObject = (IDispatch*)&(this->lpvtbl2);
486 if (IsEqualGUID(&IID_IFontDisp, riid))
487 *ppvObject = (IDispatch*)&(this->lpvtbl2);
488 if (IsEqualGUID(&IID_IPersistStream, riid))
489 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
490 if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
491 *ppvObject = (IConnectionPointContainer*)&(this->lpvtbl4);
492 if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
493 *ppvObject = (IPersistPropertyBag*)&(this->lpvtbl5);
494 if (IsEqualGUID(&IID_IPersistStreamInit, riid))
495 *ppvObject = (IPersistStreamInit*)&(this->lpvtbl6);
498 * Check that we obtained an interface.
500 if ((*ppvObject)==0)
502 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
503 return E_NOINTERFACE;
505 OLEFontImpl_AddRef((IFont*)this);
506 return S_OK;
509 /************************************************************************
510 * OLEFontImpl_AddRef (IUnknown)
512 * See Windows documentation for more details on IUnknown methods.
514 ULONG WINAPI OLEFontImpl_AddRef(
515 IFont* iface)
517 _ICOM_THIS(OLEFontImpl, iface);
518 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
519 this->ref++;
521 return this->ref;
524 /************************************************************************
525 * OLEFontImpl_Release (IUnknown)
527 * See Windows documentation for more details on IUnknown methods.
529 ULONG WINAPI OLEFontImpl_Release(
530 IFont* iface)
532 _ICOM_THIS(OLEFontImpl, iface);
533 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
536 * Decrease the reference count on this object.
538 this->ref--;
541 * If the reference count goes down to 0, perform suicide.
543 if (this->ref==0)
545 OLEFontImpl_Destroy(this);
547 return 0;
550 return this->ref;
553 /************************************************************************
554 * OLEFontImpl_get_Name (IFont)
556 * See Windows documentation for more details on IFont methods.
558 static HRESULT WINAPI OLEFontImpl_get_Name(
559 IFont* iface,
560 BSTR* pname)
562 _ICOM_THIS(OLEFontImpl, iface);
563 TRACE("(%p)->(%p)\n", this, pname);
565 * Sanity check.
567 if (pname==0)
568 return E_POINTER;
570 if (this->description.lpstrName!=0)
571 *pname = SysAllocString(this->description.lpstrName);
572 else
573 *pname = 0;
575 return S_OK;
578 /************************************************************************
579 * OLEFontImpl_put_Name (IFont)
581 * See Windows documentation for more details on IFont methods.
583 static HRESULT WINAPI OLEFontImpl_put_Name(
584 IFont* iface,
585 BSTR name)
587 _ICOM_THIS(OLEFontImpl, iface);
588 TRACE("(%p)->(%p)\n", this, name);
590 if (this->description.lpstrName==0)
592 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
594 (lstrlenW(name)+1) * sizeof(WCHAR));
596 else
598 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
600 this->description.lpstrName,
601 (lstrlenW(name)+1) * sizeof(WCHAR));
604 if (this->description.lpstrName==0)
605 return E_OUTOFMEMORY;
607 strcpyW(this->description.lpstrName, name);
608 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
609 OLEFont_SendNotify(this, DISPID_FONT_NAME);
610 return S_OK;
613 /************************************************************************
614 * OLEFontImpl_get_Size (IFont)
616 * See Windows documentation for more details on IFont methods.
618 static HRESULT WINAPI OLEFontImpl_get_Size(
619 IFont* iface,
620 CY* psize)
622 _ICOM_THIS(OLEFontImpl, iface);
623 TRACE("(%p)->(%p)\n", this, psize);
626 * Sanity check
628 if (psize==0)
629 return E_POINTER;
631 psize->s.Hi = 0;
632 psize->s.Lo = this->description.cySize.s.Lo;
634 return S_OK;
637 /************************************************************************
638 * OLEFontImpl_put_Size (IFont)
640 * See Windows documentation for more details on IFont methods.
642 static HRESULT WINAPI OLEFontImpl_put_Size(
643 IFont* iface,
644 CY size)
646 _ICOM_THIS(OLEFontImpl, iface);
647 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
648 this->description.cySize.s.Hi = 0;
649 this->description.cySize.s.Lo = size.s.Lo;
650 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
652 return S_OK;
655 /************************************************************************
656 * OLEFontImpl_get_Bold (IFont)
658 * See Windows documentation for more details on IFont methods.
660 static HRESULT WINAPI OLEFontImpl_get_Bold(
661 IFont* iface,
662 BOOL* pbold)
664 _ICOM_THIS(OLEFontImpl, iface);
665 TRACE("(%p)->(%p)\n", this, pbold);
667 * Sanity check
669 if (pbold==0)
670 return E_POINTER;
672 *pbold = this->description.sWeight > 550;
674 return S_OK;
677 /************************************************************************
678 * OLEFontImpl_put_Bold (IFont)
680 * See Windows documentation for more details on IFont methods.
682 static HRESULT WINAPI OLEFontImpl_put_Bold(
683 IFont* iface,
684 BOOL bold)
686 _ICOM_THIS(OLEFontImpl, iface);
687 TRACE("(%p)->(%d)\n", this, bold);
688 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
689 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
691 return S_OK;
694 /************************************************************************
695 * OLEFontImpl_get_Italic (IFont)
697 * See Windows documentation for more details on IFont methods.
699 static HRESULT WINAPI OLEFontImpl_get_Italic(
700 IFont* iface,
701 BOOL* pitalic)
703 _ICOM_THIS(OLEFontImpl, iface);
704 TRACE("(%p)->(%p)\n", this, pitalic);
706 * Sanity check
708 if (pitalic==0)
709 return E_POINTER;
711 *pitalic = this->description.fItalic;
713 return S_OK;
716 /************************************************************************
717 * OLEFontImpl_put_Italic (IFont)
719 * See Windows documentation for more details on IFont methods.
721 static HRESULT WINAPI OLEFontImpl_put_Italic(
722 IFont* iface,
723 BOOL italic)
725 _ICOM_THIS(OLEFontImpl, iface);
726 TRACE("(%p)->(%d)\n", this, italic);
728 this->description.fItalic = italic;
730 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
731 return S_OK;
734 /************************************************************************
735 * OLEFontImpl_get_Underline (IFont)
737 * See Windows documentation for more details on IFont methods.
739 static HRESULT WINAPI OLEFontImpl_get_Underline(
740 IFont* iface,
741 BOOL* punderline)
743 _ICOM_THIS(OLEFontImpl, iface);
744 TRACE("(%p)->(%p)\n", this, punderline);
747 * Sanity check
749 if (punderline==0)
750 return E_POINTER;
752 *punderline = this->description.fUnderline;
754 return S_OK;
757 /************************************************************************
758 * OLEFontImpl_put_Underline (IFont)
760 * See Windows documentation for more details on IFont methods.
762 static HRESULT WINAPI OLEFontImpl_put_Underline(
763 IFont* iface,
764 BOOL underline)
766 _ICOM_THIS(OLEFontImpl, iface);
767 TRACE("(%p)->(%d)\n", this, underline);
769 this->description.fUnderline = underline;
771 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
772 return S_OK;
775 /************************************************************************
776 * OLEFontImpl_get_Strikethrough (IFont)
778 * See Windows documentation for more details on IFont methods.
780 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
781 IFont* iface,
782 BOOL* pstrikethrough)
784 _ICOM_THIS(OLEFontImpl, iface);
785 TRACE("(%p)->(%p)\n", this, pstrikethrough);
788 * Sanity check
790 if (pstrikethrough==0)
791 return E_POINTER;
793 *pstrikethrough = this->description.fStrikethrough;
795 return S_OK;
798 /************************************************************************
799 * OLEFontImpl_put_Strikethrough (IFont)
801 * See Windows documentation for more details on IFont methods.
803 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
804 IFont* iface,
805 BOOL strikethrough)
807 _ICOM_THIS(OLEFontImpl, iface);
808 TRACE("(%p)->(%d)\n", this, strikethrough);
810 this->description.fStrikethrough = strikethrough;
811 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
813 return S_OK;
816 /************************************************************************
817 * OLEFontImpl_get_Weight (IFont)
819 * See Windows documentation for more details on IFont methods.
821 static HRESULT WINAPI OLEFontImpl_get_Weight(
822 IFont* iface,
823 short* pweight)
825 _ICOM_THIS(OLEFontImpl, iface);
826 TRACE("(%p)->(%p)\n", this, pweight);
829 * Sanity check
831 if (pweight==0)
832 return E_POINTER;
834 *pweight = this->description.sWeight;
836 return S_OK;
839 /************************************************************************
840 * OLEFontImpl_put_Weight (IFont)
842 * See Windows documentation for more details on IFont methods.
844 static HRESULT WINAPI OLEFontImpl_put_Weight(
845 IFont* iface,
846 short weight)
848 _ICOM_THIS(OLEFontImpl, iface);
849 TRACE("(%p)->(%d)\n", this, weight);
851 this->description.sWeight = weight;
853 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
854 return S_OK;
857 /************************************************************************
858 * OLEFontImpl_get_Charset (IFont)
860 * See Windows documentation for more details on IFont methods.
862 static HRESULT WINAPI OLEFontImpl_get_Charset(
863 IFont* iface,
864 short* pcharset)
866 _ICOM_THIS(OLEFontImpl, iface);
867 TRACE("(%p)->(%p)\n", this, pcharset);
870 * Sanity check
872 if (pcharset==0)
873 return E_POINTER;
875 *pcharset = this->description.sCharset;
877 return S_OK;
880 /************************************************************************
881 * OLEFontImpl_put_Charset (IFont)
883 * See Windows documentation for more details on IFont methods.
885 static HRESULT WINAPI OLEFontImpl_put_Charset(
886 IFont* iface,
887 short charset)
889 _ICOM_THIS(OLEFontImpl, iface);
890 TRACE("(%p)->(%d)\n", this, charset);
892 this->description.sCharset = charset;
893 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
895 return S_OK;
898 /************************************************************************
899 * OLEFontImpl_get_hFont (IFont)
901 * See Windows documentation for more details on IFont methods.
903 static HRESULT WINAPI OLEFontImpl_get_hFont(
904 IFont* iface,
905 HFONT* phfont)
907 _ICOM_THIS(OLEFontImpl, iface);
908 TRACE("(%p)->(%p)\n", this, phfont);
909 if (phfont==NULL)
910 return E_POINTER;
913 * Realize the font if necessary
915 if (this->gdiFont==0)
917 LOGFONTW logFont;
918 INT fontHeight;
919 CY cySize;
922 * The height of the font returned by the get_Size property is the
923 * height of the font in points multiplied by 10000... Using some
924 * simple conversions and the ratio given by the application, it can
925 * be converted to a height in pixels.
927 IFont_get_Size(iface, &cySize);
929 fontHeight = MulDiv( cySize.s.Lo, this->cyLogical, this->cyHimetric );
931 memset(&logFont, 0, sizeof(LOGFONTW));
933 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
934 (-fontHeight/10000L);
935 logFont.lfItalic = this->description.fItalic;
936 logFont.lfUnderline = this->description.fUnderline;
937 logFont.lfStrikeOut = this->description.fStrikethrough;
938 logFont.lfWeight = this->description.sWeight;
939 logFont.lfCharSet = this->description.sCharset;
940 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
941 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
942 logFont.lfQuality = DEFAULT_QUALITY;
943 logFont.lfPitchAndFamily = DEFAULT_PITCH;
944 strcpyW(logFont.lfFaceName,this->description.lpstrName);
946 this->gdiFont = CreateFontIndirectW(&logFont);
949 *phfont = this->gdiFont;
950 TRACE("Returning %p\n", *phfont);
951 return S_OK;
954 /************************************************************************
955 * OLEFontImpl_Clone (IFont)
957 * See Windows documentation for more details on IFont methods.
959 static HRESULT WINAPI OLEFontImpl_Clone(
960 IFont* iface,
961 IFont** ppfont)
963 OLEFontImpl* newObject = 0;
964 LOGFONTW logFont;
965 INT fontHeight;
966 CY cySize;
967 _ICOM_THIS(OLEFontImpl, iface);
968 TRACE("(%p)->(%p)\n", this, ppfont);
970 if (ppfont == NULL)
971 return E_POINTER;
973 *ppfont = NULL;
976 * Allocate space for the object.
978 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
980 if (newObject==NULL)
981 return E_OUTOFMEMORY;
983 *newObject = *this;
985 /* We need to alloc new memory for the string, otherwise
986 * we free memory twice.
988 newObject->description.lpstrName = HeapAlloc(
989 GetProcessHeap(),0,
990 (1+strlenW(this->description.lpstrName))*2
992 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
993 /* We need to clone the HFONT too. This is just cut & paste from above */
994 IFont_get_Size(iface, &cySize);
996 fontHeight = MulDiv(cySize.s.Lo, this->cyLogical,this->cyHimetric);
998 memset(&logFont, 0, sizeof(LOGFONTW));
1000 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
1001 (-fontHeight/10000L);
1002 logFont.lfItalic = this->description.fItalic;
1003 logFont.lfUnderline = this->description.fUnderline;
1004 logFont.lfStrikeOut = this->description.fStrikethrough;
1005 logFont.lfWeight = this->description.sWeight;
1006 logFont.lfCharSet = this->description.sCharset;
1007 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
1008 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1009 logFont.lfQuality = DEFAULT_QUALITY;
1010 logFont.lfPitchAndFamily = DEFAULT_PITCH;
1011 strcpyW(logFont.lfFaceName,this->description.lpstrName);
1013 newObject->gdiFont = CreateFontIndirectW(&logFont);
1016 /* The cloned object starts with a reference count of 1 */
1017 newObject->ref = 1;
1019 *ppfont = (IFont*)newObject;
1021 return S_OK;
1024 /************************************************************************
1025 * OLEFontImpl_IsEqual (IFont)
1027 * See Windows documentation for more details on IFont methods.
1029 static HRESULT WINAPI OLEFontImpl_IsEqual(
1030 IFont* iface,
1031 IFont* pFontOther)
1033 FIXME("(%p, %p), stub!\n",iface,pFontOther);
1034 return E_NOTIMPL;
1037 /************************************************************************
1038 * OLEFontImpl_SetRatio (IFont)
1040 * See Windows documentation for more details on IFont methods.
1042 static HRESULT WINAPI OLEFontImpl_SetRatio(
1043 IFont* iface,
1044 long cyLogical,
1045 long cyHimetric)
1047 _ICOM_THIS(OLEFontImpl, iface);
1048 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1050 this->cyLogical = cyLogical;
1051 this->cyHimetric = cyHimetric;
1053 return S_OK;
1056 /************************************************************************
1057 * OLEFontImpl_QueryTextMetrics (IFont)
1059 * See Windows documentation for more details on IFont methods.
1061 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1062 IFont* iface,
1063 TEXTMETRICOLE* ptm)
1065 FIXME("(%p, %p), stub!\n",iface,ptm);
1066 return E_NOTIMPL;
1069 /************************************************************************
1070 * OLEFontImpl_AddRefHfont (IFont)
1072 * See Windows documentation for more details on IFont methods.
1074 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1075 IFont* iface,
1076 HFONT hfont)
1078 _ICOM_THIS(OLEFontImpl, iface);
1079 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1081 if ( (hfont == 0) ||
1082 (hfont != this->gdiFont) )
1083 return E_INVALIDARG;
1085 this->fontLock++;
1087 return S_OK;
1090 /************************************************************************
1091 * OLEFontImpl_ReleaseHfont (IFont)
1093 * See Windows documentation for more details on IFont methods.
1095 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1096 IFont* iface,
1097 HFONT hfont)
1099 _ICOM_THIS(OLEFontImpl, iface);
1100 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1102 if ( (hfont == 0) ||
1103 (hfont != this->gdiFont) )
1104 return E_INVALIDARG;
1106 this->fontLock--;
1109 * If we just released our last font reference, destroy it.
1111 if (this->fontLock==0)
1113 DeleteObject(this->gdiFont);
1114 this->gdiFont = 0;
1117 return S_OK;
1120 /************************************************************************
1121 * OLEFontImpl_SetHdc (IFont)
1123 * See Windows documentation for more details on IFont methods.
1125 static HRESULT WINAPI OLEFontImpl_SetHdc(
1126 IFont* iface,
1127 HDC hdc)
1129 _ICOM_THIS(OLEFontImpl, iface);
1130 FIXME("(%p)->(%p): Stub\n", this, hdc);
1131 return E_NOTIMPL;
1134 /************************************************************************
1135 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1137 * See Windows documentation for more details on IUnknown methods.
1139 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1140 IDispatch* iface,
1141 REFIID riid,
1142 VOID** ppvoid)
1144 _ICOM_THIS_From_IDispatch(IFont, iface);
1146 return IFont_QueryInterface(this, riid, ppvoid);
1149 /************************************************************************
1150 * OLEFontImpl_IDispatch_Release (IUnknown)
1152 * See Windows documentation for more details on IUnknown methods.
1154 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1155 IDispatch* iface)
1157 _ICOM_THIS_From_IDispatch(IFont, iface);
1159 return IFont_Release(this);
1162 /************************************************************************
1163 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1165 * See Windows documentation for more details on IUnknown methods.
1167 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1168 IDispatch* iface)
1170 _ICOM_THIS_From_IDispatch(IFont, iface);
1172 return IFont_AddRef(this);
1175 /************************************************************************
1176 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1178 * See Windows documentation for more details on IDispatch methods.
1180 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1181 IDispatch* iface,
1182 unsigned int* pctinfo)
1184 _ICOM_THIS_From_IDispatch(IFont, iface);
1185 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1187 return E_NOTIMPL;
1190 /************************************************************************
1191 * OLEFontImpl_GetTypeInfo (IDispatch)
1193 * See Windows documentation for more details on IDispatch methods.
1195 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1196 IDispatch* iface,
1197 UINT iTInfo,
1198 LCID lcid,
1199 ITypeInfo** ppTInfo)
1201 WCHAR stdole32tlb[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
1202 ITypeLib *tl;
1203 HRESULT hres;
1205 _ICOM_THIS_From_IDispatch(OLEFontImpl, iface);
1206 TRACE("(%p, iTInfo=%d, lcid=%04x, %p), unimplemented stub!\n", this, iTInfo, (int)lcid, ppTInfo);
1207 if (iTInfo != 0)
1208 return E_FAIL;
1209 hres = LoadTypeLib(stdole32tlb, &tl);
1210 if (FAILED(hres)) {
1211 FIXME("Could not load the stdole32.tlb?\n");
1212 return hres;
1214 hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IDispatch, ppTInfo);
1215 if (FAILED(hres)) {
1216 FIXME("Did not IDispatch typeinfo from typelib, hres %lx\n",hres);
1218 return hres;
1221 /************************************************************************
1222 * OLEFontImpl_GetIDsOfNames (IDispatch)
1224 * See Windows documentation for more details on IDispatch methods.
1226 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1227 IDispatch* iface,
1228 REFIID riid,
1229 LPOLESTR* rgszNames,
1230 UINT cNames,
1231 LCID lcid,
1232 DISPID* rgDispId)
1234 _ICOM_THIS_From_IDispatch(IFont, iface);
1235 FIXME("(%p,%s,%p,%d,%04x,%p), stub!\n", this, debugstr_guid(riid), rgszNames,
1236 cNames, (int)lcid, rgDispId
1238 return E_NOTIMPL;
1241 /************************************************************************
1242 * OLEFontImpl_Invoke (IDispatch)
1244 * See Windows documentation for more details on IDispatch methods.
1246 * Note: Do not call _put_Xxx methods, since setting things here
1247 * should not call notify functions as I found out debugging the generic
1248 * MS VB5 installer.
1250 static HRESULT WINAPI OLEFontImpl_Invoke(
1251 IDispatch* iface,
1252 DISPID dispIdMember,
1253 REFIID riid,
1254 LCID lcid,
1255 WORD wFlags,
1256 DISPPARAMS* pDispParams,
1257 VARIANT* pVarResult,
1258 EXCEPINFO* pExepInfo,
1259 UINT* puArgErr)
1261 _ICOM_THIS_From_IDispatch(IFont, iface);
1262 OLEFontImpl *xthis = (OLEFontImpl*)this;
1264 switch (dispIdMember) {
1265 case DISPID_FONT_NAME:
1266 switch (wFlags) {
1267 case DISPATCH_PROPERTYGET:
1268 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1269 V_VT(pVarResult) = VT_BSTR;
1270 return OLEFontImpl_get_Name(this, &V_BSTR(pVarResult));
1271 case DISPATCH_PROPERTYPUT: {
1272 BSTR name = V_BSTR(&pDispParams->rgvarg[0]);
1273 if (V_VT(&pDispParams->rgvarg[0])!=VT_BSTR) {
1274 FIXME("property put of Name, vt is not VT_BSTR but %d\n",V_VT(&pDispParams->rgvarg[0]));
1275 return E_FAIL;
1277 if (!xthis->description.lpstrName)
1278 xthis->description.lpstrName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name)+1) * sizeof(WCHAR));
1279 else
1280 xthis->description.lpstrName = HeapReAlloc(GetProcessHeap(), 0, xthis->description.lpstrName, (lstrlenW(name)+1) * sizeof(WCHAR));
1282 if (xthis->description.lpstrName==0)
1283 return E_OUTOFMEMORY;
1284 strcpyW(xthis->description.lpstrName, name);
1285 return S_OK;
1288 break;
1289 case DISPID_FONT_BOLD:
1290 switch (wFlags) {
1291 case DISPATCH_PROPERTYGET:
1292 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1293 V_VT(pVarResult) = VT_BOOL;
1294 return OLEFontImpl_get_Bold(this, (BOOL*)&V_BOOL(pVarResult));
1295 case DISPATCH_PROPERTYPUT:
1296 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1297 FIXME("DISPID_FONT_BOLD/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1298 return E_FAIL;
1299 } else {
1300 xthis->description.sWeight = V_BOOL(&pDispParams->rgvarg[0]) ? FW_BOLD : FW_NORMAL;
1301 return S_OK;
1304 break;
1305 case DISPID_FONT_ITALIC:
1306 switch (wFlags) {
1307 case DISPATCH_PROPERTYGET:
1308 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1309 V_VT(pVarResult) = VT_BOOL;
1310 return OLEFontImpl_get_Italic(this, (BOOL*)&V_BOOL(pVarResult));
1311 case DISPATCH_PROPERTYPUT:
1312 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1313 FIXME("DISPID_FONT_ITALIC/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1314 return E_FAIL;
1315 } else {
1316 xthis->description.fItalic = V_BOOL(&pDispParams->rgvarg[0]);
1317 return S_OK;
1320 break;
1321 case DISPID_FONT_UNDER:
1322 switch (wFlags) {
1323 case DISPATCH_PROPERTYGET:
1324 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1325 V_VT(pVarResult) = VT_BOOL;
1326 return OLEFontImpl_get_Underline(this, (BOOL*)&V_BOOL(pVarResult));
1327 case DISPATCH_PROPERTYPUT:
1328 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1329 FIXME("DISPID_FONT_UNDER/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1330 return E_FAIL;
1331 } else {
1332 xthis->description.fUnderline = V_BOOL(&pDispParams->rgvarg[0]);
1333 return S_OK;
1336 break;
1337 case DISPID_FONT_STRIKE:
1338 switch (wFlags) {
1339 case DISPATCH_PROPERTYGET:
1340 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1341 V_VT(pVarResult) = VT_BOOL;
1342 return OLEFontImpl_get_Strikethrough(this, (BOOL*)&V_BOOL(pVarResult));
1343 case DISPATCH_PROPERTYPUT:
1344 if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
1345 FIXME("DISPID_FONT_STRIKE/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
1346 return E_FAIL;
1347 } else {
1348 xthis->description.fStrikethrough = V_BOOL(&pDispParams->rgvarg[0]);
1349 return S_OK;
1352 break;
1353 case DISPID_FONT_SIZE:
1354 switch (wFlags) {
1355 case DISPATCH_PROPERTYPUT: {
1356 assert (pDispParams->cArgs == 1);
1357 xthis->description.cySize.s.Hi = 0;
1358 if (V_VT(&pDispParams->rgvarg[0]) != VT_CY) {
1359 if (V_VT(&pDispParams->rgvarg[0]) == VT_I2) {
1360 xthis->description.cySize.s.Lo = V_I2(&pDispParams->rgvarg[0]) * 10000;
1361 } else {
1362 FIXME("property put for Size with vt %d unsupported!\n",V_VT(&pDispParams->rgvarg[0]));
1364 } else {
1365 xthis->description.cySize.s.Lo = V_CY(&pDispParams->rgvarg[0]).s.Lo;
1367 return S_OK;
1369 case DISPATCH_PROPERTYGET:
1370 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1371 V_VT(pVarResult) = VT_CY;
1372 return OLEFontImpl_get_Size(this, &V_CY(pVarResult));
1374 break;
1375 case DISPID_FONT_CHARSET:
1376 switch (wFlags) {
1377 case DISPATCH_PROPERTYPUT:
1378 assert (pDispParams->cArgs == 1);
1379 if (V_VT(&pDispParams->rgvarg[0]) != VT_I2)
1380 FIXME("varg of first disparg is not VT_I2, but %d\n",V_VT(&pDispParams->rgvarg[0]));
1381 xthis->description.sCharset = V_I2(&pDispParams->rgvarg[0]);
1382 return S_OK;
1383 case DISPATCH_PROPERTYGET:
1384 case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
1385 V_VT(pVarResult) = VT_I2;
1386 return OLEFontImpl_get_Charset(this, &V_I2(pVarResult));
1388 break;
1390 FIXME("%p->(%ld,%s,%lx,%x,%p,%p,%p,%p), unhandled dispid/flag!\n",
1391 this,dispIdMember,debugstr_guid(riid),lcid,
1392 wFlags,pDispParams,pVarResult,pExepInfo,puArgErr
1394 return S_OK;
1397 /************************************************************************
1398 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1400 * See Windows documentation for more details on IUnknown methods.
1402 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1403 IPersistStream* iface,
1404 REFIID riid,
1405 VOID** ppvoid)
1407 _ICOM_THIS_From_IPersistStream(IFont, iface);
1409 return IFont_QueryInterface(this, riid, ppvoid);
1412 /************************************************************************
1413 * OLEFontImpl_IPersistStream_Release (IUnknown)
1415 * See Windows documentation for more details on IUnknown methods.
1417 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1418 IPersistStream* iface)
1420 _ICOM_THIS_From_IPersistStream(IFont, iface);
1422 return IFont_Release(this);
1425 /************************************************************************
1426 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1428 * See Windows documentation for more details on IUnknown methods.
1430 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1431 IPersistStream* iface)
1433 _ICOM_THIS_From_IPersistStream(IFont, iface);
1435 return IFont_AddRef(this);
1438 /************************************************************************
1439 * OLEFontImpl_GetClassID (IPersistStream)
1441 * See Windows documentation for more details on IPersistStream methods.
1443 static HRESULT WINAPI OLEFontImpl_GetClassID(
1444 IPersistStream* iface,
1445 CLSID* pClassID)
1447 TRACE("(%p,%p)\n",iface,pClassID);
1448 if (pClassID==0)
1449 return E_POINTER;
1451 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1453 return S_OK;
1456 /************************************************************************
1457 * OLEFontImpl_IsDirty (IPersistStream)
1459 * See Windows documentation for more details on IPersistStream methods.
1461 static HRESULT WINAPI OLEFontImpl_IsDirty(
1462 IPersistStream* iface)
1464 TRACE("(%p)\n",iface);
1465 return S_OK;
1468 /************************************************************************
1469 * OLEFontImpl_Load (IPersistStream)
1471 * See Windows documentation for more details on IPersistStream methods.
1473 * This is the format of the standard font serialization as far as I
1474 * know
1476 * Offset Type Value Comment
1477 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1478 * 0x0001 Short Charset Charset value from the FONTDESC structure
1479 * 0x0003 Byte Attributes Flags defined as follows:
1480 * 00000010 - Italic
1481 * 00000100 - Underline
1482 * 00001000 - Strikethrough
1483 * 0x0004 Short Weight Weight value from FONTDESC structure
1484 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1485 * structure/
1486 * 0x000A Byte name length Length of the font name string (no null character)
1487 * 0x000B String name Name of the font (ASCII, no nul character)
1489 static HRESULT WINAPI OLEFontImpl_Load(
1490 IPersistStream* iface,
1491 IStream* pLoadStream)
1493 char readBuffer[0x100];
1494 ULONG cbRead;
1495 BYTE bVersion;
1496 BYTE bAttributes;
1497 BYTE bStringSize;
1498 INT len;
1500 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1503 * Read the version byte
1505 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1507 if ( (cbRead!=1) ||
1508 (bVersion!=0x01) )
1509 return E_FAIL;
1512 * Charset
1514 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1516 if (cbRead!=2)
1517 return E_FAIL;
1520 * Attributes
1522 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1524 if (cbRead!=1)
1525 return E_FAIL;
1527 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1528 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1529 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1532 * Weight
1534 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1536 if (cbRead!=2)
1537 return E_FAIL;
1540 * Size
1542 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1544 if (cbRead!=4)
1545 return E_FAIL;
1547 this->description.cySize.s.Hi = 0;
1550 * FontName
1552 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1554 if (cbRead!=1)
1555 return E_FAIL;
1557 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1559 if (cbRead!=bStringSize)
1560 return E_FAIL;
1562 if (this->description.lpstrName!=0)
1563 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1565 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1566 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1567 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1568 this->description.lpstrName[len] = 0;
1570 /* Ensure use of this font causes a new one to be created @@@@ */
1571 DeleteObject(this->gdiFont);
1572 this->gdiFont = 0;
1574 return S_OK;
1577 /************************************************************************
1578 * OLEFontImpl_Save (IPersistStream)
1580 * See Windows documentation for more details on IPersistStream methods.
1582 static HRESULT WINAPI OLEFontImpl_Save(
1583 IPersistStream* iface,
1584 IStream* pOutStream,
1585 BOOL fClearDirty)
1587 char* writeBuffer = NULL;
1588 ULONG cbWritten;
1589 BYTE bVersion = 0x01;
1590 BYTE bAttributes;
1591 BYTE bStringSize;
1593 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1596 * Read the version byte
1598 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1600 if (cbWritten!=1)
1601 return E_FAIL;
1604 * Charset
1606 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1608 if (cbWritten!=2)
1609 return E_FAIL;
1612 * Attributes
1614 bAttributes = 0;
1616 if (this->description.fItalic)
1617 bAttributes |= FONTPERSIST_ITALIC;
1619 if (this->description.fStrikethrough)
1620 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1622 if (this->description.fUnderline)
1623 bAttributes |= FONTPERSIST_UNDERLINE;
1625 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1627 if (cbWritten!=1)
1628 return E_FAIL;
1631 * Weight
1633 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1635 if (cbWritten!=2)
1636 return E_FAIL;
1639 * Size
1641 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1643 if (cbWritten!=4)
1644 return E_FAIL;
1647 * FontName
1649 if (this->description.lpstrName!=0)
1650 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1651 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1652 else
1653 bStringSize = 0;
1655 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1657 if (cbWritten!=1)
1658 return E_FAIL;
1660 if (bStringSize!=0)
1662 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1663 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1664 strlenW(this->description.lpstrName),
1665 writeBuffer, bStringSize, NULL, NULL );
1667 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1668 HeapFree(GetProcessHeap(), 0, writeBuffer);
1670 if (cbWritten!=bStringSize)
1671 return E_FAIL;
1674 return S_OK;
1677 /************************************************************************
1678 * OLEFontImpl_GetSizeMax (IPersistStream)
1680 * See Windows documentation for more details on IPersistStream methods.
1682 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1683 IPersistStream* iface,
1684 ULARGE_INTEGER* pcbSize)
1686 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1688 if (pcbSize==NULL)
1689 return E_POINTER;
1691 pcbSize->s.HighPart = 0;
1692 pcbSize->s.LowPart = 0;
1694 pcbSize->s.LowPart += sizeof(BYTE); /* Version */
1695 pcbSize->s.LowPart += sizeof(WORD); /* Lang code */
1696 pcbSize->s.LowPart += sizeof(BYTE); /* Flags */
1697 pcbSize->s.LowPart += sizeof(WORD); /* Weight */
1698 pcbSize->s.LowPart += sizeof(DWORD); /* Size */
1699 pcbSize->s.LowPart += sizeof(BYTE); /* StrLength */
1701 if (this->description.lpstrName!=0)
1702 pcbSize->s.LowPart += lstrlenW(this->description.lpstrName);
1704 return S_OK;
1707 /************************************************************************
1708 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1710 * See Windows documentation for more details on IUnknown methods.
1712 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1713 IConnectionPointContainer* iface,
1714 REFIID riid,
1715 VOID** ppvoid)
1717 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1719 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1722 /************************************************************************
1723 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1725 * See Windows documentation for more details on IUnknown methods.
1727 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1728 IConnectionPointContainer* iface)
1730 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1732 return IFont_Release((IFont*)this);
1735 /************************************************************************
1736 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1738 * See Windows documentation for more details on IUnknown methods.
1740 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1741 IConnectionPointContainer* iface)
1743 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1745 return IFont_AddRef((IFont*)this);
1748 /************************************************************************
1749 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1751 * See Windows documentation for more details on IConnectionPointContainer
1752 * methods.
1754 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1755 IConnectionPointContainer* iface,
1756 IEnumConnectionPoints **ppEnum)
1758 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1760 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1761 return E_NOTIMPL;
1764 /************************************************************************
1765 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1767 * See Windows documentation for more details on IConnectionPointContainer
1768 * methods.
1770 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1771 IConnectionPointContainer* iface,
1772 REFIID riid,
1773 IConnectionPoint **ppCp)
1775 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1776 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1778 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1779 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1780 (LPVOID)ppCp);
1781 } else {
1782 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1783 return E_NOINTERFACE;
1787 /************************************************************************
1788 * OLEFontImpl implementation of IPersistPropertyBag.
1790 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
1791 IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
1793 _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
1794 return IFont_QueryInterface(this,riid,ppvObj);
1797 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
1798 IPersistPropertyBag *iface
1800 _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
1801 return IFont_AddRef(this);
1804 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
1805 IPersistPropertyBag *iface
1807 _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
1808 return IFont_Release(this);
1811 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
1812 IPersistPropertyBag *iface, CLSID *classid
1814 FIXME("(%p,%p), stub!\n", iface, classid);
1815 return E_FAIL;
1818 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
1819 IPersistPropertyBag *iface
1821 FIXME("(%p), stub!\n", iface);
1822 return S_OK;
1825 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
1826 IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
1828 FIXME("(%p,%p,%p), stub!\n", iface, pPropBag, pErrorLog);
1829 return E_FAIL;
1832 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
1833 IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
1834 BOOL fSaveAllProperties
1836 FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
1837 return E_FAIL;
1840 static ICOM_VTABLE(IPersistPropertyBag) OLEFontImpl_IPersistPropertyBag_VTable =
1842 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1843 OLEFontImpl_IPersistPropertyBag_QueryInterface,
1844 OLEFontImpl_IPersistPropertyBag_AddRef,
1845 OLEFontImpl_IPersistPropertyBag_Release,
1847 OLEFontImpl_IPersistPropertyBag_GetClassID,
1848 OLEFontImpl_IPersistPropertyBag_InitNew,
1849 OLEFontImpl_IPersistPropertyBag_Load,
1850 OLEFontImpl_IPersistPropertyBag_Save
1853 /************************************************************************
1854 * OLEFontImpl implementation of IPersistStreamInit.
1856 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
1857 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
1859 _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
1860 return IFont_QueryInterface(this,riid,ppvObj);
1863 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
1864 IPersistStreamInit *iface
1866 _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
1867 return IFont_AddRef(this);
1870 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
1871 IPersistStreamInit *iface
1873 _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
1874 return IFont_Release(this);
1877 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
1878 IPersistStreamInit *iface, CLSID *classid
1880 FIXME("(%p,%p), stub!\n", iface, classid);
1881 return E_FAIL;
1884 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
1885 IPersistStreamInit *iface
1887 FIXME("(%p), stub!\n", iface);
1888 return E_FAIL;
1891 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
1892 IPersistStreamInit *iface, LPSTREAM pStm
1894 FIXME("(%p,%p), stub!\n", iface, pStm);
1895 return E_FAIL;
1898 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
1899 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
1901 FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
1902 return E_FAIL;
1905 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
1906 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
1908 FIXME("(%p,%p), stub!\n", iface, pcbSize);
1909 return E_FAIL;
1912 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
1913 IPersistStreamInit *iface
1915 FIXME("(%p), stub!\n", iface);
1916 return S_OK;
1919 static ICOM_VTABLE(IPersistStreamInit) OLEFontImpl_IPersistStreamInit_VTable =
1921 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1922 OLEFontImpl_IPersistStreamInit_QueryInterface,
1923 OLEFontImpl_IPersistStreamInit_AddRef,
1924 OLEFontImpl_IPersistStreamInit_Release,
1926 OLEFontImpl_IPersistStreamInit_GetClassID,
1927 OLEFontImpl_IPersistStreamInit_IsDirty,
1928 OLEFontImpl_IPersistStreamInit_Load,
1929 OLEFontImpl_IPersistStreamInit_Save,
1930 OLEFontImpl_IPersistStreamInit_GetSizeMax,
1931 OLEFontImpl_IPersistStreamInit_InitNew
1934 /*******************************************************************************
1935 * StdFont ClassFactory
1937 typedef struct
1939 /* IUnknown fields */
1940 ICOM_VFIELD(IClassFactory);
1941 DWORD ref;
1942 } IClassFactoryImpl;
1944 static HRESULT WINAPI
1945 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1946 ICOM_THIS(IClassFactoryImpl,iface);
1948 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1949 return E_NOINTERFACE;
1952 static ULONG WINAPI
1953 SFCF_AddRef(LPCLASSFACTORY iface) {
1954 ICOM_THIS(IClassFactoryImpl,iface);
1955 return ++(This->ref);
1958 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
1959 ICOM_THIS(IClassFactoryImpl,iface);
1960 /* static class, won't be freed */
1961 return --(This->ref);
1964 static HRESULT WINAPI SFCF_CreateInstance(
1965 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1967 FONTDESC fd;
1969 WCHAR fname[] = { 'S','y','s','t','e','m',0 };
1971 fd.cbSizeofstruct = sizeof(fd);
1972 fd.lpstrName = fname;
1973 fd.cySize.s.Lo = 80000;
1974 fd.cySize.s.Hi = 0;
1975 fd.sWeight = 0;
1976 fd.sCharset = 0;
1977 fd.fItalic = 0;
1978 fd.fUnderline = 0;
1979 fd.fStrikethrough = 0;
1980 return OleCreateFontIndirect(&fd,riid,ppobj);
1984 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1985 ICOM_THIS(IClassFactoryImpl,iface);
1986 FIXME("(%p)->(%d),stub!\n",This,dolock);
1987 return S_OK;
1990 static ICOM_VTABLE(IClassFactory) SFCF_Vtbl = {
1991 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1992 SFCF_QueryInterface,
1993 SFCF_AddRef,
1994 SFCF_Release,
1995 SFCF_CreateInstance,
1996 SFCF_LockServer
1998 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
2000 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }