2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/winsrv/concfg/font.c
5 * PURPOSE: Console Fonts Management
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
10 /* INCLUDES *******************************************************************/
17 // #include "concfg.h"
23 /* FUNCTIONS ******************************************************************/
25 /* Retrieves the character set associated with a given code page */
31 if (TranslateCharsetInfo(UlongToPtr(CodePage
), &CharInfo
, TCI_SRCCODEPAGE
))
32 return CharInfo
.ciCharset
;
34 return DEFAULT_CHARSET
;
40 IN LONG Width OPTIONAL
,
41 IN OUT LPWSTR FaceName
, // Points to a WCHAR array of LF_FACESIZE elements
48 RtlZeroMemory(&lf
, sizeof(lf
));
54 lf
.lfOrientation
= 0; // TA_BASELINE; // TA_RTLREADING; when the console supports RTL?
55 // lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = FALSE;
56 lf
.lfWeight
= FontWeight
;
57 lf
.lfCharSet
= CodePageToCharSet(CodePage
);
58 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
59 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
60 lf
.lfQuality
= DEFAULT_QUALITY
;
61 lf
.lfPitchAndFamily
= (BYTE
)(FIXED_PITCH
| FontFamily
);
63 if (!IsValidConsoleFont(FaceName
, CodePage
))
64 StringCchCopyW(FaceName
, LF_FACESIZE
, L
"Terminal");
66 StringCchCopyNW(lf
.lfFaceName
, ARRAYSIZE(lf
.lfFaceName
),
67 FaceName
, LF_FACESIZE
);
69 return CreateFontIndirectW(&lf
);
75 IN LONG Width OPTIONAL
,
76 IN OUT PCONSOLE_STATE_INFO ConsoleInfo
)
78 return CreateConsoleFontEx(Height
,
80 ConsoleInfo
->FaceName
,
81 ConsoleInfo
->FontFamily
,
82 ConsoleInfo
->FontWeight
,
83 ConsoleInfo
->CodePage
);
88 IN OUT PCONSOLE_STATE_INFO ConsoleInfo
)
92 * Width = FontSize.X = LOWORD(FontSize);
93 * Height = FontSize.Y = HIWORD(FontSize);
95 /* NOTE: FontSize is always in cell height/width units (pixels) */
96 return CreateConsoleFontEx((LONG
)(ULONG
)ConsoleInfo
->FontSize
.Y
,
97 (LONG
)(ULONG
)ConsoleInfo
->FontSize
.X
,
98 ConsoleInfo
->FaceName
,
99 ConsoleInfo
->FontFamily
,
100 ConsoleInfo
->FontWeight
,
101 ConsoleInfo
->CodePage
);
111 BOOL Success
= FALSE
;
114 // LONG LogSize, PointSize;
115 LONG CharWidth
, CharHeight
;
122 hOldFont
= SelectObject(hDC
, hFont
);
123 if (hOldFont
== NULL
)
125 DPRINT1("GetFontCellSize: SelectObject failed\n");
130 * See also: Display_SetTypeFace in applications/fontview/display.c
134 * Note that the method with GetObjectW just returns
135 * the original parameters with which the font was created.
137 if (!GetTextMetricsW(hDC
, &tm
))
139 DPRINT1("GetFontCellSize: GetTextMetrics failed\n");
143 CharHeight
= tm
.tmHeight
+ tm
.tmExternalLeading
;
146 /* Measure real char width more precisely if possible */
147 if (GetTextExtentPoint32W(hDC
, L
"R", 1, &CharSize
))
148 CharWidth
= CharSize
.cx
;
150 CharWidth
= tm
.tmAveCharWidth
; // tm.tmMaxCharWidth;
154 /*** Logical to Point size ***/
155 LogSize
= tm
.tmHeight
- tm
.tmInternalLeading
;
156 PointSize
= MulDiv(LogSize
, 72, GetDeviceCaps(hDC
, LOGPIXELSY
));
157 /*****************************/
160 *Height
= (UINT
)CharHeight
;
161 *Width
= (UINT
)CharWidth
;
165 SelectObject(hDC
, hOldFont
);
168 ReleaseDC(NULL
, hDC
);
176 IN PNEWTEXTMETRICW lpntm
,
180 LPCWSTR FaceName
= lplf
->lfFaceName
;
182 /* Record the font's attributes (Fixedwidth and Truetype) */
183 // BOOL fFixed = ((lplf->lfPitchAndFamily & 0x03) == FIXED_PITCH);
184 // BOOL fTrueType = (lplf->lfOutPrecision == OUT_STROKE_PRECIS);
187 * According to: http://support.microsoft.com/kb/247815
188 * the criteria for console-eligible fonts are:
189 * - The font must be a fixed-pitch font.
190 * - The font cannot be an italic font.
191 * - The font cannot have a negative A or C space.
192 * - If it is a TrueType font, it must be FF_MODERN.
193 * - If it is not a TrueType font, it must be OEM_CHARSET.
195 * Non documented: vertical fonts are forbidden (their name start with a '@').
197 * Additional criteria for Asian installations:
198 * - If it is not a TrueType font, the face name must be "Terminal".
199 * - If it is an Asian TrueType font, it must also be an Asian character set.
201 * To install additional TrueType fonts to be available for the console,
202 * add entries of type REG_SZ named "0", "00" etc... in:
203 * HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont
204 * The names of the fonts listed there should match those in:
205 * HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts
209 * In ReactOS we relax some of the criteria:
210 * - We allow fixed-pitch FF_MODERN (Monospace) TrueType fonts
211 * that can be italic or have negative A or C space.
212 * - If it is not a TrueType font, it can be from another character set
214 * - We do not look into the magic registry key mentioned above.
217 /* Reject variable width fonts */
218 if (((lplf
->lfPitchAndFamily
& 0x03) != FIXED_PITCH
)
219 #if 0 /* Reject italic and TrueType fonts with negative A or C space */
221 || !(lpntm
->ntmFlags
& NTM_NONNEGATIVE_AC
)
225 DPRINT1("Font '%S' rejected because it%s (lfPitchAndFamily = %d).\n",
226 FaceName
, !(lplf
->lfPitchAndFamily
& FIXED_PITCH
) ? "'s not FIXED_PITCH"
227 : (!(lpntm
->ntmFlags
& NTM_NONNEGATIVE_AC
) ? " has negative A or C space"
229 lplf
->lfPitchAndFamily
);
233 /* Reject TrueType fonts that are not FF_MODERN */
234 if ((FontType
== TRUETYPE_FONTTYPE
) && ((lplf
->lfPitchAndFamily
& 0xF0) != FF_MODERN
))
236 DPRINT1("TrueType font '%S' rejected because it's not FF_MODERN (lfPitchAndFamily = %d)\n",
237 FaceName
, lplf
->lfPitchAndFamily
);
241 /* Is the current code page Chinese, Japanese or Korean? */
242 if (IsCJKCodePage(CodePage
))
245 if (FontType
== TRUETYPE_FONTTYPE
)
247 if (lplf
->lfCharSet
!= CodePageToCharSet(CodePage
))
249 DPRINT1("TrueType font '%S' rejected because it's not user Asian charset (lfCharSet = %d)\n",
250 FaceName
, lplf
->lfCharSet
);
256 /* Reject non-TrueType fonts that are not Terminal */
257 if (wcscmp(FaceName
, L
"Terminal") != 0)
259 DPRINT1("Non-TrueType font '%S' rejected because it's not Terminal\n", FaceName
);
267 if ((FontType
!= TRUETYPE_FONTTYPE
) &&
268 (lplf
->lfCharSet
!= ANSI_CHARSET
) &&
269 (lplf
->lfCharSet
!= DEFAULT_CHARSET
) &&
270 (lplf
->lfCharSet
!= OEM_CHARSET
))
272 DPRINT1("Non-TrueType font '%S' rejected because it's not ANSI_CHARSET or DEFAULT_CHARSET or OEM_CHARSET (lfCharSet = %d)\n",
273 FaceName
, lplf
->lfCharSet
);
278 /* Reject fonts that are vertical (tategaki) */
279 if (FaceName
[0] == L
'@')
281 DPRINT1("Font '%S' rejected because it's vertical\n", FaceName
);
289 typedef struct _IS_VALID_CONSOLE_FONT_PARAM
293 } IS_VALID_CONSOLE_FONT_PARAM
, *PIS_VALID_CONSOLE_FONT_PARAM
;
296 IsValidConsoleFontProc(
298 IN PNEWTEXTMETRICW lpntm
,
302 PIS_VALID_CONSOLE_FONT_PARAM Param
= (PIS_VALID_CONSOLE_FONT_PARAM
)lParam
;
303 Param
->IsValidFont
= IsValidConsoleFont2(lplf
, lpntm
, FontType
, Param
->CodePage
);
305 /* Stop the enumeration now */
314 IS_VALID_CONSOLE_FONT_PARAM Param
;
318 Param
.IsValidFont
= FALSE
;
319 Param
.CodePage
= CodePage
;
321 RtlZeroMemory(&lf
, sizeof(lf
));
322 lf
.lfCharSet
= DEFAULT_CHARSET
; // CodePageToCharSet(CodePage);
323 // lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
324 StringCchCopyW(lf
.lfFaceName
, ARRAYSIZE(lf
.lfFaceName
), FaceName
);
327 EnumFontFamiliesExW(hDC
, &lf
, (FONTENUMPROCW
)IsValidConsoleFontProc
, (LPARAM
)&Param
, 0);
328 ReleaseDC(NULL
, hDC
);
330 return Param
.IsValidFont
;