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

Last change on this file since 8266 was 7916, checked in by sandervl, 24 years ago

Wine 20020215 resync + added extended logging

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