1 #ifdef __REACTOS__ 2 #include "precomp.h" 3 #else 4 /* 5 * Copyright (C) 2008 Tony Wasserka 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 * 21 */ 22 23 #include "config.h" 24 #include "wine/port.h" 25 26 #include "d3dx9_private.h" 27 #include "wine/unicode.h" 28 #endif /* __REACTOS__ */ 29 30 WINE_DEFAULT_DEBUG_CHANNEL(d3dx); 31 32 struct d3dx_font 33 { 34 ID3DXFont ID3DXFont_iface; 35 LONG ref; 36 37 IDirect3DDevice9 *device; 38 D3DXFONT_DESCW desc; 39 40 HDC hdc; 41 HFONT hfont; 42 }; 43 44 static inline struct d3dx_font *impl_from_ID3DXFont(ID3DXFont *iface) 45 { 46 return CONTAINING_RECORD(iface, struct d3dx_font, ID3DXFont_iface); 47 } 48 49 static HRESULT WINAPI ID3DXFontImpl_QueryInterface(ID3DXFont *iface, REFIID riid, void **out) 50 { 51 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 52 53 if (IsEqualGUID(riid, &IID_ID3DXFont) 54 || IsEqualGUID(riid, &IID_IUnknown)) 55 { 56 IUnknown_AddRef(iface); 57 *out = iface; 58 return S_OK; 59 } 60 61 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 62 63 *out = NULL; 64 return E_NOINTERFACE; 65 } 66 67 static ULONG WINAPI ID3DXFontImpl_AddRef(ID3DXFont *iface) 68 { 69 struct d3dx_font *This = impl_from_ID3DXFont(iface); 70 ULONG ref=InterlockedIncrement(&This->ref); 71 TRACE("%p increasing refcount to %u\n", iface, ref); 72 return ref; 73 } 74 75 static ULONG WINAPI ID3DXFontImpl_Release(ID3DXFont *iface) 76 { 77 struct d3dx_font *This = impl_from_ID3DXFont(iface); 78 ULONG ref=InterlockedDecrement(&This->ref); 79 80 TRACE("%p decreasing refcount to %u\n", iface, ref); 81 82 if(ref==0) { 83 DeleteObject(This->hfont); 84 DeleteDC(This->hdc); 85 IDirect3DDevice9_Release(This->device); 86 HeapFree(GetProcessHeap(), 0, This); 87 } 88 return ref; 89 } 90 91 static HRESULT WINAPI ID3DXFontImpl_GetDevice(ID3DXFont *iface, IDirect3DDevice9 **device) 92 { 93 struct d3dx_font *This = impl_from_ID3DXFont(iface); 94 95 TRACE("iface %p, device %p\n", iface, device); 96 97 if( !device ) return D3DERR_INVALIDCALL; 98 *device = This->device; 99 IDirect3DDevice9_AddRef(This->device); 100 101 return D3D_OK; 102 } 103 104 static HRESULT WINAPI ID3DXFontImpl_GetDescA(ID3DXFont *iface, D3DXFONT_DESCA *desc) 105 { 106 struct d3dx_font *This = impl_from_ID3DXFont(iface); 107 108 TRACE("iface %p, desc %p\n", iface, desc); 109 110 if( !desc ) return D3DERR_INVALIDCALL; 111 memcpy(desc, &This->desc, FIELD_OFFSET(D3DXFONT_DESCA, FaceName)); 112 WideCharToMultiByte(CP_ACP, 0, This->desc.FaceName, -1, desc->FaceName, ARRAY_SIZE(desc->FaceName), NULL, NULL); 113 114 return D3D_OK; 115 } 116 117 static HRESULT WINAPI ID3DXFontImpl_GetDescW(ID3DXFont *iface, D3DXFONT_DESCW *desc) 118 { 119 struct d3dx_font *This = impl_from_ID3DXFont(iface); 120 121 TRACE("iface %p, desc %p\n", iface, desc); 122 123 if( !desc ) return D3DERR_INVALIDCALL; 124 *desc = This->desc; 125 126 return D3D_OK; 127 } 128 129 static BOOL WINAPI ID3DXFontImpl_GetTextMetricsA(ID3DXFont *iface, TEXTMETRICA *metrics) 130 { 131 struct d3dx_font *This = impl_from_ID3DXFont(iface); 132 TRACE("iface %p, metrics %p\n", iface, metrics); 133 return GetTextMetricsA(This->hdc, metrics); 134 } 135 136 static BOOL WINAPI ID3DXFontImpl_GetTextMetricsW(ID3DXFont *iface, TEXTMETRICW *metrics) 137 { 138 struct d3dx_font *This = impl_from_ID3DXFont(iface); 139 TRACE("iface %p, metrics %p\n", iface, metrics); 140 return GetTextMetricsW(This->hdc, metrics); 141 } 142 143 static HDC WINAPI ID3DXFontImpl_GetDC(ID3DXFont *iface) 144 { 145 struct d3dx_font *This = impl_from_ID3DXFont(iface); 146 TRACE("iface %p\n", iface); 147 return This->hdc; 148 } 149 150 static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph, 151 IDirect3DTexture9 **texture, RECT *blackbox, POINT *cellinc) 152 { 153 FIXME("iface %p, glyph %#x, texture %p, blackbox %p, cellinc %p stub!\n", 154 iface, glyph, texture, blackbox, cellinc); 155 return E_NOTIMPL; 156 } 157 158 static HRESULT WINAPI ID3DXFontImpl_PreloadCharacters(ID3DXFont *iface, UINT first, UINT last) 159 { 160 FIXME("iface %p, first %u, last %u stub!\n", iface, first, last); 161 return S_OK; 162 } 163 164 static HRESULT WINAPI ID3DXFontImpl_PreloadGlyphs(ID3DXFont *iface, UINT first, UINT last) 165 { 166 FIXME("iface %p, first %u, last %u stub!\n", iface, first, last); 167 return E_NOTIMPL; 168 } 169 170 static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, const char *string, INT count) 171 { 172 FIXME("iface %p, string %s, count %d stub!\n", iface, debugstr_a(string), count); 173 return E_NOTIMPL; 174 } 175 176 static HRESULT WINAPI ID3DXFontImpl_PreloadTextW(ID3DXFont *iface, const WCHAR *string, INT count) 177 { 178 FIXME("iface %p, string %s, count %d stub!\n", iface, debugstr_w(string), count); 179 return E_NOTIMPL; 180 } 181 182 static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, 183 const char *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) 184 { 185 FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x stub!\n", 186 iface, sprite, debugstr_a(string), count, wine_dbgstr_rect(rect), format, color); 187 return 1; 188 } 189 190 static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, 191 const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) 192 { 193 FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x stub!\n", 194 iface, sprite, debugstr_w(string), count, wine_dbgstr_rect(rect), format, color); 195 return 1; 196 } 197 198 static HRESULT WINAPI ID3DXFontImpl_OnLostDevice(ID3DXFont *iface) 199 { 200 FIXME("iface %p stub!\n", iface); 201 return D3D_OK; 202 } 203 204 static HRESULT WINAPI ID3DXFontImpl_OnResetDevice(ID3DXFont *iface) 205 { 206 FIXME("iface %p stub\n", iface); 207 return D3D_OK; 208 } 209 210 static const ID3DXFontVtbl D3DXFont_Vtbl = 211 { 212 /*** IUnknown methods ***/ 213 ID3DXFontImpl_QueryInterface, 214 ID3DXFontImpl_AddRef, 215 ID3DXFontImpl_Release, 216 /*** ID3DXFont methods ***/ 217 ID3DXFontImpl_GetDevice, 218 ID3DXFontImpl_GetDescA, 219 ID3DXFontImpl_GetDescW, 220 ID3DXFontImpl_GetTextMetricsA, 221 ID3DXFontImpl_GetTextMetricsW, 222 ID3DXFontImpl_GetDC, 223 ID3DXFontImpl_GetGlyphData, 224 ID3DXFontImpl_PreloadCharacters, 225 ID3DXFontImpl_PreloadGlyphs, 226 ID3DXFontImpl_PreloadTextA, 227 ID3DXFontImpl_PreloadTextW, 228 ID3DXFontImpl_DrawTextA, 229 ID3DXFontImpl_DrawTextW, 230 ID3DXFontImpl_OnLostDevice, 231 ID3DXFontImpl_OnResetDevice 232 }; 233 234 HRESULT WINAPI D3DXCreateFontA(struct IDirect3DDevice9 *device, INT height, UINT width, 235 UINT weight, UINT miplevels, BOOL italic, DWORD charset, DWORD precision, DWORD quality, 236 DWORD pitchandfamily, const char *facename, struct ID3DXFont **font) 237 { 238 D3DXFONT_DESCA desc; 239 240 if( !device || !font ) return D3DERR_INVALIDCALL; 241 242 desc.Height=height; 243 desc.Width=width; 244 desc.Weight=weight; 245 desc.MipLevels=miplevels; 246 desc.Italic=italic; 247 desc.CharSet=charset; 248 desc.OutputPrecision=precision; 249 desc.Quality=quality; 250 desc.PitchAndFamily=pitchandfamily; 251 if(facename != NULL) lstrcpyA(desc.FaceName, facename); 252 else desc.FaceName[0] = '\0'; 253 254 return D3DXCreateFontIndirectA(device, &desc, font); 255 } 256 257 HRESULT WINAPI D3DXCreateFontW(IDirect3DDevice9 *device, INT height, UINT width, UINT weight, UINT miplevels, BOOL italic, DWORD charset, 258 DWORD precision, DWORD quality, DWORD pitchandfamily, const WCHAR *facename, ID3DXFont **font) 259 { 260 D3DXFONT_DESCW desc; 261 262 if( !device || !font ) return D3DERR_INVALIDCALL; 263 264 desc.Height=height; 265 desc.Width=width; 266 desc.Weight=weight; 267 desc.MipLevels=miplevels; 268 desc.Italic=italic; 269 desc.CharSet=charset; 270 desc.OutputPrecision=precision; 271 desc.Quality=quality; 272 desc.PitchAndFamily=pitchandfamily; 273 if(facename != NULL) strcpyW(desc.FaceName, facename); 274 else desc.FaceName[0] = '\0'; 275 276 return D3DXCreateFontIndirectW(device, &desc, font); 277 } 278 279 /*********************************************************************** 280 * D3DXCreateFontIndirectA (D3DX9_36.@) 281 */ 282 HRESULT WINAPI D3DXCreateFontIndirectA(IDirect3DDevice9 *device, const D3DXFONT_DESCA *desc, ID3DXFont **font) 283 { 284 D3DXFONT_DESCW widedesc; 285 286 if( !device || !desc || !font ) return D3DERR_INVALIDCALL; 287 288 /* Copy everything but the last structure member. This requires the 289 two D3DXFONT_DESC structures to be equal until the FaceName member */ 290 memcpy(&widedesc, desc, FIELD_OFFSET(D3DXFONT_DESCA, FaceName)); 291 MultiByteToWideChar(CP_ACP, 0, desc->FaceName, -1, widedesc.FaceName, ARRAY_SIZE(widedesc.FaceName)); 292 return D3DXCreateFontIndirectW(device, &widedesc, font); 293 } 294 295 /*********************************************************************** 296 * D3DXCreateFontIndirectW (D3DX9_36.@) 297 */ 298 HRESULT WINAPI D3DXCreateFontIndirectW(IDirect3DDevice9 *device, const D3DXFONT_DESCW *desc, ID3DXFont **font) 299 { 300 D3DDEVICE_CREATION_PARAMETERS cpars; 301 D3DDISPLAYMODE mode; 302 struct d3dx_font *object; 303 IDirect3D9 *d3d; 304 HRESULT hr; 305 306 TRACE("(%p, %p, %p)\n", device, desc, font); 307 308 if( !device || !desc || !font ) return D3DERR_INVALIDCALL; 309 310 /* the device MUST support D3DFMT_A8R8G8B8 */ 311 IDirect3DDevice9_GetDirect3D(device, &d3d); 312 IDirect3DDevice9_GetCreationParameters(device, &cpars); 313 IDirect3DDevice9_GetDisplayMode(device, 0, &mode); 314 hr = IDirect3D9_CheckDeviceFormat(d3d, cpars.AdapterOrdinal, cpars.DeviceType, mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8); 315 if(FAILED(hr)) { 316 IDirect3D9_Release(d3d); 317 return D3DXERR_INVALIDDATA; 318 } 319 IDirect3D9_Release(d3d); 320 321 object = HeapAlloc(GetProcessHeap(), 0, sizeof(struct d3dx_font)); 322 if(object==NULL) { 323 *font=NULL; 324 return E_OUTOFMEMORY; 325 } 326 object->ID3DXFont_iface.lpVtbl = &D3DXFont_Vtbl; 327 object->ref=1; 328 object->device=device; 329 object->desc=*desc; 330 331 object->hdc = CreateCompatibleDC(NULL); 332 if( !object->hdc ) { 333 HeapFree(GetProcessHeap(), 0, object); 334 return D3DXERR_INVALIDDATA; 335 } 336 337 object->hfont = CreateFontW(desc->Height, desc->Width, 0, 0, desc->Weight, desc->Italic, FALSE, FALSE, desc->CharSet, 338 desc->OutputPrecision, CLIP_DEFAULT_PRECIS, desc->Quality, desc->PitchAndFamily, desc->FaceName); 339 if( !object->hfont ) { 340 DeleteDC(object->hdc); 341 HeapFree(GetProcessHeap(), 0, object); 342 return D3DXERR_INVALIDDATA; 343 } 344 SelectObject(object->hdc, object->hfont); 345 346 IDirect3DDevice9_AddRef(device); 347 *font=&object->ID3DXFont_iface; 348 349 return D3D_OK; 350 } 351