msi: Search all installation contexts in the FindRelatedProducts action.
[wine] / dlls / oleaut32 / olefont.c
CommitLineData
eb5a29b6
FB
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
f75b9f19 8 * Copyright 2006 (Google) Benjamin Arai
0799c1a7
AJ
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
360a3f91 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
eb5a29b6
FB
23 */
24#include <assert.h>
e37c6e18 25#include <stdarg.h>
ee517e86 26#include <string.h>
297f3d89 27
bf72af30 28#define COBJMACROS
297f3d89
DP
29#define NONAMELESSUNION
30#define NONAMELESSSTRUCT
bf72af30 31
eb5a29b6 32#include "winerror.h"
e37c6e18 33#include "windef.h"
74af67ef
AJ
34#include "winbase.h"
35#include "wingdi.h"
1ed55775 36#include "winuser.h"
4c40b397 37#include "wine/list.h"
c7e7df8b 38#include "wine/unicode.h"
1f5315c8 39#include "objbase.h"
25e2a320 40#include "oleauto.h" /* for SysAllocString(....) */
1ed55775 41#include "ole2.h"
eb5a29b6 42#include "olectl.h"
0799c1a7 43#include "wine/debug.h"
e8d4268a 44#include "connpt.h" /* for CreateConnectionPoint */
d49e808b 45#include "oaidl.h"
eb5a29b6 46
0799c1a7 47WINE_DEFAULT_DEBUG_CHANNEL(ole);
b4b9fae6 48
eb5a29b6 49/***********************************************************************
d58f61c0
FB
50 * Declaration of constants used when serializing the font object.
51 */
52#define FONTPERSIST_ITALIC 0x02
53#define FONTPERSIST_UNDERLINE 0x04
54#define FONTPERSIST_STRIKETHROUGH 0x08
55
7e42fd8b 56static HDC olefont_hdc;
4c40b397
RS
57
58/***********************************************************************
59 * List of the HFONTs it has given out, with each one having a separate
60 * ref count.
61 */
62typedef struct _HFONTItem
63{
64 struct list entry;
65
7aaaf738
HD
66 /* Reference count of any IFont objects that own this hfont */
67 LONG int_refs;
68
69 /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */
70 LONG total_refs;
4c40b397 71
7aaaf738 72 /* The font associated with this object. */
4c40b397
RS
73 HFONT gdiFont;
74
75} HFONTItem, *PHFONTItem;
76
77static struct list OLEFontImpl_hFontList = LIST_INIT(OLEFontImpl_hFontList);
78
79/* Counts how many fonts contain at least one lock */
80static LONG ifont_cnt = 0;
81
82/***********************************************************************
83 * Critical section for OLEFontImpl_hFontList
84 */
85static CRITICAL_SECTION OLEFontImpl_csHFONTLIST;
86static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug =
87{
88 0, 0, &OLEFontImpl_csHFONTLIST,
89 { &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList,
90 &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList },
91 0, 0, { (DWORD_PTR)(__FILE__ ": OLEFontImpl_csHFONTLIST") }
92};
93static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 };
94
7e42fd8b
HD
95static HDC get_dc(void)
96{
97 HDC hdc;
98 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
99 if(!olefont_hdc)
100 olefont_hdc = CreateCompatibleDC(NULL);
101 hdc = olefont_hdc;
102 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
103 return hdc;
104}
105
106static void delete_dc(void)
107{
108 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
109 if(olefont_hdc)
110 {
111 DeleteDC(olefont_hdc);
112 olefont_hdc = NULL;
113 }
114 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
115}
116
4c40b397
RS
117static void HFONTItem_Delete(PHFONTItem item)
118{
119 DeleteObject(item->gdiFont);
120 list_remove(&item->entry);
121 HeapFree(GetProcessHeap(), 0, item);
122}
123
7aaaf738
HD
124/* Find hfont item entry in the list. Should be called while holding the crit sect */
125static HFONTItem *find_hfontitem(HFONT hfont)
126{
127 HFONTItem *item;
128
129 LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry)
130 {
131 if (item->gdiFont == hfont)
132 return item;
133 }
134 return NULL;
135}
136
cf602ca4
HD
137/* Add an item to the list with one internal reference */
138static HRESULT add_hfontitem(HFONT hfont)
139{
140 HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item));
141
142 if(!new_item) return E_OUTOFMEMORY;
143
144 new_item->int_refs = 1;
145 new_item->total_refs = 1;
146 new_item->gdiFont = hfont;
147 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
148 list_add_tail(&OLEFontImpl_hFontList,&new_item->entry);
149 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
150 return S_OK;
151}
152
7aaaf738
HD
153static HRESULT inc_int_ref(HFONT hfont)
154{
155 HFONTItem *item;
156 HRESULT hr = S_FALSE;
157
158 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
159 item = find_hfontitem(hfont);
160
161 if(item)
162 {
163 item->int_refs++;
164 item->total_refs++;
165 hr = S_OK;
166 }
167 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
168
169 return hr;
170}
171
172/* decrements the internal ref of a hfont item. If both refs are zero it'll
173 remove the item from the list and delete the hfont */
174static HRESULT dec_int_ref(HFONT hfont)
175{
176 HFONTItem *item;
177 HRESULT hr = S_FALSE;
178
179 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
180 item = find_hfontitem(hfont);
181
182 if(item)
183 {
184 item->int_refs--;
185 item->total_refs--;
186 if(item->int_refs == 0 && item->total_refs == 0)
187 HFONTItem_Delete(item);
188 hr = S_OK;
189 }
190 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
191
192 return hr;
193}
194
195static HRESULT inc_ext_ref(HFONT hfont)
196{
197 HFONTItem *item;
198 HRESULT hr = S_FALSE;
199
200 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
201
202 item = find_hfontitem(hfont);
203 if(item)
204 {
205 item->total_refs++;
206 hr = S_OK;
207 }
208 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
209
210 return hr;
211}
212
213static HRESULT dec_ext_ref(HFONT hfont)
214{
215 HFONTItem *item;
216 HRESULT hr = S_FALSE;
217
218 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
219
220 item = find_hfontitem(hfont);
221 if(item)
222 {
223 if(--item->total_refs >= 0) hr = S_OK;
224 }
225 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
226
227 return hr;
228}
229
7e42fd8b
HD
230static WCHAR *strdupW(const WCHAR* str)
231{
232 WCHAR *ret;
233 DWORD size = (strlenW(str) + 1) * sizeof(WCHAR);
234
235 ret = HeapAlloc(GetProcessHeap(), 0, size);
236 if(ret)
237 memcpy(ret, str, size);
238 return ret;
239}
240
d58f61c0
FB
241/***********************************************************************
242 * Declaration of the implementation class for the IFont interface
eb5a29b6
FB
243 */
244typedef struct OLEFontImpl OLEFontImpl;
245
246struct OLEFontImpl
247{
248 /*
9a624916 249 * This class supports many interfaces. IUnknown, IFont,
e8d4268a
HD
250 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
251 * The first two are supported by the first vtable, the next two are
252 * supported by the second table and the last two have their own.
eb5a29b6 253 */
1fdece9b
MS
254 IFont IFont_iface;
255 IDispatch IDispatch_iface;
256 IPersistStream IPersistStream_iface;
257 IConnectionPointContainer IConnectionPointContainer_iface;
258 IPersistPropertyBag IPersistPropertyBag_iface;
259 IPersistStreamInit IPersistStreamInit_iface;
eb5a29b6
FB
260 /*
261 * Reference count for that instance of the class.
262 */
fc200d0c 263 LONG ref;
eb5a29b6
FB
264
265 /*
266 * This structure contains the description of the class.
267 */
268 FONTDESC description;
d58f61c0
FB
269
270 /*
271 * Contain the font associated with this object.
272 */
273 HFONT gdiFont;
cf602ca4 274 BOOL dirty;
d58f61c0
FB
275 /*
276 * Size ratio
277 */
8fce9369
AJ
278 LONG cyLogical;
279 LONG cyHimetric;
e8d4268a 280
2ecbfbe5
PS
281 /*
282 * Stash realized height (pixels) from TEXTMETRIC - used in get_Size()
283 */
284 LONG nRealHeight;
285
d49e808b
RS
286 IConnectionPoint *pPropertyNotifyCP;
287 IConnectionPoint *pFontEventsCP;
eb5a29b6
FB
288};
289
290/*
9a624916 291 * Here, I define utility macros to help with the casting of the
eb5a29b6 292 * "this" parameter.
67aa858a 293 * There is a version to accommodate all of the VTables implemented
d58f61c0 294 * by this object.
eb5a29b6 295 */
738e88db 296
1fdece9b
MS
297static inline OLEFontImpl *impl_from_IFont(IFont *iface)
298{
299 return CONTAINING_RECORD(iface, OLEFontImpl, IFont_iface);
300}
301
738e88db
AJ
302static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface )
303{
1fdece9b 304 return CONTAINING_RECORD(iface, OLEFontImpl, IDispatch_iface);
738e88db
AJ
305}
306
307static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface )
308{
1fdece9b 309 return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStream_iface);
738e88db
AJ
310}
311
312static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
313{
1fdece9b 314 return CONTAINING_RECORD(iface, OLEFontImpl, IConnectionPointContainer_iface);
738e88db
AJ
315}
316
317static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface )
318{
1fdece9b 319 return CONTAINING_RECORD(iface, OLEFontImpl, IPersistPropertyBag_iface);
738e88db
AJ
320}
321
322static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface )
323{
1fdece9b 324 return CONTAINING_RECORD(iface, OLEFontImpl, IPersistStreamInit_iface);
738e88db 325}
e8d4268a 326
eb5a29b6
FB
327
328/***********************************************************************
329 * Prototypes for the implementation functions for the IFont
330 * interface
331 */
ac82f20b 332static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc);
eb5a29b6 333static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
a7f87851 334static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
eba47f1d 335
eb5a29b6
FB
336/******************************************************************************
337 * OleCreateFontIndirect [OLEAUT32.420]
338 */
9c92c7de 339HRESULT WINAPI OleCreateFontIndirect(
eb5a29b6
FB
340 LPFONTDESC lpFontDesc,
341 REFIID riid,
9c92c7de 342 LPVOID* ppvObj)
eb5a29b6
FB
343{
344 OLEFontImpl* newFont = 0;
345 HRESULT hr = S_OK;
d9908d2a 346 FONTDESC fd;
eb5a29b6 347
e8d4268a 348 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
eb5a29b6
FB
349 /*
350 * Sanity check
351 */
352 if (ppvObj==0)
353 return E_POINTER;
354
355 *ppvObj = 0;
356
615615b0 357 if (!lpFontDesc) {
0e9c97eb 358 static WCHAR fname[] = { 'S','y','s','t','e','m',0 };
615615b0
MM
359
360 fd.cbSizeofstruct = sizeof(fd);
0e9c97eb 361 fd.lpstrName = fname;
615615b0
MM
362 fd.cySize.s.Lo = 80000;
363 fd.cySize.s.Hi = 0;
364 fd.sWeight = 0;
365 fd.sCharset = 0;
366 fd.fItalic = 0;
367 fd.fUnderline = 0;
368 fd.fStrikethrough = 0;
369 lpFontDesc = &fd;
370 }
e0939a49 371
eb5a29b6
FB
372 /*
373 * Try to construct a new instance of the class.
374 */
375 newFont = OLEFontImpl_Construct(lpFontDesc);
376
377 if (newFont == 0)
378 return E_OUTOFMEMORY;
379
380 /*
381 * Make sure it supports the interface required by the caller.
382 */
1fdece9b 383 hr = IFont_QueryInterface(&newFont->IFont_iface, riid, ppvObj);
eb5a29b6
FB
384
385 /*
386 * Release the reference obtained in the constructor. If
387 * the QueryInterface was unsuccessful, it will free the class.
388 */
1fdece9b 389 IFont_Release(&newFont->IFont_iface);
eb5a29b6
FB
390
391 return hr;
392}
393
394
395/***********************************************************************
396 * Implementation of the OLEFontImpl class.
397 */
398
e8d4268a
HD
399/***********************************************************************
400 * OLEFont_SendNotify (internal)
401 *
402 * Sends notification messages of changed properties to any interested
403 * connections.
404 */
405static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
406{
d49e808b
RS
407 static const WCHAR wszName[] = {'N','a','m','e',0};
408 static const WCHAR wszSize[] = {'S','i','z','e',0};
409 static const WCHAR wszBold[] = {'B','o','l','d',0};
410 static const WCHAR wszItalic[] = {'I','t','a','l','i','c',0};
411 static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0};
412 static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
413 static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0};
414 static const WCHAR wszCharset[] = {'C','h','a','r','s','s','e','t',0};
415 static const LPCWSTR dispid_mapping[] =
416 {
417 wszName,
418 NULL,
419 wszSize,
420 wszBold,
421 wszItalic,
422 wszUnder,
423 wszStrike,
424 wszWeight,
425 wszCharset
426 };
427
e8d4268a
HD
428 IEnumConnections *pEnum;
429 CONNECTDATA CD;
d0372b4e 430 HRESULT hres;
e8d4268a 431
cf602ca4
HD
432 this->dirty = TRUE;
433
d49e808b
RS
434 hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum);
435 if (SUCCEEDED(hres))
436 {
437 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
438 IPropertyNotifySink *sink;
439
440 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
441 IPropertyNotifySink_OnChanged(sink, dispID);
442 IPropertyNotifySink_Release(sink);
443 IUnknown_Release(CD.pUnk);
444 }
445 IEnumConnections_Release(pEnum);
446 }
447
448 hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum);
449 if (SUCCEEDED(hres))
450 {
451 DISPPARAMS dispparams;
452 VARIANTARG vararg;
453
454 VariantInit(&vararg);
455 V_VT(&vararg) = VT_BSTR;
456 V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]);
9a624916 457
d49e808b
RS
458 dispparams.cArgs = 1;
459 dispparams.cNamedArgs = 0;
460 dispparams.rgdispidNamedArgs = NULL;
461 dispparams.rgvarg = &vararg;
e8d4268a 462
d49e808b
RS
463 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
464 IFontEventsDisp *disp;
465
466 IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp);
467 IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL,
468 LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL,
469 NULL, NULL);
470
471 IDispatch_Release(disp);
472 IUnknown_Release(CD.pUnk);
473 }
474 VariantClear(&vararg);
475 IEnumConnections_Release(pEnum);
e8d4268a 476 }
e8d4268a 477}
9a624916 478
eb5a29b6
FB
479/************************************************************************
480 * OLEFontImpl_QueryInterface (IUnknown)
481 *
482 * See Windows documentation for more details on IUnknown methods.
483 */
c42130f0 484static HRESULT WINAPI OLEFontImpl_QueryInterface(
eb5a29b6
FB
485 IFont* iface,
486 REFIID riid,
487 void** ppvObject)
488{
1fdece9b 489 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 490 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
eb5a29b6 491
eb5a29b6 492 *ppvObject = 0;
9a624916 493
eb5a29b6
FB
494 /*
495 * Compare the riid with the interface IDs implemented by this object.
496 */
d0372b4e 497 if (IsEqualGUID(&IID_IUnknown, riid))
a3f8fd71 498 *ppvObject = this;
d0372b4e 499 if (IsEqualGUID(&IID_IFont, riid))
a3f8fd71 500 *ppvObject = this;
d0372b4e 501 if (IsEqualGUID(&IID_IDispatch, riid))
1fdece9b 502 *ppvObject = &this->IDispatch_iface;
d0372b4e 503 if (IsEqualGUID(&IID_IFontDisp, riid))
1fdece9b 504 *ppvObject = &this->IDispatch_iface;
22e7eeb2 505 if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid))
1fdece9b 506 *ppvObject = &this->IPersistStream_iface;
d0372b4e 507 if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
1fdece9b 508 *ppvObject = &this->IConnectionPointContainer_iface;
d0372b4e 509 if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
1fdece9b 510 *ppvObject = &this->IPersistPropertyBag_iface;
d0372b4e 511 if (IsEqualGUID(&IID_IPersistStreamInit, riid))
1fdece9b 512 *ppvObject = &this->IPersistStreamInit_iface;
9a624916 513
eb5a29b6
FB
514 /*
515 * Check that we obtained an interface.
516 */
517 if ((*ppvObject)==0)
d58f61c0 518 {
d0372b4e 519 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
eb5a29b6 520 return E_NOINTERFACE;
d58f61c0 521 }
1fdece9b 522 OLEFontImpl_AddRef(&this->IFont_iface);
9a624916 523 return S_OK;
eb5a29b6 524}
9a624916 525
eb5a29b6
FB
526/************************************************************************
527 * OLEFontImpl_AddRef (IUnknown)
528 *
529 * See Windows documentation for more details on IUnknown methods.
530 */
c42130f0 531static ULONG WINAPI OLEFontImpl_AddRef(
eb5a29b6
FB
532 IFont* iface)
533{
1fdece9b 534 OLEFontImpl *this = impl_from_IFont(iface);
ce66f5d6 535 TRACE("(%p)->(ref=%d)\n", this, this->ref);
36482273 536 return InterlockedIncrement(&this->ref);
eb5a29b6 537}
9a624916 538
eb5a29b6
FB
539/************************************************************************
540 * OLEFontImpl_Release (IUnknown)
541 *
542 * See Windows documentation for more details on IUnknown methods.
543 */
c42130f0 544static ULONG WINAPI OLEFontImpl_Release(
eb5a29b6
FB
545 IFont* iface)
546{
1fdece9b 547 OLEFontImpl *this = impl_from_IFont(iface);
36482273 548 ULONG ret;
ce66f5d6 549 TRACE("(%p)->(ref=%d)\n", this, this->ref);
eb5a29b6 550
4c40b397 551 /* Decrease the reference count for current interface */
36482273 552 ret = InterlockedDecrement(&this->ref);
eb5a29b6 553
4c40b397
RS
554 /* If the reference count goes down to 0, destroy. */
555 if (ret == 0)
556 {
557 ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt);
7aaaf738
HD
558
559 /* Final IFont object so destroy font cache */
4c40b397
RS
560 if (fontlist_refs == 0)
561 {
7aaaf738
HD
562 HFONTItem *item, *cursor2;
563
4c40b397 564 EnterCriticalSection(&OLEFontImpl_csHFONTLIST);
7aaaf738
HD
565 LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry)
566 HFONTItem_Delete(item);
4c40b397 567 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST);
7e42fd8b 568 delete_dc();
4c40b397 569 }
7aaaf738
HD
570 else
571 {
572 dec_int_ref(this->gdiFont);
573 }
4c40b397
RS
574 OLEFontImpl_Destroy(this);
575 }
9a624916 576
36482273 577 return ret;
eb5a29b6 578}
9a624916 579
7e42fd8b
HD
580typedef struct
581{
582 short orig_cs;
583 short avail_cs;
584} enum_data;
585
586static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp)
587{
588 enum_data *data = (enum_data*)lp;
589
590 if(elf->lfCharSet == data->orig_cs)
591 {
592 data->avail_cs = data->orig_cs;
593 return 0;
594 }
595 if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet;
596 return 1;
597}
598
cf602ca4
HD
599static void realize_font(OLEFontImpl *This)
600{
601 if (This->dirty)
602 {
603 LOGFONTW logFont;
604 INT fontHeight;
7e42fd8b
HD
605 WCHAR text_face[LF_FACESIZE];
606 HDC hdc = get_dc();
607 HFONT old_font;
608 TEXTMETRICW tm;
609
610 text_face[0] = 0;
cf602ca4
HD
611
612 if(This->gdiFont)
613 {
7e42fd8b
HD
614 old_font = SelectObject(hdc, This->gdiFont);
615 GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
616 SelectObject(hdc, old_font);
cf602ca4
HD
617 dec_int_ref(This->gdiFont);
618 This->gdiFont = 0;
619 }
620
7e42fd8b
HD
621 memset(&logFont, 0, sizeof(LOGFONTW));
622
623 lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE);
624 logFont.lfCharSet = This->description.sCharset;
625
626 /* If the font name has been changed then enumerate all charsets
627 and pick one that'll result in the font specified being selected */
628 if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName))
629 {
630 enum_data data;
631 data.orig_cs = This->description.sCharset;
632 data.avail_cs = -1;
633 logFont.lfCharSet = DEFAULT_CHARSET;
634 EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0);
635 if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs;
636 }
637
638
cf602ca4
HD
639 /*
640 * The height of the font returned by the get_Size property is the
641 * height of the font in points multiplied by 10000... Using some
642 * simple conversions and the ratio given by the application, it can
643 * be converted to a height in pixels.
7e42fd8b
HD
644 *
645 * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms.
646 * Ratio is applied here relative to the standard.
cf602ca4
HD
647 */
648
cf602ca4
HD
649 fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 );
650
cf602ca4
HD
651
652 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 :
653 (-fontHeight/10000L);
654 logFont.lfItalic = This->description.fItalic;
655 logFont.lfUnderline = This->description.fUnderline;
656 logFont.lfStrikeOut = This->description.fStrikethrough;
657 logFont.lfWeight = This->description.sWeight;
cf602ca4
HD
658 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
659 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
660 logFont.lfQuality = DEFAULT_QUALITY;
661 logFont.lfPitchAndFamily = DEFAULT_PITCH;
cf602ca4
HD
662
663 This->gdiFont = CreateFontIndirectW(&logFont);
664 This->dirty = FALSE;
665
666 add_hfontitem(This->gdiFont);
7e42fd8b
HD
667
668 /* Fixup the name and charset properties so that they match the
669 selected font */
670 old_font = SelectObject(get_dc(), This->gdiFont);
671 GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face);
672 if(lstrcmpiW(text_face, This->description.lpstrName))
673 {
674 HeapFree(GetProcessHeap(), 0, This->description.lpstrName);
675 This->description.lpstrName = strdupW(text_face);
676 }
677 GetTextMetricsW(hdc, &tm);
678 This->description.sCharset = tm.tmCharSet;
2ecbfbe5
PS
679 /* While we have it handy, stash the realized font height for use by get_Size() */
680 This->nRealHeight = tm.tmHeight - tm.tmInternalLeading; /* corresponds to LOGFONT lfHeight */
7e42fd8b 681 SelectObject(hdc, old_font);
cf602ca4
HD
682 }
683}
684
eb5a29b6
FB
685/************************************************************************
686 * OLEFontImpl_get_Name (IFont)
687 *
688 * See Windows documentation for more details on IFont methods.
689 */
a7f87851 690static HRESULT WINAPI OLEFontImpl_get_Name(
9a624916 691 IFont* iface,
a3960292 692 BSTR* pname)
eb5a29b6 693{
1fdece9b 694 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 695 TRACE("(%p)->(%p)\n", this, pname);
eb5a29b6
FB
696 /*
697 * Sanity check.
698 */
699 if (pname==0)
700 return E_POINTER;
701
cf602ca4
HD
702 if(this->dirty) realize_font(this);
703
eb5a29b6 704 if (this->description.lpstrName!=0)
a3960292 705 *pname = SysAllocString(this->description.lpstrName);
eb5a29b6
FB
706 else
707 *pname = 0;
708
709 return S_OK;
710}
711
712/************************************************************************
713 * OLEFontImpl_put_Name (IFont)
714 *
715 * See Windows documentation for more details on IFont methods.
716 */
a7f87851 717static HRESULT WINAPI OLEFontImpl_put_Name(
9a624916 718 IFont* iface,
a3960292 719 BSTR name)
eb5a29b6 720{
1fdece9b 721 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 722 TRACE("(%p)->(%p)\n", this, name);
eb5a29b6 723
571b7a5a
AH
724 if (!name)
725 return CTL_E_INVALIDPROPERTYVALUE;
726
eb5a29b6
FB
727 if (this->description.lpstrName==0)
728 {
729 this->description.lpstrName = HeapAlloc(GetProcessHeap(),
9a624916 730 0,
a3960292 731 (lstrlenW(name)+1) * sizeof(WCHAR));
eb5a29b6
FB
732 }
733 else
734 {
735 this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
9a624916 736 0,
eb5a29b6 737 this->description.lpstrName,
a3960292 738 (lstrlenW(name)+1) * sizeof(WCHAR));
eb5a29b6
FB
739 }
740
741 if (this->description.lpstrName==0)
742 return E_OUTOFMEMORY;
743
c7e7df8b 744 strcpyW(this->description.lpstrName, name);
e8d4268a
HD
745 TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
746 OLEFont_SendNotify(this, DISPID_FONT_NAME);
eb5a29b6
FB
747 return S_OK;
748}
749
750/************************************************************************
751 * OLEFontImpl_get_Size (IFont)
752 *
753 * See Windows documentation for more details on IFont methods.
754 */
a7f87851 755static HRESULT WINAPI OLEFontImpl_get_Size(
9a624916 756 IFont* iface,
eb5a29b6
FB
757 CY* psize)
758{
1fdece9b 759 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 760 TRACE("(%p)->(%p)\n", this, psize);
eb5a29b6
FB
761
762 /*
763 * Sanity check
764 */
765 if (psize==0)
766 return E_POINTER;
767
cf602ca4
HD
768 if(this->dirty) realize_font(this);
769
2ecbfbe5
PS
770 /*
771 * Convert realized font height in pixels to points descaled by current
772 * scaling ratio then scaled up by 10000.
773 */
774 psize->s.Lo = MulDiv(this->nRealHeight,
775 this->cyHimetric * 72 * 10000,
776 this->cyLogical * 2540);
311e456a 777 psize->s.Hi = 0;
eb5a29b6
FB
778
779 return S_OK;
780}
781
782/************************************************************************
783 * OLEFontImpl_put_Size (IFont)
784 *
785 * See Windows documentation for more details on IFont methods.
786 */
a7f87851 787static HRESULT WINAPI OLEFontImpl_put_Size(
9a624916 788 IFont* iface,
eb5a29b6
FB
789 CY size)
790{
1fdece9b 791 OLEFontImpl *this = impl_from_IFont(iface);
ce66f5d6 792 TRACE("(%p)->(%d)\n", this, size.s.Lo);
311e456a 793 this->description.cySize.s.Hi = 0;
e8d4268a
HD
794 this->description.cySize.s.Lo = size.s.Lo;
795 OLEFont_SendNotify(this, DISPID_FONT_SIZE);
eb5a29b6
FB
796
797 return S_OK;
798}
799
800/************************************************************************
801 * OLEFontImpl_get_Bold (IFont)
802 *
803 * See Windows documentation for more details on IFont methods.
804 */
a7f87851 805static HRESULT WINAPI OLEFontImpl_get_Bold(
9a624916 806 IFont* iface,
a3960292 807 BOOL* pbold)
eb5a29b6 808{
1fdece9b 809 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a
HD
810 TRACE("(%p)->(%p)\n", this, pbold);
811 /*
812 * Sanity check
813 */
814 if (pbold==0)
815 return E_POINTER;
816
cf602ca4
HD
817 if(this->dirty) realize_font(this);
818
e8d4268a
HD
819 *pbold = this->description.sWeight > 550;
820
821 return S_OK;
eb5a29b6
FB
822}
823
824/************************************************************************
825 * OLEFontImpl_put_Bold (IFont)
826 *
827 * See Windows documentation for more details on IFont methods.
828 */
a7f87851 829static HRESULT WINAPI OLEFontImpl_put_Bold(
eb5a29b6 830 IFont* iface,
a3960292 831 BOOL bold)
eb5a29b6 832{
1fdece9b 833 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a
HD
834 TRACE("(%p)->(%d)\n", this, bold);
835 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
836 OLEFont_SendNotify(this, DISPID_FONT_BOLD);
837
838 return S_OK;
eb5a29b6
FB
839}
840
841/************************************************************************
842 * OLEFontImpl_get_Italic (IFont)
843 *
844 * See Windows documentation for more details on IFont methods.
845 */
a7f87851 846static HRESULT WINAPI OLEFontImpl_get_Italic(
9a624916 847 IFont* iface,
a3960292 848 BOOL* pitalic)
eb5a29b6 849{
1fdece9b 850 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 851 TRACE("(%p)->(%p)\n", this, pitalic);
eb5a29b6
FB
852 /*
853 * Sanity check
854 */
855 if (pitalic==0)
856 return E_POINTER;
857
cf602ca4
HD
858 if(this->dirty) realize_font(this);
859
eb5a29b6
FB
860 *pitalic = this->description.fItalic;
861
862 return S_OK;
863}
864
865/************************************************************************
866 * OLEFontImpl_put_Italic (IFont)
867 *
868 * See Windows documentation for more details on IFont methods.
869 */
a7f87851 870static HRESULT WINAPI OLEFontImpl_put_Italic(
9a624916 871 IFont* iface,
a3960292 872 BOOL italic)
eb5a29b6 873{
1fdece9b 874 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 875 TRACE("(%p)->(%d)\n", this, italic);
eb5a29b6
FB
876
877 this->description.fItalic = italic;
878
e8d4268a 879 OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
eb5a29b6
FB
880 return S_OK;
881}
882
883/************************************************************************
884 * OLEFontImpl_get_Underline (IFont)
885 *
886 * See Windows documentation for more details on IFont methods.
887 */
a7f87851 888static HRESULT WINAPI OLEFontImpl_get_Underline(
9a624916 889 IFont* iface,
a3960292 890 BOOL* punderline)
eb5a29b6 891{
1fdece9b 892 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 893 TRACE("(%p)->(%p)\n", this, punderline);
eb5a29b6
FB
894
895 /*
896 * Sanity check
897 */
898 if (punderline==0)
899 return E_POINTER;
900
cf602ca4
HD
901 if(this->dirty) realize_font(this);
902
eb5a29b6
FB
903 *punderline = this->description.fUnderline;
904
905 return S_OK;
906}
907
908/************************************************************************
909 * OLEFontImpl_put_Underline (IFont)
910 *
911 * See Windows documentation for more details on IFont methods.
912 */
a7f87851 913static HRESULT WINAPI OLEFontImpl_put_Underline(
eb5a29b6 914 IFont* iface,
a3960292 915 BOOL underline)
eb5a29b6 916{
1fdece9b 917 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 918 TRACE("(%p)->(%d)\n", this, underline);
eb5a29b6
FB
919
920 this->description.fUnderline = underline;
921
e8d4268a 922 OLEFont_SendNotify(this, DISPID_FONT_UNDER);
eb5a29b6
FB
923 return S_OK;
924}
925
926/************************************************************************
927 * OLEFontImpl_get_Strikethrough (IFont)
928 *
929 * See Windows documentation for more details on IFont methods.
930 */
a7f87851 931static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
9a624916 932 IFont* iface,
a3960292 933 BOOL* pstrikethrough)
eb5a29b6 934{
1fdece9b 935 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 936 TRACE("(%p)->(%p)\n", this, pstrikethrough);
eb5a29b6
FB
937
938 /*
939 * Sanity check
940 */
941 if (pstrikethrough==0)
942 return E_POINTER;
943
cf602ca4
HD
944 if(this->dirty) realize_font(this);
945
89b21b4c 946 *pstrikethrough = this->description.fStrikethrough;
eb5a29b6
FB
947
948 return S_OK;
949}
950
951/************************************************************************
952 * OLEFontImpl_put_Strikethrough (IFont)
953 *
954 * See Windows documentation for more details on IFont methods.
955 */
a7f87851 956static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
9a624916 957 IFont* iface,
a3960292 958 BOOL strikethrough)
eb5a29b6 959{
1fdece9b 960 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 961 TRACE("(%p)->(%d)\n", this, strikethrough);
eb5a29b6 962
89b21b4c 963 this->description.fStrikethrough = strikethrough;
e8d4268a 964 OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
eb5a29b6
FB
965
966 return S_OK;
967}
968
969/************************************************************************
970 * OLEFontImpl_get_Weight (IFont)
971 *
972 * See Windows documentation for more details on IFont methods.
973 */
a7f87851 974static HRESULT WINAPI OLEFontImpl_get_Weight(
9a624916 975 IFont* iface,
eb5a29b6
FB
976 short* pweight)
977{
1fdece9b 978 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 979 TRACE("(%p)->(%p)\n", this, pweight);
eb5a29b6
FB
980
981 /*
982 * Sanity check
983 */
984 if (pweight==0)
985 return E_POINTER;
986
cf602ca4
HD
987 if(this->dirty) realize_font(this);
988
eb5a29b6
FB
989 *pweight = this->description.sWeight;
990
991 return S_OK;
992}
993
994/************************************************************************
995 * OLEFontImpl_put_Weight (IFont)
996 *
997 * See Windows documentation for more details on IFont methods.
998 */
a7f87851 999static HRESULT WINAPI OLEFontImpl_put_Weight(
9a624916 1000 IFont* iface,
eb5a29b6
FB
1001 short weight)
1002{
1fdece9b 1003 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 1004 TRACE("(%p)->(%d)\n", this, weight);
eb5a29b6
FB
1005
1006 this->description.sWeight = weight;
1007
e8d4268a 1008 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
eb5a29b6
FB
1009 return S_OK;
1010}
1011
1012/************************************************************************
1013 * OLEFontImpl_get_Charset (IFont)
1014 *
1015 * See Windows documentation for more details on IFont methods.
1016 */
a7f87851 1017static HRESULT WINAPI OLEFontImpl_get_Charset(
9a624916 1018 IFont* iface,
eb5a29b6
FB
1019 short* pcharset)
1020{
1fdece9b 1021 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 1022 TRACE("(%p)->(%p)\n", this, pcharset);
eb5a29b6
FB
1023
1024 /*
1025 * Sanity check
1026 */
1027 if (pcharset==0)
1028 return E_POINTER;
1029
cf602ca4
HD
1030 if(this->dirty) realize_font(this);
1031
eb5a29b6
FB
1032 *pcharset = this->description.sCharset;
1033
1034 return S_OK;
1035}
1036
1037/************************************************************************
1038 * OLEFontImpl_put_Charset (IFont)
1039 *
1040 * See Windows documentation for more details on IFont methods.
1041 */
a7f87851 1042static HRESULT WINAPI OLEFontImpl_put_Charset(
9a624916 1043 IFont* iface,
eb5a29b6
FB
1044 short charset)
1045{
1fdece9b 1046 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 1047 TRACE("(%p)->(%d)\n", this, charset);
eb5a29b6
FB
1048
1049 this->description.sCharset = charset;
e8d4268a 1050 OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
eb5a29b6
FB
1051
1052 return S_OK;
1053}
1054
1055/************************************************************************
1056 * OLEFontImpl_get_hFont (IFont)
1057 *
1058 * See Windows documentation for more details on IFont methods.
1059 */
a7f87851 1060static HRESULT WINAPI OLEFontImpl_get_hFont(
eb5a29b6 1061 IFont* iface,
a3960292 1062 HFONT* phfont)
eb5a29b6 1063{
1fdece9b 1064 OLEFontImpl *this = impl_from_IFont(iface);
e8d4268a 1065 TRACE("(%p)->(%p)\n", this, phfont);
d58f61c0
FB
1066 if (phfont==NULL)
1067 return E_POINTER;
1068
cf602ca4 1069 if(this->dirty) realize_font(this);
d58f61c0
FB
1070
1071 *phfont = this->gdiFont;
9faec8a8 1072 TRACE("Returning %p\n", *phfont);
d58f61c0 1073 return S_OK;
eb5a29b6
FB
1074}
1075
1076/************************************************************************
1077 * OLEFontImpl_Clone (IFont)
1078 *
1079 * See Windows documentation for more details on IFont methods.
1080 */
a7f87851 1081static HRESULT WINAPI OLEFontImpl_Clone(
eb5a29b6
FB
1082 IFont* iface,
1083 IFont** ppfont)
1084{
d58f61c0 1085 OLEFontImpl* newObject = 0;
1fdece9b 1086 OLEFontImpl *this = impl_from_IFont(iface);
7aaaf738 1087
e8d4268a 1088 TRACE("(%p)->(%p)\n", this, ppfont);
d58f61c0
FB
1089
1090 if (ppfont == NULL)
1091 return E_POINTER;
1092
1093 *ppfont = NULL;
1094
1095 /*
1096 * Allocate space for the object.
1097 */
1098 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
1099
1100 if (newObject==NULL)
1101 return E_OUTOFMEMORY;
1102
1103 *newObject = *this;
1104
872097cc
MM
1105 /* We need to alloc new memory for the string, otherwise
1106 * we free memory twice.
d58f61c0 1107 */
872097cc
MM
1108 newObject->description.lpstrName = HeapAlloc(
1109 GetProcessHeap(),0,
1110 (1+strlenW(this->description.lpstrName))*2
1111 );
99b33074 1112 strcpyW(newObject->description.lpstrName, this->description.lpstrName);
872097cc 1113
872097cc 1114
7aaaf738
HD
1115 /* Increment internal ref in hfont item list */
1116 if(newObject->gdiFont) inc_int_ref(newObject->gdiFont);
872097cc 1117
4c40b397 1118 InterlockedIncrement(&ifont_cnt);
4c40b397 1119
7fbca4c1
RS
1120 /* create new connection points */
1121 newObject->pPropertyNotifyCP = NULL;
1122 newObject->pFontEventsCP = NULL;
1123 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
1124 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
1125
1126 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
1127 {
1128 OLEFontImpl_Destroy(newObject);
1129 return E_OUTOFMEMORY;
1130 }
872097cc
MM
1131
1132 /* The cloned object starts with a reference count of 1 */
d58f61c0
FB
1133 newObject->ref = 1;
1134
1fdece9b 1135 *ppfont = &newObject->IFont_iface;
d58f61c0
FB
1136
1137 return S_OK;
eb5a29b6
FB
1138}
1139
1140/************************************************************************
1141 * OLEFontImpl_IsEqual (IFont)
1142 *
1143 * See Windows documentation for more details on IFont methods.
1144 */
a7f87851 1145static HRESULT WINAPI OLEFontImpl_IsEqual(
9a624916 1146 IFont* iface,
eb5a29b6
FB
1147 IFont* pFontOther)
1148{
1fdece9b
MS
1149 OLEFontImpl *left = impl_from_IFont(iface);
1150 OLEFontImpl *right = impl_from_IFont(pFontOther);
ab8302d8 1151 INT ret;
be37e951
BA
1152 INT left_len,right_len;
1153
71a3fe3c 1154 if(pFontOther == NULL)
be37e951
BA
1155 return E_POINTER;
1156 else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo)
1157 return S_FALSE;
1158 else if (left->description.cySize.s.Hi != right->description.cySize.s.Hi)
1159 return S_FALSE;
1160 else if (left->description.sWeight != right->description.sWeight)
1161 return S_FALSE;
1162 else if (left->description.sCharset != right->description.sCharset)
1163 return S_FALSE;
1164 else if (left->description.fItalic != right->description.fItalic)
1165 return S_FALSE;
1166 else if (left->description.fUnderline != right->description.fUnderline)
1167 return S_FALSE;
1168 else if (left->description.fStrikethrough != right->description.fStrikethrough)
1169 return S_FALSE;
1170
1171 /* Check from string */
1172 left_len = strlenW(left->description.lpstrName);
1173 right_len = strlenW(right->description.lpstrName);
ab8302d8 1174 ret = CompareStringW(0,0,left->description.lpstrName, left_len,
be37e951 1175 right->description.lpstrName, right_len);
ab8302d8 1176 if (ret != CSTR_EQUAL)
be37e951
BA
1177 return S_FALSE;
1178
1179 return S_OK;
eb5a29b6
FB
1180}
1181
1182/************************************************************************
1183 * OLEFontImpl_SetRatio (IFont)
1184 *
1185 * See Windows documentation for more details on IFont methods.
1186 */
a7f87851 1187static HRESULT WINAPI OLEFontImpl_SetRatio(
eb5a29b6 1188 IFont* iface,
4eeae1ad
VB
1189 LONG cyLogical,
1190 LONG cyHimetric)
eb5a29b6 1191{
1fdece9b 1192 OLEFontImpl *this = impl_from_IFont(iface);
ce66f5d6 1193 TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric);
d58f61c0 1194
2ecbfbe5
PS
1195 if(cyLogical == 0 || cyHimetric == 0)
1196 return E_INVALIDARG;
1197
d58f61c0
FB
1198 this->cyLogical = cyLogical;
1199 this->cyHimetric = cyHimetric;
2ecbfbe5 1200 this->dirty = TRUE;
d58f61c0
FB
1201
1202 return S_OK;
eb5a29b6
FB
1203}
1204
1205/************************************************************************
1206 * OLEFontImpl_QueryTextMetrics (IFont)
1207 *
1208 * See Windows documentation for more details on IFont methods.
1209 */
a7f87851 1210static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
9a624916 1211 IFont* iface,
eb5a29b6
FB
1212 TEXTMETRICOLE* ptm)
1213{
c2292eef
AVL
1214 HDC hdcRef;
1215 HFONT hOldFont, hNewFont;
1216
1217 hdcRef = GetDC(0);
1218 OLEFontImpl_get_hFont(iface, &hNewFont);
1219 hOldFont = SelectObject(hdcRef, hNewFont);
1220 GetTextMetricsW(hdcRef, ptm);
1221 SelectObject(hdcRef, hOldFont);
1222 ReleaseDC(0, hdcRef);
1223 return S_OK;
eb5a29b6
FB
1224}
1225
1226/************************************************************************
1227 * OLEFontImpl_AddRefHfont (IFont)
1228 *
1229 * See Windows documentation for more details on IFont methods.
1230 */
a7f87851 1231static HRESULT WINAPI OLEFontImpl_AddRefHfont(
9a624916 1232 IFont* iface,
a3960292 1233 HFONT hfont)
eb5a29b6 1234{
1fdece9b 1235 OLEFontImpl *this = impl_from_IFont(iface);
d58f61c0 1236
7aaaf738 1237 TRACE("(%p)->(%p)\n", this, hfont);
4c40b397 1238
7aaaf738 1239 if (!hfont) return E_INVALIDARG;
d58f61c0 1240
7aaaf738 1241 return inc_ext_ref(hfont);
eb5a29b6
FB
1242}
1243
1244/************************************************************************
1245 * OLEFontImpl_ReleaseHfont (IFont)
1246 *
1247 * See Windows documentation for more details on IFont methods.
1248 */
a7f87851 1249static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
eb5a29b6 1250 IFont* iface,
a3960292 1251 HFONT hfont)
eb5a29b6 1252{
1fdece9b 1253 OLEFontImpl *this = impl_from_IFont(iface);
d58f61c0 1254
7aaaf738 1255 TRACE("(%p)->(%p)\n", this, hfont);
d58f61c0 1256
7aaaf738 1257 if (!hfont) return E_INVALIDARG;
d58f61c0 1258
7aaaf738 1259 return dec_ext_ref(hfont);
eb5a29b6
FB
1260}
1261
1262/************************************************************************
1263 * OLEFontImpl_SetHdc (IFont)
1264 *
1265 * See Windows documentation for more details on IFont methods.
1266 */
a7f87851 1267static HRESULT WINAPI OLEFontImpl_SetHdc(
eb5a29b6 1268 IFont* iface,
a3960292 1269 HDC hdc)
eb5a29b6 1270{
1fdece9b 1271 OLEFontImpl *this = impl_from_IFont(iface);
9faec8a8 1272 FIXME("(%p)->(%p): Stub\n", this, hdc);
eb5a29b6
FB
1273 return E_NOTIMPL;
1274}
1275
e79b8b8f
RS
1276/*
1277 * Virtual function tables for the OLEFontImpl class.
1278 */
1279static const IFontVtbl OLEFontImpl_VTable =
1280{
1281 OLEFontImpl_QueryInterface,
1282 OLEFontImpl_AddRef,
1283 OLEFontImpl_Release,
1284 OLEFontImpl_get_Name,
1285 OLEFontImpl_put_Name,
1286 OLEFontImpl_get_Size,
1287 OLEFontImpl_put_Size,
1288 OLEFontImpl_get_Bold,
1289 OLEFontImpl_put_Bold,
1290 OLEFontImpl_get_Italic,
1291 OLEFontImpl_put_Italic,
1292 OLEFontImpl_get_Underline,
1293 OLEFontImpl_put_Underline,
1294 OLEFontImpl_get_Strikethrough,
1295 OLEFontImpl_put_Strikethrough,
1296 OLEFontImpl_get_Weight,
1297 OLEFontImpl_put_Weight,
1298 OLEFontImpl_get_Charset,
1299 OLEFontImpl_put_Charset,
1300 OLEFontImpl_get_hFont,
1301 OLEFontImpl_Clone,
1302 OLEFontImpl_IsEqual,
1303 OLEFontImpl_SetRatio,
1304 OLEFontImpl_QueryTextMetrics,
1305 OLEFontImpl_AddRefHfont,
1306 OLEFontImpl_ReleaseHfont,
1307 OLEFontImpl_SetHdc
1308};
1309
eb5a29b6
FB
1310/************************************************************************
1311 * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
1312 *
1313 * See Windows documentation for more details on IUnknown methods.
1314 */
a7f87851 1315static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
eb5a29b6
FB
1316 IDispatch* iface,
1317 REFIID riid,
1318 VOID** ppvoid)
1319{
738e88db 1320 OLEFontImpl *this = impl_from_IDispatch(iface);
eb5a29b6 1321
1fdece9b 1322 return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
eb5a29b6
FB
1323}
1324
1325/************************************************************************
1326 * OLEFontImpl_IDispatch_Release (IUnknown)
1327 *
1328 * See Windows documentation for more details on IUnknown methods.
1329 */
a7f87851 1330static ULONG WINAPI OLEFontImpl_IDispatch_Release(
eb5a29b6
FB
1331 IDispatch* iface)
1332{
738e88db 1333 OLEFontImpl *this = impl_from_IDispatch(iface);
eb5a29b6 1334
1fdece9b 1335 return IFont_Release(&this->IFont_iface);
eb5a29b6
FB
1336}
1337
1338/************************************************************************
1339 * OLEFontImpl_IDispatch_AddRef (IUnknown)
1340 *
1341 * See Windows documentation for more details on IUnknown methods.
1342 */
a7f87851 1343static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
eb5a29b6
FB
1344 IDispatch* iface)
1345{
738e88db 1346 OLEFontImpl *this = impl_from_IDispatch(iface);
eb5a29b6 1347
1fdece9b 1348 return IFont_AddRef(&this->IFont_iface);
eb5a29b6
FB
1349}
1350
1351/************************************************************************
1352 * OLEFontImpl_GetTypeInfoCount (IDispatch)
1353 *
1354 * See Windows documentation for more details on IDispatch methods.
1355 */
a7f87851 1356static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
9a624916 1357 IDispatch* iface,
eb5a29b6
FB
1358 unsigned int* pctinfo)
1359{
738e88db 1360 OLEFontImpl *this = impl_from_IDispatch(iface);
34355603
RS
1361 TRACE("(%p)->(%p)\n", this, pctinfo);
1362 *pctinfo = 1;
eb5a29b6 1363
34355603 1364 return S_OK;
eb5a29b6
FB
1365}
1366
1367/************************************************************************
1368 * OLEFontImpl_GetTypeInfo (IDispatch)
1369 *
1370 * See Windows documentation for more details on IDispatch methods.
1371 */
a7f87851 1372static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
9a624916 1373 IDispatch* iface,
a3960292 1374 UINT iTInfo,
9a624916 1375 LCID lcid,
eb5a29b6
FB
1376 ITypeInfo** ppTInfo)
1377{
d765cb96 1378 static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0};
d0372b4e
MM
1379 ITypeLib *tl;
1380 HRESULT hres;
eb5a29b6 1381
738e88db 1382 OLEFontImpl *this = impl_from_IDispatch(iface);
45eba514 1383 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);
d0372b4e
MM
1384 if (iTInfo != 0)
1385 return E_FAIL;
d765cb96 1386 hres = LoadTypeLib(stdole2tlb, &tl);
d0372b4e 1387 if (FAILED(hres)) {
d765cb96 1388 ERR("Could not load the stdole2.tlb?\n");
d0372b4e
MM
1389 return hres;
1390 }
d765cb96 1391 hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IFontDisp, ppTInfo);
05f75b9f 1392 ITypeLib_Release(tl);
d0372b4e 1393 if (FAILED(hres)) {
ce66f5d6 1394 FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres);
d0372b4e
MM
1395 }
1396 return hres;
eb5a29b6
FB
1397}
1398
1399/************************************************************************
1400 * OLEFontImpl_GetIDsOfNames (IDispatch)
1401 *
1402 * See Windows documentation for more details on IDispatch methods.
1403 */
a7f87851 1404static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
eb5a29b6 1405 IDispatch* iface,
9a624916
VB
1406 REFIID riid,
1407 LPOLESTR* rgszNames,
1408 UINT cNames,
eb5a29b6
FB
1409 LCID lcid,
1410 DISPID* rgDispId)
1411{
f75b9f19
BA
1412 ITypeInfo * pTInfo;
1413 HRESULT hres;
1414
738e88db 1415 OLEFontImpl *this = impl_from_IDispatch(iface);
f75b9f19
BA
1416
1417 TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid),
1418 rgszNames, cNames, (int)lcid, rgDispId);
1419
1420 if (cNames == 0)
1421 {
1422 return E_INVALIDARG;
1423 }
1424 else
1425 {
1426 /* retrieve type information */
1427 hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo);
1428
1429 if (FAILED(hres))
1430 {
1431 ERR("GetTypeInfo failed.\n");
1432 return hres;
1433 }
1434
1435 /* convert names to DISPIDs */
1436 hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId);
1437 ITypeInfo_Release(pTInfo);
1438
1439 return hres;
1440 }
eb5a29b6
FB
1441}
1442
1443/************************************************************************
1444 * OLEFontImpl_Invoke (IDispatch)
1445 *
1446 * See Windows documentation for more details on IDispatch methods.
d0372b4e
MM
1447 *
1448 * Note: Do not call _put_Xxx methods, since setting things here
1449 * should not call notify functions as I found out debugging the generic
1450 * MS VB5 installer.
eb5a29b6 1451 */
a7f87851 1452static HRESULT WINAPI OLEFontImpl_Invoke(
eb5a29b6 1453 IDispatch* iface,
9a624916
VB
1454 DISPID dispIdMember,
1455 REFIID riid,
1456 LCID lcid,
eb5a29b6
FB
1457 WORD wFlags,
1458 DISPPARAMS* pDispParams,
9a624916 1459 VARIANT* pVarResult,
eb5a29b6 1460 EXCEPINFO* pExepInfo,
a3960292 1461 UINT* puArgErr)
eb5a29b6 1462{
738e88db 1463 OLEFontImpl *this = impl_from_IDispatch(iface);
207ec43e 1464 HRESULT hr;
d0372b4e 1465
ce66f5d6 1466 TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember,
18732f85
RS
1467 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExepInfo,
1468 puArgErr);
1469
bbdcccd3
RS
1470 /* validate parameters */
1471
1472 if (!IsEqualIID(riid, &IID_NULL))
1473 {
1474 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid));
1475 return DISP_E_UNKNOWNINTERFACE;
1476 }
1477
1478 if (wFlags & DISPATCH_PROPERTYGET)
1479 {
1480 if (!pVarResult)
1481 {
1482 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n");
1483 return DISP_E_PARAMNOTOPTIONAL;
1484 }
1485 }
1486 else if (wFlags & DISPATCH_PROPERTYPUT)
1487 {
1488 if (!pDispParams)
1489 {
1490 ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n");
1491 return DISP_E_PARAMNOTOPTIONAL;
1492 }
1493 if (pDispParams->cArgs != 1)
1494 {
06fbe601 1495 ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs);
bbdcccd3
RS
1496 return DISP_E_BADPARAMCOUNT;
1497 }
1498 }
1499 else
1500 {
1501 ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n");
1502 return DISP_E_MEMBERNOTFOUND;
1503 }
1504
d0372b4e
MM
1505 switch (dispIdMember) {
1506 case DISPID_FONT_NAME:
207ec43e 1507 if (wFlags & DISPATCH_PROPERTYGET) {
d0372b4e 1508 V_VT(pVarResult) = VT_BSTR;
1fdece9b 1509 return IFont_get_Name(&this->IFont_iface, &V_BSTR(pVarResult));
207ec43e
RS
1510 } else {
1511 VARIANTARG vararg;
1512
1513 VariantInit(&vararg);
1514 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BSTR);
1515 if (FAILED(hr))
1516 return hr;
1517
1fdece9b 1518 hr = IFont_put_Name(&this->IFont_iface, V_BSTR(&vararg));
207ec43e
RS
1519
1520 VariantClear(&vararg);
1521 return hr;
d0372b4e
MM
1522 }
1523 break;
1524 case DISPID_FONT_BOLD:
207ec43e
RS
1525 if (wFlags & DISPATCH_PROPERTYGET) {
1526 BOOL value;
1fdece9b 1527 hr = IFont_get_Bold(&this->IFont_iface, &value);
d0372b4e 1528 V_VT(pVarResult) = VT_BOOL;
207ec43e
RS
1529 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1530 return hr;
1531 } else {
1532 VARIANTARG vararg;
1533
1534 VariantInit(&vararg);
1535 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1536 if (FAILED(hr))
1537 return hr;
1538
1fdece9b 1539 hr = IFont_put_Bold(&this->IFont_iface, V_BOOL(&vararg));
207ec43e
RS
1540
1541 VariantClear(&vararg);
1542 return hr;
d0372b4e
MM
1543 }
1544 break;
1545 case DISPID_FONT_ITALIC:
207ec43e
RS
1546 if (wFlags & DISPATCH_PROPERTYGET) {
1547 BOOL value;
1fdece9b 1548 hr = IFont_get_Italic(&this->IFont_iface, &value);
d0372b4e 1549 V_VT(pVarResult) = VT_BOOL;
207ec43e
RS
1550 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1551 return hr;
1552 } else {
1553 VARIANTARG vararg;
207ec43e
RS
1554
1555 VariantInit(&vararg);
1556 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1557 if (FAILED(hr))
1558 return hr;
1559
1fdece9b 1560 hr = IFont_put_Italic(&this->IFont_iface, V_BOOL(&vararg));
207ec43e
RS
1561
1562 VariantClear(&vararg);
1563 return hr;
d0372b4e
MM
1564 }
1565 break;
1566 case DISPID_FONT_UNDER:
207ec43e
RS
1567 if (wFlags & DISPATCH_PROPERTYGET) {
1568 BOOL value;
1fdece9b 1569 hr = IFont_get_Underline(&this->IFont_iface, &value);
d0372b4e 1570 V_VT(pVarResult) = VT_BOOL;
207ec43e
RS
1571 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1572 return hr;
1573 } else {
1574 VARIANTARG vararg;
207ec43e
RS
1575
1576 VariantInit(&vararg);
1577 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1578 if (FAILED(hr))
1579 return hr;
1580
1fdece9b 1581 hr = IFont_put_Underline(&this->IFont_iface, V_BOOL(&vararg));
207ec43e
RS
1582
1583 VariantClear(&vararg);
1584 return hr;
d0372b4e
MM
1585 }
1586 break;
1587 case DISPID_FONT_STRIKE:
207ec43e
RS
1588 if (wFlags & DISPATCH_PROPERTYGET) {
1589 BOOL value;
1fdece9b 1590 hr = IFont_get_Strikethrough(&this->IFont_iface, &value);
d0372b4e 1591 V_VT(pVarResult) = VT_BOOL;
207ec43e
RS
1592 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE;
1593 return hr;
1594 } else {
1595 VARIANTARG vararg;
207ec43e
RS
1596
1597 VariantInit(&vararg);
1598 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL);
1599 if (FAILED(hr))
1600 return hr;
1601
1fdece9b 1602 hr = IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&vararg));
207ec43e
RS
1603
1604 VariantClear(&vararg);
1605 return hr;
d0372b4e
MM
1606 }
1607 break;
1608 case DISPID_FONT_SIZE:
207ec43e 1609 if (wFlags & DISPATCH_PROPERTYGET) {
d0372b4e 1610 V_VT(pVarResult) = VT_CY;
1fdece9b 1611 return OLEFontImpl_get_Size(&this->IFont_iface, &V_CY(pVarResult));
207ec43e
RS
1612 } else {
1613 VARIANTARG vararg;
207ec43e
RS
1614
1615 VariantInit(&vararg);
1616 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_CY);
1617 if (FAILED(hr))
1618 return hr;
1619
1fdece9b 1620 hr = IFont_put_Size(&this->IFont_iface, V_CY(&vararg));
207ec43e
RS
1621
1622 VariantClear(&vararg);
1623 return hr;
d0372b4e
MM
1624 }
1625 break;
c2afb5cb
RS
1626 case DISPID_FONT_WEIGHT:
1627 if (wFlags & DISPATCH_PROPERTYGET) {
1628 V_VT(pVarResult) = VT_I2;
1fdece9b 1629 return OLEFontImpl_get_Weight(&this->IFont_iface, &V_I2(pVarResult));
c2afb5cb
RS
1630 } else {
1631 VARIANTARG vararg;
c2afb5cb
RS
1632
1633 VariantInit(&vararg);
1634 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1635 if (FAILED(hr))
1636 return hr;
1637
1fdece9b 1638 hr = IFont_put_Weight(&this->IFont_iface, V_I2(&vararg));
c2afb5cb
RS
1639
1640 VariantClear(&vararg);
1641 return hr;
1642 }
1643 break;
d0372b4e 1644 case DISPID_FONT_CHARSET:
207ec43e 1645 if (wFlags & DISPATCH_PROPERTYGET) {
d0372b4e 1646 V_VT(pVarResult) = VT_I2;
1fdece9b 1647 return OLEFontImpl_get_Charset(&this->IFont_iface, &V_I2(pVarResult));
207ec43e
RS
1648 } else {
1649 VARIANTARG vararg;
207ec43e
RS
1650
1651 VariantInit(&vararg);
1652 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2);
1653 if (FAILED(hr))
1654 return hr;
1655
1fdece9b 1656 hr = IFont_put_Charset(&this->IFont_iface, V_I2(&vararg));
207ec43e
RS
1657
1658 VariantClear(&vararg);
1659 return hr;
d0372b4e
MM
1660 }
1661 break;
18732f85 1662 default:
ce66f5d6 1663 ERR("member not found for dispid 0x%x\n", dispIdMember);
18732f85 1664 return DISP_E_MEMBERNOTFOUND;
d0372b4e 1665 }
eb5a29b6
FB
1666}
1667
e79b8b8f
RS
1668static const IDispatchVtbl OLEFontImpl_IDispatch_VTable =
1669{
1670 OLEFontImpl_IDispatch_QueryInterface,
1671 OLEFontImpl_IDispatch_AddRef,
1672 OLEFontImpl_IDispatch_Release,
1673 OLEFontImpl_GetTypeInfoCount,
1674 OLEFontImpl_GetTypeInfo,
1675 OLEFontImpl_GetIDsOfNames,
1676 OLEFontImpl_Invoke
1677};
1678
d58f61c0
FB
1679/************************************************************************
1680 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
1681 *
1682 * See Windows documentation for more details on IUnknown methods.
1683 */
1684static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
1685 IPersistStream* iface,
1686 REFIID riid,
1687 VOID** ppvoid)
1688{
738e88db 1689 OLEFontImpl *this = impl_from_IPersistStream(iface);
d58f61c0 1690
1fdece9b 1691 return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
d58f61c0
FB
1692}
1693
1694/************************************************************************
1695 * OLEFontImpl_IPersistStream_Release (IUnknown)
1696 *
1697 * See Windows documentation for more details on IUnknown methods.
1698 */
1699static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
1700 IPersistStream* iface)
1701{
738e88db 1702 OLEFontImpl *this = impl_from_IPersistStream(iface);
eb5a29b6 1703
1fdece9b 1704 return IFont_Release(&this->IFont_iface);
d58f61c0
FB
1705}
1706
1707/************************************************************************
1708 * OLEFontImpl_IPersistStream_AddRef (IUnknown)
1709 *
1710 * See Windows documentation for more details on IUnknown methods.
1711 */
1712static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
1713 IPersistStream* iface)
1714{
738e88db 1715 OLEFontImpl *this = impl_from_IPersistStream(iface);
d58f61c0 1716
1fdece9b 1717 return IFont_AddRef(&this->IFont_iface);
d58f61c0
FB
1718}
1719
1720/************************************************************************
1721 * OLEFontImpl_GetClassID (IPersistStream)
1722 *
1723 * See Windows documentation for more details on IPersistStream methods.
1724 */
1725static HRESULT WINAPI OLEFontImpl_GetClassID(
9a624916 1726 IPersistStream* iface,
d58f61c0
FB
1727 CLSID* pClassID)
1728{
d0372b4e 1729 TRACE("(%p,%p)\n",iface,pClassID);
d58f61c0
FB
1730 if (pClassID==0)
1731 return E_POINTER;
1732
9d16a422 1733 *pClassID = CLSID_StdFont;
d58f61c0
FB
1734
1735 return S_OK;
1736}
1737
1738/************************************************************************
1739 * OLEFontImpl_IsDirty (IPersistStream)
1740 *
1741 * See Windows documentation for more details on IPersistStream methods.
1742 */
1743static HRESULT WINAPI OLEFontImpl_IsDirty(
1744 IPersistStream* iface)
1745{
d0372b4e 1746 TRACE("(%p)\n",iface);
d58f61c0
FB
1747 return S_OK;
1748}
1749
1750/************************************************************************
1751 * OLEFontImpl_Load (IPersistStream)
1752 *
1753 * See Windows documentation for more details on IPersistStream methods.
1754 *
1755 * This is the format of the standard font serialization as far as I
1756 * know
1757 *
1758 * Offset Type Value Comment
1759 * 0x0000 Byte Unknown Probably a version number, contains 0x01
1760 * 0x0001 Short Charset Charset value from the FONTDESC structure
1761 * 0x0003 Byte Attributes Flags defined as follows:
1762 * 00000010 - Italic
1763 * 00000100 - Underline
1764 * 00001000 - Strikethrough
1765 * 0x0004 Short Weight Weight value from FONTDESC structure
1766 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
1767 * structure/
1768 * 0x000A Byte name length Length of the font name string (no null character)
1769 * 0x000B String name Name of the font (ASCII, no nul character)
1770 */
1771static HRESULT WINAPI OLEFontImpl_Load(
1772 IPersistStream* iface,
1773 IStream* pLoadStream)
1774{
1775 char readBuffer[0x100];
1776 ULONG cbRead;
1777 BYTE bVersion;
1778 BYTE bAttributes;
1779 BYTE bStringSize;
193cf50a 1780 INT len;
d58f61c0 1781
738e88db 1782 OLEFontImpl *this = impl_from_IPersistStream(iface);
9a624916 1783
d58f61c0
FB
1784 /*
1785 * Read the version byte
1786 */
1787 IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
1788
1789 if ( (cbRead!=1) ||
1790 (bVersion!=0x01) )
1791 return E_FAIL;
1792
1793 /*
1794 * Charset
1795 */
1796 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
1797
1798 if (cbRead!=2)
1799 return E_FAIL;
1800
1801 /*
1802 * Attributes
1803 */
1804 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
1805
1806 if (cbRead!=1)
1807 return E_FAIL;
1808
1809 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
89b21b4c 1810 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
d58f61c0 1811 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
9a624916 1812
d58f61c0
FB
1813 /*
1814 * Weight
1815 */
1816 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
1817
1818 if (cbRead!=2)
1819 return E_FAIL;
1820
1821 /*
1822 * Size
1823 */
311e456a 1824 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
d58f61c0
FB
1825
1826 if (cbRead!=4)
1827 return E_FAIL;
1828
311e456a 1829 this->description.cySize.s.Hi = 0;
d58f61c0
FB
1830
1831 /*
1832 * FontName
1833 */
1834 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
1835
1836 if (cbRead!=1)
1837 return E_FAIL;
1838
d58f61c0
FB
1839 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
1840
1841 if (cbRead!=bStringSize)
1842 return E_FAIL;
1843
5ad7d858 1844 HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
d58f61c0 1845
193cf50a
AJ
1846 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
1847 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
1848 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
1849 this->description.lpstrName[len] = 0;
d58f61c0 1850
9d6a10a4 1851 /* Ensure use of this font causes a new one to be created */
7aaaf738 1852 dec_int_ref(this->gdiFont);
99b33074 1853 this->gdiFont = 0;
9d6a10a4 1854 this->dirty = TRUE;
99b33074 1855
d58f61c0
FB
1856 return S_OK;
1857}
1858
1859/************************************************************************
1860 * OLEFontImpl_Save (IPersistStream)
1861 *
1862 * See Windows documentation for more details on IPersistStream methods.
1863 */
1864static HRESULT WINAPI OLEFontImpl_Save(
1865 IPersistStream* iface,
1866 IStream* pOutStream,
1867 BOOL fClearDirty)
1868{
1869 char* writeBuffer = NULL;
1870 ULONG cbWritten;
1871 BYTE bVersion = 0x01;
1872 BYTE bAttributes;
1873 BYTE bStringSize;
9a624916 1874
738e88db 1875 OLEFontImpl *this = impl_from_IPersistStream(iface);
d58f61c0
FB
1876
1877 /*
1878 * Read the version byte
1879 */
1880 IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
1881
1882 if (cbWritten!=1)
1883 return E_FAIL;
1884
1885 /*
1886 * Charset
1887 */
1888 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
1889
1890 if (cbWritten!=2)
1891 return E_FAIL;
1892
1893 /*
1894 * Attributes
1895 */
1896 bAttributes = 0;
1897
1898 if (this->description.fItalic)
1899 bAttributes |= FONTPERSIST_ITALIC;
1900
89b21b4c 1901 if (this->description.fStrikethrough)
d58f61c0 1902 bAttributes |= FONTPERSIST_STRIKETHROUGH;
9a624916 1903
d58f61c0
FB
1904 if (this->description.fUnderline)
1905 bAttributes |= FONTPERSIST_UNDERLINE;
1906
1907 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
1908
1909 if (cbWritten!=1)
1910 return E_FAIL;
9a624916 1911
d58f61c0
FB
1912 /*
1913 * Weight
1914 */
1915 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
1916
1917 if (cbWritten!=2)
1918 return E_FAIL;
1919
1920 /*
1921 * Size
1922 */
311e456a 1923 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
d58f61c0
FB
1924
1925 if (cbWritten!=4)
1926 return E_FAIL;
1927
1928 /*
1929 * FontName
1930 */
1931 if (this->description.lpstrName!=0)
193cf50a
AJ
1932 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1933 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
d58f61c0
FB
1934 else
1935 bStringSize = 0;
1936
1937 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
1938
1939 if (cbWritten!=1)
1940 return E_FAIL;
1941
1942 if (bStringSize!=0)
1943 {
193cf50a
AJ
1944 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
1945 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1946 strlenW(this->description.lpstrName),
1947 writeBuffer, bStringSize, NULL, NULL );
d58f61c0
FB
1948
1949 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
d58f61c0
FB
1950 HeapFree(GetProcessHeap(), 0, writeBuffer);
1951
1952 if (cbWritten!=bStringSize)
1953 return E_FAIL;
1954 }
1955
1956 return S_OK;
1957}
1958
1959/************************************************************************
1960 * OLEFontImpl_GetSizeMax (IPersistStream)
1961 *
1962 * See Windows documentation for more details on IPersistStream methods.
1963 */
1964static HRESULT WINAPI OLEFontImpl_GetSizeMax(
1965 IPersistStream* iface,
1966 ULARGE_INTEGER* pcbSize)
1967{
738e88db 1968 OLEFontImpl *this = impl_from_IPersistStream(iface);
d58f61c0
FB
1969
1970 if (pcbSize==NULL)
1971 return E_POINTER;
1972
399901e0
GG
1973 pcbSize->u.HighPart = 0;
1974 pcbSize->u.LowPart = 0;
d58f61c0 1975
399901e0
GG
1976 pcbSize->u.LowPart += sizeof(BYTE); /* Version */
1977 pcbSize->u.LowPart += sizeof(WORD); /* Lang code */
1978 pcbSize->u.LowPart += sizeof(BYTE); /* Flags */
1979 pcbSize->u.LowPart += sizeof(WORD); /* Weight */
1980 pcbSize->u.LowPart += sizeof(DWORD); /* Size */
1981 pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */
d58f61c0
FB
1982
1983 if (this->description.lpstrName!=0)
e2359813
RS
1984 pcbSize->u.LowPart += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
1985 strlenW(this->description.lpstrName),
1986 NULL, 0, NULL, NULL );
d58f61c0
FB
1987
1988 return S_OK;
1989}
e8d4268a 1990
e79b8b8f
RS
1991static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =
1992{
1993 OLEFontImpl_IPersistStream_QueryInterface,
1994 OLEFontImpl_IPersistStream_AddRef,
1995 OLEFontImpl_IPersistStream_Release,
1996 OLEFontImpl_GetClassID,
1997 OLEFontImpl_IsDirty,
1998 OLEFontImpl_Load,
1999 OLEFontImpl_Save,
2000 OLEFontImpl_GetSizeMax
2001};
2002
e8d4268a
HD
2003/************************************************************************
2004 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
2005 *
2006 * See Windows documentation for more details on IUnknown methods.
2007 */
2008static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
2009 IConnectionPointContainer* iface,
2010 REFIID riid,
2011 VOID** ppvoid)
2012{
738e88db 2013 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
e8d4268a 2014
1fdece9b 2015 return IFont_QueryInterface(&this->IFont_iface, riid, ppvoid);
e8d4268a
HD
2016}
2017
2018/************************************************************************
2019 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
2020 *
2021 * See Windows documentation for more details on IUnknown methods.
2022 */
2023static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
2024 IConnectionPointContainer* iface)
2025{
738e88db 2026 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
e8d4268a 2027
1fdece9b 2028 return IFont_Release(&this->IFont_iface);
e8d4268a
HD
2029}
2030
2031/************************************************************************
2032 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
2033 *
2034 * See Windows documentation for more details on IUnknown methods.
2035 */
2036static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
2037 IConnectionPointContainer* iface)
2038{
738e88db 2039 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
e8d4268a 2040
1fdece9b 2041 return IFont_AddRef(&this->IFont_iface);
e8d4268a
HD
2042}
2043
2044/************************************************************************
2045 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
2046 *
2047 * See Windows documentation for more details on IConnectionPointContainer
2048 * methods.
2049 */
2050static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
2051 IConnectionPointContainer* iface,
2052 IEnumConnectionPoints **ppEnum)
2053{
738e88db 2054 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
e8d4268a
HD
2055
2056 FIXME("(%p)->(%p): stub\n", this, ppEnum);
2057 return E_NOTIMPL;
2058}
2059
2060/************************************************************************
2061 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
2062 *
2063 * See Windows documentation for more details on IConnectionPointContainer
2064 * methods.
2065 */
2066static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
2067 IConnectionPointContainer* iface,
2068 REFIID riid,
2069 IConnectionPoint **ppCp)
2070{
738e88db 2071 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface);
3dade1e7 2072 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp);
e8d4268a 2073
d49e808b
RS
2074 if(IsEqualIID(riid, &IID_IPropertyNotifySink)) {
2075 return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP,
2076 &IID_IConnectionPoint,
2077 (LPVOID)ppCp);
2078 } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) {
2079 return IConnectionPoint_QueryInterface(this->pFontEventsCP,
2080 &IID_IConnectionPoint,
2081 (LPVOID)ppCp);
e8d4268a 2082 } else {
98fd1c56
RS
2083 FIXME("no connection point for %s\n", debugstr_guid(riid));
2084 return CONNECT_E_NOCONNECTION;
e8d4268a
HD
2085 }
2086}
2087
e79b8b8f
RS
2088static const IConnectionPointContainerVtbl
2089 OLEFontImpl_IConnectionPointContainer_VTable =
2090{
2091 OLEFontImpl_IConnectionPointContainer_QueryInterface,
2092 OLEFontImpl_IConnectionPointContainer_AddRef,
2093 OLEFontImpl_IConnectionPointContainer_Release,
2094 OLEFontImpl_EnumConnectionPoints,
2095 OLEFontImpl_FindConnectionPoint
2096};
2097
d0372b4e
MM
2098/************************************************************************
2099 * OLEFontImpl implementation of IPersistPropertyBag.
2100 */
2101static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
2102 IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
2103) {
738e88db 2104 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1fdece9b 2105 return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj);
d0372b4e
MM
2106}
2107
2108static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
2109 IPersistPropertyBag *iface
2110) {
738e88db 2111 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1fdece9b 2112 return IFont_AddRef(&this->IFont_iface);
d0372b4e
MM
2113}
2114
2115static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
2116 IPersistPropertyBag *iface
2117) {
738e88db 2118 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
1fdece9b 2119 return IFont_Release(&this->IFont_iface);
d0372b4e
MM
2120}
2121
2122static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
2123 IPersistPropertyBag *iface, CLSID *classid
2124) {
2125 FIXME("(%p,%p), stub!\n", iface, classid);
2126 return E_FAIL;
2127}
2128
2129static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
2130 IPersistPropertyBag *iface
2131) {
2132 FIXME("(%p), stub!\n", iface);
2133 return S_OK;
2134}
2135
2136static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
2137 IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
2138) {
93010bf3
RS
2139/* (from Visual Basic 6 property bag)
2140 Name = "MS Sans Serif"
2141 Size = 13.8
2142 Charset = 0
2143 Weight = 400
2144 Underline = 0 'False
2145 Italic = 0 'False
2146 Strikethrough = 0 'False
2147*/
2148 static const WCHAR sAttrName[] = {'N','a','m','e',0};
2149 static const WCHAR sAttrSize[] = {'S','i','z','e',0};
2150 static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0};
2151 static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0};
2152 static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};
2153 static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};
2154 static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
738e88db 2155 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface);
2c91cced
NS
2156 VARIANT value;
2157 HRESULT iRes;
93010bf3 2158
2c91cced 2159 VariantInit(&value);
93010bf3 2160
2c91cced
NS
2161 iRes = IPropertyBag_Read(pPropBag, sAttrName, &value, pErrorLog);
2162 if (iRes == S_OK)
2163 {
2164 iRes = VariantChangeType(&value, &value, 0, VT_BSTR);
93010bf3 2165 if (iRes == S_OK)
1fdece9b 2166 iRes = IFont_put_Name(&this->IFont_iface, V_BSTR(&value));
93010bf3 2167 }
2c91cced
NS
2168 else if (iRes == E_INVALIDARG)
2169 iRes = S_OK;
2170
2171 VariantClear(&value);
93010bf3
RS
2172
2173 if (iRes == S_OK) {
2c91cced 2174 iRes = IPropertyBag_Read(pPropBag, sAttrSize, &value, pErrorLog);
93010bf3
RS
2175 if (iRes == S_OK)
2176 {
2c91cced 2177 iRes = VariantChangeType(&value, &value, 0, VT_CY);
93010bf3 2178 if (iRes == S_OK)
1fdece9b 2179 iRes = IFont_put_Size(&this->IFont_iface, V_CY(&value));
93010bf3
RS
2180 }
2181 else if (iRes == E_INVALIDARG)
2182 iRes = S_OK;
2c91cced
NS
2183
2184 VariantClear(&value);
93010bf3
RS
2185 }
2186
2187 if (iRes == S_OK) {
2c91cced 2188 iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &value, pErrorLog);
93010bf3
RS
2189 if (iRes == S_OK)
2190 {
2c91cced 2191 iRes = VariantChangeType(&value, &value, 0, VT_I2);
93010bf3 2192 if (iRes == S_OK)
1fdece9b 2193 iRes = IFont_put_Charset(&this->IFont_iface, V_I2(&value));
93010bf3
RS
2194 }
2195 else if (iRes == E_INVALIDARG)
2196 iRes = S_OK;
2c91cced
NS
2197
2198 VariantClear(&value);
93010bf3
RS
2199 }
2200
2201 if (iRes == S_OK) {
2c91cced 2202 iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &value, pErrorLog);
93010bf3
RS
2203 if (iRes == S_OK)
2204 {
2c91cced 2205 iRes = VariantChangeType(&value, &value, 0, VT_I2);
93010bf3 2206 if (iRes == S_OK)
1fdece9b 2207 iRes = IFont_put_Weight(&this->IFont_iface, V_I2(&value));
93010bf3
RS
2208 }
2209 else if (iRes == E_INVALIDARG)
2210 iRes = S_OK;
93010bf3 2211
2c91cced 2212 VariantClear(&value);
93010bf3
RS
2213 }
2214
2215 if (iRes == S_OK) {
2c91cced 2216 iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &value, pErrorLog);
93010bf3
RS
2217 if (iRes == S_OK)
2218 {
2c91cced 2219 iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
93010bf3 2220 if (iRes == S_OK)
1fdece9b 2221 iRes = IFont_put_Underline(&this->IFont_iface, V_BOOL(&value));
93010bf3
RS
2222 }
2223 else if (iRes == E_INVALIDARG)
2224 iRes = S_OK;
2c91cced
NS
2225
2226 VariantClear(&value);
93010bf3
RS
2227 }
2228
2229 if (iRes == S_OK) {
2c91cced 2230 iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &value, pErrorLog);
93010bf3
RS
2231 if (iRes == S_OK)
2232 {
2c91cced 2233 iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
93010bf3 2234 if (iRes == S_OK)
1fdece9b 2235 iRes = IFont_put_Italic(&this->IFont_iface, V_BOOL(&value));
93010bf3
RS
2236 }
2237 else if (iRes == E_INVALIDARG)
2238 iRes = S_OK;
2c91cced
NS
2239
2240 VariantClear(&value);
93010bf3
RS
2241 }
2242
2243 if (iRes == S_OK) {
2c91cced 2244 iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &value, pErrorLog);
93010bf3
RS
2245 if (iRes == S_OK)
2246 {
2c91cced 2247 iRes = VariantChangeType(&value, &value, 0, VT_BOOL);
93010bf3 2248 if (iRes == S_OK)
1fdece9b 2249 IFont_put_Strikethrough(&this->IFont_iface, V_BOOL(&value));
93010bf3
RS
2250 }
2251 else if (iRes == E_INVALIDARG)
2252 iRes = S_OK;
2c91cced
NS
2253
2254 VariantClear(&value);
93010bf3
RS
2255 }
2256
2257 if (FAILED(iRes))
ce66f5d6 2258 WARN("-- 0x%08x\n", iRes);
93010bf3 2259 return iRes;
d0372b4e
MM
2260}
2261
2262static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
2263 IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
2264 BOOL fSaveAllProperties
2265) {
2266 FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
2267 return E_FAIL;
2268}
2269
eba47f1d 2270static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable =
d0372b4e 2271{
d0372b4e
MM
2272 OLEFontImpl_IPersistPropertyBag_QueryInterface,
2273 OLEFontImpl_IPersistPropertyBag_AddRef,
2274 OLEFontImpl_IPersistPropertyBag_Release,
2275
2276 OLEFontImpl_IPersistPropertyBag_GetClassID,
2277 OLEFontImpl_IPersistPropertyBag_InitNew,
2278 OLEFontImpl_IPersistPropertyBag_Load,
2279 OLEFontImpl_IPersistPropertyBag_Save
2280};
2281
2282/************************************************************************
2283 * OLEFontImpl implementation of IPersistStreamInit.
2284 */
2285static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
2286 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
2287) {
738e88db 2288 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
1fdece9b 2289 return IFont_QueryInterface(&this->IFont_iface,riid,ppvObj);
d0372b4e
MM
2290}
2291
2292static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
2293 IPersistStreamInit *iface
2294) {
738e88db 2295 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
1fdece9b 2296 return IFont_AddRef(&this->IFont_iface);
d0372b4e
MM
2297}
2298
2299static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
2300 IPersistStreamInit *iface
2301) {
738e88db 2302 OLEFontImpl *this = impl_from_IPersistStreamInit(iface);
1fdece9b 2303 return IFont_Release(&this->IFont_iface);
d0372b4e
MM
2304}
2305
2306static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
2307 IPersistStreamInit *iface, CLSID *classid
2308) {
2309 FIXME("(%p,%p), stub!\n", iface, classid);
2310 return E_FAIL;
2311}
2312
2313static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
2314 IPersistStreamInit *iface
2315) {
2316 FIXME("(%p), stub!\n", iface);
2317 return E_FAIL;
2318}
2319
2320static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
2321 IPersistStreamInit *iface, LPSTREAM pStm
2322) {
2323 FIXME("(%p,%p), stub!\n", iface, pStm);
2324 return E_FAIL;
2325}
2326
2327static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
2328 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
2329) {
2330 FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
2331 return E_FAIL;
2332}
2333
2334static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
2335 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
2336) {
2337 FIXME("(%p,%p), stub!\n", iface, pcbSize);
2338 return E_FAIL;
2339}
2340
2341static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
2342 IPersistStreamInit *iface
2343) {
2344 FIXME("(%p), stub!\n", iface);
2345 return S_OK;
2346}
2347
eba47f1d 2348static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable =
d0372b4e 2349{
d0372b4e
MM
2350 OLEFontImpl_IPersistStreamInit_QueryInterface,
2351 OLEFontImpl_IPersistStreamInit_AddRef,
2352 OLEFontImpl_IPersistStreamInit_Release,
2353
2354 OLEFontImpl_IPersistStreamInit_GetClassID,
2355 OLEFontImpl_IPersistStreamInit_IsDirty,
2356 OLEFontImpl_IPersistStreamInit_Load,
2357 OLEFontImpl_IPersistStreamInit_Save,
2358 OLEFontImpl_IPersistStreamInit_GetSizeMax,
2359 OLEFontImpl_IPersistStreamInit_InitNew
2360};
2361
e79b8b8f
RS
2362/************************************************************************
2363 * OLEFontImpl_Construct
2364 *
2365 * This method will construct a new instance of the OLEFontImpl
2366 * class.
2367 *
2368 * The caller of this method must release the object when it's
2369 * done with it.
2370 */
ac82f20b 2371static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc)
e79b8b8f
RS
2372{
2373 OLEFontImpl* newObject = 0;
2374
2375 /*
2376 * Allocate space for the object.
2377 */
2378 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
2379
2380 if (newObject==0)
2381 return newObject;
2382
2383 /*
2384 * Initialize the virtual function table.
2385 */
1fdece9b
MS
2386 newObject->IFont_iface.lpVtbl = &OLEFontImpl_VTable;
2387 newObject->IDispatch_iface.lpVtbl = &OLEFontImpl_IDispatch_VTable;
2388 newObject->IPersistStream_iface.lpVtbl = &OLEFontImpl_IPersistStream_VTable;
2389 newObject->IConnectionPointContainer_iface.lpVtbl = &OLEFontImpl_IConnectionPointContainer_VTable;
2390 newObject->IPersistPropertyBag_iface.lpVtbl = &OLEFontImpl_IPersistPropertyBag_VTable;
2391 newObject->IPersistStreamInit_iface.lpVtbl = &OLEFontImpl_IPersistStreamInit_VTable;
e79b8b8f
RS
2392
2393 /*
2394 * Start with one reference count. The caller of this function
2395 * must release the interface pointer when it is done.
2396 */
2397 newObject->ref = 1;
2398
2399 /*
2400 * Copy the description of the font in the object.
2401 */
2402 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
2403
2404 newObject->description.cbSizeofstruct = sizeof(FONTDESC);
2405 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
2406 0,
2407 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
2408 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
2409 newObject->description.cySize = fontDesc->cySize;
2410 newObject->description.sWeight = fontDesc->sWeight;
2411 newObject->description.sCharset = fontDesc->sCharset;
2412 newObject->description.fItalic = fontDesc->fItalic;
2413 newObject->description.fUnderline = fontDesc->fUnderline;
2414 newObject->description.fStrikethrough = fontDesc->fStrikethrough;
2415
2416 /*
2417 * Initializing all the other members.
2418 */
2419 newObject->gdiFont = 0;
cf602ca4 2420 newObject->dirty = TRUE;
2ecbfbe5 2421 newObject->cyLogical = GetDeviceCaps(get_dc(), LOGPIXELSY);
e79b8b8f
RS
2422 newObject->cyHimetric = 2540L;
2423 newObject->pPropertyNotifyCP = NULL;
2424 newObject->pFontEventsCP = NULL;
2425
2426 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP);
2427 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP);
2428
2429 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP)
2430 {
2431 OLEFontImpl_Destroy(newObject);
2432 return NULL;
2433 }
2434
2435 InterlockedIncrement(&ifont_cnt);
2436
2437 TRACE("returning %p\n", newObject);
2438 return newObject;
2439}
2440
2441/************************************************************************
2442 * OLEFontImpl_Destroy
2443 *
2444 * This method is called by the Release method when the reference
2445 * count goes down to 0. It will free all resources used by
2446 * this object.
2447 */
2448static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
2449{
2450 TRACE("(%p)\n", fontDesc);
2451
2452 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
2453
e79b8b8f
RS
2454 if (fontDesc->pPropertyNotifyCP)
2455 IConnectionPoint_Release(fontDesc->pPropertyNotifyCP);
2456 if (fontDesc->pFontEventsCP)
2457 IConnectionPoint_Release(fontDesc->pFontEventsCP);
2458
2459 HeapFree(GetProcessHeap(), 0, fontDesc);
2460}
2461
c0ccd263
MM
2462/*******************************************************************************
2463 * StdFont ClassFactory
2464 */
2465typedef struct
2466{
2467 /* IUnknown fields */
e4094231
MS
2468 IClassFactory IClassFactory_iface;
2469 LONG ref;
c0ccd263
MM
2470} IClassFactoryImpl;
2471
e4094231
MS
2472static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
2473{
2474 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
2475}
2476
9a624916 2477static HRESULT WINAPI
c0ccd263 2478SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
e4094231 2479 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
c0ccd263
MM
2480
2481 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
2482 return E_NOINTERFACE;
2483}
2484
2485static ULONG WINAPI
2486SFCF_AddRef(LPCLASSFACTORY iface) {
e4094231 2487 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
36482273 2488 return InterlockedIncrement(&This->ref);
c0ccd263
MM
2489}
2490
2491static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
e4094231 2492 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
c0ccd263 2493 /* static class, won't be freed */
36482273 2494 return InterlockedDecrement(&This->ref);
c0ccd263
MM
2495}
2496
2497static HRESULT WINAPI SFCF_CreateInstance(
2498 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
2499) {
615615b0 2500 return OleCreateFontIndirect(NULL,riid,ppobj);
c0ccd263 2501
c0ccd263
MM
2502}
2503
2504static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
e4094231 2505 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
c0ccd263
MM
2506 FIXME("(%p)->(%d),stub!\n",This,dolock);
2507 return S_OK;
2508}
2509
eba47f1d 2510static const IClassFactoryVtbl SFCF_Vtbl = {
c0ccd263
MM
2511 SFCF_QueryInterface,
2512 SFCF_AddRef,
2513 SFCF_Release,
2514 SFCF_CreateInstance,
2515 SFCF_LockServer
2516};
e4094231 2517static IClassFactoryImpl STDFONT_CF = {{&SFCF_Vtbl}, 1 };
c0ccd263 2518
a3f8fd71 2519void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; }