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

Last change on this file since 8889 was 8450, checked in by sandervl, 23 years ago

Wine resync

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