📄 font.c
字号:
/* font.c
* Copyright (c) 1997 David Cole
*
* Manage font dialog and font related .INI file settings.
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "platform.h"
#include "resource.h"
#include "utils.h"
#include "font.h"
#include "term.h"
#include "dtelnet.h"
#include "dialog.h"
static BOOL haveDialog; /* have we created the Font dialog? */
typedef struct FontData {
BOOL fMore; /* Display more charsets (not only DEFAULT/ANSI/OEM) */
} FontData;
static FontData fontData = {
FALSE /* fMore */
};
static FontDesc fd[3] = {
{"", 0, 0, 0}, /* DT_FONT_REQUESTED */
{"", 0, 0, 0}, /* DT_FONT_REAL */
{"", 0, 0, 0} /* DT_FONT_OEM */
};
/* Enumerate all of the font sizes we will offer
*/
static int validSizes[] = {
8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28
};
/* Return a FontDesc */
FontDesc *fontGet (int which)
{
if (which<DT_FONT_REQUESTED || which>DT_FONT_OEM) return NULL;
else return &fd[which];
}
/* Create fonts from "Requested" FontDesc,
return HFONTs, TEXTMETRIC and fill FontDesc REAL and OEM */
void fontCreate (HWND hwnd, TEXTMETRIC *ptm, HFONT *hfmain, HFONT *hfaux)
{
HFONT hfont, hfontOld;
HDC dc;
TEXTMETRIC tm;
dc = GetDC(hwnd);
hfont = CreateFont(-fd[DT_FONT_REQUESTED].fdSize, 0, 0, 0,
FW_DONTCARE, 0, 0, 0,
fd[DT_FONT_REQUESTED].fdCharSet, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
FIXED_PITCH, fd[DT_FONT_REQUESTED].fdName);
if (hfont!=NULL) {
hfontOld = (HFONT)SelectObject(dc, hfont);
GetTextFace(dc, sizeof(fd[DT_FONT_REAL].fdName), fd[DT_FONT_REAL].fdName);
GetTextMetrics(dc, ptm);
fd[DT_FONT_REAL].fdCharSet = ptm->tmCharSet;
fd[DT_FONT_REAL].fdSize = ptm->tmHeight - ptm->tmExternalLeading
- ptm->tmInternalLeading;
fd[DT_FONT_REAL].fdWidth = ptm->tmMaxCharWidth;
SelectObject(dc, hfontOld);
}
*hfmain = hfont;
hfont = CreateFont(-fd[DT_FONT_REAL].fdSize,
/* Was: fd[DT_FONT_REAL].fdWidth, */
ptm->tmAveCharWidth,
0, 0, FW_DONTCARE, 0, 0, 0,
OEM_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
FIXED_PITCH, fd[DT_FONT_REAL].fdName);
if (hfont!=NULL) {
hfontOld = (HFONT)SelectObject(dc, hfont);
GetTextFace(dc, sizeof(fd[DT_FONT_OEM].fdName), fd[DT_FONT_OEM].fdName);
GetTextMetrics(dc, &tm);
fd[DT_FONT_OEM].fdCharSet = tm.tmCharSet;
fd[DT_FONT_OEM].fdSize = tm.tmHeight - tm.tmExternalLeading
- tm.tmInternalLeading;
fd[DT_FONT_OEM].fdWidth = tm.tmMaxCharWidth;
SelectObject(dc, hfontOld);
}
*hfaux = hfont;
ReleaseDC(hwnd, dc);
}
/* Return the name of the font being used in the terminal window
*/
static void fontGetDefault(void)
{
HDC dc; /* get display context of screen */
TEXTMETRIC tm; /* get size of OEM Fixed Font */
/* We have not selected a font yet, scan the font list and look
* for the best font. On win31, this will be oemXXXX, on win95,
* it will be Terminal.
*/
dc = CreateDC("DISPLAY", NULL, NULL, NULL);
if (dc == NULL) {
telnetFatal("Cannot get DISPLAY dc");
return;
}
SelectObject(dc, GetStockObject(OEM_FIXED_FONT));
GetTextMetrics(dc, &tm);
fd[DT_FONT_REQUESTED].fdSize = tm.tmHeight;
fd[DT_FONT_REQUESTED].fdCharSet = tm.tmCharSet;
GetTextFace(dc, sizeof(fd[DT_FONT_REQUESTED].fdName),
fd[DT_FONT_REQUESTED].fdName);
DeleteDC(dc);
}
/* Called once for every font on the system. Add each Fixed Pitch
* font found to the font name listbox.
*/
int CALLBACK enumFontProc(LOGFONT* lf, TEXTMETRIC* tm,
int fontType, LPARAM wnd)
{
if ((lf->lfPitchAndFamily & 0x3) == FIXED_PITCH)
SendMessage((HWND)wnd, LB_ADDSTRING, 0, (LPARAM)lf->lfFaceName);
return 1;
}
/* Add all Fixed Pitch fonts to the font name listbox.
*/
static void fontListNames(HWND wnd)
{
HDC dc; /* display context for screen */
LRESULT idx; /* find index of font currently being used */
/* Load up the listbox with all of the font names
*/
SendMessage(wnd, LB_RESETCONTENT, 0, 0);
dc = CreateDC("DISPLAY", NULL, NULL, NULL);
if (dc == NULL) {
telnetFatal("Cannot get DISPLAY dc");
return;
}
EnumFontFamilies(dc, NULL, (FONTENUMPROC)enumFontProc, (LPARAM)wnd);
DeleteDC(dc);
/* Select the font that is currently being used
*/
if (fd[DT_FONT_REQUESTED].fdName[0] != '\0') {
idx = SendMessage(wnd, LB_FINDSTRINGEXACT, 0,
(LPARAM)(LPCSTR)fd[DT_FONT_REQUESTED].fdName);
if (idx == LB_ERR)
idx = 0;
}
SendMessage(wnd, LB_SETCURSEL, (WPARAM)idx, 0);
}
/* Select the current font size
*/
static void fontSizeSelect (HWND wnd, int fs)
{
char str[20];
LRESULT idx;
sprintf(str, "%2d", fs);
idx = SendMessage(wnd, CB_FINDSTRINGEXACT, 0, (LPARAM)str);
if (idx != LB_ERR) {
SendMessage(wnd, CB_SETCURSEL, (WPARAM)idx, 0);
} else {
SetWindowText (wnd, str);
}
}
/* Initialise the list of font sizes that we allow
*/
static void fontListSizes(HWND wnd)
{
int i;
char str [20];
/* Load up the listbox with all of the font names
*/
SendMessage(wnd, LB_RESETCONTENT, 0, 0);
for (i = 0; i < numElem(validSizes); i++) {
sprintf(str, "%2d", validSizes[i]);
SendMessage(wnd, CB_ADDSTRING, 0, (LPARAM)str);
}
fontSizeSelect (wnd, fd[DT_FONT_REQUESTED].fdSize);
}
static struct CharacterSet fontCharacterSets [] = {
{"default", DEFAULT_CHARSET},
{"ANSI", ANSI_CHARSET},
{"OEM", OEM_CHARSET}
};
#define NfontCharacterSets (sizeof(fontCharacterSets)\
/sizeof(fontCharacterSets[0]))
static struct CharacterSet fontMoreCharacterSets [] = {
{"default", DEFAULT_CHARSET},
{"ANSI", ANSI_CHARSET},
{"OEM", OEM_CHARSET},
{"SYMBOL", SYMBOL_CHARSET},
{"SHIFTJIS", SHIFTJIS_CHARSET},
{"HANGEUL", HANGEUL_CHARSET},
{"GB2312", GB2312_CHARSET},
{"CHINESEBIG5", CHINESEBIG5_CHARSET},
{"JOHAB", JOHAB_CHARSET},
{"HEBREW", HEBREW_CHARSET},
{"ARABIC", ARABIC_CHARSET},
{"GREEK", GREEK_CHARSET},
{"TURKISH", TURKISH_CHARSET},
{"THAI", THAI_CHARSET},
{"EASTEUROPE", EASTEUROPE_CHARSET},
{"RUSSIAN", RUSSIAN_CHARSET},
{"MAC", MAC_CHARSET},
{"BALTIC", BALTIC_CHARSET}
};
#define NfontMoreCharacterSets (sizeof(fontMoreCharacterSets)\
/sizeof(fontMoreCharacterSets[0]))
static void fontListCharSets(HWND hwnd, BOOL fMore)
{
int i, ncs;
CharacterSet *csp;
if (fMore) {
csp = fontMoreCharacterSets;
ncs = NfontMoreCharacterSets;
} else {
csp = fontCharacterSets;
ncs = NfontCharacterSets;
}
SendMessage(hwnd, LB_RESETCONTENT, 0, 0);
for (i=0; i<ncs; ++i) {
SendMessage(hwnd, LB_ADDSTRING, 0,
(LPARAM)csp[i].csName);
if (csp[i].csCode==fd[DT_FONT_REQUESTED].fdCharSet) {
SendMessage(hwnd, LB_SETCURSEL, (WPARAM)i, 0L);
}
}
}
/* Save the currently selected font name to <fontName>
*/
static void fontGetNameList(HWND wnd)
{
LRESULT idx = SendMessage(wnd, LB_GETCURSEL, 0, 0L);
if (idx == LB_ERR)
return;
SendMessage(wnd, LB_GETTEXT, (WPARAM)idx, (LPARAM)(LPCSTR)fd[DT_FONT_REQUESTED].fdName);
}
/* Save the currently selected font size to <fontSize>
* return -1/0/1 = error/OK/not changed
*/
static int fontGetSizeList(HWND wnd)
{
LRESULT idx;
int fs;
idx = SendMessage(wnd, CB_GETCURSEL, 0, 0L);
if (idx == LB_ERR) return EOF;
fs = validSizes[(int)idx];
if (fs == fd[DT_FONT_REQUESTED].fdSize) return 1;
else {
fd[DT_FONT_REQUESTED].fdSize = fs;
return 0;
}
}
/* Save the currently entered font size to <fontSize>
* return -1/0/1 = error/OK/not changed
*/
static int fontGetSizeEdit (HWND wnd)
{
char buff [16];
int fs;
GetWindowText (wnd, buff, sizeof (buff));
fs = atoi (buff);
if (fs < 4 || fs > 100) return EOF;
if (fs == fd[DT_FONT_REQUESTED].fdSize) return 1;
else {
fd[DT_FONT_REQUESTED].fdSize = fs;
fontSizeSelect (wnd, fs);
return 0;
}
}
/* Save the currently selected character set to <fontCharSet>
*/
static void fontGetCharSetList(HWND wnd)
{
LRESULT idx = SendMessage(wnd, LB_GETCURSEL, 0, 0L);
if (idx < 0)
return;
fd[DT_FONT_REQUESTED].fdCharSet = fontMoreCharacterSets[(int)idx].csCode;
}
static struct CharacterSet *fontFindCharset (int csCode)
{
int i, found;
for (i=0, found=-1; found==-1 && i<NfontMoreCharacterSets; ++i) {
if (csCode==fontMoreCharacterSets[i].csCode) found = i;
}
if (found==-1) return NULL;
else return &fontMoreCharacterSets[found];
}
static void fontSetDlgFontName (HWND hdlg, int id, int csCode)
{
struct CharacterSet *p;
char tmp [32], *s;
p = fontFindCharset (csCode);
if (p) {
s = p->csName;
} else {
s = tmp;
sprintf (s, "charset #%d", fd[DT_FONT_REAL].fdCharSet);
}
SetDlgItemText (hdlg, id, s);
}
static void fontSetStaticFields (HWND hdlg)
{
char tmp[256];
int n;
SetDlgItemText (hdlg, IDC_R_FONT_NAME, fd[DT_FONT_REAL].fdName);
sprintf (tmp, "%d x %d", fd[DT_FONT_REAL].fdSize, fd[DT_FONT_REAL].fdWidth);
SetDlgItemText (hdlg, IDC_R_FONT_SIZE, tmp);
fontSetDlgFontName (hdlg, IDC_R_FONT_CHARSET, fd[DT_FONT_REAL].fdCharSet);
SetDlgItemText (hdlg, IDC_O_FONT_NAME, fd[DT_FONT_OEM].fdName);
sprintf (tmp, "%d x %d", fd[DT_FONT_OEM].fdSize, fd[DT_FONT_OEM].fdWidth);
SetDlgItemText (hdlg, IDC_O_FONT_SIZE, tmp);
fontSetDlgFontName (hdlg, IDC_O_FONT_CHARSET, fd[DT_FONT_OEM].fdCharSet);
{
#ifdef WIN32
static const char sAnsi [] = "System's default ANSI charset is";
static const char sOem [] = "System's OEM charset is";
n = GetACP ();
sprintf (tmp, n ? "%s win-%d" : "%s not known", sAnsi, n);
SetDlgItemText (hdlg, IDC_FONT_ACP, tmp);
n = GetOEMCP ();
sprintf (tmp, n ? "%s CP%d" : "%s not known", sOem, n);
SetDlgItemText (hdlg, IDC_FONT_OEMCP, tmp);
#else
static const char sKB [] = "Keyboard codepage is";
n = GetKBCodePage ();
sprintf (tmp, n ? "%s CP%d" : "%s not known", sKB, n);
SetDlgItemText (hdlg, IDC_FONT_ACP, tmp);
SetDlgItemText (hdlg, IDC_FONT_OEMCP, "");
#endif
}
}
/* Dialog procedure for the Font dialog
*/
BOOL CALLBACK fontDlgProc(HWND dlg,
unsigned message, WPARAM wparam, LONG lparam)
{
int nChecked;
int rc;
switch (message) {
case WM_INITDIALOG:
/* Flag that we have created the dialog, and register the
* dialog window handle with the dialog handling code.
*/
haveDialog = TRUE;
dialogRegister(dlg);
/* Initialise the font name and font size listboxes.
*/
fontListNames(GetDlgItem(dlg, IDC_FONT_NAME));
fontListSizes(GetDlgItem(dlg, IDC_FONT_SIZE));
fontListCharSets(GetDlgItem(dlg, IDC_FONT_CHARSET),
fontData.fMore);
CheckDlgButton(dlg, IDC_FONT_MORECS, fontData.fMore);
fontSetStaticFields(dlg);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wparam)) {
case IDC_FONT_NAME:
/* Every time a new font name is selected, redisplay the
* terminal using that font.
*/
fontGetNameList(GetDlgItem(dlg, IDC_FONT_NAME));
termSetFont();
fontSetStaticFields(dlg);
return TRUE;
case IDC_FONT_SIZE:
/* Every time a new font size is selected, redisplay the
* terminal using the new size.
*/
#ifdef WIN32
if (HIWORD(wparam) == CBN_SELCHANGE) {
#else
if (HIWORD(lparam) == CBN_SELCHANGE) {
#endif
rc = fontGetSizeList (GetDlgItem (dlg, IDC_FONT_SIZE));
#ifdef WIN32
} else if (HIWORD(wparam) == CBN_KILLFOCUS) {
#else
} else if (HIWORD(lparam) == CBN_KILLFOCUS) {
#endif
rc = fontGetSizeEdit (GetDlgItem (dlg, IDC_FONT_SIZE));
} else {
return TRUE;
}
if (rc==0) {
termSetFont();
fontSetStaticFields(dlg);
}
return TRUE;
case IDC_FONT_CHARSET:
fontGetCharSetList(GetDlgItem(dlg, IDC_FONT_CHARSET));
termSetFont();
fontSetStaticFields(dlg);
return TRUE;
case IDC_FONT_MORECS:
nChecked = IsDlgButtonChecked(dlg, IDC_FONT_MORECS);
fontData.fMore = (BOOL)nChecked;
fontListCharSets(GetDlgItem(dlg, IDC_FONT_CHARSET),
fontData.fMore);
return TRUE;
case IDOK:
case IDCANCEL:
/* Destroy the dialog and unregister the dialog handle
* with the dialog handling code.
*/
DestroyWindow(dlg);
dialogUnRegister(dlg);
haveDialog = FALSE;
return TRUE;
}
break;
}
return FALSE;
}
/* Called when the user invokes the Font dialog
*/
void showFontDialog(HINSTANCE instance, HWND wnd)
{
if (!haveDialog)
CreateDialog(instance, MAKEINTRESOURCE(IDD_FONT_DIALOG),
wnd, fontDlgProc);
}
/* Load the font settings from the .INI file.
*/
void fontGetProfile()
{
LPCSTR fname;
fontGetDefault();
fname = telnetIniFile();
GetPrivateProfileString("Font", "Name", "",
fd[DT_FONT_REQUESTED].fdName, sizeof(fd[DT_FONT_REQUESTED].fdName), fname);
fd[DT_FONT_REQUESTED].fdSize = GetPrivateProfileInt("Font", "Size", fd[DT_FONT_REQUESTED].fdSize, fname);
fd[DT_FONT_REQUESTED].fdCharSet = (unsigned char)GetPrivateProfileInt("Font", "CharSet",
fd[DT_FONT_REQUESTED].fdCharSet, fname);
fontData.fMore = (BOOL)GetPrivateProfileInt("Font", "MoreCharSet", 0, fname);
}
/* Save the font settings to the .INI file.
*/
void fontSaveProfile()
{
LPCSTR fname;
char str[20];
fname = telnetIniFile();
WritePrivateProfileString("Font", "Name", fd[DT_FONT_REQUESTED].fdName, fname);
sprintf(str, "%d", fd[DT_FONT_REQUESTED].fdSize);
WritePrivateProfileString("Font", "Size", str, fname);
sprintf(str, "%d", fd[DT_FONT_REQUESTED].fdCharSet);
WritePrivateProfileString("Font", "CharSet", str, fname);
sprintf(str, "%d", (int)fontData.fMore);
WritePrivateProfileString("Font", "MoreCharSet", str, fname);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -