1 /**
2 * xrdp: A Remote Desktop Protocol server.
3 *
4 * Copyright (C) Jay Sorg 2004-2012
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <windows.h>
20 #include <tchar.h>
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include "os_calls.h"
26 #include "arch.h"
27
28 static HINSTANCE g_instance = 0;
29 static HWND g_wnd = 0;
30 static HWND g_lb = 0;
31 static HWND g_exit_button = 0;
32 static HWND g_go_button = 0;
33 static HWND g_font_list = 0;
34 static char g_font_name[512] = "";
35 static int g_font_size = 10;
36 static HFONT g_font = 0;
37 static int g_running = 0;
38
39 #define FONT_DATASIZE(_w, _h) (((_h * ((_w + 7) / 8)) + 3) & ~3)
40
41 /*****************************************************************************/
42 int
check_messages(void)43 check_messages(void)
44 {
45 MSG msg;
46
47 while (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
48 {
49 GetMessage(&msg, NULL, 0, 0);
50 TranslateMessage(&msg);
51 DispatchMessage(&msg);
52 }
53
54 return 0;
55 }
56
57 /*****************************************************************************/
58 static int
msg(char * msg1,...)59 msg(char *msg1, ...)
60 {
61 va_list ap;
62 char text1[512];
63
64 va_start(ap, msg1);
65 vsnprintf(text1, 511, msg1, ap);
66 SendMessageA(g_lb, LB_ADDSTRING, 0, (LPARAM)text1);
67 va_end(ap);
68 return 0;
69 }
70
71 /*****************************************************************************/
72 static int
show_last_error(void)73 show_last_error(void)
74 {
75 LPVOID lpMsgBuf;
76
77 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
78 NULL, GetLastError(),
79 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
80 (LPSTR)&lpMsgBuf, 0, NULL);
81 msg("GetLastError - %s", lpMsgBuf);
82 LocalFree(lpMsgBuf);
83 return 0;
84 }
85
86 /*****************************************************************************/
87 static int
font_dump(void)88 font_dump(void)
89 {
90 HDC dc;
91 HDC dc1;
92 RECT rect;
93 HBRUSH brush;
94 HGDIOBJ saved;
95 HBITMAP bitmap;
96 BITMAPINFO bi;
97 char *bits;
98 ABC abc;
99 SIZE sz;
100 char filename[256];
101 TCHAR text[256];
102 char zero1;
103 char *bmtext;
104 int bmtextindex;
105 int fd;
106 int x1;
107 int strlen1;
108 int index1;
109 int index2;
110 int len;
111 int pixel;
112 int red;
113 int green;
114 int blue;
115 int width;
116 int height;
117 int roller;
118 int outlen;
119 tui8 b1;
120 short x2;
121
122 if (g_running)
123 {
124 return 0;
125 }
126
127 g_running = 1;
128 msg("starting");
129 g_font_name[0] = 0;
130 SendMessageA(g_font_list, WM_GETTEXT, 255, (LPARAM)g_font_name);
131
132 if (g_strlen(g_font_name) == 0)
133 {
134 msg("error font not set");
135 g_running = 0;
136 return 1;
137 }
138
139 dc = GetDC(g_wnd);
140 height = -MulDiv(g_font_size, GetDeviceCaps(dc, LOGPIXELSY), 72);
141 g_font = CreateFontA(height, 0, 0, 0, FW_DONTCARE, 0, 0, 0, 0, 0, 0,
142 0, 0, g_font_name);
143 ReleaseDC(g_wnd, dc);
144
145 if (g_font == 0)
146 {
147 msg("error - Font creation failed");
148 }
149
150 zero1 = 0;
151 g_snprintf(filename, 255, "%s-%d.fv1", g_font_name, g_font_size);
152 msg("creating file %s", filename);
153 g_file_delete(filename);
154 fd = g_file_open(filename);
155 g_file_write(fd, "FNT1", 4);
156 strlen1 = g_strlen(g_font_name);
157 g_file_write(fd, g_font_name, strlen1);
158 x1 = strlen1;
159
160 while (x1 < 32)
161 {
162 g_file_write(fd, &zero1, 1);
163 x1++;
164 }
165
166 x2 = g_font_size; /* font size */
167 g_file_write(fd, (char *)&x2, 2);
168 x2 = 1; /* style */
169 g_file_write(fd, (char *)&x2, 2);
170 /* pad */
171 index1 = 0;
172
173 while (index1 < 8)
174 {
175 g_file_write(fd, &zero1, 1);
176 index1++;
177 }
178
179 for (x1 = 32; x1 < 0x4e00; x1++)
180 {
181 check_messages();
182 dc = GetWindowDC(g_wnd);
183 saved = SelectObject(dc, g_font);
184
185 if (!GetCharABCWidths(dc, x1, x1, &abc))
186 {
187 show_last_error();
188 }
189
190 text[0] = (TCHAR)x1;
191 text[1] = 0;
192
193 if (!GetTextExtentPoint32(dc, text, 1, &sz))
194 {
195 show_last_error();
196 }
197
198 SelectObject(dc, saved);
199 ReleaseDC(g_wnd, dc);
200
201 if ((sz.cx > 0) && (sz.cy > 0))
202 {
203 dc = GetWindowDC(g_wnd);
204 saved = SelectObject(dc, g_font);
205 SetBkColor(dc, RGB(255, 255, 255));
206
207 if (!ExtTextOut(dc, 50, 50, ETO_OPAQUE, 0, text, 1, 0))
208 {
209 show_last_error();
210 }
211
212 SelectObject(dc, saved);
213 ReleaseDC(g_wnd, dc);
214 Sleep(10);
215 /* width */
216 x2 = abc.abcB;
217 g_file_write(fd, (char *)&x2, 2);
218 /* height */
219 x2 = sz.cy;
220 g_file_write(fd, (char *)&x2, 2);
221 /* baseline */
222 x2 = -sz.cy;
223 g_file_write(fd, (char *)&x2, 2);
224 /* offset */
225 x2 = abc.abcA;
226 g_file_write(fd, (char *)&x2, 2);
227 /* incby */
228 x2 = sz.cx;
229 g_file_write(fd, (char *)&x2, 2);
230 /* pad */
231 index1 = 0;
232
233 while (index1 < 6)
234 {
235 g_file_write(fd, &zero1, 1);
236 index1++;
237 }
238
239 dc = GetWindowDC(g_wnd);
240 rect.left = 50 + abc.abcA;
241 rect.top = 50;
242 rect.right = rect.left + abc.abcB;
243 rect.bottom = rect.top + sz.cy;
244 memset(&bi, 0, sizeof(bi));
245 width = (abc.abcB + 7) & (~7);
246 height = sz.cy;
247 bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
248 bi.bmiHeader.biWidth = width;
249 bi.bmiHeader.biHeight = height;
250 bi.bmiHeader.biPlanes = 1;
251 bi.bmiHeader.biBitCount = 32;
252 bitmap = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, (void *)&bits, 0, 0);
253
254 if (bitmap == 0)
255 {
256 msg("error - CreateDIBSection failed");
257 }
258 else
259 {
260 memset(bits, 0, width * height * 4);
261 dc1 = CreateCompatibleDC(dc);
262 SelectObject(dc1, bitmap);
263
264 if (!BitBlt(dc1, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY))
265 {
266 show_last_error();
267 }
268
269 bmtext = (char *)g_malloc(width * height + 16, 1);
270 bmtextindex = 0;
271
272 for (index1 = (height - 1); index1 >= 0; index1--)
273 {
274 for (index2 = 0; index2 < width; index2++)
275 {
276 pixel = ((int *)bits)[index1 * width + index2];
277 red = (pixel >> 16) & 0xff;
278 green = (pixel >> 8) & 0xff;
279 blue = (pixel >> 0) & 0xff;
280
281 if (red == 0 && green == 0 && blue == 0)
282 {
283 bmtext[bmtextindex] = '1';
284 bmtextindex++;
285 }
286 else
287 {
288 bmtext[bmtextindex] = '0';
289 bmtextindex++;
290 }
291 }
292 }
293
294 outlen = 0;
295 b1 = 0;
296 roller = 0;
297 len = g_strlen(bmtext);
298
299 for (index2 = 0; index2 < len; index2++)
300 {
301 if (bmtext[index2] == '1')
302 {
303 switch (roller)
304 {
305 case 0:
306 b1 = b1 | 0x80;
307 break;
308 case 1:
309 b1 = b1 | 0x40;
310 break;
311 case 2:
312 b1 = b1 | 0x20;
313 break;
314 case 3:
315 b1 = b1 | 0x10;
316 break;
317 case 4:
318 b1 = b1 | 0x08;
319 break;
320 case 5:
321 b1 = b1 | 0x04;
322 break;
323 case 6:
324 b1 = b1 | 0x02;
325 break;
326 case 7:
327 b1 = b1 | 0x01;
328 break;
329 }
330 }
331
332 roller++;
333
334 if (roller == 8)
335 {
336 roller = 0;
337 g_file_write(fd, &b1, 1);
338 outlen++;
339 b1 = 0;
340 }
341 }
342
343 while ((outlen % 4) != 0)
344 {
345 g_file_write(fd, &zero1, 1);
346 outlen++;
347 }
348
349 free(bmtext);
350 DeleteDC(dc1);
351 DeleteObject(bitmap);
352 }
353
354 if (sz.cx != (long)(abc.abcA + abc.abcB + abc.abcC))
355 {
356 msg("error - width not right 1");
357 }
358
359 brush = CreateSolidBrush(RGB(255, 255, 255));
360 FillRect(dc, &rect, brush);
361 DeleteObject(brush);
362 ReleaseDC(g_wnd, dc);
363 }
364 else
365 {
366 /* write out a blank glyph here */
367 /* width */
368 x2 = 1;
369 g_file_write(fd, (char *)&x2, 2);
370 /* height */
371 x2 = 1;
372 g_file_write(fd, (char *)&x2, 2);
373 /* baseline */
374 x2 = 0;
375 g_file_write(fd, (char *)&x2, 2);
376 /* offset */
377 x2 = 0;
378 g_file_write(fd, (char *)&x2, 2);
379 /* incby */
380 x2 = 1;
381 g_file_write(fd, (char *)&x2, 2);
382 /* pad */
383 index1 = 0;
384
385 while (index1 < 6)
386 {
387 g_file_write(fd, &zero1, 1);
388 index1++;
389 }
390
391 /* blank bitmap */
392 index1 = 0;
393
394 while (index1 < 4)
395 {
396 g_file_write(fd, &zero1, 1);
397 index1++;
398 }
399 }
400 }
401
402 g_file_close(fd);
403 msg("done");
404 g_running = 0;
405 return 0;
406 }
407
408 /*****************************************************************************/
409 static LRESULT CALLBACK
wnd_proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)410 wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
411 {
412 PAINTSTRUCT ps;
413 HBRUSH brush;
414 RECT rect;
415
416 switch (message)
417 {
418 case WM_PAINT:
419 BeginPaint(hWnd, &ps);
420 brush = CreateSolidBrush(RGB(255, 255, 255));
421 rect = ps.rcPaint;
422 FillRect(ps.hdc, &rect, brush);
423 DeleteObject(brush);
424 EndPaint(hWnd, &ps);
425 break;
426 case WM_CLOSE:
427 DestroyWindow(g_wnd);
428 g_wnd = 0;
429 break;
430 case WM_DESTROY:
431 PostQuitMessage(0);
432 break;
433 case WM_TIMER:
434 KillTimer(g_wnd, 1);
435 font_dump();
436 break;
437 case WM_COMMAND:
438
439 if ((HWND)lParam == g_exit_button)
440 {
441 PostMessage(g_wnd, WM_CLOSE, 0, 0);
442 }
443 else if ((HWND)lParam == g_go_button)
444 {
445 while (SendMessage(g_lb, LB_GETCOUNT, 0, 0) > 0)
446 {
447 SendMessage(g_lb, LB_DELETESTRING, 0, 0);
448 }
449
450 SetTimer(g_wnd, 1, 1000, 0);
451 }
452
453 break;
454 }
455
456 return DefWindowProc(hWnd, message, wParam, lParam);
457 }
458
459 /*****************************************************************************/
460 static int
create_window(void)461 create_window(void)
462 {
463 WNDCLASS wc;
464 DWORD style;
465 HDC dc;
466 int height;
467 int left;
468 int top;
469
470 ZeroMemory(&wc, sizeof(wc));
471 wc.lpfnWndProc = wnd_proc; /* points to window procedure */
472 /* name of window class */
473 wc.lpszClassName = _T("fontdump");
474 wc.hCursor = LoadCursor(0, IDC_ARROW);
475
476 /* Register the window class. */
477 if (!RegisterClass(&wc))
478 {
479 return 0; /* Failed to register window class */
480 }
481
482 style = WS_OVERLAPPED | WS_CAPTION | WS_POPUP | WS_MINIMIZEBOX |
483 WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX;
484 left = GetSystemMetrics(SM_CXSCREEN) / 2 - 640 / 2;
485 top = GetSystemMetrics(SM_CYSCREEN) / 2 - 480 / 2;
486 g_wnd = CreateWindow(wc.lpszClassName, _T("fontdump"),
487 style, left, top, 640, 480,
488 (HWND) NULL, (HMENU) NULL, g_instance,
489 (LPVOID) NULL);
490 style = WS_CHILD | WS_VISIBLE | WS_BORDER;
491 g_lb = CreateWindow(_T("LISTBOX"), _T("LISTBOX1"), style,
492 200, 10, 400, 400, g_wnd, 0, g_instance, 0);
493 style = WS_CHILD | WS_VISIBLE;
494 g_exit_button = CreateWindow(_T("BUTTON"), _T("Exit"), style,
495 540, 410, 75, 25, g_wnd, 0, g_instance, 0);
496 g_go_button = CreateWindow(_T("BUTTON"), _T("Go"), style,
497 440, 410, 75, 25, g_wnd, 0, g_instance, 0);
498 style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN;
499 g_font_list = CreateWindow(_T("COMBOBOX"), _T("COMBOBOX1"), style,
500 50, 250, 125, 125, g_wnd, 0, g_instance, 0);
501 ShowWindow(g_wnd, SW_SHOWNORMAL);
502 PostMessage(g_wnd, WM_SETFONT, (WPARAM)g_font, 0);
503 SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Tahoma");
504 SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Serif");
505 SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Sans");
506 SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Arial");
507 SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Comic Sans MS");
508 return 0;
509 }
510
511 /*****************************************************************************/
512 static int
main_loop(void)513 main_loop(void)
514 {
515 MSG msg;
516
517 while (GetMessage(&msg, NULL, 0, 0))
518 {
519 TranslateMessage(&msg);
520 DispatchMessage(&msg);
521 }
522
523 return (int)(msg.wParam);
524 }
525
526 /*****************************************************************************/
527 int WINAPI
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)528 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
529 LPSTR lpCmdLine, int nCmdShow)
530 {
531 g_instance = hInstance;
532 create_window();
533 return main_loop();
534 }
535