ReactOS 0.4.15-dev-7942-gd23573b
font.c
Go to the documentation of this file.
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
24#include "d3dx9_private.h"
25
26#include "usp10.h"
27#endif /* __REACTOS__ */
28
30
32{
33 unsigned int id;
36 IDirect3DTexture9 *texture;
37
39};
40
42{
45
46 IDirect3DDevice9 *device;
49
52
54
55 IDirect3DTexture9 **textures;
57
59};
60
61static int glyph_rb_compare(const void *key, const struct wine_rb_entry *entry)
62{
63 struct d3dx_glyph *glyph = WINE_RB_ENTRY_VALUE(entry, struct d3dx_glyph, entry);
64 unsigned int id = (UINT_PTR)key;
65
66 return id - glyph->id;
67}
68
69static void glyph_rb_free(struct wine_rb_entry *entry, void *context)
70{
71 struct d3dx_glyph *glyph = WINE_RB_ENTRY_VALUE(entry, struct d3dx_glyph, entry);
72
73 heap_free(glyph);
74}
75
76static inline struct d3dx_font *impl_from_ID3DXFont(ID3DXFont *iface)
77{
78 return CONTAINING_RECORD(iface, struct d3dx_font, ID3DXFont_iface);
79}
80
82{
83 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
84
85 if (IsEqualGUID(riid, &IID_ID3DXFont)
87 {
88 IUnknown_AddRef(iface);
89 *out = iface;
90 return S_OK;
91 }
92
93 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
94
95 *out = NULL;
96 return E_NOINTERFACE;
97}
98
100{
101 struct d3dx_font *font = impl_from_ID3DXFont(iface);
103
104 TRACE("%p increasing refcount to %u\n", iface, ref);
105 return ref;
106}
107
109{
110 struct d3dx_font *font = impl_from_ID3DXFont(iface);
112 unsigned int i;
113
114 TRACE("%p decreasing refcount to %u\n", iface, ref);
115
116 if (!ref)
117 {
118 for (i = 0; i < font->texture_count; ++i)
119 IDirect3DTexture9_Release(font->textures[i]);
120
121 heap_free(font->textures);
122
123 wine_rb_destroy(&font->glyph_tree, glyph_rb_free, NULL);
124
125 DeleteObject(font->hfont);
126 DeleteDC(font->hdc);
129 }
130 return ref;
131}
132
133static HRESULT WINAPI ID3DXFontImpl_GetDevice(ID3DXFont *iface, IDirect3DDevice9 **device)
134{
135 struct d3dx_font *font = impl_from_ID3DXFont(iface);
136
137 TRACE("iface %p, device %p\n", iface, device);
138
139 if( !device ) return D3DERR_INVALIDCALL;
140 *device = font->device;
142
143 return D3D_OK;
144}
145
147{
148 struct d3dx_font *font = impl_from_ID3DXFont(iface);
149
150 TRACE("iface %p, desc %p\n", iface, desc);
151
152 if( !desc ) return D3DERR_INVALIDCALL;
153 memcpy(desc, &font->desc, FIELD_OFFSET(D3DXFONT_DESCA, FaceName));
154 WideCharToMultiByte(CP_ACP, 0, font->desc.FaceName, -1, desc->FaceName, ARRAY_SIZE(desc->FaceName), NULL, NULL);
155
156 return D3D_OK;
157}
158
160{
161 struct d3dx_font *font = impl_from_ID3DXFont(iface);
162
163 TRACE("iface %p, desc %p\n", iface, desc);
164
165 if( !desc ) return D3DERR_INVALIDCALL;
166 *desc = font->desc;
167
168 return D3D_OK;
169}
170
172{
173 struct d3dx_font *font = impl_from_ID3DXFont(iface);
174 TRACE("iface %p, metrics %p\n", iface, metrics);
175 return GetTextMetricsA(font->hdc, metrics);
176}
177
179{
180 struct d3dx_font *font = impl_from_ID3DXFont(iface);
181 TRACE("iface %p, metrics %p\n", iface, metrics);
182 return GetTextMetricsW(font->hdc, metrics);
183}
184
186{
187 struct d3dx_font *font = impl_from_ID3DXFont(iface);
188 TRACE("iface %p\n", iface);
189 return font->hdc;
190}
191
193 IDirect3DTexture9 **texture, RECT *black_box, POINT *cell_inc)
194{
195 struct d3dx_font *font = impl_from_ID3DXFont(iface);
196 struct wine_rb_entry *entry;
197 HRESULT hr;
198
199 TRACE("iface %p, glyph %#x, texture %p, black_box %p, cell_inc %p.\n",
200 iface, glyph, texture, black_box, cell_inc);
201
202 hr = ID3DXFont_PreloadGlyphs(iface, glyph, glyph);
203 if (FAILED(hr))
204 return hr;
205
206 entry = wine_rb_get(&font->glyph_tree, ULongToPtr(glyph));
207 if (entry)
208 {
209 struct d3dx_glyph *current_glyph = WINE_RB_ENTRY_VALUE(entry, struct d3dx_glyph, entry);
210
211 if (cell_inc)
212 *cell_inc = current_glyph->cell_inc;
213 if (black_box)
214 *black_box = current_glyph->black_box;
215 if (texture)
216 {
217 *texture = current_glyph->texture;
218 if (*texture)
219 IDirect3DTexture9_AddRef(current_glyph->texture);
220 }
221 return D3D_OK;
222 }
223
224 return D3DXERR_INVALIDDATA;
225}
226
228{
229 struct d3dx_font *font = impl_from_ID3DXFont(iface);
230 unsigned int i, count, start, end;
231 WORD *indices;
232 WCHAR *chars;
233
234 TRACE("iface %p, first %u, last %u.\n", iface, first, last);
235
236 if (last < first)
237 return D3D_OK;
238
239 count = last - first + 1;
240 indices = heap_alloc(count * sizeof(*indices));
241 if (!indices)
242 return E_OUTOFMEMORY;
243
244 chars = heap_alloc(count * sizeof(*chars));
245 if (!chars)
246 {
248 return E_OUTOFMEMORY;
249 }
250
251 for (i = 0; i < count; ++i)
252 chars[i] = first + i;
253
254 GetGlyphIndicesW(font->hdc, chars, count, indices, 0);
255
256 start = end = indices[0];
257 for (i = 1; i < count; ++i)
258 {
259 if (indices[i] == end + 1)
260 {
261 end = indices[i];
262 continue;
263 }
265 start = end = indices[i];
266 }
268
269 heap_free(chars);
271
272 return D3D_OK;
273}
274
276{
277 x &= 0x55555555;
278 x = (x ^ (x >> 1)) & 0x33333333;
279 x = (x ^ (x >> 2)) & 0x0f0f0f0f;
280 x = (x ^ (x >> 4)) & 0x00ff00ff;
281 x = (x ^ (x >> 8)) & 0x0000ffff;
282 return x;
283}
284
285/* The glyphs are stored in a grid. Cell sizes vary between different font
286 * sizes.
287 *
288 * The grid is filled in Morton order:
289 * 1 2 5 6 17 18 21 22
290 * 3 4 7 8 19 20 23 24
291 * 9 10 13 14 25 26 29 30
292 * 11 12 15 16 27 28 31 32
293 * 33 34 ...
294 * ...
295 *
296 * i.e. we try to fill one small square, then three equal-sized squares so
297 * that we get one big square, etc.
298 *
299 * The glyphs are positioned around their baseline, which is located at y
300 * position glyph_size * i + tmAscent. Concerning the x position, the glyphs
301 * are centered around glyph_size * (i + 0.5). */
303{
304 static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
305 struct d3dx_font *font = impl_from_ID3DXFont(iface);
306 IDirect3DTexture9 *current_texture = NULL;
307 unsigned int size, stride, glyph, x, y;
308 struct d3dx_glyph *current_glyph;
309 D3DLOCKED_RECT lockrect;
311 BOOL mapped = FALSE;
312 DWORD *pixel_data;
313 BYTE *buffer;
314 HRESULT hr;
315
316 TRACE("iface %p, first %u, last %u.\n", iface, first, last);
317
318 if (last < first)
319 return D3D_OK;
320
321 if (font->texture_count)
322 current_texture = font->textures[font->texture_count - 1];
323
324 for (glyph = first; glyph <= last; ++glyph)
325 {
326 if (wine_rb_get(&font->glyph_tree, ULongToPtr(glyph)))
327 continue;
328
329 current_glyph = heap_alloc(sizeof(*current_glyph));
330 if (!current_glyph)
331 {
332 if (mapped)
333 IDirect3DTexture9_UnlockRect(current_texture, 0);
334 return E_OUTOFMEMORY;
335 }
336
337 current_glyph->id = glyph;
338 current_glyph->texture = NULL;
339 wine_rb_put(&font->glyph_tree, ULongToPtr(current_glyph->id), &current_glyph->entry);
340
342 if (size == GDI_ERROR)
343 {
344 WARN("GetGlyphOutlineW failed.\n");
345 continue;
346 }
347 if (!size)
348 continue;
349
351 if (!buffer)
352 {
353 if (mapped)
354 IDirect3DTexture9_UnlockRect(current_texture, 0);
355 return E_OUTOFMEMORY;
356 }
357
359
360 if (font->texture_pos == font->glyphs_per_texture)
361 {
362 unsigned int new_texture_count = font->texture_count + 1;
363 IDirect3DTexture9 **new_textures;
364
365 if (mapped)
366 IDirect3DTexture9_UnlockRect(current_texture, 0);
367 mapped = FALSE;
368 new_textures = heap_realloc(font->textures, new_texture_count * sizeof(*new_textures));
369 if (!new_textures)
370 {
372 return E_OUTOFMEMORY;
373 }
374 font->textures = new_textures;
375
376 if (FAILED(hr = IDirect3DDevice9_CreateTexture(font->device, font->texture_size,
377 font->texture_size, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
378 &font->textures[font->texture_count], NULL)))
379 {
381 return hr;
382 }
383
384 current_texture = font->textures[font->texture_count++];
385 font->texture_pos = 0;
386 }
387
388 if (!mapped)
389 {
390 if (FAILED(hr = IDirect3DTexture9_LockRect(current_texture, 0, &lockrect, NULL, 0)))
391 {
393 return hr;
394 }
395 mapped = TRUE;
396 }
397
398 x = morton_decode(font->texture_pos) * font->glyph_size;
399 y = morton_decode(font->texture_pos >> 1) * font->glyph_size;
400
401 current_glyph->black_box.left = x - metrics.gmptGlyphOrigin.x + font->glyph_size / 2
402 - metrics.gmBlackBoxX / 2;
403 current_glyph->black_box.top = y - metrics.gmptGlyphOrigin.y + font->metrics.tmAscent + 1;
404 current_glyph->black_box.right = current_glyph->black_box.left + metrics.gmBlackBoxX;
405 current_glyph->black_box.bottom = current_glyph->black_box.top + metrics.gmBlackBoxY;
406 current_glyph->cell_inc.x = metrics.gmptGlyphOrigin.x - 1;
407 current_glyph->cell_inc.y = font->metrics.tmAscent - metrics.gmptGlyphOrigin.y - 1;
408 current_glyph->texture = current_texture;
409
410 pixel_data = lockrect.pBits;
411 stride = (metrics.gmBlackBoxX + 3) & ~3;
412 for (y = 0; y < metrics.gmBlackBoxY; ++y)
413 for (x = 0; x < metrics.gmBlackBoxX; ++x)
414 pixel_data[(current_glyph->black_box.top + y) * lockrect.Pitch / 4
415 + current_glyph->black_box.left + x] =
416 (buffer[y * stride + x] * 255 / 64 << 24) | 0x00ffffffu;
417
419 ++font->texture_pos;
420 }
421 if (mapped)
422 IDirect3DTexture9_UnlockRect(current_texture, 0);
423
424 return D3D_OK;
425}
426
427static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, const char *string, INT count)
428{
429 WCHAR *wstr;
430 HRESULT hr;
431 int countW;
432
433 TRACE("iface %p, string %s, count %d.\n", iface, debugstr_an(string, count), count);
434
435 if (!string && !count)
436 return D3D_OK;
437
438 if (!string)
439 return D3DERR_INVALIDCALL;
440
441 countW = MultiByteToWideChar(CP_ACP, 0, string, count < 0 ? -1 : count, NULL, 0);
442
443 wstr = heap_alloc(countW * sizeof(*wstr));
444 if (!wstr)
445 return E_OUTOFMEMORY;
446
447 MultiByteToWideChar(CP_ACP, 0, string, count < 0 ? -1 : count, wstr, countW);
448
449 hr = ID3DXFont_PreloadTextW(iface, wstr, count < 0 ? countW - 1 : countW);
450
451 heap_free(wstr);
452
453 return hr;
454}
455
457{
458 struct d3dx_font *font = impl_from_ID3DXFont(iface);
459 WORD *indices;
460 int i;
461
462 TRACE("iface %p, string %s, count %d.\n", iface, debugstr_wn(string, count), count);
463
464 if (!string && !count)
465 return D3D_OK;
466
467 if (!string)
468 return D3DERR_INVALIDCALL;
469
470 if (count < 0)
471 count = lstrlenW(string);
472
473 indices = heap_alloc(count * sizeof(*indices));
474 if (!indices)
475 return E_OUTOFMEMORY;
476
477 GetGlyphIndicesW(font->hdc, string, count, indices, 0);
478
479 for (i = 0; i < count; ++i)
481
483
484 return D3D_OK;
485}
486
488 const char *string, INT count, RECT *rect, DWORD format, D3DCOLOR color)
489{
490 int ret, countW;
491 WCHAR *wstr;
492
493 TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x.\n",
495
496 if (!string || !count)
497 return 0;
498
499 countW = MultiByteToWideChar(CP_ACP, 0, string, count < 0 ? -1 : count, NULL, 0);
500
501 if (!countW)
502 return 0;
503
504 wstr = heap_alloc_zero(countW * sizeof(*wstr));
505 if (!wstr)
506 return 0;
507
508 MultiByteToWideChar(CP_ACP, 0, string, count < 0 ? -1 : count, wstr, countW);
509
510 ret = ID3DXFont_DrawTextW(iface, sprite, wstr, count < 0 ? countW - 1 : countW,
511 rect, format, color);
512
513 heap_free(wstr);
514
515 return ret;
516}
517
518static void word_break(HDC hdc, const WCHAR *str, unsigned int *str_len,
519 unsigned int chars_fit, unsigned int *chars_used, SIZE *size)
520{
521 SCRIPT_LOGATTR *sla;
523 unsigned int i;
524
525 *chars_used = 0;
526
527 sla = heap_alloc(*str_len * sizeof(*sla));
528 if (!sla)
529 return;
530
531 memset(&sa, 0, sizeof(sa));
532 sa.eScript = SCRIPT_UNDEFINED;
533
534 ScriptBreak(str, *str_len, &sa, sla);
535
536 /* Work back from the last character that did fit to a place where we can break */
537 i = chars_fit;
538 while (i > 0 && !sla[i].fSoftBreak) /* chars_fit < *str_len so this is valid */
539 --i;
540
541 /* If the there is no word that fits put in all characters that do fit */
542 if (!sla[i].fSoftBreak)
543 i = chars_fit;
544
545 *chars_used = i;
546 if (sla[i].fWhiteSpace)
547 ++(*chars_used);
548
549 /* Remove extra spaces */
550 while (i > 0 && sla[i-1].fWhiteSpace)
551 --i;
552 *str_len = i;
553
554 /* Remeasure the string */
556 heap_free(sla);
557}
558
559static const WCHAR *read_line(HDC hdc, const WCHAR *str, unsigned int *count,
560 WCHAR *dest, unsigned int *dest_len, int width, DWORD format, SIZE *size)
561{
562 unsigned int orig_count = *count;
563 unsigned int i = 0;
564 int num_fit;
565
566 *dest_len = 0;
567 while (*count && (str[i] != '\n' || (format & DT_SINGLELINE)))
568 {
569 --(*count);
570 if (str[i] != '\r' && str[i] != '\n')
571 dest[(*dest_len)++] = str[i];
572 ++i;
573 }
574
575 num_fit = 0;
576 GetTextExtentExPointW(hdc, dest, *dest_len, width, &num_fit, NULL, size);
577
578 if (num_fit < *dest_len && (format & DT_WORDBREAK))
579 {
580 unsigned int chars_used;
581
582 word_break(hdc, dest, dest_len, num_fit, &chars_used, size);
583 *count = orig_count - chars_used;
584 i = chars_used;
585 }
586
587 if (*count && str[i] == '\n')
588 {
589 --(*count);
590 ++i;
591 }
592
593 if (*count)
594 return str + i;
595 return NULL;
596}
597
598static int compute_rect(struct d3dx_font *font, const WCHAR *string, unsigned int count,
600{
601 int y, lh, width, top = rect->top;
602 int max_width = 0;
603 SIZE size;
604
605 y = rect->top;
606 lh = font->metrics.tmHeight;
607 width = rect->right - rect->left;
608
609 while (string)
610 {
611 unsigned int line_len;
612
613 string = read_line(font->hdc, string, &count, line, &line_len, width, format, &size);
614
615 if (size.cx > max_width)
616 max_width = size.cx;
617
618 y += lh;
619 if (!(format & DT_NOCLIP) && (y > rect->bottom))
620 break;
621 }
622
623 if (format & DT_CENTER)
624 {
625 rect->left += (rect->right - rect->left - max_width) / 2;
626 rect->right = rect->left + max_width;
627 }
628 else if (format & DT_RIGHT)
629 {
630 rect->left = rect->right - max_width;
631 }
632 else
633 {
634 rect->right = rect->left + max_width;
635 }
636
637 if (format & DT_VCENTER)
638 {
639 rect->top += (rect->bottom - y) / 2;
640 rect->bottom = rect->top + y - top;
641 }
642 else if (format & DT_BOTTOM)
643 {
644 rect->top += rect->bottom - y;
645 }
646 else
647 {
648 rect->bottom = y;
649 }
650
651 return rect->bottom - top;
652}
653
655 const WCHAR *string, INT in_count, RECT *rect, DWORD format, D3DCOLOR color)
656{
657 struct d3dx_font *font = impl_from_ID3DXFont(iface);
658 int lh, x, y, width, top, ret = 0;
659 ID3DXSprite *target = sprite;
660 unsigned int count;
661 RECT r = {0};
662 WCHAR *line;
663 SIZE size;
664
665 TRACE("iface %p, sprite %p, string %s, in_count %d, rect %s, format %#x, color 0x%08x.\n",
666 iface, sprite, debugstr_wn(string, in_count), in_count, wine_dbgstr_rect(rect), format, color);
667
668 if (!string)
669 return 0;
670
671 count = in_count < 0 ? lstrlenW(string) : in_count;
672
673 if (!count)
674 return 0;
675
676 if (format & DT_CALCRECT)
677 format |= DT_NOCLIP;
678
679 if (format & DT_SINGLELINE)
680 format &= ~DT_WORDBREAK;
681
682 line = heap_alloc(count * sizeof(*line));
683 if (!line)
684 return 0;
685
687 {
688 if (!rect)
689 {
690 rect = &r;
691 format |= DT_NOCLIP;
692 }
693 else if (!(format & DT_CALCRECT))
694 {
695 r = *rect;
696 rect = &r;
697 }
698
699 top = rect->top;
700
701 ret = compute_rect(font, string, count, line, rect, format);
702
703 if (format & DT_CALCRECT)
704 goto cleanup;
705 }
706 else
707 {
708 top = rect->top;
709 }
710
711 y = rect->top;
712 lh = font->metrics.tmHeight;
713 width = rect->right - rect->left;
714
715 if (!sprite)
716 {
717 D3DXCreateSprite(font->device, &target);
719 }
720
721 while (string)
722 {
723 unsigned int line_len, i;
725
726 string = read_line(font->hdc, string, &count, line, &line_len, width, format, &size);
727
728 if (format & DT_CENTER)
729 x = (rect->left + rect->right - size.cx) / 2;
730 else if (format & DT_RIGHT)
731 x = rect->right - size.cx;
732 else
733 x = rect->left;
734
735 memset(&results, 0, sizeof(results));
736 results.nGlyphs = line_len;
737
738 results.lpCaretPos = heap_alloc(line_len * sizeof(*results.lpCaretPos));
739 if (!results.lpCaretPos)
740 goto cleanup;
741
742 results.lpGlyphs = heap_alloc(line_len * sizeof(*results.lpGlyphs));
743 if (!results.lpGlyphs)
744 {
745 heap_free(results.lpCaretPos);
746 goto cleanup;
747 }
748
749 GetCharacterPlacementW(font->hdc, line, line_len, 0, &results, 0);
750
751 for (i = 0; i < results.nGlyphs; ++i)
752 {
753 IDirect3DTexture9 *texture;
755 POINT cell_inc;
756 RECT black_box;
757
758 ID3DXFont_GetGlyphData(iface, results.lpGlyphs[i], &texture, &black_box, &cell_inc);
759
760 if (!texture)
761 continue;
762
763 pos.x = cell_inc.x + x + results.lpCaretPos[i];
764 pos.y = cell_inc.y + y;
765 pos.z = 0;
766
767 if (!(format & DT_NOCLIP))
768 {
769 if (pos.x > rect->right)
770 {
772 continue;
773 }
774
775 if (pos.x + black_box.right - black_box.left > rect->right)
776 black_box.right = black_box.left + rect->right - pos.x;
777
778 if (pos.y + black_box.bottom - black_box.top > rect->bottom)
779 black_box.bottom = black_box.top + rect->bottom - pos.y;
780 }
781
782 ID3DXSprite_Draw(target, texture, &black_box, NULL, &pos, color);
784 }
785
786 heap_free(results.lpCaretPos);
787 heap_free(results.lpGlyphs);
788
789 y += lh;
790 if (!(DT_NOCLIP & format) && (y > rect->bottom))
791 break;
792 }
793
794 ret = y - top;
795
796cleanup:
797 if (target != sprite)
798 {
801 }
802
804
805 return ret;
806}
807
809{
810 FIXME("iface %p stub!\n", iface);
811 return D3D_OK;
812}
813
815{
816 FIXME("iface %p stub\n", iface);
817 return D3D_OK;
818}
819
820static const ID3DXFontVtbl D3DXFont_Vtbl =
821{
822 /*** IUnknown methods ***/
826 /*** ID3DXFont methods ***/
842};
843
846 DWORD pitchandfamily, const char *facename, struct ID3DXFont **font)
847{
849
850 if( !device || !font ) return D3DERR_INVALIDCALL;
851
852 desc.Height=height;
853 desc.Width=width;
854 desc.Weight=weight;
855 desc.MipLevels=miplevels;
856 desc.Italic=italic;
857 desc.CharSet=charset;
858 desc.OutputPrecision=precision;
859 desc.Quality=quality;
860 desc.PitchAndFamily=pitchandfamily;
861 if(facename != NULL) lstrcpyA(desc.FaceName, facename);
862 else desc.FaceName[0] = '\0';
863
865}
866
868 DWORD precision, DWORD quality, DWORD pitchandfamily, const WCHAR *facename, ID3DXFont **font)
869{
871
872 if( !device || !font ) return D3DERR_INVALIDCALL;
873
874 desc.Height=height;
875 desc.Width=width;
876 desc.Weight=weight;
877 desc.MipLevels=miplevels;
878 desc.Italic=italic;
879 desc.CharSet=charset;
880 desc.OutputPrecision=precision;
881 desc.Quality=quality;
882 desc.PitchAndFamily=pitchandfamily;
883 if(facename != NULL) lstrcpyW(desc.FaceName, facename);
884 else desc.FaceName[0] = '\0';
885
887}
888
889/***********************************************************************
890 * D3DXCreateFontIndirectA (D3DX9_36.@)
891 */
893{
894 D3DXFONT_DESCW widedesc;
895
896 if( !device || !desc || !font ) return D3DERR_INVALIDCALL;
897
898 /* Copy everything but the last structure member. This requires the
899 two D3DXFONT_DESC structures to be equal until the FaceName member */
900 memcpy(&widedesc, desc, FIELD_OFFSET(D3DXFONT_DESCA, FaceName));
901 MultiByteToWideChar(CP_ACP, 0, desc->FaceName, -1, widedesc.FaceName, ARRAY_SIZE(widedesc.FaceName));
902 return D3DXCreateFontIndirectW(device, &widedesc, font);
903}
904
905/***********************************************************************
906 * D3DXCreateFontIndirectW (D3DX9_36.@)
907 */
909{
911 struct d3dx_font *object;
913 IDirect3D9 *d3d;
914 HRESULT hr;
915
916 TRACE("(%p, %p, %p)\n", device, desc, font);
917
918 if( !device || !desc || !font ) return D3DERR_INVALIDCALL;
919
920 /* the device MUST support D3DFMT_A8R8G8B8 */
925 if (FAILED(hr))
926 {
928 return D3DXERR_INVALIDDATA;
929 }
931
932 object = heap_alloc_zero(sizeof(*object));
933 if (!object)
934 {
935 *font = NULL;
936 return E_OUTOFMEMORY;
937 }
938 object->ID3DXFont_iface.lpVtbl = &D3DXFont_Vtbl;
939 object->ref = 1;
940 object->device = device;
941 object->desc = *desc;
942
943 object->hdc = CreateCompatibleDC(NULL);
944 if (!object->hdc)
945 {
946 heap_free(object);
947 return D3DXERR_INVALIDDATA;
948 }
949
950 object->hfont = CreateFontW(desc->Height, desc->Width, 0, 0, desc->Weight, desc->Italic, FALSE, FALSE, desc->CharSet,
951 desc->OutputPrecision, CLIP_DEFAULT_PRECIS, desc->Quality, desc->PitchAndFamily, desc->FaceName);
952 if (!object->hfont)
953 {
954 DeleteDC(object->hdc);
955 heap_free(object);
956 return D3DXERR_INVALIDDATA;
957 }
958 SelectObject(object->hdc, object->hfont);
959
960 wine_rb_init(&object->glyph_tree, glyph_rb_compare);
961
962 if (!GetTextMetricsW(object->hdc, &object->metrics))
963 {
964 DeleteObject(object->hfont);
965 DeleteDC(object->hdc);
966 heap_free(object);
967 return D3DXERR_INVALIDDATA;
968 }
969
970 object->glyph_size = make_pow2(object->metrics.tmHeight);
971
972 object->texture_size = object->glyph_size;
973 if (object->glyph_size < 256)
974 object->texture_size = min(256, object->texture_size * 16);
975
976 object->glyphs_per_texture = object->texture_size * object->texture_size
977 / (object->glyph_size * object->glyph_size);
978 object->texture_pos = object->glyphs_per_texture;
979
981 *font = &object->ID3DXFont_iface;
982
983 return D3D_OK;
984}
static struct _test_info results[8]
Definition: SetCursorPos.c:31
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
#define ULongToPtr(ul)
Definition: basetsd.h:92
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
CFF_Charset charset
Definition: cffcmap.c:138
#define D3DXERR_INVALIDDATA
Definition: compiler.c:30
@ D3DFMT_A8R8G8B8
Definition: d3d8types.h:604
@ D3DRTYPE_TEXTURE
Definition: d3d8types.h:812
@ D3DPOOL_MANAGED
Definition: d3d8types.h:710
#define IDirect3DTexture9_AddRef(p)
Definition: d3d9.h:1013
#define IDirect3DDevice9_GetDirect3D(p, a)
Definition: d3d9.h:1513
#define IDirect3DTexture9_UnlockRect(p, a)
Definition: d3d9.h:1035
#define IDirect3DDevice9_CreateTexture(p, a, b, c, d, e, f, g, h)
Definition: d3d9.h:1530
#define IDirect3DDevice9_GetCreationParameters(p, a)
Definition: d3d9.h:1516
#define IDirect3D9_Release(p)
Definition: d3d9.h:220
#define IDirect3DDevice9_Release(p)
Definition: d3d9.h:1508
#define IDirect3DTexture9_LockRect(p, a, b, c, d)
Definition: d3d9.h:1034
#define IDirect3D9_CheckDeviceFormat(p, a, b, c, d, e, f)
Definition: d3d9.h:229
#define IDirect3DTexture9_Release(p)
Definition: d3d9.h:1014
#define IDirect3DDevice9_AddRef(p)
Definition: d3d9.h:1507
#define IDirect3DDevice9_GetDisplayMode(p, a, b)
Definition: d3d9.h:1515
#define D3D_OK
Definition: d3d.h:106
#define D3DERR_INVALIDCALL
struct ID3DXFont ID3DXFont
Definition: d3dx8core.h:53
static uint32_t make_pow2(uint32_t num)
#define ID3DXSprite_Release(p)
Definition: d3dx9core.h:442
#define ID3DXFont_PreloadTextW(p, a, b)
Definition: d3dx9core.h:178
#define ID3DXSprite_Begin(p, a)
Definition: d3dx9core.h:449
#define ID3DXSprite_Draw(p, a, b, c, d, e)
Definition: d3dx9core.h:450
#define ID3DXFont_GetGlyphData(p, a, b, c, d)
Definition: d3dx9core.h:174
#define ID3DXFont_PreloadGlyphs(p, a, b)
Definition: d3dx9core.h:176
#define ID3DXFont_DrawTextW(p, a, b, c, d, e, f)
Definition: d3dx9core.h:180
#define ID3DXSprite_End(p)
Definition: d3dx9core.h:452
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT32 uint32_t
Definition: types.h:75
static struct d3dx_font * impl_from_ID3DXFont(ID3DXFont *iface)
Definition: font.c:76
static uint32_t morton_decode(uint32_t x)
Definition: font.c:275
static HRESULT WINAPI ID3DXFontImpl_OnLostDevice(ID3DXFont *iface)
Definition: font.c:808
static ULONG WINAPI ID3DXFontImpl_AddRef(ID3DXFont *iface)
Definition: font.c:99
static HRESULT WINAPI ID3DXFontImpl_PreloadCharacters(ID3DXFont *iface, UINT first, UINT last)
Definition: font.c:227
static BOOL WINAPI ID3DXFontImpl_GetTextMetricsW(ID3DXFont *iface, TEXTMETRICW *metrics)
Definition: font.c:178
static HRESULT WINAPI ID3DXFontImpl_PreloadTextA(ID3DXFont *iface, const char *string, INT count)
Definition: font.c:427
static int compute_rect(struct d3dx_font *font, const WCHAR *string, unsigned int count, WCHAR *line, RECT *rect, DWORD format)
Definition: font.c:598
static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, const char *string, INT count, RECT *rect, DWORD format, D3DCOLOR color)
Definition: font.c:487
HRESULT WINAPI D3DXCreateFontW(IDirect3DDevice9 *device, INT height, UINT width, UINT weight, UINT miplevels, BOOL italic, DWORD charset, DWORD precision, DWORD quality, DWORD pitchandfamily, const WCHAR *facename, ID3DXFont **font)
Definition: font.c:867
HRESULT WINAPI D3DXCreateFontIndirectW(IDirect3DDevice9 *device, const D3DXFONT_DESCW *desc, ID3DXFont **font)
Definition: font.c:908
static HRESULT WINAPI ID3DXFontImpl_GetDescW(ID3DXFont *iface, D3DXFONT_DESCW *desc)
Definition: font.c:159
static HDC WINAPI ID3DXFontImpl_GetDC(ID3DXFont *iface)
Definition: font.c:185
HRESULT WINAPI D3DXCreateFontA(struct IDirect3DDevice9 *device, INT height, UINT width, UINT weight, UINT miplevels, BOOL italic, DWORD charset, DWORD precision, DWORD quality, DWORD pitchandfamily, const char *facename, struct ID3DXFont **font)
Definition: font.c:844
static HRESULT WINAPI ID3DXFontImpl_QueryInterface(ID3DXFont *iface, REFIID riid, void **out)
Definition: font.c:81
static HRESULT WINAPI ID3DXFontImpl_GetDescA(ID3DXFont *iface, D3DXFONT_DESCA *desc)
Definition: font.c:146
static void word_break(HDC hdc, const WCHAR *str, unsigned int *str_len, unsigned int chars_fit, unsigned int *chars_used, SIZE *size)
Definition: font.c:518
static BOOL WINAPI ID3DXFontImpl_GetTextMetricsA(ID3DXFont *iface, TEXTMETRICA *metrics)
Definition: font.c:171
HRESULT WINAPI D3DXCreateFontIndirectA(IDirect3DDevice9 *device, const D3DXFONT_DESCA *desc, ID3DXFont **font)
Definition: font.c:892
static HRESULT WINAPI ID3DXFontImpl_GetDevice(ID3DXFont *iface, IDirect3DDevice9 **device)
Definition: font.c:133
static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, const WCHAR *string, INT in_count, RECT *rect, DWORD format, D3DCOLOR color)
Definition: font.c:654
static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph, IDirect3DTexture9 **texture, RECT *black_box, POINT *cell_inc)
Definition: font.c:192
static int glyph_rb_compare(const void *key, const struct wine_rb_entry *entry)
Definition: font.c:61
static const ID3DXFontVtbl D3DXFont_Vtbl
Definition: font.c:820
static void glyph_rb_free(struct wine_rb_entry *entry, void *context)
Definition: font.c:69
static HRESULT WINAPI ID3DXFontImpl_PreloadTextW(ID3DXFont *iface, const WCHAR *string, INT count)
Definition: font.c:456
static HRESULT WINAPI ID3DXFontImpl_OnResetDevice(ID3DXFont *iface)
Definition: font.c:814
static ULONG WINAPI ID3DXFontImpl_Release(ID3DXFont *iface)
Definition: font.c:108
static HRESULT WINAPI ID3DXFontImpl_PreloadGlyphs(ID3DXFont *iface, UINT first, UINT last)
Definition: font.c:302
#define CP_ACP
Definition: compat.h:109
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
static void cleanup(void)
Definition: main.c:1335
HRESULT WINAPI ScriptBreak(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: usp10.c:3047
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint texture
Definition: glext.h:6295
GLsizei stride
Definition: glext.h:5848
GLuint buffer
Definition: glext.h:5915
GLuint color
Definition: glext.h:6243
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLenum mode
Definition: glext.h:6217
const GLint * first
Definition: glext.h:5794
GLenum GLint GLint * precision
Definition: glext.h:7539
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
int quality
Definition: jpeglib.h:992
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
static const WCHAR desc[]
Definition: protectdata.c:36
static const MAT2 mat
Definition: font.c:66
static UINT UINT last
Definition: font.c:45
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static char * dest
Definition: rtl.c:135
#define min(a, b)
Definition: monoChain.cc:55
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
Definition: mk_font.cpp:20
unsigned int UINT
Definition: ndis.h:50
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
static void wine_rb_destroy(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context)
Definition: rbtree.h:198
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
static struct wine_rb_entry * wine_rb_get(const struct wine_rb_tree *tree, const void *key)
Definition: rbtree.h:203
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
static int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
Definition: rbtree.h:215
#define memset(x, y, z)
Definition: compat.h:39
weight
Definition: sortkey.c:157
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI D3DXCreateSprite(struct IDirect3DDevice9 *device, struct ID3DXSprite **sprite)
Definition: sprite.c:569
& rect
Definition: startmenu.cpp:1413
WCHAR FaceName[LF_FACESIZE]
Definition: d3dx9core.h:122
Definition: wingdi.h:2472
Definition: http.c:7252
Definition: font.c:42
unsigned int glyphs_per_texture
Definition: font.c:58
unsigned int texture_count
Definition: font.c:56
TEXTMETRICW metrics
Definition: font.c:48
ID3DXFont ID3DXFont_iface
Definition: font.c:43
unsigned int texture_pos
Definition: font.c:56
HDC hdc
Definition: font.c:50
D3DXFONT_DESCW desc
Definition: font.c:47
IDirect3DTexture9 ** textures
Definition: font.c:55
unsigned int texture_size
Definition: font.c:58
unsigned int glyph_size
Definition: font.c:58
LONG ref
Definition: font.c:44
struct wine_rb_tree glyph_tree
Definition: font.c:53
IDirect3DDevice9 * device
Definition: font.c:46
HFONT hfont
Definition: font.c:51
IDirect3DTexture9 * texture
Definition: font.c:36
RECT black_box
Definition: font.c:34
unsigned int id
Definition: font.c:33
POINT cell_inc
Definition: font.c:35
struct wine_rb_entry entry
Definition: font.c:38
Definition: devices.h:37
Definition: copy.c:22
Definition: parser.c:49
Definition: send.c:48
Definition: sprite.c:40
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: rbtree.h:36
int read_line()
#define str_len
Definition: treelist.c:89
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define SCRIPT_UNDEFINED
Definition: usp10.h:69
int ret
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
DWORD WINAPI GetGlyphIndicesW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpstr, _In_ int c, _Out_writes_(c) LPWORD pgi, _In_ DWORD fl)
DWORD WINAPI GetCharacterPlacementW(_In_ HDC hdc, _In_reads_(nCount) LPCWSTR lpString, _In_ int nCount, _In_ int nMexExtent, _Inout_ LPGCP_RESULTSW lpResults, _In_ DWORD dwFlags)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define GGO_GLYPH_INDEX
Definition: wingdi.h:855
HFONT WINAPI CreateFontW(_In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_opt_ LPCWSTR)
#define GDI_ERROR
Definition: wingdi.h:1309
#define GGO_GRAY8_BITMAP
Definition: wingdi.h:854
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
BOOL WINAPI GetTextExtentExPointW(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpszString, _In_ int cchString, _In_ int nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
BOOL WINAPI DeleteDC(_In_ HDC)
DWORD WINAPI GetGlyphOutlineW(_In_ HDC hdc, _In_ UINT uChar, _In_ UINT fuFormat, _Out_ LPGLYPHMETRICS lpgm, _In_ DWORD cjBuffer, _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer, _In_ CONST MAT2 *lpmat2)
#define DT_CENTER
Definition: winuser.h:527
#define DT_SINGLELINE
Definition: winuser.h:540
#define DT_NOCLIP
Definition: winuser.h:536
#define DT_WORDBREAK
Definition: winuser.h:544
#define DT_VCENTER
Definition: winuser.h:543
#define DT_BOTTOM
Definition: winuser.h:525
#define DT_RIGHT
Definition: winuser.h:538
#define DT_CALCRECT
Definition: winuser.h:526
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193