2 * Copyright (C) 2008 Tony Wasserka
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/port.h"
23 #include "wine/debug.h"
24 #include "wine/unicode.h"
25 #include "d3dx9_36_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
29 typedef struct ID3DXFontImpl
31 ID3DXFont ID3DXFont_iface;
34 IDirect3DDevice9 *device;
41 static inline ID3DXFontImpl *impl_from_ID3DXFont(ID3DXFont *iface)
43 return CONTAINING_RECORD(iface, ID3DXFontImpl, ID3DXFont_iface);
46 static HRESULT WINAPI ID3DXFontImpl_QueryInterface(ID3DXFont *iface, REFIID riid, void **object)
48 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
50 TRACE("(%p): QueryInterface from %s\n", This, debugstr_guid(riid));
51 if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ID3DXFont)) {
52 IUnknown_AddRef(iface);
56 WARN("(%p)->(%s, %p): not found\n", iface, debugstr_guid(riid), *object);
60 static ULONG WINAPI ID3DXFontImpl_AddRef(ID3DXFont *iface)
62 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
63 ULONG ref=InterlockedIncrement(&This->ref);
64 TRACE("(%p)->(): AddRef from %d\n", This, ref-1);
68 static ULONG WINAPI ID3DXFontImpl_Release(ID3DXFont *iface)
70 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
71 ULONG ref=InterlockedDecrement(&This->ref);
73 TRACE("(%p)->(): ReleaseRef to %d\n", This, ref);
76 DeleteObject(This->hfont);
78 IDirect3DDevice9_Release(This->device);
79 HeapFree(GetProcessHeap(), 0, This);
84 static HRESULT WINAPI ID3DXFontImpl_GetDevice(ID3DXFont *iface, LPDIRECT3DDEVICE9 *device)
86 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
88 TRACE("(%p)->(%p)\n", This, device);
90 if( !device ) return D3DERR_INVALIDCALL;
91 *device = This->device;
92 IDirect3DDevice9_AddRef(This->device);
97 static HRESULT WINAPI ID3DXFontImpl_GetDescA(ID3DXFont *iface, D3DXFONT_DESCA *desc)
99 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
101 TRACE("(%p)->(%p)\n", This, desc);
103 if( !desc ) return D3DERR_INVALIDCALL;
104 memcpy(desc, &This->desc, FIELD_OFFSET(D3DXFONT_DESCA, FaceName));
105 WideCharToMultiByte(CP_ACP, 0, This->desc.FaceName, -1, desc->FaceName, sizeof(desc->FaceName) / sizeof(CHAR), NULL, NULL);
110 static HRESULT WINAPI ID3DXFontImpl_GetDescW(ID3DXFont *iface, D3DXFONT_DESCW *desc)
112 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
114 TRACE("(%p)->(%p)\n", This, desc);
116 if( !desc ) return D3DERR_INVALIDCALL;
122 static BOOL WINAPI ID3DXFontImpl_GetTextMetricsA(ID3DXFont *iface, TEXTMETRICA *metrics)
124 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
125 TRACE("(%p)->(%p)\n", This, metrics);
126 return GetTextMetricsA(This->hdc, metrics);
129 static BOOL WINAPI ID3DXFontImpl_GetTextMetricsW(ID3DXFont *iface, TEXTMETRICW *metrics)
131 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
132 TRACE("(%p)->(%p)\n", This, metrics);
133 return GetTextMetricsW(This->hdc, metrics);
136 static HDC WINAPI ID3DXFontImpl_GetDC(ID3DXFont *iface)
138 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
139 TRACE("(%p)->()\n", This);
143 static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph,
144 LPDIRECT3DTEXTURE9 *texture, RECT *blackbox, POINT *cellinc)
146 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
147 FIXME("(%p)->(%u, %p, %p, %p): stub\n", This, glyph, texture, blackbox, cellinc);
151 static HRESULT WINAPI ID3DXFontImpl_PreloadCharacters(ID3DXFont *iface, UINT first, UINT last)
153 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
154 FIXME("(%p)->(%u, %u): stub\n", This, first, last);
158 static HRESULT WINAPI ID3DXFontImpl_PreloadGlyphs(ID3DXFont *iface, UINT first, UINT last)
160 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
161 FIXME("(%p)->(%u, %u): stub\n", This, first, last);
165 static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, LPCSTR string, INT count)
167 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
168 FIXME("(%p)->(%s, %d): stub\n", This, string, count);
172 static HRESULT WINAPI ID3DXFontImpl_PreloadTextW(ID3DXFont *iface, LPCWSTR string, INT count)
174 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
175 FIXME("(%p)->(%s, %d): stub\n", This, debugstr_w(string), count);
179 static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, LPD3DXSPRITE sprite, LPCSTR string,
180 INT count, LPRECT rect, DWORD format, D3DCOLOR color)
182 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
183 FIXME("(%p)->(%p, %s, %d, %p, %d, %#x): stub\n", This, sprite, string, count, rect, format, color);
187 static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, LPD3DXSPRITE sprite, LPCWSTR string,
188 INT count, LPRECT rect, DWORD format, D3DCOLOR color)
190 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
191 FIXME("(%p)->(%p, %s, %d, %p, %d, %#x): stub\n", This, sprite, debugstr_w(string), count, rect, format, color);
195 static HRESULT WINAPI ID3DXFontImpl_OnLostDevice(ID3DXFont *iface)
197 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
198 FIXME("(%p)->(): stub\n", This);
202 static HRESULT WINAPI ID3DXFontImpl_OnResetDevice(ID3DXFont *iface)
204 ID3DXFontImpl *This=impl_from_ID3DXFont(iface);
205 FIXME("(%p)->(): stub\n", This);
209 static const ID3DXFontVtbl D3DXFont_Vtbl =
211 /*** IUnknown methods ***/
212 ID3DXFontImpl_QueryInterface,
213 ID3DXFontImpl_AddRef,
214 ID3DXFontImpl_Release,
215 /*** ID3DXFont methods ***/
216 ID3DXFontImpl_GetDevice,
217 ID3DXFontImpl_GetDescA,
218 ID3DXFontImpl_GetDescW,
219 ID3DXFontImpl_GetTextMetricsA,
220 ID3DXFontImpl_GetTextMetricsW,
222 ID3DXFontImpl_GetGlyphData,
223 ID3DXFontImpl_PreloadCharacters,
224 ID3DXFontImpl_PreloadGlyphs,
225 ID3DXFontImpl_PreloadTextA,
226 ID3DXFontImpl_PreloadTextW,
227 ID3DXFontImpl_DrawTextA,
228 ID3DXFontImpl_DrawTextW,
229 ID3DXFontImpl_OnLostDevice,
230 ID3DXFontImpl_OnResetDevice
233 HRESULT WINAPI D3DXCreateFontA(LPDIRECT3DDEVICE9 device, INT height, UINT width, UINT weight, UINT miplevels, BOOL italic, DWORD charset,
234 DWORD precision, DWORD quality, DWORD pitchandfamily, LPCSTR facename, LPD3DXFONT *font)
238 if( !device || !font ) return D3DERR_INVALIDCALL;
243 desc.MipLevels=miplevels;
245 desc.CharSet=charset;
246 desc.OutputPrecision=precision;
247 desc.Quality=quality;
248 desc.PitchAndFamily=pitchandfamily;
249 if(facename != NULL) lstrcpyA(desc.FaceName, facename);
250 else desc.FaceName[0] = '\0';
252 return D3DXCreateFontIndirectA(device, &desc, font);
255 HRESULT WINAPI D3DXCreateFontW(LPDIRECT3DDEVICE9 device, INT height, UINT width, UINT weight, UINT miplevels, BOOL italic, DWORD charset,
256 DWORD precision, DWORD quality, DWORD pitchandfamily, LPCWSTR facename, LPD3DXFONT *font)
260 if( !device || !font ) return D3DERR_INVALIDCALL;
265 desc.MipLevels=miplevels;
267 desc.CharSet=charset;
268 desc.OutputPrecision=precision;
269 desc.Quality=quality;
270 desc.PitchAndFamily=pitchandfamily;
271 if(facename != NULL) strcpyW(desc.FaceName, facename);
272 else desc.FaceName[0] = '\0';
274 return D3DXCreateFontIndirectW(device, &desc, font);
277 /***********************************************************************
278 * D3DXCreateFontIndirectA (D3DX9_36.@)
280 HRESULT WINAPI D3DXCreateFontIndirectA(LPDIRECT3DDEVICE9 device, CONST D3DXFONT_DESCA *desc, LPD3DXFONT *font)
282 D3DXFONT_DESCW widedesc;
284 if( !device || !desc || !font ) return D3DERR_INVALIDCALL;
286 /* Copy everything but the last structure member. This requires the
287 two D3DXFONT_DESC structures to be equal until the FaceName member */
288 memcpy(&widedesc, desc, FIELD_OFFSET(D3DXFONT_DESCA, FaceName));
289 MultiByteToWideChar(CP_ACP, 0, desc->FaceName, -1,
290 widedesc.FaceName, sizeof(widedesc.FaceName)/sizeof(WCHAR));
291 return D3DXCreateFontIndirectW(device, &widedesc, font);
294 /***********************************************************************
295 * D3DXCreateFontIndirectW (D3DX9_36.@)
297 HRESULT WINAPI D3DXCreateFontIndirectW(LPDIRECT3DDEVICE9 device, CONST D3DXFONT_DESCW *desc, LPD3DXFONT *font)
299 D3DDEVICE_CREATION_PARAMETERS cpars;
301 ID3DXFontImpl *object;
305 FIXME("(%p, %p, %p): stub\n", device, desc, font);
307 if( !device || !desc || !font ) return D3DERR_INVALIDCALL;
309 /* the device MUST support D3DFMT_A8R8G8B8 */
310 IDirect3DDevice9_GetDirect3D(device, &d3d);
311 IDirect3DDevice9_GetCreationParameters(device, &cpars);
312 IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
313 hr = IDirect3D9_CheckDeviceFormat(d3d, cpars.AdapterOrdinal, cpars.DeviceType, mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
315 IDirect3D9_Release(d3d);
316 return D3DXERR_INVALIDDATA;
318 IDirect3D9_Release(d3d);
320 object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXFontImpl));
323 return E_OUTOFMEMORY;
325 object->ID3DXFont_iface.lpVtbl = &D3DXFont_Vtbl;
327 object->device=device;
330 object->hdc = CreateCompatibleDC(NULL);
332 HeapFree(GetProcessHeap(), 0, object);
333 return D3DXERR_INVALIDDATA;
336 object->hfont = CreateFontW(desc->Height, desc->Width, 0, 0, desc->Weight, desc->Italic, FALSE, FALSE, desc->CharSet,
337 desc->OutputPrecision, CLIP_DEFAULT_PRECIS, desc->Quality, desc->PitchAndFamily, desc->FaceName);
338 if( !object->hfont ) {
339 DeleteDC(object->hdc);
340 HeapFree(GetProcessHeap(), 0, object);
341 return D3DXERR_INVALIDDATA;
343 SelectObject(object->hdc, object->hfont);
345 IDirect3DDevice9_AddRef(device);
346 *font=&object->ID3DXFont_iface;