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

Last change on this file since 6648 was 6648, checked in by bird, 24 years ago

Added $Id:$ keyword.

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