source: trunk/src/oleaut32/olefont.c@ 10367

Last change on this file since 10367 was 9400, checked in by sandervl, 23 years ago

Wine resync

File size: 46.7 KB
Line 
1/*
2 * OLE Font encapsulation implementation
3 *
4 * This file contains an implementation of the IFont
5 * interface and the OleCreateFontIndirect API call.
6 *
7 * Copyright 1999 Francis Beaudet
8 *
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.
13 *
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.
18 *
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
22 */
23#ifdef __WIN32OS2__
24#define WINE_LARGE_INTEGER
25#include "oleaut32.h"
26#endif
27#include <assert.h>
28#include <string.h>
29#include "winerror.h"
30#include "winbase.h"
31#include "wingdi.h"
32#include "winuser.h"
33#include "wine/unicode.h"
34#include "oleauto.h" /* for SysAllocString(....) */
35#include "wine/obj_base.h"
36#include "wine/obj_olefont.h"
37#include "wine/obj_storage.h"
38#include "ole2.h"
39#include "olectl.h"
40#include "wine/debug.h"
41#include "connpt.h" /* for CreateConnectionPoint */
42
43WINE_DEFAULT_DEBUG_CHANNEL(ole);
44
45/***********************************************************************
46 * Declaration of constants used when serializing the font object.
47 */
48#define FONTPERSIST_ITALIC 0x02
49#define FONTPERSIST_UNDERLINE 0x04
50#define FONTPERSIST_STRIKETHROUGH 0x08
51
52/***********************************************************************
53 * Declaration of the implementation class for the IFont interface
54 */
55typedef struct OLEFontImpl OLEFontImpl;
56
57struct OLEFontImpl
58{
59 /*
60 * This class supports many interfaces. IUnknown, IFont,
61 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
62 * The first two are supported by the first vtable, the next two are
63 * supported by the second table and the last two have their own.
64 */
65 ICOM_VTABLE(IFont)* lpvtbl1;
66 ICOM_VTABLE(IDispatch)* lpvtbl2;
67 ICOM_VTABLE(IPersistStream)* lpvtbl3;
68 ICOM_VTABLE(IConnectionPointContainer)* lpvtbl4;
69 /*
70 * Reference count for that instance of the class.
71 */
72 ULONG ref;
73
74 /*
75 * This structure contains the description of the class.
76 */
77 FONTDESC description;
78
79 /*
80 * Contain the font associated with this object.
81 */
82 HFONT gdiFont;
83
84 /*
85 * Font lock count.
86 */
87 DWORD fontLock;
88
89 /*
90 * Size ratio
91 */
92 long cyLogical;
93 long cyHimetric;
94
95 IConnectionPoint *pCP;
96};
97
98/*
99 * Here, I define utility macros to help with the casting of the
100 * "this" parameter.
101 * There is a version to accomodate all of the VTables implemented
102 * by this object.
103 */
104#define _ICOM_THIS(class,name) class* this = (class*)name;
105#define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
106#define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
107#define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
108
109
110/***********************************************************************
111 * Prototypes for the implementation functions for the IFont
112 * interface
113 */
114static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
115static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
116static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
117static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
118static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
119static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
120static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
121static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
122static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
123static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
124static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
125static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
126static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
127static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
128static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
129static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
130static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
131static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
132static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
133static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
134static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
135static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
136static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
137static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
138static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
139static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
140static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
141static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
142static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
143
144/***********************************************************************
145 * Prototypes for the implementation functions for the IDispatch
146 * interface
147 */
148static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
149 REFIID riid,
150 VOID** ppvoid);
151static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
152static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
153static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
154 unsigned int* pctinfo);
155static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
156 UINT iTInfo,
157 LCID lcid,
158 ITypeInfo** ppTInfo);
159static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
160 REFIID riid,
161 LPOLESTR* rgszNames,
162 UINT cNames,
163 LCID lcid,
164 DISPID* rgDispId);
165static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
166 DISPID dispIdMember,
167 REFIID riid,
168 LCID lcid,
169 WORD wFlags,
170 DISPPARAMS* pDispParams,
171 VARIANT* pVarResult,
172 EXCEPINFO* pExepInfo,
173 UINT* puArgErr);
174
175/***********************************************************************
176 * Prototypes for the implementation functions for the IPersistStream
177 * interface
178 */
179static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
180 REFIID riid,
181 VOID** ppvoid);
182static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
183static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
184static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
185 CLSID* pClassID);
186static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
187static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
188 IStream* pLoadStream);
189static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
190 IStream* pOutStream,
191 BOOL fClearDirty);
192static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
193 ULARGE_INTEGER* pcbSize);
194
195/***********************************************************************
196 * Prototypes for the implementation functions for the
197 * IConnectionPointContainer interface
198 */
199static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
200 IConnectionPointContainer* iface,
201 REFIID riid,
202 VOID** ppvoid);
203static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
204 IConnectionPointContainer* iface);
205static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
206 IConnectionPointContainer* iface);
207static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
208 IConnectionPointContainer* iface,
209 IEnumConnectionPoints **ppEnum);
210static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
211 IConnectionPointContainer* iface,
212 REFIID riid,
213 IConnectionPoint **ppCp);
214
215/*
216 * Virtual function tables for the OLEFontImpl class.
217 */
218static ICOM_VTABLE(IFont) OLEFontImpl_VTable =
219{
220 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
221 OLEFontImpl_QueryInterface,
222 OLEFontImpl_AddRef,
223 OLEFontImpl_Release,
224 OLEFontImpl_get_Name,
225 OLEFontImpl_put_Name,
226 OLEFontImpl_get_Size,
227 OLEFontImpl_put_Size,
228 OLEFontImpl_get_Bold,
229 OLEFontImpl_put_Bold,
230 OLEFontImpl_get_Italic,
231 OLEFontImpl_put_Italic,
232 OLEFontImpl_get_Underline,
233 OLEFontImpl_put_Underline,
234 OLEFontImpl_get_Strikethrough,
235 OLEFontImpl_put_Strikethrough,
236 OLEFontImpl_get_Weight,
237 OLEFontImpl_put_Weight,
238 OLEFontImpl_get_Charset,
239 OLEFontImpl_put_Charset,
240 OLEFontImpl_get_hFont,
241 OLEFontImpl_Clone,
242 OLEFontImpl_IsEqual,
243 OLEFontImpl_SetRatio,
244 OLEFontImpl_QueryTextMetrics,
245 OLEFontImpl_AddRefHfont,
246 OLEFontImpl_ReleaseHfont,
247 OLEFontImpl_SetHdc
248};
249
250static ICOM_VTABLE(IDispatch) OLEFontImpl_IDispatch_VTable =
251{
252 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
253 OLEFontImpl_IDispatch_QueryInterface,
254 OLEFontImpl_IDispatch_AddRef,
255 OLEFontImpl_IDispatch_Release,
256 OLEFontImpl_GetTypeInfoCount,
257 OLEFontImpl_GetTypeInfo,
258 OLEFontImpl_GetIDsOfNames,
259 OLEFontImpl_Invoke
260};
261
262static ICOM_VTABLE(IPersistStream) OLEFontImpl_IPersistStream_VTable =
263{
264 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
265 OLEFontImpl_IPersistStream_QueryInterface,
266 OLEFontImpl_IPersistStream_AddRef,
267 OLEFontImpl_IPersistStream_Release,
268 OLEFontImpl_GetClassID,
269 OLEFontImpl_IsDirty,
270 OLEFontImpl_Load,
271 OLEFontImpl_Save,
272 OLEFontImpl_GetSizeMax
273};
274
275static ICOM_VTABLE(IConnectionPointContainer)
276 OLEFontImpl_IConnectionPointContainer_VTable =
277{
278 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
279 OLEFontImpl_IConnectionPointContainer_QueryInterface,
280 OLEFontImpl_IConnectionPointContainer_AddRef,
281 OLEFontImpl_IConnectionPointContainer_Release,
282 OLEFontImpl_EnumConnectionPoints,
283 OLEFontImpl_FindConnectionPoint
284};
285
286/******************************************************************************
287 * OleCreateFontIndirect [OLEAUT32.420]
288 */
289HRESULT WINAPI OleCreateFontIndirect(
290 LPFONTDESC lpFontDesc,
291 REFIID riid,
292 LPVOID* ppvObj)
293{
294 OLEFontImpl* newFont = 0;
295 HRESULT hr = S_OK;
296
297 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
298 /*
299 * Sanity check
300 */
301 if (ppvObj==0)
302 return E_POINTER;
303
304 *ppvObj = 0;
305
306 if (lpFontDesc == 0)
307 return NO_ERROR; /* MSDN Oct 2001 */
308
309 /*
310 * Try to construct a new instance of the class.
311 */
312 newFont = OLEFontImpl_Construct(lpFontDesc);
313
314 if (newFont == 0)
315 return E_OUTOFMEMORY;
316
317 /*
318 * Make sure it supports the interface required by the caller.
319 */
320 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
321
322 /*
323 * Release the reference obtained in the constructor. If
324 * the QueryInterface was unsuccessful, it will free the class.
325 */
326 IFont_Release((IFont*)newFont);
327
328 return hr;
329}
330
331
332/***********************************************************************
333 * Implementation of the OLEFontImpl class.
334 */
335
336/***********************************************************************
337 * OLEFont_SendNotify (internal)
338 *
339 * Sends notification messages of changed properties to any interested
340 * connections.
341 */
342static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
343{
344 IEnumConnections *pEnum;
345 CONNECTDATA CD;
346
347 IConnectionPoint_EnumConnections(this->pCP, &pEnum);
348
349 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
350 IPropertyNotifySink *sink;
351
352 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
353 IPropertyNotifySink_OnChanged(sink, dispID);
354 IPropertyNotifySink_Release(sink);
355 IUnknown_Release(CD.pUnk);
356 }
357 IEnumConnections_Release(pEnum);
358 return;
359}
360
361/************************************************************************
362 * OLEFontImpl_Construct
363 *
364 * This method will construct a new instance of the OLEFontImpl
365 * class.
366 *
367 * The caller of this method must release the object when it's
368 * done with it.
369 */
370static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
371{
372 OLEFontImpl* newObject = 0;
373
374 /*
375 * Allocate space for the object.
376 */
377 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
378
379 if (newObject==0)
380 return newObject;
381
382 /*
383 * Initialize the virtual function table.
384 */
385 newObject->lpvtbl1 = &OLEFontImpl_VTable;
386 newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
387 newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
388 newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
389
390 /*
391 * Start with one reference count. The caller of this function
392 * must release the interface pointer when it is done.
393 */
394 newObject->ref = 1;
395
396 /*
397 * Copy the description of the font in the object.
398 */
399 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
400
401 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
402 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
403 0,
404 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
405 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
406 newObject->description.cySize = fontDesc->cySize;
407 newObject->description.sWeight = fontDesc->sWeight;
408 newObject->description.sCharset = fontDesc->sCharset;
409 newObject->description.fItalic = fontDesc->fItalic;
410 newObject->description.fUnderline = fontDesc->fUnderline;
411 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
412
413 /*
414 * Initializing all the other members.
415 */
416 newObject->gdiFont = 0;
417 newObject->fontLock = 0;
418 newObject->cyHimetric = 1;
419 newObject->cyLogical = 1;
420
421 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
422
423 TRACE("returning %p\n", newObject);
424 return newObject;
425}
426
427/************************************************************************
428 * OLEFontImpl_Destroy
429 *
430 * This method is called by the Release method when the reference
431 * count goes down to 0. It will free all resources used by
432 * this object.
433 */
434static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
435{
436 TRACE("(%p)\n", fontDesc);
437
438 if (fontDesc->description.lpstrName!=0)
439 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
440
441 if (fontDesc->gdiFont!=0)
442 DeleteObject(fontDesc->gdiFont);
443
444 HeapFree(GetProcessHeap(), 0, fontDesc);
445}
446
447/************************************************************************
448 * OLEFontImpl_QueryInterface (IUnknown)
449 *
450 * See Windows documentation for more details on IUnknown methods.
451 */
452HRESULT WINAPI OLEFontImpl_QueryInterface(
453 IFont* iface,
454 REFIID riid,
455 void** ppvObject)
456{
457 _ICOM_THIS(OLEFontImpl, iface);
458 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
459
460 /*
461 * Perform a sanity check on the parameters.
462 */
463 if ( (this==0) || (ppvObject==0) )
464 return E_INVALIDARG;
465
466 /*
467 * Initialize the return parameter.
468 */
469 *ppvObject = 0;
470
471 /*
472 * Compare the riid with the interface IDs implemented by this object.
473 */
474 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
475 {
476 *ppvObject = (IFont*)this;
477 }
478 else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
479 {
480 *ppvObject = (IFont*)this;
481 }
482 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
483 {
484 *ppvObject = (IDispatch*)&(this->lpvtbl2);
485 }
486 else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
487 {
488 *ppvObject = (IDispatch*)&(this->lpvtbl2);
489 }
490 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
491 {
492 *ppvObject = (IPersistStream*)&(this->lpvtbl3);
493 }
494 else if (memcmp(&IID_IConnectionPointContainer, riid,
495 sizeof(IID_IConnectionPointContainer)) == 0)
496 {
497 *ppvObject = (IPersistStream*)&(this->lpvtbl4);
498 }
499
500 /*
501 * Check that we obtained an interface.
502 */
503 if ((*ppvObject)==0)
504 {
505 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
506 return E_NOINTERFACE;
507 }
508
509 /*
510 * Query Interface always increases the reference count by one when it is
511 * successful
512 */
513 OLEFontImpl_AddRef((IFont*)this);
514
515 return S_OK;
516}
517
518/************************************************************************
519 * OLEFontImpl_AddRef (IUnknown)
520 *
521 * See Windows documentation for more details on IUnknown methods.
522 */
523ULONG WINAPI OLEFontImpl_AddRef(
524 IFont* iface)
525{
526 _ICOM_THIS(OLEFontImpl, iface);
527 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
528 this->ref++;
529
530 return this->ref;
531}
532
533/************************************************************************
534 * OLEFontImpl_Release (IUnknown)
535 *
536 * See Windows documentation for more details on IUnknown methods.
537 */
538ULONG WINAPI OLEFontImpl_Release(
539 IFont* iface)
540{
541 _ICOM_THIS(OLEFontImpl, iface);
542 TRACE("(%p)->(ref=%ld)\n", this, this->ref);
543
544 /*
545 * Decrease the reference count on this object.
546 */
547 this->ref--;
548
549 /*
550 * If the reference count goes down to 0, perform suicide.
551 */
552 if (this->ref==0)
553 {
554 OLEFontImpl_Destroy(this);
555
556 return 0;
557 }
558
559 return this->ref;
560}
561
562/************************************************************************
563 * OLEFontImpl_get_Name (IFont)
564 *
565 * See Windows documentation for more details on IFont methods.
566 */
567static HRESULT WINAPI OLEFontImpl_get_Name(
568 IFont* iface,
569 BSTR* pname)
570{
571 _ICOM_THIS(OLEFontImpl, iface);
572 TRACE("(%p)->(%p)\n", this, pname);
573 /*
574 * Sanity check.
575 */
576 if (pname==0)
577 return E_POINTER;
578
579 if (this->description.lpstrName!=0)
580 *pname = SysAllocString(this->description.lpstrName);
581 else
582 *pname = 0;
583
584 return S_OK;
585}
586
587/************************************************************************
588 * OLEFontImpl_put_Name (IFont)
589 *
590 * See Windows documentation for more details on IFont methods.
591 */
592static HRESULT WINAPI OLEFontImpl_put_Name(
593 IFont* iface,
594 BSTR name)
595{
596 _ICOM_THIS(OLEFontImpl, iface);
597 TRACE("(%p)->(%p)\n", this, name);
598
599 if (this->description.lpstrName==0)
600 {
601 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
602 0,
603 (lstrlenW(name)+1) * sizeof(WCHAR));
604 }
605 else
606 {
607 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
608 0,
609 this->description.lpstrName,
610 (lstrlenW(name)+1) * sizeof(WCHAR));
611 }
612
613 if (this->description.lpstrName==0)
614 return E_OUTOFMEMORY;
615
616 strcpyW(this->description.lpstrName, name);
617 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
618 OLEFont_SendNotify(this, DISPID_FONT_NAME);
619 return S_OK;
620}
621
622/************************************************************************
623 * OLEFontImpl_get_Size (IFont)
624 *
625 * See Windows documentation for more details on IFont methods.
626 */
627static HRESULT WINAPI OLEFontImpl_get_Size(
628 IFont* iface,
629 CY* psize)
630{
631 _ICOM_THIS(OLEFontImpl, iface);
632 TRACE("(%p)->(%p)\n", this, psize);
633
634 /*
635 * Sanity check
636 */
637 if (psize==0)
638 return E_POINTER;
639
640 psize->s.Hi = 0;
641 psize->s.Lo = this->description.cySize.s.Lo;
642
643 return S_OK;
644}
645
646/************************************************************************
647 * OLEFontImpl_put_Size (IFont)
648 *
649 * See Windows documentation for more details on IFont methods.
650 */
651static HRESULT WINAPI OLEFontImpl_put_Size(
652 IFont* iface,
653 CY size)
654{
655 _ICOM_THIS(OLEFontImpl, iface);
656 TRACE("(%p)->(%ld)\n", this, size.s.Lo);
657 this->description.cySize.s.Hi = 0;
658 this->description.cySize.s.Lo = size.s.Lo;
659 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
660
661 return S_OK;
662}
663
664/************************************************************************
665 * OLEFontImpl_get_Bold (IFont)
666 *
667 * See Windows documentation for more details on IFont methods.
668 */
669static HRESULT WINAPI OLEFontImpl_get_Bold(
670 IFont* iface,
671 BOOL* pbold)
672{
673 _ICOM_THIS(OLEFontImpl, iface);
674 TRACE("(%p)->(%p)\n", this, pbold);
675 /*
676 * Sanity check
677 */
678 if (pbold==0)
679 return E_POINTER;
680
681 *pbold = this->description.sWeight > 550;
682
683 return S_OK;
684}
685
686/************************************************************************
687 * OLEFontImpl_put_Bold (IFont)
688 *
689 * See Windows documentation for more details on IFont methods.
690 */
691static HRESULT WINAPI OLEFontImpl_put_Bold(
692 IFont* iface,
693 BOOL bold)
694{
695 _ICOM_THIS(OLEFontImpl, iface);
696 TRACE("(%p)->(%d)\n", this, bold);
697 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
698 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
699
700 return S_OK;
701}
702
703/************************************************************************
704 * OLEFontImpl_get_Italic (IFont)
705 *
706 * See Windows documentation for more details on IFont methods.
707 */
708static HRESULT WINAPI OLEFontImpl_get_Italic(
709 IFont* iface,
710 BOOL* pitalic)
711{
712 _ICOM_THIS(OLEFontImpl, iface);
713 TRACE("(%p)->(%p)\n", this, pitalic);
714 /*
715 * Sanity check
716 */
717 if (pitalic==0)
718 return E_POINTER;
719
720 *pitalic = this->description.fItalic;
721
722 return S_OK;
723}
724
725/************************************************************************
726 * OLEFontImpl_put_Italic (IFont)
727 *
728 * See Windows documentation for more details on IFont methods.
729 */
730static HRESULT WINAPI OLEFontImpl_put_Italic(
731 IFont* iface,
732 BOOL italic)
733{
734 _ICOM_THIS(OLEFontImpl, iface);
735 TRACE("(%p)->(%d)\n", this, italic);
736
737 this->description.fItalic = italic;
738
739 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
740 return S_OK;
741}
742
743/************************************************************************
744 * OLEFontImpl_get_Underline (IFont)
745 *
746 * See Windows documentation for more details on IFont methods.
747 */
748static HRESULT WINAPI OLEFontImpl_get_Underline(
749 IFont* iface,
750 BOOL* punderline)
751{
752 _ICOM_THIS(OLEFontImpl, iface);
753 TRACE("(%p)->(%p)\n", this, punderline);
754
755 /*
756 * Sanity check
757 */
758 if (punderline==0)
759 return E_POINTER;
760
761 *punderline = this->description.fUnderline;
762
763 return S_OK;
764}
765
766/************************************************************************
767 * OLEFontImpl_put_Underline (IFont)
768 *
769 * See Windows documentation for more details on IFont methods.
770 */
771static HRESULT WINAPI OLEFontImpl_put_Underline(
772 IFont* iface,
773 BOOL underline)
774{
775 _ICOM_THIS(OLEFontImpl, iface);
776 TRACE("(%p)->(%d)\n", this, underline);
777
778 this->description.fUnderline = underline;
779
780 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
781 return S_OK;
782}
783
784/************************************************************************
785 * OLEFontImpl_get_Strikethrough (IFont)
786 *
787 * See Windows documentation for more details on IFont methods.
788 */
789static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
790 IFont* iface,
791 BOOL* pstrikethrough)
792{
793 _ICOM_THIS(OLEFontImpl, iface);
794 TRACE("(%p)->(%p)\n", this, pstrikethrough);
795
796 /*
797 * Sanity check
798 */
799 if (pstrikethrough==0)
800 return E_POINTER;
801
802 *pstrikethrough = this->description.fStrikethrough;
803
804 return S_OK;
805}
806
807/************************************************************************
808 * OLEFontImpl_put_Strikethrough (IFont)
809 *
810 * See Windows documentation for more details on IFont methods.
811 */
812static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
813 IFont* iface,
814 BOOL strikethrough)
815{
816 _ICOM_THIS(OLEFontImpl, iface);
817 TRACE("(%p)->(%d)\n", this, strikethrough);
818
819 this->description.fStrikethrough = strikethrough;
820 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
821
822 return S_OK;
823}
824
825/************************************************************************
826 * OLEFontImpl_get_Weight (IFont)
827 *
828 * See Windows documentation for more details on IFont methods.
829 */
830static HRESULT WINAPI OLEFontImpl_get_Weight(
831 IFont* iface,
832 short* pweight)
833{
834 _ICOM_THIS(OLEFontImpl, iface);
835 TRACE("(%p)->(%p)\n", this, pweight);
836
837 /*
838 * Sanity check
839 */
840 if (pweight==0)
841 return E_POINTER;
842
843 *pweight = this->description.sWeight;
844
845 return S_OK;
846}
847
848/************************************************************************
849 * OLEFontImpl_put_Weight (IFont)
850 *
851 * See Windows documentation for more details on IFont methods.
852 */
853static HRESULT WINAPI OLEFontImpl_put_Weight(
854 IFont* iface,
855 short weight)
856{
857 _ICOM_THIS(OLEFontImpl, iface);
858 TRACE("(%p)->(%d)\n", this, weight);
859
860 this->description.sWeight = weight;
861
862 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
863 return S_OK;
864}
865
866/************************************************************************
867 * OLEFontImpl_get_Charset (IFont)
868 *
869 * See Windows documentation for more details on IFont methods.
870 */
871static HRESULT WINAPI OLEFontImpl_get_Charset(
872 IFont* iface,
873 short* pcharset)
874{
875 _ICOM_THIS(OLEFontImpl, iface);
876 TRACE("(%p)->(%p)\n", this, pcharset);
877
878 /*
879 * Sanity check
880 */
881 if (pcharset==0)
882 return E_POINTER;
883
884 *pcharset = this->description.sCharset;
885
886 return S_OK;
887}
888
889/************************************************************************
890 * OLEFontImpl_put_Charset (IFont)
891 *
892 * See Windows documentation for more details on IFont methods.
893 */
894static HRESULT WINAPI OLEFontImpl_put_Charset(
895 IFont* iface,
896 short charset)
897{
898 _ICOM_THIS(OLEFontImpl, iface);
899 TRACE("(%p)->(%d)\n", this, charset);
900
901 this->description.sCharset = charset;
902 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
903
904 return S_OK;
905}
906
907/************************************************************************
908 * OLEFontImpl_get_hFont (IFont)
909 *
910 * See Windows documentation for more details on IFont methods.
911 */
912static HRESULT WINAPI OLEFontImpl_get_hFont(
913 IFont* iface,
914 HFONT* phfont)
915{
916 _ICOM_THIS(OLEFontImpl, iface);
917 TRACE("(%p)->(%p)\n", this, phfont);
918 if (phfont==NULL)
919 return E_POINTER;
920
921 /*
922 * Realize the font if necessary
923 */
924 if (this->gdiFont==0)
925{
926 LOGFONTW logFont;
927 INT fontHeight;
928 CY cySize;
929
930 /*
931 * The height of the font returned by the get_Size property is the
932 * height of the font in points multiplied by 10000... Using some
933 * simple conversions and the ratio given by the application, it can
934 * be converted to a height in pixels.
935 */
936 IFont_get_Size(iface, &cySize);
937
938 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
939 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
940
941 memset(&logFont, 0, sizeof(LOGFONTW));
942
943 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
944 (-fontHeight/10000L);
945 logFont.lfItalic = this->description.fItalic;
946 logFont.lfUnderline = this->description.fUnderline;
947 logFont.lfStrikeOut = this->description.fStrikethrough;
948 logFont.lfWeight = this->description.sWeight;
949 logFont.lfCharSet = this->description.sCharset;
950 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
951 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
952 logFont.lfQuality = DEFAULT_QUALITY;
953 logFont.lfPitchAndFamily = DEFAULT_PITCH;
954 strcpyW(logFont.lfFaceName,this->description.lpstrName);
955
956 this->gdiFont = CreateFontIndirectW(&logFont);
957 }
958
959 *phfont = this->gdiFont;
960 TRACE("Returning %p\n", *phfont);
961 return S_OK;
962}
963
964/************************************************************************
965 * OLEFontImpl_Clone (IFont)
966 *
967 * See Windows documentation for more details on IFont methods.
968 */
969static HRESULT WINAPI OLEFontImpl_Clone(
970 IFont* iface,
971 IFont** ppfont)
972{
973 OLEFontImpl* newObject = 0;
974 LOGFONTW logFont;
975 INT fontHeight;
976 CY cySize;
977 _ICOM_THIS(OLEFontImpl, iface);
978 TRACE("(%p)->(%p)\n", this, ppfont);
979
980 if (ppfont == NULL)
981 return E_POINTER;
982
983 *ppfont = NULL;
984
985 /*
986 * Allocate space for the object.
987 */
988 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
989
990 if (newObject==NULL)
991 return E_OUTOFMEMORY;
992
993 *newObject = *this;
994
995 /* We need to alloc new memory for the string, otherwise
996 * we free memory twice.
997 */
998 newObject->description.lpstrName = HeapAlloc(
999 GetProcessHeap(),0,
1000 (1+strlenW(this->description.lpstrName))*2
1001 );
1002 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
1003 /* We need to clone the HFONT too. This is just cut & paste from above */
1004 IFont_get_Size(iface, &cySize);
1005
1006 fontHeight = MulDiv(cySize.s.Lo, 2540L, 72L);
1007 fontHeight = MulDiv(fontHeight, this->cyLogical,this->cyHimetric);
1008
1009 memset(&logFont, 0, sizeof(LOGFONTW));
1010
1011 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
1012 (-fontHeight/10000L);
1013 logFont.lfItalic = this->description.fItalic;
1014 logFont.lfUnderline = this->description.fUnderline;
1015 logFont.lfStrikeOut = this->description.fStrikethrough;
1016 logFont.lfWeight = this->description.sWeight;
1017 logFont.lfCharSet = this->description.sCharset;
1018 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
1019 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1020 logFont.lfQuality = DEFAULT_QUALITY;
1021 logFont.lfPitchAndFamily = DEFAULT_PITCH;
1022 strcpyW(logFont.lfFaceName,this->description.lpstrName);
1023
1024 newObject->gdiFont = CreateFontIndirectW(&logFont);
1025
1026
1027 /* The cloned object starts with a reference count of 1 */
1028 newObject->ref = 1;
1029
1030 *ppfont = (IFont*)newObject;
1031
1032 return S_OK;
1033}
1034
1035/************************************************************************
1036 * OLEFontImpl_IsEqual (IFont)
1037 *
1038 * See Windows documentation for more details on IFont methods.
1039 */
1040static HRESULT WINAPI OLEFontImpl_IsEqual(
1041 IFont* iface,
1042 IFont* pFontOther)
1043{
1044 FIXME("():Stub\n");
1045 return E_NOTIMPL;
1046}
1047
1048/************************************************************************
1049 * OLEFontImpl_SetRatio (IFont)
1050 *
1051 * See Windows documentation for more details on IFont methods.
1052 */
1053static HRESULT WINAPI OLEFontImpl_SetRatio(
1054 IFont* iface,
1055 long cyLogical,
1056 long cyHimetric)
1057{
1058 _ICOM_THIS(OLEFontImpl, iface);
1059 TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
1060
1061 this->cyLogical = cyLogical;
1062 this->cyHimetric = cyHimetric;
1063
1064 return S_OK;
1065}
1066
1067/************************************************************************
1068 * OLEFontImpl_QueryTextMetrics (IFont)
1069 *
1070 * See Windows documentation for more details on IFont methods.
1071 */
1072static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
1073 IFont* iface,
1074 TEXTMETRICOLE* ptm)
1075{
1076 FIXME("():Stub\n");
1077 return E_NOTIMPL;
1078}
1079
1080/************************************************************************
1081 * OLEFontImpl_AddRefHfont (IFont)
1082 *
1083 * See Windows documentation for more details on IFont methods.
1084 */
1085static HRESULT WINAPI OLEFontImpl_AddRefHfont(
1086 IFont* iface,
1087 HFONT hfont)
1088{
1089 _ICOM_THIS(OLEFontImpl, iface);
1090 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1091
1092 if ( (hfont == 0) ||
1093 (hfont != this->gdiFont) )
1094 return E_INVALIDARG;
1095
1096 this->fontLock++;
1097
1098 return S_OK;
1099}
1100
1101/************************************************************************
1102 * OLEFontImpl_ReleaseHfont (IFont)
1103 *
1104 * See Windows documentation for more details on IFont methods.
1105 */
1106static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
1107 IFont* iface,
1108 HFONT hfont)
1109{
1110 _ICOM_THIS(OLEFontImpl, iface);
1111 TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
1112
1113 if ( (hfont == 0) ||
1114 (hfont != this->gdiFont) )
1115 return E_INVALIDARG;
1116
1117 this->fontLock--;
1118
1119 /*
1120 * If we just released our last font reference, destroy it.
1121 */
1122 if (this->fontLock==0)
1123 {
1124 DeleteObject(this->gdiFont);
1125 this->gdiFont = 0;
1126 }
1127
1128 return S_OK;
1129}
1130
1131/************************************************************************
1132 * OLEFontImpl_SetHdc (IFont)
1133 *
1134 * See Windows documentation for more details on IFont methods.
1135 */
1136static HRESULT WINAPI OLEFontImpl_SetHdc(
1137 IFont* iface,
1138 HDC hdc)
1139{
1140 _ICOM_THIS(OLEFontImpl, iface);
1141 FIXME("(%p)->(%p): Stub\n", this, hdc);
1142 return E_NOTIMPL;
1143}
1144
1145/************************************************************************
1146 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1147 *
1148 * See Windows documentation for more details on IUnknown methods.
1149 */
1150static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
1151 IDispatch* iface,
1152 REFIID riid,
1153 VOID** ppvoid)
1154{
1155 _ICOM_THIS_From_IDispatch(IFont, iface);
1156
1157 return IFont_QueryInterface(this, riid, ppvoid);
1158}
1159
1160/************************************************************************
1161 * OLEFontImpl_IDispatch_Release (IUnknown)
1162 *
1163 * See Windows documentation for more details on IUnknown methods.
1164 */
1165static ULONG WINAPI OLEFontImpl_IDispatch_Release(
1166 IDispatch* iface)
1167{
1168 _ICOM_THIS_From_IDispatch(IFont, iface);
1169
1170 return IFont_Release(this);
1171}
1172
1173/************************************************************************
1174 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1175 *
1176 * See Windows documentation for more details on IUnknown methods.
1177 */
1178static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
1179 IDispatch* iface)
1180{
1181 _ICOM_THIS_From_IDispatch(IFont, iface);
1182
1183 return IFont_AddRef(this);
1184}
1185
1186/************************************************************************
1187 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1188 *
1189 * See Windows documentation for more details on IDispatch methods.
1190 */
1191static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
1192 IDispatch* iface,
1193 unsigned int* pctinfo)
1194{
1195 _ICOM_THIS_From_IDispatch(IFont, iface);
1196 FIXME("(%p)->(%p): Stub\n", this, pctinfo);
1197
1198 return E_NOTIMPL;
1199}
1200
1201/************************************************************************
1202 * OLEFontImpl_GetTypeInfo (IDispatch)
1203 *
1204 * See Windows documentation for more details on IDispatch methods.
1205 */
1206static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
1207 IDispatch* iface,
1208 UINT iTInfo,
1209 LCID lcid,
1210 ITypeInfo** ppTInfo)
1211{
1212 _ICOM_THIS_From_IDispatch(IFont, iface);
1213 FIXME("(%p):Stub\n", this);
1214
1215 return E_NOTIMPL;
1216}
1217
1218/************************************************************************
1219 * OLEFontImpl_GetIDsOfNames (IDispatch)
1220 *
1221 * See Windows documentation for more details on IDispatch methods.
1222 */
1223static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
1224 IDispatch* iface,
1225 REFIID riid,
1226 LPOLESTR* rgszNames,
1227 UINT cNames,
1228 LCID lcid,
1229 DISPID* rgDispId)
1230{
1231 _ICOM_THIS_From_IDispatch(IFont, iface);
1232 FIXME("(%p):Stub\n", this);
1233
1234 return E_NOTIMPL;
1235}
1236
1237/************************************************************************
1238 * OLEFontImpl_Invoke (IDispatch)
1239 *
1240 * See Windows documentation for more details on IDispatch methods.
1241 */
1242static HRESULT WINAPI OLEFontImpl_Invoke(
1243 IDispatch* iface,
1244 DISPID dispIdMember,
1245 REFIID riid,
1246 LCID lcid,
1247 WORD wFlags,
1248 DISPPARAMS* pDispParams,
1249 VARIANT* pVarResult,
1250 EXCEPINFO* pExepInfo,
1251 UINT* puArgErr)
1252{
1253 _ICOM_THIS_From_IDispatch(IFont, iface);
1254 FIXME("%p->(%ld,%s,%lx,%x), stub!\n", this,dispIdMember,debugstr_guid(riid),lcid,
1255 wFlags
1256 );
1257 return S_OK;
1258}
1259
1260/************************************************************************
1261 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1262 *
1263 * See Windows documentation for more details on IUnknown methods.
1264 */
1265static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1266 IPersistStream* iface,
1267 REFIID riid,
1268 VOID** ppvoid)
1269{
1270 _ICOM_THIS_From_IPersistStream(IFont, iface);
1271
1272 return IFont_QueryInterface(this, riid, ppvoid);
1273}
1274
1275/************************************************************************
1276 * OLEFontImpl_IPersistStream_Release (IUnknown)
1277 *
1278 * See Windows documentation for more details on IUnknown methods.
1279 */
1280static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1281 IPersistStream* iface)
1282{
1283 _ICOM_THIS_From_IPersistStream(IFont, iface);
1284
1285 return IFont_Release(this);
1286}
1287
1288/************************************************************************
1289 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1290 *
1291 * See Windows documentation for more details on IUnknown methods.
1292 */
1293static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1294 IPersistStream* iface)
1295{
1296 _ICOM_THIS_From_IPersistStream(IFont, iface);
1297
1298 return IFont_AddRef(this);
1299}
1300
1301/************************************************************************
1302 * OLEFontImpl_GetClassID (IPersistStream)
1303 *
1304 * See Windows documentation for more details on IPersistStream methods.
1305 */
1306static HRESULT WINAPI OLEFontImpl_GetClassID(
1307 IPersistStream* iface,
1308 CLSID* pClassID)
1309{
1310 if (pClassID==0)
1311 return E_POINTER;
1312
1313 memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
1314
1315 return S_OK;
1316}
1317
1318/************************************************************************
1319 * OLEFontImpl_IsDirty (IPersistStream)
1320 *
1321 * See Windows documentation for more details on IPersistStream methods.
1322 */
1323static HRESULT WINAPI OLEFontImpl_IsDirty(
1324 IPersistStream* iface)
1325{
1326 return S_OK;
1327}
1328
1329/************************************************************************
1330 * OLEFontImpl_Load (IPersistStream)
1331 *
1332 * See Windows documentation for more details on IPersistStream methods.
1333 *
1334 * This is the format of the standard font serialization as far as I
1335 * know
1336 *
1337 * Offset Type Value Comment
1338 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1339 * 0x0001 Short Charset Charset value from the FONTDESC structure
1340 * 0x0003 Byte Attributes Flags defined as follows:
1341 * 00000010 - Italic
1342 * 00000100 - Underline
1343 * 00001000 - Strikethrough
1344 * 0x0004 Short Weight Weight value from FONTDESC structure
1345 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1346 * structure/
1347 * 0x000A Byte name length Length of the font name string (no null character)
1348 * 0x000B String name Name of the font (ASCII, no nul character)
1349 */
1350static HRESULT WINAPI OLEFontImpl_Load(
1351 IPersistStream* iface,
1352 IStream* pLoadStream)
1353{
1354 char readBuffer[0x100];
1355 ULONG cbRead;
1356 BYTE bVersion;
1357 BYTE bAttributes;
1358 BYTE bStringSize;
1359 INT len;
1360
1361 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1362
1363 /*
1364 * Read the version byte
1365 */
1366 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1367
1368 if ( (cbRead!=1) ||
1369 (bVersion!=0x01) )
1370 return E_FAIL;
1371
1372 /*
1373 * Charset
1374 */
1375 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1376
1377 if (cbRead!=2)
1378 return E_FAIL;
1379
1380 /*
1381 * Attributes
1382 */
1383 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1384
1385 if (cbRead!=1)
1386 return E_FAIL;
1387
1388 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
1389 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
1390 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
1391
1392 /*
1393 * Weight
1394 */
1395 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1396
1397 if (cbRead!=2)
1398 return E_FAIL;
1399
1400 /*
1401 * Size
1402 */
1403 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
1404
1405 if (cbRead!=4)
1406 return E_FAIL;
1407
1408 this->description.cySize.s.Hi = 0;
1409
1410 /*
1411 * FontName
1412 */
1413 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1414
1415 if (cbRead!=1)
1416 return E_FAIL;
1417
1418 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1419
1420 if (cbRead!=bStringSize)
1421 return E_FAIL;
1422
1423 if (this->description.lpstrName!=0)
1424 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
1425
1426 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1427 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1428 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1429 this->description.lpstrName[len] = 0;
1430
1431 /* Ensure use of this font causes a new one to be created @@@@ */
1432 DeleteObject(this->gdiFont);
1433 this->gdiFont = 0;
1434
1435 return S_OK;
1436}
1437
1438/************************************************************************
1439 * OLEFontImpl_Save (IPersistStream)
1440 *
1441 * See Windows documentation for more details on IPersistStream methods.
1442 */
1443static HRESULT WINAPI OLEFontImpl_Save(
1444 IPersistStream* iface,
1445 IStream* pOutStream,
1446 BOOL fClearDirty)
1447{
1448 char* writeBuffer = NULL;
1449 ULONG cbWritten;
1450 BYTE bVersion = 0x01;
1451 BYTE bAttributes;
1452 BYTE bStringSize;
1453
1454 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1455
1456 /*
1457 * Read the version byte
1458 */
1459 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1460
1461 if (cbWritten!=1)
1462 return E_FAIL;
1463
1464 /*
1465 * Charset
1466 */
1467 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1468
1469 if (cbWritten!=2)
1470 return E_FAIL;
1471
1472 /*
1473 * Attributes
1474 */
1475 bAttributes = 0;
1476
1477 if (this->description.fItalic)
1478 bAttributes |= FONTPERSIST_ITALIC;
1479
1480 if (this->description.fStrikethrough)
1481 bAttributes |= FONTPERSIST_STRIKETHROUGH;
1482
1483 if (this->description.fUnderline)
1484 bAttributes |= FONTPERSIST_UNDERLINE;
1485
1486 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1487
1488 if (cbWritten!=1)
1489 return E_FAIL;
1490
1491 /*
1492 * Weight
1493 */
1494 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1495
1496 if (cbWritten!=2)
1497 return E_FAIL;
1498
1499 /*
1500 * Size
1501 */
1502 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
1503
1504 if (cbWritten!=4)
1505 return E_FAIL;
1506
1507 /*
1508 * FontName
1509 */
1510 if (this->description.lpstrName!=0)
1511 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1512 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
1513 else
1514 bStringSize = 0;
1515
1516 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1517
1518 if (cbWritten!=1)
1519 return E_FAIL;
1520
1521 if (bStringSize!=0)
1522 {
1523 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1524 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1525 strlenW(this->description.lpstrName),
1526 writeBuffer, bStringSize, NULL, NULL );
1527
1528 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
1529 HeapFree(GetProcessHeap(), 0, writeBuffer);
1530
1531 if (cbWritten!=bStringSize)
1532 return E_FAIL;
1533 }
1534
1535 return S_OK;
1536}
1537
1538/************************************************************************
1539 * OLEFontImpl_GetSizeMax (IPersistStream)
1540 *
1541 * See Windows documentation for more details on IPersistStream methods.
1542 */
1543static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1544 IPersistStream* iface,
1545 ULARGE_INTEGER* pcbSize)
1546{
1547 _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
1548
1549 if (pcbSize==NULL)
1550 return E_POINTER;
1551
1552 pcbSize->s.HighPart = 0;
1553 pcbSize->s.LowPart = 0;
1554
1555 pcbSize->s.LowPart += sizeof(BYTE); /* Version */
1556 pcbSize->s.LowPart += sizeof(WORD); /* Lang code */
1557 pcbSize->s.LowPart += sizeof(BYTE); /* Flags */
1558 pcbSize->s.LowPart += sizeof(WORD); /* Weight */
1559 pcbSize->s.LowPart += sizeof(DWORD); /* Size */
1560 pcbSize->s.LowPart += sizeof(BYTE); /* StrLength */
1561
1562 if (this->description.lpstrName!=0)
1563 pcbSize->s.LowPart += lstrlenW(this->description.lpstrName);
1564
1565 return S_OK;
1566}
1567
1568/************************************************************************
1569 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
1570 *
1571 * See Windows documentation for more details on IUnknown methods.
1572 */
1573static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
1574 IConnectionPointContainer* iface,
1575 REFIID riid,
1576 VOID** ppvoid)
1577{
1578 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1579
1580 return IFont_QueryInterface((IFont*)this, riid, ppvoid);
1581}
1582
1583/************************************************************************
1584 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
1585 *
1586 * See Windows documentation for more details on IUnknown methods.
1587 */
1588static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
1589 IConnectionPointContainer* iface)
1590{
1591 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1592
1593 return IFont_Release((IFont*)this);
1594}
1595
1596/************************************************************************
1597 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
1598 *
1599 * See Windows documentation for more details on IUnknown methods.
1600 */
1601static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
1602 IConnectionPointContainer* iface)
1603{
1604 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1605
1606 return IFont_AddRef((IFont*)this);
1607}
1608
1609/************************************************************************
1610 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
1611 *
1612 * See Windows documentation for more details on IConnectionPointContainer
1613 * methods.
1614 */
1615static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
1616 IConnectionPointContainer* iface,
1617 IEnumConnectionPoints **ppEnum)
1618{
1619 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1620
1621 FIXME("(%p)->(%p): stub\n", this, ppEnum);
1622 return E_NOTIMPL;
1623}
1624
1625/************************************************************************
1626 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
1627 *
1628 * See Windows documentation for more details on IConnectionPointContainer
1629 * methods.
1630 */
1631static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
1632 IConnectionPointContainer* iface,
1633 REFIID riid,
1634 IConnectionPoint **ppCp)
1635{
1636 _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
1637 TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
1638
1639 if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
1640 return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
1641 (LPVOID)ppCp);
1642 } else {
1643 FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
1644 return E_NOINTERFACE;
1645 }
1646}
1647
1648/*******************************************************************************
1649 * StdFont ClassFactory
1650 */
1651typedef struct
1652{
1653 /* IUnknown fields */
1654 ICOM_VFIELD(IClassFactory);
1655 DWORD ref;
1656} IClassFactoryImpl;
1657
1658static HRESULT WINAPI
1659SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1660 ICOM_THIS(IClassFactoryImpl,iface);
1661
1662 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1663 return E_NOINTERFACE;
1664}
1665
1666static ULONG WINAPI
1667SFCF_AddRef(LPCLASSFACTORY iface) {
1668 ICOM_THIS(IClassFactoryImpl,iface);
1669 return ++(This->ref);
1670}
1671
1672static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
1673 ICOM_THIS(IClassFactoryImpl,iface);
1674 /* static class, won't be freed */
1675 return --(This->ref);
1676}
1677
1678static HRESULT WINAPI SFCF_CreateInstance(
1679 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1680) {
1681 FONTDESC fd;
1682
1683 WCHAR fname[] = { 'S','y','s','t','e','m',0 };
1684
1685 fd.cbSizeofstruct = sizeof(fd);
1686 fd.lpstrName = fname;
1687 fd.cySize.s.Lo = 80000;
1688 fd.cySize.s.Hi = 0;
1689 fd.sWeight = 0;
1690 fd.sCharset = 0;
1691 fd.fItalic = 0;
1692 fd.fUnderline = 0;
1693 fd.fStrikethrough = 0;
1694 return OleCreateFontIndirect(&fd,riid,ppobj);
1695
1696}
1697
1698static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1699 ICOM_THIS(IClassFactoryImpl,iface);
1700 FIXME("(%p)->(%d),stub!\n",This,dolock);
1701 return S_OK;
1702}
1703
1704static ICOM_VTABLE(IClassFactory) SFCF_Vtbl = {
1705 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1706 SFCF_QueryInterface,
1707 SFCF_AddRef,
1708 SFCF_Release,
1709 SFCF_CreateInstance,
1710 SFCF_LockServer
1711};
1712static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
1713
1714void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }
Note: See TracBrowser for help on using the repository browser.