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"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
27 #define D3DERR_INVALIDCALL 0x8876086c
31 ID3DX10Font ID3DX10Font_iface
;
36 D3DX10_FONT_DESCW desc
;
40 static inline struct d3dx_font
*impl_from_ID3DX10Font(ID3DX10Font
*iface
)
42 return CONTAINING_RECORD(iface
, struct d3dx_font
, ID3DX10Font_iface
);
45 static HRESULT WINAPI
d3dx_font_QueryInterface(ID3DX10Font
*iface
, REFIID riid
, void **out
)
47 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
49 if (IsEqualGUID(riid
, &IID_ID3DX10Font
)
50 || IsEqualGUID(riid
, &IID_IUnknown
))
52 IUnknown_AddRef(iface
);
57 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
63 static ULONG WINAPI
d3dx_font_AddRef(ID3DX10Font
*iface
)
65 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
66 ULONG refcount
= InterlockedIncrement(&font
->refcount
);
68 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
72 static ULONG WINAPI
d3dx_font_Release(ID3DX10Font
*iface
)
74 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
75 ULONG refcount
= InterlockedDecrement(&font
->refcount
);
77 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
81 DeleteObject(font
->hfont
);
83 ID3D10Device_Release(font
->device
);
89 static HRESULT WINAPI
d3dx_font_GetDevice(ID3DX10Font
*iface
, ID3D10Device
**device
)
91 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
93 TRACE("iface %p, device %p.\n", iface
, device
);
95 if (!device
) return D3DERR_INVALIDCALL
;
96 *device
= font
->device
;
97 ID3D10Device_AddRef(font
->device
);
102 static HRESULT WINAPI
d3dx_font_GetDescA(ID3DX10Font
*iface
, D3DX10_FONT_DESCA
*desc
)
104 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
106 TRACE("iface %p, desc %p.\n", iface
, desc
);
109 return D3DERR_INVALIDCALL
;
111 memcpy(desc
, &font
->desc
, FIELD_OFFSET(D3DX10_FONT_DESCA
, FaceName
));
112 WideCharToMultiByte(CP_ACP
, 0, font
->desc
.FaceName
, -1, desc
->FaceName
,
113 ARRAY_SIZE(desc
->FaceName
), NULL
, NULL
);
118 static HRESULT WINAPI
d3dx_font_GetDescW(ID3DX10Font
*iface
, D3DX10_FONT_DESCW
*desc
)
120 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
122 TRACE("iface %p, desc %p.\n", iface
, desc
);
125 return D3DERR_INVALIDCALL
;
132 static BOOL WINAPI
d3dx_font_GetTextMetricsA(ID3DX10Font
*iface
, TEXTMETRICA
*metrics
)
134 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
136 TRACE("iface %p, metrics %p.\n", iface
, metrics
);
138 return GetTextMetricsA(font
->hdc
, metrics
);
141 static BOOL WINAPI
d3dx_font_GetTextMetricsW(ID3DX10Font
*iface
, TEXTMETRICW
*metrics
)
143 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
145 TRACE("iface %p, metrics %p.\n", iface
, metrics
);
147 return GetTextMetricsW(font
->hdc
, metrics
);
150 static HDC WINAPI
d3dx_font_GetDC(ID3DX10Font
*iface
)
152 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
154 TRACE("iface %p.\n", iface
);
159 static HRESULT WINAPI
d3dx_font_GetGlyphData(ID3DX10Font
*iface
, UINT glyph
,
160 ID3D10ShaderResourceView
**view
, RECT
*black_box
, POINT
*cell_inc
)
162 FIXME("iface %p, glyph %u, view %p, black_box %p, cell_inc %p stub!\n",
163 iface
, glyph
, view
, black_box
, cell_inc
);
168 static HRESULT WINAPI
d3dx_font_PreloadCharacters(ID3DX10Font
*iface
, UINT first
, UINT last
)
170 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
171 unsigned int i
, count
, start
, end
;
175 TRACE("iface %p, first %u, last %u.\n", iface
, first
, last
);
180 count
= last
- first
+ 1;
181 indices
= malloc(count
* sizeof(*indices
));
183 return E_OUTOFMEMORY
;
185 chars
= malloc(count
* sizeof(*chars
));
189 return E_OUTOFMEMORY
;
192 for (i
= 0; i
< count
; ++i
)
193 chars
[i
] = first
+ i
;
195 GetGlyphIndicesW(font
->hdc
, chars
, count
, indices
, 0);
197 start
= end
= indices
[0];
198 for (i
= 1; i
< count
; ++i
)
200 if (indices
[i
] == end
+ 1)
205 ID3DX10Font_PreloadGlyphs(iface
, start
, end
);
206 start
= end
= indices
[i
];
208 ID3DX10Font_PreloadGlyphs(iface
, start
, end
);
216 static HRESULT WINAPI
d3dx_font_PreloadGlyphs(ID3DX10Font
*iface
, UINT first
, UINT last
)
218 FIXME("iface %p, first %u, last %u stub!\n", iface
, first
, last
);
223 static HRESULT WINAPI
d3dx_font_PreloadTextA(ID3DX10Font
*iface
, const char *string
, INT count
)
229 TRACE("iface %p, string %s, count %d.\n", iface
, debugstr_an(string
, count
), count
);
231 if (!string
&& !count
)
235 return D3DERR_INVALIDCALL
;
237 countW
= MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, NULL
, 0);
239 if (!(wstr
= malloc(countW
* sizeof(*wstr
))))
240 return E_OUTOFMEMORY
;
242 MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, wstr
, countW
);
244 hr
= ID3DX10Font_PreloadTextW(iface
, wstr
, count
< 0 ? countW
- 1 : countW
);
251 static HRESULT WINAPI
d3dx_font_PreloadTextW(ID3DX10Font
*iface
, const WCHAR
*string
, INT count
)
253 struct d3dx_font
*font
= impl_from_ID3DX10Font(iface
);
257 TRACE("iface %p, string %s, count %d.\n", iface
, debugstr_wn(string
, count
), count
);
259 if (!string
&& !count
)
263 return D3DERR_INVALIDCALL
;
266 count
= lstrlenW(string
);
268 indices
= malloc(count
* sizeof(*indices
));
270 return E_OUTOFMEMORY
;
272 GetGlyphIndicesW(font
->hdc
, string
, count
, indices
, 0);
274 for (i
= 0; i
< count
; ++i
)
275 ID3DX10Font_PreloadGlyphs(iface
, indices
[i
], indices
[i
]);
282 static INT WINAPI
d3dx_font_DrawTextA(ID3DX10Font
*iface
, ID3DX10Sprite
*sprite
,
283 const char *string
, INT count
, RECT
*rect
, UINT format
, D3DXCOLOR color
)
288 TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color {%.8e,%.8e,%.8e,%8e}.\n",
289 iface
, sprite
, debugstr_an(string
, count
), count
, wine_dbgstr_rect(rect
), format
,
290 color
.r
, color
.g
, color
.b
, color
.a
);
292 if (!string
|| !count
)
295 if (!(countW
= MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, NULL
, 0)))
298 if (!(wstr
= calloc(countW
, sizeof(*wstr
))))
301 MultiByteToWideChar(CP_ACP
, 0, string
, count
< 0 ? -1 : count
, wstr
, countW
);
303 ret
= ID3DX10Font_DrawTextW(iface
, sprite
, wstr
, count
< 0 ? countW
- 1 : countW
,
304 rect
, format
, color
);
311 static INT WINAPI
d3dx_font_DrawTextW(ID3DX10Font
*iface
, ID3DX10Sprite
*sprite
,
312 const WCHAR
*string
, INT count
, RECT
*rect
, UINT format
, D3DXCOLOR color
)
314 FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color {%.8e,%.8e,%.8e,%.8e} stub!\n",
315 iface
, sprite
, debugstr_wn(string
, count
), count
, wine_dbgstr_rect(rect
),
316 format
, color
.r
, color
.g
, color
.b
, color
.a
);
321 static const ID3DX10FontVtbl d3dx_font_vtbl
=
323 /*** IUnknown methods ***/
324 d3dx_font_QueryInterface
,
327 /*** ID3DX10Font methods ***/
331 d3dx_font_GetTextMetricsA
,
332 d3dx_font_GetTextMetricsW
,
334 d3dx_font_GetGlyphData
,
335 d3dx_font_PreloadCharacters
,
336 d3dx_font_PreloadGlyphs
,
337 d3dx_font_PreloadTextA
,
338 d3dx_font_PreloadTextW
,
343 HRESULT WINAPI
D3DX10CreateFontA(ID3D10Device
*device
, INT height
, UINT width
, UINT weight
,
344 UINT miplevels
, BOOL italic
, UINT charset
, UINT precision
, UINT quality
,
345 UINT pitchandfamily
, const char *facename
, ID3DX10Font
**font
)
347 D3DX10_FONT_DESCA desc
;
349 TRACE("device %p, height %d, width %u, weight %u, miplevels %u, italic %#x, charset %u, "
350 "precision %u, quality %u, pitchandfamily %u, facename %s, font %p.\n",
351 device
, height
, width
, weight
, miplevels
, italic
, charset
, precision
, quality
,
352 pitchandfamily
, debugstr_a(facename
), font
);
354 if (!device
|| !font
)
355 return D3DERR_INVALIDCALL
;
357 desc
.Height
= height
;
359 desc
.Weight
= weight
;
360 desc
.MipLevels
= miplevels
;
361 desc
.Italic
= italic
;
362 desc
.CharSet
= charset
;
363 desc
.OutputPrecision
= precision
;
364 desc
.Quality
= quality
;
365 desc
.PitchAndFamily
= pitchandfamily
;
367 lstrcpyA(desc
.FaceName
, facename
);
369 desc
.FaceName
[0] = 0;
371 return D3DX10CreateFontIndirectA(device
, &desc
, font
);
374 HRESULT WINAPI
D3DX10CreateFontW(ID3D10Device
*device
, INT height
, UINT width
, UINT weight
,
375 UINT miplevels
, BOOL italic
, UINT charset
, UINT precision
, UINT quality
,
376 UINT pitchandfamily
, const WCHAR
*facename
, ID3DX10Font
**font
)
378 D3DX10_FONT_DESCW desc
;
380 TRACE("device %p, height %d, width %u, weight %u, miplevels %u, italic %#x, charset %u, "
381 "precision %u, quality %u, pitchandfamily %u, facename %s, font %p.\n",
382 device
, height
, width
, weight
, miplevels
, italic
, charset
, precision
, quality
,
383 pitchandfamily
, debugstr_w(facename
), font
);
385 if (!device
|| !font
)
386 return D3DERR_INVALIDCALL
;
388 desc
.Height
= height
;
390 desc
.Weight
= weight
;
391 desc
.MipLevels
= miplevels
;
392 desc
.Italic
= italic
;
393 desc
.CharSet
= charset
;
394 desc
.OutputPrecision
= precision
;
395 desc
.Quality
= quality
;
396 desc
.PitchAndFamily
= pitchandfamily
;
398 lstrcpyW(desc
.FaceName
, facename
);
400 desc
.FaceName
[0] = '\0';
402 return D3DX10CreateFontIndirectW(device
, &desc
, font
);
405 HRESULT WINAPI
D3DX10CreateFontIndirectA(ID3D10Device
*device
, const D3DX10_FONT_DESCA
*desc
,
408 D3DX10_FONT_DESCW descW
;
410 TRACE("device %p, desc %p, font %p.\n", device
, desc
, font
);
412 if (!device
|| !desc
|| !font
)
413 return D3DERR_INVALIDCALL
;
415 memcpy(&descW
, desc
, FIELD_OFFSET(D3DX10_FONT_DESCA
, FaceName
));
416 MultiByteToWideChar(CP_ACP
, 0, desc
->FaceName
, -1, descW
.FaceName
, ARRAY_SIZE(descW
.FaceName
));
417 return D3DX10CreateFontIndirectW(device
, &descW
, font
);
420 HRESULT WINAPI
D3DX10CreateFontIndirectW(ID3D10Device
*device
, const D3DX10_FONT_DESCW
*desc
,
423 struct d3dx_font
*object
;
425 TRACE("device %p, desc %p, font %p.\n", device
, desc
, font
);
427 if (!device
|| !desc
|| !font
)
428 return D3DERR_INVALIDCALL
;
432 if (!(object
= calloc(1, sizeof(*object
))))
433 return E_OUTOFMEMORY
;
435 object
->hdc
= CreateCompatibleDC(NULL
);
442 object
->hfont
= CreateFontW(desc
->Height
, desc
->Width
, 0, 0, desc
->Weight
, desc
->Italic
, FALSE
, FALSE
, desc
->CharSet
,
443 desc
->OutputPrecision
, CLIP_DEFAULT_PRECIS
, desc
->Quality
, desc
->PitchAndFamily
, desc
->FaceName
);
446 DeleteDC(object
->hdc
);
450 SelectObject(object
->hdc
, object
->hfont
);
452 object
->ID3DX10Font_iface
.lpVtbl
= &d3dx_font_vtbl
;
453 object
->refcount
= 1;
454 object
->device
= device
;
455 object
->desc
= *desc
;
456 ID3D10Device_AddRef(device
);
458 *font
= &object
->ID3DX10Font_iface
;