⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 font.c

📁 dtelent是开源的开发项目
💻 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 + -