1 /* RetroArch - A frontend for libretro.
2 * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
3 * Copyright (C) 2011-2017 - Daniel De Matteis
4 *
5 * RetroArch is free software: you can redistribute it and/or modify it under the terms
6 * of the GNU General Public License as published by the Free Software Found-
7 * ation, either version 3 of the License, or (at your option) any later version.
8 *
9 * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along with RetroArch.
14 * If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #define CINTERFACE
18
19 #include <tchar.h>
20
21 #include <compat/strl.h>
22
23 #ifdef HAVE_CONFIG_H
24 #include "../../config.h"
25 #endif
26
27 #include "../common/d3d_common.h"
28 #include "../common/d3d9_common.h"
29 #include "../font_driver.h"
30
31 #include "../../configuration.h"
32
33 typedef struct d3dx_font_desc
34 {
35 INT Height;
36 UINT Width;
37 UINT Weight;
38 UINT MipLevels;
39 BOOL Italic;
40 BYTE CharSet;
41 BYTE OutputPrecision;
42 BYTE Quality;
43 BYTE PitchAndFamily;
44 CHAR FaceName[32];
45 } d3dx_font_desc_t;
46
47 typedef struct
48 {
49 d3d9_video_t *d3d;
50 void *font;
51 uint32_t font_size;
52 uint32_t ascent;
53 } d3dfonts_t;
54
d3dfonts_w32_init_font(void * video_data,const char * font_path,float font_size,bool is_threaded)55 static void *d3dfonts_w32_init_font(void *video_data,
56 const char *font_path, float font_size,
57 bool is_threaded)
58 {
59 TEXTMETRICA metrics;
60 d3dx_font_desc_t desc;
61 d3dfonts_t *d3dfonts = (d3dfonts_t*)calloc(1, sizeof(*d3dfonts));
62 if (!d3dfonts)
63 return NULL;
64
65 desc.Height = (int)font_size;
66 desc.Width = 0;
67 desc.Weight = 400;
68 desc.MipLevels = 0;
69 desc.Italic = FALSE;
70 desc.CharSet = DEFAULT_CHARSET;
71 desc.OutputPrecision = OUT_TT_PRECIS;
72 desc.Quality = CLIP_DEFAULT_PRECIS;
73 desc.PitchAndFamily = DEFAULT_PITCH;
74 #ifdef UNICODE
75 strlcpy(desc.FaceName, T(L"Verdana"), sizeof(desc.FaceName));
76 #else
77 strlcpy(desc.FaceName, (const char*)_T("Verdana"), sizeof(desc.FaceName));
78 #endif
79
80 d3dfonts->font_size = font_size * 1.2; /* to match the other font drivers */
81 d3dfonts->d3d = (d3d9_video_t*)video_data;
82
83 desc.Height = d3dfonts->font_size;
84
85 if (!d3d9x_create_font_indirect(d3dfonts->d3d->dev,
86 &desc, (void**)&d3dfonts->font))
87 goto error;
88
89 d3d9x_font_get_text_metrics(d3dfonts->font, &metrics);
90
91 d3dfonts->ascent = metrics.tmAscent;
92
93 return d3dfonts;
94
95 error:
96 free(d3dfonts);
97 return NULL;
98 }
99
d3dfonts_w32_free_font(void * data,bool is_threaded)100 static void d3dfonts_w32_free_font(void *data, bool is_threaded)
101 {
102 d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
103
104 if (!d3dfonts)
105 return;
106
107 if (d3dfonts->font)
108 d3d9x_font_release(d3dfonts->font);
109
110 free(d3dfonts);
111 }
112
d3dfonts_w32_get_message_width(void * data,const char * msg,unsigned msg_len,float scale)113 static int d3dfonts_w32_get_message_width(void* data, const char* msg,
114 unsigned msg_len, float scale)
115 {
116 RECT box = {0,0,0,0};
117 d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
118
119 if (!d3dfonts || !msg)
120 return 0;
121
122 d3d9x_font_draw_text(d3dfonts->font, NULL, (void*)msg,
123 msg_len? msg_len : -1, &box, DT_CALCRECT, 0);
124
125 return box.right - box.left;
126 }
127
d3dfonts_w32_render_msg(void * userdata,void * data,const char * msg,const struct font_params * params)128 static void d3dfonts_w32_render_msg(
129 void *userdata,
130 void *data, const char *msg,
131 const struct font_params *params)
132 {
133 unsigned format;
134 unsigned a, r, g, b;
135 unsigned width, height;
136 RECT rect, rect_shifted;
137 RECT *p_rect_shifted = NULL;
138 RECT *p_rect = NULL;
139 d3dfonts_t *d3dfonts = (d3dfonts_t*)data;
140 float drop_mod = 0.3f;
141 float drop_alpha = 1.0f;
142 int drop_x = -2;
143 int drop_y = -2;
144 settings_t *settings = config_get_ptr();
145 float video_msg_pos_x = settings->floats.video_msg_pos_x;
146 float video_msg_pos_y = settings->floats.video_msg_pos_y;
147 float video_msg_color_r = settings->floats.video_msg_color_r;
148 float video_msg_color_g = settings->floats.video_msg_color_g;
149 float video_msg_color_b = settings->floats.video_msg_color_b;
150
151 if (!d3dfonts || !msg)
152 return;
153
154 width = d3dfonts->d3d->video_info.width;
155 height = d3dfonts->d3d->video_info.height;
156
157 p_rect = &d3dfonts->d3d->font_rect;
158 p_rect_shifted = &d3dfonts->d3d->font_rect_shifted;
159 format = DT_LEFT;
160
161 if(params)
162 {
163 a = FONT_COLOR_GET_ALPHA(params->color);
164 r = FONT_COLOR_GET_RED(params->color);
165 g = FONT_COLOR_GET_GREEN(params->color);
166 b = FONT_COLOR_GET_BLUE(params->color);
167
168 switch (params->text_align)
169 {
170 case TEXT_ALIGN_RIGHT:
171 format = DT_RIGHT;
172 rect.left = 0;
173 rect.right = params->x * width;
174 break;
175 case TEXT_ALIGN_CENTER:
176 format = DT_CENTER;
177 rect.left = (params->x - 1.0) * width;
178 rect.right = (params->x + 1.0) * width;
179 break;
180 case TEXT_ALIGN_LEFT:
181 default:
182 format = DT_LEFT;
183 rect.left = params->x * width;
184 rect.right = width;
185 break;
186 }
187
188 rect.top = (1.0 - params->y) * height - d3dfonts->ascent;
189 rect.bottom = height;
190 p_rect = ▭
191
192 drop_x = params->drop_x;
193 drop_y = params->drop_y;
194
195 if(drop_x || drop_y)
196 {
197 drop_mod = params->drop_mod;
198 drop_alpha = params->drop_alpha;
199 rect_shifted = rect;
200 rect_shifted.left += params->drop_x;
201 rect_shifted.right += params->drop_x;
202 rect_shifted.top -= params->drop_y;
203 rect_shifted.bottom -= params->drop_y;
204 p_rect_shifted = &rect_shifted;
205 }
206 }
207 else
208 {
209 a = 255;
210 r = video_msg_color_r * 255;
211 g = video_msg_color_g * 255;
212 b = video_msg_color_b * 255;
213 }
214
215 if(drop_x || drop_y)
216 {
217 unsigned drop_a = a * drop_alpha;
218 unsigned drop_r = r * drop_mod;
219 unsigned drop_g = g * drop_mod;
220 unsigned drop_b = b * drop_mod;
221
222 d3d9x_font_draw_text(d3dfonts->font, NULL,
223 (void*)msg, -1, p_rect_shifted, format,
224 D3DCOLOR_ARGB(drop_a , drop_r, drop_g, drop_b));
225 }
226
227 d3d9x_font_draw_text(d3dfonts->font, NULL, (void*)msg, -1,
228 p_rect, format, D3DCOLOR_ARGB(a, r, g, b));
229 }
230
231 font_renderer_t d3d_win32_font = {
232 d3dfonts_w32_init_font,
233 d3dfonts_w32_free_font,
234 d3dfonts_w32_render_msg,
235 "d3dxfont",
236 NULL, /* get_glyph */
237 NULL, /* bind_block */
238 NULL, /* flush */
239 d3dfonts_w32_get_message_width,
240 NULL /* get_line_metrics */
241 };
242