02ef4c3c8681a8eb63b8a7624b38f08970cc1358
[reactos.git] / reactos / dll / cpl / console / font.c
1 /*
2 * PROJECT: ReactOS Console Configuration DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/console/font.c
5 * PURPOSE: Font dialog
6 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
9 */
10
11 #include "console.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 /*
18 * Current active font, corresponding to the active console font,
19 * and used for painting the text samples.
20 */
21 HFONT hCurrentFont = NULL;
22
23
24 /*
25 * Standard font pixel/point heights for TrueType fonts
26 */
27 static const SHORT TrueTypePoints[] =
28 {
29 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72
30 };
31
32 typedef struct _FONTSIZE_LIST_CTL
33 {
34 LIST_CTL RasterSizeList; // ListBox for Raster font sizes; needs to handle bisection.
35 HWND hWndTTSizeList; // ComboBox for TrueType font sizes.
36 BOOL bIsTTSizeDirty; // TRUE or FALSE depending on whether we have edited the edit zone.
37 BOOL UseRasterOrTTList; // TRUE: Use the Raster size list; FALSE: Use the TrueType size list.
38 BOOL TTSizePixelUnit; // TRUE: Size in pixels (default); FALSE: Size in points.
39 LONG CurrentRasterSize;
40 LONG CurrentTTSize; // In whatever unit (pixels or points) currently selected.
41 } FONTSIZE_LIST_CTL, *PFONTSIZE_LIST_CTL;
42
43 /* Used by FontTypeChange() only */
44 static INT CurrentSelFont = LB_ERR;
45 static DWORD CurrentFontType = (DWORD)-1; // Invalid font type
46
47
48 // PLIST_GETCOUNT
49 static INT
50 RasterSizeList_GetCount(
51 IN PLIST_CTL ListCtl)
52 {
53 return (INT)SendMessageW(ListCtl->hWndList, LB_GETCOUNT, 0, 0);
54 }
55
56 // PLIST_GETDATA
57 static ULONG_PTR
58 RasterSizeList_GetData(
59 IN PLIST_CTL ListCtl,
60 IN INT Index)
61 {
62 return (ULONG_PTR)SendMessageW(ListCtl->hWndList, LB_GETITEMDATA, (WPARAM)Index, 0);
63 }
64
65
66 INT
67 LogicalSizeToPointSize(
68 IN HDC hDC OPTIONAL,
69 IN UINT LogicalSize)
70 {
71 INT PointSize;
72 HDC hOrgDC = hDC;
73
74 if (!hDC)
75 hDC = GetDC(NULL);
76
77 // LogicalSize = tm.tmHeight - tm.tmInternalLeading;
78 PointSize = MulDiv(LogicalSize, 72, GetDeviceCaps(hDC, LOGPIXELSY));
79
80 if (!hOrgDC)
81 ReleaseDC(NULL, hDC);
82
83 return PointSize;
84 }
85
86 INT
87 PointSizeToLogicalSize(
88 IN HDC hDC OPTIONAL,
89 IN INT PointSize)
90 {
91 INT LogicalSize;
92 HDC hOrgDC = hDC;
93
94 if (!hDC)
95 hDC = GetDC(NULL);
96
97 LogicalSize = MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
98
99 if (!hOrgDC)
100 ReleaseDC(NULL, hDC);
101
102 return LogicalSize;
103 }
104
105
106 static VOID
107 FontSizeList_SelectFontSize(
108 IN PFONTSIZE_LIST_CTL SizeList,
109 IN ULONG FontSize)
110 {
111 INT nSel;
112 WCHAR szFontSize[100];
113
114 //
115 // FIXME: Check whether FontSize == 0
116 // (or in the case of raster font maybe, whether HIWORD(FontSize) == Height == 0) ??
117 //
118
119 /* Find and select the best font size in the list corresponding to the current size */
120 if (SizeList->UseRasterOrTTList)
121 {
122 INT idx;
123
124 /* Raster font size (in pixels) */
125 SizeList->CurrentRasterSize = FontSize;
126
127 nSel = BisectListSortedByValue(&SizeList->RasterSizeList, FontSize, NULL, FALSE);
128 idx = (INT)SendMessageW(SizeList->RasterSizeList.hWndList, LB_GETCOUNT, 0, 0);
129 if (nSel == LB_ERR)
130 {
131 /* Not found, select the first element of the list */
132 nSel = 0;
133 }
134 else if (nSel >= idx)
135 {
136 /*
137 * We got an index beyond the end of the list (as per Bisect* functionality),
138 * so instead, select the last element of the list.
139 */
140 nSel = idx-1;
141 }
142 SendMessageW(SizeList->RasterSizeList.hWndList, LB_SETCURSEL, (WPARAM)nSel, 0);
143 }
144 else
145 {
146 /* TrueType font size (in pixels or points) */
147 SizeList->CurrentTTSize = FontSize;
148
149 // _ultow(szFontSize, FontSize, 10);
150 StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", FontSize);
151
152 /* Find the font size in the list, or add it both in the ComboBox list, sorted by size value (string), and its edit box */
153 nSel = SendMessageW(SizeList->hWndTTSizeList, CB_FINDSTRINGEXACT, 0, (LPARAM)szFontSize);
154 if (nSel == CB_ERR)
155 {
156 nSel = (UINT)SendMessageW(SizeList->hWndTTSizeList, CB_ADDSTRING, -1, (LPARAM)szFontSize);
157 // ComboBox_SetText(...)
158 SetWindowTextW(SizeList->hWndTTSizeList, szFontSize);
159 SizeList->bIsTTSizeDirty = TRUE;
160 }
161 SendMessageW(SizeList->hWndTTSizeList, CB_SETCURSEL, (WPARAM)nSel, 0);
162 }
163 }
164
165 static LONG
166 FontSizeList_GetSelectedFontSize(
167 IN PFONTSIZE_LIST_CTL SizeList)
168 {
169 INT nSel;
170 LONG FontSize;
171 WCHAR szFontSize[100];
172
173 if (SizeList->UseRasterOrTTList)
174 {
175 /* Raster font size (in pixels) */
176
177 nSel = (INT)SendMessageW(SizeList->RasterSizeList.hWndList, LB_GETCURSEL, 0, 0);
178 if (nSel == LB_ERR) return 0;
179
180 FontSize = (LONG)SizeList->RasterSizeList.GetData(&SizeList->RasterSizeList, nSel);
181 if (FontSize == LB_ERR) return 0;
182
183 SizeList->CurrentRasterSize = FontSize;
184 }
185 else
186 {
187 /* TrueType font size (in pixels or points) */
188
189 if (!SizeList->bIsTTSizeDirty)
190 {
191 /*
192 * The user just selected an existing size, read the ComboBox selection.
193 *
194 * See: https://support.microsoft.com/en-us/help/66365/how-to-process-a-cbn-selchange-notification-message
195 * for more details.
196 */
197 nSel = SendMessageW(SizeList->hWndTTSizeList, CB_GETCURSEL, 0, 0);
198 SendMessageW(SizeList->hWndTTSizeList, CB_GETLBTEXT, nSel, (LPARAM)szFontSize);
199 }
200 else
201 {
202 /* Read the ComboBox edit string, as the user has entered a custom size */
203 // ComboBox_GetText(...)
204 GetWindowTextW(SizeList->hWndTTSizeList, szFontSize, ARRAYSIZE(szFontSize));
205
206 // HACK???
207 nSel = SendMessageW(SizeList->hWndTTSizeList, CB_FINDSTRINGEXACT, 0, (LPARAM)szFontSize);
208 if (nSel == CB_ERR)
209 {
210 nSel = (UINT)SendMessageW(SizeList->hWndTTSizeList, CB_ADDSTRING, -1, (LPARAM)szFontSize);
211 //// ComboBox_SetText(...)
212 //SetWindowTextW(SizeList->hWndTTSizeList, szFontSize);
213 //SizeList->bIsTTSizeDirty = TRUE;
214 }
215 SendMessageW(SizeList->hWndTTSizeList, CB_SETCURSEL, (WPARAM)nSel, 0);
216 }
217
218 SizeList->bIsTTSizeDirty = FALSE;
219
220 /* If _wtol fails and returns 0, the font size is considered invalid */
221 // FontSize = wcstoul(szFontSize, &pszNext, 10); if (!*pszNext) { /* Error */ }
222 FontSize = _wtol(szFontSize);
223 if (FontSize == 0) return 0;
224
225 SizeList->CurrentTTSize = FontSize;
226
227 /*
228 * If the font size is given in points, instead of pixels,
229 * convert it into logical size.
230 */
231 if (!SizeList->TTSizePixelUnit)
232 FontSize = -PointSizeToLogicalSize(NULL, FontSize);
233 }
234
235 return FontSize;
236 }
237
238
239 static VOID
240 AddFontToList(
241 IN HWND hWndList,
242 IN LPCWSTR pszFaceName,
243 IN DWORD FontType)
244 {
245 INT iItem;
246
247 /* Make sure the font doesn't already exist in the list */
248 if (SendMessageW(hWndList, LB_FINDSTRINGEXACT, 0, (LPARAM)pszFaceName) != LB_ERR)
249 return;
250
251 /* Add the font */
252 iItem = (INT)SendMessageW(hWndList, LB_ADDSTRING, 0, (LPARAM)pszFaceName);
253 if (iItem == LB_ERR)
254 {
255 DPRINT1("Failed to add font '%S'\n", pszFaceName);
256 return;
257 }
258
259 DPRINT1("Add font '%S'\n", pszFaceName);
260
261 /* Store this information in the list-item's userdata area */
262 // SendMessageW(hWndList, LB_SETITEMDATA, idx, MAKELPARAM(fFixed, fTrueType));
263 SendMessageW(hWndList, LB_SETITEMDATA, iItem, (LPARAM)FontType);
264 }
265
266 typedef struct _FACE_NAMES_PROC_PARAM
267 {
268 HWND hWndList;
269 UINT CodePage;
270 } FACE_NAMES_PROC_PARAM, *PFACE_NAMES_PROC_PARAM;
271
272 static BOOL CALLBACK
273 EnumFaceNamesProc(
274 IN PLOGFONTW lplf,
275 IN PNEWTEXTMETRICW lpntm,
276 IN DWORD FontType,
277 IN LPARAM lParam)
278 {
279 PFACE_NAMES_PROC_PARAM Param = (PFACE_NAMES_PROC_PARAM)lParam;
280
281 /*
282 * To install additional TrueType fonts to be available for the console,
283 * add entries of type REG_SZ named "0", "00" etc... in:
284 * HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont
285 * The names of the fonts listed there should match those in:
286 * HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts
287 */
288 if (IsValidConsoleFont2(lplf, lpntm, FontType, Param->CodePage))
289 {
290 /* Add the font to the list */
291 AddFontToList(Param->hWndList, lplf->lfFaceName, FontType);
292 }
293
294 /* Continue the font enumeration */
295 return TRUE;
296 }
297
298 static BOOL CALLBACK
299 EnumFontSizesProc(
300 IN PLOGFONTW lplf,
301 IN PNEWTEXTMETRICW lpntm,
302 IN DWORD FontType,
303 IN LPARAM lParam)
304 {
305 PFONTSIZE_LIST_CTL SizeList = (PFONTSIZE_LIST_CTL)lParam;
306 UINT iItem, iDupItem;
307 WCHAR szFontSize[100];
308
309 if (FontType != TRUETYPE_FONTTYPE)
310 {
311 WPARAM FontSize;
312
313 /*
314 * Format:
315 * Width = FontSize.X = LOWORD(FontSize);
316 * Height = FontSize.Y = HIWORD(FontSize);
317 */
318
319 StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d x %d", lplf->lfWidth, lplf->lfHeight);
320 FontSize = MAKEWPARAM(lplf->lfWidth, lplf->lfHeight);
321
322 /* Add the font size into the list, sorted by size value. Avoid any duplicates. */
323 /* Store this information in the list-item's userdata area */
324 iDupItem = LB_ERR;
325 iItem = BisectListSortedByValue(&SizeList->RasterSizeList, FontSize, &iDupItem, TRUE);
326 if (iItem == LB_ERR)
327 iItem = 0;
328 if (iDupItem == LB_ERR)
329 {
330 iItem = (UINT)SendMessageW(SizeList->RasterSizeList.hWndList, LB_INSERTSTRING, iItem, (LPARAM)szFontSize);
331 if (iItem != LB_ERR && iItem != LB_ERRSPACE)
332 iItem = SendMessageW(SizeList->RasterSizeList.hWndList, LB_SETITEMDATA, iItem, FontSize);
333 }
334
335 return TRUE;
336 }
337 else
338 {
339 /* TrueType or vectored font: list all the hardcoded font points */
340 ULONG i;
341 for (i = 0; i < ARRAYSIZE(TrueTypePoints); ++i)
342 {
343 // _ultow(szFontSize, TrueTypePoints[i], 10);
344 StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", TrueTypePoints[i]);
345
346 /* Add the font size into the list, sorted by size value (string). Avoid any duplicates. */
347 if (SendMessageW(SizeList->hWndTTSizeList, CB_FINDSTRINGEXACT, 0, (LPARAM)szFontSize) == CB_ERR)
348 iItem = (UINT)SendMessageW(SizeList->hWndTTSizeList, CB_INSERTSTRING, -1, (LPARAM)szFontSize);
349 }
350
351 /* Stop the enumeration now */
352 return FALSE;
353 }
354 }
355
356 static VOID
357 FaceNameList_Initialize(
358 IN HWND hWndList,
359 IN UINT CodePage)
360 {
361 FACE_NAMES_PROC_PARAM Param;
362 HDC hDC;
363 LOGFONTW lf;
364 INT idx;
365
366 Param.hWndList = hWndList;
367 Param.CodePage = CodePage;
368
369 ZeroMemory(&lf, sizeof(lf));
370 lf.lfCharSet = DEFAULT_CHARSET; // CodePageToCharSet(CodePage);
371 // lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
372
373 hDC = GetDC(NULL);
374 EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFaceNamesProc, (LPARAM)&Param, 0);
375 ReleaseDC(NULL, hDC);
376
377 idx = (INT)SendMessageW(hWndList, LB_GETCOUNT, 0, 0);
378 if (idx != LB_ERR && idx != 0)
379 {
380 /* We have found some fonts and filled the list, we are fine! */
381 return;
382 }
383
384 /* No fonts were found. Manually add default ones into the list. */
385 DPRINT1("The ideal console fonts were not found; manually add default ones.\n");
386
387 AddFontToList(hWndList, L"Terminal", RASTER_FONTTYPE);
388 AddFontToList(hWndList, L"Lucida Console", TRUETYPE_FONTTYPE);
389 if (CodePageToCharSet(CodePage) != DEFAULT_CHARSET)
390 AddFontToList(hWndList, L"Droid Sans Fallback", TRUETYPE_FONTTYPE);
391 }
392
393 static VOID
394 FaceNameList_SelectFaceName(
395 IN HWND hWndList,
396 IN LPCWSTR FaceName)
397 {
398 INT iItem;
399
400 iItem = (INT)SendMessageW(hWndList, LB_FINDSTRINGEXACT, 0, (LPARAM)FaceName);
401 if (iItem == LB_ERR)
402 iItem = (INT)SendMessageW(hWndList, LB_FINDSTRINGEXACT, 0, (LPARAM)L"Terminal");
403 if (iItem == LB_ERR)
404 iItem = 0;
405 SendMessageW(hWndList, LB_SETCURSEL, (WPARAM)iItem, 0);
406
407 // return iItem;
408 }
409
410 static VOID
411 UpdateFontSizeList(
412 IN HWND hDlg,
413 IN PFONTSIZE_LIST_CTL SizeList)
414 {
415 HWND hDlgItem;
416
417 if (SizeList->UseRasterOrTTList)
418 {
419 /*
420 * Raster font: show the Raster size list, and
421 * hide the TrueType size list and the units.
422 */
423
424 // EnableDlgItem(hDlg, IDC_CHECK_BOLD_FONTS, FALSE);
425
426 hDlgItem = GetDlgItem(hDlg, IDC_RADIO_PIXEL_UNIT);
427 ShowWindow(hDlgItem, SW_HIDE);
428 EnableWindow(hDlgItem, FALSE);
429
430 hDlgItem = GetDlgItem(hDlg, IDC_RADIO_POINT_UNIT);
431 ShowWindow(hDlgItem, SW_HIDE);
432 EnableWindow(hDlgItem, FALSE);
433
434 hDlgItem = SizeList->hWndTTSizeList;
435 ShowWindow(hDlgItem, SW_HIDE);
436 EnableWindow(hDlgItem, FALSE);
437
438 hDlgItem = SizeList->RasterSizeList.hWndList;
439 EnableWindow(hDlgItem, TRUE);
440 ShowWindow(hDlgItem, SW_SHOW);
441 }
442 else
443 {
444 /*
445 * TrueType font: show the TrueType size list
446 * and the units, and hide the Raster size list.
447 */
448
449 // EnableDlgItem(hDlg, IDC_CHECK_BOLD_FONTS, TRUE);
450
451 hDlgItem = SizeList->RasterSizeList.hWndList;
452 ShowWindow(hDlgItem, SW_HIDE);
453 EnableWindow(hDlgItem, FALSE);
454
455 hDlgItem = SizeList->hWndTTSizeList;
456 EnableWindow(hDlgItem, TRUE);
457 ShowWindow(hDlgItem, SW_SHOW);
458
459 hDlgItem = GetDlgItem(hDlg, IDC_RADIO_PIXEL_UNIT);
460 EnableWindow(hDlgItem, TRUE);
461 ShowWindow(hDlgItem, SW_SHOW);
462
463 hDlgItem = GetDlgItem(hDlg, IDC_RADIO_POINT_UNIT);
464 EnableWindow(hDlgItem, TRUE);
465 ShowWindow(hDlgItem, SW_SHOW);
466 }
467 }
468
469 static BOOL
470 FontSizeChange(
471 IN HWND hDlg,
472 IN PFONTSIZE_LIST_CTL SizeList,
473 IN OUT PCONSOLE_STATE_INFO pConInfo);
474
475 static BOOL
476 FontTypeChange(
477 IN HWND hDlg,
478 IN PFONTSIZE_LIST_CTL SizeList,
479 IN OUT PCONSOLE_STATE_INFO pConInfo)
480 {
481 HWND hListBox = GetDlgItem(hDlg, IDC_LBOX_FONTTYPE);
482 INT Length, nSel;
483 LOGFONTW lf;
484 LPWSTR FaceName;
485 DWORD FontType;
486 LPCWSTR FontGrpBoxLabelTpl = NULL;
487 WCHAR FontGrpBoxLabel[260];
488
489 nSel = (INT)SendMessageW(hListBox, LB_GETCURSEL, 0, 0);
490 if (nSel == LB_ERR) return FALSE;
491
492 /*
493 * This is disabled, because there can be external parameters
494 * that may have changed (e.g. ConInfo->FontWeight, code page, ...)
495 * and that we don't control here, and that need a font refresh.
496 */
497 #if 0
498 /* Check whether the selection has changed */
499 if (nSel == CurrentSelFont)
500 return FALSE;
501 #endif
502
503 Length = (INT)SendMessageW(hListBox, LB_GETTEXTLEN, nSel, 0);
504 if (Length == LB_ERR) return FALSE;
505
506 FaceName = HeapAlloc(GetProcessHeap(),
507 HEAP_ZERO_MEMORY,
508 (Length + 1) * sizeof(WCHAR));
509 if (FaceName == NULL) return FALSE;
510
511 Length = (INT)SendMessageW(hListBox, LB_GETTEXT, nSel, (LPARAM)FaceName);
512 FaceName[Length] = L'\0';
513
514 StringCchCopyW(pConInfo->FaceName, ARRAYSIZE(pConInfo->FaceName), FaceName);
515 DPRINT1("pConInfo->FaceName = '%S'\n", pConInfo->FaceName);
516
517 ZeroMemory(&lf, sizeof(lf));
518 lf.lfCharSet = DEFAULT_CHARSET; // CodePageToCharSet(pConInfo->CodePage);
519 // lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
520 StringCchCopyW(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FaceName);
521
522 /*
523 * Retrieve the read-only font group box label string template,
524 * and set the group box label to the name of the selected font.
525 */
526 Length = LoadStringW(hApplet, IDS_GROUPBOX_FONT_NAME, (LPWSTR)&FontGrpBoxLabelTpl, 0);
527 if (FontGrpBoxLabelTpl && Length > 0)
528 {
529 StringCchCopyNW(FontGrpBoxLabel, ARRAYSIZE(FontGrpBoxLabel), FontGrpBoxLabelTpl, Length);
530 StringCchCatW(FontGrpBoxLabel, ARRAYSIZE(FontGrpBoxLabel), FaceName);
531 SetDlgItemTextW(hDlg, IDC_GROUPBOX_FONT_NAME, FontGrpBoxLabel);
532 }
533
534 HeapFree(GetProcessHeap(), 0, FaceName);
535
536 /*
537 * Reset the font size list, only:
538 * - if we have changed the type of font, or
539 * - if the font type is the same and is RASTER but the font has changed.
540 * Otherwise, if the font type is not RASTER and has not changed,
541 * we always display the TrueType default sizes and we don't need to
542 * recreate the list when we change between different TrueType fonts.
543 */
544 FontType = SendMessageW(hListBox, LB_GETITEMDATA, nSel, 0);
545 if (FontType != LB_ERR)
546 {
547 SizeList->UseRasterOrTTList = (FontType == RASTER_FONTTYPE);
548
549 /* Display the correct font size list (if needed) */
550 if (CurrentFontType != FontType)
551 UpdateFontSizeList(hDlg, SizeList);
552
553 /* Enumerate the available sizes for the selected font */
554 if ((CurrentFontType != FontType) ||
555 (FontType == RASTER_FONTTYPE && CurrentSelFont != nSel))
556 {
557 HDC hDC;
558
559 if (SizeList->UseRasterOrTTList)
560 SendMessageW(SizeList->RasterSizeList.hWndList, LB_RESETCONTENT, 0, 0);
561 else
562 SendMessageW(SizeList->hWndTTSizeList, CB_RESETCONTENT, 0, 0);
563
564 hDC = GetDC(NULL);
565 EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFontSizesProc, (LPARAM)SizeList, 0);
566 ReleaseDC(NULL, hDC);
567
568 /* Re-select the current font size */
569 if (SizeList->UseRasterOrTTList)
570 FontSizeList_SelectFontSize(SizeList, SizeList->CurrentRasterSize);
571 else
572 FontSizeList_SelectFontSize(SizeList, SizeList->CurrentTTSize);
573 }
574 }
575 else
576 {
577 /* We failed, display the raster fonts size list */
578 SizeList->UseRasterOrTTList = TRUE;
579 UpdateFontSizeList(hDlg, SizeList);
580 }
581 CurrentFontType = FontType;
582 CurrentSelFont = nSel;
583
584 FontSizeChange(hDlg, SizeList, pConInfo);
585 return TRUE;
586 }
587
588 static BOOL
589 FontSizeChange(
590 IN HWND hDlg,
591 IN PFONTSIZE_LIST_CTL SizeList,
592 IN OUT PCONSOLE_STATE_INFO pConInfo)
593 {
594 HDC hDC;
595 LONG CharWidth, CharHeight, FontSize;
596 WCHAR szFontSize[100];
597
598 /*
599 * Retrieve the current selected font size.
600 * - If SizeList->UseRasterOrTTList is TRUE, or if it is FALSE but
601 * if SizeList->TTSizePixelUnit is TRUE, then the font size is in pixels;
602 * - If SizeList->TTSizePixelUnit is FALSE, then the font size is in points.
603 */
604 FontSize = FontSizeList_GetSelectedFontSize(SizeList);
605 CharHeight = (SizeList->UseRasterOrTTList ? (LONG)HIWORD(FontSize) : FontSize);
606 CharWidth = (SizeList->UseRasterOrTTList ? (LONG)LOWORD(FontSize) : 0);
607
608 if (hCurrentFont) DeleteObject(hCurrentFont);
609 hCurrentFont = CreateConsoleFont2(CharHeight, CharWidth, pConInfo);
610 if (hCurrentFont == NULL)
611 DPRINT1("FontSizeChange: CreateConsoleFont2 failed\n");
612
613 /* Retrieve the real character size in pixels */
614 hDC = GetDC(NULL);
615 GetFontCellSize(hDC, hCurrentFont, (PUINT)&CharHeight, (PUINT)&CharWidth);
616 ReleaseDC(NULL, hDC);
617
618 /*
619 * Format:
620 * Width = FontSize.X = LOWORD(FontSize);
621 * Height = FontSize.Y = HIWORD(FontSize);
622 */
623 pConInfo->FontSize.X = (SHORT)(SizeList->UseRasterOrTTList ? CharWidth : 0);
624 pConInfo->FontSize.Y = (SHORT)CharHeight;
625
626 DPRINT1("pConInfo->FontSize = (%d x %d) ; (CharWidth x CharHeight) = (%d x %d)\n",
627 pConInfo->FontSize.X, pConInfo->FontSize.Y, CharWidth, CharHeight);
628
629 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_FONT_WINDOW_PREVIEW), NULL, TRUE);
630 InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_SELECT_FONT_PREVIEW), NULL, TRUE);
631
632 StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", CharWidth);
633 SetDlgItemText(hDlg, IDC_FONT_SIZE_X, szFontSize);
634 StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", CharHeight);
635 SetDlgItemText(hDlg, IDC_FONT_SIZE_Y, szFontSize);
636
637 return TRUE;
638 }
639
640
641 INT_PTR
642 CALLBACK
643 FontProc(HWND hDlg,
644 UINT uMsg,
645 WPARAM wParam,
646 LPARAM lParam)
647 {
648 PFONTSIZE_LIST_CTL SizeList;
649
650 SizeList = (PFONTSIZE_LIST_CTL)GetWindowLongPtrW(hDlg, DWLP_USER);
651
652 switch (uMsg)
653 {
654 case WM_INITDIALOG:
655 {
656 HWND hFontList = GetDlgItem(hDlg, IDC_LBOX_FONTTYPE);
657
658 SizeList = (PFONTSIZE_LIST_CTL)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*SizeList));
659 if (!SizeList)
660 {
661 EndDialog(hDlg, 0);
662 return (INT_PTR)TRUE;
663 }
664 SizeList->RasterSizeList.hWndList = GetDlgItem(hDlg, IDC_LBOX_FONTSIZE);
665 SizeList->RasterSizeList.GetCount = RasterSizeList_GetCount;
666 SizeList->RasterSizeList.GetData = RasterSizeList_GetData;
667 SizeList->hWndTTSizeList = GetDlgItem(hDlg, IDC_CBOX_FONTSIZE);
668 SizeList->bIsTTSizeDirty = FALSE;
669 SetWindowLongPtrW(hDlg, DWLP_USER, (LONG_PTR)SizeList);
670
671 /* By default show the raster font size list */
672 SizeList->UseRasterOrTTList = TRUE;
673
674 /* By default show the font sizes in pixel units */
675 CheckRadioButton(hDlg, IDC_RADIO_PIXEL_UNIT, IDC_RADIO_POINT_UNIT, IDC_RADIO_PIXEL_UNIT);
676 SizeList->TTSizePixelUnit = TRUE;
677
678 UpdateFontSizeList(hDlg, SizeList);
679
680 /* Initialize the font list */
681 FaceNameList_Initialize(hFontList, ConInfo->CodePage);
682
683 /* Select the current font */
684 DPRINT1("ConInfo->FaceName = '%S'\n", ConInfo->FaceName);
685 FaceNameList_SelectFaceName(hFontList, ConInfo->FaceName);
686
687 if (ConInfo->FontWeight >= FW_BOLD)
688 CheckDlgButton(hDlg, IDC_CHECK_BOLD_FONTS, BST_CHECKED);
689 else
690 CheckDlgButton(hDlg, IDC_CHECK_BOLD_FONTS, BST_UNCHECKED);
691
692 /* Select the current font size */
693 /*
694 * Format:
695 * Width = FontSize.X = LOWORD(FontSize);
696 * Height = FontSize.Y = HIWORD(FontSize);
697 */
698 SizeList->CurrentRasterSize = MAKELONG(ConInfo->FontSize.X, ConInfo->FontSize.Y);
699 SizeList->CurrentTTSize = ConInfo->FontSize.Y;
700 // FontSizeList_SelectFontSize(SizeList, SizeList->CurrentRasterSize);
701
702 /* Refresh everything */
703 FontTypeChange(hDlg, SizeList, ConInfo);
704
705 return TRUE;
706 }
707
708 case WM_DESTROY:
709 {
710 if (SizeList)
711 HeapFree(GetProcessHeap(), 0, SizeList);
712 return (INT_PTR)TRUE;
713 }
714
715 case WM_DRAWITEM:
716 {
717 LPDRAWITEMSTRUCT drawItem = (LPDRAWITEMSTRUCT)lParam;
718
719 if (drawItem->CtlID == IDC_STATIC_SELECT_FONT_PREVIEW)
720 PaintText(drawItem, ConInfo, Screen);
721
722 return TRUE;
723 }
724
725 case WM_DISPLAYCHANGE:
726 {
727 /* Retransmit to the preview window */
728 SendDlgItemMessageW(hDlg, IDC_STATIC_FONT_WINDOW_PREVIEW,
729 WM_DISPLAYCHANGE, wParam, lParam);
730 break;
731 }
732
733 case WM_NOTIFY:
734 {
735 switch (((LPNMHDR)lParam)->code)
736 {
737 case PSN_APPLY:
738 {
739 ApplyConsoleInfo(hDlg);
740 return TRUE;
741 }
742 }
743
744 break;
745 }
746
747 case WM_COMMAND:
748 {
749 if (HIWORD(wParam) == LBN_SELCHANGE /* || CBN_SELCHANGE */)
750 {
751 switch (LOWORD(wParam))
752 {
753 case IDC_LBOX_FONTTYPE:
754 {
755 /* Change the property sheet state only if the font has really changed */
756 if (FontTypeChange(hDlg, SizeList, ConInfo))
757 PropSheet_Changed(GetParent(hDlg), hDlg);
758 break;
759 }
760
761 case IDC_LBOX_FONTSIZE:
762 case IDC_CBOX_FONTSIZE:
763 {
764 /* Change the property sheet state only if the font has really changed */
765 if (FontSizeChange(hDlg, SizeList, ConInfo))
766 PropSheet_Changed(GetParent(hDlg), hDlg);
767 break;
768 }
769 }
770 }
771 /* NOTE: CBN_EDITUPDATE is sent first, and is followed by CBN_EDITCHANGE */
772 else if (HIWORD(wParam) == CBN_EDITUPDATE && LOWORD(wParam) == IDC_CBOX_FONTSIZE)
773 {
774 ULONG FontSize;
775 PWCHAR pszNext = NULL;
776 WCHAR szFontSize[100];
777 WCHAR szMessage[260];
778
779 GetWindowTextW(SizeList->hWndTTSizeList, szFontSize, ARRAYSIZE(szFontSize));
780 FontSize = wcstoul(szFontSize, &pszNext, 10);
781 if (!*pszNext)
782 {
783 // FIXME: Localize!
784 StringCchPrintfW(szMessage, ARRAYSIZE(szMessage), L"\"%s\" is not a valid font size.", szFontSize);
785 MessageBoxW(hDlg, szMessage, L"Error", MB_ICONINFORMATION | MB_OK);
786 FontSizeList_SelectFontSize(SizeList, FontSize);
787 }
788 /**/SizeList->bIsTTSizeDirty = TRUE;/**/
789 }
790 else if (HIWORD(wParam) == CBN_KILLFOCUS && LOWORD(wParam) == IDC_CBOX_FONTSIZE)
791 {
792 /* Change the property sheet state only if the font has really changed */
793 if (FontSizeChange(hDlg, SizeList, ConInfo))
794 PropSheet_Changed(GetParent(hDlg), hDlg);
795 }
796 else
797 if (HIWORD(wParam) == BN_CLICKED)
798 {
799 switch (LOWORD(wParam))
800 {
801 case IDC_CHECK_BOLD_FONTS:
802 {
803 if (IsDlgButtonChecked(hDlg, IDC_CHECK_BOLD_FONTS) == BST_CHECKED)
804 ConInfo->FontWeight = FW_BOLD;
805 else
806 ConInfo->FontWeight = FW_NORMAL;
807
808 FontTypeChange(hDlg, SizeList, ConInfo);
809 PropSheet_Changed(GetParent(hDlg), hDlg);
810 break;
811 }
812
813 case IDC_RADIO_PIXEL_UNIT:
814 case IDC_RADIO_POINT_UNIT:
815 {
816 SizeList->TTSizePixelUnit = (LOWORD(wParam) == IDC_RADIO_PIXEL_UNIT);
817
818 /* The call is valid only for TrueType fonts */
819 if (CurrentFontType != TRUETYPE_FONTTYPE)
820 break;
821
822 /* Change the property sheet state only if the font has really changed */
823 if (FontSizeChange(hDlg, SizeList, ConInfo))
824 PropSheet_Changed(GetParent(hDlg), hDlg);
825 break;
826 }
827 }
828 }
829
830 break;
831 }
832
833 default:
834 break;
835 }
836
837 return FALSE;
838 }