include: Remove the wine_ prefix on rbtree functions.
[wine.git] / dlls / d3dx10_43 / font.c
blob1a95dbeca02a26a6e0f96624bf7f07eb0a306b95
1 /*
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
20 #define COBJMACROS
21 #include "d3dx10.h"
23 #include "wine/debug.h"
24 #include "wine/heap.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
28 #define D3DERR_INVALIDCALL 0x8876086c
30 struct d3dx_font
32 ID3DX10Font ID3DX10Font_iface;
33 LONG refcount;
35 HDC hdc;
36 HFONT hfont;
37 D3DX10_FONT_DESCW desc;
38 ID3D10Device *device;
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);
54 *out = iface;
55 return S_OK;
58 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
60 *out = NULL;
61 return E_NOINTERFACE;
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);
70 return 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);
80 if (!refcount)
82 DeleteObject(font->hfont);
83 DeleteDC(font->hdc);
84 ID3D10Device_Release(font->device);
85 heap_free(font);
87 return refcount;
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);
100 return S_OK;
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);
109 if (!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);
116 return S_OK;
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);
125 if (!desc)
126 return D3DERR_INVALIDCALL;
128 *desc = font->desc;
130 return S_OK;
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);
157 return font->hdc;
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);
166 return E_NOTIMPL;
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;
173 WORD *indices;
174 WCHAR *chars;
176 TRACE("iface %p, first %u, last %u.\n", iface, first, last);
178 if (last < first)
179 return S_OK;
181 count = last - first + 1;
182 indices = heap_alloc(count * sizeof(*indices));
183 if (!indices)
184 return E_OUTOFMEMORY;
186 chars = heap_alloc(count * sizeof(*chars));
187 if (!chars)
189 heap_free(indices);
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)
203 end = indices[i];
204 continue;
206 ID3DX10Font_PreloadGlyphs(iface, start, end);
207 start = end = indices[i];
209 ID3DX10Font_PreloadGlyphs(iface, start, end);
211 heap_free(chars);
212 heap_free(indices);
214 return S_OK;
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);
221 return E_NOTIMPL;
224 static HRESULT WINAPI d3dx_font_PreloadTextA(ID3DX10Font *iface, const char *string, INT count)
226 WCHAR *wstr;
227 HRESULT hr;
228 int countW;
230 TRACE("iface %p, string %s, count %d.\n", iface, debugstr_an(string, count), count);
232 if (!string && !count)
233 return S_OK;
235 if (!string)
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);
247 heap_free(wstr);
249 return hr;
252 static HRESULT WINAPI d3dx_font_PreloadTextW(ID3DX10Font *iface, const WCHAR *string, INT count)
254 struct d3dx_font *font = impl_from_ID3DX10Font(iface);
255 WORD *indices;
256 int i;
258 TRACE("iface %p, string %s, count %d.\n", iface, debugstr_wn(string, count), count);
260 if (!string && !count)
261 return S_OK;
263 if (!string)
264 return D3DERR_INVALIDCALL;
266 if (count < 0)
267 count = lstrlenW(string);
269 indices = heap_alloc(count * sizeof(*indices));
270 if (!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]);
278 heap_free(indices);
280 return S_OK;
283 static INT WINAPI d3dx_font_DrawTextA(ID3DX10Font *iface, ID3DX10Sprite *sprite,
284 const char *string, INT count, RECT *rect, UINT format, D3DXCOLOR color)
286 int ret, countW;
287 WCHAR *wstr;
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)
294 return 0;
296 if (!(countW = MultiByteToWideChar(CP_ACP, 0, string, count < 0 ? -1 : count, NULL, 0)))
297 return 0;
299 if (!(wstr = heap_alloc_zero(countW * sizeof(*wstr))))
300 return 0;
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);
307 heap_free(wstr);
309 return ret;
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);
319 return E_NOTIMPL;
322 static const ID3DX10FontVtbl d3dx_font_vtbl =
324 /*** IUnknown methods ***/
325 d3dx_font_QueryInterface,
326 d3dx_font_AddRef,
327 d3dx_font_Release,
328 /*** ID3DX10Font methods ***/
329 d3dx_font_GetDevice,
330 d3dx_font_GetDescA,
331 d3dx_font_GetDescW,
332 d3dx_font_GetTextMetricsA,
333 d3dx_font_GetTextMetricsW,
334 d3dx_font_GetDC,
335 d3dx_font_GetGlyphData,
336 d3dx_font_PreloadCharacters,
337 d3dx_font_PreloadGlyphs,
338 d3dx_font_PreloadTextA,
339 d3dx_font_PreloadTextW,
340 d3dx_font_DrawTextA,
341 d3dx_font_DrawTextW,
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;
359 desc.Width = width;
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;
367 if (facename)
368 lstrcpyA(desc.FaceName, facename);
369 else
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;
390 desc.Width = width;
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;
398 if (facename)
399 lstrcpyW(desc.FaceName, facename);
400 else
401 desc.FaceName[0] = '\0';
403 return D3DX10CreateFontIndirectW(device, &desc, font);
406 HRESULT WINAPI D3DX10CreateFontIndirectA(ID3D10Device *device, const D3DX10_FONT_DESCA *desc,
407 ID3DX10Font **font)
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,
422 ID3DX10Font **font)
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;
431 *font = NULL;
433 if (!(object = heap_alloc_zero(sizeof(*object))))
434 return E_OUTOFMEMORY;
436 object->hdc = CreateCompatibleDC(NULL);
437 if (!object->hdc)
439 heap_free(object);
440 return E_FAIL;
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);
445 if (!object->hfont)
447 DeleteDC(object->hdc);
448 heap_free(object);
449 return E_FAIL;
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;
461 return S_OK;