Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenolefont.c
Go to the documentation of this file.
00001 /* 00002 * OLE Font encapsulation implementation 00003 * 00004 * This file contains an implementation of the IFont 00005 * interface and the OleCreateFontIndirect API call. 00006 * 00007 * Copyright 1999 Francis Beaudet 00008 * Copyright 2006 (Google) Benjamin Arai 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00023 */ 00024 #include <assert.h> 00025 #include <stdarg.h> 00026 #include <string.h> 00027 00028 #define COBJMACROS 00029 #define NONAMELESSUNION 00030 #define NONAMELESSSTRUCT 00031 00032 #include "winerror.h" 00033 #include "windef.h" 00034 #include "winbase.h" 00035 #include "wingdi.h" 00036 #include "winuser.h" 00037 #include "wine/list.h" 00038 #include "wine/unicode.h" 00039 #include "objbase.h" 00040 #include "oleauto.h" /* for SysAllocString(....) */ 00041 #include "ole2.h" 00042 #include "olectl.h" 00043 #include "wine/debug.h" 00044 #include "connpt.h" /* for CreateConnectionPoint */ 00045 #include "oaidl.h" 00046 00047 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00048 00049 /*********************************************************************** 00050 * Declaration of constants used when serializing the font object. 00051 */ 00052 #define FONTPERSIST_ITALIC 0x02 00053 #define FONTPERSIST_UNDERLINE 0x04 00054 #define FONTPERSIST_STRIKETHROUGH 0x08 00055 00056 static HDC olefont_hdc; 00057 00058 /*********************************************************************** 00059 * List of the HFONTs it has given out, with each one having a separate 00060 * ref count. 00061 */ 00062 typedef struct _HFONTItem 00063 { 00064 struct list entry; 00065 00066 /* Reference count of any IFont objects that own this hfont */ 00067 LONG int_refs; 00068 00069 /* Total reference count of any refs held by the application obtained by AddRefHfont plus any internal refs */ 00070 LONG total_refs; 00071 00072 /* The font associated with this object. */ 00073 HFONT gdiFont; 00074 00075 } HFONTItem, *PHFONTItem; 00076 00077 static struct list OLEFontImpl_hFontList = LIST_INIT(OLEFontImpl_hFontList); 00078 00079 /* Counts how many fonts contain at least one lock */ 00080 static LONG ifont_cnt = 0; 00081 00082 /*********************************************************************** 00083 * Critical section for OLEFontImpl_hFontList 00084 */ 00085 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST; 00086 static CRITICAL_SECTION_DEBUG OLEFontImpl_csHFONTLIST_debug = 00087 { 00088 0, 0, &OLEFontImpl_csHFONTLIST, 00089 { &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList, 00090 &OLEFontImpl_csHFONTLIST_debug.ProcessLocksList }, 00091 0, 0, { (DWORD_PTR)(__FILE__ ": OLEFontImpl_csHFONTLIST") } 00092 }; 00093 static CRITICAL_SECTION OLEFontImpl_csHFONTLIST = { &OLEFontImpl_csHFONTLIST_debug, -1, 0, 0, 0, 0 }; 00094 00095 static HDC get_dc(void) 00096 { 00097 HDC hdc; 00098 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00099 if(!olefont_hdc) 00100 olefont_hdc = CreateCompatibleDC(NULL); 00101 hdc = olefont_hdc; 00102 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00103 return hdc; 00104 } 00105 00106 static void delete_dc(void) 00107 { 00108 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00109 if(olefont_hdc) 00110 { 00111 DeleteDC(olefont_hdc); 00112 olefont_hdc = NULL; 00113 } 00114 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00115 } 00116 00117 static void HFONTItem_Delete(PHFONTItem item) 00118 { 00119 DeleteObject(item->gdiFont); 00120 list_remove(&item->entry); 00121 HeapFree(GetProcessHeap(), 0, item); 00122 } 00123 00124 /* Find hfont item entry in the list. Should be called while holding the crit sect */ 00125 static HFONTItem *find_hfontitem(HFONT hfont) 00126 { 00127 HFONTItem *item; 00128 00129 LIST_FOR_EACH_ENTRY(item, &OLEFontImpl_hFontList, HFONTItem, entry) 00130 { 00131 if (item->gdiFont == hfont) 00132 return item; 00133 } 00134 return NULL; 00135 } 00136 00137 /* Add an item to the list with one internal reference */ 00138 static HRESULT add_hfontitem(HFONT hfont) 00139 { 00140 HFONTItem *new_item = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_item)); 00141 00142 if(!new_item) return E_OUTOFMEMORY; 00143 00144 new_item->int_refs = 1; 00145 new_item->total_refs = 1; 00146 new_item->gdiFont = hfont; 00147 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00148 list_add_tail(&OLEFontImpl_hFontList,&new_item->entry); 00149 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00150 return S_OK; 00151 } 00152 00153 static HRESULT inc_int_ref(HFONT hfont) 00154 { 00155 HFONTItem *item; 00156 HRESULT hr = S_FALSE; 00157 00158 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00159 item = find_hfontitem(hfont); 00160 00161 if(item) 00162 { 00163 item->int_refs++; 00164 item->total_refs++; 00165 hr = S_OK; 00166 } 00167 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00168 00169 return hr; 00170 } 00171 00172 /* decrements the internal ref of a hfont item. If both refs are zero it'll 00173 remove the item from the list and delete the hfont */ 00174 static HRESULT dec_int_ref(HFONT hfont) 00175 { 00176 HFONTItem *item; 00177 HRESULT hr = S_FALSE; 00178 00179 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00180 item = find_hfontitem(hfont); 00181 00182 if(item) 00183 { 00184 item->int_refs--; 00185 item->total_refs--; 00186 if(item->int_refs == 0 && item->total_refs == 0) 00187 HFONTItem_Delete(item); 00188 hr = S_OK; 00189 } 00190 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00191 00192 return hr; 00193 } 00194 00195 static HRESULT inc_ext_ref(HFONT hfont) 00196 { 00197 HFONTItem *item; 00198 HRESULT hr = S_FALSE; 00199 00200 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00201 00202 item = find_hfontitem(hfont); 00203 if(item) 00204 { 00205 item->total_refs++; 00206 hr = S_OK; 00207 } 00208 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00209 00210 return hr; 00211 } 00212 00213 static HRESULT dec_ext_ref(HFONT hfont) 00214 { 00215 HFONTItem *item; 00216 HRESULT hr = S_FALSE; 00217 00218 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00219 00220 item = find_hfontitem(hfont); 00221 if(item) 00222 { 00223 if(--item->total_refs >= 0) hr = S_OK; 00224 } 00225 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00226 00227 return hr; 00228 } 00229 00230 static WCHAR *strdupW(const WCHAR* str) 00231 { 00232 WCHAR *ret; 00233 DWORD size = (strlenW(str) + 1) * sizeof(WCHAR); 00234 00235 ret = HeapAlloc(GetProcessHeap(), 0, size); 00236 if(ret) 00237 memcpy(ret, str, size); 00238 return ret; 00239 } 00240 00241 /*********************************************************************** 00242 * Declaration of the implementation class for the IFont interface 00243 */ 00244 typedef struct OLEFontImpl OLEFontImpl; 00245 00246 struct OLEFontImpl 00247 { 00248 /* 00249 * This class supports many interfaces. IUnknown, IFont, 00250 * IDispatch, IDispFont IPersistStream and IConnectionPointContainer. 00251 * The first two are supported by the first vtable, the next two are 00252 * supported by the second table and the last two have their own. 00253 */ 00254 const IFontVtbl* lpVtbl; 00255 const IDispatchVtbl* lpvtblIDispatch; 00256 const IPersistStreamVtbl* lpvtblIPersistStream; 00257 const IConnectionPointContainerVtbl* lpvtblIConnectionPointContainer; 00258 const IPersistPropertyBagVtbl* lpvtblIPersistPropertyBag; 00259 const IPersistStreamInitVtbl* lpvtblIPersistStreamInit; 00260 /* 00261 * Reference count for that instance of the class. 00262 */ 00263 LONG ref; 00264 00265 /* 00266 * This structure contains the description of the class. 00267 */ 00268 FONTDESC description; 00269 00270 /* 00271 * Contain the font associated with this object. 00272 */ 00273 HFONT gdiFont; 00274 BOOL dirty; 00275 /* 00276 * Size ratio 00277 */ 00278 LONG cyLogical; 00279 LONG cyHimetric; 00280 00281 IConnectionPoint *pPropertyNotifyCP; 00282 IConnectionPoint *pFontEventsCP; 00283 }; 00284 00285 /* 00286 * Here, I define utility macros to help with the casting of the 00287 * "this" parameter. 00288 * There is a version to accommodate all of the VTables implemented 00289 * by this object. 00290 */ 00291 00292 static inline OLEFontImpl *impl_from_IDispatch( IDispatch *iface ) 00293 { 00294 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIDispatch)); 00295 } 00296 00297 static inline OLEFontImpl *impl_from_IPersistStream( IPersistStream *iface ) 00298 { 00299 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStream)); 00300 } 00301 00302 static inline OLEFontImpl *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface ) 00303 { 00304 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIConnectionPointContainer)); 00305 } 00306 00307 static inline OLEFontImpl *impl_from_IPersistPropertyBag( IPersistPropertyBag *iface ) 00308 { 00309 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistPropertyBag)); 00310 } 00311 00312 static inline OLEFontImpl *impl_from_IPersistStreamInit( IPersistStreamInit *iface ) 00313 { 00314 return (OLEFontImpl *)((char*)iface - FIELD_OFFSET(OLEFontImpl, lpvtblIPersistStreamInit)); 00315 } 00316 00317 00318 /*********************************************************************** 00319 * Prototypes for the implementation functions for the IFont 00320 * interface 00321 */ 00322 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc); 00323 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc); 00324 static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface); 00325 00326 /****************************************************************************** 00327 * OleCreateFontIndirect [OLEAUT32.420] 00328 */ 00329 HRESULT WINAPI OleCreateFontIndirect( 00330 LPFONTDESC lpFontDesc, 00331 REFIID riid, 00332 LPVOID* ppvObj) 00333 { 00334 OLEFontImpl* newFont = 0; 00335 HRESULT hr = S_OK; 00336 00337 TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj); 00338 /* 00339 * Sanity check 00340 */ 00341 if (ppvObj==0) 00342 return E_POINTER; 00343 00344 *ppvObj = 0; 00345 00346 if (!lpFontDesc) { 00347 FONTDESC fd; 00348 00349 static WCHAR fname[] = { 'S','y','s','t','e','m',0 }; 00350 00351 fd.cbSizeofstruct = sizeof(fd); 00352 fd.lpstrName = fname; 00353 fd.cySize.s.Lo = 80000; 00354 fd.cySize.s.Hi = 0; 00355 fd.sWeight = 0; 00356 fd.sCharset = 0; 00357 fd.fItalic = 0; 00358 fd.fUnderline = 0; 00359 fd.fStrikethrough = 0; 00360 lpFontDesc = &fd; 00361 } 00362 00363 /* 00364 * Try to construct a new instance of the class. 00365 */ 00366 newFont = OLEFontImpl_Construct(lpFontDesc); 00367 00368 if (newFont == 0) 00369 return E_OUTOFMEMORY; 00370 00371 /* 00372 * Make sure it supports the interface required by the caller. 00373 */ 00374 hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj); 00375 00376 /* 00377 * Release the reference obtained in the constructor. If 00378 * the QueryInterface was unsuccessful, it will free the class. 00379 */ 00380 IFont_Release((IFont*)newFont); 00381 00382 return hr; 00383 } 00384 00385 00386 /*********************************************************************** 00387 * Implementation of the OLEFontImpl class. 00388 */ 00389 00390 /*********************************************************************** 00391 * OLEFont_SendNotify (internal) 00392 * 00393 * Sends notification messages of changed properties to any interested 00394 * connections. 00395 */ 00396 static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID) 00397 { 00398 static const WCHAR wszName[] = {'N','a','m','e',0}; 00399 static const WCHAR wszSize[] = {'S','i','z','e',0}; 00400 static const WCHAR wszBold[] = {'B','o','l','d',0}; 00401 static const WCHAR wszItalic[] = {'I','t','a','l','i','c',0}; 00402 static const WCHAR wszUnder[] = {'U','n','d','e','r','l','i','n','e',0}; 00403 static const WCHAR wszStrike[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; 00404 static const WCHAR wszWeight[] = {'W','e','i','g','h','t',0}; 00405 static const WCHAR wszCharset[] = {'C','h','a','r','s','s','e','t',0}; 00406 static const LPCWSTR dispid_mapping[] = 00407 { 00408 wszName, 00409 NULL, 00410 wszSize, 00411 wszBold, 00412 wszItalic, 00413 wszUnder, 00414 wszStrike, 00415 wszWeight, 00416 wszCharset 00417 }; 00418 00419 IEnumConnections *pEnum; 00420 CONNECTDATA CD; 00421 HRESULT hres; 00422 00423 this->dirty = TRUE; 00424 00425 hres = IConnectionPoint_EnumConnections(this->pPropertyNotifyCP, &pEnum); 00426 if (SUCCEEDED(hres)) 00427 { 00428 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { 00429 IPropertyNotifySink *sink; 00430 00431 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink); 00432 IPropertyNotifySink_OnChanged(sink, dispID); 00433 IPropertyNotifySink_Release(sink); 00434 IUnknown_Release(CD.pUnk); 00435 } 00436 IEnumConnections_Release(pEnum); 00437 } 00438 00439 hres = IConnectionPoint_EnumConnections(this->pFontEventsCP, &pEnum); 00440 if (SUCCEEDED(hres)) 00441 { 00442 DISPPARAMS dispparams; 00443 VARIANTARG vararg; 00444 00445 VariantInit(&vararg); 00446 V_VT(&vararg) = VT_BSTR; 00447 V_BSTR(&vararg) = SysAllocString(dispid_mapping[dispID]); 00448 00449 dispparams.cArgs = 1; 00450 dispparams.cNamedArgs = 0; 00451 dispparams.rgdispidNamedArgs = NULL; 00452 dispparams.rgvarg = &vararg; 00453 00454 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) { 00455 IFontEventsDisp *disp; 00456 00457 IUnknown_QueryInterface(CD.pUnk, &IID_IFontEventsDisp, (LPVOID)&disp); 00458 IDispatch_Invoke(disp, DISPID_FONT_CHANGED, &IID_NULL, 00459 LOCALE_NEUTRAL, INVOKE_FUNC, &dispparams, NULL, 00460 NULL, NULL); 00461 00462 IDispatch_Release(disp); 00463 IUnknown_Release(CD.pUnk); 00464 } 00465 VariantClear(&vararg); 00466 IEnumConnections_Release(pEnum); 00467 } 00468 } 00469 00470 /************************************************************************ 00471 * OLEFontImpl_QueryInterface (IUnknown) 00472 * 00473 * See Windows documentation for more details on IUnknown methods. 00474 */ 00475 static HRESULT WINAPI OLEFontImpl_QueryInterface( 00476 IFont* iface, 00477 REFIID riid, 00478 void** ppvObject) 00479 { 00480 OLEFontImpl *this = (OLEFontImpl *)iface; 00481 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject); 00482 00483 /* 00484 * Perform a sanity check on the parameters. 00485 */ 00486 if ( (this==0) || (ppvObject==0) ) 00487 return E_INVALIDARG; 00488 00489 /* 00490 * Initialize the return parameter. 00491 */ 00492 *ppvObject = 0; 00493 00494 /* 00495 * Compare the riid with the interface IDs implemented by this object. 00496 */ 00497 if (IsEqualGUID(&IID_IUnknown, riid)) 00498 *ppvObject = this; 00499 if (IsEqualGUID(&IID_IFont, riid)) 00500 *ppvObject = this; 00501 if (IsEqualGUID(&IID_IDispatch, riid)) 00502 *ppvObject = &this->lpvtblIDispatch; 00503 if (IsEqualGUID(&IID_IFontDisp, riid)) 00504 *ppvObject = &this->lpvtblIDispatch; 00505 if (IsEqualIID(&IID_IPersist, riid) || IsEqualGUID(&IID_IPersistStream, riid)) 00506 *ppvObject = &this->lpvtblIPersistStream; 00507 if (IsEqualGUID(&IID_IConnectionPointContainer, riid)) 00508 *ppvObject = &this->lpvtblIConnectionPointContainer; 00509 if (IsEqualGUID(&IID_IPersistPropertyBag, riid)) 00510 *ppvObject = &this->lpvtblIPersistPropertyBag; 00511 if (IsEqualGUID(&IID_IPersistStreamInit, riid)) 00512 *ppvObject = &this->lpvtblIPersistStreamInit; 00513 00514 /* 00515 * Check that we obtained an interface. 00516 */ 00517 if ((*ppvObject)==0) 00518 { 00519 FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid)); 00520 return E_NOINTERFACE; 00521 } 00522 OLEFontImpl_AddRef((IFont*)this); 00523 return S_OK; 00524 } 00525 00526 /************************************************************************ 00527 * OLEFontImpl_AddRef (IUnknown) 00528 * 00529 * See Windows documentation for more details on IUnknown methods. 00530 */ 00531 static ULONG WINAPI OLEFontImpl_AddRef( 00532 IFont* iface) 00533 { 00534 OLEFontImpl *this = (OLEFontImpl *)iface; 00535 TRACE("(%p)->(ref=%d)\n", this, this->ref); 00536 return InterlockedIncrement(&this->ref); 00537 } 00538 00539 /************************************************************************ 00540 * OLEFontImpl_Release (IUnknown) 00541 * 00542 * See Windows documentation for more details on IUnknown methods. 00543 */ 00544 static ULONG WINAPI OLEFontImpl_Release( 00545 IFont* iface) 00546 { 00547 OLEFontImpl *this = (OLEFontImpl *)iface; 00548 ULONG ret; 00549 TRACE("(%p)->(ref=%d)\n", this, this->ref); 00550 00551 /* Decrease the reference count for current interface */ 00552 ret = InterlockedDecrement(&this->ref); 00553 00554 /* If the reference count goes down to 0, destroy. */ 00555 if (ret == 0) 00556 { 00557 ULONG fontlist_refs = InterlockedDecrement(&ifont_cnt); 00558 00559 /* Final IFont object so destroy font cache */ 00560 if (fontlist_refs == 0) 00561 { 00562 HFONTItem *item, *cursor2; 00563 00564 EnterCriticalSection(&OLEFontImpl_csHFONTLIST); 00565 LIST_FOR_EACH_ENTRY_SAFE(item, cursor2, &OLEFontImpl_hFontList, HFONTItem, entry) 00566 HFONTItem_Delete(item); 00567 LeaveCriticalSection(&OLEFontImpl_csHFONTLIST); 00568 delete_dc(); 00569 } 00570 else 00571 { 00572 dec_int_ref(this->gdiFont); 00573 } 00574 OLEFontImpl_Destroy(this); 00575 } 00576 00577 return ret; 00578 } 00579 00580 typedef struct 00581 { 00582 short orig_cs; 00583 short avail_cs; 00584 } enum_data; 00585 00586 static int CALLBACK font_enum_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lp) 00587 { 00588 enum_data *data = (enum_data*)lp; 00589 00590 if(elf->lfCharSet == data->orig_cs) 00591 { 00592 data->avail_cs = data->orig_cs; 00593 return 0; 00594 } 00595 if(data->avail_cs == -1) data->avail_cs = elf->lfCharSet; 00596 return 1; 00597 } 00598 00599 static void realize_font(OLEFontImpl *This) 00600 { 00601 if (This->dirty) 00602 { 00603 LOGFONTW logFont; 00604 INT fontHeight; 00605 WCHAR text_face[LF_FACESIZE]; 00606 HDC hdc = get_dc(); 00607 HFONT old_font; 00608 TEXTMETRICW tm; 00609 00610 text_face[0] = 0; 00611 00612 if(This->gdiFont) 00613 { 00614 old_font = SelectObject(hdc, This->gdiFont); 00615 GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); 00616 SelectObject(hdc, old_font); 00617 dec_int_ref(This->gdiFont); 00618 This->gdiFont = 0; 00619 } 00620 00621 memset(&logFont, 0, sizeof(LOGFONTW)); 00622 00623 lstrcpynW(logFont.lfFaceName, This->description.lpstrName, LF_FACESIZE); 00624 logFont.lfCharSet = This->description.sCharset; 00625 00626 /* If the font name has been changed then enumerate all charsets 00627 and pick one that'll result in the font specified being selected */ 00628 if(text_face[0] && lstrcmpiW(text_face, This->description.lpstrName)) 00629 { 00630 enum_data data; 00631 data.orig_cs = This->description.sCharset; 00632 data.avail_cs = -1; 00633 logFont.lfCharSet = DEFAULT_CHARSET; 00634 EnumFontFamiliesExW(get_dc(), &logFont, font_enum_proc, (LPARAM)&data, 0); 00635 if(data.avail_cs != -1) logFont.lfCharSet = data.avail_cs; 00636 } 00637 00638 00639 /* 00640 * The height of the font returned by the get_Size property is the 00641 * height of the font in points multiplied by 10000... Using some 00642 * simple conversions and the ratio given by the application, it can 00643 * be converted to a height in pixels. 00644 * 00645 * Standard ratio is 72 / 2540, or 18 / 635 in lowest terms. 00646 * Ratio is applied here relative to the standard. 00647 */ 00648 00649 fontHeight = MulDiv( This->description.cySize.s.Lo, This->cyLogical*635, This->cyHimetric*18 ); 00650 00651 00652 logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L) - 1 : 00653 (-fontHeight/10000L); 00654 logFont.lfItalic = This->description.fItalic; 00655 logFont.lfUnderline = This->description.fUnderline; 00656 logFont.lfStrikeOut = This->description.fStrikethrough; 00657 logFont.lfWeight = This->description.sWeight; 00658 logFont.lfOutPrecision = OUT_CHARACTER_PRECIS; 00659 logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; 00660 logFont.lfQuality = DEFAULT_QUALITY; 00661 logFont.lfPitchAndFamily = DEFAULT_PITCH; 00662 00663 This->gdiFont = CreateFontIndirectW(&logFont); 00664 This->dirty = FALSE; 00665 00666 add_hfontitem(This->gdiFont); 00667 00668 /* Fixup the name and charset properties so that they match the 00669 selected font */ 00670 old_font = SelectObject(get_dc(), This->gdiFont); 00671 GetTextFaceW(hdc, sizeof(text_face) / sizeof(text_face[0]), text_face); 00672 if(lstrcmpiW(text_face, This->description.lpstrName)) 00673 { 00674 HeapFree(GetProcessHeap(), 0, This->description.lpstrName); 00675 This->description.lpstrName = strdupW(text_face); 00676 } 00677 GetTextMetricsW(hdc, &tm); 00678 This->description.sCharset = tm.tmCharSet; 00679 SelectObject(hdc, old_font); 00680 } 00681 } 00682 00683 /************************************************************************ 00684 * OLEFontImpl_get_Name (IFont) 00685 * 00686 * See Windows documentation for more details on IFont methods. 00687 */ 00688 static HRESULT WINAPI OLEFontImpl_get_Name( 00689 IFont* iface, 00690 BSTR* pname) 00691 { 00692 OLEFontImpl *this = (OLEFontImpl *)iface; 00693 TRACE("(%p)->(%p)\n", this, pname); 00694 /* 00695 * Sanity check. 00696 */ 00697 if (pname==0) 00698 return E_POINTER; 00699 00700 if(this->dirty) realize_font(this); 00701 00702 if (this->description.lpstrName!=0) 00703 *pname = SysAllocString(this->description.lpstrName); 00704 else 00705 *pname = 0; 00706 00707 return S_OK; 00708 } 00709 00710 /************************************************************************ 00711 * OLEFontImpl_put_Name (IFont) 00712 * 00713 * See Windows documentation for more details on IFont methods. 00714 */ 00715 static HRESULT WINAPI OLEFontImpl_put_Name( 00716 IFont* iface, 00717 BSTR name) 00718 { 00719 OLEFontImpl *this = (OLEFontImpl *)iface; 00720 TRACE("(%p)->(%p)\n", this, name); 00721 00722 if (!name) 00723 return CTL_E_INVALIDPROPERTYVALUE; 00724 00725 if (this->description.lpstrName==0) 00726 { 00727 this->description.lpstrName = HeapAlloc(GetProcessHeap(), 00728 0, 00729 (lstrlenW(name)+1) * sizeof(WCHAR)); 00730 } 00731 else 00732 { 00733 this->description.lpstrName = HeapReAlloc(GetProcessHeap(), 00734 0, 00735 this->description.lpstrName, 00736 (lstrlenW(name)+1) * sizeof(WCHAR)); 00737 } 00738 00739 if (this->description.lpstrName==0) 00740 return E_OUTOFMEMORY; 00741 00742 strcpyW(this->description.lpstrName, name); 00743 TRACE("new name %s\n", debugstr_w(this->description.lpstrName)); 00744 OLEFont_SendNotify(this, DISPID_FONT_NAME); 00745 return S_OK; 00746 } 00747 00748 /************************************************************************ 00749 * OLEFontImpl_get_Size (IFont) 00750 * 00751 * See Windows documentation for more details on IFont methods. 00752 */ 00753 static HRESULT WINAPI OLEFontImpl_get_Size( 00754 IFont* iface, 00755 CY* psize) 00756 { 00757 OLEFontImpl *this = (OLEFontImpl *)iface; 00758 TRACE("(%p)->(%p)\n", this, psize); 00759 00760 /* 00761 * Sanity check 00762 */ 00763 if (psize==0) 00764 return E_POINTER; 00765 00766 if(this->dirty) realize_font(this); 00767 00768 psize->s.Hi = 0; 00769 psize->s.Lo = this->description.cySize.s.Lo; 00770 00771 return S_OK; 00772 } 00773 00774 /************************************************************************ 00775 * OLEFontImpl_put_Size (IFont) 00776 * 00777 * See Windows documentation for more details on IFont methods. 00778 */ 00779 static HRESULT WINAPI OLEFontImpl_put_Size( 00780 IFont* iface, 00781 CY size) 00782 { 00783 OLEFontImpl *this = (OLEFontImpl *)iface; 00784 TRACE("(%p)->(%d)\n", this, size.s.Lo); 00785 this->description.cySize.s.Hi = 0; 00786 this->description.cySize.s.Lo = size.s.Lo; 00787 OLEFont_SendNotify(this, DISPID_FONT_SIZE); 00788 00789 return S_OK; 00790 } 00791 00792 /************************************************************************ 00793 * OLEFontImpl_get_Bold (IFont) 00794 * 00795 * See Windows documentation for more details on IFont methods. 00796 */ 00797 static HRESULT WINAPI OLEFontImpl_get_Bold( 00798 IFont* iface, 00799 BOOL* pbold) 00800 { 00801 OLEFontImpl *this = (OLEFontImpl *)iface; 00802 TRACE("(%p)->(%p)\n", this, pbold); 00803 /* 00804 * Sanity check 00805 */ 00806 if (pbold==0) 00807 return E_POINTER; 00808 00809 if(this->dirty) realize_font(this); 00810 00811 *pbold = this->description.sWeight > 550; 00812 00813 return S_OK; 00814 } 00815 00816 /************************************************************************ 00817 * OLEFontImpl_put_Bold (IFont) 00818 * 00819 * See Windows documentation for more details on IFont methods. 00820 */ 00821 static HRESULT WINAPI OLEFontImpl_put_Bold( 00822 IFont* iface, 00823 BOOL bold) 00824 { 00825 OLEFontImpl *this = (OLEFontImpl *)iface; 00826 TRACE("(%p)->(%d)\n", this, bold); 00827 this->description.sWeight = bold ? FW_BOLD : FW_NORMAL; 00828 OLEFont_SendNotify(this, DISPID_FONT_BOLD); 00829 00830 return S_OK; 00831 } 00832 00833 /************************************************************************ 00834 * OLEFontImpl_get_Italic (IFont) 00835 * 00836 * See Windows documentation for more details on IFont methods. 00837 */ 00838 static HRESULT WINAPI OLEFontImpl_get_Italic( 00839 IFont* iface, 00840 BOOL* pitalic) 00841 { 00842 OLEFontImpl *this = (OLEFontImpl *)iface; 00843 TRACE("(%p)->(%p)\n", this, pitalic); 00844 /* 00845 * Sanity check 00846 */ 00847 if (pitalic==0) 00848 return E_POINTER; 00849 00850 if(this->dirty) realize_font(this); 00851 00852 *pitalic = this->description.fItalic; 00853 00854 return S_OK; 00855 } 00856 00857 /************************************************************************ 00858 * OLEFontImpl_put_Italic (IFont) 00859 * 00860 * See Windows documentation for more details on IFont methods. 00861 */ 00862 static HRESULT WINAPI OLEFontImpl_put_Italic( 00863 IFont* iface, 00864 BOOL italic) 00865 { 00866 OLEFontImpl *this = (OLEFontImpl *)iface; 00867 TRACE("(%p)->(%d)\n", this, italic); 00868 00869 this->description.fItalic = italic; 00870 00871 OLEFont_SendNotify(this, DISPID_FONT_ITALIC); 00872 return S_OK; 00873 } 00874 00875 /************************************************************************ 00876 * OLEFontImpl_get_Underline (IFont) 00877 * 00878 * See Windows documentation for more details on IFont methods. 00879 */ 00880 static HRESULT WINAPI OLEFontImpl_get_Underline( 00881 IFont* iface, 00882 BOOL* punderline) 00883 { 00884 OLEFontImpl *this = (OLEFontImpl *)iface; 00885 TRACE("(%p)->(%p)\n", this, punderline); 00886 00887 /* 00888 * Sanity check 00889 */ 00890 if (punderline==0) 00891 return E_POINTER; 00892 00893 if(this->dirty) realize_font(this); 00894 00895 *punderline = this->description.fUnderline; 00896 00897 return S_OK; 00898 } 00899 00900 /************************************************************************ 00901 * OLEFontImpl_put_Underline (IFont) 00902 * 00903 * See Windows documentation for more details on IFont methods. 00904 */ 00905 static HRESULT WINAPI OLEFontImpl_put_Underline( 00906 IFont* iface, 00907 BOOL underline) 00908 { 00909 OLEFontImpl *this = (OLEFontImpl *)iface; 00910 TRACE("(%p)->(%d)\n", this, underline); 00911 00912 this->description.fUnderline = underline; 00913 00914 OLEFont_SendNotify(this, DISPID_FONT_UNDER); 00915 return S_OK; 00916 } 00917 00918 /************************************************************************ 00919 * OLEFontImpl_get_Strikethrough (IFont) 00920 * 00921 * See Windows documentation for more details on IFont methods. 00922 */ 00923 static HRESULT WINAPI OLEFontImpl_get_Strikethrough( 00924 IFont* iface, 00925 BOOL* pstrikethrough) 00926 { 00927 OLEFontImpl *this = (OLEFontImpl *)iface; 00928 TRACE("(%p)->(%p)\n", this, pstrikethrough); 00929 00930 /* 00931 * Sanity check 00932 */ 00933 if (pstrikethrough==0) 00934 return E_POINTER; 00935 00936 if(this->dirty) realize_font(this); 00937 00938 *pstrikethrough = this->description.fStrikethrough; 00939 00940 return S_OK; 00941 } 00942 00943 /************************************************************************ 00944 * OLEFontImpl_put_Strikethrough (IFont) 00945 * 00946 * See Windows documentation for more details on IFont methods. 00947 */ 00948 static HRESULT WINAPI OLEFontImpl_put_Strikethrough( 00949 IFont* iface, 00950 BOOL strikethrough) 00951 { 00952 OLEFontImpl *this = (OLEFontImpl *)iface; 00953 TRACE("(%p)->(%d)\n", this, strikethrough); 00954 00955 this->description.fStrikethrough = strikethrough; 00956 OLEFont_SendNotify(this, DISPID_FONT_STRIKE); 00957 00958 return S_OK; 00959 } 00960 00961 /************************************************************************ 00962 * OLEFontImpl_get_Weight (IFont) 00963 * 00964 * See Windows documentation for more details on IFont methods. 00965 */ 00966 static HRESULT WINAPI OLEFontImpl_get_Weight( 00967 IFont* iface, 00968 short* pweight) 00969 { 00970 OLEFontImpl *this = (OLEFontImpl *)iface; 00971 TRACE("(%p)->(%p)\n", this, pweight); 00972 00973 /* 00974 * Sanity check 00975 */ 00976 if (pweight==0) 00977 return E_POINTER; 00978 00979 if(this->dirty) realize_font(this); 00980 00981 *pweight = this->description.sWeight; 00982 00983 return S_OK; 00984 } 00985 00986 /************************************************************************ 00987 * OLEFontImpl_put_Weight (IFont) 00988 * 00989 * See Windows documentation for more details on IFont methods. 00990 */ 00991 static HRESULT WINAPI OLEFontImpl_put_Weight( 00992 IFont* iface, 00993 short weight) 00994 { 00995 OLEFontImpl *this = (OLEFontImpl *)iface; 00996 TRACE("(%p)->(%d)\n", this, weight); 00997 00998 this->description.sWeight = weight; 00999 01000 OLEFont_SendNotify(this, DISPID_FONT_WEIGHT); 01001 return S_OK; 01002 } 01003 01004 /************************************************************************ 01005 * OLEFontImpl_get_Charset (IFont) 01006 * 01007 * See Windows documentation for more details on IFont methods. 01008 */ 01009 static HRESULT WINAPI OLEFontImpl_get_Charset( 01010 IFont* iface, 01011 short* pcharset) 01012 { 01013 OLEFontImpl *this = (OLEFontImpl *)iface; 01014 TRACE("(%p)->(%p)\n", this, pcharset); 01015 01016 /* 01017 * Sanity check 01018 */ 01019 if (pcharset==0) 01020 return E_POINTER; 01021 01022 if(this->dirty) realize_font(this); 01023 01024 *pcharset = this->description.sCharset; 01025 01026 return S_OK; 01027 } 01028 01029 /************************************************************************ 01030 * OLEFontImpl_put_Charset (IFont) 01031 * 01032 * See Windows documentation for more details on IFont methods. 01033 */ 01034 static HRESULT WINAPI OLEFontImpl_put_Charset( 01035 IFont* iface, 01036 short charset) 01037 { 01038 OLEFontImpl *this = (OLEFontImpl *)iface; 01039 TRACE("(%p)->(%d)\n", this, charset); 01040 01041 this->description.sCharset = charset; 01042 OLEFont_SendNotify(this, DISPID_FONT_CHARSET); 01043 01044 return S_OK; 01045 } 01046 01047 /************************************************************************ 01048 * OLEFontImpl_get_hFont (IFont) 01049 * 01050 * See Windows documentation for more details on IFont methods. 01051 */ 01052 static HRESULT WINAPI OLEFontImpl_get_hFont( 01053 IFont* iface, 01054 HFONT* phfont) 01055 { 01056 OLEFontImpl *this = (OLEFontImpl *)iface; 01057 TRACE("(%p)->(%p)\n", this, phfont); 01058 if (phfont==NULL) 01059 return E_POINTER; 01060 01061 if(this->dirty) realize_font(this); 01062 01063 *phfont = this->gdiFont; 01064 TRACE("Returning %p\n", *phfont); 01065 return S_OK; 01066 } 01067 01068 /************************************************************************ 01069 * OLEFontImpl_Clone (IFont) 01070 * 01071 * See Windows documentation for more details on IFont methods. 01072 */ 01073 static HRESULT WINAPI OLEFontImpl_Clone( 01074 IFont* iface, 01075 IFont** ppfont) 01076 { 01077 OLEFontImpl* newObject = 0; 01078 OLEFontImpl *this = (OLEFontImpl *)iface; 01079 01080 TRACE("(%p)->(%p)\n", this, ppfont); 01081 01082 if (ppfont == NULL) 01083 return E_POINTER; 01084 01085 *ppfont = NULL; 01086 01087 /* 01088 * Allocate space for the object. 01089 */ 01090 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); 01091 01092 if (newObject==NULL) 01093 return E_OUTOFMEMORY; 01094 01095 *newObject = *this; 01096 01097 /* We need to alloc new memory for the string, otherwise 01098 * we free memory twice. 01099 */ 01100 newObject->description.lpstrName = HeapAlloc( 01101 GetProcessHeap(),0, 01102 (1+strlenW(this->description.lpstrName))*2 01103 ); 01104 strcpyW(newObject->description.lpstrName, this->description.lpstrName); 01105 01106 01107 /* Increment internal ref in hfont item list */ 01108 if(newObject->gdiFont) inc_int_ref(newObject->gdiFont); 01109 01110 InterlockedIncrement(&ifont_cnt); 01111 01112 /* create new connection points */ 01113 newObject->pPropertyNotifyCP = NULL; 01114 newObject->pFontEventsCP = NULL; 01115 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); 01116 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP); 01117 01118 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP) 01119 { 01120 OLEFontImpl_Destroy(newObject); 01121 return E_OUTOFMEMORY; 01122 } 01123 01124 /* The cloned object starts with a reference count of 1 */ 01125 newObject->ref = 1; 01126 01127 *ppfont = (IFont*)newObject; 01128 01129 return S_OK; 01130 } 01131 01132 /************************************************************************ 01133 * OLEFontImpl_IsEqual (IFont) 01134 * 01135 * See Windows documentation for more details on IFont methods. 01136 */ 01137 static HRESULT WINAPI OLEFontImpl_IsEqual( 01138 IFont* iface, 01139 IFont* pFontOther) 01140 { 01141 OLEFontImpl *left = (OLEFontImpl *)iface; 01142 OLEFontImpl *right = (OLEFontImpl *)pFontOther; 01143 INT ret; 01144 INT left_len,right_len; 01145 01146 if((iface == NULL) || (pFontOther == NULL)) 01147 return E_POINTER; 01148 else if (left->description.cySize.s.Lo != right->description.cySize.s.Lo) 01149 return S_FALSE; 01150 else if (left->description.cySize.s.Hi != right->description.cySize.s.Hi) 01151 return S_FALSE; 01152 else if (left->description.sWeight != right->description.sWeight) 01153 return S_FALSE; 01154 else if (left->description.sCharset != right->description.sCharset) 01155 return S_FALSE; 01156 else if (left->description.fItalic != right->description.fItalic) 01157 return S_FALSE; 01158 else if (left->description.fUnderline != right->description.fUnderline) 01159 return S_FALSE; 01160 else if (left->description.fStrikethrough != right->description.fStrikethrough) 01161 return S_FALSE; 01162 01163 /* Check from string */ 01164 left_len = strlenW(left->description.lpstrName); 01165 right_len = strlenW(right->description.lpstrName); 01166 ret = CompareStringW(0,0,left->description.lpstrName, left_len, 01167 right->description.lpstrName, right_len); 01168 if (ret != CSTR_EQUAL) 01169 return S_FALSE; 01170 01171 return S_OK; 01172 } 01173 01174 /************************************************************************ 01175 * OLEFontImpl_SetRatio (IFont) 01176 * 01177 * See Windows documentation for more details on IFont methods. 01178 */ 01179 static HRESULT WINAPI OLEFontImpl_SetRatio( 01180 IFont* iface, 01181 LONG cyLogical, 01182 LONG cyHimetric) 01183 { 01184 OLEFontImpl *this = (OLEFontImpl *)iface; 01185 TRACE("(%p)->(%d, %d)\n", this, cyLogical, cyHimetric); 01186 01187 this->cyLogical = cyLogical; 01188 this->cyHimetric = cyHimetric; 01189 01190 return S_OK; 01191 } 01192 01193 /************************************************************************ 01194 * OLEFontImpl_QueryTextMetrics (IFont) 01195 * 01196 * See Windows documentation for more details on IFont methods. 01197 */ 01198 static HRESULT WINAPI OLEFontImpl_QueryTextMetrics( 01199 IFont* iface, 01200 TEXTMETRICOLE* ptm) 01201 { 01202 HDC hdcRef; 01203 HFONT hOldFont, hNewFont; 01204 01205 hdcRef = GetDC(0); 01206 OLEFontImpl_get_hFont(iface, &hNewFont); 01207 hOldFont = SelectObject(hdcRef, hNewFont); 01208 GetTextMetricsW(hdcRef, ptm); 01209 SelectObject(hdcRef, hOldFont); 01210 ReleaseDC(0, hdcRef); 01211 return S_OK; 01212 } 01213 01214 /************************************************************************ 01215 * OLEFontImpl_AddRefHfont (IFont) 01216 * 01217 * See Windows documentation for more details on IFont methods. 01218 */ 01219 static HRESULT WINAPI OLEFontImpl_AddRefHfont( 01220 IFont* iface, 01221 HFONT hfont) 01222 { 01223 OLEFontImpl *this = (OLEFontImpl *)iface; 01224 01225 TRACE("(%p)->(%p)\n", this, hfont); 01226 01227 if (!hfont) return E_INVALIDARG; 01228 01229 return inc_ext_ref(hfont); 01230 } 01231 01232 /************************************************************************ 01233 * OLEFontImpl_ReleaseHfont (IFont) 01234 * 01235 * See Windows documentation for more details on IFont methods. 01236 */ 01237 static HRESULT WINAPI OLEFontImpl_ReleaseHfont( 01238 IFont* iface, 01239 HFONT hfont) 01240 { 01241 OLEFontImpl *this = (OLEFontImpl *)iface; 01242 01243 TRACE("(%p)->(%p)\n", this, hfont); 01244 01245 if (!hfont) return E_INVALIDARG; 01246 01247 return dec_ext_ref(hfont); 01248 } 01249 01250 /************************************************************************ 01251 * OLEFontImpl_SetHdc (IFont) 01252 * 01253 * See Windows documentation for more details on IFont methods. 01254 */ 01255 static HRESULT WINAPI OLEFontImpl_SetHdc( 01256 IFont* iface, 01257 HDC hdc) 01258 { 01259 OLEFontImpl *this = (OLEFontImpl *)iface; 01260 FIXME("(%p)->(%p): Stub\n", this, hdc); 01261 return E_NOTIMPL; 01262 } 01263 01264 /* 01265 * Virtual function tables for the OLEFontImpl class. 01266 */ 01267 static const IFontVtbl OLEFontImpl_VTable = 01268 { 01269 OLEFontImpl_QueryInterface, 01270 OLEFontImpl_AddRef, 01271 OLEFontImpl_Release, 01272 OLEFontImpl_get_Name, 01273 OLEFontImpl_put_Name, 01274 OLEFontImpl_get_Size, 01275 OLEFontImpl_put_Size, 01276 OLEFontImpl_get_Bold, 01277 OLEFontImpl_put_Bold, 01278 OLEFontImpl_get_Italic, 01279 OLEFontImpl_put_Italic, 01280 OLEFontImpl_get_Underline, 01281 OLEFontImpl_put_Underline, 01282 OLEFontImpl_get_Strikethrough, 01283 OLEFontImpl_put_Strikethrough, 01284 OLEFontImpl_get_Weight, 01285 OLEFontImpl_put_Weight, 01286 OLEFontImpl_get_Charset, 01287 OLEFontImpl_put_Charset, 01288 OLEFontImpl_get_hFont, 01289 OLEFontImpl_Clone, 01290 OLEFontImpl_IsEqual, 01291 OLEFontImpl_SetRatio, 01292 OLEFontImpl_QueryTextMetrics, 01293 OLEFontImpl_AddRefHfont, 01294 OLEFontImpl_ReleaseHfont, 01295 OLEFontImpl_SetHdc 01296 }; 01297 01298 /************************************************************************ 01299 * OLEFontImpl_IDispatch_QueryInterface (IUnknown) 01300 * 01301 * See Windows documentation for more details on IUnknown methods. 01302 */ 01303 static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface( 01304 IDispatch* iface, 01305 REFIID riid, 01306 VOID** ppvoid) 01307 { 01308 OLEFontImpl *this = impl_from_IDispatch(iface); 01309 01310 return IFont_QueryInterface((IFont *)this, riid, ppvoid); 01311 } 01312 01313 /************************************************************************ 01314 * OLEFontImpl_IDispatch_Release (IUnknown) 01315 * 01316 * See Windows documentation for more details on IUnknown methods. 01317 */ 01318 static ULONG WINAPI OLEFontImpl_IDispatch_Release( 01319 IDispatch* iface) 01320 { 01321 OLEFontImpl *this = impl_from_IDispatch(iface); 01322 01323 return IFont_Release((IFont *)this); 01324 } 01325 01326 /************************************************************************ 01327 * OLEFontImpl_IDispatch_AddRef (IUnknown) 01328 * 01329 * See Windows documentation for more details on IUnknown methods. 01330 */ 01331 static ULONG WINAPI OLEFontImpl_IDispatch_AddRef( 01332 IDispatch* iface) 01333 { 01334 OLEFontImpl *this = impl_from_IDispatch(iface); 01335 01336 return IFont_AddRef((IFont *)this); 01337 } 01338 01339 /************************************************************************ 01340 * OLEFontImpl_GetTypeInfoCount (IDispatch) 01341 * 01342 * See Windows documentation for more details on IDispatch methods. 01343 */ 01344 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount( 01345 IDispatch* iface, 01346 unsigned int* pctinfo) 01347 { 01348 OLEFontImpl *this = impl_from_IDispatch(iface); 01349 TRACE("(%p)->(%p)\n", this, pctinfo); 01350 *pctinfo = 1; 01351 01352 return S_OK; 01353 } 01354 01355 /************************************************************************ 01356 * OLEFontImpl_GetTypeInfo (IDispatch) 01357 * 01358 * See Windows documentation for more details on IDispatch methods. 01359 */ 01360 static HRESULT WINAPI OLEFontImpl_GetTypeInfo( 01361 IDispatch* iface, 01362 UINT iTInfo, 01363 LCID lcid, 01364 ITypeInfo** ppTInfo) 01365 { 01366 static const WCHAR stdole2tlb[] = {'s','t','d','o','l','e','2','.','t','l','b',0}; 01367 ITypeLib *tl; 01368 HRESULT hres; 01369 01370 OLEFontImpl *this = impl_from_IDispatch(iface); 01371 TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo); 01372 if (iTInfo != 0) 01373 return E_FAIL; 01374 hres = LoadTypeLib(stdole2tlb, &tl); 01375 if (FAILED(hres)) { 01376 ERR("Could not load the stdole2.tlb?\n"); 01377 return hres; 01378 } 01379 hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IFontDisp, ppTInfo); 01380 ITypeLib_Release(tl); 01381 if (FAILED(hres)) { 01382 FIXME("Did not IDispatch typeinfo from typelib, hres %x\n",hres); 01383 } 01384 return hres; 01385 } 01386 01387 /************************************************************************ 01388 * OLEFontImpl_GetIDsOfNames (IDispatch) 01389 * 01390 * See Windows documentation for more details on IDispatch methods. 01391 */ 01392 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames( 01393 IDispatch* iface, 01394 REFIID riid, 01395 LPOLESTR* rgszNames, 01396 UINT cNames, 01397 LCID lcid, 01398 DISPID* rgDispId) 01399 { 01400 ITypeInfo * pTInfo; 01401 HRESULT hres; 01402 01403 OLEFontImpl *this = impl_from_IDispatch(iface); 01404 01405 TRACE("(%p,%s,%p,cNames=%d,lcid=%04x,%p)\n", this, debugstr_guid(riid), 01406 rgszNames, cNames, (int)lcid, rgDispId); 01407 01408 if (cNames == 0) 01409 { 01410 return E_INVALIDARG; 01411 } 01412 else 01413 { 01414 /* retrieve type information */ 01415 hres = OLEFontImpl_GetTypeInfo(iface, 0, lcid, &pTInfo); 01416 01417 if (FAILED(hres)) 01418 { 01419 ERR("GetTypeInfo failed.\n"); 01420 return hres; 01421 } 01422 01423 /* convert names to DISPIDs */ 01424 hres = DispGetIDsOfNames (pTInfo, rgszNames, cNames, rgDispId); 01425 ITypeInfo_Release(pTInfo); 01426 01427 return hres; 01428 } 01429 } 01430 01431 /************************************************************************ 01432 * OLEFontImpl_Invoke (IDispatch) 01433 * 01434 * See Windows documentation for more details on IDispatch methods. 01435 * 01436 * Note: Do not call _put_Xxx methods, since setting things here 01437 * should not call notify functions as I found out debugging the generic 01438 * MS VB5 installer. 01439 */ 01440 static HRESULT WINAPI OLEFontImpl_Invoke( 01441 IDispatch* iface, 01442 DISPID dispIdMember, 01443 REFIID riid, 01444 LCID lcid, 01445 WORD wFlags, 01446 DISPPARAMS* pDispParams, 01447 VARIANT* pVarResult, 01448 EXCEPINFO* pExepInfo, 01449 UINT* puArgErr) 01450 { 01451 OLEFontImpl *this = impl_from_IDispatch(iface); 01452 HRESULT hr; 01453 01454 TRACE("%p->(%d,%s,0x%x,0x%x,%p,%p,%p,%p)\n", this, dispIdMember, 01455 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExepInfo, 01456 puArgErr); 01457 01458 /* validate parameters */ 01459 01460 if (!IsEqualIID(riid, &IID_NULL)) 01461 { 01462 ERR("riid was %s instead of IID_NULL\n", debugstr_guid(riid)); 01463 return DISP_E_UNKNOWNINTERFACE; 01464 } 01465 01466 if (wFlags & DISPATCH_PROPERTYGET) 01467 { 01468 if (!pVarResult) 01469 { 01470 ERR("null pVarResult not allowed when DISPATCH_PROPERTYGET specified\n"); 01471 return DISP_E_PARAMNOTOPTIONAL; 01472 } 01473 } 01474 else if (wFlags & DISPATCH_PROPERTYPUT) 01475 { 01476 if (!pDispParams) 01477 { 01478 ERR("null pDispParams not allowed when DISPATCH_PROPERTYPUT specified\n"); 01479 return DISP_E_PARAMNOTOPTIONAL; 01480 } 01481 if (pDispParams->cArgs != 1) 01482 { 01483 ERR("param count for DISPATCH_PROPERTYPUT was %d instead of 1\n", pDispParams->cArgs); 01484 return DISP_E_BADPARAMCOUNT; 01485 } 01486 } 01487 else 01488 { 01489 ERR("one of DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT must be specified\n"); 01490 return DISP_E_MEMBERNOTFOUND; 01491 } 01492 01493 switch (dispIdMember) { 01494 case DISPID_FONT_NAME: 01495 if (wFlags & DISPATCH_PROPERTYGET) { 01496 V_VT(pVarResult) = VT_BSTR; 01497 return IFont_get_Name((IFont *)this, &V_BSTR(pVarResult)); 01498 } else { 01499 VARIANTARG vararg; 01500 01501 VariantInit(&vararg); 01502 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BSTR); 01503 if (FAILED(hr)) 01504 return hr; 01505 01506 hr = IFont_put_Name((IFont *)this, V_BSTR(&vararg)); 01507 01508 VariantClear(&vararg); 01509 return hr; 01510 } 01511 break; 01512 case DISPID_FONT_BOLD: 01513 if (wFlags & DISPATCH_PROPERTYGET) { 01514 BOOL value; 01515 hr = IFont_get_Bold((IFont *)this, &value); 01516 V_VT(pVarResult) = VT_BOOL; 01517 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; 01518 return hr; 01519 } else { 01520 VARIANTARG vararg; 01521 01522 VariantInit(&vararg); 01523 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); 01524 if (FAILED(hr)) 01525 return hr; 01526 01527 hr = IFont_put_Bold((IFont *)this, V_BOOL(&vararg)); 01528 01529 VariantClear(&vararg); 01530 return hr; 01531 } 01532 break; 01533 case DISPID_FONT_ITALIC: 01534 if (wFlags & DISPATCH_PROPERTYGET) { 01535 BOOL value; 01536 hr = IFont_get_Italic((IFont *)this, &value); 01537 V_VT(pVarResult) = VT_BOOL; 01538 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; 01539 return hr; 01540 } else { 01541 VARIANTARG vararg; 01542 01543 VariantInit(&vararg); 01544 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); 01545 if (FAILED(hr)) 01546 return hr; 01547 01548 hr = IFont_put_Italic((IFont *)this, V_BOOL(&vararg)); 01549 01550 VariantClear(&vararg); 01551 return hr; 01552 } 01553 break; 01554 case DISPID_FONT_UNDER: 01555 if (wFlags & DISPATCH_PROPERTYGET) { 01556 BOOL value; 01557 hr = IFont_get_Underline((IFont *)this, &value); 01558 V_VT(pVarResult) = VT_BOOL; 01559 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; 01560 return hr; 01561 } else { 01562 VARIANTARG vararg; 01563 01564 VariantInit(&vararg); 01565 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); 01566 if (FAILED(hr)) 01567 return hr; 01568 01569 hr = IFont_put_Underline((IFont *)this, V_BOOL(&vararg)); 01570 01571 VariantClear(&vararg); 01572 return hr; 01573 } 01574 break; 01575 case DISPID_FONT_STRIKE: 01576 if (wFlags & DISPATCH_PROPERTYGET) { 01577 BOOL value; 01578 hr = IFont_get_Strikethrough((IFont *)this, &value); 01579 V_VT(pVarResult) = VT_BOOL; 01580 V_BOOL(pVarResult) = value ? VARIANT_TRUE : VARIANT_FALSE; 01581 return hr; 01582 } else { 01583 VARIANTARG vararg; 01584 01585 VariantInit(&vararg); 01586 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_BOOL); 01587 if (FAILED(hr)) 01588 return hr; 01589 01590 hr = IFont_put_Strikethrough((IFont *)this, V_BOOL(&vararg)); 01591 01592 VariantClear(&vararg); 01593 return hr; 01594 } 01595 break; 01596 case DISPID_FONT_SIZE: 01597 if (wFlags & DISPATCH_PROPERTYGET) { 01598 V_VT(pVarResult) = VT_CY; 01599 return OLEFontImpl_get_Size((IFont *)this, &V_CY(pVarResult)); 01600 } else { 01601 VARIANTARG vararg; 01602 01603 VariantInit(&vararg); 01604 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_CY); 01605 if (FAILED(hr)) 01606 return hr; 01607 01608 hr = IFont_put_Size((IFont *)this, V_CY(&vararg)); 01609 01610 VariantClear(&vararg); 01611 return hr; 01612 } 01613 break; 01614 case DISPID_FONT_WEIGHT: 01615 if (wFlags & DISPATCH_PROPERTYGET) { 01616 V_VT(pVarResult) = VT_I2; 01617 return OLEFontImpl_get_Weight((IFont *)this, &V_I2(pVarResult)); 01618 } else { 01619 VARIANTARG vararg; 01620 01621 VariantInit(&vararg); 01622 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2); 01623 if (FAILED(hr)) 01624 return hr; 01625 01626 hr = IFont_put_Weight((IFont *)this, V_I2(&vararg)); 01627 01628 VariantClear(&vararg); 01629 return hr; 01630 } 01631 break; 01632 case DISPID_FONT_CHARSET: 01633 if (wFlags & DISPATCH_PROPERTYGET) { 01634 V_VT(pVarResult) = VT_I2; 01635 return OLEFontImpl_get_Charset((IFont *)this, &V_I2(pVarResult)); 01636 } else { 01637 VARIANTARG vararg; 01638 01639 VariantInit(&vararg); 01640 hr = VariantChangeTypeEx(&vararg, &pDispParams->rgvarg[0], lcid, 0, VT_I2); 01641 if (FAILED(hr)) 01642 return hr; 01643 01644 hr = IFont_put_Charset((IFont *)this, V_I2(&vararg)); 01645 01646 VariantClear(&vararg); 01647 return hr; 01648 } 01649 break; 01650 default: 01651 ERR("member not found for dispid 0x%x\n", dispIdMember); 01652 return DISP_E_MEMBERNOTFOUND; 01653 } 01654 } 01655 01656 static const IDispatchVtbl OLEFontImpl_IDispatch_VTable = 01657 { 01658 OLEFontImpl_IDispatch_QueryInterface, 01659 OLEFontImpl_IDispatch_AddRef, 01660 OLEFontImpl_IDispatch_Release, 01661 OLEFontImpl_GetTypeInfoCount, 01662 OLEFontImpl_GetTypeInfo, 01663 OLEFontImpl_GetIDsOfNames, 01664 OLEFontImpl_Invoke 01665 }; 01666 01667 /************************************************************************ 01668 * OLEFontImpl_IPersistStream_QueryInterface (IUnknown) 01669 * 01670 * See Windows documentation for more details on IUnknown methods. 01671 */ 01672 static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface( 01673 IPersistStream* iface, 01674 REFIID riid, 01675 VOID** ppvoid) 01676 { 01677 OLEFontImpl *this = impl_from_IPersistStream(iface); 01678 01679 return IFont_QueryInterface((IFont *)this, riid, ppvoid); 01680 } 01681 01682 /************************************************************************ 01683 * OLEFontImpl_IPersistStream_Release (IUnknown) 01684 * 01685 * See Windows documentation for more details on IUnknown methods. 01686 */ 01687 static ULONG WINAPI OLEFontImpl_IPersistStream_Release( 01688 IPersistStream* iface) 01689 { 01690 OLEFontImpl *this = impl_from_IPersistStream(iface); 01691 01692 return IFont_Release((IFont *)this); 01693 } 01694 01695 /************************************************************************ 01696 * OLEFontImpl_IPersistStream_AddRef (IUnknown) 01697 * 01698 * See Windows documentation for more details on IUnknown methods. 01699 */ 01700 static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef( 01701 IPersistStream* iface) 01702 { 01703 OLEFontImpl *this = impl_from_IPersistStream(iface); 01704 01705 return IFont_AddRef((IFont *)this); 01706 } 01707 01708 /************************************************************************ 01709 * OLEFontImpl_GetClassID (IPersistStream) 01710 * 01711 * See Windows documentation for more details on IPersistStream methods. 01712 */ 01713 static HRESULT WINAPI OLEFontImpl_GetClassID( 01714 IPersistStream* iface, 01715 CLSID* pClassID) 01716 { 01717 TRACE("(%p,%p)\n",iface,pClassID); 01718 if (pClassID==0) 01719 return E_POINTER; 01720 01721 *pClassID = CLSID_StdFont; 01722 01723 return S_OK; 01724 } 01725 01726 /************************************************************************ 01727 * OLEFontImpl_IsDirty (IPersistStream) 01728 * 01729 * See Windows documentation for more details on IPersistStream methods. 01730 */ 01731 static HRESULT WINAPI OLEFontImpl_IsDirty( 01732 IPersistStream* iface) 01733 { 01734 TRACE("(%p)\n",iface); 01735 return S_OK; 01736 } 01737 01738 /************************************************************************ 01739 * OLEFontImpl_Load (IPersistStream) 01740 * 01741 * See Windows documentation for more details on IPersistStream methods. 01742 * 01743 * This is the format of the standard font serialization as far as I 01744 * know 01745 * 01746 * Offset Type Value Comment 01747 * 0x0000 Byte Unknown Probably a version number, contains 0x01 01748 * 0x0001 Short Charset Charset value from the FONTDESC structure 01749 * 0x0003 Byte Attributes Flags defined as follows: 01750 * 00000010 - Italic 01751 * 00000100 - Underline 01752 * 00001000 - Strikethrough 01753 * 0x0004 Short Weight Weight value from FONTDESC structure 01754 * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC 01755 * structure/ 01756 * 0x000A Byte name length Length of the font name string (no null character) 01757 * 0x000B String name Name of the font (ASCII, no nul character) 01758 */ 01759 static HRESULT WINAPI OLEFontImpl_Load( 01760 IPersistStream* iface, 01761 IStream* pLoadStream) 01762 { 01763 char readBuffer[0x100]; 01764 ULONG cbRead; 01765 BYTE bVersion; 01766 BYTE bAttributes; 01767 BYTE bStringSize; 01768 INT len; 01769 01770 OLEFontImpl *this = impl_from_IPersistStream(iface); 01771 01772 /* 01773 * Read the version byte 01774 */ 01775 IStream_Read(pLoadStream, &bVersion, 1, &cbRead); 01776 01777 if ( (cbRead!=1) || 01778 (bVersion!=0x01) ) 01779 return E_FAIL; 01780 01781 /* 01782 * Charset 01783 */ 01784 IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead); 01785 01786 if (cbRead!=2) 01787 return E_FAIL; 01788 01789 /* 01790 * Attributes 01791 */ 01792 IStream_Read(pLoadStream, &bAttributes, 1, &cbRead); 01793 01794 if (cbRead!=1) 01795 return E_FAIL; 01796 01797 this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0; 01798 this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0; 01799 this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0; 01800 01801 /* 01802 * Weight 01803 */ 01804 IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead); 01805 01806 if (cbRead!=2) 01807 return E_FAIL; 01808 01809 /* 01810 * Size 01811 */ 01812 IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead); 01813 01814 if (cbRead!=4) 01815 return E_FAIL; 01816 01817 this->description.cySize.s.Hi = 0; 01818 01819 /* 01820 * FontName 01821 */ 01822 IStream_Read(pLoadStream, &bStringSize, 1, &cbRead); 01823 01824 if (cbRead!=1) 01825 return E_FAIL; 01826 01827 IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead); 01828 01829 if (cbRead!=bStringSize) 01830 return E_FAIL; 01831 01832 HeapFree(GetProcessHeap(), 0, this->description.lpstrName); 01833 01834 len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 ); 01835 this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) ); 01836 MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len ); 01837 this->description.lpstrName[len] = 0; 01838 01839 /* Ensure use of this font causes a new one to be created */ 01840 dec_int_ref(this->gdiFont); 01841 this->gdiFont = 0; 01842 this->dirty = TRUE; 01843 01844 return S_OK; 01845 } 01846 01847 /************************************************************************ 01848 * OLEFontImpl_Save (IPersistStream) 01849 * 01850 * See Windows documentation for more details on IPersistStream methods. 01851 */ 01852 static HRESULT WINAPI OLEFontImpl_Save( 01853 IPersistStream* iface, 01854 IStream* pOutStream, 01855 BOOL fClearDirty) 01856 { 01857 char* writeBuffer = NULL; 01858 ULONG cbWritten; 01859 BYTE bVersion = 0x01; 01860 BYTE bAttributes; 01861 BYTE bStringSize; 01862 01863 OLEFontImpl *this = impl_from_IPersistStream(iface); 01864 01865 /* 01866 * Read the version byte 01867 */ 01868 IStream_Write(pOutStream, &bVersion, 1, &cbWritten); 01869 01870 if (cbWritten!=1) 01871 return E_FAIL; 01872 01873 /* 01874 * Charset 01875 */ 01876 IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten); 01877 01878 if (cbWritten!=2) 01879 return E_FAIL; 01880 01881 /* 01882 * Attributes 01883 */ 01884 bAttributes = 0; 01885 01886 if (this->description.fItalic) 01887 bAttributes |= FONTPERSIST_ITALIC; 01888 01889 if (this->description.fStrikethrough) 01890 bAttributes |= FONTPERSIST_STRIKETHROUGH; 01891 01892 if (this->description.fUnderline) 01893 bAttributes |= FONTPERSIST_UNDERLINE; 01894 01895 IStream_Write(pOutStream, &bAttributes, 1, &cbWritten); 01896 01897 if (cbWritten!=1) 01898 return E_FAIL; 01899 01900 /* 01901 * Weight 01902 */ 01903 IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten); 01904 01905 if (cbWritten!=2) 01906 return E_FAIL; 01907 01908 /* 01909 * Size 01910 */ 01911 IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten); 01912 01913 if (cbWritten!=4) 01914 return E_FAIL; 01915 01916 /* 01917 * FontName 01918 */ 01919 if (this->description.lpstrName!=0) 01920 bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, 01921 strlenW(this->description.lpstrName), NULL, 0, NULL, NULL ); 01922 else 01923 bStringSize = 0; 01924 01925 IStream_Write(pOutStream, &bStringSize, 1, &cbWritten); 01926 01927 if (cbWritten!=1) 01928 return E_FAIL; 01929 01930 if (bStringSize!=0) 01931 { 01932 if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY; 01933 WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, 01934 strlenW(this->description.lpstrName), 01935 writeBuffer, bStringSize, NULL, NULL ); 01936 01937 IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten); 01938 HeapFree(GetProcessHeap(), 0, writeBuffer); 01939 01940 if (cbWritten!=bStringSize) 01941 return E_FAIL; 01942 } 01943 01944 return S_OK; 01945 } 01946 01947 /************************************************************************ 01948 * OLEFontImpl_GetSizeMax (IPersistStream) 01949 * 01950 * See Windows documentation for more details on IPersistStream methods. 01951 */ 01952 static HRESULT WINAPI OLEFontImpl_GetSizeMax( 01953 IPersistStream* iface, 01954 ULARGE_INTEGER* pcbSize) 01955 { 01956 OLEFontImpl *this = impl_from_IPersistStream(iface); 01957 01958 if (pcbSize==NULL) 01959 return E_POINTER; 01960 01961 pcbSize->u.HighPart = 0; 01962 pcbSize->u.LowPart = 0; 01963 01964 pcbSize->u.LowPart += sizeof(BYTE); /* Version */ 01965 pcbSize->u.LowPart += sizeof(WORD); /* Lang code */ 01966 pcbSize->u.LowPart += sizeof(BYTE); /* Flags */ 01967 pcbSize->u.LowPart += sizeof(WORD); /* Weight */ 01968 pcbSize->u.LowPart += sizeof(DWORD); /* Size */ 01969 pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */ 01970 01971 if (this->description.lpstrName!=0) 01972 pcbSize->u.LowPart += WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName, 01973 strlenW(this->description.lpstrName), 01974 NULL, 0, NULL, NULL ); 01975 01976 return S_OK; 01977 } 01978 01979 static const IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable = 01980 { 01981 OLEFontImpl_IPersistStream_QueryInterface, 01982 OLEFontImpl_IPersistStream_AddRef, 01983 OLEFontImpl_IPersistStream_Release, 01984 OLEFontImpl_GetClassID, 01985 OLEFontImpl_IsDirty, 01986 OLEFontImpl_Load, 01987 OLEFontImpl_Save, 01988 OLEFontImpl_GetSizeMax 01989 }; 01990 01991 /************************************************************************ 01992 * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown) 01993 * 01994 * See Windows documentation for more details on IUnknown methods. 01995 */ 01996 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface( 01997 IConnectionPointContainer* iface, 01998 REFIID riid, 01999 VOID** ppvoid) 02000 { 02001 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); 02002 02003 return IFont_QueryInterface((IFont*)this, riid, ppvoid); 02004 } 02005 02006 /************************************************************************ 02007 * OLEFontImpl_IConnectionPointContainer_Release (IUnknown) 02008 * 02009 * See Windows documentation for more details on IUnknown methods. 02010 */ 02011 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release( 02012 IConnectionPointContainer* iface) 02013 { 02014 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); 02015 02016 return IFont_Release((IFont*)this); 02017 } 02018 02019 /************************************************************************ 02020 * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown) 02021 * 02022 * See Windows documentation for more details on IUnknown methods. 02023 */ 02024 static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef( 02025 IConnectionPointContainer* iface) 02026 { 02027 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); 02028 02029 return IFont_AddRef((IFont*)this); 02030 } 02031 02032 /************************************************************************ 02033 * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer) 02034 * 02035 * See Windows documentation for more details on IConnectionPointContainer 02036 * methods. 02037 */ 02038 static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints( 02039 IConnectionPointContainer* iface, 02040 IEnumConnectionPoints **ppEnum) 02041 { 02042 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); 02043 02044 FIXME("(%p)->(%p): stub\n", this, ppEnum); 02045 return E_NOTIMPL; 02046 } 02047 02048 /************************************************************************ 02049 * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer) 02050 * 02051 * See Windows documentation for more details on IConnectionPointContainer 02052 * methods. 02053 */ 02054 static HRESULT WINAPI OLEFontImpl_FindConnectionPoint( 02055 IConnectionPointContainer* iface, 02056 REFIID riid, 02057 IConnectionPoint **ppCp) 02058 { 02059 OLEFontImpl *this = impl_from_IConnectionPointContainer(iface); 02060 TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppCp); 02061 02062 if(IsEqualIID(riid, &IID_IPropertyNotifySink)) { 02063 return IConnectionPoint_QueryInterface(this->pPropertyNotifyCP, 02064 &IID_IConnectionPoint, 02065 (LPVOID)ppCp); 02066 } else if(IsEqualIID(riid, &IID_IFontEventsDisp)) { 02067 return IConnectionPoint_QueryInterface(this->pFontEventsCP, 02068 &IID_IConnectionPoint, 02069 (LPVOID)ppCp); 02070 } else { 02071 FIXME("no connection point for %s\n", debugstr_guid(riid)); 02072 return CONNECT_E_NOCONNECTION; 02073 } 02074 } 02075 02076 static const IConnectionPointContainerVtbl 02077 OLEFontImpl_IConnectionPointContainer_VTable = 02078 { 02079 OLEFontImpl_IConnectionPointContainer_QueryInterface, 02080 OLEFontImpl_IConnectionPointContainer_AddRef, 02081 OLEFontImpl_IConnectionPointContainer_Release, 02082 OLEFontImpl_EnumConnectionPoints, 02083 OLEFontImpl_FindConnectionPoint 02084 }; 02085 02086 /************************************************************************ 02087 * OLEFontImpl implementation of IPersistPropertyBag. 02088 */ 02089 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface( 02090 IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj 02091 ) { 02092 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); 02093 return IFont_QueryInterface((IFont *)this,riid,ppvObj); 02094 } 02095 02096 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef( 02097 IPersistPropertyBag *iface 02098 ) { 02099 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); 02100 return IFont_AddRef((IFont *)this); 02101 } 02102 02103 static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release( 02104 IPersistPropertyBag *iface 02105 ) { 02106 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); 02107 return IFont_Release((IFont *)this); 02108 } 02109 02110 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID( 02111 IPersistPropertyBag *iface, CLSID *classid 02112 ) { 02113 FIXME("(%p,%p), stub!\n", iface, classid); 02114 return E_FAIL; 02115 } 02116 02117 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew( 02118 IPersistPropertyBag *iface 02119 ) { 02120 FIXME("(%p), stub!\n", iface); 02121 return S_OK; 02122 } 02123 02124 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load( 02125 IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog 02126 ) { 02127 /* (from Visual Basic 6 property bag) 02128 Name = "MS Sans Serif" 02129 Size = 13.8 02130 Charset = 0 02131 Weight = 400 02132 Underline = 0 'False 02133 Italic = 0 'False 02134 Strikethrough = 0 'False 02135 */ 02136 static const WCHAR sAttrName[] = {'N','a','m','e',0}; 02137 static const WCHAR sAttrSize[] = {'S','i','z','e',0}; 02138 static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0}; 02139 static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0}; 02140 static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0}; 02141 static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0}; 02142 static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0}; 02143 VARIANT rawAttr; 02144 VARIANT valueAttr; 02145 HRESULT iRes = S_OK; 02146 OLEFontImpl *this = impl_from_IPersistPropertyBag(iface); 02147 02148 VariantInit(&rawAttr); 02149 VariantInit(&valueAttr); 02150 02151 if (iRes == S_OK) { 02152 iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog); 02153 if (iRes == S_OK) 02154 { 02155 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR); 02156 if (iRes == S_OK) 02157 iRes = IFont_put_Name((IFont *)this, V_BSTR(&valueAttr)); 02158 } 02159 else if (iRes == E_INVALIDARG) 02160 iRes = S_OK; 02161 VariantClear(&rawAttr); 02162 VariantClear(&valueAttr); 02163 } 02164 02165 if (iRes == S_OK) { 02166 iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog); 02167 if (iRes == S_OK) 02168 { 02169 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY); 02170 if (iRes == S_OK) 02171 iRes = IFont_put_Size((IFont *)this, V_CY(&valueAttr)); 02172 } 02173 else if (iRes == E_INVALIDARG) 02174 iRes = S_OK; 02175 VariantClear(&rawAttr); 02176 VariantClear(&valueAttr); 02177 } 02178 02179 if (iRes == S_OK) { 02180 iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog); 02181 if (iRes == S_OK) 02182 { 02183 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); 02184 if (iRes == S_OK) 02185 iRes = IFont_put_Charset((IFont *)this, V_I2(&valueAttr)); 02186 } 02187 else if (iRes == E_INVALIDARG) 02188 iRes = S_OK; 02189 VariantClear(&rawAttr); 02190 VariantClear(&valueAttr); 02191 } 02192 02193 if (iRes == S_OK) { 02194 iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog); 02195 if (iRes == S_OK) 02196 { 02197 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2); 02198 if (iRes == S_OK) 02199 iRes = IFont_put_Weight((IFont *)this, V_I2(&valueAttr)); 02200 } 02201 else if (iRes == E_INVALIDARG) 02202 iRes = S_OK; 02203 VariantClear(&rawAttr); 02204 VariantClear(&valueAttr); 02205 02206 } 02207 02208 if (iRes == S_OK) { 02209 iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog); 02210 if (iRes == S_OK) 02211 { 02212 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); 02213 if (iRes == S_OK) 02214 iRes = IFont_put_Underline((IFont *)this, V_BOOL(&valueAttr)); 02215 } 02216 else if (iRes == E_INVALIDARG) 02217 iRes = S_OK; 02218 VariantClear(&rawAttr); 02219 VariantClear(&valueAttr); 02220 } 02221 02222 if (iRes == S_OK) { 02223 iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog); 02224 if (iRes == S_OK) 02225 { 02226 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); 02227 if (iRes == S_OK) 02228 iRes = IFont_put_Italic((IFont *)this, V_BOOL(&valueAttr)); 02229 } 02230 else if (iRes == E_INVALIDARG) 02231 iRes = S_OK; 02232 VariantClear(&rawAttr); 02233 VariantClear(&valueAttr); 02234 } 02235 02236 if (iRes == S_OK) { 02237 iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog); 02238 if (iRes == S_OK) 02239 { 02240 iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL); 02241 if (iRes == S_OK) 02242 IFont_put_Strikethrough((IFont *)this, V_BOOL(&valueAttr)); 02243 } 02244 else if (iRes == E_INVALIDARG) 02245 iRes = S_OK; 02246 VariantClear(&rawAttr); 02247 VariantClear(&valueAttr); 02248 } 02249 02250 if (FAILED(iRes)) 02251 WARN("-- 0x%08x\n", iRes); 02252 return iRes; 02253 } 02254 02255 static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save( 02256 IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty, 02257 BOOL fSaveAllProperties 02258 ) { 02259 FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties); 02260 return E_FAIL; 02261 } 02262 02263 static const IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable = 02264 { 02265 OLEFontImpl_IPersistPropertyBag_QueryInterface, 02266 OLEFontImpl_IPersistPropertyBag_AddRef, 02267 OLEFontImpl_IPersistPropertyBag_Release, 02268 02269 OLEFontImpl_IPersistPropertyBag_GetClassID, 02270 OLEFontImpl_IPersistPropertyBag_InitNew, 02271 OLEFontImpl_IPersistPropertyBag_Load, 02272 OLEFontImpl_IPersistPropertyBag_Save 02273 }; 02274 02275 /************************************************************************ 02276 * OLEFontImpl implementation of IPersistStreamInit. 02277 */ 02278 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface( 02279 IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj 02280 ) { 02281 OLEFontImpl *this = impl_from_IPersistStreamInit(iface); 02282 return IFont_QueryInterface((IFont *)this,riid,ppvObj); 02283 } 02284 02285 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef( 02286 IPersistStreamInit *iface 02287 ) { 02288 OLEFontImpl *this = impl_from_IPersistStreamInit(iface); 02289 return IFont_AddRef((IFont *)this); 02290 } 02291 02292 static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release( 02293 IPersistStreamInit *iface 02294 ) { 02295 OLEFontImpl *this = impl_from_IPersistStreamInit(iface); 02296 return IFont_Release((IFont *)this); 02297 } 02298 02299 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID( 02300 IPersistStreamInit *iface, CLSID *classid 02301 ) { 02302 FIXME("(%p,%p), stub!\n", iface, classid); 02303 return E_FAIL; 02304 } 02305 02306 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty( 02307 IPersistStreamInit *iface 02308 ) { 02309 FIXME("(%p), stub!\n", iface); 02310 return E_FAIL; 02311 } 02312 02313 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load( 02314 IPersistStreamInit *iface, LPSTREAM pStm 02315 ) { 02316 FIXME("(%p,%p), stub!\n", iface, pStm); 02317 return E_FAIL; 02318 } 02319 02320 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save( 02321 IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty 02322 ) { 02323 FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty); 02324 return E_FAIL; 02325 } 02326 02327 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax( 02328 IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize 02329 ) { 02330 FIXME("(%p,%p), stub!\n", iface, pcbSize); 02331 return E_FAIL; 02332 } 02333 02334 static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew( 02335 IPersistStreamInit *iface 02336 ) { 02337 FIXME("(%p), stub!\n", iface); 02338 return S_OK; 02339 } 02340 02341 static const IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable = 02342 { 02343 OLEFontImpl_IPersistStreamInit_QueryInterface, 02344 OLEFontImpl_IPersistStreamInit_AddRef, 02345 OLEFontImpl_IPersistStreamInit_Release, 02346 02347 OLEFontImpl_IPersistStreamInit_GetClassID, 02348 OLEFontImpl_IPersistStreamInit_IsDirty, 02349 OLEFontImpl_IPersistStreamInit_Load, 02350 OLEFontImpl_IPersistStreamInit_Save, 02351 OLEFontImpl_IPersistStreamInit_GetSizeMax, 02352 OLEFontImpl_IPersistStreamInit_InitNew 02353 }; 02354 02355 /************************************************************************ 02356 * OLEFontImpl_Construct 02357 * 02358 * This method will construct a new instance of the OLEFontImpl 02359 * class. 02360 * 02361 * The caller of this method must release the object when it's 02362 * done with it. 02363 */ 02364 static OLEFontImpl* OLEFontImpl_Construct(const FONTDESC *fontDesc) 02365 { 02366 OLEFontImpl* newObject = 0; 02367 02368 /* 02369 * Allocate space for the object. 02370 */ 02371 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl)); 02372 02373 if (newObject==0) 02374 return newObject; 02375 02376 /* 02377 * Initialize the virtual function table. 02378 */ 02379 newObject->lpVtbl = &OLEFontImpl_VTable; 02380 newObject->lpvtblIDispatch = &OLEFontImpl_IDispatch_VTable; 02381 newObject->lpvtblIPersistStream = &OLEFontImpl_IPersistStream_VTable; 02382 newObject->lpvtblIConnectionPointContainer = &OLEFontImpl_IConnectionPointContainer_VTable; 02383 newObject->lpvtblIPersistPropertyBag = &OLEFontImpl_IPersistPropertyBag_VTable; 02384 newObject->lpvtblIPersistStreamInit = &OLEFontImpl_IPersistStreamInit_VTable; 02385 02386 /* 02387 * Start with one reference count. The caller of this function 02388 * must release the interface pointer when it is done. 02389 */ 02390 newObject->ref = 1; 02391 02392 /* 02393 * Copy the description of the font in the object. 02394 */ 02395 assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC)); 02396 02397 newObject->description.cbSizeofstruct = sizeof(FONTDESC); 02398 newObject->description.lpstrName = HeapAlloc(GetProcessHeap(), 02399 0, 02400 (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR)); 02401 strcpyW(newObject->description.lpstrName, fontDesc->lpstrName); 02402 newObject->description.cySize = fontDesc->cySize; 02403 newObject->description.sWeight = fontDesc->sWeight; 02404 newObject->description.sCharset = fontDesc->sCharset; 02405 newObject->description.fItalic = fontDesc->fItalic; 02406 newObject->description.fUnderline = fontDesc->fUnderline; 02407 newObject->description.fStrikethrough = fontDesc->fStrikethrough; 02408 02409 /* 02410 * Initializing all the other members. 02411 */ 02412 newObject->gdiFont = 0; 02413 newObject->dirty = TRUE; 02414 newObject->cyLogical = 72L; 02415 newObject->cyHimetric = 2540L; 02416 newObject->pPropertyNotifyCP = NULL; 02417 newObject->pFontEventsCP = NULL; 02418 02419 CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pPropertyNotifyCP); 02420 CreateConnectionPoint((IUnknown*)newObject, &IID_IFontEventsDisp, &newObject->pFontEventsCP); 02421 02422 if (!newObject->pPropertyNotifyCP || !newObject->pFontEventsCP) 02423 { 02424 OLEFontImpl_Destroy(newObject); 02425 return NULL; 02426 } 02427 02428 InterlockedIncrement(&ifont_cnt); 02429 02430 TRACE("returning %p\n", newObject); 02431 return newObject; 02432 } 02433 02434 /************************************************************************ 02435 * OLEFontImpl_Destroy 02436 * 02437 * This method is called by the Release method when the reference 02438 * count goes down to 0. It will free all resources used by 02439 * this object. 02440 */ 02441 static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc) 02442 { 02443 TRACE("(%p)\n", fontDesc); 02444 02445 HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName); 02446 02447 if (fontDesc->pPropertyNotifyCP) 02448 IConnectionPoint_Release(fontDesc->pPropertyNotifyCP); 02449 if (fontDesc->pFontEventsCP) 02450 IConnectionPoint_Release(fontDesc->pFontEventsCP); 02451 02452 HeapFree(GetProcessHeap(), 0, fontDesc); 02453 } 02454 02455 /******************************************************************************* 02456 * StdFont ClassFactory 02457 */ 02458 typedef struct 02459 { 02460 /* IUnknown fields */ 02461 const IClassFactoryVtbl *lpVtbl; 02462 LONG ref; 02463 } IClassFactoryImpl; 02464 02465 static HRESULT WINAPI 02466 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) { 02467 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 02468 02469 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj); 02470 return E_NOINTERFACE; 02471 } 02472 02473 static ULONG WINAPI 02474 SFCF_AddRef(LPCLASSFACTORY iface) { 02475 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 02476 return InterlockedIncrement(&This->ref); 02477 } 02478 02479 static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) { 02480 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 02481 /* static class, won't be freed */ 02482 return InterlockedDecrement(&This->ref); 02483 } 02484 02485 static HRESULT WINAPI SFCF_CreateInstance( 02486 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj 02487 ) { 02488 return OleCreateFontIndirect(NULL,riid,ppobj); 02489 02490 } 02491 02492 static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) { 02493 IClassFactoryImpl *This = (IClassFactoryImpl *)iface; 02494 FIXME("(%p)->(%d),stub!\n",This,dolock); 02495 return S_OK; 02496 } 02497 02498 static const IClassFactoryVtbl SFCF_Vtbl = { 02499 SFCF_QueryInterface, 02500 SFCF_AddRef, 02501 SFCF_Release, 02502 SFCF_CreateInstance, 02503 SFCF_LockServer 02504 }; 02505 static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 }; 02506 02507 void _get_STDFONT_CF(LPVOID *ppv) { *ppv = &STDFONT_CF; } Generated on Mon May 28 2012 04:25:25 for ReactOS by
1.7.6.1
|