Added DebugBreak.
[wine.git] / ole / olefont.c
blobd5e16d3fbec6e466c679a7370fd75fd867e7568c
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 DEFAULT_DEBUG_CHANNEL(ole)
20 /***********************************************************************
21 * Declaration of constants used when serializing the font object.
23 #define FONTPERSIST_ITALIC 0x02
24 #define FONTPERSIST_UNDERLINE 0x04
25 #define FONTPERSIST_STRIKETHROUGH 0x08
27 /***********************************************************************
28 * Declaration of the implementation class for the IFont interface
30 typedef struct OLEFontImpl OLEFontImpl;
32 struct OLEFontImpl
35 * This class supports many interfaces. IUnknown, IFont,
36 * IDispatch, IDispFont and IPersistStream. The first two are
37 * supported by the first vtablem the next two are supported by
38 * the second table and the last one has it's own.
40 ICOM_VTABLE(IFont)* lpvtbl1;
41 ICOM_VTABLE(IDispatch)* lpvtbl2;
42 ICOM_VTABLE(IPersistStream)* lpvtbl3;
45 * Reference count for that instance of the class.
47 ULONG ref;
50 * This structure contains the description of the class.
52 FONTDESC description;
55 * Contain the font associated with this object.
57 HFONT gdiFont;
60 * Font lock count.
62 DWORD fontLock;
65 * Size ratio
67 long cyLogical;
68 long cyHimetric;
72 * Here, I define utility macros to help with the casting of the
73 * "this" parameter.
74 * There is a version to accomodate all of the VTables implemented
75 * by this object.
77 #define _ICOM_THIS(class,name) class* this = (class*)name;
78 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
79 #define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
81 /***********************************************************************
82 * Prototypes for the implementation functions for the IFont
83 * interface
85 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
86 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
87 static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
88 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
89 static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
90 static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
91 static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
92 static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
93 static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
94 static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
95 static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
96 static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
97 static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
98 static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
99 static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
100 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
101 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
102 static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
103 static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
104 static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
105 static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
106 static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
107 static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
108 static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
109 static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
110 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
111 static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
112 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
113 static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
115 /***********************************************************************
116 * Prototypes for the implementation functions for the IDispatch
117 * interface
119 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
120 REFIID riid,
121 VOID** ppvoid);
122 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
123 static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
124 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
125 unsigned int* pctinfo);
126 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
127 UINT iTInfo,
128 LCID lcid,
129 ITypeInfo** ppTInfo);
130 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
131 REFIID riid,
132 LPOLESTR* rgszNames,
133 UINT cNames,
134 LCID lcid,
135 DISPID* rgDispId);
136 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
137 DISPID dispIdMember,
138 REFIID riid,
139 LCID lcid,
140 WORD wFlags,
141 DISPPARAMS* pDispParams,
142 VARIANT* pVarResult,
143 EXCEPINFO* pExepInfo,
144 UINT* puArgErr);
146 /***********************************************************************
147 * Prototypes for the implementation functions for the IPersistStream
148 * interface
150 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
151 REFIID riid,
152 VOID** ppvoid);
153 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
154 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
155 static HRESULT WINAPI OLEFontImpl_GetClassID(const IPersistStream* iface,
156 CLSID* pClassID);
157 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
158 static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
159 IStream* pLoadStream);
160 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
161 IStream* pOutStream,
162 BOOL fClearDirty);
163 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
164 ULARGE_INTEGER* pcbSize);
167 * Virtual function tables for the OLEFontImpl class.
169 static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
171 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
172 OLEFontImpl_QueryInterface,
173 OLEFontImpl_AddRef,
174 OLEFontImpl_Release,
175 OLEFontImpl_get_Name,
176 OLEFontImpl_put_Name,
177 OLEFontImpl_get_Size,
178 OLEFontImpl_put_Size,
179 OLEFontImpl_get_Bold,
180 OLEFontImpl_put_Bold,
181 OLEFontImpl_get_Italic,
182 OLEFontImpl_put_Italic,
183 OLEFontImpl_get_Underline,
184 OLEFontImpl_put_Underline,
185 OLEFontImpl_get_Strikethrough,
186 OLEFontImpl_put_Strikethrough,
187 OLEFontImpl_get_Weight,
188 OLEFontImpl_put_Weight,
189 OLEFontImpl_get_Charset,
190 OLEFontImpl_put_Charset,
191 OLEFontImpl_get_hFont,
192 OLEFontImpl_Clone,
193 OLEFontImpl_IsEqual,
194 OLEFontImpl_SetRatio,
195 OLEFontImpl_QueryTextMetrics,
196 OLEFontImpl_AddRefHfont,
197 OLEFontImpl_ReleaseHfont,
198 OLEFontImpl_SetHdc
201 static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
203 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
204 OLEFontImpl_IDispatch_QueryInterface,
205 OLEFontImpl_IDispatch_AddRef,
206 OLEFontImpl_IDispatch_Release,
207 OLEFontImpl_GetTypeInfoCount,
208 OLEFontImpl_GetTypeInfo,
209 OLEFontImpl_GetIDsOfNames,
210 OLEFontImpl_Invoke
213 static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
215 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
216 OLEFontImpl_IPersistStream_QueryInterface,
217 OLEFontImpl_IPersistStream_AddRef,
218 OLEFontImpl_IPersistStream_Release,
219 OLEFontImpl_GetClassID,
220 OLEFontImpl_IsDirty,
221 OLEFontImpl_Load,
222 OLEFontImpl_Save,
223 OLEFontImpl_GetSizeMax
226 /******************************************************************************
227 * OleCreateFontIndirect [OLEAUT32.420]
229 WINOLECTLAPI OleCreateFontIndirect(
230 LPFONTDESC lpFontDesc,
231 REFIID riid,
232 VOID** ppvObj)
234 OLEFontImpl* newFont = 0;
235 HRESULT hr = S_OK;
238 * Sanity check
240 if (ppvObj==0)
241 return E_POINTER;
243 *ppvObj = 0;
246 * Try to construct a new instance of the class.
248 newFont = OLEFontImpl_Construct(lpFontDesc);
250 if (newFont == 0)
251 return E_OUTOFMEMORY;
254 * Make sure it supports the interface required by the caller.
256 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
259 * Release the reference obtained in the constructor. If
260 * the QueryInterface was unsuccessful, it will free the class.
262 IFont_Release((IFont*)newFont);
264 return hr;
268 /***********************************************************************
269 * Implementation of the OLEFontImpl class.
272 /************************************************************************
273 * OLEFontImpl_Construct
275 * This method will construct a new instance of the OLEFontImpl
276 * class.
278 * The caller of this method must release the object when it's
279 * done with it.
281 static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
283 OLEFontImpl* newObject = 0;
286 * Allocate space for the object.
288 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
290 if (newObject==0)
291 return newObject;
294 * Initialize the virtual function table.
296 newObject->lpvtbl1 = &OLEFontImpl_VTable;
297 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
298 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
301 * Start with one reference count. The caller of this function
302 * must release the interface pointer when it is done.
304 newObject->ref = 1;
307 * Copy the description of the font in the object.
309 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
311 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
312 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
314 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
315 lstrcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
316 newObject->description.cySize = fontDesc->cySize;
317 newObject->description.sWeight = fontDesc->sWeight;
318 newObject->description.sCharset = fontDesc->sCharset;
319 newObject->description.fItalic = fontDesc->fItalic;
320 newObject->description.fUnderline = fontDesc->fUnderline;
321 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
324 * Initializing all the other members.
326 newObject->gdiFont = 0;
327 newObject->fontLock = 0;
328 newObject->cyHimetric = 1;
329 newObject->cyLogical = 1;
331 return newObject;
334 /************************************************************************
335 * OLEFontImpl_Construct
337 * This method is called by the Release method when the reference
338 * count goes doen to 0. it will free all resources used by
339 * this object.
341 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
343 if (fontDesc->description.lpstrName!=0)
344 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
346 if (fontDesc->gdiFont!=0)
347 DeleteObject(fontDesc->gdiFont);
349 HeapFree(GetProcessHeap(), 0, fontDesc);
352 /************************************************************************
353 * OLEFontImpl_QueryInterface (IUnknown)
355 * See Windows documentation for more details on IUnknown methods.
357 HRESULT WINAPI OLEFontImpl_QueryInterface(
358 IFont* iface,
359 REFIID riid,
360 void** ppvObject)
362 _ICOM_THIS(OLEFontImpl, iface);
365 * Perform a sanity check on the parameters.
367 if ( (this==0) || (ppvObject==0) )
368 return E_INVALIDARG;
371 * Initialize the return parameter.
373 *ppvObject = 0;
376 * Compare the riid with the interface IDs implemented by this object.
378 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
380 *ppvObject = (IFont*)this;
382 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
384 *ppvObject = (IFont*)this;
386 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
388 *ppvObject = (IDispatch*)&(this->lpvtbl2);
390 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
392 *ppvObject = (IDispatch*)&(this->lpvtbl2);
394 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
396 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
400 * Check that we obtained an interface.
402 if ((*ppvObject)==0)
404 char clsid[50];
406 WINE_StringFromCLSID((LPCLSID)riid,clsid);
408 WARN(ole,
409 "() : asking for un supported interface %s\n",
410 clsid);
412 return E_NOINTERFACE;
416 * Query Interface always increases the reference count by one when it is
417 * successful
419 OLEFontImpl_AddRef((IFont*)this);
421 return S_OK;;
424 /************************************************************************
425 * OLEFontImpl_AddRef (IUnknown)
427 * See Windows documentation for more details on IUnknown methods.
429 ULONG WINAPI OLEFontImpl_AddRef(
430 IFont* iface)
432 _ICOM_THIS(OLEFontImpl, iface);
434 this->ref++;
436 return this->ref;
439 /************************************************************************
440 * OLEFontImpl_Release (IUnknown)
442 * See Windows documentation for more details on IUnknown methods.
444 ULONG WINAPI OLEFontImpl_Release(
445 IFont* iface)
447 _ICOM_THIS(OLEFontImpl, iface);
450 * Decrease the reference count on this object.
452 this->ref--;
455 * If the reference count goes down to 0, perform suicide.
457 if (this->ref==0)
459 OLEFontImpl_Destroy(this);
461 return 0;
464 return this->ref;
467 /************************************************************************
468 * OLEFontImpl_get_Name (IFont)
470 * See Windows documentation for more details on IFont methods.
472 static HRESULT WINAPI OLEFontImpl_get_Name(
473 IFont* iface,
474 BSTR* pname)
476 _ICOM_THIS(OLEFontImpl, iface);
479 * Sanity check.
481 if (pname==0)
482 return E_POINTER;
484 if (this->description.lpstrName!=0)
485 *pname = SysAllocString(this->description.lpstrName);
486 else
487 *pname = 0;
489 return S_OK;
492 /************************************************************************
493 * OLEFontImpl_put_Name (IFont)
495 * See Windows documentation for more details on IFont methods.
497 static HRESULT WINAPI OLEFontImpl_put_Name(
498 IFont* iface,
499 BSTR name)
501 _ICOM_THIS(OLEFontImpl, iface);
503 if (this->description.lpstrName==0)
505 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
507 (lstrlenW(name)+1) * sizeof(WCHAR));
509 else
511 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
513 this->description.lpstrName,
514 (lstrlenW(name)+1) * sizeof(WCHAR));
517 if (this->description.lpstrName==0)
518 return E_OUTOFMEMORY;
520 lstrcpyW(this->description.lpstrName, name);
522 return S_OK;
525 /************************************************************************
526 * OLEFontImpl_get_Size (IFont)
528 * See Windows documentation for more details on IFont methods.
530 static HRESULT WINAPI OLEFontImpl_get_Size(
531 IFont* iface,
532 CY* psize)
534 _ICOM_THIS(OLEFontImpl, iface);
537 * Sanity check
539 if (psize==0)
540 return E_POINTER;
542 psize->u.Hi = 0;
543 psize->u.Lo = this->description.cySize.u.Lo;
545 return S_OK;
548 /************************************************************************
549 * OLEFontImpl_put_Size (IFont)
551 * See Windows documentation for more details on IFont methods.
553 static HRESULT WINAPI OLEFontImpl_put_Size(
554 IFont* iface,
555 CY size)
557 _ICOM_THIS(OLEFontImpl, iface);
559 this->description.cySize.u.Hi = 0;
560 this->description.cySize.u.Lo = this->description.cySize.u.Lo;
562 return S_OK;
565 /************************************************************************
566 * OLEFontImpl_get_Bold (IFont)
568 * See Windows documentation for more details on IFont methods.
570 static HRESULT WINAPI OLEFontImpl_get_Bold(
571 IFont* iface,
572 BOOL* pbold)
574 FIXME(ole,"():Stub\n");
575 return E_NOTIMPL;
578 /************************************************************************
579 * OLEFontImpl_put_Bold (IFont)
581 * See Windows documentation for more details on IFont methods.
583 static HRESULT WINAPI OLEFontImpl_put_Bold(
584 IFont* iface,
585 BOOL bold)
587 FIXME(ole,"():Stub\n");
588 return E_NOTIMPL;
591 /************************************************************************
592 * OLEFontImpl_get_Italic (IFont)
594 * See Windows documentation for more details on IFont methods.
596 static HRESULT WINAPI OLEFontImpl_get_Italic(
597 IFont* iface,
598 BOOL* pitalic)
600 _ICOM_THIS(OLEFontImpl, iface);
603 * Sanity check
605 if (pitalic==0)
606 return E_POINTER;
608 *pitalic = this->description.fItalic;
610 return S_OK;
613 /************************************************************************
614 * OLEFontImpl_put_Italic (IFont)
616 * See Windows documentation for more details on IFont methods.
618 static HRESULT WINAPI OLEFontImpl_put_Italic(
619 IFont* iface,
620 BOOL italic)
622 _ICOM_THIS(OLEFontImpl, iface);
624 this->description.fItalic = italic;
626 return S_OK;
629 /************************************************************************
630 * OLEFontImpl_get_Underline (IFont)
632 * See Windows documentation for more details on IFont methods.
634 static HRESULT WINAPI OLEFontImpl_get_Underline(
635 IFont* iface,
636 BOOL* punderline)
638 _ICOM_THIS(OLEFontImpl, iface);
641 * Sanity check
643 if (punderline==0)
644 return E_POINTER;
646 *punderline = this->description.fUnderline;
648 return S_OK;
651 /************************************************************************
652 * OLEFontImpl_put_Underline (IFont)
654 * See Windows documentation for more details on IFont methods.
656 static HRESULT WINAPI OLEFontImpl_put_Underline(
657 IFont* iface,
658 BOOL underline)
660 _ICOM_THIS(OLEFontImpl, iface);
662 this->description.fUnderline = underline;
664 return S_OK;
667 /************************************************************************
668 * OLEFontImpl_get_Strikethrough (IFont)
670 * See Windows documentation for more details on IFont methods.
672 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
673 IFont* iface,
674 BOOL* pstrikethrough)
676 _ICOM_THIS(OLEFontImpl, iface);
679 * Sanity check
681 if (pstrikethrough==0)
682 return E_POINTER;
684 *pstrikethrough = this->description.fStrikethrough;
686 return S_OK;
689 /************************************************************************
690 * OLEFontImpl_put_Strikethrough (IFont)
692 * See Windows documentation for more details on IFont methods.
694 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
695 IFont* iface,
696 BOOL strikethrough)
698 _ICOM_THIS(OLEFontImpl, iface);
700 this->description.fStrikethrough = strikethrough;
702 return S_OK;
705 /************************************************************************
706 * OLEFontImpl_get_Weight (IFont)
708 * See Windows documentation for more details on IFont methods.
710 static HRESULT WINAPI OLEFontImpl_get_Weight(
711 IFont* iface,
712 short* pweight)
714 _ICOM_THIS(OLEFontImpl, iface);
717 * Sanity check
719 if (pweight==0)
720 return E_POINTER;
722 *pweight = this->description.sWeight;
724 return S_OK;
727 /************************************************************************
728 * OLEFontImpl_put_Weight (IFont)
730 * See Windows documentation for more details on IFont methods.
732 static HRESULT WINAPI OLEFontImpl_put_Weight(
733 IFont* iface,
734 short weight)
736 _ICOM_THIS(OLEFontImpl, iface);
738 this->description.sWeight = weight;
740 return S_OK;
743 /************************************************************************
744 * OLEFontImpl_get_Charset (IFont)
746 * See Windows documentation for more details on IFont methods.
748 static HRESULT WINAPI OLEFontImpl_get_Charset(
749 IFont* iface,
750 short* pcharset)
752 _ICOM_THIS(OLEFontImpl, iface);
755 * Sanity check
757 if (pcharset==0)
758 return E_POINTER;
760 *pcharset = this->description.sCharset;
762 return S_OK;
765 /************************************************************************
766 * OLEFontImpl_put_Charset (IFont)
768 * See Windows documentation for more details on IFont methods.
770 static HRESULT WINAPI OLEFontImpl_put_Charset(
771 IFont* iface,
772 short charset)
774 _ICOM_THIS(OLEFontImpl, iface);
776 this->description.sCharset = charset;
778 return S_OK;
781 /************************************************************************
782 * OLEFontImpl_get_hFont (IFont)
784 * See Windows documentation for more details on IFont methods.
786 static HRESULT WINAPI OLEFontImpl_get_hFont(
787 IFont* iface,
788 HFONT* phfont)
790 _ICOM_THIS(OLEFontImpl, iface);
792 if (phfont==NULL)
793 return E_POINTER;
796 * Realize the font if necessary
798 if (this->gdiFont==0)
800 LOGFONTW logFont;
801 INT fontHeight;
802 CY cySize;
805 * The height of the font returned by the get_Size property is the
806 * height of the font in points multiplied by 10000... Using some
807 * simple conversions and the ratio given by the application, it can
808 * be converted to a height in pixels.
810 IFont_get_Size(iface, &cySize);
812 fontHeight = MulDiv(cySize.u.Lo, 2540L, 72L);
813 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
815 memset(&logFont, 0, sizeof(LOGFONTW));
817 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
818 (-fontHeight/10000L);
819 logFont.lfItalic = this->description.fItalic;
820 logFont.lfUnderline = this->description.fUnderline;
821 logFont.lfStrikeOut = this->description.fStrikethrough;
822 logFont.lfWeight = this->description.sWeight;
823 logFont.lfCharSet = this->description.sCharset;
824 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
825 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
826 logFont.lfQuality = DEFAULT_QUALITY;
827 logFont.lfPitchAndFamily = DEFAULT_PITCH;
828 lstrcpyW(logFont.lfFaceName,this->description.lpstrName);
830 this->gdiFont = CreateFontIndirectW(&logFont);
833 *phfont = this->gdiFont;
835 return S_OK;
838 /************************************************************************
839 * OLEFontImpl_Clone (IFont)
841 * See Windows documentation for more details on IFont methods.
843 static HRESULT WINAPI OLEFontImpl_Clone(
844 IFont* iface,
845 IFont** ppfont)
847 OLEFontImpl* newObject = 0;
849 _ICOM_THIS(OLEFontImpl, iface);
851 if (ppfont == NULL)
852 return E_POINTER;
854 *ppfont = NULL;
857 * Allocate space for the object.
859 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
861 if (newObject==NULL)
862 return E_OUTOFMEMORY;
864 *newObject = *this;
867 * That new object starts with a reference count of 1
869 newObject->ref = 1;
871 *ppfont = (IFont*)newObject;
873 return S_OK;
876 /************************************************************************
877 * OLEFontImpl_IsEqual (IFont)
879 * See Windows documentation for more details on IFont methods.
881 static HRESULT WINAPI OLEFontImpl_IsEqual(
882 IFont* iface,
883 IFont* pFontOther)
885 FIXME(ole,"():Stub\n");
886 return E_NOTIMPL;
889 /************************************************************************
890 * OLEFontImpl_SetRatio (IFont)
892 * See Windows documentation for more details on IFont methods.
894 static HRESULT WINAPI OLEFontImpl_SetRatio(
895 IFont* iface,
896 long cyLogical,
897 long cyHimetric)
899 _ICOM_THIS(OLEFontImpl, iface);
901 this->cyLogical = cyLogical;
902 this->cyHimetric = cyHimetric;
904 return S_OK;
907 /************************************************************************
908 * OLEFontImpl_QueryTextMetrics (IFont)
910 * See Windows documentation for more details on IFont methods.
912 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
913 IFont* iface,
914 TEXTMETRICOLE* ptm)
916 FIXME(ole,"():Stub\n");
917 return E_NOTIMPL;
920 /************************************************************************
921 * OLEFontImpl_AddRefHfont (IFont)
923 * See Windows documentation for more details on IFont methods.
925 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
926 IFont* iface,
927 HFONT hfont)
929 _ICOM_THIS(OLEFontImpl, iface);
931 if ( (hfont == 0) ||
932 (hfont != this->gdiFont) )
933 return E_INVALIDARG;
935 this->fontLock++;
937 return S_OK;
940 /************************************************************************
941 * OLEFontImpl_ReleaseHfont (IFont)
943 * See Windows documentation for more details on IFont methods.
945 static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
946 IFont* iface,
947 HFONT hfont)
949 _ICOM_THIS(OLEFontImpl, iface);
951 if ( (hfont == 0) ||
952 (hfont != this->gdiFont) )
953 return E_INVALIDARG;
955 this->fontLock--;
958 * If we just released our last font reference, destroy it.
960 if (this->fontLock==0)
962 DeleteObject(this->gdiFont);
963 this->gdiFont = 0;
966 return S_OK;
969 /************************************************************************
970 * OLEFontImpl_SetHdc (IFont)
972 * See Windows documentation for more details on IFont methods.
974 static HRESULT WINAPI OLEFontImpl_SetHdc(
975 IFont* iface,
976 HDC hdc)
978 FIXME(ole,"():Stub\n");
979 return E_NOTIMPL;
982 /************************************************************************
983 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
985 * See Windows documentation for more details on IUnknown methods.
987 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
988 IDispatch* iface,
989 REFIID riid,
990 VOID** ppvoid)
992 _ICOM_THIS_From_IDispatch(IFont, iface);
994 return IFont_QueryInterface(this, riid, ppvoid);
997 /************************************************************************
998 * OLEFontImpl_IDispatch_Release (IUnknown)
1000 * See Windows documentation for more details on IUnknown methods.
1002 static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1003 IDispatch* iface)
1005 _ICOM_THIS_From_IDispatch(IFont, iface);
1007 return IFont_Release(this);
1010 /************************************************************************
1011 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1013 * See Windows documentation for more details on IUnknown methods.
1015 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1016 IDispatch* iface)
1018 _ICOM_THIS_From_IDispatch(IFont, iface);
1020 return IFont_AddRef(this);
1023 /************************************************************************
1024 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1026 * See Windows documentation for more details on IDispatch methods.
1028 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1029 IDispatch* iface,
1030 unsigned int* pctinfo)
1032 FIXME(ole,"():Stub\n");
1034 return E_NOTIMPL;
1037 /************************************************************************
1038 * OLEFontImpl_GetTypeInfo (IDispatch)
1040 * See Windows documentation for more details on IDispatch methods.
1042 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1043 IDispatch* iface,
1044 UINT iTInfo,
1045 LCID lcid,
1046 ITypeInfo** ppTInfo)
1048 FIXME(ole,"():Stub\n");
1050 return E_NOTIMPL;
1053 /************************************************************************
1054 * OLEFontImpl_GetIDsOfNames (IDispatch)
1056 * See Windows documentation for more details on IDispatch methods.
1058 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1059 IDispatch* iface,
1060 REFIID riid,
1061 LPOLESTR* rgszNames,
1062 UINT cNames,
1063 LCID lcid,
1064 DISPID* rgDispId)
1066 FIXME(ole,"():Stub\n");
1068 return E_NOTIMPL;
1071 /************************************************************************
1072 * OLEFontImpl_Invoke (IDispatch)
1074 * See Windows documentation for more details on IDispatch methods.
1076 static HRESULT WINAPI OLEFontImpl_Invoke(
1077 IDispatch* iface,
1078 DISPID dispIdMember,
1079 REFIID riid,
1080 LCID lcid,
1081 WORD wFlags,
1082 DISPPARAMS* pDispParams,
1083 VARIANT* pVarResult,
1084 EXCEPINFO* pExepInfo,
1085 UINT* puArgErr)
1087 FIXME(ole,"():Stub\n");
1089 return E_NOTIMPL;
1092 /************************************************************************
1093 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1095 * See Windows documentation for more details on IUnknown methods.
1097 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1098 IPersistStream* iface,
1099 REFIID riid,
1100 VOID** ppvoid)
1102 _ICOM_THIS_From_IPersistStream(IFont, iface);
1104 return IFont_QueryInterface(this, riid, ppvoid);
1107 /************************************************************************
1108 * OLEFontImpl_IPersistStream_Release (IUnknown)
1110 * See Windows documentation for more details on IUnknown methods.
1112 static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1113 IPersistStream* iface)
1115 _ICOM_THIS_From_IPersistStream(IFont, iface);
1117 return IFont_Release(this);
1120 /************************************************************************
1121 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1123 * See Windows documentation for more details on IUnknown methods.
1125 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1126 IPersistStream* iface)
1128 _ICOM_THIS_From_IPersistStream(IFont, iface);
1130 return IFont_AddRef(this);
1133 /************************************************************************
1134 * OLEFontImpl_GetClassID (IPersistStream)
1136 * See Windows documentation for more details on IPersistStream methods.
1138 static HRESULT WINAPI OLEFontImpl_GetClassID(
1139 const IPersistStream* iface,
1140 CLSID* pClassID)
1142 if (pClassID==0)
1143 return E_POINTER;
1145 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1147 return S_OK;
1150 /************************************************************************
1151 * OLEFontImpl_IsDirty (IPersistStream)
1153 * See Windows documentation for more details on IPersistStream methods.
1155 static HRESULT WINAPI OLEFontImpl_IsDirty(
1156 IPersistStream* iface)
1158 return S_OK;
1161 /************************************************************************
1162 * OLEFontImpl_Load (IPersistStream)
1164 * See Windows documentation for more details on IPersistStream methods.
1166 * This is the format of the standard font serialization as far as I
1167 * know
1169 * Offset Type Value Comment
1170 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1171 * 0x0001 Short Charset Charset value from the FONTDESC structure
1172 * 0x0003 Byte Attributes Flags defined as follows:
1173 * 00000010 - Italic
1174 * 00000100 - Underline
1175 * 00001000 - Strikethrough
1176 * 0x0004 Short Weight Weight value from FONTDESC structure
1177 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1178 * structure/
1179 * 0x000A Byte name length Length of the font name string (no null character)
1180 * 0x000B String name Name of the font (ASCII, no nul character)
1182 static HRESULT WINAPI OLEFontImpl_Load(
1183 IPersistStream* iface,
1184 IStream* pLoadStream)
1186 char readBuffer[0x100];
1187 ULONG cbRead;
1188 BYTE bVersion;
1189 BYTE bAttributes;
1190 BYTE bStringSize;
1192 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1195 * Read the version byte
1197 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1199 if ( (cbRead!=1) ||
1200 (bVersion!=0x01) )
1201 return E_FAIL;
1204 * Charset
1206 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1208 if (cbRead!=2)
1209 return E_FAIL;
1212 * Attributes
1214 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1216 if (cbRead!=1)
1217 return E_FAIL;
1219 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1220 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1221 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1224 * Weight
1226 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1228 if (cbRead!=2)
1229 return E_FAIL;
1232 * Size
1234 IStream_Read(pLoadStream, &this->description.cySize.u.Lo, 4, &cbRead);
1236 if (cbRead!=4)
1237 return E_FAIL;
1239 this->description.cySize.u.Hi = 0;
1242 * FontName
1244 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1246 if (cbRead!=1)
1247 return E_FAIL;
1249 memset(readBuffer, 0, 0x100);
1250 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1252 if (cbRead!=bStringSize)
1253 return E_FAIL;
1255 if (this->description.lpstrName!=0)
1256 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1258 this->description.lpstrName = HEAP_strdupAtoW(GetProcessHeap(),
1259 HEAP_ZERO_MEMORY,
1260 readBuffer);
1262 return S_OK;
1265 /************************************************************************
1266 * OLEFontImpl_Save (IPersistStream)
1268 * See Windows documentation for more details on IPersistStream methods.
1270 static HRESULT WINAPI OLEFontImpl_Save(
1271 IPersistStream* iface,
1272 IStream* pOutStream,
1273 BOOL fClearDirty)
1275 char* writeBuffer = NULL;
1276 ULONG cbWritten;
1277 BYTE bVersion = 0x01;
1278 BYTE bAttributes;
1279 BYTE bStringSize;
1281 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1284 * Read the version byte
1286 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1288 if (cbWritten!=1)
1289 return E_FAIL;
1292 * Charset
1294 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1296 if (cbWritten!=2)
1297 return E_FAIL;
1300 * Attributes
1302 bAttributes = 0;
1304 if (this->description.fItalic)
1305 bAttributes |= FONTPERSIST_ITALIC;
1307 if (this->description.fStrikethrough)
1308 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1310 if (this->description.fUnderline)
1311 bAttributes |= FONTPERSIST_UNDERLINE;
1313 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1315 if (cbWritten!=1)
1316 return E_FAIL;
1319 * Weight
1321 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1323 if (cbWritten!=2)
1324 return E_FAIL;
1327 * Size
1329 IStream_Write(pOutStream, &this->description.cySize.u.Lo, 4, &cbWritten);
1331 if (cbWritten!=4)
1332 return E_FAIL;
1335 * FontName
1337 if (this->description.lpstrName!=0)
1338 bStringSize = lstrlenW(this->description.lpstrName);
1339 else
1340 bStringSize = 0;
1342 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1344 if (cbWritten!=1)
1345 return E_FAIL;
1347 if (bStringSize!=0)
1349 writeBuffer = HEAP_strdupWtoA(GetProcessHeap(),
1350 HEAP_ZERO_MEMORY,
1351 this->description.lpstrName);
1353 if (writeBuffer==0)
1354 return E_OUTOFMEMORY;
1356 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1358 HeapFree(GetProcessHeap(), 0, writeBuffer);
1360 if (cbWritten!=bStringSize)
1361 return E_FAIL;
1364 return S_OK;
1367 /************************************************************************
1368 * OLEFontImpl_GetSizeMax (IPersistStream)
1370 * See Windows documentation for more details on IPersistStream methods.
1372 static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1373 IPersistStream* iface,
1374 ULARGE_INTEGER* pcbSize)
1376 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1378 if (pcbSize==NULL)
1379 return E_POINTER;
1381 pcbSize->HighPart = 0;
1382 pcbSize->LowPart = 0;
1384 pcbSize->LowPart += sizeof(BYTE); /* Version */
1385 pcbSize->LowPart += sizeof(WORD); /* Lang code */
1386 pcbSize->LowPart += sizeof(BYTE); /* Flags */
1387 pcbSize->LowPart += sizeof(WORD); /* Weight */
1388 pcbSize->LowPart += sizeof(DWORD); /* Size */
1389 pcbSize->LowPart += sizeof(BYTE); /* StrLength */
1391 if (this->description.lpstrName!=0)
1392 pcbSize->LowPart += lstrlenW(this->description.lpstrName);
1394 return S_OK;