-/*\r
- * OLE Font encapsulation implementation\r
- *\r
- * This file contains an implementation of the IFont\r
- * interface and the OleCreateFontIndirect API call.\r
- *\r
- * Copyright 1999 Francis Beaudet\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
- */\r
-#include <assert.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-\r
-#define COBJMACROS\r
-#define NONAMELESSUNION\r
-#define NONAMELESSSTRUCT\r
-\r
-#include "winerror.h"\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "wingdi.h"\r
-#include "winuser.h"\r
-#include "wine/unicode.h"\r
-#include "objbase.h"\r
-#include "oleauto.h" /* for SysAllocString(....) */\r
-#include "ole2.h"\r
-#include "olectl.h"\r
-#include "wine/debug.h"\r
-#include "connpt.h" /* for CreateConnectionPoint */\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(ole);\r
-\r
-/***********************************************************************\r
- * Declaration of constants used when serializing the font object.\r
- */\r
-#define FONTPERSIST_ITALIC 0x02\r
-#define FONTPERSIST_UNDERLINE 0x04\r
-#define FONTPERSIST_STRIKETHROUGH 0x08\r
-\r
-/***********************************************************************\r
- * Declaration of the implementation class for the IFont interface\r
- */\r
-typedef struct OLEFontImpl OLEFontImpl;\r
-\r
-struct OLEFontImpl\r
-{\r
- /*\r
- * This class supports many interfaces. IUnknown, IFont,\r
- * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.\r
- * The first two are supported by the first vtable, the next two are\r
- * supported by the second table and the last two have their own.\r
- */\r
- IFontVtbl* lpvtbl1;\r
- IDispatchVtbl* lpvtbl2;\r
- IPersistStreamVtbl* lpvtbl3;\r
- IConnectionPointContainerVtbl* lpvtbl4;\r
- IPersistPropertyBagVtbl* lpvtbl5;\r
- IPersistStreamInitVtbl* lpvtbl6;\r
- /*\r
- * Reference count for that instance of the class.\r
- */\r
- ULONG ref;\r
-\r
- /*\r
- * This structure contains the description of the class.\r
- */\r
- FONTDESC description;\r
-\r
- /*\r
- * Contain the font associated with this object.\r
- */\r
- HFONT gdiFont;\r
-\r
- /*\r
- * Font lock count.\r
- */\r
- DWORD fontLock;\r
-\r
- /*\r
- * Size ratio\r
- */\r
- long cyLogical;\r
- long cyHimetric;\r
-\r
- IConnectionPoint *pCP;\r
-};\r
-\r
-/*\r
- * Here, I define utility macros to help with the casting of the\r
- * "this" parameter.\r
- * There is a version to accommodate all of the VTables implemented\r
- * by this object.\r
- */\r
-#define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*))\r
-#define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*))\r
-#define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*))\r
-#define _ICOM_THIS_From_IPersistPropertyBag(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*))\r
-#define _ICOM_THIS_From_IPersistStreamInit(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*))\r
-\r
-\r
-/***********************************************************************\r
- * Prototypes for the implementation functions for the IFont\r
- * interface\r
- */\r
-static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);\r
-static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);\r
-static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);\r
-static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);\r
-static ULONG WINAPI OLEFontImpl_Release(IFont* iface);\r
-static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);\r
-static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);\r
-static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);\r
-static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);\r
-static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);\r
-static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);\r
-static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);\r
-static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);\r
-static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);\r
-static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);\r
-static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);\r
-static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);\r
-static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);\r
-static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);\r
-static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);\r
-static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);\r
-static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);\r
-static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);\r
-static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);\r
-static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, LONG cyLogical, LONG cyHimetric);\r
-static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);\r
-static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);\r
-static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);\r
-static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);\r
-\r
-/***********************************************************************\r
- * Prototypes for the implementation functions for the IDispatch\r
- * interface\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,\r
- REFIID riid,\r
- VOID** ppvoid);\r
-static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);\r
-static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);\r
-static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,\r
- unsigned int* pctinfo);\r
-static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,\r
- UINT iTInfo,\r
- LCID lcid,\r
- ITypeInfo** ppTInfo);\r
-static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,\r
- REFIID riid,\r
- LPOLESTR* rgszNames,\r
- UINT cNames,\r
- LCID lcid,\r
- DISPID* rgDispId);\r
-static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,\r
- DISPID dispIdMember,\r
- REFIID riid,\r
- LCID lcid,\r
- WORD wFlags,\r
- DISPPARAMS* pDispParams,\r
- VARIANT* pVarResult,\r
- EXCEPINFO* pExepInfo,\r
- UINT* puArgErr);\r
-\r
-/***********************************************************************\r
- * Prototypes for the implementation functions for the IPersistStream\r
- * interface\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,\r
- REFIID riid,\r
- VOID** ppvoid);\r
-static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);\r
-static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);\r
-static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,\r
- CLSID* pClassID);\r
-static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);\r
-static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,\r
- IStream* pLoadStream);\r
-static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,\r
- IStream* pOutStream,\r
- BOOL fClearDirty);\r
-static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,\r
- ULARGE_INTEGER* pcbSize);\r
-\r
-/***********************************************************************\r
- * Prototypes for the implementation functions for the\r
- * IConnectionPointContainer interface\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(\r
- IConnectionPointContainer* iface,\r
- REFIID riid,\r
- VOID** ppvoid);\r
-static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(\r
- IConnectionPointContainer* iface);\r
-static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(\r
- IConnectionPointContainer* iface);\r
-static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(\r
- IConnectionPointContainer* iface,\r
- IEnumConnectionPoints **ppEnum);\r
-static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(\r
- IConnectionPointContainer* iface,\r
- REFIID riid,\r
- IConnectionPoint **ppCp);\r
-\r
-/*\r
- * Virtual function tables for the OLEFontImpl class.\r
- */\r
-static IFontVtbl OLEFontImpl_VTable =\r
-{\r
- OLEFontImpl_QueryInterface,\r
- OLEFontImpl_AddRef,\r
- OLEFontImpl_Release,\r
- OLEFontImpl_get_Name,\r
- OLEFontImpl_put_Name,\r
- OLEFontImpl_get_Size,\r
- OLEFontImpl_put_Size,\r
- OLEFontImpl_get_Bold,\r
- OLEFontImpl_put_Bold,\r
- OLEFontImpl_get_Italic,\r
- OLEFontImpl_put_Italic,\r
- OLEFontImpl_get_Underline,\r
- OLEFontImpl_put_Underline,\r
- OLEFontImpl_get_Strikethrough,\r
- OLEFontImpl_put_Strikethrough,\r
- OLEFontImpl_get_Weight,\r
- OLEFontImpl_put_Weight,\r
- OLEFontImpl_get_Charset,\r
- OLEFontImpl_put_Charset,\r
- OLEFontImpl_get_hFont,\r
- OLEFontImpl_Clone,\r
- OLEFontImpl_IsEqual,\r
- OLEFontImpl_SetRatio,\r
- OLEFontImpl_QueryTextMetrics,\r
- OLEFontImpl_AddRefHfont,\r
- OLEFontImpl_ReleaseHfont,\r
- OLEFontImpl_SetHdc\r
-};\r
-\r
-static IDispatchVtbl OLEFontImpl_IDispatch_VTable =\r
-{\r
- OLEFontImpl_IDispatch_QueryInterface,\r
- OLEFontImpl_IDispatch_AddRef,\r
- OLEFontImpl_IDispatch_Release,\r
- OLEFontImpl_GetTypeInfoCount,\r
- OLEFontImpl_GetTypeInfo,\r
- OLEFontImpl_GetIDsOfNames,\r
- OLEFontImpl_Invoke\r
-};\r
-\r
-static IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =\r
-{\r
- OLEFontImpl_IPersistStream_QueryInterface,\r
- OLEFontImpl_IPersistStream_AddRef,\r
- OLEFontImpl_IPersistStream_Release,\r
- OLEFontImpl_GetClassID,\r
- OLEFontImpl_IsDirty,\r
- OLEFontImpl_Load,\r
- OLEFontImpl_Save,\r
- OLEFontImpl_GetSizeMax\r
-};\r
-\r
-static IConnectionPointContainerVtbl\r
- OLEFontImpl_IConnectionPointContainer_VTable =\r
-{\r
- OLEFontImpl_IConnectionPointContainer_QueryInterface,\r
- OLEFontImpl_IConnectionPointContainer_AddRef,\r
- OLEFontImpl_IConnectionPointContainer_Release,\r
- OLEFontImpl_EnumConnectionPoints,\r
- OLEFontImpl_FindConnectionPoint\r
-};\r
-\r
-static IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable;\r
-static IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable;\r
-/******************************************************************************\r
- * OleCreateFontIndirect [OLEAUT32.420]\r
- */\r
-HRESULT WINAPI OleCreateFontIndirect(\r
- LPFONTDESC lpFontDesc,\r
- REFIID riid,\r
- LPVOID* ppvObj)\r
-{\r
- OLEFontImpl* newFont = 0;\r
- HRESULT hr = S_OK;\r
-\r
- TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);\r
- /*\r
- * Sanity check\r
- */\r
- if (ppvObj==0)\r
- return E_POINTER;\r
-\r
- *ppvObj = 0;\r
-\r
- if (!lpFontDesc) {\r
- FONTDESC fd;\r
-\r
- static const WCHAR fname[] = { 'S','y','s','t','e','m',0 };\r
-\r
- fd.cbSizeofstruct = sizeof(fd);\r
- fd.lpstrName = (WCHAR*)fname;\r
- fd.cySize.s.Lo = 80000;\r
- fd.cySize.s.Hi = 0;\r
- fd.sWeight = 0;\r
- fd.sCharset = 0;\r
- fd.fItalic = 0;\r
- fd.fUnderline = 0;\r
- fd.fStrikethrough = 0;\r
- lpFontDesc = &fd;\r
- }\r
-\r
- /*\r
- * Try to construct a new instance of the class.\r
- */\r
- newFont = OLEFontImpl_Construct(lpFontDesc);\r
-\r
- if (newFont == 0)\r
- return E_OUTOFMEMORY;\r
-\r
- /*\r
- * Make sure it supports the interface required by the caller.\r
- */\r
- hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);\r
-\r
- /*\r
- * Release the reference obtained in the constructor. If\r
- * the QueryInterface was unsuccessful, it will free the class.\r
- */\r
- IFont_Release((IFont*)newFont);\r
-\r
- return hr;\r
-}\r
-\r
-\r
-/***********************************************************************\r
- * Implementation of the OLEFontImpl class.\r
- */\r
-\r
-/***********************************************************************\r
- * OLEFont_SendNotify (internal)\r
- *\r
- * Sends notification messages of changed properties to any interested\r
- * connections.\r
- */\r
-static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)\r
-{\r
- IEnumConnections *pEnum;\r
- CONNECTDATA CD;\r
- HRESULT hres;\r
-\r
- hres = IConnectionPoint_EnumConnections(this->pCP, &pEnum);\r
- if (FAILED(hres)) /* When we have 0 connections. */\r
- return;\r
-\r
- while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {\r
- IPropertyNotifySink *sink;\r
-\r
- IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);\r
- IPropertyNotifySink_OnChanged(sink, dispID);\r
- IPropertyNotifySink_Release(sink);\r
- IUnknown_Release(CD.pUnk);\r
- }\r
- IEnumConnections_Release(pEnum);\r
- return;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Construct\r
- *\r
- * This method will construct a new instance of the OLEFontImpl\r
- * class.\r
- *\r
- * The caller of this method must release the object when it's\r
- * done with it.\r
- */\r
-static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)\r
-{\r
- OLEFontImpl* newObject = 0;\r
-\r
- /*\r
- * Allocate space for the object.\r
- */\r
- newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));\r
-\r
- if (newObject==0)\r
- return newObject;\r
-\r
- /*\r
- * Initialize the virtual function table.\r
- */\r
- newObject->lpvtbl1 = &OLEFontImpl_VTable;\r
- newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;\r
- newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;\r
- newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;\r
- newObject->lpvtbl5 = &OLEFontImpl_IPersistPropertyBag_VTable;\r
- newObject->lpvtbl6 = &OLEFontImpl_IPersistStreamInit_VTable;\r
-\r
- /*\r
- * Start with one reference count. The caller of this function\r
- * must release the interface pointer when it is done.\r
- */\r
- newObject->ref = 1;\r
-\r
- /*\r
- * Copy the description of the font in the object.\r
- */\r
- assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));\r
-\r
- newObject->description.cbSizeofstruct = sizeof(FONTDESC);\r
- newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),\r
- 0,\r
- (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));\r
- strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);\r
- newObject->description.cySize = fontDesc->cySize;\r
- newObject->description.sWeight = fontDesc->sWeight;\r
- newObject->description.sCharset = fontDesc->sCharset;\r
- newObject->description.fItalic = fontDesc->fItalic;\r
- newObject->description.fUnderline = fontDesc->fUnderline;\r
- newObject->description.fStrikethrough = fontDesc->fStrikethrough;\r
-\r
- /*\r
- * Initializing all the other members.\r
- */\r
- newObject->gdiFont = 0;\r
- newObject->fontLock = 0;\r
- newObject->cyLogical = 72L;\r
- newObject->cyHimetric = 2540L;\r
- CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);\r
- TRACE("returning %p\n", newObject);\r
- return newObject;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Destroy\r
- *\r
- * This method is called by the Release method when the reference\r
- * count goes down to 0. It will free all resources used by\r
- * this object.\r
- */\r
-static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)\r
-{\r
- TRACE("(%p)\n", fontDesc);\r
-\r
- HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);\r
-\r
- if (fontDesc->gdiFont!=0)\r
- DeleteObject(fontDesc->gdiFont);\r
-\r
- HeapFree(GetProcessHeap(), 0, fontDesc);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_QueryInterface (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-HRESULT WINAPI OLEFontImpl_QueryInterface(\r
- IFont* iface,\r
- REFIID riid,\r
- void** ppvObject)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);\r
-\r
- /*\r
- * Perform a sanity check on the parameters.\r
- */\r
- if ( (this==0) || (ppvObject==0) )\r
- return E_INVALIDARG;\r
-\r
- /*\r
- * Initialize the return parameter.\r
- */\r
- *ppvObject = 0;\r
-\r
- /*\r
- * Compare the riid with the interface IDs implemented by this object.\r
- */\r
- if (IsEqualGUID(&IID_IUnknown, riid))\r
- *ppvObject = (IFont*)this;\r
- if (IsEqualGUID(&IID_IFont, riid))\r
- *ppvObject = (IFont*)this;\r
- if (IsEqualGUID(&IID_IDispatch, riid))\r
- *ppvObject = (IDispatch*)&(this->lpvtbl2);\r
- if (IsEqualGUID(&IID_IFontDisp, riid))\r
- *ppvObject = (IDispatch*)&(this->lpvtbl2);\r
- if (IsEqualGUID(&IID_IPersistStream, riid))\r
- *ppvObject = (IPersistStream*)&(this->lpvtbl3);\r
- if (IsEqualGUID(&IID_IConnectionPointContainer, riid))\r
- *ppvObject = (IConnectionPointContainer*)&(this->lpvtbl4);\r
- if (IsEqualGUID(&IID_IPersistPropertyBag, riid))\r
- *ppvObject = (IPersistPropertyBag*)&(this->lpvtbl5);\r
- if (IsEqualGUID(&IID_IPersistStreamInit, riid))\r
- *ppvObject = (IPersistStreamInit*)&(this->lpvtbl6);\r
-\r
- /*\r
- * Check that we obtained an interface.\r
- */\r
- if ((*ppvObject)==0)\r
- {\r
- FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));\r
- return E_NOINTERFACE;\r
- }\r
- OLEFontImpl_AddRef((IFont*)this);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_AddRef (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-ULONG WINAPI OLEFontImpl_AddRef(\r
- IFont* iface)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(ref=%ld)\n", this, this->ref);\r
- return InterlockedIncrement(&this->ref);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Release (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-ULONG WINAPI OLEFontImpl_Release(\r
- IFont* iface)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- ULONG ret;\r
- TRACE("(%p)->(ref=%ld)\n", this, this->ref);\r
-\r
- /*\r
- * Decrease the reference count on this object.\r
- */\r
- ret = InterlockedDecrement(&this->ref);\r
-\r
- /*\r
- * If the reference count goes down to 0, perform suicide.\r
- */\r
- if (ret==0) OLEFontImpl_Destroy(this);\r
-\r
- return ret;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Name (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Name(\r
- IFont* iface,\r
- BSTR* pname)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, pname);\r
- /*\r
- * Sanity check.\r
- */\r
- if (pname==0)\r
- return E_POINTER;\r
-\r
- if (this->description.lpstrName!=0)\r
- *pname = SysAllocString(this->description.lpstrName);\r
- else\r
- *pname = 0;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Name (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Name(\r
- IFont* iface,\r
- BSTR name)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, name);\r
-\r
- if (this->description.lpstrName==0)\r
- {\r
- this->description.lpstrName = HeapAlloc(GetProcessHeap(),\r
- 0,\r
- (lstrlenW(name)+1) * sizeof(WCHAR));\r
- }\r
- else\r
- {\r
- this->description.lpstrName = HeapReAlloc(GetProcessHeap(),\r
- 0,\r
- this->description.lpstrName,\r
- (lstrlenW(name)+1) * sizeof(WCHAR));\r
- }\r
-\r
- if (this->description.lpstrName==0)\r
- return E_OUTOFMEMORY;\r
-\r
- strcpyW(this->description.lpstrName, name);\r
- TRACE("new name %s\n", debugstr_w(this->description.lpstrName));\r
- OLEFont_SendNotify(this, DISPID_FONT_NAME);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Size (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Size(\r
- IFont* iface,\r
- CY* psize)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, psize);\r
-\r
- /*\r
- * Sanity check\r
- */\r
- if (psize==0)\r
- return E_POINTER;\r
-\r
- psize->s.Hi = 0;\r
- psize->s.Lo = this->description.cySize.s.Lo;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Size (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Size(\r
- IFont* iface,\r
- CY size)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%ld)\n", this, size.s.Lo);\r
- this->description.cySize.s.Hi = 0;\r
- this->description.cySize.s.Lo = size.s.Lo;\r
- OLEFont_SendNotify(this, DISPID_FONT_SIZE);\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Bold (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Bold(\r
- IFont* iface,\r
- BOOL* pbold)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, pbold);\r
- /*\r
- * Sanity check\r
- */\r
- if (pbold==0)\r
- return E_POINTER;\r
-\r
- *pbold = this->description.sWeight > 550;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Bold (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Bold(\r
- IFont* iface,\r
- BOOL bold)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%d)\n", this, bold);\r
- this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;\r
- OLEFont_SendNotify(this, DISPID_FONT_BOLD);\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Italic (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Italic(\r
- IFont* iface,\r
- BOOL* pitalic)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, pitalic);\r
- /*\r
- * Sanity check\r
- */\r
- if (pitalic==0)\r
- return E_POINTER;\r
-\r
- *pitalic = this->description.fItalic;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Italic (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Italic(\r
- IFont* iface,\r
- BOOL italic)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%d)\n", this, italic);\r
-\r
- this->description.fItalic = italic;\r
-\r
- OLEFont_SendNotify(this, DISPID_FONT_ITALIC);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Underline (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Underline(\r
- IFont* iface,\r
- BOOL* punderline)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, punderline);\r
-\r
- /*\r
- * Sanity check\r
- */\r
- if (punderline==0)\r
- return E_POINTER;\r
-\r
- *punderline = this->description.fUnderline;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Underline (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Underline(\r
- IFont* iface,\r
- BOOL underline)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%d)\n", this, underline);\r
-\r
- this->description.fUnderline = underline;\r
-\r
- OLEFont_SendNotify(this, DISPID_FONT_UNDER);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Strikethrough (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Strikethrough(\r
- IFont* iface,\r
- BOOL* pstrikethrough)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, pstrikethrough);\r
-\r
- /*\r
- * Sanity check\r
- */\r
- if (pstrikethrough==0)\r
- return E_POINTER;\r
-\r
- *pstrikethrough = this->description.fStrikethrough;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Strikethrough (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Strikethrough(\r
- IFont* iface,\r
- BOOL strikethrough)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%d)\n", this, strikethrough);\r
-\r
- this->description.fStrikethrough = strikethrough;\r
- OLEFont_SendNotify(this, DISPID_FONT_STRIKE);\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Weight (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Weight(\r
- IFont* iface,\r
- short* pweight)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, pweight);\r
-\r
- /*\r
- * Sanity check\r
- */\r
- if (pweight==0)\r
- return E_POINTER;\r
-\r
- *pweight = this->description.sWeight;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Weight (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Weight(\r
- IFont* iface,\r
- short weight)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%d)\n", this, weight);\r
-\r
- this->description.sWeight = weight;\r
-\r
- OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_Charset (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_Charset(\r
- IFont* iface,\r
- short* pcharset)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, pcharset);\r
-\r
- /*\r
- * Sanity check\r
- */\r
- if (pcharset==0)\r
- return E_POINTER;\r
-\r
- *pcharset = this->description.sCharset;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_put_Charset (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_put_Charset(\r
- IFont* iface,\r
- short charset)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%d)\n", this, charset);\r
-\r
- this->description.sCharset = charset;\r
- OLEFont_SendNotify(this, DISPID_FONT_CHARSET);\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_get_hFont (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_get_hFont(\r
- IFont* iface,\r
- HFONT* phfont)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, phfont);\r
- if (phfont==NULL)\r
- return E_POINTER;\r
-\r
- /*\r
- * Realize the font if necessary\r
- */\r
- if (this->gdiFont==0)\r
-{\r
- LOGFONTW logFont;\r
- INT fontHeight;\r
- CY cySize;\r
-\r
- /*\r
- * The height of the font returned by the get_Size property is the\r
- * height of the font in points multiplied by 10000... Using some\r
- * simple conversions and the ratio given by the application, it can\r
- * be converted to a height in pixels.\r
- */\r
- IFont_get_Size(iface, &cySize);\r
-\r
- fontHeight = MulDiv( cySize.s.Lo, this->cyLogical, this->cyHimetric );\r
-\r
- memset(&logFont, 0, sizeof(LOGFONTW));\r
-\r
- logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :\r
- (-fontHeight/10000L);\r
- logFont.lfItalic = this->description.fItalic;\r
- logFont.lfUnderline = this->description.fUnderline;\r
- logFont.lfStrikeOut = this->description.fStrikethrough;\r
- logFont.lfWeight = this->description.sWeight;\r
- logFont.lfCharSet = this->description.sCharset;\r
- logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;\r
- logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
- logFont.lfQuality = DEFAULT_QUALITY;\r
- logFont.lfPitchAndFamily = DEFAULT_PITCH;\r
- strcpyW(logFont.lfFaceName,this->description.lpstrName);\r
-\r
- this->gdiFont = CreateFontIndirectW(&logFont);\r
- }\r
-\r
- *phfont = this->gdiFont;\r
- TRACE("Returning %p\n", *phfont);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Clone (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_Clone(\r
- IFont* iface,\r
- IFont** ppfont)\r
-{\r
- OLEFontImpl* newObject = 0;\r
- LOGFONTW logFont;\r
- INT fontHeight;\r
- CY cySize;\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p)\n", this, ppfont);\r
-\r
- if (ppfont == NULL)\r
- return E_POINTER;\r
-\r
- *ppfont = NULL;\r
-\r
- /*\r
- * Allocate space for the object.\r
- */\r
- newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));\r
-\r
- if (newObject==NULL)\r
- return E_OUTOFMEMORY;\r
-\r
- *newObject = *this;\r
-\r
- /* We need to alloc new memory for the string, otherwise\r
- * we free memory twice.\r
- */\r
- newObject->description.lpstrName = HeapAlloc(\r
- GetProcessHeap(),0,\r
- (1+strlenW(this->description.lpstrName))*2\r
- );\r
- strcpyW(newObject->description.lpstrName, this->description.lpstrName);\r
- /* We need to clone the HFONT too. This is just cut & paste from above */\r
- IFont_get_Size(iface, &cySize);\r
-\r
- fontHeight = MulDiv(cySize.s.Lo, this->cyLogical,this->cyHimetric);\r
-\r
- memset(&logFont, 0, sizeof(LOGFONTW));\r
-\r
- logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :\r
- (-fontHeight/10000L);\r
- logFont.lfItalic = this->description.fItalic;\r
- logFont.lfUnderline = this->description.fUnderline;\r
- logFont.lfStrikeOut = this->description.fStrikethrough;\r
- logFont.lfWeight = this->description.sWeight;\r
- logFont.lfCharSet = this->description.sCharset;\r
- logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;\r
- logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
- logFont.lfQuality = DEFAULT_QUALITY;\r
- logFont.lfPitchAndFamily = DEFAULT_PITCH;\r
- strcpyW(logFont.lfFaceName,this->description.lpstrName);\r
-\r
- newObject->gdiFont = CreateFontIndirectW(&logFont);\r
-\r
-\r
- /* The cloned object starts with a reference count of 1 */\r
- newObject->ref = 1;\r
-\r
- *ppfont = (IFont*)newObject;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IsEqual (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IsEqual(\r
- IFont* iface,\r
- IFont* pFontOther)\r
-{\r
- FIXME("(%p, %p), stub!\n",iface,pFontOther);\r
- return E_NOTIMPL;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_SetRatio (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_SetRatio(\r
- IFont* iface,\r
- LONG cyLogical,\r
- LONG cyHimetric)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);\r
-\r
- this->cyLogical = cyLogical;\r
- this->cyHimetric = cyHimetric;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_QueryTextMetrics (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(\r
- IFont* iface,\r
- TEXTMETRICOLE* ptm)\r
-{\r
- HDC hdcRef;\r
- HFONT hOldFont, hNewFont;\r
-\r
- hdcRef = GetDC(0);\r
- OLEFontImpl_get_hFont(iface, &hNewFont);\r
- hOldFont = SelectObject(hdcRef, hNewFont);\r
- GetTextMetricsW(hdcRef, ptm);\r
- SelectObject(hdcRef, hOldFont);\r
- ReleaseDC(0, hdcRef);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_AddRefHfont (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_AddRefHfont(\r
- IFont* iface,\r
- HFONT hfont)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);\r
-\r
- if ( (hfont == 0) ||\r
- (hfont != this->gdiFont) )\r
- return E_INVALIDARG;\r
-\r
- this->fontLock++;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_ReleaseHfont (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_ReleaseHfont(\r
- IFont* iface,\r
- HFONT hfont)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);\r
-\r
- if ( (hfont == 0) ||\r
- (hfont != this->gdiFont) )\r
- return E_INVALIDARG;\r
-\r
- this->fontLock--;\r
-\r
- /*\r
- * If we just released our last font reference, destroy it.\r
- */\r
- if (this->fontLock==0)\r
- {\r
- DeleteObject(this->gdiFont);\r
- this->gdiFont = 0;\r
- }\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_SetHdc (IFont)\r
- *\r
- * See Windows documentation for more details on IFont methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_SetHdc(\r
- IFont* iface,\r
- HDC hdc)\r
-{\r
- OLEFontImpl *this = (OLEFontImpl *)iface;\r
- FIXME("(%p)->(%p): Stub\n", this, hdc);\r
- return E_NOTIMPL;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IDispatch_QueryInterface (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(\r
- IDispatch* iface,\r
- REFIID riid,\r
- VOID** ppvoid)\r
-{\r
- _ICOM_THIS_From_IDispatch(IFont, iface);\r
-\r
- return IFont_QueryInterface(this, riid, ppvoid);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IDispatch_Release (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static ULONG WINAPI OLEFontImpl_IDispatch_Release(\r
- IDispatch* iface)\r
-{\r
- _ICOM_THIS_From_IDispatch(IFont, iface);\r
-\r
- return IFont_Release(this);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IDispatch_AddRef (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(\r
- IDispatch* iface)\r
-{\r
- _ICOM_THIS_From_IDispatch(IFont, iface);\r
-\r
- return IFont_AddRef(this);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_GetTypeInfoCount (IDispatch)\r
- *\r
- * See Windows documentation for more details on IDispatch methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(\r
- IDispatch* iface,\r
- unsigned int* pctinfo)\r
-{\r
- _ICOM_THIS_From_IDispatch(IFont, iface);\r
- FIXME("(%p)->(%p): Stub\n", this, pctinfo);\r
-\r
- return E_NOTIMPL;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_GetTypeInfo (IDispatch)\r
- *\r
- * See Windows documentation for more details on IDispatch methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_GetTypeInfo(\r
- IDispatch* iface,\r
- UINT iTInfo,\r
- LCID lcid,\r
- ITypeInfo** ppTInfo)\r
-{\r
- static const WCHAR stdole32tlb[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};\r
- ITypeLib *tl;\r
- HRESULT hres;\r
-\r
- _ICOM_THIS_From_IDispatch(OLEFontImpl, iface);\r
- TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);\r
- if (iTInfo != 0)\r
- return E_FAIL;\r
- hres = LoadTypeLib(stdole32tlb, &tl);\r
- if (FAILED(hres)) {\r
- ERR("Could not load the stdole32.tlb?\n");\r
- return hres;\r
- }\r
- hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IDispatch, ppTInfo);\r
- if (FAILED(hres)) {\r
- FIXME("Did not IDispatch typeinfo from typelib, hres %lx\n",hres);\r
- }\r
- return hres;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_GetIDsOfNames (IDispatch)\r
- *\r
- * See Windows documentation for more details on IDispatch methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(\r
- IDispatch* iface,\r
- REFIID riid,\r
- LPOLESTR* rgszNames,\r
- UINT cNames,\r
- LCID lcid,\r
- DISPID* rgDispId)\r
-{\r
- _ICOM_THIS_From_IDispatch(IFont, iface);\r
- FIXME("(%p,%s,%p,%d,%04x,%p), stub!\n", this, debugstr_guid(riid), rgszNames,\r
- cNames, (int)lcid, rgDispId\r
- );\r
- return E_NOTIMPL;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Invoke (IDispatch)\r
- *\r
- * See Windows documentation for more details on IDispatch methods.\r
- * \r
- * Note: Do not call _put_Xxx methods, since setting things here\r
- * should not call notify functions as I found out debugging the generic\r
- * MS VB5 installer.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_Invoke(\r
- IDispatch* iface,\r
- DISPID dispIdMember,\r
- REFIID riid,\r
- LCID lcid,\r
- WORD wFlags,\r
- DISPPARAMS* pDispParams,\r
- VARIANT* pVarResult,\r
- EXCEPINFO* pExepInfo,\r
- UINT* puArgErr)\r
-{\r
- _ICOM_THIS_From_IDispatch(IFont, iface);\r
- OLEFontImpl *xthis = (OLEFontImpl*)this;\r
-\r
- switch (dispIdMember) {\r
- case DISPID_FONT_NAME:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_BSTR;\r
- return OLEFontImpl_get_Name(this, &V_BSTR(pVarResult));\r
- case DISPATCH_PROPERTYPUT: {\r
- BSTR name;\r
- BOOL freename;\r
- \r
- if (V_VT(&pDispParams->rgvarg[0]) == VT_DISPATCH) {\r
- IFont *font;\r
- HRESULT hr = S_OK;\r
- \r
- hr = IUnknown_QueryInterface(V_DISPATCH(&pDispParams->rgvarg[0]), &IID_IFont, (void **) &font);\r
- if (FAILED(hr))\r
- {\r
- FIXME("dispatch value for name property is not an OleFont, returning hr=0x%lx\n", hr);\r
- return hr;\r
- }\r
-\r
- hr = IFont_get_Name(font, &name); /* this allocates a new BSTR so free it later */\r
- if (FAILED(hr)) return hr;\r
-\r
- IUnknown_Release(font);\r
- \r
- freename = TRUE;\r
- } else if (V_VT(&pDispParams->rgvarg[0]) == VT_BSTR) {\r
- name = V_BSTR(&pDispParams->rgvarg[0]);\r
- freename = FALSE;\r
- } else {\r
- FIXME("app is trying to set name property with a non BSTR, non dispatch value. returning E_FAIL\n");\r
- return E_FAIL;\r
- }\r
-\r
- TRACE("name is %s\n", debugstr_w(name));\r
- \r
- if (!xthis->description.lpstrName)\r
- xthis->description.lpstrName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name)+1) * sizeof(WCHAR));\r
- else\r
- xthis->description.lpstrName = HeapReAlloc(GetProcessHeap(), 0, xthis->description.lpstrName, (lstrlenW(name)+1) * sizeof(WCHAR));\r
-\r
- if (xthis->description.lpstrName==0)\r
- return E_OUTOFMEMORY;\r
- strcpyW(xthis->description.lpstrName, name);\r
-\r
- if (freename) SysFreeString(name);\r
- \r
- return S_OK;\r
- }\r
- }\r
- break;\r
- case DISPID_FONT_BOLD:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_BOOL;\r
- return OLEFontImpl_get_Bold(this, (BOOL*)&V_BOOL(pVarResult));\r
- case DISPATCH_PROPERTYPUT:\r
- if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {\r
- FIXME("DISPID_FONT_BOLD/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));\r
- return E_FAIL;\r
- } else {\r
- xthis->description.sWeight = V_BOOL(&pDispParams->rgvarg[0]) ? FW_BOLD : FW_NORMAL;\r
- return S_OK;\r
- }\r
- }\r
- break;\r
- case DISPID_FONT_ITALIC:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_BOOL;\r
- return OLEFontImpl_get_Italic(this, (BOOL*)&V_BOOL(pVarResult));\r
- case DISPATCH_PROPERTYPUT:\r
- if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {\r
- FIXME("DISPID_FONT_ITALIC/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));\r
- return E_FAIL;\r
- } else {\r
- xthis->description.fItalic = V_BOOL(&pDispParams->rgvarg[0]);\r
- return S_OK;\r
- }\r
- }\r
- break;\r
- case DISPID_FONT_UNDER:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_BOOL;\r
- return OLEFontImpl_get_Underline(this, (BOOL*)&V_BOOL(pVarResult));\r
- case DISPATCH_PROPERTYPUT:\r
- if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {\r
- FIXME("DISPID_FONT_UNDER/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));\r
- return E_FAIL;\r
- } else {\r
- xthis->description.fUnderline = V_BOOL(&pDispParams->rgvarg[0]);\r
- return S_OK;\r
- }\r
- }\r
- break;\r
- case DISPID_FONT_STRIKE:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_BOOL;\r
- return OLEFontImpl_get_Strikethrough(this, (BOOL*)&V_BOOL(pVarResult));\r
- case DISPATCH_PROPERTYPUT:\r
- if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {\r
- FIXME("DISPID_FONT_STRIKE/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));\r
- return E_FAIL;\r
- } else {\r
- xthis->description.fStrikethrough = V_BOOL(&pDispParams->rgvarg[0]);\r
- return S_OK;\r
- }\r
- }\r
- break;\r
- case DISPID_FONT_SIZE:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYPUT: {\r
- assert (pDispParams->cArgs == 1);\r
- xthis->description.cySize.s.Hi = 0;\r
- if (V_VT(&pDispParams->rgvarg[0]) != VT_CY) {\r
- if (V_VT(&pDispParams->rgvarg[0]) == VT_I2) {\r
- xthis->description.cySize.s.Lo = V_I2(&pDispParams->rgvarg[0]) * 10000;\r
- } else {\r
- FIXME("property put for Size with vt %d unsupported!\n",V_VT(&pDispParams->rgvarg[0]));\r
- }\r
- } else {\r
- xthis->description.cySize.s.Lo = V_CY(&pDispParams->rgvarg[0]).s.Lo;\r
- }\r
- return S_OK;\r
- }\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_CY;\r
- return OLEFontImpl_get_Size(this, &V_CY(pVarResult));\r
- }\r
- break;\r
- case DISPID_FONT_CHARSET:\r
- switch (wFlags) {\r
- case DISPATCH_PROPERTYPUT:\r
- assert (pDispParams->cArgs == 1);\r
- if (V_VT(&pDispParams->rgvarg[0]) != VT_I2)\r
- FIXME("varg of first disparg is not VT_I2, but %d\n",V_VT(&pDispParams->rgvarg[0]));\r
- xthis->description.sCharset = V_I2(&pDispParams->rgvarg[0]);\r
- return S_OK;\r
- case DISPATCH_PROPERTYGET:\r
- case DISPATCH_PROPERTYGET|DISPATCH_METHOD:\r
- V_VT(pVarResult) = VT_I2;\r
- return OLEFontImpl_get_Charset(this, &V_I2(pVarResult));\r
- }\r
- break;\r
- }\r
- FIXME("%p->(%ld,%s,%lx,%x,%p,%p,%p,%p), unhandled dispid/flag!\n",\r
- this,dispIdMember,debugstr_guid(riid),lcid,\r
- wFlags,pDispParams,pVarResult,pExepInfo,puArgErr\r
- );\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(\r
- IPersistStream* iface,\r
- REFIID riid,\r
- VOID** ppvoid)\r
-{\r
- _ICOM_THIS_From_IPersistStream(IFont, iface);\r
-\r
- return IFont_QueryInterface(this, riid, ppvoid);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IPersistStream_Release (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static ULONG WINAPI OLEFontImpl_IPersistStream_Release(\r
- IPersistStream* iface)\r
-{\r
- _ICOM_THIS_From_IPersistStream(IFont, iface);\r
-\r
- return IFont_Release(this);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IPersistStream_AddRef (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(\r
- IPersistStream* iface)\r
-{\r
- _ICOM_THIS_From_IPersistStream(IFont, iface);\r
-\r
- return IFont_AddRef(this);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_GetClassID (IPersistStream)\r
- *\r
- * See Windows documentation for more details on IPersistStream methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_GetClassID(\r
- IPersistStream* iface,\r
- CLSID* pClassID)\r
-{\r
- TRACE("(%p,%p)\n",iface,pClassID);\r
- if (pClassID==0)\r
- return E_POINTER;\r
-\r
- memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IsDirty (IPersistStream)\r
- *\r
- * See Windows documentation for more details on IPersistStream methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IsDirty(\r
- IPersistStream* iface)\r
-{\r
- TRACE("(%p)\n",iface);\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Load (IPersistStream)\r
- *\r
- * See Windows documentation for more details on IPersistStream methods.\r
- *\r
- * This is the format of the standard font serialization as far as I\r
- * know\r
- *\r
- * Offset Type Value Comment\r
- * 0x0000 Byte Unknown Probably a version number, contains 0x01\r
- * 0x0001 Short Charset Charset value from the FONTDESC structure\r
- * 0x0003 Byte Attributes Flags defined as follows:\r
- * 00000010 - Italic\r
- * 00000100 - Underline\r
- * 00001000 - Strikethrough\r
- * 0x0004 Short Weight Weight value from FONTDESC structure\r
- * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC\r
- * structure/\r
- * 0x000A Byte name length Length of the font name string (no null character)\r
- * 0x000B String name Name of the font (ASCII, no nul character)\r
- */\r
-static HRESULT WINAPI OLEFontImpl_Load(\r
- IPersistStream* iface,\r
- IStream* pLoadStream)\r
-{\r
- char readBuffer[0x100];\r
- ULONG cbRead;\r
- BYTE bVersion;\r
- BYTE bAttributes;\r
- BYTE bStringSize;\r
- INT len;\r
-\r
- _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);\r
-\r
- /*\r
- * Read the version byte\r
- */\r
- IStream_Read(pLoadStream, &bVersion, 1, &cbRead);\r
-\r
- if ( (cbRead!=1) ||\r
- (bVersion!=0x01) )\r
- return E_FAIL;\r
-\r
- /*\r
- * Charset\r
- */\r
- IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);\r
-\r
- if (cbRead!=2)\r
- return E_FAIL;\r
-\r
- /*\r
- * Attributes\r
- */\r
- IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);\r
-\r
- if (cbRead!=1)\r
- return E_FAIL;\r
-\r
- this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;\r
- this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;\r
- this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;\r
-\r
- /*\r
- * Weight\r
- */\r
- IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);\r
-\r
- if (cbRead!=2)\r
- return E_FAIL;\r
-\r
- /*\r
- * Size\r
- */\r
- IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);\r
-\r
- if (cbRead!=4)\r
- return E_FAIL;\r
-\r
- this->description.cySize.s.Hi = 0;\r
-\r
- /*\r
- * FontName\r
- */\r
- IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);\r
-\r
- if (cbRead!=1)\r
- return E_FAIL;\r
-\r
- IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);\r
-\r
- if (cbRead!=bStringSize)\r
- return E_FAIL;\r
-\r
- HeapFree(GetProcessHeap(), 0, this->description.lpstrName);\r
-\r
- len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );\r
- this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );\r
- MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );\r
- this->description.lpstrName[len] = 0;\r
-\r
- /* Ensure use of this font causes a new one to be created @@@@ */\r
- DeleteObject(this->gdiFont);\r
- this->gdiFont = 0;\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_Save (IPersistStream)\r
- *\r
- * See Windows documentation for more details on IPersistStream methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_Save(\r
- IPersistStream* iface,\r
- IStream* pOutStream,\r
- BOOL fClearDirty)\r
-{\r
- char* writeBuffer = NULL;\r
- ULONG cbWritten;\r
- BYTE bVersion = 0x01;\r
- BYTE bAttributes;\r
- BYTE bStringSize;\r
-\r
- _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);\r
-\r
- /*\r
- * Read the version byte\r
- */\r
- IStream_Write(pOutStream, &bVersion, 1, &cbWritten);\r
-\r
- if (cbWritten!=1)\r
- return E_FAIL;\r
-\r
- /*\r
- * Charset\r
- */\r
- IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);\r
-\r
- if (cbWritten!=2)\r
- return E_FAIL;\r
-\r
- /*\r
- * Attributes\r
- */\r
- bAttributes = 0;\r
-\r
- if (this->description.fItalic)\r
- bAttributes |= FONTPERSIST_ITALIC;\r
-\r
- if (this->description.fStrikethrough)\r
- bAttributes |= FONTPERSIST_STRIKETHROUGH;\r
-\r
- if (this->description.fUnderline)\r
- bAttributes |= FONTPERSIST_UNDERLINE;\r
-\r
- IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);\r
-\r
- if (cbWritten!=1)\r
- return E_FAIL;\r
-\r
- /*\r
- * Weight\r
- */\r
- IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);\r
-\r
- if (cbWritten!=2)\r
- return E_FAIL;\r
-\r
- /*\r
- * Size\r
- */\r
- IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);\r
-\r
- if (cbWritten!=4)\r
- return E_FAIL;\r
-\r
- /*\r
- * FontName\r
- */\r
- if (this->description.lpstrName!=0)\r
- bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,\r
- strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );\r
- else\r
- bStringSize = 0;\r
-\r
- IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);\r
-\r
- if (cbWritten!=1)\r
- return E_FAIL;\r
-\r
- if (bStringSize!=0)\r
- {\r
- if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;\r
- WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,\r
- strlenW(this->description.lpstrName),\r
- writeBuffer, bStringSize, NULL, NULL );\r
-\r
- IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);\r
- HeapFree(GetProcessHeap(), 0, writeBuffer);\r
-\r
- if (cbWritten!=bStringSize)\r
- return E_FAIL;\r
- }\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_GetSizeMax (IPersistStream)\r
- *\r
- * See Windows documentation for more details on IPersistStream methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_GetSizeMax(\r
- IPersistStream* iface,\r
- ULARGE_INTEGER* pcbSize)\r
-{\r
- _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);\r
-\r
- if (pcbSize==NULL)\r
- return E_POINTER;\r
-\r
- pcbSize->u.HighPart = 0;\r
- pcbSize->u.LowPart = 0;\r
-\r
- pcbSize->u.LowPart += sizeof(BYTE); /* Version */\r
- pcbSize->u.LowPart += sizeof(WORD); /* Lang code */\r
- pcbSize->u.LowPart += sizeof(BYTE); /* Flags */\r
- pcbSize->u.LowPart += sizeof(WORD); /* Weight */\r
- pcbSize->u.LowPart += sizeof(DWORD); /* Size */\r
- pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */\r
-\r
- if (this->description.lpstrName!=0)\r
- pcbSize->u.LowPart += lstrlenW(this->description.lpstrName);\r
-\r
- return S_OK;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(\r
- IConnectionPointContainer* iface,\r
- REFIID riid,\r
- VOID** ppvoid)\r
-{\r
- _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);\r
-\r
- return IFont_QueryInterface((IFont*)this, riid, ppvoid);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(\r
- IConnectionPointContainer* iface)\r
-{\r
- _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);\r
-\r
- return IFont_Release((IFont*)this);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)\r
- *\r
- * See Windows documentation for more details on IUnknown methods.\r
- */\r
-static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(\r
- IConnectionPointContainer* iface)\r
-{\r
- _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);\r
-\r
- return IFont_AddRef((IFont*)this);\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)\r
- *\r
- * See Windows documentation for more details on IConnectionPointContainer\r
- * methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(\r
- IConnectionPointContainer* iface,\r
- IEnumConnectionPoints **ppEnum)\r
-{\r
- _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);\r
-\r
- FIXME("(%p)->(%p): stub\n", this, ppEnum);\r
- return E_NOTIMPL;\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)\r
- *\r
- * See Windows documentation for more details on IConnectionPointContainer\r
- * methods.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(\r
- IConnectionPointContainer* iface,\r
- REFIID riid,\r
- IConnectionPoint **ppCp)\r
-{\r
- _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);\r
- TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);\r
-\r
- if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {\r
- return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,\r
- (LPVOID)ppCp);\r
- } else {\r
- FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));\r
- return E_NOINTERFACE;\r
- }\r
-}\r
-\r
-/************************************************************************\r
- * OLEFontImpl implementation of IPersistPropertyBag.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(\r
- IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj\r
-) {\r
- _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);\r
- return IFont_QueryInterface(this,riid,ppvObj);\r
-}\r
-\r
-static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(\r
- IPersistPropertyBag *iface\r
-) {\r
- _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);\r
- return IFont_AddRef(this);\r
-}\r
-\r
-static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(\r
- IPersistPropertyBag *iface\r
-) {\r
- _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);\r
- return IFont_Release(this);\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(\r
- IPersistPropertyBag *iface, CLSID *classid\r
-) {\r
- FIXME("(%p,%p), stub!\n", iface, classid);\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(\r
- IPersistPropertyBag *iface\r
-) {\r
- FIXME("(%p), stub!\n", iface);\r
- return S_OK;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(\r
- IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog\r
-) {\r
-/* (from Visual Basic 6 property bag)\r
- Name = "MS Sans Serif"\r
- Size = 13.8\r
- Charset = 0\r
- Weight = 400\r
- Underline = 0 'False\r
- Italic = 0 'False\r
- Strikethrough = 0 'False\r
-*/\r
- static const WCHAR sAttrName[] = {'N','a','m','e',0};\r
- static const WCHAR sAttrSize[] = {'S','i','z','e',0};\r
- static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0};\r
- static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0};\r
- static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};\r
- static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};\r
- static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};\r
- VARIANT rawAttr;\r
- VARIANT valueAttr;\r
- HRESULT iRes = S_OK;\r
- _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);\r
-\r
- VariantInit(&rawAttr);\r
- VariantInit(&valueAttr);\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR);\r
- if (iRes == S_OK)\r
- iRes = IFont_put_Name(this, V_BSTR(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
- }\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY);\r
- if (iRes == S_OK)\r
- iRes = IFont_put_Size(this, V_CY(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
- }\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);\r
- if (iRes == S_OK)\r
- iRes = IFont_put_Charset(this, V_I2(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
- }\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);\r
- if (iRes == S_OK)\r
- iRes = IFont_put_Weight(this, V_I2(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
-\r
- }\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);\r
- if (iRes == S_OK)\r
- iRes = IFont_put_Underline(this, V_BOOL(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
- }\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);\r
- if (iRes == S_OK)\r
- iRes = IFont_put_Italic(this, V_BOOL(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
- }\r
-\r
- if (iRes == S_OK) {\r
- iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog);\r
- if (iRes == S_OK)\r
- {\r
- iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);\r
- if (iRes == S_OK)\r
- IFont_put_Strikethrough(this, V_BOOL(&valueAttr));\r
- }\r
- else if (iRes == E_INVALIDARG)\r
- iRes = S_OK;\r
- VariantClear(&rawAttr);\r
- VariantClear(&valueAttr);\r
- }\r
-\r
- if (FAILED(iRes))\r
- WARN("-- 0x%08lx\n", iRes);\r
- return iRes;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(\r
- IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,\r
- BOOL fSaveAllProperties\r
-) {\r
- FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);\r
- return E_FAIL;\r
-}\r
-\r
-static IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable = \r
-{\r
- OLEFontImpl_IPersistPropertyBag_QueryInterface,\r
- OLEFontImpl_IPersistPropertyBag_AddRef,\r
- OLEFontImpl_IPersistPropertyBag_Release,\r
-\r
- OLEFontImpl_IPersistPropertyBag_GetClassID,\r
- OLEFontImpl_IPersistPropertyBag_InitNew,\r
- OLEFontImpl_IPersistPropertyBag_Load,\r
- OLEFontImpl_IPersistPropertyBag_Save\r
-};\r
-\r
-/************************************************************************\r
- * OLEFontImpl implementation of IPersistStreamInit.\r
- */\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(\r
- IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj\r
-) {\r
- _ICOM_THIS_From_IPersistStreamInit(IFont, iface);\r
- return IFont_QueryInterface(this,riid,ppvObj);\r
-}\r
-\r
-static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(\r
- IPersistStreamInit *iface\r
-) {\r
- _ICOM_THIS_From_IPersistStreamInit(IFont, iface);\r
- return IFont_AddRef(this);\r
-}\r
-\r
-static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(\r
- IPersistStreamInit *iface\r
-) {\r
- _ICOM_THIS_From_IPersistStreamInit(IFont, iface);\r
- return IFont_Release(this);\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(\r
- IPersistStreamInit *iface, CLSID *classid\r
-) {\r
- FIXME("(%p,%p), stub!\n", iface, classid);\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(\r
- IPersistStreamInit *iface\r
-) {\r
- FIXME("(%p), stub!\n", iface);\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(\r
- IPersistStreamInit *iface, LPSTREAM pStm\r
-) {\r
- FIXME("(%p,%p), stub!\n", iface, pStm);\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(\r
- IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty\r
-) {\r
- FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(\r
- IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize\r
-) {\r
- FIXME("(%p,%p), stub!\n", iface, pcbSize);\r
- return E_FAIL;\r
-}\r
-\r
-static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(\r
- IPersistStreamInit *iface\r
-) {\r
- FIXME("(%p), stub!\n", iface);\r
- return S_OK;\r
-}\r
-\r
-static IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable = \r
-{\r
- OLEFontImpl_IPersistStreamInit_QueryInterface,\r
- OLEFontImpl_IPersistStreamInit_AddRef,\r
- OLEFontImpl_IPersistStreamInit_Release,\r
-\r
- OLEFontImpl_IPersistStreamInit_GetClassID,\r
- OLEFontImpl_IPersistStreamInit_IsDirty,\r
- OLEFontImpl_IPersistStreamInit_Load,\r
- OLEFontImpl_IPersistStreamInit_Save,\r
- OLEFontImpl_IPersistStreamInit_GetSizeMax,\r
- OLEFontImpl_IPersistStreamInit_InitNew\r
-};\r
-\r
-/*******************************************************************************\r
- * StdFont ClassFactory\r
- */\r
-typedef struct\r
-{\r
- /* IUnknown fields */\r
- IClassFactoryVtbl *lpVtbl;\r
- DWORD ref;\r
-} IClassFactoryImpl;\r
-\r
-static HRESULT WINAPI\r
-SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
-\r
- FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);\r
- return E_NOINTERFACE;\r
-}\r
-\r
-static ULONG WINAPI\r
-SFCF_AddRef(LPCLASSFACTORY iface) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
- return InterlockedIncrement(&This->ref);\r
-}\r
-\r
-static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
- /* static class, won't be freed */\r
- return InterlockedDecrement(&This->ref);\r
-}\r
-\r
-static HRESULT WINAPI SFCF_CreateInstance(\r
- LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj\r
-) {\r
- return OleCreateFontIndirect(NULL,riid,ppobj);\r
-\r
-}\r
-\r
-static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {\r
- IClassFactoryImpl *This = (IClassFactoryImpl *)iface;\r
- FIXME("(%p)->(%d),stub!\n",This,dolock);\r
- return S_OK;\r
-}\r
-\r
-static IClassFactoryVtbl SFCF_Vtbl = {\r
- SFCF_QueryInterface,\r
- SFCF_AddRef,\r
- SFCF_Release,\r
- SFCF_CreateInstance,\r
- SFCF_LockServer\r
-};\r
-static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };\r
-\r
-void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }\r
+/*
+ * OLE Font encapsulation implementation
+ *
+ * This file contains an implementation of the IFont
+ * interface and the OleCreateFontIndirect API call.
+ *
+ * Copyright 1999 Francis Beaudet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+#include "oleauto.h" /* for SysAllocString(....) */
+#include "ole2.h"
+#include "olectl.h"
+#include "wine/debug.h"
+#include "connpt.h" /* for CreateConnectionPoint */
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+/***********************************************************************
+ * Declaration of constants used when serializing the font object.
+ */
+#define FONTPERSIST_ITALIC 0x02
+#define FONTPERSIST_UNDERLINE 0x04
+#define FONTPERSIST_STRIKETHROUGH 0x08
+
+/***********************************************************************
+ * Declaration of the implementation class for the IFont interface
+ */
+typedef struct OLEFontImpl OLEFontImpl;
+
+struct OLEFontImpl
+{
+ /*
+ * This class supports many interfaces. IUnknown, IFont,
+ * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
+ * The first two are supported by the first vtable, the next two are
+ * supported by the second table and the last two have their own.
+ */
+ IFontVtbl* lpvtbl1;
+ IDispatchVtbl* lpvtbl2;
+ IPersistStreamVtbl* lpvtbl3;
+ IConnectionPointContainerVtbl* lpvtbl4;
+ IPersistPropertyBagVtbl* lpvtbl5;
+ IPersistStreamInitVtbl* lpvtbl6;
+ /*
+ * Reference count for that instance of the class.
+ */
+ ULONG ref;
+
+ /*
+ * This structure contains the description of the class.
+ */
+ FONTDESC description;
+
+ /*
+ * Contain the font associated with this object.
+ */
+ HFONT gdiFont;
+
+ /*
+ * Font lock count.
+ */
+ DWORD fontLock;
+
+ /*
+ * Size ratio
+ */
+ long cyLogical;
+ long cyHimetric;
+
+ IConnectionPoint *pCP;
+};
+
+/*
+ * Here, I define utility macros to help with the casting of the
+ * "this" parameter.
+ * There is a version to accommodate all of the VTables implemented
+ * by this object.
+ */
+#define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*))
+#define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*))
+#define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*))
+#define _ICOM_THIS_From_IPersistPropertyBag(class, name) class* this = (class*)(((char*)name)-4*sizeof(void*))
+#define _ICOM_THIS_From_IPersistStreamInit(class, name) class* this = (class*)(((char*)name)-5*sizeof(void*))
+
+
+/***********************************************************************
+ * Prototypes for the implementation functions for the IFont
+ * interface
+ */
+static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc);
+static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc);
+static HRESULT WINAPI OLEFontImpl_QueryInterface(IFont* iface, REFIID riid, VOID** ppvoid);
+static ULONG WINAPI OLEFontImpl_AddRef(IFont* iface);
+static ULONG WINAPI OLEFontImpl_Release(IFont* iface);
+static HRESULT WINAPI OLEFontImpl_get_Name(IFont* iface, BSTR* pname);
+static HRESULT WINAPI OLEFontImpl_put_Name(IFont* iface, BSTR name);
+static HRESULT WINAPI OLEFontImpl_get_Size(IFont* iface, CY* psize);
+static HRESULT WINAPI OLEFontImpl_put_Size(IFont* iface, CY size);
+static HRESULT WINAPI OLEFontImpl_get_Bold(IFont* iface, BOOL* pbold);
+static HRESULT WINAPI OLEFontImpl_put_Bold(IFont* iface, BOOL bold);
+static HRESULT WINAPI OLEFontImpl_get_Italic(IFont* iface, BOOL* pitalic);
+static HRESULT WINAPI OLEFontImpl_put_Italic(IFont* iface, BOOL italic);
+static HRESULT WINAPI OLEFontImpl_get_Underline(IFont* iface, BOOL* punderline);
+static HRESULT WINAPI OLEFontImpl_put_Underline(IFont* iface, BOOL underline);
+static HRESULT WINAPI OLEFontImpl_get_Strikethrough(IFont* iface, BOOL* pstrikethrough);
+static HRESULT WINAPI OLEFontImpl_put_Strikethrough(IFont* iface, BOOL strikethrough);
+static HRESULT WINAPI OLEFontImpl_get_Weight(IFont* iface, short* pweight);
+static HRESULT WINAPI OLEFontImpl_put_Weight(IFont* iface, short weight);
+static HRESULT WINAPI OLEFontImpl_get_Charset(IFont* iface, short* pcharset);
+static HRESULT WINAPI OLEFontImpl_put_Charset(IFont* iface, short charset);
+static HRESULT WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
+static HRESULT WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
+static HRESULT WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
+static HRESULT WINAPI OLEFontImpl_SetRatio(IFont* iface, LONG cyLogical, LONG cyHimetric);
+static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
+static HRESULT WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
+static HRESULT WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
+static HRESULT WINAPI OLEFontImpl_SetHdc(IFont* iface, HDC hdc);
+
+/***********************************************************************
+ * Prototypes for the implementation functions for the IDispatch
+ * interface
+ */
+static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
+ REFIID riid,
+ VOID** ppvoid);
+static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
+static ULONG WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
+static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch* iface,
+ unsigned int* pctinfo);
+static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch* iface,
+ UINT iTInfo,
+ LCID lcid,
+ ITypeInfo** ppTInfo);
+static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch* iface,
+ REFIID riid,
+ LPOLESTR* rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID* rgDispId);
+static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch* iface,
+ DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS* pDispParams,
+ VARIANT* pVarResult,
+ EXCEPINFO* pExepInfo,
+ UINT* puArgErr);
+
+/***********************************************************************
+ * Prototypes for the implementation functions for the IPersistStream
+ * interface
+ */
+static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
+ REFIID riid,
+ VOID** ppvoid);
+static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
+static ULONG WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
+static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
+ CLSID* pClassID);
+static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream* iface);
+static HRESULT WINAPI OLEFontImpl_Load(IPersistStream* iface,
+ IStream* pLoadStream);
+static HRESULT WINAPI OLEFontImpl_Save(IPersistStream* iface,
+ IStream* pOutStream,
+ BOOL fClearDirty);
+static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream* iface,
+ ULARGE_INTEGER* pcbSize);
+
+/***********************************************************************
+ * Prototypes for the implementation functions for the
+ * IConnectionPointContainer interface
+ */
+static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
+ IConnectionPointContainer* iface,
+ REFIID riid,
+ VOID** ppvoid);
+static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
+ IConnectionPointContainer* iface);
+static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
+ IConnectionPointContainer* iface);
+static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
+ IConnectionPointContainer* iface,
+ IEnumConnectionPoints **ppEnum);
+static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
+ IConnectionPointContainer* iface,
+ REFIID riid,
+ IConnectionPoint **ppCp);
+
+/*
+ * Virtual function tables for the OLEFontImpl class.
+ */
+static IFontVtbl OLEFontImpl_VTable =
+{
+ OLEFontImpl_QueryInterface,
+ OLEFontImpl_AddRef,
+ OLEFontImpl_Release,
+ OLEFontImpl_get_Name,
+ OLEFontImpl_put_Name,
+ OLEFontImpl_get_Size,
+ OLEFontImpl_put_Size,
+ OLEFontImpl_get_Bold,
+ OLEFontImpl_put_Bold,
+ OLEFontImpl_get_Italic,
+ OLEFontImpl_put_Italic,
+ OLEFontImpl_get_Underline,
+ OLEFontImpl_put_Underline,
+ OLEFontImpl_get_Strikethrough,
+ OLEFontImpl_put_Strikethrough,
+ OLEFontImpl_get_Weight,
+ OLEFontImpl_put_Weight,
+ OLEFontImpl_get_Charset,
+ OLEFontImpl_put_Charset,
+ OLEFontImpl_get_hFont,
+ OLEFontImpl_Clone,
+ OLEFontImpl_IsEqual,
+ OLEFontImpl_SetRatio,
+ OLEFontImpl_QueryTextMetrics,
+ OLEFontImpl_AddRefHfont,
+ OLEFontImpl_ReleaseHfont,
+ OLEFontImpl_SetHdc
+};
+
+static IDispatchVtbl OLEFontImpl_IDispatch_VTable =
+{
+ OLEFontImpl_IDispatch_QueryInterface,
+ OLEFontImpl_IDispatch_AddRef,
+ OLEFontImpl_IDispatch_Release,
+ OLEFontImpl_GetTypeInfoCount,
+ OLEFontImpl_GetTypeInfo,
+ OLEFontImpl_GetIDsOfNames,
+ OLEFontImpl_Invoke
+};
+
+static IPersistStreamVtbl OLEFontImpl_IPersistStream_VTable =
+{
+ OLEFontImpl_IPersistStream_QueryInterface,
+ OLEFontImpl_IPersistStream_AddRef,
+ OLEFontImpl_IPersistStream_Release,
+ OLEFontImpl_GetClassID,
+ OLEFontImpl_IsDirty,
+ OLEFontImpl_Load,
+ OLEFontImpl_Save,
+ OLEFontImpl_GetSizeMax
+};
+
+static IConnectionPointContainerVtbl
+ OLEFontImpl_IConnectionPointContainer_VTable =
+{
+ OLEFontImpl_IConnectionPointContainer_QueryInterface,
+ OLEFontImpl_IConnectionPointContainer_AddRef,
+ OLEFontImpl_IConnectionPointContainer_Release,
+ OLEFontImpl_EnumConnectionPoints,
+ OLEFontImpl_FindConnectionPoint
+};
+
+static IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable;
+static IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable;
+/******************************************************************************
+ * OleCreateFontIndirect [OLEAUT32.420]
+ */
+HRESULT WINAPI OleCreateFontIndirect(
+ LPFONTDESC lpFontDesc,
+ REFIID riid,
+ LPVOID* ppvObj)
+{
+ OLEFontImpl* newFont = 0;
+ HRESULT hr = S_OK;
+
+ TRACE("(%p, %s, %p)\n", lpFontDesc, debugstr_guid(riid), ppvObj);
+ /*
+ * Sanity check
+ */
+ if (ppvObj==0)
+ return E_POINTER;
+
+ *ppvObj = 0;
+
+ if (!lpFontDesc) {
+ FONTDESC fd;
+
+ static const WCHAR fname[] = { 'S','y','s','t','e','m',0 };
+
+ fd.cbSizeofstruct = sizeof(fd);
+ fd.lpstrName = (WCHAR*)fname;
+ fd.cySize.s.Lo = 80000;
+ fd.cySize.s.Hi = 0;
+ fd.sWeight = 0;
+ fd.sCharset = 0;
+ fd.fItalic = 0;
+ fd.fUnderline = 0;
+ fd.fStrikethrough = 0;
+ lpFontDesc = &fd;
+ }
+
+ /*
+ * Try to construct a new instance of the class.
+ */
+ newFont = OLEFontImpl_Construct(lpFontDesc);
+
+ if (newFont == 0)
+ return E_OUTOFMEMORY;
+
+ /*
+ * Make sure it supports the interface required by the caller.
+ */
+ hr = IFont_QueryInterface((IFont*)newFont, riid, ppvObj);
+
+ /*
+ * Release the reference obtained in the constructor. If
+ * the QueryInterface was unsuccessful, it will free the class.
+ */
+ IFont_Release((IFont*)newFont);
+
+ return hr;
+}
+
+
+/***********************************************************************
+ * Implementation of the OLEFontImpl class.
+ */
+
+/***********************************************************************
+ * OLEFont_SendNotify (internal)
+ *
+ * Sends notification messages of changed properties to any interested
+ * connections.
+ */
+static void OLEFont_SendNotify(OLEFontImpl* this, DISPID dispID)
+{
+ IEnumConnections *pEnum;
+ CONNECTDATA CD;
+ HRESULT hres;
+
+ hres = IConnectionPoint_EnumConnections(this->pCP, &pEnum);
+ if (FAILED(hres)) /* When we have 0 connections. */
+ return;
+
+ while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
+ IPropertyNotifySink *sink;
+
+ IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
+ IPropertyNotifySink_OnChanged(sink, dispID);
+ IPropertyNotifySink_Release(sink);
+ IUnknown_Release(CD.pUnk);
+ }
+ IEnumConnections_Release(pEnum);
+ return;
+}
+
+/************************************************************************
+ * OLEFontImpl_Construct
+ *
+ * This method will construct a new instance of the OLEFontImpl
+ * class.
+ *
+ * The caller of this method must release the object when it's
+ * done with it.
+ */
+static OLEFontImpl* OLEFontImpl_Construct(LPFONTDESC fontDesc)
+{
+ OLEFontImpl* newObject = 0;
+
+ /*
+ * Allocate space for the object.
+ */
+ newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
+
+ if (newObject==0)
+ return newObject;
+
+ /*
+ * Initialize the virtual function table.
+ */
+ newObject->lpvtbl1 = &OLEFontImpl_VTable;
+ newObject->lpvtbl2 = &OLEFontImpl_IDispatch_VTable;
+ newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
+ newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
+ newObject->lpvtbl5 = &OLEFontImpl_IPersistPropertyBag_VTable;
+ newObject->lpvtbl6 = &OLEFontImpl_IPersistStreamInit_VTable;
+
+ /*
+ * Start with one reference count. The caller of this function
+ * must release the interface pointer when it is done.
+ */
+ newObject->ref = 1;
+
+ /*
+ * Copy the description of the font in the object.
+ */
+ assert(fontDesc->cbSizeofstruct >= sizeof(FONTDESC));
+
+ newObject->description.cbSizeofstruct = sizeof(FONTDESC);
+ newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
+ 0,
+ (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
+ strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
+ newObject->description.cySize = fontDesc->cySize;
+ newObject->description.sWeight = fontDesc->sWeight;
+ newObject->description.sCharset = fontDesc->sCharset;
+ newObject->description.fItalic = fontDesc->fItalic;
+ newObject->description.fUnderline = fontDesc->fUnderline;
+ newObject->description.fStrikethrough = fontDesc->fStrikethrough;
+
+ /*
+ * Initializing all the other members.
+ */
+ newObject->gdiFont = 0;
+ newObject->fontLock = 0;
+ newObject->cyLogical = 72L;
+ newObject->cyHimetric = 2540L;
+ CreateConnectionPoint((IUnknown*)newObject, &IID_IPropertyNotifySink, &newObject->pCP);
+ TRACE("returning %p\n", newObject);
+ return newObject;
+}
+
+/************************************************************************
+ * OLEFontImpl_Destroy
+ *
+ * This method is called by the Release method when the reference
+ * count goes down to 0. It will free all resources used by
+ * this object.
+ */
+static void OLEFontImpl_Destroy(OLEFontImpl* fontDesc)
+{
+ TRACE("(%p)\n", fontDesc);
+
+ HeapFree(GetProcessHeap(), 0, fontDesc->description.lpstrName);
+
+ if (fontDesc->gdiFont!=0)
+ DeleteObject(fontDesc->gdiFont);
+
+ HeapFree(GetProcessHeap(), 0, fontDesc);
+}
+
+/************************************************************************
+ * OLEFontImpl_QueryInterface (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+HRESULT WINAPI OLEFontImpl_QueryInterface(
+ IFont* iface,
+ REFIID riid,
+ void** ppvObject)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%s, %p)\n", this, debugstr_guid(riid), ppvObject);
+
+ /*
+ * Perform a sanity check on the parameters.
+ */
+ if ( (this==0) || (ppvObject==0) )
+ return E_INVALIDARG;
+
+ /*
+ * Initialize the return parameter.
+ */
+ *ppvObject = 0;
+
+ /*
+ * Compare the riid with the interface IDs implemented by this object.
+ */
+ if (IsEqualGUID(&IID_IUnknown, riid))
+ *ppvObject = (IFont*)this;
+ if (IsEqualGUID(&IID_IFont, riid))
+ *ppvObject = (IFont*)this;
+ if (IsEqualGUID(&IID_IDispatch, riid))
+ *ppvObject = (IDispatch*)&(this->lpvtbl2);
+ if (IsEqualGUID(&IID_IFontDisp, riid))
+ *ppvObject = (IDispatch*)&(this->lpvtbl2);
+ if (IsEqualGUID(&IID_IPersistStream, riid))
+ *ppvObject = (IPersistStream*)&(this->lpvtbl3);
+ if (IsEqualGUID(&IID_IConnectionPointContainer, riid))
+ *ppvObject = (IConnectionPointContainer*)&(this->lpvtbl4);
+ if (IsEqualGUID(&IID_IPersistPropertyBag, riid))
+ *ppvObject = (IPersistPropertyBag*)&(this->lpvtbl5);
+ if (IsEqualGUID(&IID_IPersistStreamInit, riid))
+ *ppvObject = (IPersistStreamInit*)&(this->lpvtbl6);
+
+ /*
+ * Check that we obtained an interface.
+ */
+ if ((*ppvObject)==0)
+ {
+ FIXME("() : asking for unsupported interface %s\n",debugstr_guid(riid));
+ return E_NOINTERFACE;
+ }
+ OLEFontImpl_AddRef((IFont*)this);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_AddRef (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+ULONG WINAPI OLEFontImpl_AddRef(
+ IFont* iface)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(ref=%ld)\n", this, this->ref);
+ return InterlockedIncrement(&this->ref);
+}
+
+/************************************************************************
+ * OLEFontImpl_Release (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+ULONG WINAPI OLEFontImpl_Release(
+ IFont* iface)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ ULONG ret;
+ TRACE("(%p)->(ref=%ld)\n", this, this->ref);
+
+ /*
+ * Decrease the reference count on this object.
+ */
+ ret = InterlockedDecrement(&this->ref);
+
+ /*
+ * If the reference count goes down to 0, perform suicide.
+ */
+ if (ret==0) OLEFontImpl_Destroy(this);
+
+ return ret;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Name (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Name(
+ IFont* iface,
+ BSTR* pname)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, pname);
+ /*
+ * Sanity check.
+ */
+ if (pname==0)
+ return E_POINTER;
+
+ if (this->description.lpstrName!=0)
+ *pname = SysAllocString(this->description.lpstrName);
+ else
+ *pname = 0;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Name (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Name(
+ IFont* iface,
+ BSTR name)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, name);
+
+ if (this->description.lpstrName==0)
+ {
+ this->description.lpstrName = HeapAlloc(GetProcessHeap(),
+ 0,
+ (lstrlenW(name)+1) * sizeof(WCHAR));
+ }
+ else
+ {
+ this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
+ 0,
+ this->description.lpstrName,
+ (lstrlenW(name)+1) * sizeof(WCHAR));
+ }
+
+ if (this->description.lpstrName==0)
+ return E_OUTOFMEMORY;
+
+ strcpyW(this->description.lpstrName, name);
+ TRACE("new name %s\n", debugstr_w(this->description.lpstrName));
+ OLEFont_SendNotify(this, DISPID_FONT_NAME);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Size (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Size(
+ IFont* iface,
+ CY* psize)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, psize);
+
+ /*
+ * Sanity check
+ */
+ if (psize==0)
+ return E_POINTER;
+
+ psize->s.Hi = 0;
+ psize->s.Lo = this->description.cySize.s.Lo;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Size (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Size(
+ IFont* iface,
+ CY size)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%ld)\n", this, size.s.Lo);
+ this->description.cySize.s.Hi = 0;
+ this->description.cySize.s.Lo = size.s.Lo;
+ OLEFont_SendNotify(this, DISPID_FONT_SIZE);
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Bold (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Bold(
+ IFont* iface,
+ BOOL* pbold)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, pbold);
+ /*
+ * Sanity check
+ */
+ if (pbold==0)
+ return E_POINTER;
+
+ *pbold = this->description.sWeight > 550;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Bold (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Bold(
+ IFont* iface,
+ BOOL bold)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%d)\n", this, bold);
+ this->description.sWeight = bold ? FW_BOLD : FW_NORMAL;
+ OLEFont_SendNotify(this, DISPID_FONT_BOLD);
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Italic (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Italic(
+ IFont* iface,
+ BOOL* pitalic)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, pitalic);
+ /*
+ * Sanity check
+ */
+ if (pitalic==0)
+ return E_POINTER;
+
+ *pitalic = this->description.fItalic;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Italic (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Italic(
+ IFont* iface,
+ BOOL italic)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%d)\n", this, italic);
+
+ this->description.fItalic = italic;
+
+ OLEFont_SendNotify(this, DISPID_FONT_ITALIC);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Underline (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Underline(
+ IFont* iface,
+ BOOL* punderline)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, punderline);
+
+ /*
+ * Sanity check
+ */
+ if (punderline==0)
+ return E_POINTER;
+
+ *punderline = this->description.fUnderline;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Underline (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Underline(
+ IFont* iface,
+ BOOL underline)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%d)\n", this, underline);
+
+ this->description.fUnderline = underline;
+
+ OLEFont_SendNotify(this, DISPID_FONT_UNDER);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Strikethrough (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
+ IFont* iface,
+ BOOL* pstrikethrough)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, pstrikethrough);
+
+ /*
+ * Sanity check
+ */
+ if (pstrikethrough==0)
+ return E_POINTER;
+
+ *pstrikethrough = this->description.fStrikethrough;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Strikethrough (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
+ IFont* iface,
+ BOOL strikethrough)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%d)\n", this, strikethrough);
+
+ this->description.fStrikethrough = strikethrough;
+ OLEFont_SendNotify(this, DISPID_FONT_STRIKE);
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Weight (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Weight(
+ IFont* iface,
+ short* pweight)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, pweight);
+
+ /*
+ * Sanity check
+ */
+ if (pweight==0)
+ return E_POINTER;
+
+ *pweight = this->description.sWeight;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Weight (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Weight(
+ IFont* iface,
+ short weight)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%d)\n", this, weight);
+
+ this->description.sWeight = weight;
+
+ OLEFont_SendNotify(this, DISPID_FONT_WEIGHT);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_Charset (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_Charset(
+ IFont* iface,
+ short* pcharset)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, pcharset);
+
+ /*
+ * Sanity check
+ */
+ if (pcharset==0)
+ return E_POINTER;
+
+ *pcharset = this->description.sCharset;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_put_Charset (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_put_Charset(
+ IFont* iface,
+ short charset)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%d)\n", this, charset);
+
+ this->description.sCharset = charset;
+ OLEFont_SendNotify(this, DISPID_FONT_CHARSET);
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_get_hFont (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_get_hFont(
+ IFont* iface,
+ HFONT* phfont)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, phfont);
+ if (phfont==NULL)
+ return E_POINTER;
+
+ /*
+ * Realize the font if necessary
+ */
+ if (this->gdiFont==0)
+{
+ LOGFONTW logFont;
+ INT fontHeight;
+ CY cySize;
+
+ /*
+ * The height of the font returned by the get_Size property is the
+ * height of the font in points multiplied by 10000... Using some
+ * simple conversions and the ratio given by the application, it can
+ * be converted to a height in pixels.
+ */
+ IFont_get_Size(iface, &cySize);
+
+ fontHeight = MulDiv( cySize.s.Lo, this->cyLogical, this->cyHimetric );
+
+ memset(&logFont, 0, sizeof(LOGFONTW));
+
+ logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
+ (-fontHeight/10000L);
+ logFont.lfItalic = this->description.fItalic;
+ logFont.lfUnderline = this->description.fUnderline;
+ logFont.lfStrikeOut = this->description.fStrikethrough;
+ logFont.lfWeight = this->description.sWeight;
+ logFont.lfCharSet = this->description.sCharset;
+ logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
+ logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ logFont.lfQuality = DEFAULT_QUALITY;
+ logFont.lfPitchAndFamily = DEFAULT_PITCH;
+ strcpyW(logFont.lfFaceName,this->description.lpstrName);
+
+ this->gdiFont = CreateFontIndirectW(&logFont);
+ }
+
+ *phfont = this->gdiFont;
+ TRACE("Returning %p\n", *phfont);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_Clone (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_Clone(
+ IFont* iface,
+ IFont** ppfont)
+{
+ OLEFontImpl* newObject = 0;
+ LOGFONTW logFont;
+ INT fontHeight;
+ CY cySize;
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p)\n", this, ppfont);
+
+ if (ppfont == NULL)
+ return E_POINTER;
+
+ *ppfont = NULL;
+
+ /*
+ * Allocate space for the object.
+ */
+ newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEFontImpl));
+
+ if (newObject==NULL)
+ return E_OUTOFMEMORY;
+
+ *newObject = *this;
+
+ /* We need to alloc new memory for the string, otherwise
+ * we free memory twice.
+ */
+ newObject->description.lpstrName = HeapAlloc(
+ GetProcessHeap(),0,
+ (1+strlenW(this->description.lpstrName))*2
+ );
+ strcpyW(newObject->description.lpstrName, this->description.lpstrName);
+ /* We need to clone the HFONT too. This is just cut & paste from above */
+ IFont_get_Size(iface, &cySize);
+
+ fontHeight = MulDiv(cySize.s.Lo, this->cyLogical,this->cyHimetric);
+
+ memset(&logFont, 0, sizeof(LOGFONTW));
+
+ logFont.lfHeight = ((fontHeight%10000L)>5000L) ? (-fontHeight/10000L)-1 :
+ (-fontHeight/10000L);
+ logFont.lfItalic = this->description.fItalic;
+ logFont.lfUnderline = this->description.fUnderline;
+ logFont.lfStrikeOut = this->description.fStrikethrough;
+ logFont.lfWeight = this->description.sWeight;
+ logFont.lfCharSet = this->description.sCharset;
+ logFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
+ logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ logFont.lfQuality = DEFAULT_QUALITY;
+ logFont.lfPitchAndFamily = DEFAULT_PITCH;
+ strcpyW(logFont.lfFaceName,this->description.lpstrName);
+
+ newObject->gdiFont = CreateFontIndirectW(&logFont);
+
+
+ /* The cloned object starts with a reference count of 1 */
+ newObject->ref = 1;
+
+ *ppfont = (IFont*)newObject;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_IsEqual (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_IsEqual(
+ IFont* iface,
+ IFont* pFontOther)
+{
+ FIXME("(%p, %p), stub!\n",iface,pFontOther);
+ return E_NOTIMPL;
+}
+
+/************************************************************************
+ * OLEFontImpl_SetRatio (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_SetRatio(
+ IFont* iface,
+ LONG cyLogical,
+ LONG cyHimetric)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
+
+ this->cyLogical = cyLogical;
+ this->cyHimetric = cyHimetric;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_QueryTextMetrics (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_QueryTextMetrics(
+ IFont* iface,
+ TEXTMETRICOLE* ptm)
+{
+ HDC hdcRef;
+ HFONT hOldFont, hNewFont;
+
+ hdcRef = GetDC(0);
+ OLEFontImpl_get_hFont(iface, &hNewFont);
+ hOldFont = SelectObject(hdcRef, hNewFont);
+ GetTextMetricsW(hdcRef, ptm);
+ SelectObject(hdcRef, hOldFont);
+ ReleaseDC(0, hdcRef);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_AddRefHfont (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_AddRefHfont(
+ IFont* iface,
+ HFONT hfont)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
+
+ if ( (hfont == 0) ||
+ (hfont != this->gdiFont) )
+ return E_INVALIDARG;
+
+ this->fontLock++;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_ReleaseHfont (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_ReleaseHfont(
+ IFont* iface,
+ HFONT hfont)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
+
+ if ( (hfont == 0) ||
+ (hfont != this->gdiFont) )
+ return E_INVALIDARG;
+
+ this->fontLock--;
+
+ /*
+ * If we just released our last font reference, destroy it.
+ */
+ if (this->fontLock==0)
+ {
+ DeleteObject(this->gdiFont);
+ this->gdiFont = 0;
+ }
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_SetHdc (IFont)
+ *
+ * See Windows documentation for more details on IFont methods.
+ */
+static HRESULT WINAPI OLEFontImpl_SetHdc(
+ IFont* iface,
+ HDC hdc)
+{
+ OLEFontImpl *this = (OLEFontImpl *)iface;
+ FIXME("(%p)->(%p): Stub\n", this, hdc);
+ return E_NOTIMPL;
+}
+
+/************************************************************************
+ * OLEFontImpl_IDispatch_QueryInterface (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(
+ IDispatch* iface,
+ REFIID riid,
+ VOID** ppvoid)
+{
+ _ICOM_THIS_From_IDispatch(IFont, iface);
+
+ return IFont_QueryInterface(this, riid, ppvoid);
+}
+
+/************************************************************************
+ * OLEFontImpl_IDispatch_Release (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEFontImpl_IDispatch_Release(
+ IDispatch* iface)
+{
+ _ICOM_THIS_From_IDispatch(IFont, iface);
+
+ return IFont_Release(this);
+}
+
+/************************************************************************
+ * OLEFontImpl_IDispatch_AddRef (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEFontImpl_IDispatch_AddRef(
+ IDispatch* iface)
+{
+ _ICOM_THIS_From_IDispatch(IFont, iface);
+
+ return IFont_AddRef(this);
+}
+
+/************************************************************************
+ * OLEFontImpl_GetTypeInfoCount (IDispatch)
+ *
+ * See Windows documentation for more details on IDispatch methods.
+ */
+static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
+ IDispatch* iface,
+ unsigned int* pctinfo)
+{
+ _ICOM_THIS_From_IDispatch(IFont, iface);
+ FIXME("(%p)->(%p): Stub\n", this, pctinfo);
+
+ return E_NOTIMPL;
+}
+
+/************************************************************************
+ * OLEFontImpl_GetTypeInfo (IDispatch)
+ *
+ * See Windows documentation for more details on IDispatch methods.
+ */
+static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
+ IDispatch* iface,
+ UINT iTInfo,
+ LCID lcid,
+ ITypeInfo** ppTInfo)
+{
+ static const WCHAR stdole32tlb[] = {'s','t','d','o','l','e','3','2','.','t','l','b',0};
+ ITypeLib *tl;
+ HRESULT hres;
+
+ _ICOM_THIS_From_IDispatch(OLEFontImpl, iface);
+ TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);
+ if (iTInfo != 0)
+ return E_FAIL;
+ hres = LoadTypeLib(stdole32tlb, &tl);
+ if (FAILED(hres)) {
+ ERR("Could not load the stdole32.tlb?\n");
+ return hres;
+ }
+ hres = ITypeLib_GetTypeInfoOfGuid(tl, &IID_IDispatch, ppTInfo);
+ if (FAILED(hres)) {
+ FIXME("Did not IDispatch typeinfo from typelib, hres %lx\n",hres);
+ }
+ return hres;
+}
+
+/************************************************************************
+ * OLEFontImpl_GetIDsOfNames (IDispatch)
+ *
+ * See Windows documentation for more details on IDispatch methods.
+ */
+static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
+ IDispatch* iface,
+ REFIID riid,
+ LPOLESTR* rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID* rgDispId)
+{
+ _ICOM_THIS_From_IDispatch(IFont, iface);
+ FIXME("(%p,%s,%p,%d,%04x,%p), stub!\n", this, debugstr_guid(riid), rgszNames,
+ cNames, (int)lcid, rgDispId
+ );
+ return E_NOTIMPL;
+}
+
+/************************************************************************
+ * OLEFontImpl_Invoke (IDispatch)
+ *
+ * See Windows documentation for more details on IDispatch methods.
+ *
+ * Note: Do not call _put_Xxx methods, since setting things here
+ * should not call notify functions as I found out debugging the generic
+ * MS VB5 installer.
+ */
+static HRESULT WINAPI OLEFontImpl_Invoke(
+ IDispatch* iface,
+ DISPID dispIdMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS* pDispParams,
+ VARIANT* pVarResult,
+ EXCEPINFO* pExepInfo,
+ UINT* puArgErr)
+{
+ _ICOM_THIS_From_IDispatch(IFont, iface);
+ OLEFontImpl *xthis = (OLEFontImpl*)this;
+
+ switch (dispIdMember) {
+ case DISPID_FONT_NAME:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_BSTR;
+ return OLEFontImpl_get_Name(this, &V_BSTR(pVarResult));
+ case DISPATCH_PROPERTYPUT: {
+ BSTR name;
+ BOOL freename;
+
+ if (V_VT(&pDispParams->rgvarg[0]) == VT_DISPATCH) {
+ IFont *font;
+ HRESULT hr = S_OK;
+
+ hr = IUnknown_QueryInterface(V_DISPATCH(&pDispParams->rgvarg[0]), &IID_IFont, (void **) &font);
+ if (FAILED(hr))
+ {
+ FIXME("dispatch value for name property is not an OleFont, returning hr=0x%lx\n", hr);
+ return hr;
+ }
+
+ hr = IFont_get_Name(font, &name); /* this allocates a new BSTR so free it later */
+ if (FAILED(hr)) return hr;
+
+ IUnknown_Release(font);
+
+ freename = TRUE;
+ } else if (V_VT(&pDispParams->rgvarg[0]) == VT_BSTR) {
+ name = V_BSTR(&pDispParams->rgvarg[0]);
+ freename = FALSE;
+ } else {
+ FIXME("app is trying to set name property with a non BSTR, non dispatch value. returning E_FAIL\n");
+ return E_FAIL;
+ }
+
+ TRACE("name is %s\n", debugstr_w(name));
+
+ if (!xthis->description.lpstrName)
+ xthis->description.lpstrName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name)+1) * sizeof(WCHAR));
+ else
+ xthis->description.lpstrName = HeapReAlloc(GetProcessHeap(), 0, xthis->description.lpstrName, (lstrlenW(name)+1) * sizeof(WCHAR));
+
+ if (xthis->description.lpstrName==0)
+ return E_OUTOFMEMORY;
+ strcpyW(xthis->description.lpstrName, name);
+
+ if (freename) SysFreeString(name);
+
+ return S_OK;
+ }
+ }
+ break;
+ case DISPID_FONT_BOLD:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_BOOL;
+ return OLEFontImpl_get_Bold(this, (BOOL*)&V_BOOL(pVarResult));
+ case DISPATCH_PROPERTYPUT:
+ if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
+ FIXME("DISPID_FONT_BOLD/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
+ return E_FAIL;
+ } else {
+ xthis->description.sWeight = V_BOOL(&pDispParams->rgvarg[0]) ? FW_BOLD : FW_NORMAL;
+ return S_OK;
+ }
+ }
+ break;
+ case DISPID_FONT_ITALIC:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_BOOL;
+ return OLEFontImpl_get_Italic(this, (BOOL*)&V_BOOL(pVarResult));
+ case DISPATCH_PROPERTYPUT:
+ if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
+ FIXME("DISPID_FONT_ITALIC/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
+ return E_FAIL;
+ } else {
+ xthis->description.fItalic = V_BOOL(&pDispParams->rgvarg[0]);
+ return S_OK;
+ }
+ }
+ break;
+ case DISPID_FONT_UNDER:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_BOOL;
+ return OLEFontImpl_get_Underline(this, (BOOL*)&V_BOOL(pVarResult));
+ case DISPATCH_PROPERTYPUT:
+ if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
+ FIXME("DISPID_FONT_UNDER/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
+ return E_FAIL;
+ } else {
+ xthis->description.fUnderline = V_BOOL(&pDispParams->rgvarg[0]);
+ return S_OK;
+ }
+ }
+ break;
+ case DISPID_FONT_STRIKE:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_BOOL;
+ return OLEFontImpl_get_Strikethrough(this, (BOOL*)&V_BOOL(pVarResult));
+ case DISPATCH_PROPERTYPUT:
+ if (V_VT(&pDispParams->rgvarg[0]) != VT_BOOL) {
+ FIXME("DISPID_FONT_STRIKE/put, vt is %d, not VT_BOOL.\n",V_VT(&pDispParams->rgvarg[0]));
+ return E_FAIL;
+ } else {
+ xthis->description.fStrikethrough = V_BOOL(&pDispParams->rgvarg[0]);
+ return S_OK;
+ }
+ }
+ break;
+ case DISPID_FONT_SIZE:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYPUT: {
+ assert (pDispParams->cArgs == 1);
+ xthis->description.cySize.s.Hi = 0;
+ if (V_VT(&pDispParams->rgvarg[0]) != VT_CY) {
+ if (V_VT(&pDispParams->rgvarg[0]) == VT_I2) {
+ xthis->description.cySize.s.Lo = V_I2(&pDispParams->rgvarg[0]) * 10000;
+ } else {
+ FIXME("property put for Size with vt %d unsupported!\n",V_VT(&pDispParams->rgvarg[0]));
+ }
+ } else {
+ xthis->description.cySize.s.Lo = V_CY(&pDispParams->rgvarg[0]).s.Lo;
+ }
+ return S_OK;
+ }
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_CY;
+ return OLEFontImpl_get_Size(this, &V_CY(pVarResult));
+ }
+ break;
+ case DISPID_FONT_CHARSET:
+ switch (wFlags) {
+ case DISPATCH_PROPERTYPUT:
+ assert (pDispParams->cArgs == 1);
+ if (V_VT(&pDispParams->rgvarg[0]) != VT_I2)
+ FIXME("varg of first disparg is not VT_I2, but %d\n",V_VT(&pDispParams->rgvarg[0]));
+ xthis->description.sCharset = V_I2(&pDispParams->rgvarg[0]);
+ return S_OK;
+ case DISPATCH_PROPERTYGET:
+ case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
+ V_VT(pVarResult) = VT_I2;
+ return OLEFontImpl_get_Charset(this, &V_I2(pVarResult));
+ }
+ break;
+ }
+ FIXME("%p->(%ld,%s,%lx,%x,%p,%p,%p,%p), unhandled dispid/flag!\n",
+ this,dispIdMember,debugstr_guid(riid),lcid,
+ wFlags,pDispParams,pVarResult,pExepInfo,puArgErr
+ );
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_IPersistStream_QueryInterface (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(
+ IPersistStream* iface,
+ REFIID riid,
+ VOID** ppvoid)
+{
+ _ICOM_THIS_From_IPersistStream(IFont, iface);
+
+ return IFont_QueryInterface(this, riid, ppvoid);
+}
+
+/************************************************************************
+ * OLEFontImpl_IPersistStream_Release (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEFontImpl_IPersistStream_Release(
+ IPersistStream* iface)
+{
+ _ICOM_THIS_From_IPersistStream(IFont, iface);
+
+ return IFont_Release(this);
+}
+
+/************************************************************************
+ * OLEFontImpl_IPersistStream_AddRef (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEFontImpl_IPersistStream_AddRef(
+ IPersistStream* iface)
+{
+ _ICOM_THIS_From_IPersistStream(IFont, iface);
+
+ return IFont_AddRef(this);
+}
+
+/************************************************************************
+ * OLEFontImpl_GetClassID (IPersistStream)
+ *
+ * See Windows documentation for more details on IPersistStream methods.
+ */
+static HRESULT WINAPI OLEFontImpl_GetClassID(
+ IPersistStream* iface,
+ CLSID* pClassID)
+{
+ TRACE("(%p,%p)\n",iface,pClassID);
+ if (pClassID==0)
+ return E_POINTER;
+
+ memcpy(pClassID, &CLSID_StdFont, sizeof(CLSID_StdFont));
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_IsDirty (IPersistStream)
+ *
+ * See Windows documentation for more details on IPersistStream methods.
+ */
+static HRESULT WINAPI OLEFontImpl_IsDirty(
+ IPersistStream* iface)
+{
+ TRACE("(%p)\n",iface);
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_Load (IPersistStream)
+ *
+ * See Windows documentation for more details on IPersistStream methods.
+ *
+ * This is the format of the standard font serialization as far as I
+ * know
+ *
+ * Offset Type Value Comment
+ * 0x0000 Byte Unknown Probably a version number, contains 0x01
+ * 0x0001 Short Charset Charset value from the FONTDESC structure
+ * 0x0003 Byte Attributes Flags defined as follows:
+ * 00000010 - Italic
+ * 00000100 - Underline
+ * 00001000 - Strikethrough
+ * 0x0004 Short Weight Weight value from FONTDESC structure
+ * 0x0006 DWORD size "Low" portion of the cySize member of the FONTDESC
+ * structure/
+ * 0x000A Byte name length Length of the font name string (no null character)
+ * 0x000B String name Name of the font (ASCII, no nul character)
+ */
+static HRESULT WINAPI OLEFontImpl_Load(
+ IPersistStream* iface,
+ IStream* pLoadStream)
+{
+ char readBuffer[0x100];
+ ULONG cbRead;
+ BYTE bVersion;
+ BYTE bAttributes;
+ BYTE bStringSize;
+ INT len;
+
+ _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
+
+ /*
+ * Read the version byte
+ */
+ IStream_Read(pLoadStream, &bVersion, 1, &cbRead);
+
+ if ( (cbRead!=1) ||
+ (bVersion!=0x01) )
+ return E_FAIL;
+
+ /*
+ * Charset
+ */
+ IStream_Read(pLoadStream, &this->description.sCharset, 2, &cbRead);
+
+ if (cbRead!=2)
+ return E_FAIL;
+
+ /*
+ * Attributes
+ */
+ IStream_Read(pLoadStream, &bAttributes, 1, &cbRead);
+
+ if (cbRead!=1)
+ return E_FAIL;
+
+ this->description.fItalic = (bAttributes & FONTPERSIST_ITALIC) != 0;
+ this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
+ this->description.fUnderline = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
+
+ /*
+ * Weight
+ */
+ IStream_Read(pLoadStream, &this->description.sWeight, 2, &cbRead);
+
+ if (cbRead!=2)
+ return E_FAIL;
+
+ /*
+ * Size
+ */
+ IStream_Read(pLoadStream, &this->description.cySize.s.Lo, 4, &cbRead);
+
+ if (cbRead!=4)
+ return E_FAIL;
+
+ this->description.cySize.s.Hi = 0;
+
+ /*
+ * FontName
+ */
+ IStream_Read(pLoadStream, &bStringSize, 1, &cbRead);
+
+ if (cbRead!=1)
+ return E_FAIL;
+
+ IStream_Read(pLoadStream, readBuffer, bStringSize, &cbRead);
+
+ if (cbRead!=bStringSize)
+ return E_FAIL;
+
+ HeapFree(GetProcessHeap(), 0, this->description.lpstrName);
+
+ len = MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, NULL, 0 );
+ this->description.lpstrName = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
+ this->description.lpstrName[len] = 0;
+
+ /* Ensure use of this font causes a new one to be created @@@@ */
+ DeleteObject(this->gdiFont);
+ this->gdiFont = 0;
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_Save (IPersistStream)
+ *
+ * See Windows documentation for more details on IPersistStream methods.
+ */
+static HRESULT WINAPI OLEFontImpl_Save(
+ IPersistStream* iface,
+ IStream* pOutStream,
+ BOOL fClearDirty)
+{
+ char* writeBuffer = NULL;
+ ULONG cbWritten;
+ BYTE bVersion = 0x01;
+ BYTE bAttributes;
+ BYTE bStringSize;
+
+ _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
+
+ /*
+ * Read the version byte
+ */
+ IStream_Write(pOutStream, &bVersion, 1, &cbWritten);
+
+ if (cbWritten!=1)
+ return E_FAIL;
+
+ /*
+ * Charset
+ */
+ IStream_Write(pOutStream, &this->description.sCharset, 2, &cbWritten);
+
+ if (cbWritten!=2)
+ return E_FAIL;
+
+ /*
+ * Attributes
+ */
+ bAttributes = 0;
+
+ if (this->description.fItalic)
+ bAttributes |= FONTPERSIST_ITALIC;
+
+ if (this->description.fStrikethrough)
+ bAttributes |= FONTPERSIST_STRIKETHROUGH;
+
+ if (this->description.fUnderline)
+ bAttributes |= FONTPERSIST_UNDERLINE;
+
+ IStream_Write(pOutStream, &bAttributes, 1, &cbWritten);
+
+ if (cbWritten!=1)
+ return E_FAIL;
+
+ /*
+ * Weight
+ */
+ IStream_Write(pOutStream, &this->description.sWeight, 2, &cbWritten);
+
+ if (cbWritten!=2)
+ return E_FAIL;
+
+ /*
+ * Size
+ */
+ IStream_Write(pOutStream, &this->description.cySize.s.Lo, 4, &cbWritten);
+
+ if (cbWritten!=4)
+ return E_FAIL;
+
+ /*
+ * FontName
+ */
+ if (this->description.lpstrName!=0)
+ bStringSize = WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
+ strlenW(this->description.lpstrName), NULL, 0, NULL, NULL );
+ else
+ bStringSize = 0;
+
+ IStream_Write(pOutStream, &bStringSize, 1, &cbWritten);
+
+ if (cbWritten!=1)
+ return E_FAIL;
+
+ if (bStringSize!=0)
+ {
+ if (!(writeBuffer = HeapAlloc( GetProcessHeap(), 0, bStringSize ))) return E_OUTOFMEMORY;
+ WideCharToMultiByte( CP_ACP, 0, this->description.lpstrName,
+ strlenW(this->description.lpstrName),
+ writeBuffer, bStringSize, NULL, NULL );
+
+ IStream_Write(pOutStream, writeBuffer, bStringSize, &cbWritten);
+ HeapFree(GetProcessHeap(), 0, writeBuffer);
+
+ if (cbWritten!=bStringSize)
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_GetSizeMax (IPersistStream)
+ *
+ * See Windows documentation for more details on IPersistStream methods.
+ */
+static HRESULT WINAPI OLEFontImpl_GetSizeMax(
+ IPersistStream* iface,
+ ULARGE_INTEGER* pcbSize)
+{
+ _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
+
+ if (pcbSize==NULL)
+ return E_POINTER;
+
+ pcbSize->u.HighPart = 0;
+ pcbSize->u.LowPart = 0;
+
+ pcbSize->u.LowPart += sizeof(BYTE); /* Version */
+ pcbSize->u.LowPart += sizeof(WORD); /* Lang code */
+ pcbSize->u.LowPart += sizeof(BYTE); /* Flags */
+ pcbSize->u.LowPart += sizeof(WORD); /* Weight */
+ pcbSize->u.LowPart += sizeof(DWORD); /* Size */
+ pcbSize->u.LowPart += sizeof(BYTE); /* StrLength */
+
+ if (this->description.lpstrName!=0)
+ pcbSize->u.LowPart += lstrlenW(this->description.lpstrName);
+
+ return S_OK;
+}
+
+/************************************************************************
+ * OLEFontImpl_IConnectionPointContainer_QueryInterface (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
+ IConnectionPointContainer* iface,
+ REFIID riid,
+ VOID** ppvoid)
+{
+ _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
+
+ return IFont_QueryInterface((IFont*)this, riid, ppvoid);
+}
+
+/************************************************************************
+ * OLEFontImpl_IConnectionPointContainer_Release (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_Release(
+ IConnectionPointContainer* iface)
+{
+ _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
+
+ return IFont_Release((IFont*)this);
+}
+
+/************************************************************************
+ * OLEFontImpl_IConnectionPointContainer_AddRef (IUnknown)
+ *
+ * See Windows documentation for more details on IUnknown methods.
+ */
+static ULONG WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
+ IConnectionPointContainer* iface)
+{
+ _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
+
+ return IFont_AddRef((IFont*)this);
+}
+
+/************************************************************************
+ * OLEFontImpl_EnumConnectionPoints (IConnectionPointContainer)
+ *
+ * See Windows documentation for more details on IConnectionPointContainer
+ * methods.
+ */
+static HRESULT WINAPI OLEFontImpl_EnumConnectionPoints(
+ IConnectionPointContainer* iface,
+ IEnumConnectionPoints **ppEnum)
+{
+ _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
+
+ FIXME("(%p)->(%p): stub\n", this, ppEnum);
+ return E_NOTIMPL;
+}
+
+/************************************************************************
+ * OLEFontImpl_FindConnectionPoint (IConnectionPointContainer)
+ *
+ * See Windows documentation for more details on IConnectionPointContainer
+ * methods.
+ */
+static HRESULT WINAPI OLEFontImpl_FindConnectionPoint(
+ IConnectionPointContainer* iface,
+ REFIID riid,
+ IConnectionPoint **ppCp)
+{
+ _ICOM_THIS_From_IConnectionPointContainer(OLEFontImpl, iface);
+ TRACE("(%p)->(%s, %p): stub\n", this, debugstr_guid(riid), ppCp);
+
+ if(memcmp(riid, &IID_IPropertyNotifySink, sizeof(IID_IPropertyNotifySink)) == 0) {
+ return IConnectionPoint_QueryInterface(this->pCP, &IID_IConnectionPoint,
+ (LPVOID)ppCp);
+ } else {
+ FIXME("Tried to find connection point on %s\n", debugstr_guid(riid));
+ return E_NOINTERFACE;
+ }
+}
+
+/************************************************************************
+ * OLEFontImpl implementation of IPersistPropertyBag.
+ */
+static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_QueryInterface(
+ IPersistPropertyBag *iface, REFIID riid, LPVOID *ppvObj
+) {
+ _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
+ return IFont_QueryInterface(this,riid,ppvObj);
+}
+
+static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_AddRef(
+ IPersistPropertyBag *iface
+) {
+ _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
+ return IFont_AddRef(this);
+}
+
+static ULONG WINAPI OLEFontImpl_IPersistPropertyBag_Release(
+ IPersistPropertyBag *iface
+) {
+ _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
+ return IFont_Release(this);
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_GetClassID(
+ IPersistPropertyBag *iface, CLSID *classid
+) {
+ FIXME("(%p,%p), stub!\n", iface, classid);
+ return E_FAIL;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_InitNew(
+ IPersistPropertyBag *iface
+) {
+ FIXME("(%p), stub!\n", iface);
+ return S_OK;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Load(
+ IPersistPropertyBag *iface, IPropertyBag* pPropBag, IErrorLog* pErrorLog
+) {
+/* (from Visual Basic 6 property bag)
+ Name = "MS Sans Serif"
+ Size = 13.8
+ Charset = 0
+ Weight = 400
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+*/
+ static const WCHAR sAttrName[] = {'N','a','m','e',0};
+ static const WCHAR sAttrSize[] = {'S','i','z','e',0};
+ static const WCHAR sAttrCharset[] = {'C','h','a','r','s','e','t',0};
+ static const WCHAR sAttrWeight[] = {'W','e','i','g','h','t',0};
+ static const WCHAR sAttrUnderline[] = {'U','n','d','e','r','l','i','n','e',0};
+ static const WCHAR sAttrItalic[] = {'I','t','a','l','i','c',0};
+ static const WCHAR sAttrStrikethrough[] = {'S','t','r','i','k','e','t','h','r','o','u','g','h',0};
+ VARIANT rawAttr;
+ VARIANT valueAttr;
+ HRESULT iRes = S_OK;
+ _ICOM_THIS_From_IPersistPropertyBag(IFont, iface);
+
+ VariantInit(&rawAttr);
+ VariantInit(&valueAttr);
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrName, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BSTR);
+ if (iRes == S_OK)
+ iRes = IFont_put_Name(this, V_BSTR(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+ }
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrSize, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_CY);
+ if (iRes == S_OK)
+ iRes = IFont_put_Size(this, V_CY(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+ }
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrCharset, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
+ if (iRes == S_OK)
+ iRes = IFont_put_Charset(this, V_I2(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+ }
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrWeight, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_I2);
+ if (iRes == S_OK)
+ iRes = IFont_put_Weight(this, V_I2(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+
+ }
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrUnderline, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
+ if (iRes == S_OK)
+ iRes = IFont_put_Underline(this, V_BOOL(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+ }
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrItalic, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
+ if (iRes == S_OK)
+ iRes = IFont_put_Italic(this, V_BOOL(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+ }
+
+ if (iRes == S_OK) {
+ iRes = IPropertyBag_Read(pPropBag, sAttrStrikethrough, &rawAttr, pErrorLog);
+ if (iRes == S_OK)
+ {
+ iRes = VariantChangeType(&rawAttr, &valueAttr, 0, VT_BOOL);
+ if (iRes == S_OK)
+ IFont_put_Strikethrough(this, V_BOOL(&valueAttr));
+ }
+ else if (iRes == E_INVALIDARG)
+ iRes = S_OK;
+ VariantClear(&rawAttr);
+ VariantClear(&valueAttr);
+ }
+
+ if (FAILED(iRes))
+ WARN("-- 0x%08lx\n", iRes);
+ return iRes;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistPropertyBag_Save(
+ IPersistPropertyBag *iface, IPropertyBag* pPropBag, BOOL fClearDirty,
+ BOOL fSaveAllProperties
+) {
+ FIXME("(%p,%p,%d,%d), stub!\n", iface, pPropBag, fClearDirty, fSaveAllProperties);
+ return E_FAIL;
+}
+
+static IPersistPropertyBagVtbl OLEFontImpl_IPersistPropertyBag_VTable =
+{
+ OLEFontImpl_IPersistPropertyBag_QueryInterface,
+ OLEFontImpl_IPersistPropertyBag_AddRef,
+ OLEFontImpl_IPersistPropertyBag_Release,
+
+ OLEFontImpl_IPersistPropertyBag_GetClassID,
+ OLEFontImpl_IPersistPropertyBag_InitNew,
+ OLEFontImpl_IPersistPropertyBag_Load,
+ OLEFontImpl_IPersistPropertyBag_Save
+};
+
+/************************************************************************
+ * OLEFontImpl implementation of IPersistStreamInit.
+ */
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_QueryInterface(
+ IPersistStreamInit *iface, REFIID riid, LPVOID *ppvObj
+) {
+ _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
+ return IFont_QueryInterface(this,riid,ppvObj);
+}
+
+static ULONG WINAPI OLEFontImpl_IPersistStreamInit_AddRef(
+ IPersistStreamInit *iface
+) {
+ _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
+ return IFont_AddRef(this);
+}
+
+static ULONG WINAPI OLEFontImpl_IPersistStreamInit_Release(
+ IPersistStreamInit *iface
+) {
+ _ICOM_THIS_From_IPersistStreamInit(IFont, iface);
+ return IFont_Release(this);
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetClassID(
+ IPersistStreamInit *iface, CLSID *classid
+) {
+ FIXME("(%p,%p), stub!\n", iface, classid);
+ return E_FAIL;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_IsDirty(
+ IPersistStreamInit *iface
+) {
+ FIXME("(%p), stub!\n", iface);
+ return E_FAIL;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Load(
+ IPersistStreamInit *iface, LPSTREAM pStm
+) {
+ FIXME("(%p,%p), stub!\n", iface, pStm);
+ return E_FAIL;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_Save(
+ IPersistStreamInit *iface, LPSTREAM pStm, BOOL fClearDirty
+) {
+ FIXME("(%p,%p,%d), stub!\n", iface, pStm, fClearDirty);
+ return E_FAIL;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_GetSizeMax(
+ IPersistStreamInit *iface, ULARGE_INTEGER *pcbSize
+) {
+ FIXME("(%p,%p), stub!\n", iface, pcbSize);
+ return E_FAIL;
+}
+
+static HRESULT WINAPI OLEFontImpl_IPersistStreamInit_InitNew(
+ IPersistStreamInit *iface
+) {
+ FIXME("(%p), stub!\n", iface);
+ return S_OK;
+}
+
+static IPersistStreamInitVtbl OLEFontImpl_IPersistStreamInit_VTable =
+{
+ OLEFontImpl_IPersistStreamInit_QueryInterface,
+ OLEFontImpl_IPersistStreamInit_AddRef,
+ OLEFontImpl_IPersistStreamInit_Release,
+
+ OLEFontImpl_IPersistStreamInit_GetClassID,
+ OLEFontImpl_IPersistStreamInit_IsDirty,
+ OLEFontImpl_IPersistStreamInit_Load,
+ OLEFontImpl_IPersistStreamInit_Save,
+ OLEFontImpl_IPersistStreamInit_GetSizeMax,
+ OLEFontImpl_IPersistStreamInit_InitNew
+};
+
+/*******************************************************************************
+ * StdFont ClassFactory
+ */
+typedef struct
+{
+ /* IUnknown fields */
+ IClassFactoryVtbl *lpVtbl;
+ DWORD ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI
+SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+ FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+SFCF_AddRef(LPCLASSFACTORY iface) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI SFCF_Release(LPCLASSFACTORY iface) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ /* static class, won't be freed */
+ return InterlockedDecrement(&This->ref);
+}
+
+static HRESULT WINAPI SFCF_CreateInstance(
+ LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+ return OleCreateFontIndirect(NULL,riid,ppobj);
+
+}
+
+static HRESULT WINAPI SFCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ FIXME("(%p)->(%d),stub!\n",This,dolock);
+ return S_OK;
+}
+
+static IClassFactoryVtbl SFCF_Vtbl = {
+ SFCF_QueryInterface,
+ SFCF_AddRef,
+ SFCF_Release,
+ SFCF_CreateInstance,
+ SFCF_LockServer
+};
+static IClassFactoryImpl STDFONT_CF = {&SFCF_Vtbl, 1 };
+
+void _get_STDFONT_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDFONT_CF; }