reactos/rosapps/devutils/vgafontedit/editglyphdlg.c
Colin Finck 7901978873 Wrote a Win32 Font Editor for our VGA Fonts used in blue.sys.
It has a MDI user interface, imports binary fonts (.bin) and PC Screen Fonts (.psf) and exports .bin fonts.
Compiles without any warnings with GCC and MSVC (at /W3).

The "misc.c" file was taken from devmgmt (thanks Ged!) and modified.
The used bitmaps and icons were all done myself, but partly consist of characters of the cp737 font we have in media/vgafont.

svn path=/trunk/; revision=32079
2008-02-01 21:40:18 +00:00

298 lines
8.2 KiB
C

/*
* PROJECT: ReactOS VGA Font Editor
* LICENSE: GNU General Public License Version 2.0 or any later version
* FILE: devutils/vgafontedit/editglyphdlg.c
* PURPOSE: Dialog for editing a glyph
* COPYRIGHT: Copyright 2008 Colin Finck <mail@colinfinck.de>
*/
#include "precomp.h"
static VOID
AddToolboxButton(IN HWND hToolbar, IN INT iBitmap, IN INT idCommand, IN BYTE fsState)
{
TBBUTTON tbb = {0,};
tbb.fsState = fsState;
tbb.fsStyle = BTNS_CHECKGROUP;
tbb.iBitmap = iBitmap;
tbb.idCommand = idCommand;
SendMessageW( hToolbar, TB_ADDBUTTONSW, 1, (LPARAM)&tbb );
}
static VOID
InitToolbox(IN PEDIT_GLYPH_INFO Info)
{
HWND hToolbar;
INT iBitmap;
TBADDBITMAP tbab;
hToolbar = GetDlgItem(Info->hSelf, IDC_EDIT_GLYPH_TOOLBOX);
// Identify the used Common Controls version
SendMessageW(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
// Set the button size to 24x24
SendMessageW( hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(24, 24) );
SendMessageW( hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(24, 24) );
// Add the Toolbox bitmaps
tbab.hInst = hInstance;
tbab.nID = IDB_EDIT_GLYPH_TOOLBOX;
iBitmap = SendMessageW(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
AddToolboxButton(hToolbar, iBitmap + TOOLBOX_PEN, ID_TOOLBOX_PEN, TBSTATE_ENABLED | TBSTATE_CHECKED);
}
static VOID
GetBitRect(IN PEDIT_GLYPH_INFO Info, IN UINT uRow, IN UINT uColumn, OUT LPRECT BitRect)
{
BitRect->left = uColumn * Info->lEditSpacing + 1;
BitRect->top = uRow * Info->lEditSpacing + 1;
BitRect->right = BitRect->left + Info->lEditSpacing - 1;
BitRect->bottom = BitRect->top + Info->lEditSpacing - 1;
}
static VOID
SetPixelBit(IN PEDIT_GLYPH_INFO Info, IN UINT uRow, IN UINT uColumn, IN BOOL uBit)
{
// Set the bit in the bitfield
if(uBit)
Info->CharacterBits[uRow] |= 1 << (7 - uColumn);
else
Info->CharacterBits[uRow] &= ~( 1 << (7 - uColumn) );
// Redraw everything
InvalidateRect(Info->hEdit, NULL, FALSE);
InvalidateRect(Info->hPreview, NULL, FALSE);
}
static BOOL
EditGlyphCommand(IN INT idCommand, IN PEDIT_GLYPH_INFO Info)
{
switch(idCommand)
{
case IDOK:
{
RECT rect;
UINT uColumn;
UINT uRow;
RtlCopyMemory( Info->FontWndInfo->Font->Bits + Info->uCharacter * 8, Info->CharacterBits, sizeof(Info->CharacterBits) );
GetCharacterPosition(Info->uCharacter, &uRow, &uColumn);
GetCharacterRect(uRow, uColumn, &rect);
InvalidateRect(Info->FontWndInfo->hFontBoxesWnd, &rect, FALSE);
Info->FontWndInfo->OpenInfo->bModified = TRUE;
// Fall through
}
case IDCANCEL:
EndDialog(Info->hSelf, 0);
return TRUE;
}
return FALSE;
}
INT_PTR CALLBACK
EditGlyphDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PEDIT_GLYPH_INFO Info;
Info = (PEDIT_GLYPH_INFO) GetWindowLongW(hwnd, GWLP_USERDATA);
if(Info || uMsg == WM_INITDIALOG)
{
switch(uMsg)
{
case WM_COMMAND:
return EditGlyphCommand( LOWORD(wParam), Info );
case WM_DESTROY:
SetWindowLongW(hwnd, GWLP_USERDATA, 0);
SetWindowLongW(Info->hEdit, GWLP_USERDATA, 0);
SetWindowLongW(Info->hPreview, GWLP_USERDATA, 0 );
HeapFree(hProcessHeap, 0, Info);
return TRUE;
case WM_INITDIALOG:
Info = (PEDIT_GLYPH_INFO) lParam;
Info->hSelf = hwnd;
Info->hEdit = GetDlgItem(hwnd, IDC_EDIT_GLYPH_EDIT);
Info->hPreview = GetDlgItem(hwnd, IDC_EDIT_GLYPH_PREVIEW);
SetWindowLongW(hwnd, GWLP_USERDATA, (LONG)Info);
SetWindowLongW(Info->hEdit, GWLP_USERDATA, (LONG)Info);
SetWindowLongW(Info->hPreview, GWLP_USERDATA, (LONG)Info);
InitToolbox(Info);
return TRUE;
}
}
return FALSE;
}
static LRESULT CALLBACK
EditGlyphEditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PEDIT_GLYPH_INFO Info;
Info = (PEDIT_GLYPH_INFO) GetWindowLongW(hwnd, GWLP_USERDATA);
if(Info)
{
switch(uMsg)
{
case WM_CREATE:
return 0;
case WM_LBUTTONDOWN:
SetPixelBit(Info, GET_Y_LPARAM(lParam) / Info->lEditSpacing, GET_X_LPARAM(lParam) / Info->lEditSpacing, 1);
return 0;
case WM_RBUTTONDOWN:
SetPixelBit(Info, GET_Y_LPARAM(lParam) / Info->lEditSpacing, GET_X_LPARAM(lParam) / Info->lEditSpacing, 0);
return 0;
case WM_PAINT:
{
BOOL bBit;
HPEN hOldPen;
HPEN hPen;
PAINTSTRUCT ps;
RECT rect;
UINT i;
UINT j;
BeginPaint(hwnd, &ps);
// Draw the grid
GetClientRect(hwnd, &rect);
Info->lEditSpacing = rect.right / 8;
hPen = CreatePen( PS_SOLID, 1, RGB(128, 128, 128) );
hOldPen = SelectObject(ps.hdc, hPen);
for(i = 1; i < 8; i++)
{
MoveToEx(ps.hdc, i * Info->lEditSpacing, 0, NULL);
LineTo (ps.hdc, i * Info->lEditSpacing, rect.right);
MoveToEx(ps.hdc, 0, i * Info->lEditSpacing, NULL);
LineTo (ps.hdc, rect.right, i * Info->lEditSpacing);
}
SelectObject(ps.hdc, hOldPen);
DeleteObject(hPen);
// Draw all bits
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
bBit = (BOOL) (Info->CharacterBits[i] << j & 0x80);
GetBitRect(Info, i, j, &rect);
FillRect( ps.hdc, &rect, (HBRUSH) GetStockObject(bBit ? BLACK_BRUSH : WHITE_BRUSH) );
}
}
// Draw the bounding rectangle
SelectObject( ps.hdc, GetStockObject(NULL_BRUSH) );
Rectangle(ps.hdc, 0, 0, rect.right, rect.right);
EndPaint(hwnd, &ps);
return 0;
}
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
static LRESULT CALLBACK
EditGlyphPreviewWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PEDIT_GLYPH_INFO Info;
Info = (PEDIT_GLYPH_INFO) GetWindowLongW(hwnd, GWLP_USERDATA);
if(Info)
{
switch(uMsg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
{
BOOL bBit;
INT iLeft;
INT iTop;
PAINTSTRUCT ps;
RECT rect;
UINT i;
UINT j;
BeginPaint(hwnd, &ps);
// Draw the bounding rectangle
GetClientRect(hwnd, &rect);
Rectangle(ps.hdc, 0, 0, rect.right, rect.bottom);
// Draw all bits
iLeft = rect.right / 2 - 8 / 2;
iTop = rect.bottom / 2 - 8 / 2;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
bBit = (BOOL) (Info->CharacterBits[i] << j & 0x80);
SetPixel( ps.hdc, j + iLeft, i + iTop, (bBit ? 0 : 0xFFFFFF) );
}
}
EndPaint(hwnd, &ps);
return 0;
}
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
BOOL
InitEditGlyphWndClasses(VOID)
{
WNDCLASSW wc = {0,};
wc.lpfnWndProc = EditGlyphEditWndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.lpszClassName = EDIT_GLYPH_EDIT_CLASSW;
if( !RegisterClassW(&wc) )
return FALSE;
wc.lpfnWndProc = EditGlyphPreviewWndProc;
wc.lpszClassName = EDIT_GLYPH_PREVIEW_CLASSW;
return RegisterClassW(&wc) != 0;
}
VOID
UnInitEditGlyphWndClasses(VOID)
{
UnregisterClassW(EDIT_GLYPH_EDIT_CLASSW, hInstance);
UnregisterClassW(EDIT_GLYPH_PREVIEW_CLASSW, hInstance);
}