- clean-up of texture 'loading'
[wine.git] / ole / olefont.c
blobe3a1743d173d1ee685b3bbce4604345c17fddecd
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
8 */
9 #include <assert.h>
10 #include <string.h>
11 #include "winerror.h"
12 #include "oleauto.h"
13 #include "ocidl.h"
14 #include "olectl.h"
15 #include "debug.h"
16 #include "heap.h"
18 /***********************************************************************
19 * Declaration of constants used when serializing the font object.
21 #define FONTPERSIST_ITALIC 0x02
22 #define FONTPERSIST_UNDERLINE 0x04
23 #define FONTPERSIST_STRIKETHROUGH 0x08
25 /***********************************************************************
26 * Declaration of the implementation class for the IFont interface
28 typedef struct OLEFontImpl OLEFontImpl;
30 struct OLEFontImpl
33 * This class supports many interfaces. IUnknown, IFont,
34 * IDispatch, IDispFont and IPersistStream. The first two are
35 * supported by the first vtablem the next two are supported by
36 * the second table and the last one has it's own.
38 ICOM_VTABLE(IFont)* lpvtbl1;
39 ICOM_VTABLE(IDispatch)* lpvtbl2;
40 ICOM_VTABLE(IPersistStream)* lpvtbl3;
43 * Reference count for that instance of the class.
45 ULONG ref;
48 * This structure contains the description of the class.
50 FONTDESC description;
53 * Contain the font associated with this object.
55 HFONT gdiFont;
58 * Font lock count.
60 DWORD fontLock;
63 * Size ratio
65 long cyLogical;
66 long cyHimetric;
70 * Here, I define utility macros to help with the casting of the
71 * "this" parameter.
72 * There is a version to accomodate all of the VTables implemented
73 * by this object.
75 #define _ICOM_THIS(class,name) class* this = (class*)name;
76 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((void*)name)-sizeof(void*));
77 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((void*)name)-2*sizeof(void*));
79 /***********************************************************************
80 * Prototypes for the implementation functions for the IFont
81 * interface
83 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
84 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
85 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
86 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
87 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
88 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
89 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
90 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
91 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
92 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
93 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
94 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
95 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
96 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
97 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
98 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
99 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
100 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
101 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
102 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
103 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
104 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
105 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
106 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
107 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
108 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
109 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
110 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
111 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
113 /***********************************************************************
114 * Prototypes for the implementation functions for the IDispatch
115 * interface
117 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
118 REFIID riid,
119 VOID** ppvoid);
120 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
121 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
122 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
123 unsigned int* pctinfo);
124 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
125 UINT iTInfo,
126 LCID lcid,
127 ITypeInfo** ppTInfo);
128 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
129 REFIID riid,
130 LPOLESTR* rgszNames,
131 UINT cNames,
132 LCID lcid,
133 DISPID* rgDispId);
134 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
135 DISPID dispIdMember,
136 REFIID riid,
137 LCID lcid,
138 WORD wFlags,
139 DISPPARAMS* pDispParams,
140 VARIANT* pVarResult,
141 EXCEPINFO* pExepInfo,
142 UINT* puArgErr);
144 /***********************************************************************
145 * Prototypes for the implementation functions for the IPersistStream
146 * interface
148 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
149 REFIID riid,
150 VOID** ppvoid);
151 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
152 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
153 static HRESULT WINAPI OLEFontImpl_GetClassID(const IPersistStream* iface,
154 CLSID* pClassID);
155 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
156 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
157 IStream* pLoadStream);
158 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
159 IStream* pOutStream,
160 BOOL fClearDirty);
161 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
162 ULARGE_INTEGER* pcbSize);
165 * Virtual function tables for the OLEFontImpl class.
167 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
169 OLEFontImpl_QueryInterface,
170 OLEFontImpl_AddRef,
171 OLEFontImpl_Release,
172 OLEFontImpl_get_Name,
173 OLEFontImpl_put_Name,
174 OLEFontImpl_get_Size,
175 OLEFontImpl_put_Size,
176 OLEFontImpl_get_Bold,
177 OLEFontImpl_put_Bold,
178 OLEFontImpl_get_Italic,
179 OLEFontImpl_put_Italic,
180 OLEFontImpl_get_Underline,
181 OLEFontImpl_put_Underline,
182 OLEFontImpl_get_Strikethrough,
183 OLEFontImpl_put_Strikethrough,
184 OLEFontImpl_get_Weight,
185 OLEFontImpl_put_Weight,
186 OLEFontImpl_get_Charset,
187 OLEFontImpl_put_Charset,
188 OLEFontImpl_get_hFont,
189 OLEFontImpl_Clone,
190 OLEFontImpl_IsEqual,
191 OLEFontImpl_SetRatio,
192 OLEFontImpl_QueryTextMetrics,
193 OLEFontImpl_AddRefHfont,
194 OLEFontImpl_ReleaseHfont,
195 OLEFontImpl_SetHdc
198 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
200 OLEFontImpl_IDispatch_QueryInterface,
201 OLEFontImpl_IDispatch_AddRef,
202 OLEFontImpl_IDispatch_Release,
203 OLEFontImpl_GetTypeInfoCount,
204 OLEFontImpl_GetTypeInfo,
205 OLEFontImpl_GetIDsOfNames,
206 OLEFontImpl_Invoke
209 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
211 OLEFontImpl_IPersistStream_QueryInterface,
212 OLEFontImpl_IPersistStream_AddRef,
213 OLEFontImpl_IPersistStream_Release,
214 OLEFontImpl_GetClassID,
215 OLEFontImpl_IsDirty,
216 OLEFontImpl_Load,
217 OLEFontImpl_Save,
218 OLEFontImpl_GetSizeMax
221 /******************************************************************************
222 * OleCreateFontIndirect [OLEAUT32.420]
224 WINOLECTLAPI OleCreateFontIndirect(
225 LPFONTDESC lpFontDesc,
226 REFIID riid,
227 VOID** ppvObj)
229 OLEFontImpl* newFont = 0;
230 HRESULT hr = S_OK;
233 * Sanity check
235 if (ppvObj==0)
236 return E_POINTER;
238 *ppvObj = 0;
241 * Try to construct a new instance of the class.
243 newFont = OLEFontImpl_Construct(lpFontDesc);
245 if (newFont == 0)
246 return E_OUTOFMEMORY;
249 * Make sure it supports the interface required by the caller.
251 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
254 * Release the reference obtained in the constructor. If
255 * the QueryInterface was unsuccessful, it will free the class.
257 IFont_Release((IFont*)newFont);
259 return hr;
263 /***********************************************************************
264 * Implementation of the OLEFontImpl class.
267 /************************************************************************
268 * OLEFontImpl_Construct
270 * This method will construct a new instance of the OLEFontImpl
271 * class.
273 * The caller of this method must release the object when it's
274 * done with it.
276 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
278 OLEFontImpl* newObject = 0;
281 * Allocate space for the object.
283 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
285 if (newObject==0)
286 return newObject;
289 * Initialize the virtual function table.
291 newObject->lpvtbl1 = &OLEFontImpl_VTable;
292 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
293 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
296 * Start with one reference count. The caller of this function
297 * must release the interface pointer when it is done.
299 newObject->ref = 1;
302 * Copy the description of the font in the object.
304 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
306 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
307 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
309 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
310 lstrcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
311 newObject->description.cySize = fontDesc->cySize;
312 newObject->description.sWeight = fontDesc->sWeight;
313 newObject->description.sCharset = fontDesc->sCharset;
314 newObject->description.fItalic = fontDesc->fItalic;
315 newObject->description.fUnderline = fontDesc->fUnderline;
316 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
319 * Initializing all the other members.
321 newObject->gdiFont = 0;
322 newObject->fontLock = 0;
323 newObject->cyHimetric = 1;
324 newObject->cyLogical = 1;
326 return newObject;
329 /************************************************************************
330 * OLEFontImpl_Construct
332 * This method is called by the Release method when the reference
333 * count goes doen to 0. it will free all resources used by
334 * this object.
336 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
338 if (fontDesc->description.lpstrName!=0)
339 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
341 if (fontDesc->gdiFont!=0)
342 DeleteObject(fontDesc->gdiFont);
344 HeapFree(GetProcessHeap(), 0, fontDesc);
347 /************************************************************************
348 * OLEFontImpl_QueryInterface (IUnknown)
350 * See Windows documentation for more details on IUnknown methods.
352 HRESULT WINAPI OLEFontImpl_QueryInterface(
353 IFont* iface,
354 REFIID riid,
355 void** ppvObject)
357 _ICOM_THIS(OLEFontImpl, iface);
360 * Perform a sanity check on the parameters.
362 if ( (this==0) || (ppvObject==0) )
363 return E_INVALIDARG;
366 * Initialize the return parameter.
368 *ppvObject = 0;
371 * Compare the riid with the interface IDs implemented by this object.
373 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
375 *ppvObject = (IFont*)this;
377 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
379 *ppvObject = (IFont*)this;
381 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
383 *ppvObject = (IDispatch*)&(this->lpvtbl2);
385 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
387 *ppvObject = (IDispatch*)&(this->lpvtbl2);
389 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
391 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
395 * Check that we obtained an interface.
397 if ((*ppvObject)==0)
399 char clsid[50];
401 WINE_StringFromCLSID((LPCLSID)riid,clsid);
403 WARN(ole,
404 "() : asking for un supported interface %s\n",
405 clsid);
407 return E_NOINTERFACE;
411 * Query Interface always increases the reference count by one when it is
412 * successful
414 OLEFontImpl_AddRef((IFont*)this);
416 return S_OK;;
419 /************************************************************************
420 * OLEFontImpl_AddRef (IUnknown)
422 * See Windows documentation for more details on IUnknown methods.
424 ULONG WINAPI OLEFontImpl_AddRef(
425 IFont* iface)
427 _ICOM_THIS(OLEFontImpl, iface);
429 this->ref++;
431 return this->ref;
434 /************************************************************************
435 * OLEFontImpl_Release (IUnknown)
437 * See Windows documentation for more details on IUnknown methods.
439 ULONG WINAPI OLEFontImpl_Release(
440 IFont* iface)
442 _ICOM_THIS(OLEFontImpl, iface);
445 * Decrease the reference count on this object.
447 this->ref--;
450 * If the reference count goes down to 0, perform suicide.
452 if (this->ref==0)
454 OLEFontImpl_Destroy(this);
456 return 0;
459 return this->ref;
462 /************************************************************************
463 * OLEFontImpl_get_Name (IFont)
465 * See Windows documentation for more details on IFont methods.
467 static HRESULT WINAPI OLEFontImpl_get_Name(
468 IFont* iface,
469 BSTR* pname)
471 _ICOM_THIS(OLEFontImpl, iface);
474 * Sanity check.
476 if (pname==0)
477 return E_POINTER;
479 if (this->description.lpstrName!=0)
480 *pname = SysAllocString(this->description.lpstrName);
481 else
482 *pname = 0;
484 return S_OK;
487 /************************************************************************
488 * OLEFontImpl_put_Name (IFont)
490 * See Windows documentation for more details on IFont methods.
492 static HRESULT WINAPI OLEFontImpl_put_Name(
493 IFont* iface,
494 BSTR name)
496 _ICOM_THIS(OLEFontImpl, iface);
498 if (this->description.lpstrName==0)
500 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
502 (lstrlenW(name)+1) * sizeof(WCHAR));
504 else
506 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
508 this->description.lpstrName,
509 (lstrlenW(name)+1) * sizeof(WCHAR));
512 if (this->description.lpstrName==0)
513 return E_OUTOFMEMORY;
515 lstrcpyW(this->description.lpstrName, name);
517 return S_OK;
520 /************************************************************************
521 * OLEFontImpl_get_Size (IFont)
523 * See Windows documentation for more details on IFont methods.
525 static HRESULT WINAPI OLEFontImpl_get_Size(
526 IFont* iface,
527 CY* psize)
529 _ICOM_THIS(OLEFontImpl, iface);
532 * Sanity check
534 if (psize==0)
535 return E_POINTER;
537 psize->u.Hi = 0;
538 psize->u.Lo = this->description.cySize.u.Lo;
540 return S_OK;
543 /************************************************************************
544 * OLEFontImpl_put_Size (IFont)
546 * See Windows documentation for more details on IFont methods.
548 static HRESULT WINAPI OLEFontImpl_put_Size(
549 IFont* iface,
550 CY size)
552 _ICOM_THIS(OLEFontImpl, iface);
554 this->description.cySize.u.Hi = 0;
555 this->description.cySize.u.Lo = this->description.cySize.u.Lo;
557 return S_OK;
560 /************************************************************************
561 * OLEFontImpl_get_Bold (IFont)
563 * See Windows documentation for more details on IFont methods.
565 static HRESULT WINAPI OLEFontImpl_get_Bold(
566 IFont* iface,
567 BOOL* pbold)
569 FIXME(ole,"():Stub\n");
570 return E_NOTIMPL;
573 /************************************************************************
574 * OLEFontImpl_put_Bold (IFont)
576 * See Windows documentation for more details on IFont methods.
578 static HRESULT WINAPI OLEFontImpl_put_Bold(
579 IFont* iface,
580 BOOL bold)
582 FIXME(ole,"():Stub\n");
583 return E_NOTIMPL;
586 /************************************************************************
587 * OLEFontImpl_get_Italic (IFont)
589 * See Windows documentation for more details on IFont methods.
591 static HRESULT WINAPI OLEFontImpl_get_Italic(
592 IFont* iface,
593 BOOL* pitalic)
595 _ICOM_THIS(OLEFontImpl, iface);
598 * Sanity check
600 if (pitalic==0)
601 return E_POINTER;
603 *pitalic = this->description.fItalic;
605 return S_OK;
608 /************************************************************************
609 * OLEFontImpl_put_Italic (IFont)
611 * See Windows documentation for more details on IFont methods.
613 static HRESULT WINAPI OLEFontImpl_put_Italic(
614 IFont* iface,
615 BOOL italic)
617 _ICOM_THIS(OLEFontImpl, iface);
619 this->description.fItalic = italic;
621 return S_OK;
624 /************************************************************************
625 * OLEFontImpl_get_Underline (IFont)
627 * See Windows documentation for more details on IFont methods.
629 static HRESULT WINAPI OLEFontImpl_get_Underline(
630 IFont* iface,
631 BOOL* punderline)
633 _ICOM_THIS(OLEFontImpl, iface);
636 * Sanity check
638 if (punderline==0)
639 return E_POINTER;
641 *punderline = this->description.fUnderline;
643 return S_OK;
646 /************************************************************************
647 * OLEFontImpl_put_Underline (IFont)
649 * See Windows documentation for more details on IFont methods.
651 static HRESULT WINAPI OLEFontImpl_put_Underline(
652 IFont* iface,
653 BOOL underline)
655 _ICOM_THIS(OLEFontImpl, iface);
657 this->description.fUnderline = underline;
659 return S_OK;
662 /************************************************************************
663 * OLEFontImpl_get_Strikethrough (IFont)
665 * See Windows documentation for more details on IFont methods.
667 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
668 IFont* iface,
669 BOOL* pstrikethrough)
671 _ICOM_THIS(OLEFontImpl, iface);
674 * Sanity check
676 if (pstrikethrough==0)
677 return E_POINTER;
679 *pstrikethrough = this->description.fStrikethrough;
681 return S_OK;
684 /************************************************************************
685 * OLEFontImpl_put_Strikethrough (IFont)
687 * See Windows documentation for more details on IFont methods.
689 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
690 IFont* iface,
691 BOOL strikethrough)
693 _ICOM_THIS(OLEFontImpl, iface);
695 this->description.fStrikethrough = strikethrough;
697 return S_OK;
700 /************************************************************************
701 * OLEFontImpl_get_Weight (IFont)
703 * See Windows documentation for more details on IFont methods.
705 static HRESULT WINAPI OLEFontImpl_get_Weight(
706 IFont* iface,
707 short* pweight)
709 _ICOM_THIS(OLEFontImpl, iface);
712 * Sanity check
714 if (pweight==0)
715 return E_POINTER;
717 *pweight = this->description.sWeight;
719 return S_OK;
722 /************************************************************************
723 * OLEFontImpl_put_Weight (IFont)
725 * See Windows documentation for more details on IFont methods.
727 static HRESULT WINAPI OLEFontImpl_put_Weight(
728 IFont* iface,
729 short weight)
731 _ICOM_THIS(OLEFontImpl, iface);
733 this->description.sWeight = weight;
735 return S_OK;
738 /************************************************************************
739 * OLEFontImpl_get_Charset (IFont)
741 * See Windows documentation for more details on IFont methods.
743 static HRESULT WINAPI OLEFontImpl_get_Charset(
744 IFont* iface,
745 short* pcharset)
747 _ICOM_THIS(OLEFontImpl, iface);
750 * Sanity check
752 if (pcharset==0)
753 return E_POINTER;
755 *pcharset = this->description.sCharset;
757 return S_OK;
760 /************************************************************************
761 * OLEFontImpl_put_Charset (IFont)
763 * See Windows documentation for more details on IFont methods.
765 static HRESULT WINAPI OLEFontImpl_put_Charset(
766 IFont* iface,
767 short charset)
769 _ICOM_THIS(OLEFontImpl, iface);
771 this->description.sCharset = charset;
773 return S_OK;
776 /************************************************************************
777 * OLEFontImpl_get_hFont (IFont)
779 * See Windows documentation for more details on IFont methods.
781 static HRESULT WINAPI OLEFontImpl_get_hFont(
782 IFont* iface,
783 HFONT* phfont)
785 _ICOM_THIS(OLEFontImpl, iface);
787 if (phfont==NULL)
788 return E_POINTER;
791 * Realize the font if necessary
793 if (this->gdiFont==0)
795 LOGFONTW logFont;
796 INT fontHeight;
797 CY cySize;
800 * The height of the font returned by the get_Size property is the
801 * height of the font in points multiplied by 10000... Using some
802 * simple conversions and the ratio given by the application, it can
803 * be converted to a height in pixels.
805 IFont_get_Size(iface, &cySize);
807 fontHeight = MulDiv(cySize.u.Lo, 2540L, 72L);
808 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
810 memset(&logFont, 0, sizeof(LOGFONTW));
812 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
813 (-fontHeight/10000L);
814 logFont.lfItalic = this->description.fItalic;
815 logFont.lfUnderline = this->description.fUnderline;
816 logFont.lfStrikeOut = this->description.fStrikethrough;
817 logFont.lfWeight = this->description.sWeight;
818 logFont.lfCharSet = this->description.sCharset;
819 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
820 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
821 logFont.lfQuality = DEFAULT_QUALITY;
822 logFont.lfPitchAndFamily = DEFAULT_PITCH;
823 lstrcpyW(logFont.lfFaceName,this->description.lpstrName);
825 this->gdiFont = CreateFontIndirectW(&logFont);
828 *phfont = this->gdiFont;
830 return S_OK;
833 /************************************************************************
834 * OLEFontImpl_Clone (IFont)
836 * See Windows documentation for more details on IFont methods.
838 static HRESULT WINAPI OLEFontImpl_Clone(
839 IFont* iface,
840 IFont** ppfont)
842 OLEFontImpl* newObject = 0;
844 _ICOM_THIS(OLEFontImpl, iface);
846 if (ppfont == NULL)
847 return E_POINTER;
849 *ppfont = NULL;
852 * Allocate space for the object.
854 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
856 if (newObject==NULL)
857 return E_OUTOFMEMORY;
859 *newObject = *this;
862 * That new object starts with a reference count of 1
864 newObject->ref = 1;
866 *ppfont = (IFont*)newObject;
868 return S_OK;
871 /************************************************************************
872 * OLEFontImpl_IsEqual (IFont)
874 * See Windows documentation for more details on IFont methods.
876 static HRESULT WINAPI OLEFontImpl_IsEqual(
877 IFont* iface,
878 IFont* pFontOther)
880 FIXME(ole,"():Stub\n");
881 return E_NOTIMPL;
884 /************************************************************************
885 * OLEFontImpl_SetRatio (IFont)
887 * See Windows documentation for more details on IFont methods.
889 static HRESULT WINAPI OLEFontImpl_SetRatio(
890 IFont* iface,
891 long cyLogical,
892 long cyHimetric)
894 _ICOM_THIS(OLEFontImpl, iface);
896 this->cyLogical = cyLogical;
897 this->cyHimetric = cyHimetric;
899 return S_OK;
902 /************************************************************************
903 * OLEFontImpl_QueryTextMetrics (IFont)
905 * See Windows documentation for more details on IFont methods.
907 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
908 IFont* iface,
909 TEXTMETRICOLE* ptm)
911 FIXME(ole,"():Stub\n");
912 return E_NOTIMPL;
915 /************************************************************************
916 * OLEFontImpl_AddRefHfont (IFont)
918 * See Windows documentation for more details on IFont methods.
920 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
921 IFont* iface,
922 HFONT hfont)
924 _ICOM_THIS(OLEFontImpl, iface);
926 if ( (hfont == 0) ||
927 (hfont != this->gdiFont) )
928 return E_INVALIDARG;
930 this->fontLock++;
932 return S_OK;
935 /************************************************************************
936 * OLEFontImpl_ReleaseHfont (IFont)
938 * See Windows documentation for more details on IFont methods.
940 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
941 IFont* iface,
942 HFONT hfont)
944 _ICOM_THIS(OLEFontImpl, iface);
946 if ( (hfont == 0) ||
947 (hfont != this->gdiFont) )
948 return E_INVALIDARG;
950 this->fontLock--;
953 * If we just released our last font reference, destroy it.
955 if (this->fontLock==0)
957 DeleteObject(this->gdiFont);
958 this->gdiFont = 0;
961 return S_OK;
964 /************************************************************************
965 * OLEFontImpl_SetHdc (IFont)
967 * See Windows documentation for more details on IFont methods.
969 static HRESULT WINAPI OLEFontImpl_SetHdc(
970 IFont* iface,
971 HDC hdc)
973 FIXME(ole,"():Stub\n");
974 return E_NOTIMPL;
977 /************************************************************************
978 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
980 * See Windows documentation for more details on IUnknown methods.
982 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
983 IDispatch* iface,
984 REFIID riid,
985 VOID** ppvoid)
987 _ICOM_THIS_From_IDispatch(IFont, iface);
989 return IFont_QueryInterface(this, riid, ppvoid);
992 /************************************************************************
993 * OLEFontImpl_IDispatch_Release (IUnknown)
995 * See Windows documentation for more details on IUnknown methods.
997 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
998 IDispatch* iface)
1000 _ICOM_THIS_From_IDispatch(IFont, iface);
1002 return IFont_Release(this);
1005 /************************************************************************
1006 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1008 * See Windows documentation for more details on IUnknown methods.
1010 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1011 IDispatch* iface)
1013 _ICOM_THIS_From_IDispatch(IFont, iface);
1015 return IFont_AddRef(this);
1018 /************************************************************************
1019 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1021 * See Windows documentation for more details on IDispatch methods.
1023 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1024 IDispatch* iface,
1025 unsigned int* pctinfo)
1027 FIXME(ole,"():Stub\n");
1029 return E_NOTIMPL;
1032 /************************************************************************
1033 * OLEFontImpl_GetTypeInfo (IDispatch)
1035 * See Windows documentation for more details on IDispatch methods.
1037 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1038 IDispatch* iface,
1039 UINT iTInfo,
1040 LCID lcid,
1041 ITypeInfo** ppTInfo)
1043 FIXME(ole,"():Stub\n");
1045 return E_NOTIMPL;
1048 /************************************************************************
1049 * OLEFontImpl_GetIDsOfNames (IDispatch)
1051 * See Windows documentation for more details on IDispatch methods.
1053 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1054 IDispatch* iface,
1055 REFIID riid,
1056 LPOLESTR* rgszNames,
1057 UINT cNames,
1058 LCID lcid,
1059 DISPID* rgDispId)
1061 FIXME(ole,"():Stub\n");
1063 return E_NOTIMPL;
1066 /************************************************************************
1067 * OLEFontImpl_Invoke (IDispatch)
1069 * See Windows documentation for more details on IDispatch methods.
1071 static HRESULT WINAPI OLEFontImpl_Invoke(
1072 IDispatch* iface,
1073 DISPID dispIdMember,
1074 REFIID riid,
1075 LCID lcid,
1076 WORD wFlags,
1077 DISPPARAMS* pDispParams,
1078 VARIANT* pVarResult,
1079 EXCEPINFO* pExepInfo,
1080 UINT* puArgErr)
1082 FIXME(ole,"():Stub\n");
1084 return E_NOTIMPL;
1087 /************************************************************************
1088 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1090 * See Windows documentation for more details on IUnknown methods.
1092 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1093 IPersistStream* iface,
1094 REFIID riid,
1095 VOID** ppvoid)
1097 _ICOM_THIS_From_IPersistStream(IFont, iface);
1099 return IFont_QueryInterface(this, riid, ppvoid);
1102 /************************************************************************
1103 * OLEFontImpl_IPersistStream_Release (IUnknown)
1105 * See Windows documentation for more details on IUnknown methods.
1107 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1108 IPersistStream* iface)
1110 _ICOM_THIS_From_IPersistStream(IFont, iface);
1112 return IFont_Release(this);
1115 /************************************************************************
1116 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1118 * See Windows documentation for more details on IUnknown methods.
1120 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1121 IPersistStream* iface)
1123 _ICOM_THIS_From_IPersistStream(IFont, iface);
1125 return IFont_AddRef(this);
1128 /************************************************************************
1129 * OLEFontImpl_GetClassID (IPersistStream)
1131 * See Windows documentation for more details on IPersistStream methods.
1133 static HRESULT WINAPI OLEFontImpl_GetClassID(
1134 const IPersistStream* iface,
1135 CLSID* pClassID)
1137 if (pClassID==0)
1138 return E_POINTER;
1140 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1142 return S_OK;
1145 /************************************************************************
1146 * OLEFontImpl_IsDirty (IPersistStream)
1148 * See Windows documentation for more details on IPersistStream methods.
1150 static HRESULT WINAPI OLEFontImpl_IsDirty(
1151 IPersistStream* iface)
1153 return S_OK;
1156 /************************************************************************
1157 * OLEFontImpl_Load (IPersistStream)
1159 * See Windows documentation for more details on IPersistStream methods.
1161 * This is the format of the standard font serialization as far as I
1162 * know
1164 * Offset Type Value Comment
1165 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1166 * 0x0001 Short Charset Charset value from the FONTDESC structure
1167 * 0x0003 Byte Attributes Flags defined as follows:
1168 * 00000010 - Italic
1169 * 00000100 - Underline
1170 * 00001000 - Strikethrough
1171 * 0x0004 Short Weight Weight value from FONTDESC structure
1172 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1173 * structure/
1174 * 0x000A Byte name length Length of the font name string (no null character)
1175 * 0x000B String name Name of the font (ASCII, no nul character)
1177 static HRESULT WINAPI OLEFontImpl_Load(
1178 IPersistStream* iface,
1179 IStream* pLoadStream)
1181 char readBuffer[0x100];
1182 ULONG cbRead;
1183 BYTE bVersion;
1184 BYTE bAttributes;
1185 BYTE bStringSize;
1187 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1190 * Read the version byte
1192 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1194 if ( (cbRead!=1) ||
1195 (bVersion!=0x01) )
1196 return E_FAIL;
1199 * Charset
1201 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1203 if (cbRead!=2)
1204 return E_FAIL;
1207 * Attributes
1209 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1211 if (cbRead!=1)
1212 return E_FAIL;
1214 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1215 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1216 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1219 * Weight
1221 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1223 if (cbRead!=2)
1224 return E_FAIL;
1227 * Size
1229 IStream_Read(pLoadStream, &this->description.cySize.u.Lo, 4, &cbRead);
1231 if (cbRead!=4)
1232 return E_FAIL;
1234 this->description.cySize.u.Hi = 0;
1237 * FontName
1239 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1241 if (cbRead!=1)
1242 return E_FAIL;
1244 memset(readBuffer, 0, 0x100);
1245 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1247 if (cbRead!=bStringSize)
1248 return E_FAIL;
1250 if (this->description.lpstrName!=0)
1251 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1253 this->description.lpstrName = HEAP_strdupAtoW(GetProcessHeap(),
1254 HEAP_ZERO_MEMORY,
1255 readBuffer);
1257 return S_OK;
1260 /************************************************************************
1261 * OLEFontImpl_Save (IPersistStream)
1263 * See Windows documentation for more details on IPersistStream methods.
1265 static HRESULT WINAPI OLEFontImpl_Save(
1266 IPersistStream* iface,
1267 IStream* pOutStream,
1268 BOOL fClearDirty)
1270 char* writeBuffer = NULL;
1271 ULONG cbWritten;
1272 BYTE bVersion = 0x01;
1273 BYTE bAttributes;
1274 BYTE bStringSize;
1276 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1279 * Read the version byte
1281 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1283 if (cbWritten!=1)
1284 return E_FAIL;
1287 * Charset
1289 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1291 if (cbWritten!=2)
1292 return E_FAIL;
1295 * Attributes
1297 bAttributes = 0;
1299 if (this->description.fItalic)
1300 bAttributes |= FONTPERSIST_ITALIC;
1302 if (this->description.fStrikethrough)
1303 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1305 if (this->description.fUnderline)
1306 bAttributes |= FONTPERSIST_UNDERLINE;
1308 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1310 if (cbWritten!=1)
1311 return E_FAIL;
1314 * Weight
1316 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1318 if (cbWritten!=2)
1319 return E_FAIL;
1322 * Size
1324 IStream_Write(pOutStream, &this->description.cySize.u.Lo, 4, &cbWritten);
1326 if (cbWritten!=4)
1327 return E_FAIL;
1330 * FontName
1332 if (this->description.lpstrName!=0)
1333 bStringSize = lstrlenW(this->description.lpstrName);
1334 else
1335 bStringSize = 0;
1337 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1339 if (cbWritten!=1)
1340 return E_FAIL;
1342 if (bStringSize!=0)
1344 writeBuffer = HEAP_strdupWtoA(GetProcessHeap(),
1345 HEAP_ZERO_MEMORY,
1346 this->description.lpstrName);
1348 if (writeBuffer==0)
1349 return E_OUTOFMEMORY;
1351 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1353 HeapFree(GetProcessHeap(), 0, writeBuffer);
1355 if (cbWritten!=bStringSize)
1356 return E_FAIL;
1359 return S_OK;
1362 /************************************************************************
1363 * OLEFontImpl_GetSizeMax (IPersistStream)
1365 * See Windows documentation for more details on IPersistStream methods.
1367 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1368 IPersistStream* iface,
1369 ULARGE_INTEGER* pcbSize)
1371 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1373 if (pcbSize==NULL)
1374 return E_POINTER;
1376 pcbSize->HighPart = 0;
1377 pcbSize->LowPart = 0;
1379 pcbSize->LowPart += sizeof(BYTE); /* Version */
1380 pcbSize->LowPart += sizeof(WORD); /* Lang code */
1381 pcbSize->LowPart += sizeof(BYTE); /* Flags */
1382 pcbSize->LowPart += sizeof(WORD); /* Weight */
1383 pcbSize->LowPart += sizeof(DWORD); /* Size */
1384 pcbSize->LowPart += sizeof(BYTE); /* StrLength */
1386 if (this->description.lpstrName!=0)
1387 pcbSize->LowPart += lstrlenW(this->description.lpstrName);
1389 return S_OK;