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
23 #include "wine/debug.h"
24 #include "wine/heap.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
28 #define D3DERR_INVALIDCALL 0x8876086c
32 ID3DX10Font ID3DX10Font_iface
;
37 D3DX10_FONT_DESCW desc
;
41 static inline struct d3dx_font
*impl_from_ID3DX10Font(ID3DX10Font
*iface
)
43 return CONTAINING_RECORD(iface
, struct d3dx_font
, ID3DX10Font_iface
);
46 static HRESULT WINAPI
d3dx_font_QueryInterface(ID3DX10Font
*iface
, REFIID riid
, void **out
)
48 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
50 if (IsEqualGUID(riid
, &IID_ID3DX10Font
)
51 || IsEqualGUID(riid
, &IID_IUnknown
))
53 IUnknown_AddRef(iface
);
58 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
64 static ULONG WINAPI
d3dx_font_AddRef(ID3DX10Font
*iface
)
66 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
67 ULONG refcount
= InterlockedIncrement(&font
->refcount
);
69 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
73 static ULONG WINAPI
d3dx_font_Release(ID3DX10Font
*iface
)
75 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
76 ULONG refcount
= InterlockedDecrement(&font
->refcount
);
78 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
82 DeleteObject(font
->hfont
);
84 ID3D10Device_Release(font
->device
);
90 static HRESULT WINAPI
d3dx_font_GetDevice(ID3DX10Font
*iface
, ID3D10Device
**device
)
92 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
94 TRACE("iface %p, device %p.\n", iface
, device
);
96 if (!device
) return D3DERR_INVALIDCALL
;
97 *device
= font
->device
;
98 ID3D10Device_AddRef(font
->device
);
103 static HRESULT WINAPI
d3dx_font_GetDescA(ID3DX10Font
*iface
, D3DX10_FONT_DESCA
*desc
)
105 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
107 TRACE("iface %p, desc %p.\n", iface
, desc
);
110 return D3DERR_INVALIDCALL
;
112 memcpy(desc
, &font
->desc
, FIELD_OFFSET(D3DX10_FONT_DESCA
, FaceName
));
113 WideCharToMultiByte(CP_ACP
, 0, font
->desc
.FaceName
, -1, desc
->FaceName
,
114 ARRAY_SIZE(desc
->FaceName
), NULL
, NULL
);
119 static HRESULT WINAPI
d3dx_font_GetDescW(ID3DX10Font
*iface
, D3DX10_FONT_DESCW
*desc
)
121 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
123 TRACE("iface %p, desc %p.\n", iface
, desc
);
126 return D3DERR_INVALIDCALL
;
133 static BOOL WINAPI
d3dx_font_GetTextMetricsA(ID3DX10Font
*iface
, TEXTMETRICA
*metrics
)
135 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
137 TRACE("iface %p, metrics %p.\n", iface
, metrics
);
139 return GetTextMetricsA(font
->hdc
, metrics
);
142 static BOOL WINAPI
d3dx_font_GetTextMetricsW(ID3DX10Font
*iface
, TEXTMETRICW
*metrics
)
144 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
146 TRACE("iface %p, metrics %p.\n", iface
, metrics
);
148 return GetTextMetricsW(font
->hdc
, metrics
);
151 static HDC WINAPI
d3dx_font_GetDC(ID3DX10Font
*iface
)
153 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
155 TRACE("iface %p.\n", iface
);
160 static HRESULT WINAPI
d3dx_font_GetGlyphData(ID3DX10Font
*iface
, UINT glyph
,
161 ID3D10ShaderResourceView
**view
, RECT
*black_box
, POINT
*cell_inc
)
163 FIXME("iface %p, glyph %u, view %p, black_box %p, cell_inc %p stub!\n",
164 iface
, glyph
, view
, black_box
, cell_inc
);
169 static HRESULT WINAPI
d3dx_font_PreloadCharacters(ID3DX10Font
*iface
, UINT first
, UINT last
)
171 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
172 unsigned int i
, count
, start
, end
;
176 TRACE("iface %p, first %u, last %u.\n", iface
, first
, last
);
181 count
= last
- first
+ 1;
182 indices
= heap_alloc(count
* sizeof(*indices
));
184 return E_OUTOFMEMORY
;
186 chars
= heap_alloc(count
* sizeof(*chars
));
190 return E_OUTOFMEMORY
;
193 for (i
= 0; i
< count
; ++i
)
194 chars
[i
] = first
+ i
;
196 GetGlyphIndicesW(font
->hdc
, chars
, count
, indices
, 0);
198 start
= end
= indices
[0];
199 for (i
= 1; i
< count
; ++i
)
201 if (indices
[i
] == end
+ 1)
206 ID3DX10Font_PreloadGlyphs(iface
, start
, end
);
207 start
= end
= indices
[i
];
209 ID3DX10Font_PreloadGlyphs(iface
, start
, end
);
217 static HRESULT WINAPI
d3dx_font_PreloadGlyphs(ID3DX10Font
*iface
, UINT first
, UINT last
)
219 FIXME("iface %p, first %u, last %u stub!\n", iface
, first
, last
);
224 static HRESULT WINAPI
d3dx_font_PreloadTextA(ID3DX10Font
*iface
, const char *string
, INT count
)
230 TRACE("iface %p, string %s, count %d.\n", iface
, debugstr_an(string
, count
), count
);
232 if (!string
&& !count
)
236 return D3DERR_INVALIDCALL
;
238 countW
= MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, NULL
, 0);
240 if (!(wstr
= heap_alloc(countW
* sizeof(*wstr
))))
241 return E_OUTOFMEMORY
;
243 MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, wstr
, countW
);
245 hr
= ID3DX10Font_PreloadTextW(iface
, wstr
, count
< 0 ? countW
- 1 : countW
);
252 static HRESULT WINAPI
d3dx_font_PreloadTextW(ID3DX10Font
*iface
, const WCHAR
*string
, INT count
)
254 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
258 TRACE("iface %p, string %s, count %d.\n", iface
, debugstr_wn(string
, count
), count
);
260 if (!string
&& !count
)
264 return D3DERR_INVALIDCALL
;
267 count
= lstrlenW(string
);
269 indices
= heap_alloc(count
* sizeof(*indices
));
271 return E_OUTOFMEMORY
;
273 GetGlyphIndicesW(font
->hdc
, string
, count
, indices
, 0);
275 for (i
= 0; i
< count
; ++i
)
276 ID3DX10Font_PreloadGlyphs(iface
, indices
[i
], indices
[i
]);
283 static INT WINAPI
d3dx_font_DrawTextA(ID3DX10Font
*iface
, ID3DX10Sprite
*sprite
,
284 const char *string
, INT count
, RECT
*rect
, UINT format
, D3DXCOLOR color
)
289 TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color {%.8e,%.8e,%.8e,%8e}.\n",
290 iface
, sprite
, debugstr_an(string
, count
), count
, wine_dbgstr_rect(rect
), format
,
291 color
.r
, color
.g
, color
.b
, color
.a
);
293 if (!string
|| !count
)
296 if (!(countW
= MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, NULL
, 0)))
299 if (!(wstr
= heap_alloc_zero(countW
* sizeof(*wstr
))))
302 MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, wstr
, countW
);
304 ret
= ID3DX10Font_DrawTextW(iface
, sprite
, wstr
, count
< 0 ? countW
- 1 : countW
,
305 rect
, format
, color
);
312 static INT WINAPI
d3dx_font_DrawTextW(ID3DX10Font
*iface
, ID3DX10Sprite
*sprite
,
313 const WCHAR
*string
, INT count
, RECT
*rect
, DWORD format
, D3DXCOLOR color
)
315 FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color {%.8e,%.8e,%.8e,%.8e} stub!\n",
316 iface
, sprite
, debugstr_wn(string
, count
), count
, wine_dbgstr_rect(rect
),
317 format
, color
.r
, color
.g
, color
.b
, color
.a
);
322 static const ID3DX10FontVtbl d3dx_font_vtbl
=
324 /*** IUnknown methods ***/
325 d3dx_font_QueryInterface
,
328 /*** ID3DX10Font methods ***/
332 d3dx_font_GetTextMetricsA
,
333 d3dx_font_GetTextMetricsW
,
335 d3dx_font_GetGlyphData
,
336 d3dx_font_PreloadCharacters
,
337 d3dx_font_PreloadGlyphs
,
338 d3dx_font_PreloadTextA
,
339 d3dx_font_PreloadTextW
,
344 HRESULT WINAPI
D3DX10CreateFontA(ID3D10Device
*device
, INT height
, UINT width
, UINT weight
,
345 UINT miplevels
, BOOL italic
, UINT charset
, UINT precision
, UINT quality
,
346 UINT pitchandfamily
, const char *facename
, ID3DX10Font
**font
)
348 D3DX10_FONT_DESCA desc
;
350 TRACE("device %p, height %d, width %u, weight %u, miplevels %u, italic %#x, charset %u, "
351 "precision %u, quality %u, pitchandfamily %u, facename %s, font %p.\n",
352 device
, height
, width
, weight
, miplevels
, italic
, charset
, precision
, quality
,
353 pitchandfamily
, debugstr_a(facename
), font
);
355 if (!device
|| !font
)
356 return D3DERR_INVALIDCALL
;
358 desc
.Height
= height
;
360 desc
.Weight
= weight
;
361 desc
.MipLevels
= miplevels
;
362 desc
.Italic
= italic
;
363 desc
.CharSet
= charset
;
364 desc
.OutputPrecision
= precision
;
365 desc
.Quality
= quality
;
366 desc
.PitchAndFamily
= pitchandfamily
;
368 lstrcpyA(desc
.FaceName
, facename
);
370 desc
.FaceName
[0] = 0;
372 return D3DX10CreateFontIndirectA(device
, &desc
, font
);
375 HRESULT WINAPI
D3DX10CreateFontW(ID3D10Device
*device
, INT height
, UINT width
, UINT weight
,
376 UINT miplevels
, BOOL italic
, UINT charset
, UINT precision
, UINT quality
,
377 UINT pitchandfamily
, const WCHAR
*facename
, ID3DX10Font
**font
)
379 D3DX10_FONT_DESCW desc
;
381 TRACE("device %p, height %d, width %u, weight %u, miplevels %u, italic %#x, charset %u, "
382 "precision %u, quality %u, pitchandfamily %u, facename %s, font %p.\n",
383 device
, height
, width
, weight
, miplevels
, italic
, charset
, precision
, quality
,
384 pitchandfamily
, debugstr_w(facename
), font
);
386 if (!device
|| !font
)
387 return D3DERR_INVALIDCALL
;
389 desc
.Height
= height
;
391 desc
.Weight
= weight
;
392 desc
.MipLevels
= miplevels
;
393 desc
.Italic
= italic
;
394 desc
.CharSet
= charset
;
395 desc
.OutputPrecision
= precision
;
396 desc
.Quality
= quality
;
397 desc
.PitchAndFamily
= pitchandfamily
;
399 lstrcpyW(desc
.FaceName
, facename
);
401 desc
.FaceName
[0] = '\0';
403 return D3DX10CreateFontIndirectW(device
, &desc
, font
);
406 HRESULT WINAPI
D3DX10CreateFontIndirectA(ID3D10Device
*device
, const D3DX10_FONT_DESCA
*desc
,
409 D3DX10_FONT_DESCW descW
;
411 TRACE("device %p, desc %p, font %p.\n", device
, desc
, font
);
413 if (!device
|| !desc
|| !font
)
414 return D3DERR_INVALIDCALL
;
416 memcpy(&descW
, desc
, FIELD_OFFSET(D3DX10_FONT_DESCA
, FaceName
));
417 MultiByteToWideChar(CP_ACP
, 0, desc
->FaceName
, -1, descW
.FaceName
, ARRAY_SIZE(descW
.FaceName
));
418 return D3DX10CreateFontIndirectW(device
, &descW
, font
);
421 HRESULT WINAPI
D3DX10CreateFontIndirectW(ID3D10Device
*device
, const D3DX10_FONT_DESCW
*desc
,
424 struct d3dx_font
*object
;
426 TRACE("device %p, desc %p, font %p.\n", device
, desc
, font
);
428 if (!device
|| !desc
|| !font
)
429 return D3DERR_INVALIDCALL
;
433 if (!(object
= heap_alloc_zero(sizeof(*object
))))
434 return E_OUTOFMEMORY
;
436 object
->hdc
= CreateCompatibleDC(NULL
);
443 object
->hfont
= CreateFontW(desc
->Height
, desc
->Width
, 0, 0, desc
->Weight
, desc
->Italic
, FALSE
, FALSE
, desc
->CharSet
,
444 desc
->OutputPrecision
, CLIP_DEFAULT_PRECIS
, desc
->Quality
, desc
->PitchAndFamily
, desc
->FaceName
);
447 DeleteDC(object
->hdc
);
451 SelectObject(object
->hdc
, object
->hfont
);
453 object
->ID3DX10Font_iface
.lpVtbl
= &d3dx_font_vtbl
;
454 object
->refcount
= 1;
455 object
->device
= device
;
456 object
->desc
= *desc
;
457 ID3D10Device_AddRef(device
);
459 *font
= &object
->ID3DX10Font_iface
;