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