You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fontdump.c 14 KiB

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