OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / win / win32 / mhfont.c
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. */
4
5 /* font management and such */
6
7 #include "mhfont.h"
8
9 #define MAXFONTS 64
10
11 /* font table - 64 fonts ought to be enough */
12 static struct font_table_entry {
13     int code;
14     HFONT hFont;
15 } font_table[MAXFONTS];
16 static int font_table_size = 0;
17 HFONT version_splash_font;
18
19 #define NHFONT_CODE(win, attr) (((attr & 0xFF) << 8) | (win_type & 0xFF))
20
21 static void __cdecl font_table_cleanup(void);
22
23 void
24 mswin_init_splashfonts(HWND hWnd)
25 {
26     HDC hdc = GetDC(hWnd);
27     LOGFONT lgfnt;
28     ZeroMemory(&lgfnt, sizeof(lgfnt));
29     lgfnt.lfHeight = -80;                      // height of font
30     lgfnt.lfWidth = 0;                         // average character width
31     lgfnt.lfEscapement = 0;                    // angle of escapement
32     lgfnt.lfOrientation = 0;                   // base-line orientation angle
33     lgfnt.lfWeight = FW_BOLD;                  // font weight
34     lgfnt.lfItalic = FALSE;                    // italic attribute option
35     lgfnt.lfUnderline = FALSE;                 // underline attribute option
36     lgfnt.lfStrikeOut = FALSE;                 // strikeout attribute option
37     lgfnt.lfCharSet = ANSI_CHARSET;            // character set identifier
38     lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS; // output precision
39     lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
40     lgfnt.lfQuality = DEFAULT_QUALITY;           // output quality
41     lgfnt.lfPitchAndFamily = DEFAULT_PITCH;      // pitch and family
42     NH_A2W("Times New Roman", lgfnt.lfFaceName, LF_FACESIZE);
43     version_splash_font = CreateFontIndirect(&lgfnt);
44     ReleaseDC(hWnd, hdc);
45 }
46
47 void
48 mswin_destroy_splashfonts()
49 {
50     DeleteObject(version_splash_font);
51 }
52
53 /* create font based on window type, charater attributes and
54    window device context */
55 HGDIOBJ
56 mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace)
57 {
58     HFONT fnt = NULL;
59     LOGFONT lgfnt;
60     int font_size;
61     int font_index;
62     static BOOL once = FALSE;
63
64     if (!once) {
65         once = TRUE;
66         atexit(font_table_cleanup);
67     }
68
69     ZeroMemory(&lgfnt, sizeof(lgfnt));
70
71     /* try find font in the table */
72     for (font_index = 0; font_index < font_table_size; font_index++)
73         if (NHFONT_CODE(win_type, attr) == font_table[font_index].code)
74             break;
75
76     if (!replace && font_index < font_table_size)
77         return font_table[font_index].hFont;
78
79     switch (win_type) {
80     case NHW_STATUS:
81         font_size = (attr == ATR_BOLD) ? iflags.wc_fontsiz_status + 1
82                                        : iflags.wc_fontsiz_status;
83         lgfnt.lfHeight = -font_size * GetDeviceCaps(hdc, LOGPIXELSY)
84                          / 72;   // height of font
85         lgfnt.lfWidth = 0;       // average character width
86         lgfnt.lfEscapement = 0;  // angle of escapement
87         lgfnt.lfOrientation = 0; // base-line orientation angle
88         lgfnt.lfWeight =
89             (attr == ATR_BOLD) ? FW_BOLD : FW_NORMAL; // font weight
90         lgfnt.lfItalic = FALSE;            // italic attribute option
91         lgfnt.lfUnderline = FALSE;         // underline attribute option
92         lgfnt.lfStrikeOut = FALSE;         // strikeout attribute option
93         lgfnt.lfCharSet = mswin_charset(); // character set identifier
94         lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS;   // output precision
95         lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
96         lgfnt.lfQuality = DEFAULT_QUALITY;           // output quality
97         if (iflags.wc_font_status && *iflags.wc_font_status) {
98             lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
99             NH_A2W(iflags.wc_font_status, lgfnt.lfFaceName, LF_FACESIZE);
100         } else {
101             lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
102         }
103         break;
104
105     case NHW_MENU:
106         lgfnt.lfHeight = -iflags.wc_fontsiz_menu
107                          * GetDeviceCaps(hdc, LOGPIXELSY)
108                          / 72;   // height of font
109         lgfnt.lfWidth = 0;       // average character width
110         lgfnt.lfEscapement = 0;  // angle of escapement
111         lgfnt.lfOrientation = 0; // base-line orientation angle
112         lgfnt.lfWeight = (attr == ATR_BOLD || attr == ATR_INVERSE)
113                              ? FW_BOLD
114                              : FW_NORMAL; // font weight
115         lgfnt.lfItalic =
116             (attr == ATR_BLINK) ? TRUE : FALSE; // italic attribute option
117         lgfnt.lfUnderline =
118             (attr == ATR_ULINE) ? TRUE : FALSE; // underline attribute option
119         lgfnt.lfStrikeOut = FALSE;              // strikeout attribute option
120         lgfnt.lfCharSet = mswin_charset();      // character set identifier
121         lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS;   // output precision
122         lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
123         lgfnt.lfQuality = DEFAULT_QUALITY;           // output quality
124         if (iflags.wc_font_menu && *iflags.wc_font_menu) {
125             lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
126             NH_A2W(iflags.wc_font_menu, lgfnt.lfFaceName, LF_FACESIZE);
127         } else {
128             lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
129         }
130         break;
131
132     case NHW_MESSAGE:
133         font_size = (attr == ATR_INVERSE) ? iflags.wc_fontsiz_message + 1
134                                           : iflags.wc_fontsiz_message;
135         lgfnt.lfHeight = -font_size * GetDeviceCaps(hdc, LOGPIXELSY)
136                          / 72;   // height of font
137         lgfnt.lfWidth = 0;       // average character width
138         lgfnt.lfEscapement = 0;  // angle of escapement
139         lgfnt.lfOrientation = 0; // base-line orientation angle
140         lgfnt.lfWeight = (attr == ATR_BOLD || attr == ATR_INVERSE)
141                              ? FW_BOLD
142                              : FW_NORMAL; // font weight
143         lgfnt.lfItalic =
144             (attr == ATR_BLINK) ? TRUE : FALSE; // italic attribute option
145         lgfnt.lfUnderline =
146             (attr == ATR_ULINE) ? TRUE : FALSE; // underline attribute option
147         lgfnt.lfStrikeOut = FALSE;              // strikeout attribute option
148         lgfnt.lfCharSet = mswin_charset();      // character set identifier
149         lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS;   // output precision
150         lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
151         lgfnt.lfQuality = DEFAULT_QUALITY;           // output quality
152         if (iflags.wc_font_message && *iflags.wc_font_message) {
153             lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
154             NH_A2W(iflags.wc_font_message, lgfnt.lfFaceName, LF_FACESIZE);
155         } else {
156             lgfnt.lfPitchAndFamily = VARIABLE_PITCH; // pitch and family
157         }
158         break;
159
160     case NHW_TEXT:
161         lgfnt.lfHeight = -iflags.wc_fontsiz_text
162                          * GetDeviceCaps(hdc, LOGPIXELSY)
163                          / 72;   // height of font
164         lgfnt.lfWidth = 0;       // average character width
165         lgfnt.lfEscapement = 0;  // angle of escapement
166         lgfnt.lfOrientation = 0; // base-line orientation angle
167         lgfnt.lfWeight = (attr == ATR_BOLD || attr == ATR_INVERSE)
168                              ? FW_BOLD
169                              : FW_NORMAL; // font weight
170         lgfnt.lfItalic =
171             (attr == ATR_BLINK) ? TRUE : FALSE; // italic attribute option
172         lgfnt.lfUnderline =
173             (attr == ATR_ULINE) ? TRUE : FALSE; // underline attribute option
174         lgfnt.lfStrikeOut = FALSE;              // strikeout attribute option
175         lgfnt.lfCharSet = mswin_charset();      // character set identifier
176         lgfnt.lfOutPrecision = OUT_DEFAULT_PRECIS;   // output precision
177         lgfnt.lfClipPrecision = CLIP_DEFAULT_PRECIS; // clipping precision
178         lgfnt.lfQuality = DEFAULT_QUALITY;           // output quality
179         if (iflags.wc_font_text && *iflags.wc_font_text) {
180             lgfnt.lfPitchAndFamily = DEFAULT_PITCH; // pitch and family
181             NH_A2W(iflags.wc_font_text, lgfnt.lfFaceName, LF_FACESIZE);
182         } else {
183             lgfnt.lfPitchAndFamily = FIXED_PITCH; // pitch and family
184         }
185         break;
186     }
187
188     fnt = CreateFontIndirect(&lgfnt);
189
190     /* add font to the table */
191     if (font_index == font_table_size) {
192         if (font_table_size >= MAXFONTS)
193             panic("font table overflow!");
194         font_table_size++;
195     } else {
196         DeleteObject(font_table[font_index].hFont);
197     }
198
199     font_table[font_index].code = NHFONT_CODE(win_type, attr);
200     font_table[font_index].hFont = fnt;
201     return fnt;
202 }
203
204 UINT
205 mswin_charset()
206 {
207     CHARSETINFO cis;
208     if (SYMHANDLING(H_IBM))
209         if (TranslateCharsetInfo((DWORD *) GetOEMCP(), &cis, TCI_SRCCODEPAGE))
210             return cis.ciCharset;
211         else
212             return OEM_CHARSET;
213     else if (TranslateCharsetInfo((DWORD *) GetACP(), &cis, TCI_SRCCODEPAGE))
214         return cis.ciCharset;
215     else
216         return ANSI_CHARSET;
217 }
218
219 void __cdecl font_table_cleanup(void)
220 {
221     int i;
222     for (i = 0; i < font_table_size; i++) {
223         DeleteObject(font_table[i].hFont);
224     }
225     font_table_size = 0;
226 }