ReactOS  0.4.15-dev-1033-gd7d716a
fontboxeswnd.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS VGA Font Editor
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Implements the window showing the character boxes for a font
5  * COPYRIGHT: Copyright 2008 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 static const WCHAR szFontBoxesWndClass[] = L"VGAFontEditFontBoxesWndClass";
11 
12 static VOID
13 DrawCharacterPixel(IN PAINTSTRUCT *ps, IN UINT uCharacter, IN UCHAR uRow, IN UCHAR uColumn, IN UCHAR uBit, IN COLORREF clBackground)
14 {
15  INT x;
16  INT y;
17 
18  x = (uCharacter % 16) * (CHARACTER_BOX_WIDTH + CHARACTER_BOX_PADDING) + 24 + uColumn;
19  y = (uCharacter / 16) * (CHARACTER_BOX_HEIGHT + CHARACTER_BOX_PADDING)+ 1 + CHARACTER_INFO_BOX_HEIGHT + 2 + uRow;
20 
21  SetPixel( ps->hdc, x, y, (uBit ? 0 : clBackground) );
22 }
23 
24 VOID
25 GetCharacterRect(IN UINT uFontRow, IN UINT uFontColumn, OUT LPRECT CharacterRect)
26 {
27  CharacterRect->left = uFontColumn * (CHARACTER_BOX_WIDTH + CHARACTER_BOX_PADDING);
28  CharacterRect->top = uFontRow * (CHARACTER_BOX_HEIGHT + CHARACTER_BOX_PADDING);
29  CharacterRect->right = CharacterRect->left + CHARACTER_BOX_WIDTH;
30  CharacterRect->bottom = CharacterRect->top + CHARACTER_BOX_HEIGHT;
31 }
32 
33 static INT
34 FontBoxesHitTest(IN UINT xPos, IN UINT yPos, OUT LPRECT CharacterRect)
35 {
36  UINT uFontColumn;
37  UINT uFontRow;
38 
39  uFontColumn = xPos / (CHARACTER_BOX_WIDTH + CHARACTER_BOX_PADDING);
40  uFontRow = yPos / (CHARACTER_BOX_HEIGHT + CHARACTER_BOX_PADDING);
41  GetCharacterRect(uFontRow, uFontColumn, CharacterRect);
42 
43  if(xPos > (UINT)CharacterRect->right || yPos > (UINT)CharacterRect->bottom)
44  // The user clicked on separator space, so return HITTEST_SEPARATOR
45  return HITTEST_SEPARATOR;
46  else
47  // Return the character number
48  return (uFontRow * 16 + uFontColumn);
49 }
50 
51 static VOID
52 SetSelectedCharacter(IN PFONT_WND_INFO Info, IN UINT uNewCharacter, OPTIONAL IN LPRECT NewCharacterRect)
53 {
54  LPRECT pCharacterRect;
55  RECT OldCharacterRect;
56  UINT uFontColumn;
57  UINT uFontRow;
58 
59  // Remove the selection of the old character
60  GetCharacterPosition(Info->uSelectedCharacter, &uFontRow, &uFontColumn);
61  GetCharacterRect(uFontRow, uFontColumn, &OldCharacterRect);
62  InvalidateRect(Info->hFontBoxesWnd, &OldCharacterRect, FALSE);
63 
64  // You may pass the RECT of the new character, otherwise we'll allocate memory for one and get it ourselves
65  if(NewCharacterRect)
66  pCharacterRect = NewCharacterRect;
67  else
68  {
69  GetCharacterPosition(uNewCharacter, &uFontRow, &uFontColumn);
70  pCharacterRect = (LPRECT) HeapAlloc( hProcessHeap, 0, sizeof(RECT) );
71  GetCharacterRect(uFontRow, uFontColumn, pCharacterRect);
72  }
73 
74  // Select the new character
75  Info->uSelectedCharacter = uNewCharacter;
76  InvalidateRect(Info->hFontBoxesWnd, pCharacterRect, FALSE);
77 
78  if(!NewCharacterRect)
79  HeapFree(hProcessHeap, 0, pCharacterRect);
80 }
81 
82 static VOID
84 {
85  COLORREF clBackground;
86  HBRUSH hBrush = 0;
87  HBRUSH hOldBrush = 0;
88  HDC hBoxDC;
89  HFONT hFont;
90  HFONT hOldFont;
91  RECT CharacterRect;
92  UINT uFontColumn;
93  UINT uStartColumn;
94  UINT uEndColumn;
95  UINT uFontRow;
96  UINT uStartRow;
97  UINT uEndRow;
98  UINT uCharacter;
99  UCHAR uCharacterColumn;
100  UCHAR uCharacterRow;
101  UCHAR uBit;
102  WCHAR szInfoText[9];
103  HBITMAP hBitmapOld;
104 
105  // Preparations
106  hBoxDC = CreateCompatibleDC(NULL);
107  hBitmapOld = SelectObject(hBoxDC, Info->MainWndInfo->hBoxBmp);
108 
109  hFont = CreateFontW(13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Tahoma");
110  hOldFont = SelectObject(ps->hdc, hFont);
111 
112  SetBkMode( ps->hdc, TRANSPARENT );
113 
114  // What ranges do we have to draw?
115  uStartRow = ps->rcPaint.top / (CHARACTER_BOX_HEIGHT + CHARACTER_BOX_PADDING);
116  uEndRow = ps->rcPaint.bottom / (CHARACTER_BOX_HEIGHT + CHARACTER_BOX_PADDING);
117  uStartColumn = ps->rcPaint.left / (CHARACTER_BOX_WIDTH + CHARACTER_BOX_PADDING);
118  uEndColumn = ps->rcPaint.right / (CHARACTER_BOX_WIDTH + CHARACTER_BOX_PADDING);
119 
120  for(uFontRow = uStartRow; uFontRow <= uEndRow; uFontRow++)
121  {
122  for(uFontColumn = uStartColumn; uFontColumn <= uEndColumn; uFontColumn++)
123  {
124  GetCharacterRect(uFontRow, uFontColumn, &CharacterRect);
125  uCharacter = uFontRow * 16 + uFontColumn;
126 
127  // Draw the Character Info Box (header)
128  BitBlt(ps->hdc,
129  CharacterRect.left,
130  CharacterRect.top,
133  hBoxDC,
134  0,
135  0,
136  SRCCOPY);
137 
138  // Draw the header text
139  wsprintfW(szInfoText, L"%02u = %02X", uCharacter, uCharacter);
140  DrawTextW( ps->hdc, szInfoText, -1, &CharacterRect, DT_CENTER );
141 
142  // Draw the Character Bitmap Box (rectangle with the actual character)
143  if(Info->uSelectedCharacter == uCharacter)
144  {
145  clBackground = RGB(255, 255, 0);
146  hBrush = CreateSolidBrush(clBackground);
147  hOldBrush = SelectObject(ps->hdc, hBrush);
148  }
149  else
150  {
151  clBackground = RGB(255, 255, 255);
153  }
154 
155  Rectangle(ps->hdc,
156  CharacterRect.left,
157  CharacterRect.top + CHARACTER_INFO_BOX_HEIGHT,
158  CharacterRect.right,
159  CharacterRect.bottom);
160 
161  // Draw the actual character into the box
162  for(uCharacterRow = 0; uCharacterRow < 8; uCharacterRow++)
163  {
164  for(uCharacterColumn = 0; uCharacterColumn < 8; uCharacterColumn++)
165  {
166  uBit = Info->Font->Bits[uCharacter * 8 + uCharacterRow] << uCharacterColumn & 0x80;
167  DrawCharacterPixel(ps, uCharacter, uCharacterRow, uCharacterColumn, uBit, clBackground);
168  }
169  }
170  }
171  }
172 
173  SelectObject(hBoxDC, hBitmapOld);
174  SelectObject(ps->hdc, hOldFont);
176  SelectObject(ps->hdc, hOldBrush);
177  DeleteObject(hBrush);
178  DeleteDC(hBoxDC);
179 }
180 
181 VOID
183 {
184  PEDIT_GLYPH_INFO EditGlyphInfo;
185 
186  // Has the window for this character already been opened?
187  EditGlyphInfo = FontWndInfo->FirstEditGlyphWnd;
188 
189  while(EditGlyphInfo)
190  {
191  if(EditGlyphInfo->uCharacter == FontWndInfo->uSelectedCharacter)
192  {
193  // Yes, it has. Bring it to the front.
194  SetFocus(EditGlyphInfo->hSelf);
195  return;
196  }
197 
198  EditGlyphInfo = EditGlyphInfo->NextEditGlyphWnd;
199  }
200 
201  // No. Then create a new one
202  EditGlyphInfo = (PEDIT_GLYPH_INFO) HeapAlloc( hProcessHeap, 0, sizeof(EDIT_GLYPH_INFO) );
203  EditGlyphInfo->FontWndInfo = FontWndInfo;
204  EditGlyphInfo->uCharacter = FontWndInfo->uSelectedCharacter;
205  RtlCopyMemory( EditGlyphInfo->CharacterBits, FontWndInfo->Font->Bits + FontWndInfo->uSelectedCharacter * 8, sizeof(EditGlyphInfo->CharacterBits) );
206 
207  // Add the new window to the linked list
208  EditGlyphInfo->PrevEditGlyphWnd = FontWndInfo->LastEditGlyphWnd;
209  EditGlyphInfo->NextEditGlyphWnd = NULL;
210 
211  if(FontWndInfo->LastEditGlyphWnd)
212  FontWndInfo->LastEditGlyphWnd->NextEditGlyphWnd = EditGlyphInfo;
213  else
214  FontWndInfo->FirstEditGlyphWnd = EditGlyphInfo;
215 
216  FontWndInfo->LastEditGlyphWnd = EditGlyphInfo;
217 
218  // Open the window as a modeless dialog, so people can edit several characters at the same time.
219  EditGlyphInfo->hSelf = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_EDITGLYPH), FontWndInfo->hSelf, EditGlyphDlgProc, (LPARAM)EditGlyphInfo);
220  ShowWindow(EditGlyphInfo->hSelf, SW_SHOW);
221 }
222 
223 VOID
225 {
226  FontWndInfo->hFontBoxesWnd = CreateWindowExW(0,
228  0,
230  0,
231  0,
232  0,
233  0,
234  FontWndInfo->hSelf,
235  NULL,
236  hInstance,
237  FontWndInfo);
238 }
239 
240 static LRESULT CALLBACK
242 {
244 
246 
247  if(Info || uMsg == WM_CREATE)
248  {
249  switch(uMsg)
250  {
251  case WM_CREATE:
252  Info = (PFONT_WND_INFO)( ( (LPCREATESTRUCT)lParam )->lpCreateParams );
254 
255  // Set a fixed window size
257 
258  return 0;
259 
260  case WM_DESTROY:
262  return 0;
263 
264  case WM_KEYDOWN:
265  switch(wParam)
266  {
267  case VK_DOWN:
268  if(Info->uSelectedCharacter < 239)
269  SetSelectedCharacter(Info, Info->uSelectedCharacter + 16, NULL);
270  return 0;
271 
272  case VK_LEFT:
273  if(Info->uSelectedCharacter)
274  SetSelectedCharacter(Info, Info->uSelectedCharacter - 1, NULL);
275  return 0;
276 
277  case VK_RETURN:
279  return 0;
280 
281  case VK_RIGHT:
282  if(Info->uSelectedCharacter < 255)
283  SetSelectedCharacter(Info, Info->uSelectedCharacter + 1, NULL);
284  return 0;
285 
286  case VK_UP:
287  if(Info->uSelectedCharacter > 15)
288  SetSelectedCharacter(Info, Info->uSelectedCharacter - 16, NULL);
289  return 0;
290  }
291 
292  break;
293 
294  case WM_LBUTTONDBLCLK:
295  {
297  return 0;
298  }
299 
300  case WM_LBUTTONDOWN:
301  {
302  RECT CharacterRect;
303  INT iRet;
304 
305  iRet = FontBoxesHitTest( GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), &CharacterRect );
306 
307  if(iRet >= 0)
308  SetSelectedCharacter( Info, (UINT)iRet, &CharacterRect );
309 
310  return 0;
311  }
312 
313  case WM_PAINT:
314  {
315  PAINTSTRUCT ps;
316 
317  BeginPaint(hwnd, &ps);
318  DrawProc(Info, &ps);
319  EndPaint(hwnd, &ps);
320 
321  return 0;
322  }
323  }
324  }
325 
326  return DefWindowProcW(hwnd, uMsg, wParam, lParam);
327 }
328 
329 BOOL
331 {
332  WNDCLASSW wc = {0,};
333 
335  wc.hInstance = hInstance;
336  wc.hCursor = LoadCursor( NULL, IDC_ARROW );
337  wc.hbrBackground = (HBRUSH)( COLOR_BTNFACE + 1 );
339  wc.style = CS_DBLCLKS;
340 
341  return RegisterClassW(&wc) != 0;
342 }
343 
344 VOID
346 {
348 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define IN
Definition: typedefs.h:39
FORCEINLINE VOID SetPixel(_In_ ULONG Left, _In_ ULONG Top, _In_ UCHAR Color)
Definition: arm.h:50
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
HFONT WINAPI CreateFontW(_In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_opt_ LPCWSTR)
UINT style
Definition: winuser.h:3151
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
UCHAR Bits[2048]
Definition: raw.h:13
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define CHARACTER_BOX_WIDTH
Definition: precomp.h:103
#define RGB(r, g, b)
Definition: precomp.h:62
#define FONT_BOXES_WND_HEIGHT
Definition: precomp.h:107
struct _EDIT_GLYPH_INFO * PEDIT_GLYPH_INFO
Definition: precomp.h:37
static VOID DrawProc(IN PFONT_WND_INFO Info, IN PAINTSTRUCT *ps)
Definition: fontboxeswnd.c:83
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
LONG top
Definition: windef.h:307
#define GET_X_LPARAM(lp)
Definition: windowsx.h:274
#define VK_LEFT
Definition: winuser.h:2199
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1499
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
INT_PTR CALLBACK EditGlyphDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: editglyphdlg.c:119
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define WHITE_BRUSH
Definition: wingdi.h:901
HWND WINAPI SetFocus(_In_opt_ HWND)
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_DOWN
Definition: winuser.h:2202
#define WS_CHILD
Definition: pedump.c:617
#define GetWindowLongPtrW
Definition: winuser.h:4804
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1232
PEDIT_GLYPH_INFO LastEditGlyphWnd
Definition: precomp.h:78
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
LONG right
Definition: windef.h:308
int32_t INT
Definition: typedefs.h:58
#define VK_RETURN
Definition: winuser.h:2176
WPARAM wParam
Definition: combotst.c:138
HFONT hFont
Definition: main.c:53
struct TraceInfo Info
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
PEDIT_GLYPH_INFO NextEditGlyphWnd
Definition: precomp.h:94
VOID EditCurrentGlyph(PFONT_WND_INFO FontWndInfo)
Definition: fontboxeswnd.c:182
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1034
HINSTANCE hInstance
Definition: charmap.c:20
#define VK_UP
Definition: winuser.h:2200
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
WNDPROC lpfnWndProc
Definition: winuser.h:3152
PEDIT_GLYPH_INFO PrevEditGlyphWnd
Definition: precomp.h:93
#define TRANSPARENT
Definition: wingdi.h:949
#define GWLP_USERDATA
Definition: treelist.c:63
static VOID SetSelectedCharacter(IN PFONT_WND_INFO Info, IN UINT uNewCharacter, OPTIONAL IN LPRECT NewCharacterRect)
Definition: fontboxeswnd.c:52
smooth NULL
Definition: ftsmooth.c:416
UINT uSelectedCharacter
Definition: precomp.h:72
#define WM_KEYDOWN
Definition: winuser.h:1697
LPCWSTR lpszClassName
Definition: winuser.h:3160
LONG_PTR LPARAM
Definition: windef.h:208
#define LPRECT
Definition: precomp.h:28
UINT uCharacter
Definition: precomp.h:85
PEDIT_GLYPH_INFO FirstEditGlyphWnd
Definition: precomp.h:77
#define SW_SHOW
Definition: winuser.h:769
static VOID DrawCharacterPixel(IN PAINTSTRUCT *ps, IN UINT uCharacter, IN UCHAR uRow, IN UCHAR uColumn, IN UCHAR uBit, IN COLORREF clBackground)
Definition: fontboxeswnd.c:13
#define WM_DESTROY
Definition: winuser.h:1591
#define CHARACTER_INFO_BOX_HEIGHT
Definition: precomp.h:101
UCHAR CharacterBits[8]
Definition: precomp.h:86
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static __inline VOID GetCharacterPosition(IN UINT uCharacter, OUT PUINT uFontRow, OUT PUINT uFontColumn)
Definition: precomp.h:142
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define HITTEST_SEPARATOR
Definition: precomp.h:112
DWORD COLORREF
Definition: windef.h:300
#define IDD_EDITGLYPH
Definition: resource.h:29
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
static INT FontBoxesHitTest(IN UINT xPos, IN UINT yPos, OUT LPRECT CharacterRect)
Definition: fontboxeswnd.c:34
HWND hSelf
Definition: precomp.h:70
PFONT_WND_INFO FontWndInfo
Definition: precomp.h:83
#define WM_PAINT
Definition: winuser.h:1602
VOID CreateFontBoxesWindow(IN PFONT_WND_INFO FontWndInfo)
Definition: fontboxeswnd.c:224
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID GetCharacterRect(IN UINT uFontRow, IN UINT uFontColumn, OUT LPRECT CharacterRect)
Definition: fontboxeswnd.c:25
static const WCHAR L[]
Definition: oid.c:1250
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define COLOR_BTNFACE
Definition: winuser.h:918
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1760
#define CS_DBLCLKS
Definition: winuser.h:646
#define LoadCursor
Definition: winuser.h:5787
#define VK_RIGHT
Definition: winuser.h:2201
PBITMAP_FONT Font
Definition: precomp.h:68
static LRESULT CALLBACK FontBoxesWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: fontboxeswnd.c:241
HCURSOR hCursor
Definition: winuser.h:3157
BOOL InitFontBoxesWndClass(VOID)
Definition: fontboxeswnd.c:330
BOOL WINAPI DeleteDC(_In_ HDC)
struct _FONT_WND_INFO * PFONT_WND_INFO
Definition: precomp.h:36
#define CHARACTER_BOX_HEIGHT
Definition: precomp.h:104
HBRUSH hbrBackground
Definition: winuser.h:3158
#define CHARACTER_BOX_PADDING
Definition: precomp.h:105
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
static const WCHAR szFontBoxesWndClass[]
Definition: fontboxeswnd.c:10
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:275
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
HINSTANCE hInstance
Definition: winuser.h:3155
VOID UnInitFontBoxesWndClass(VOID)
Definition: fontboxeswnd.c:345
#define IDC_ARROW
Definition: winuser.h:682
#define OUT
Definition: typedefs.h:40
#define WM_CREATE
Definition: winuser.h:1590
#define FONT_BOXES_WND_WIDTH
Definition: precomp.h:106
HWND WINAPI CreateDialogParamW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
LONG bottom
Definition: windef.h:309
#define DT_CENTER
Definition: winuser.h:527
#define SWP_NOMOVE
Definition: winuser.h:1229
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SetWindowLongPtrW
Definition: winuser.h:5321
static HBITMAP
Definition: button.c:44
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
LONG_PTR LRESULT
Definition: windef.h:209
#define WS_VISIBLE
Definition: pedump.c:620
LPARAM lParam
Definition: combotst.c:139
#define HeapFree(x, y, z)
Definition: compat.h:483
#define SRCCOPY
Definition: wingdi.h:332
static VOID NTAPI BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:49
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:17
HANDLE hProcessHeap
Definition: kbswitch.c:25
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68