mirror of
https://github.com/reactos/reactos.git
synced 2024-09-13 06:11:59 +00:00
7901978873
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
298 lines
8.2 KiB
C
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);
|
|
}
|