xrdp/fontdump/fontdump.c

459 lines
12 KiB
C
Raw Normal View History

2007-09-04 06:40:55 +04:00
#include <windows.h>
#include <tchar.h>
2007-09-11 10:30:47 +04:00
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
2007-09-04 06:40:55 +04:00
#include "os_calls.h"
#include "arch.h"
static HINSTANCE g_instance = 0;
static HWND g_wnd = 0;
2007-09-10 09:16:23 +04:00
static HWND g_lb = 0;
static HWND g_exit_button = 0;
static HWND g_go_button = 0;
2007-09-11 11:42:25 +04:00
static HWND g_font_list = 0;
static char g_font_name[512] = "";
2007-09-04 06:40:55 +04:00
static int g_font_size = 10;
static HFONT g_font = 0;
2007-09-11 10:30:47 +04:00
static int g_running = 0;
2007-09-04 06:40:55 +04:00
2007-09-10 09:16:23 +04:00
#define FONT_DATASIZE(_w, _h) (((_h * ((_w + 7) / 8)) + 3) & ~3)
2007-09-04 11:04:34 +04:00
/*****************************************************************************/
2007-09-04 06:40:55 +04:00
int
2007-09-11 10:30:47 +04:00
check_messages(void)
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
{
GetMessage(&msg, NULL, 0, 0);
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
/*****************************************************************************/
static int
2007-09-04 06:40:55 +04:00
msg(char* msg1, ...)
{
2007-09-11 10:30:47 +04:00
va_list ap;
char text1[512];
va_start(ap, msg1);
vsnprintf(text1, 511, msg1, ap);
SendMessageA(g_lb, LB_ADDSTRING, 0, (LPARAM)text1);
va_end(ap);
2007-09-04 06:40:55 +04:00
return 0;
}
2007-09-04 11:04:34 +04:00
/*****************************************************************************/
2007-09-11 10:30:47 +04:00
static int
2007-09-04 11:04:34 +04:00
show_last_error(void)
{
LPVOID lpMsgBuf;
2007-09-11 10:30:47 +04:00
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&lpMsgBuf, 0, NULL);
msg("GetLastError - %s", lpMsgBuf);
2007-09-04 11:04:34 +04:00
LocalFree(lpMsgBuf);
return 0;
}
2007-09-04 06:40:55 +04:00
/*****************************************************************************/
static int
font_dump(void)
{
HDC dc;
2007-09-04 11:04:34 +04:00
HDC dc1;
2007-09-04 06:40:55 +04:00
RECT rect;
HBRUSH brush;
HGDIOBJ saved;
2007-09-04 11:04:34 +04:00
HBITMAP bitmap;
BITMAPINFO bi;
char* bits;
2007-09-04 06:40:55 +04:00
ABC abc;
2007-09-04 11:04:34 +04:00
SIZE sz;
2007-09-04 06:40:55 +04:00
char filename[256];
TCHAR text[256];
char zero1;
2007-09-10 09:16:23 +04:00
char* bmtext;
int bmtextindex;
2007-09-04 06:40:55 +04:00
int fd;
int x1;
int strlen1;
2007-09-10 09:16:23 +04:00
int index1;
int index2;
int len;
int pixel;
int red;
int green;
int blue;
int width;
int height;
int roller;
int outlen;
tui8 b1;
2007-09-04 06:40:55 +04:00
short x2;
2007-09-11 10:30:47 +04:00
if (g_running)
{
return 0;
}
g_running = 1;
msg("starting");
2007-09-11 11:42:25 +04:00
g_font_name[0] = 0;
SendMessageA(g_font_list, WM_GETTEXT, 255, (LPARAM)g_font_name);
if (g_strlen(g_font_name) == 0)
{
msg("error font not set");
g_running = 0;
return 1;
}
dc = GetDC(g_wnd);
height = -MulDiv(g_font_size, GetDeviceCaps(dc, LOGPIXELSY), 72);
g_font = CreateFontA(height, 0, 0, 0, FW_DONTCARE, 0, 0, 0, 0, 0, 0,
0, 0, g_font_name);
ReleaseDC(g_wnd, dc);
if (g_font == 0)
{
msg("error - Font creation failed");
}
2007-09-04 06:40:55 +04:00
zero1 = 0;
g_snprintf(filename, 255, "%s-%d.fv1", g_font_name, g_font_size);
2007-09-11 10:30:47 +04:00
msg("creating file %s", filename);
2007-09-04 06:40:55 +04:00
g_file_delete(filename);
fd = g_file_open(filename);
g_file_write(fd, "FNT1", 4);
strlen1 = g_strlen(g_font_name);
g_file_write(fd, g_font_name, strlen1);
x1 = strlen1;
while (x1 < 32)
{
g_file_write(fd, &zero1, 1);
x1++;
}
x2 = g_font_size; /* font size */
g_file_write(fd, (char*)&x2, 2);
2007-09-04 11:04:34 +04:00
x2 = 1; /* style */
2007-09-04 06:40:55 +04:00
g_file_write(fd, (char*)&x2, 2);
2007-09-10 09:16:23 +04:00
/* pad */
index1 = 0;
while (index1 < 8)
2007-09-04 11:04:34 +04:00
{
g_file_write(fd, &zero1, 1);
2007-09-10 09:16:23 +04:00
index1++;
2007-09-04 11:04:34 +04:00
}
2007-09-23 11:53:33 +04:00
for (x1 = 32; x1 < 4096; x1++)
2007-09-04 06:40:55 +04:00
{
2007-09-11 10:30:47 +04:00
check_messages();
2007-09-04 06:40:55 +04:00
dc = GetWindowDC(g_wnd);
saved = SelectObject(dc, g_font);
2007-09-04 11:04:34 +04:00
if (!GetCharABCWidths(dc, x1, x1, &abc))
{
show_last_error();
}
text[0] = (TCHAR)x1;
text[1] = 0;
if (!GetTextExtentPoint32(dc, text, 1, &sz))
{
show_last_error();
}
2007-09-04 06:40:55 +04:00
SelectObject(dc, saved);
ReleaseDC(g_wnd, dc);
2007-09-04 11:04:34 +04:00
if ((sz.cx > 0) && (sz.cy > 0))
{
dc = GetWindowDC(g_wnd);
saved = SelectObject(dc, g_font);
SetBkColor(dc, RGB(255, 255, 255));
if (!ExtTextOut(dc, 50, 50, ETO_OPAQUE, 0, text, 1, 0))
{
show_last_error();
}
SelectObject(dc, saved);
ReleaseDC(g_wnd, dc);
Sleep(10);
2007-09-10 09:16:23 +04:00
/* width */
x2 = abc.abcB;
g_file_write(fd, (char*)&x2, 2);
/* height */
x2 = sz.cy;
g_file_write(fd, (char*)&x2, 2);
/* baseline */
x2 = -sz.cy;
g_file_write(fd, (char*)&x2, 2);
/* offset */
x2 = abc.abcA;
g_file_write(fd, (char*)&x2, 2);
/* incby */
x2 = sz.cx;
g_file_write(fd, (char*)&x2, 2);
/* pad */
index1 = 0;
while (index1 < 6)
{
g_file_write(fd, &zero1, 1);
index1++;
}
2007-09-04 11:04:34 +04:00
dc = GetWindowDC(g_wnd);
rect.left = 50 + abc.abcA;
rect.top = 50;
2007-09-10 09:16:23 +04:00
rect.right = rect.left + abc.abcB;
rect.bottom = rect.top + sz.cy;
2007-09-04 11:04:34 +04:00
memset(&bi, 0, sizeof(bi));
2007-09-10 09:16:23 +04:00
width = (abc.abcB + 7) & (~7);
height = sz.cy;
2007-09-04 11:04:34 +04:00
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
2007-09-10 09:16:23 +04:00
bi.bmiHeader.biWidth = width;
bi.bmiHeader.biHeight = height;
2007-09-04 11:04:34 +04:00
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bitmap = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, (void*)&bits, 0, 0);
if (bitmap == 0)
{
2007-09-11 10:30:47 +04:00
msg("error - CreateDIBSection failed");
2007-09-04 11:04:34 +04:00
}
else
{
2007-09-10 09:16:23 +04:00
memset(bits, 0, width * height * 4);
2007-09-04 11:04:34 +04:00
dc1 = CreateCompatibleDC(dc);
SelectObject(dc1, bitmap);
2007-09-10 09:16:23 +04:00
if (!BitBlt(dc1, 0, 0, width, height, dc, rect.left, rect.top, SRCCOPY))
2007-09-04 11:04:34 +04:00
{
show_last_error();
}
2007-09-10 09:16:23 +04:00
bmtext = (char*)g_malloc(width * height + 16, 1);
bmtextindex = 0;
for (index1 = (height - 1); index1 >= 0; index1--)
{
for (index2 = 0; index2 < width; index2++)
{
pixel = ((int*)bits)[index1 * width + index2];
red = (pixel >> 16) & 0xff;
green = (pixel >> 8) & 0xff;
blue = (pixel >> 0) & 0xff;
if (red == 0 && green == 0 && blue == 0)
{
bmtext[bmtextindex] = '1';
bmtextindex++;
}
else
{
bmtext[bmtextindex] = '0';
bmtextindex++;
}
}
}
outlen = 0;
b1 = 0;
roller = 0;
len = g_strlen(bmtext);
for (index2 = 0; index2 < len; index2++)
{
if (bmtext[index2] == '1')
{
switch (roller)
{
case 0: b1 = b1 | 0x80; break;
case 1: b1 = b1 | 0x40; break;
case 2: b1 = b1 | 0x20; break;
case 3: b1 = b1 | 0x10; break;
case 4: b1 = b1 | 0x08; break;
case 5: b1 = b1 | 0x04; break;
case 6: b1 = b1 | 0x02; break;
case 7: b1 = b1 | 0x01; break;
}
}
roller++;
if (roller == 8)
{
roller = 0;
g_file_write(fd, &b1, 1);
outlen++;
b1 = 0;
}
}
while ((outlen % 4) != 0)
{
g_file_write(fd, &zero1, 1);
outlen++;
}
free(bmtext);
2007-09-04 11:04:34 +04:00
DeleteDC(dc1);
DeleteObject(bitmap);
}
if (sz.cx != (long)(abc.abcA + abc.abcB + abc.abcC))
{
2007-09-11 10:30:47 +04:00
msg("error - width not right 1");
2007-09-04 11:04:34 +04:00
}
brush = CreateSolidBrush(RGB(255, 255, 255));
FillRect(dc, &rect, brush);
DeleteObject(brush);
ReleaseDC(g_wnd, dc);
}
else
{
2007-09-10 09:16:23 +04:00
/* write out a blank glyph here */
/* width */
x2 = 1;
g_file_write(fd, (char*)&x2, 2);
/* height */
x2 = 1;
g_file_write(fd, (char*)&x2, 2);
/* baseline */
x2 = 0;
g_file_write(fd, (char*)&x2, 2);
/* offset */
x2 = 0;
g_file_write(fd, (char*)&x2, 2);
/* incby */
x2 = 1;
g_file_write(fd, (char*)&x2, 2);
/* pad */
index1 = 0;
while (index1 < 6)
{
g_file_write(fd, &zero1, 1);
index1++;
}
/* blank bitmap */
index1 = 0;
while (index1 < 4)
{
g_file_write(fd, &zero1, 1);
index1++;
}
2007-09-04 11:04:34 +04:00
}
2007-09-04 06:40:55 +04:00
}
g_file_close(fd);
2007-09-11 10:30:47 +04:00
msg("done");
g_running = 0;
2007-09-04 06:40:55 +04:00
return 0;
}
/*****************************************************************************/
static LRESULT CALLBACK
wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HBRUSH brush;
RECT rect;
switch (message)
{
case WM_PAINT:
BeginPaint(hWnd, &ps);
2007-09-04 11:04:34 +04:00
brush = CreateSolidBrush(RGB(255, 255, 255));
2007-09-04 06:40:55 +04:00
rect = ps.rcPaint;
FillRect(ps.hdc, &rect, brush);
DeleteObject(brush);
EndPaint(hWnd, &ps);
break;
case WM_CLOSE:
DestroyWindow(g_wnd);
g_wnd = 0;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_TIMER:
KillTimer(g_wnd, 1);
font_dump();
break;
2007-09-10 09:16:23 +04:00
case WM_COMMAND:
2007-09-11 10:30:47 +04:00
if ((HWND)lParam == g_exit_button)
{
PostMessage(g_wnd, WM_CLOSE, 0, 0);
}
else if ((HWND)lParam == g_go_button)
{
while (SendMessage(g_lb, LB_GETCOUNT, 0, 0) > 0)
{
SendMessage(g_lb, LB_DELETESTRING, 0, 0);
}
SetTimer(g_wnd, 1, 1000, 0);
}
2007-09-10 09:16:23 +04:00
break;
2007-09-04 06:40:55 +04:00
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
/*****************************************************************************/
static int
create_window(void)
{
WNDCLASS wc;
DWORD style;
HDC dc;
int height;
2007-09-11 10:30:47 +04:00
int left;
int top;
2007-09-04 06:40:55 +04:00
ZeroMemory(&wc, sizeof(wc));
wc.lpfnWndProc = wnd_proc; /* points to window procedure */
/* name of window class */
wc.lpszClassName = _T("fontdump");
wc.hCursor = LoadCursor(0, IDC_ARROW);
/* Register the window class. */
if (!RegisterClass(&wc))
{
return 0; /* Failed to register window class */
}
style = WS_OVERLAPPED | WS_CAPTION | WS_POPUP | WS_MINIMIZEBOX |
WS_SYSMENU | WS_SIZEBOX | WS_MAXIMIZEBOX;
2007-09-11 10:30:47 +04:00
left = GetSystemMetrics(SM_CXSCREEN) / 2 - 640 / 2;
top = GetSystemMetrics(SM_CYSCREEN) / 2 - 480 / 2;
2007-09-04 06:40:55 +04:00
g_wnd = CreateWindow(wc.lpszClassName, _T("fontdump"),
2007-09-11 10:30:47 +04:00
style, left, top, 640, 480,
2007-09-04 06:40:55 +04:00
(HWND) NULL, (HMENU) NULL, g_instance,
(LPVOID) NULL);
2007-09-10 09:16:23 +04:00
style = WS_CHILD | WS_VISIBLE | WS_BORDER;
g_lb = CreateWindow(_T("LISTBOX"), _T("LISTBOX1"), style,
200, 10, 400, 400, g_wnd, 0, g_instance, 0);
style = WS_CHILD | WS_VISIBLE;
g_exit_button = CreateWindow(_T("BUTTON"), _T("Exit"), style,
540, 410, 75, 25, g_wnd, 0, g_instance, 0);
g_go_button = CreateWindow(_T("BUTTON"), _T("Go"), style,
440, 410, 75, 25, g_wnd, 0, g_instance, 0);
2007-09-11 11:42:25 +04:00
style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN;
g_font_list = CreateWindow(_T("COMBOBOX"), _T("COMBOBOX1"), style,
50, 250, 125, 125, g_wnd, 0, g_instance, 0);
2007-09-04 06:40:55 +04:00
ShowWindow(g_wnd, SW_SHOWNORMAL);
PostMessage(g_wnd, WM_SETFONT, (WPARAM)g_font, 0);
2007-09-11 11:42:25 +04:00
SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Tahoma");
SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Serif");
SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"DejaVu Sans");
SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Arial");
SendMessageA(g_font_list, CB_ADDSTRING, 0, (LPARAM)"Comic Sans MS");
2007-09-04 06:40:55 +04:00
return 0;
}
/*****************************************************************************/
static int
main_loop(void)
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)(msg.wParam);
}
/*****************************************************************************/
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
g_instance = hInstance;
create_window();
return main_loop();
}