1 /* NetHack 3.6 mhfont.c $NHDT-Date: 1432512812 2015/05/25 00:13:32 $ $NHDT-Branch: master $:$NHDT-Revision: 1.23 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* font management and such */
11 /* font table - 64 fonts ought to be enough */
14 static cached_font font_table[MAXFONTS];
15 static int font_table_size = 0;
17 #define NHFONT_CODE(win, attr) (((attr & 0xFF) << 8) | (win_type & 0xFF))
19 static void __cdecl font_table_cleanup(void);
22 mswin_create_splashfont(HWND hWnd)
24 HDC hdc = GetDC(hWnd);
25 double scale = win10_monitor_scale(hWnd);
27 ZeroMemory(&lgfnt, sizeof(lgfnt));
28 lgfnt.lfHeight = -(int)(80 * scale); // height of font
29 lgfnt.lfWidth = 0; // average character width
30 lgfnt.lfEscapement = 0; // angle of escapement
31 lgfnt.lfOrientation = 0; // base-line orientation angle
32 lgfnt.lfWeight = FW_BOLD; // font weight
33 lgfnt.lfItalic = FALSE; // italic attribute option
34 lgfnt.lfUnderline = FALSE; // underline attribute option
35 lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
36 lgfnt.lfCharSet = ANSI_CHARSET; // character set identifier
37 lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
38 lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
39 lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
40 lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
41 NH_A2W("Times New Roman", lgfnt.lfFaceName, LF_FACESIZE);
42 HFONT font = CreateFontIndirect(&lgfnt);
49 mswin_font_supports_unicode(HFONT hFont)
51 for (int i = 0; i < font_table_size; i++)
52 if (font_table[i].hFont == hFont)
53 return font_table[i].supportsUnicode;
58 /* create font based on window type, charater attributes and
59 window device context */
61 mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
67 static BOOL once = FALSE;
71 atexit(font_table_cleanup);
74 ZeroMemory(&lgfnt, sizeof(lgfnt));
76 /* try find font in the table */
77 for (font_index = 0; font_index < font_table_size; font_index++)
78 if (NHFONT_CODE(win_type, attr) == font_table[font_index].code)
81 if (!replace && font_index < font_table_size)
82 return &font_table[font_index];
86 font_size = (attr == ATR_BOLD) ? iflags.wc_fontsiz_status + 1
87 : iflags.wc_fontsiz_status;
88 lgfnt.lfHeight = -font_size * GetDeviceCaps(hdc, LOGPIXELSY)
89 / 72; // height of font
90 lgfnt.lfWidth = 0; // average character width
91 lgfnt.lfEscapement = 0; // angle of escapement
92 lgfnt.lfOrientation = 0; // base-line orientation angle
94 (attr == ATR_BOLD) ? FW_BOLD : FW_NORMAL; // font weight
95 lgfnt.lfItalic = FALSE; // italic attribute option
96 lgfnt.lfUnderline = (attr == ATR_ULINE); // underline attribute option
97 lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
98 lgfnt.lfCharSet = mswin_charset(); // character set identifier
99 lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
100 lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
101 lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
102 if (iflags.wc_font_status && *iflags.wc_font_status) {
103 lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
104 NH_A2W(iflags.wc_font_status, lgfnt.lfFaceName, LF_FACESIZE);
106 lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
111 lgfnt.lfHeight = -iflags.wc_fontsiz_menu
112 * GetDeviceCaps(hdc, LOGPIXELSY)
113 / 72; // height of font
114 lgfnt.lfWidth = 0; // average character width
115 lgfnt.lfEscapement = 0; // angle of escapement
116 lgfnt.lfOrientation = 0; // base-line orientation angle
117 lgfnt.lfWeight = (attr == ATR_BOLD || attr == ATR_INVERSE)
119 : FW_NORMAL; // font weight
121 (attr == ATR_BLINK) ? TRUE : FALSE; // italic attribute option
123 (attr == ATR_ULINE) ? TRUE : FALSE; // underline attribute option
124 lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
125 lgfnt.lfCharSet = mswin_charset(); // character set identifier
126 lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
127 lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
128 lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
129 if (iflags.wc_font_menu && *iflags.wc_font_menu) {
130 lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
131 NH_A2W(iflags.wc_font_menu, lgfnt.lfFaceName, LF_FACESIZE);
133 lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
138 font_size = (attr == ATR_INVERSE) ? iflags.wc_fontsiz_message + 1
139 : iflags.wc_fontsiz_message;
140 lgfnt.lfHeight = -font_size * GetDeviceCaps(hdc, LOGPIXELSY)
141 / 72; // height of font
142 lgfnt.lfWidth = 0; // average character width
143 lgfnt.lfEscapement = 0; // angle of escapement
144 lgfnt.lfOrientation = 0; // base-line orientation angle
145 lgfnt.lfWeight = (attr == ATR_BOLD || attr == ATR_INVERSE)
147 : FW_NORMAL; // font weight
149 (attr == ATR_BLINK) ? TRUE : FALSE; // italic attribute option
151 (attr == ATR_ULINE) ? TRUE : FALSE; // underline attribute option
152 lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
153 lgfnt.lfCharSet = mswin_charset(); // character set identifier
154 lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
155 lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
156 lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
157 if (iflags.wc_font_message && *iflags.wc_font_message) {
158 lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
159 NH_A2W(iflags.wc_font_message, lgfnt.lfFaceName, LF_FACESIZE);
161 lgfnt.lfPitchAndFamily = VARIABLE_PITCH; // pitch and family
166 lgfnt.lfHeight = -iflags.wc_fontsiz_text
167 * GetDeviceCaps(hdc, LOGPIXELSY)
168 / 72; // height of font
169 lgfnt.lfWidth = 0; // average character width
170 lgfnt.lfEscapement = 0; // angle of escapement
171 lgfnt.lfOrientation = 0; // base-line orientation angle
172 lgfnt.lfWeight = (attr == ATR_BOLD || attr == ATR_INVERSE)
174 : FW_NORMAL; // font weight
176 (attr == ATR_BLINK) ? TRUE : FALSE; // italic attribute option
178 (attr == ATR_ULINE) ? TRUE : FALSE; // underline attribute option
179 lgfnt.lfStrikeOut = FALSE; // strikeout attribute option
180 lgfnt.lfCharSet = mswin_charset(); // character set identifier
181 lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
182 lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
183 lgfnt.lfQuality = DEFAULT_QUALITY; // output quality
184 if (iflags.wc_font_text && *iflags.wc_font_text) {
185 lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
186 NH_A2W(iflags.wc_font_text, lgfnt.lfFaceName, LF_FACESIZE);
188 lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
193 fnt = CreateFontIndirect(&lgfnt);
195 /* add font to the table */
196 if (font_index == font_table_size) {
197 if (font_table_size >= MAXFONTS)
198 panic("font table overflow!");
201 DeleteObject(font_table[font_index].hFont);
204 font_table[font_index].code = NHFONT_CODE(win_type, attr);
205 font_table[font_index].hFont = fnt;
206 font_table[font_index].supportsUnicode = winos_font_support_cp437(fnt);
208 HGDIOBJ savedFont = SelectObject(hdc, fnt);
210 GetTextExtentPoint32A(hdc, " ", 1, &size);
211 SelectObject(hdc, savedFont);
213 font_table[font_index].height = size.cy;
214 font_table[font_index].width = size.cx;
216 return &font_table[font_index];
223 if (SYMHANDLING(H_IBM))
224 if (TranslateCharsetInfo((DWORD *) (uintptr_t) GetOEMCP(), &cis, TCI_SRCCODEPAGE))
225 return cis.ciCharset;
228 else if (TranslateCharsetInfo((DWORD *) (uintptr_t) GetACP(), &cis, TCI_SRCCODEPAGE))
229 return cis.ciCharset;
234 void __cdecl font_table_cleanup(void)
237 for (i = 0; i < font_table_size; i++) {
238 DeleteObject(font_table[i].hFont);