00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "precomp.h"
00022
#pragma hdrstop
00023
00024
#ifdef DEBUG_PRINT
00025
ULONG gDebugFlag;
00026
00027
#endif
00028
00029 ULONG
NumberOfMouseButtons;
00030
00031 PFONT_INFO FontInfo;
00032 ULONG
FontInfoLength;
00033 ULONG
NumberOfFonts;
00034
00035 WCHAR
DefaultFaceName[LF_FACESIZE];
00036 COORD
DefaultFontSize;
00037 BYTE DefaultFontFamily;
00038 ULONG
DefaultFontIndex = 0;
00039
00040 typedef struct _FONTENUMDC {
00041 HDC
hDC;
00042 BOOL bFindFaces;
00043 SHORT TTPointSize;
00044 ULONG
ulFE;
00045 }
FONTENUMDC, *
PFONTENUMDC;
00046
00047
00048
00049
00050 CPTABLEINFO
GlyphCP;
00051 USHORT GlyphTable[256];
00052
00053
00054 #define FONT_BUFFER_SIZE 12
00055
00056 #define FE_ABANDONFONT 1
00057 #define FE_FONTOK 2
00058
00059
00060
00061
00062 PFACENODE gpFaceNames;
00063
00064
00065
NTSTATUS
00066 GetMouseButtons(
00067 PULONG NumButtons
00068 )
00069 {
00070 *NumButtons =
NumberOfMouseButtons;
00071
return STATUS_SUCCESS;
00072 }
00073
00074
VOID
00075 InitializeMouseButtons( VOID )
00076 {
00077
NumberOfMouseButtons =
GetSystemMetrics(SM_CMOUSEBUTTONS);
00078 }
00079
00080 PFACENODE AddFaceNode(
PFACENODE *ppStart, LPWSTR pwsz) {
00081
PFACENODE pNew;
00082
PFACENODE *ppTmp;
00083
int cb;
00084
00085
00086
00087
00088
for (ppTmp = ppStart; *ppTmp; ppTmp = &((*ppTmp)->pNext)) {
00089
if (wcscmp(((*ppTmp)->awch), pwsz) == 0) {
00090
00091
return *ppTmp;
00092 }
00093 }
00094
00095 cb = (wcslen(pwsz) + 1) *
sizeof(WCHAR);
00096 pNew = (
PFACENODE)
ConsoleHeapAlloc(
MAKE_TAG(
FONT_TAG ),
sizeof(
FACENODE) + cb);
00097
if (pNew ==
NULL) {
00098
return NULL;
00099 }
00100
00101 pNew->
pNext =
NULL;
00102 pNew->
dwFlag = 0;
00103 wcscpy(pNew->
awch, pwsz);
00104 *ppTmp = pNew;
00105
return pNew;
00106 }
00107
00108
VOID
00109 InitializeFonts( VOID )
00110 {
00111 WCHAR FontName[
CONSOLE_MAX_FONT_NAME_LENGTH];
00112
int i;
00113
static CONST LPWSTR FontList[] = {
L"woafont",
00114
L"ega80woa.fon",
00115
L"ega40woa.fon",
00116
L"cga80woa.fon",
00117
L"cga40woa.fon"};
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 OpenProfileUserMapping();
00131
00132
for (i = 0; i <
NELEM(FontList); i++) {
00133 GetPrivateProfileString(
L"386enh", FontList[i],
L"",
00134 FontName,
NELEM(FontName),
L"system.ini");
00135 GdiAddFontResourceW(FontName, AFRW_ADD_LOCAL_FONT,
NULL);
00136 }
00137
00138 CloseProfileUserMapping();
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
int CALLBACK
00152 FontEnum(
00153 LPENUMLOGFONTW lpLogFont,
00154 LPNEWTEXTMETRICW lpTextMetric,
00155
int nFontType,
00156 LPARAM lParam
00157 )
00158
00159
00160
00161
00162
00163
00164
00165
00166 {
00167
PFONTENUMDC pfed = (
PFONTENUMDC)lParam;
00168 HDC hDC = pfed->
hDC;
00169
BOOL bFindFaces = pfed->
bFindFaces;
00170 HFONT hFont;
00171 TEXTMETRICW tmi;
00172 LONG nFont;
00173 LONG nFontNew;
00174 COORD SizeToShow;
00175 COORD SizeActual;
00176 COORD SizeWant;
00177
BYTE tmFamily;
00178 SIZE
Size;
00179 LPWSTR pwszFace = lpLogFont->elfLogFont.lfFaceName;
00180
PFACENODE pFN;
00181
00182
DBGFONTS((
" FontEnum \"%ls\" (%d,%d) weight 0x%lx(%d) -- %s\n",
00183 pwszFace,
00184 lpLogFont->elfLogFont.lfWidth, lpLogFont->elfLogFont.lfHeight,
00185 lpLogFont->elfLogFont.lfWeight, lpLogFont->elfLogFont.lfWeight,
00186 bFindFaces ?
"Finding Faces" :
"Creating Fonts"));
00187
00188
00189
00190
00191
00192
if
00193 (
00194 !(lpLogFont->elfLogFont.lfPitchAndFamily & FIXED_PITCH) ||
00195 (lpLogFont->elfLogFont.lfItalic) ||
00196 !(lpTextMetric->ntmFlags & NTM_NONNEGATIVE_AC)
00197 )
00198 {
00199
if (!
IsAvailableTTFont(pwszFace))
00200 {
00201
DBGFONTS((
" REJECT face (variable pitch, italic, or neg a&c)\n"));
00202
return bFindFaces ?
TRUE :
FALSE;
00203 }
00204 }
00205
00206
if (nFontType == TRUETYPE_FONTTYPE) {
00207 lpLogFont->elfLogFont.lfHeight = pfed->
TTPointSize;
00208 lpLogFont->elfLogFont.lfWidth = 0;
00209 lpLogFont->elfLogFont.lfWeight = FW_NORMAL;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
if ((nFontType == TRUETYPE_FONTTYPE) &&
00221 ((lpLogFont->elfLogFont.lfPitchAndFamily & 0xf0) != FF_MODERN)) {
00222
DBGFONTS((
" REJECT face (TT but not FF_MODERN)\n"));
00223
return bFindFaces ?
TRUE :
FALSE;
00224 }
00225
00226
00227
00228
00229
if ((nFontType != TRUETYPE_FONTTYPE) &&
00230
#if defined(FE_SB)
00231
(!
CONSOLE_IS_DBCS_ENABLED() ||
00232 !IS_ANY_DBCS_CHARSET(lpLogFont->elfLogFont.lfCharSet)) &&
00233
#endif
00234
(lpLogFont->elfLogFont.lfCharSet != OEM_CHARSET)) {
00235
DBGFONTS((
" REJECT face (not TT nor OEM)\n"));
00236
return bFindFaces ?
TRUE :
FALSE;
00237 }
00238
00239
00240
00241
00242
if ((nFontType != TRUETYPE_FONTTYPE) &&
00243 (pwszFace[0] ==
L'@')) {
00244
DBGFONTS((
" REJECT face (not TT and TATEGAKI)\n"));
00245
return bFindFaces ?
TRUE :
FALSE;
00246 }
00247
00248
00249
00250
00251
if (
CONSOLE_IS_DBCS_ENABLED() &&
00252 (nFontType != TRUETYPE_FONTTYPE) &&
00253 (wcscmp(pwszFace,
L"Terminal") != 0)) {
00254
DBGFONTS((
" REJECT face (not TT nor Terminal)\n"));
00255
return bFindFaces ?
TRUE :
FALSE;
00256 }
00257
00258
00259
00260
00261
if (
IsAvailableTTFont(pwszFace) &&
00262 !IS_ANY_DBCS_CHARSET(lpLogFont->elfLogFont.lfCharSet) &&
00263 !
IsAvailableTTFontCP(pwszFace,0)
00264 ) {
00265
DBGFONTS((
" REJECT face (Far East TT and not Far East charset)\n"));
00266
return TRUE;
00267 }
00268
00269
00270
00271
00272 pFN =
AddFaceNode(&
gpFaceNames, pwszFace);
00273
if (pFN ==
NULL) {
00274
return FALSE;
00275 }
00276
00277
if (bFindFaces) {
00278
if (nFontType == TRUETYPE_FONTTYPE) {
00279
DBGFONTS((
"NEW TT FACE %ls\n", pwszFace));
00280 pFN->
dwFlag |=
EF_TTFONT;
00281 }
else if (nFontType == RASTER_FONTTYPE) {
00282
DBGFONTS((
"NEW OEM FACE %ls\n",pwszFace));
00283 pFN->
dwFlag |=
EF_OEMFONT;
00284 }
00285
return 0;
00286 }
00287
00288
00289
if (
IS_BOLD(lpLogFont->elfLogFont.lfWeight)) {
00290
DBGFONTS2((
" A bold font (weight %d)\n", lpLogFont->elfLogFont.lfWeight));
00291
00292 }
00293
00294
00295 SizeWant.Y = (
SHORT)lpLogFont->elfLogFont.lfHeight;
00296 SizeWant.X = (
SHORT)lpLogFont->elfLogFont.lfWidth;
00297 CreateBoldFont:
00298 lpLogFont->elfLogFont.lfQuality = NONANTIALIASED_QUALITY;
00299 hFont = CreateFontIndirectW(&lpLogFont->elfLogFont);
00300
if (!hFont) {
00301
DBGFONTS((
" REJECT font (can't create)\n"));
00302 RIPMSG0(RIP_WARNING,
"FontEnum: CreateFontIndirectW returned NULL hFont.");
00303
return 0;
00304 }
00305
00306
DBGFONTS2((
" hFont = %lx\n", hFont));
00307
00308
00309
00310
00311
00312
00313 SelectObject(hDC,hFont);
00314
if (!GetTextMetricsW(hDC, &tmi)) {
00315 tmi = *((LPTEXTMETRICW)lpTextMetric);
00316 }
00317
00318
if (GetTextExtentPoint32W(hDC,
L"0", 1, &
Size)) {
00319 SizeActual.X = (
SHORT)
Size.cx;
00320 }
else {
00321 SizeActual.X = (
SHORT)(tmi.tmMaxCharWidth);
00322 }
00323 SizeActual.Y = (
SHORT)(tmi.tmHeight + tmi.tmExternalLeading);
00324
DBGFONTS2((
" actual size %d,%d\n", SizeActual.X, SizeActual.Y));
00325 tmFamily = tmi.tmPitchAndFamily;
00326
if (
TM_IS_TT_FONT(tmFamily) && (SizeWant.Y >= 0)) {
00327 SizeToShow = SizeWant;
00328
if (SizeWant.X == 0) {
00329
00330
00331 SizeToShow.X = SizeActual.X;
00332 }
00333 }
else {
00334 SizeToShow = SizeActual;
00335 }
00336
DBGFONTS2((
" SizeToShow = (%d,%d), SizeActual = (%d,%d)\n",
00337 SizeToShow.X, SizeToShow.Y, SizeActual.X, SizeActual.Y));
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
for (nFont = 0; nFont < (LONG)
NumberOfFonts; ++nFont) {
00352 COORD SizeShown;
00353
00354
if (
FontInfo[nFont].
hFont ==
NULL) {
00355
DBGFONTS((
"! Font %x has a NULL hFont\n", nFont));
00356
continue;
00357 }
00358
00359
00360
if (
FontInfo[nFont].
SizeWant.X > 0) {
00361 SizeShown.X =
FontInfo[nFont].
SizeWant.X;
00362 }
else {
00363 SizeShown.X =
FontInfo[nFont].
Size.X;
00364 }
00365
00366
if (
FontInfo[nFont].
SizeWant.Y > 0) {
00367
00368 SizeShown.Y =
FontInfo[nFont].
SizeWant.Y;
00369 }
else {
00370 SizeShown.Y =
FontInfo[nFont].
Size.Y;
00371
if (
FontInfo[nFont].
SizeWant.Y < 0) {
00372
00373
if (SizeWant.Y < 0 && SizeWant.Y >
FontInfo[nFont].
SizeWant.Y) {
00374
00375
DBGFONTS((
"INSERT %d pt at %x, before %d pt\n",
00376 -SizeWant.Y, nFont, -
FontInfo[nFont].
SizeWant.Y));
00377 nFontNew = nFont;
00378
goto InsertNewFont;
00379 }
00380 }
00381 }
00382
00383
00384
00385
if (
SIZE_EQUAL(SizeShown, SizeToShow) &&
00386
FontInfo[nFont].
Family == tmFamily &&
00387
FontInfo[nFont].
Weight == tmi.tmWeight &&
00388 wcscmp(
FontInfo[nFont].FaceName, pwszFace) == 0) {
00389
00390
00391
00392
DBGFONTS2((
" Already have the font\n"));
00393 DeleteObject(hFont);
00394 pfed->
ulFE |=
FE_FONTOK;
00395
return TRUE;
00396 }
00397
00398
00399
if ((SizeToShow.Y < SizeShown.Y) ||
00400 (SizeToShow.Y == SizeShown.Y && SizeToShow.X < SizeShown.X)) {
00401
00402
00403
00404
DBGFONTS((
"INSERT at %x, SizeToShow = (%d,%d)\n", nFont,
00405 SizeToShow.X,SizeToShow.Y));
00406 nFontNew = nFont;
00407
goto InsertNewFont;
00408 }
00409 }
00410
00411
00412
00413
00414
00415 nFontNew = (LONG)
NumberOfFonts;
00416
00417 InsertNewFont:
00418
00419
00420
00421
00422
if (
NumberOfFonts ==
FontInfoLength) {
00423
PFONT_INFO Temp;
00424
00425
FontInfoLength +=
FONT_INCREMENT;
00426 Temp = (
PFONT_INFO)
ConsoleHeapReAlloc(
MAKE_TAG(
FONT_TAG ),
FontInfo,
sizeof(
FONT_INFO) *
FontInfoLength);
00427
if (Temp ==
NULL) {
00428 RIPMSG0(RIP_WARNING,
"FontEnum: failed to allocate PFONT_INFO");
00429
FontInfoLength -=
FONT_INCREMENT;
00430
return FALSE;
00431 }
00432
FontInfo = Temp;
00433 }
00434
00435
if (nFontNew < (LONG)
NumberOfFonts) {
00436 RtlMoveMemory(&
FontInfo[nFontNew+1],
00437 &
FontInfo[nFontNew],
00438
sizeof(
FONT_INFO)*(
NumberOfFonts - nFontNew));
00439
00440
00441
00442
if (nFontNew < (LONG)
DefaultFontIndex &&
00443
DefaultFontIndex+1 <
NumberOfFonts) {
00444
DefaultFontIndex++;
00445 }
00446 }
00447
00448
00449
00450
00451
FontInfo[nFontNew].
hFont = hFont;
00452
FontInfo[nFontNew].
Family = tmFamily;
00453
FontInfo[nFontNew].
Size = SizeActual;
00454
if (
TM_IS_TT_FONT(tmFamily)) {
00455
FontInfo[nFontNew].
SizeWant = SizeWant;
00456 }
else {
00457
FontInfo[nFontNew].
SizeWant.X = 0;
00458
FontInfo[nFontNew].
SizeWant.Y = 0;
00459 }
00460
FontInfo[nFontNew].
Weight = tmi.tmWeight;
00461
FontInfo[nFont].
FaceName = pFN->
awch;
00462
#if defined(FE_SB)
00463
FontInfo[nFontNew].tmCharSet = tmi.tmCharSet;
00464
#endif
00465
00466 ++
NumberOfFonts;
00467
00468
if (nFontType == TRUETYPE_FONTTYPE && !
IS_BOLD(
FontInfo[nFontNew].Weight)) {
00469 lpLogFont->elfLogFont.lfWeight = FW_BOLD;
00470
goto CreateBoldFont;
00471 }
00472
00473 pfed->
ulFE |=
FE_FONTOK;
00474
return TRUE;
00475 }
00476
00477
BOOL
00478 DoFontEnum(
00479 HDC hDC,
00480 LPWSTR pwszFace,
00481 SHORT TTPointSize)
00482 {
00483 ULONG ulFE = 0;
00484
BOOL bDeleteDC =
FALSE;
00485
BOOL bFindFaces = (pwszFace ==
NULL);
00486
FONTENUMDC fed;
00487 LOGFONTW LogFont;
00488
00489
DBGFONTS((
"DoFontEnum \"%ls\"\n", pwszFace));
00490
if (hDC ==
NULL) {
00491 hDC = CreateDCW(
L"DISPLAY",
NULL,
NULL,
NULL);
00492 bDeleteDC =
TRUE;
00493 }
00494
00495 fed.
hDC = hDC;
00496 fed.
bFindFaces = bFindFaces;
00497 fed.
ulFE = 0;
00498 fed.
TTPointSize = TTPointSize;
00499 RtlZeroMemory(&LogFont,
sizeof(LOGFONT));
00500 LogFont.lfCharSet = DEFAULT_CHARSET;
00501
if (pwszFace)
00502 wcscpy(LogFont.lfFaceName, pwszFace);
00503
00504
00505
00506 EnumFontFamiliesExW(hDC, &LogFont, (FONTENUMPROC)
FontEnum, (LPARAM)&fed, 0);
00507
if (bDeleteDC) {
00508 DeleteDC(hDC);
00509 }
00510
return (fed.ulFE &
FE_FONTOK) != 0;
00511 }
00512
00513
00514
NTSTATUS
00515 EnumerateFonts(
00516 DWORD Flags)
00517 {
00518 TEXTMETRIC tmi;
00519 HDC hDC;
00520
PFACENODE pFN;
00521 ULONG ulOldEnumFilter;
00522
DWORD FontIndex;
00523
DWORD dwFontType = 0;
00524
00525
DBGFONTS((
"EnumerateFonts %lx\n", Flags));
00526
00527 dwFontType = (
EF_TTFONT|
EF_OEMFONT|
EF_DEFFACE) & Flags;
00528
00529
if (
FontInfo ==
NULL) {
00530
00531
00532
00533
NumberOfFonts = 0;
00534
00535
FontInfo = (
PFONT_INFO)
ConsoleHeapAlloc(
MAKE_TAG(
FONT_TAG ),
sizeof(
FONT_INFO) *
INITIAL_FONTS);
00536
if (
FontInfo ==
NULL)
00537
return STATUS_NO_MEMORY;
00538
FontInfoLength =
INITIAL_FONTS;
00539 }
00540
00541 hDC = CreateDCW(
L"DISPLAY",
NULL,
NULL,
NULL);
00542
00543
00544 ulOldEnumFilter = SetFontEnumeration(0);
00545
00546 SetFontEnumeration(ulOldEnumFilter & ~FE_FILTER_TRUETYPE);
00547
00548
if (Flags &
EF_DEFFACE) {
00549 SelectObject(hDC,GetStockObject(OEM_FIXED_FONT));
00550
00551
if (GetTextMetricsW(hDC, &tmi)) {
00552
DefaultFontSize.X = (
SHORT)(tmi.tmMaxCharWidth);
00553
DefaultFontSize.Y = (
SHORT)(tmi.tmHeight+tmi.tmExternalLeading);
00554
DefaultFontFamily = tmi.tmPitchAndFamily;
00555
#if defined(FE_SB)
00556
if (IS_ANY_DBCS_CHARSET(tmi.tmCharSet))
00557
DefaultFontSize.X /= 2;
00558
#endif
00559
}
00560 GetTextFaceW(hDC, LF_FACESIZE,
DefaultFaceName);
00561
#if defined(FE_SB)
00562
DBGFONTS((
"Default (OEM) Font %ls (%d,%d) CharSet 0x%02X\n",
DefaultFaceName,
00563
DefaultFontSize.X,
DefaultFontSize.Y,
00564 tmi.tmCharSet));
00565
#else
00566
DBGFONTS((
"Default (OEM) Font %ls (%d,%d)\n",
DefaultFaceName,
00567
DefaultFontSize.X,
DefaultFontSize.Y));
00568
#endif
00569
00570
00571 pFN =
AddFaceNode(&
gpFaceNames,
DefaultFaceName);
00572 pFN->
dwFlag |=
EF_DEFFACE |
EF_OEMFONT;
00573 }
00574
00575
00576
00577
00578
for (pFN =
gpFaceNames; pFN; pFN = pFN->
pNext) {
00579
DBGFONTS((
"\"%ls\" is %s%s%s%s%s%s\n", pFN->
awch,
00580 pFN->
dwFlag &
EF_NEW ?
"NEW " :
" ",
00581 pFN->
dwFlag &
EF_OLD ?
"OLD " :
" ",
00582 pFN->
dwFlag &
EF_ENUMERATED ?
"ENUMERATED " :
" ",
00583 pFN->
dwFlag &
EF_OEMFONT ?
"OEMFONT " :
" ",
00584 pFN->
dwFlag &
EF_TTFONT ?
"TTFONT " :
" ",
00585 pFN->
dwFlag &
EF_DEFFACE ?
"DEFFACE " :
" "));
00586
00587
if ((pFN->
dwFlag & dwFontType) == 0) {
00588
00589
continue;
00590 }
00591
if (pFN->
dwFlag &
EF_ENUMERATED) {
00592
00593
continue;
00594 }
00595
00596
DoFontEnum(hDC, pFN->
awch,
DefaultFontSize.Y);
00597 pFN->
dwFlag |=
EF_ENUMERATED;
00598 }
00599
00600
00601
00602 SetFontEnumeration(ulOldEnumFilter);
00603
00604 DeleteDC(hDC);
00605
00606
00607
if (
NumberOfFonts > 0 &&
DefaultFontSize.X == 0 &&
DefaultFontSize.Y == 0) {
00608
DefaultFontSize.X =
FontInfo[0].
Size.X;
00609
DefaultFontSize.Y =
FontInfo[0].
Size.Y;
00610
DefaultFontFamily =
FontInfo[0].
Family;
00611 }
00612
00613
for (FontIndex = 0; FontIndex <
NumberOfFonts; FontIndex++) {
00614
if (
FontInfo[FontIndex].
Size.X ==
DefaultFontSize.X &&
00615
FontInfo[FontIndex].
Size.Y ==
DefaultFontSize.Y &&
00616
FontInfo[FontIndex].
Family ==
DefaultFontFamily) {
00617
#if defined(FE_SB)
00618
if (
CONSOLE_IS_DBCS_ENABLED() &&
00619 !IS_ANY_DBCS_CHARSET(
FontInfo[FontIndex].tmCharSet))
00620 {
00621
continue ;
00622 }
00623
#endif
00624
break;
00625 }
00626 }
00627
ASSERT(FontIndex <
NumberOfFonts);
00628
if (FontIndex <
NumberOfFonts) {
00629
DefaultFontIndex = FontIndex;
00630 }
else {
00631
DefaultFontIndex = 0;
00632 }
00633
DBGFONTS((
"EnumerateFonts : DefaultFontIndex = %ld\n",
DefaultFontIndex));
00634
00635
return STATUS_SUCCESS;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
int
00650 FindCreateFont(
00651 DWORD Family,
00652 LPWSTR pwszFace,
00653 COORD Size,
00654 LONG Weight,
00655 UINT CodePage)
00656 {
00657
#define NOT_CREATED_NOR_FOUND -1
00658
#define CREATED_BUT_NOT_FOUND -2
00659
00660
int i;
00661
int FontIndex =
NOT_CREATED_NOR_FOUND;
00662
int BestMatch =
NOT_CREATED_NOR_FOUND;
00663
BOOL bFontOK;
00664 WCHAR AltFaceName[LF_FACESIZE];
00665 COORD AltFontSize;
00666
BYTE AltFontFamily;
00667 ULONG AltFontIndex = 0;
00668 LPWSTR pwszAltFace =
NULL;
00669
00670
BYTE CharSet =
CodePageToCharSet(CodePage);
00671
00672
DBGFONTS((
"FindCreateFont Family=%x %ls (%d,%d) %d %d %x\n",
00673 Family, pwszFace,
Size.X,
Size.Y, Weight, CodePage, CharSet));
00674
00675
if (
CONSOLE_IS_DBCS_ENABLED() &&
00676 !IS_ANY_DBCS_CHARSET(CharSet))
00677 {
00678
MakeAltRasterFont(CodePage,
FontInfo[
DefaultFontIndex].
Size,
00679 &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName);
00680
00681
if (pwszFace ==
NULL || *pwszFace ==
L'\0') {
00682 pwszFace = AltFaceName;
00683 }
00684
if (
Size.Y == 0) {
00685
Size.X = AltFontSize.X;
00686
Size.Y = AltFontSize.Y;
00687 }
00688 }
00689
else {
00690
if (pwszFace ==
NULL || *pwszFace ==
L'\0') {
00691 pwszFace =
DefaultFaceName;
00692 }
00693
if (
Size.Y == 0) {
00694
Size.X =
DefaultFontSize.X;
00695
Size.Y =
DefaultFontSize.Y;
00696 }
00697 }
00698
00699
if (
IsAvailableTTFont(pwszFace)) {
00700 pwszAltFace =
GetAltFaceName(pwszFace);
00701 }
00702
else {
00703 pwszAltFace = pwszFace;
00704 }
00705
00706
00707
00708
00709 TryFindExactFont:
00710
for (i=0; i < (
int)
NumberOfFonts; i++) {
00711
00712
00713
00714
if ((Family != 0) &&
00715 ((
BYTE)Family !=
FontInfo[i].
Family)) {
00716
continue;
00717 }
00718
00719
00720
00721
00722
if ((
FontInfo[i].
SizeWant.Y !=
Size.Y) &&
00723 !
SIZE_EQUAL(
FontInfo[i].
Size,
Size)) {
00724
continue;
00725 }
00726
00727
00728
00729
00730
if ((Weight != 0) && (Weight !=
FontInfo[i].
Weight)) {
00731
continue;
00732 }
00733
#if defined(FE_SB)
00734
if (!
TM_IS_TT_FONT(
FontInfo[i].Family) &&
00735
FontInfo[i].tmCharSet != CharSet) {
00736
continue;
00737 }
00738
#endif
00739
00740
00741
00742
00743
00744
00745
if ((pwszFace ==
NULL) || (pwszFace[0] ==
L'\0') ||
00746 wcscmp(
FontInfo[i].FaceName, pwszFace) == 0 ||
00747 wcscmp(
FontInfo[i].FaceName, pwszAltFace) == 0
00748 ) {
00749 FontIndex = i;
00750
goto FoundFont;
00751 }
else if (!
TM_IS_TT_FONT(
FontInfo[i].Family)) {
00752 BestMatch = i;
00753 }
00754 }
00755
00756
00757
00758
00759
if (FontIndex ==
NOT_CREATED_NOR_FOUND) {
00760 ULONG ulOldEnumFilter;
00761 ulOldEnumFilter = SetFontEnumeration(0);
00762
00763 SetFontEnumeration(ulOldEnumFilter & ~FE_FILTER_TRUETYPE);
00764
if (
Size.Y < 0) {
00765
Size.Y = -
Size.Y;
00766 }
00767 bFontOK =
DoFontEnum(
NULL, pwszFace,
Size.Y);
00768 SetFontEnumeration(ulOldEnumFilter);
00769
if (bFontOK) {
00770
DBGFONTS((
"FindCreateFont created font!\n"));
00771 FontIndex =
CREATED_BUT_NOT_FOUND;
00772
goto TryFindExactFont;
00773 }
else {
00774
DBGFONTS((
"FindCreateFont failed to create font!\n"));
00775 }
00776 }
00777
00778
00779
00780
00781
00782
if (BestMatch >= 0) {
00783 FontIndex = BestMatch;
00784
goto FoundFont;
00785 }
00786
00787
00788
00789
00790
00791
for (i=0; i < (
int)
NumberOfFonts; i++) {
00792
#if defined(FE_SB)
00793
if (
CONSOLE_IS_DBCS_ENABLED()) {
00794
if ((Family != 0) &&
00795 ((
BYTE)Family !=
FontInfo[i].
Family)) {
00796
continue;
00797 }
00798
00799
if (!
TM_IS_TT_FONT(
FontInfo[i].Family) &&
00800
FontInfo[i].tmCharSet != CharSet) {
00801
continue;
00802 }
00803 }
00804
else {
00805
#endif
00806
if ((
BYTE)Family !=
FontInfo[i].
Family) {
00807
continue;
00808 }
00809
#if defined(FE_SB)
00810
}
00811
#endif
00812
00813
if (
FontInfo[i].
Size.Y >=
Size.Y &&
00814
FontInfo[i].
Size.X >=
Size.X) {
00815
00816 FontIndex = i;
00817
break;
00818 }
00819 }
00820
00821
if (FontIndex < 0) {
00822
DBGFONTS((
"FindCreateFont defaults!\n"));
00823
#if defined(FE_SB)
00824
if (
CONSOLE_IS_DBCS_ENABLED() &&
00825 !
IsAvailableFarEastCodePage(CodePage))
00826 {
00827 FontIndex = AltFontIndex;
00828 }
00829
else
00830
#endif
00831
FontIndex =
DefaultFontIndex;
00832 }
00833
00834 FoundFont:
00835
DBGFONTS((
"FindCreateFont returns %x : %ls (%d,%d)\n", FontIndex,
00836
FontInfo[FontIndex].FaceName,
00837
FontInfo[FontIndex].
Size.X,
FontInfo[FontIndex].
Size.Y));
00838
return FontIndex;
00839
00840
#undef NOT_CREATED_NOR_FOUND
00841
#undef CREATED_BUT_NOT_FOUND
00842
}
00843
00844
00845
NTSTATUS
00846 FindTextBufferFontInfo(
00847 IN
PSCREEN_INFORMATION ScreenInfo,
00848 IN UINT CodePage,
00849 OUT
PTEXT_BUFFER_FONT_INFO TextFontInfo
00850 )
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 {
00865
PTEXT_BUFFER_FONT_INFO CurrentFont;
00866
00867 CurrentFont = ScreenInfo->BufferInfo.TextInfo.ListOfTextBufferFont;
00868
00869
while (CurrentFont !=
NULL) {
00870
if (CurrentFont->
FontCodePage == CodePage) {
00871 *TextFontInfo = *CurrentFont;
00872
return STATUS_SUCCESS;
00873 }
00874 CurrentFont = CurrentFont->
NextTextBufferFont;
00875 }
00876
00877
return STATUS_UNSUCCESSFUL;
00878 }
00879
00880
NTSTATUS
00881 StoreTextBufferFontInfo(
00882 IN
PSCREEN_INFORMATION ScreenInfo,
00883 IN ULONG FontIndex,
00884 IN COORD FontSize,
00885 IN BYTE FontFamily,
00886 IN LONG FontWeight,
00887 IN LPWSTR FaceName,
00888 IN UINT CodePage
00889 )
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 {
00905
PTEXT_BUFFER_FONT_INFO CurrentFont, PrevFont;
00906
00907 CurrentFont = ScreenInfo->BufferInfo.TextInfo.ListOfTextBufferFont;
00908
00909
while (CurrentFont !=
NULL) {
00910
if (CurrentFont->
FontCodePage == CodePage) {
00911 CurrentFont->
FontNumber = FontIndex;
00912 CurrentFont->
FontSize = FontSize;
00913 CurrentFont->
Family = FontFamily;
00914 CurrentFont->
Weight = FontWeight;
00915
00916 wcscpy(CurrentFont->
FaceName, FaceName);
00917
break;
00918 }
00919 PrevFont = CurrentFont;
00920 CurrentFont = CurrentFont->
NextTextBufferFont;
00921 }
00922
00923
if (CurrentFont ==
NULL) {
00924 CurrentFont =
ConsoleHeapAlloc(
MAKE_TAG(
FONT_TAG ),
sizeof(
TEXT_BUFFER_FONT_INFO));
00925
if (CurrentFont ==
NULL) {
00926
return STATUS_NO_MEMORY;
00927 }
00928
00929 CurrentFont->
NextTextBufferFont =
NULL;
00930 CurrentFont->
FontNumber = FontIndex;
00931 CurrentFont->
FontSize = FontSize;
00932 CurrentFont->
Family = FontFamily;
00933 CurrentFont->
Weight = FontWeight;
00934 CurrentFont->
FontCodePage = CodePage;
00935 wcscpy(CurrentFont->
FaceName, FaceName);
00936
00937
if (ScreenInfo->BufferInfo.TextInfo.ListOfTextBufferFont ==
NULL) {
00938 ScreenInfo->BufferInfo.TextInfo.ListOfTextBufferFont = CurrentFont;
00939 }
00940
else {
00941 PrevFont->
NextTextBufferFont = CurrentFont;
00942 }
00943 }
00944
00945 ScreenInfo->BufferInfo.TextInfo.CurrentTextBufferFont = *CurrentFont;
00946 ScreenInfo->BufferInfo.TextInfo.CurrentTextBufferFont.
NextTextBufferFont =
NULL;
00947
00948
return STATUS_SUCCESS;
00949 }
00950
00951
NTSTATUS
00952 RemoveTextBufferFontInfo(
00953 IN
PSCREEN_INFORMATION ScreenInfo
00954 )
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 {
00969
PTEXT_BUFFER_FONT_INFO CurrentFont;
00970
00971 CurrentFont = ScreenInfo->BufferInfo.TextInfo.ListOfTextBufferFont;
00972
00973
while (CurrentFont !=
NULL) {
00974
PTEXT_BUFFER_FONT_INFO NextFont;
00975
00976 NextFont = CurrentFont->
NextTextBufferFont;
00977
ConsoleHeapFree(CurrentFont);
00978
00979 CurrentFont = NextFont;
00980 }
00981
00982 ScreenInfo->BufferInfo.TextInfo.ListOfTextBufferFont =
NULL;
00983
00984
return STATUS_SUCCESS;
00985 }
00986
00987
NTSTATUS
00988 GetNumFonts(
00989 OUT PULONG NumFonts
00990 )
00991 {
00992 *NumFonts =
NumberOfFonts;
00993
return STATUS_SUCCESS;
00994 }
00995
00996
00997
NTSTATUS
00998 GetAvailableFonts(
00999 IN
PSCREEN_INFORMATION ScreenInfo,
01000 IN BOOLEAN MaximumWindow,
01001 OUT PVOID Buffer,
01002 IN OUT PULONG NumFonts
01003 )
01004 {
01005 PCONSOLE_FONT_INFO BufPtr;
01006 ULONG i;
01007 COORD WindowSize;
01008
WINDOW_LIMITS WindowLimits;
01009
01010
01011
01012
01013
01014
01015 *NumFonts = (*NumFonts >
NumberOfFonts) ?
NumberOfFonts : *NumFonts;
01016
01017
01018
01019
01020
01021 BufPtr = (PCONSOLE_FONT_INFO)
Buffer;
01022
01023
if (MaximumWindow) {
01024
GetWindowLimits(ScreenInfo, &WindowLimits);
01025 WindowSize = WindowLimits.
MaximumWindowSize;
01026 }
01027
else {
01028 WindowSize.X = (
SHORT)
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
01029 WindowSize.Y = (
SHORT)
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
01030 }
01031
for (i=0;i<*NumFonts;i++,BufPtr++) {
01032 BufPtr->nFont = i;
01033 BufPtr->dwFontSize.X = WindowSize.X *
SCR_FONTSIZE(ScreenInfo).X /
FontInfo[i].
Size.X;
01034 BufPtr->dwFontSize.Y = WindowSize.Y *
SCR_FONTSIZE(ScreenInfo).Y /
FontInfo[i].
Size.Y;
01035 }
01036
01037
return STATUS_SUCCESS;
01038 }
01039
01040
NTSTATUS
01041 GetFontSize(
01042 IN DWORD FontIndex,
01043 OUT PCOORD FontSize
01044 )
01045 {
01046
if (FontIndex >=
NumberOfFonts)
01047
return STATUS_INVALID_PARAMETER;
01048 *FontSize =
FontInfo[FontIndex].
Size;
01049
return STATUS_SUCCESS;
01050 }
01051
01052
NTSTATUS
01053 GetCurrentFont(
01054 IN
PSCREEN_INFORMATION ScreenInfo,
01055 IN BOOLEAN MaximumWindow,
01056 OUT PULONG FontIndex,
01057 OUT PCOORD FontSize
01058 )
01059 {
01060 COORD WindowSize;
01061
WINDOW_LIMITS WindowLimits;
01062
01063
if (MaximumWindow) {
01064
GetWindowLimits(ScreenInfo, &WindowLimits);
01065 WindowSize = WindowLimits.
MaximumWindowSize;
01066 }
01067
else {
01068 WindowSize.X = (
SHORT)
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
01069 WindowSize.Y = (
SHORT)
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
01070 }
01071 *FontIndex =
SCR_FONTNUMBER(ScreenInfo);
01072 *FontSize = WindowSize;
01073
return STATUS_SUCCESS;
01074 }
01075
01076
NTSTATUS
01077 SetScreenBufferFont(
01078 IN
PSCREEN_INFORMATION ScreenInfo,
01079 IN ULONG FontIndex,
01080 IN UINT CodePage
01081 )
01082 {
01083 COORD FontSize;
01084
WINDOW_LIMITS WindowLimits;
01085
NTSTATUS Status;
01086 ULONG ulFlagPrev;
01087
DBGFONTS((
"SetScreenBufferFont %lx %x\n", ScreenInfo, FontIndex));
01088
01089
if (ScreenInfo ==
NULL) {
01090
01091
return STATUS_SUCCESS;
01092 }
01093
01094
01095
01096
01097
if (!(ScreenInfo->Flags &
CONSOLE_TEXTMODE_BUFFER)) {
01098
return STATUS_UNSUCCESSFUL;
01099 }
01100
01101
Status =
GetFontSize(FontIndex, &FontSize);
01102
if (!
NT_SUCCESS(
Status)) {
01103
return((ULONG)
Status);
01104 }
01105
01106 ulFlagPrev = ScreenInfo->Flags;
01107
if (
TM_IS_TT_FONT(
FontInfo[FontIndex].Family)) {
01108 ScreenInfo->Flags &= ~
CONSOLE_OEMFONT_DISPLAY;
01109 }
else {
01110 ScreenInfo->Flags |=
CONSOLE_OEMFONT_DISPLAY;
01111 }
01112
01113
01114
01115
01116
if ((ulFlagPrev &
CONSOLE_OEMFONT_DISPLAY) != (ScreenInfo->Flags &
CONSOLE_OEMFONT_DISPLAY)) {
01117
if (ulFlagPrev &
CONSOLE_OEMFONT_DISPLAY) {
01118
01119
01120
01121
DBGCHARS((
"SetScreenBufferFont converts UnicodeOem to Unicode\n"));
01122
FalseUnicodeToRealUnicode(
01123 ScreenInfo->BufferInfo.TextInfo.TextRows,
01124 ScreenInfo->ScreenBufferSize.X * ScreenInfo->ScreenBufferSize.Y,
01125 ScreenInfo->Console->OutputCP);
01126 }
else {
01127
01128
01129
01130
DBGCHARS((
"SetScreenBufferFont converts Unicode to UnicodeOem\n"));
01131
RealUnicodeToFalseUnicode(
01132 ScreenInfo->BufferInfo.TextInfo.TextRows,
01133 ScreenInfo->ScreenBufferSize.X * ScreenInfo->ScreenBufferSize.Y,
01134 ScreenInfo->Console->OutputCP);
01135 }
01136 }
01137
01138
01139
01140
01141
Status =
StoreTextBufferFontInfo(ScreenInfo,
01142 FontIndex,
01143 FontSize,
01144
FontInfo[FontIndex].Family,
01145
FontInfo[FontIndex].Weight,
01146
FontInfo[FontIndex].FaceName,
01147 CodePage);
01148
if (!
NT_SUCCESS(
Status)) {
01149
return((ULONG)
Status);
01150 }
01151
01152
01153
01154
01155
Status =
SetFont(ScreenInfo);
01156
if (!
NT_SUCCESS(
Status)) {
01157
return((ULONG)
Status);
01158 }
01159
01160
01161
01162
01163
01164
GetWindowLimits(ScreenInfo, &WindowLimits);
01165
if (WindowLimits.
MaximumWindowSize.X <
CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
01166 ScreenInfo->Window.Right -=
CONSOLE_WINDOW_SIZE_X(ScreenInfo) - WindowLimits.
MaximumWindowSize.X;
01167 ScreenInfo->WindowMaximizedX = (ScreenInfo->Window.Left == 0 &&
01168 (
SHORT)(ScreenInfo->Window.Right+1) == ScreenInfo->ScreenBufferSize.X);
01169 }
01170
if (WindowLimits.
MaximumWindowSize.Y <
CONSOLE_WINDOW_SIZE_Y(ScreenInfo)) {
01171 ScreenInfo->Window.Bottom -=
CONSOLE_WINDOW_SIZE_Y(ScreenInfo) - WindowLimits.
MaximumWindowSize.Y;
01172
if (ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y > ScreenInfo->Window.Bottom) {
01173 ScreenInfo->Window.Top += ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y - ScreenInfo->Window.Bottom;
01174 ScreenInfo->Window.Bottom += ScreenInfo->BufferInfo.TextInfo.CursorPosition.Y - ScreenInfo->Window.Bottom;
01175 }
01176 ScreenInfo->WindowMaximizedY = (ScreenInfo->Window.Top == 0 &&
01177 (
SHORT)(ScreenInfo->Window.Bottom+1) == ScreenInfo->ScreenBufferSize.Y);
01178 }
01179
if (WindowLimits.
MinimumWindowSize.X >
CONSOLE_WINDOW_SIZE_X(ScreenInfo)) {
01180
if (WindowLimits.
MinimumWindowSize.X > ScreenInfo->ScreenBufferSize.X) {
01181 COORD NewBufferSize;
01182
01183 NewBufferSize.X = WindowLimits.
MinimumWindowSize.X;
01184 NewBufferSize.Y = ScreenInfo->ScreenBufferSize.Y;
01185
ResizeScreenBuffer(ScreenInfo,
01186 NewBufferSize,
01187
FALSE
01188 );
01189 }
01190
if ((ScreenInfo->Window.Left+WindowLimits.
MinimumWindowSize.X) > ScreenInfo->ScreenBufferSize.X) {
01191 ScreenInfo->Window.Left = 0;
01192 ScreenInfo->Window.Right = WindowLimits.
MinimumWindowSize.X-1;
01193 }
else {
01194 ScreenInfo->Window.Right = ScreenInfo->Window.Left+WindowLimits.
MinimumWindowSize.X-1;
01195 }
01196 ScreenInfo->WindowMaximizedX = (ScreenInfo->Window.Left == 0 &&
01197 (
SHORT)(ScreenInfo->Window.Right+1) == ScreenInfo->ScreenBufferSize.X);
01198 }
01199
01200
SetLineChar(ScreenInfo);
01201 {
01202 COORD WindowedWindowSize;
01203
01204 WindowedWindowSize.X =
CONSOLE_WINDOW_SIZE_X(ScreenInfo);
01205 WindowedWindowSize.Y =
CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
01206
01207
01208
#if defined(FE_IME)
01209
if (CONSOLE_IS_DBCS_OUTPUTCP(ScreenInfo->Console))
01210 {
01211 PCONVERSIONAREA_INFORMATION ConvAreaInfo;
01212
01213 ConvAreaInfo = ScreenInfo->Console->ConsoleIme.ConvAreaRoot;
01214
while (ConvAreaInfo) {
01215
01216
Status =
StoreTextBufferFontInfo(ConvAreaInfo->ScreenBuffer,
01217
SCR_FONTNUMBER(ScreenInfo),
01218
SCR_FONTSIZE(ScreenInfo),
01219
SCR_FAMILY(ScreenInfo),
01220
SCR_FONTWEIGHT(ScreenInfo),
01221
SCR_FACENAME(ScreenInfo),
01222
SCR_FONTCODEPAGE(ScreenInfo));
01223
if (!
NT_SUCCESS(
Status)) {
01224
return((ULONG)
Status);
01225 }
01226
01227 ConvAreaInfo->ScreenBuffer->Window = ScreenInfo->Window;
01228 ConvAreaInfo->ScreenBuffer->BufferInfo.TextInfo.ModeIndex = ScreenInfo->BufferInfo.TextInfo.ModeIndex;
01229
01230 ConvAreaInfo = ConvAreaInfo->ConvAreaNext;
01231 }
01232 }
01233
#endif // FE_IME
01234
}
01235
01236
01237
01238
01239
01240
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
01241
SetWindowSize(ScreenInfo);
01242 }
01243
01244
01245
01246
01247
01248
SetCursorInformation(ScreenInfo,
01249 ScreenInfo->BufferInfo.TextInfo.CursorSize,
01250 (BOOLEAN)ScreenInfo->BufferInfo.TextInfo.CursorVisible
01251 );
01252
01253
WriteToScreen(ScreenInfo,
01254 &ScreenInfo->Window);
01255
return STATUS_SUCCESS;
01256 }
01257
01258
01259
NTSTATUS
01260 SetFont(
01261 IN OUT
PSCREEN_INFORMATION ScreenInfo
01262 )
01263 {
01264
if (
ACTIVE_SCREEN_BUFFER(ScreenInfo)) {
01265
int FontIndex =
FindCreateFont(
SCR_FAMILY(ScreenInfo),
01266
SCR_FACENAME(ScreenInfo),
01267
SCR_FONTSIZE(ScreenInfo),
01268
SCR_FONTWEIGHT(ScreenInfo),
01269
SCR_FONTCODEPAGE(ScreenInfo));
01270
if (SelectObject(ScreenInfo->Console->hDC,
FontInfo[FontIndex].
hFont)==0)
01271
return STATUS_INVALID_PARAMETER;
01272
01273
if ((
DWORD)FontIndex !=
SCR_FONTNUMBER(ScreenInfo)) {
01274
NTSTATUS Status;
01275
Status =
StoreTextBufferFontInfo(ScreenInfo,
01276 FontIndex,
01277
FontInfo[FontIndex].
Size,
01278
FontInfo[FontIndex].Family,
01279
FontInfo[FontIndex].Weight,
01280
FontInfo[FontIndex].FaceName,
01281 ScreenInfo->Console->OutputCP);
01282
if (!
NT_SUCCESS(
Status)) {
01283
return((ULONG)
Status);
01284 }
01285 }
01286
01287
01288
01289
01290
01291
01292
01293 {
01294 TEXTMETRIC tmi;
01295
01296 GetTextMetricsW( ScreenInfo->Console->hDC, &tmi);
01297
ASSERT ((tmi.tmPitchAndFamily & 1) == 0);
01298 ScreenInfo->Console->LastAttributes = ScreenInfo->Attributes;
01299 SetTextColor(ScreenInfo->Console->hDC,
ConvertAttrToRGB(ScreenInfo->Console,
LOBYTE(ScreenInfo->Attributes)));
01300 SetBkColor(ScreenInfo->Console->hDC,
ConvertAttrToRGB(ScreenInfo->Console,
LOBYTE(ScreenInfo->Attributes >> 4)));
01301 }
01302 }
01303
return STATUS_SUCCESS;
01304 }
01305
01306
int
01307 ConvertToOem(
01308 IN UINT Codepage,
01309 IN LPWSTR Source,
01310 IN
int SourceLength,
01311 OUT LPSTR Target,
01312 IN
int TargetLength
01313 )
01314 {
01315
DBGCHARS((
"ConvertToOem U->%d %.*ls\n", Codepage,
01316 SourceLength > 10 ? 10 : SourceLength, Source));
01317
if (Codepage ==
OEMCP) {
01318 ULONG Length;
01319
NTSTATUS Status;
01320
01321
Status =
RtlUnicodeToOemN(Target,
01322 TargetLength,
01323 &Length,
01324 Source,
01325 SourceLength *
sizeof(WCHAR)
01326 );
01327
if (!
NT_SUCCESS(
Status)) {
01328
return 0;
01329 }
else {
01330
return Length;
01331 }
01332 }
else {
01333
return WideCharToMultiByte(Codepage,
01334 0,
01335 Source,
01336 SourceLength,
01337 Target,
01338 TargetLength,
01339
NULL,
01340
NULL);
01341 }
01342 }
01343
01344
int
01345 ConvertInputToUnicode(
01346 IN UINT Codepage,
01347 IN LPSTR Source,
01348 IN
int SourceLength,
01349 OUT LPWSTR Target,
01350 IN
int TargetLength
01351 )
01352
01353
01354
01355 {
01356
DBGCHARS((
"ConvertInputToUnicode %d->U %.*s\n", Codepage,
01357 SourceLength > 10 ? 10 : SourceLength, Source));
01358
if (Codepage ==
OEMCP) {
01359 ULONG Length;
01360
NTSTATUS Status;
01361
01362
Status =
RtlOemToUnicodeN(Target,
01363 TargetLength *
sizeof(WCHAR),
01364 &Length,
01365 Source,
01366 SourceLength
01367 );
01368
if (!
NT_SUCCESS(
Status)) {
01369
return 0;
01370 }
else {
01371
return Length /
sizeof(WCHAR);
01372 }
01373 }
else {
01374
return MultiByteToWideChar(Codepage,
01375 0,
01376 Source,
01377 SourceLength,
01378 Target,
01379 TargetLength);
01380 }
01381 }
01382
01383
int
01384 ConvertOutputToUnicode(
01385 IN UINT Codepage,
01386 IN LPSTR Source,
01387 IN
int SourceLength,
01388 OUT LPWSTR Target,
01389 IN
int TargetLength
01390 )
01391
01392
01393
01394
01395
01396 {
01397
NTSTATUS Status;
01398 ULONG Length;
01399
CHAR StackBuffer[
STACK_BUFFER_SIZE];
01400 LPSTR pszT;
01401
01402
DBGCHARS((
"ConvertOutputToUnicode %d->U %.*s\n", Codepage,
01403 SourceLength > 10 ? 10 : SourceLength, Source));
01404
if (Codepage ==
OEMCP) {
01405
Status =
RtlCustomCPToUnicodeN(&
GlyphCP,
01406 Target,
01407 TargetLength *
sizeof(WCHAR),
01408 &Length,
01409 Source,
01410 SourceLength
01411 );
01412
if (!
NT_SUCCESS(
Status)) {
01413
return 0;
01414 }
else {
01415
return Length /
sizeof(WCHAR);
01416 }
01417 }
01418
01419
if (TargetLength >
STACK_BUFFER_SIZE) {
01420 pszT = (LPSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),SourceLength);
01421
if (pszT ==
NULL) {
01422
return 0;
01423 }
01424 }
else {
01425 pszT = StackBuffer;
01426 }
01427 RtlCopyMemory(pszT, Source, SourceLength);
01428 Length = MultiByteToWideChar(Codepage, MB_USEGLYPHCHARS,
01429 pszT, SourceLength, Target, TargetLength);
01430
if (pszT != StackBuffer) {
01431
ConsoleHeapFree(pszT);
01432 }
01433
return Length;
01434 }
01435
01436
#if defined(FE_SB)
01437
WCHAR
01438 SB_CharToWcharGlyph(
01439 IN UINT Codepage,
01440 IN
char Ch)
01441 #
else
01442 WCHAR
01443 CharToWcharGlyph(
01444 IN UINT Codepage,
01445 IN
char Ch)
01446 #endif
01447 {
01448 WCHAR wch;
01449
if (Codepage ==
OEMCP) {
01450
RtlCustomCPToUnicodeN(&
GlyphCP, &wch,
sizeof(wch),
NULL, &Ch,
sizeof(Ch));
01451 }
else {
01452 MultiByteToWideChar(Codepage, MB_USEGLYPHCHARS, &Ch, 1, &wch, 1);
01453 }
01454
#ifdef DEBUG_PRINT
01455
if (Ch > 0x7F) {
01456
DBGCHARS((
"CharToWcharGlyph %d 0x%02x -> 0x%04x\n",Codepage,(UCHAR)Ch,wch));
01457 }
01458
#endif
01459
return wch;
01460 }
01461
01462
#if defined(FE_SB)
01463
WCHAR
01464 SB_CharToWchar(
01465 IN UINT Codepage,
01466 IN
char Ch)
01467 #
else
01468 WCHAR
01469 CharToWchar(
01470 IN UINT Codepage,
01471 IN
char Ch)
01472 #endif
01473 {
01474 WCHAR wch;
01475
if (Codepage ==
OEMCP) {
01476
RtlOemToUnicodeN(&wch,
sizeof(wch),
NULL, &Ch,
sizeof(Ch));
01477 }
else {
01478 MultiByteToWideChar(Codepage, 0, &Ch, 1, &wch, 1);
01479 }
01480
#ifdef DEBUG_PRINT
01481
if (Ch > 0x7F) {
01482
DBGCHARS((
"CharToWchar %d 0x%02x -> 0x%04x\n",Codepage,(UCHAR)Ch,wch));
01483 }
01484
#endif
01485
return wch;
01486 }
01487
01488
char
01489 WcharToChar(
01490 IN UINT Codepage,
01491 IN WCHAR Wchar)
01492 {
01493
char ch;
01494
if (Codepage ==
OEMCP) {
01495
RtlUnicodeToOemN(&ch,
sizeof(ch),
NULL, &Wchar,
sizeof(Wchar));
01496 }
else {
01497 WideCharToMultiByte(Codepage, 0, &Wchar, 1, &ch, 1,
NULL,
NULL);
01498 }
01499
#ifdef DEBUG_PRINT
01500
if (Wchar > 0x007F) {
01501
DBGCHARS((
"WcharToChar %d 0x%04x -> 0x%02x\n",Codepage,Wchar,(UCHAR)ch));
01502 }
01503
#endif
01504
return ch;
01505 }
01506
01507
int
01508 ConvertOutputToOem(
01509 IN UINT Codepage,
01510 IN LPWSTR Source,
01511 IN
int SourceLength,
01512 OUT LPSTR Target,
01513 IN
int TargetLength
01514 )
01515
01516
01517
01518
01519
01520
01521 {
01522
if (Codepage ==
OEMCP) {
01523
NTSTATUS Status;
01524 ULONG Length;
01525
01526
Status =
RtlUnicodeToOemN(Target,
01527 TargetLength,
01528 &Length,
01529 Source,
01530 SourceLength *
sizeof(WCHAR)
01531 );
01532
if (
NT_SUCCESS(
Status)) {
01533
return Length;
01534 }
else {
01535
return 0;
01536 }
01537 }
else {
01538
ASSERT (Source != (LPWSTR)Target);
01539
#ifdef SOURCE_EQ_TARGET
01540
LPSTR pszDestTmp;
01541
CHAR StackBuffer[
STACK_BUFFER_SIZE];
01542
01543
DBGCHARS((
"ConvertOutputToOem U->%d %.*ls\n", Codepage,
01544 SourceLength > 10 ? 10 : SourceLength, Source));
01545
01546
if (TargetLength >
STACK_BUFFER_SIZE) {
01547 pszDestTmp = (LPSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),TargetLength);
01548
if (pszDestTmp ==
NULL) {
01549
return 0;
01550 }
01551 }
else {
01552 pszDestTmp = StackBuffer;
01553 }
01554 TargetLength = WideCharToMultiByte(Codepage, 0,
01555 Source, SourceLength,
01556 pszDestTmp, TargetLength,
NULL,
NULL);
01557
01558 RtlCopyMemory(Target, pszDestTmp, TargetLength);
01559
if (pszDestTmp != StackBuffer) {
01560
ConsoleHeapFree(pszDestTmp);
01561 }
01562
return TargetLength;
01563
#else
01564
DBGCHARS((
"ConvertOutputToOem U->%d %.*ls\n", Codepage,
01565 SourceLength > 10 ? 10 : SourceLength, Source));
01566
return WideCharToMultiByte(Codepage, 0,
01567 Source, SourceLength, Target, TargetLength,
NULL,
NULL);
01568
#endif
01569
}
01570 }
01571
01572
NTSTATUS
01573 RealUnicodeToFalseUnicode(
01574 IN OUT LPWSTR Source,
01575 IN
int SourceLength,
01576 IN UINT Codepage
01577 )
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588 {
01589
NTSTATUS Status;
01590 LPSTR Temp;
01591 ULONG TempLength;
01592 ULONG Length;
01593
CHAR StackBuffer[
STACK_BUFFER_SIZE];
01594
BOOL NormalChars;
01595
int i;
01596
01597
DBGCHARS((
"RealUnicodeToFalseUnicode U->%d:ACP->U %.*ls\n", Codepage,
01598 SourceLength > 10 ? 10 : SourceLength, Source));
01599
#if defined(FE_SB)
01600
if (
OEMCP ==
WINDOWSCP && Codepage ==
WINDOWSCP)
01601
return STATUS_SUCCESS;
01602
if (SourceLength == 0 )
01603
return STATUS_SUCCESS;
01604
#endif
01605
NormalChars =
TRUE;
01606
for (i=0;i<SourceLength;i++) {
01607
if (Source[i] > 0x7f) {
01608 NormalChars =
FALSE;
01609
break;
01610 }
01611 }
01612
if (NormalChars) {
01613
return STATUS_SUCCESS;
01614 }
01615 TempLength = SourceLength;
01616
if (TempLength >
STACK_BUFFER_SIZE) {
01617 Temp = (LPSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),TempLength);
01618
if (Temp ==
NULL) {
01619
return STATUS_NO_MEMORY;
01620 }
01621 }
else {
01622 Temp = StackBuffer;
01623 }
01624
if (Codepage ==
OEMCP) {
01625
Status =
RtlUnicodeToOemN(Temp,
01626 TempLength,
01627 &Length,
01628 Source,
01629 SourceLength *
sizeof(WCHAR)
01630 );
01631 }
else {
01632
Status = WideCharToMultiByte(Codepage,
01633 0,
01634 Source,
01635 SourceLength,
01636 Temp,
01637 TempLength,
01638
NULL,
01639
NULL);
01640 }
01641
if (!
NT_SUCCESS(
Status)) {
01642
if (TempLength >
STACK_BUFFER_SIZE) {
01643
ConsoleHeapFree(Temp);
01644 }
01645
return Status;
01646 }
01647
01648
if (
CONSOLE_IS_DBCS_ENABLED()) {
01649 MultiByteToWideChar(
USACP,
01650 0,
01651 Temp,
01652 TempLength,
01653 Source,
01654 SourceLength
01655 );
01656 }
else {
01657
Status =
RtlMultiByteToUnicodeN(Source,
01658 SourceLength *
sizeof(WCHAR),
01659 &Length,
01660 Temp,
01661 TempLength
01662 );
01663 }
01664
01665
if (TempLength >
STACK_BUFFER_SIZE) {
01666
ConsoleHeapFree(Temp);
01667 }
01668
if (!
NT_SUCCESS(
Status)) {
01669
return Status;
01670 }
else {
01671
return STATUS_SUCCESS;
01672 }
01673 }
01674
01675
NTSTATUS
01676 FalseUnicodeToRealUnicode(
01677 IN OUT LPWSTR Source,
01678 IN
int SourceLength,
01679 IN UINT Codepage
01680 )
01681
01682
01683
01684
01685
01686
01687
01688
01689 {
01690
NTSTATUS Status;
01691 LPSTR Temp;
01692 ULONG TempLength;
01693 ULONG Length;
01694
CHAR StackBuffer[
STACK_BUFFER_SIZE];
01695
BOOL NormalChars;
01696
int i;
01697
01698
DBGCHARS((
"UnicodeAnsiToUnicodeAnsi U->ACP:%d->U %.*ls\n", Codepage,
01699 SourceLength > 10 ? 10 : SourceLength, Source));
01700
#if defined(FE_SB)
01701
if (
OEMCP ==
WINDOWSCP && Codepage ==
WINDOWSCP)
01702
return STATUS_SUCCESS;
01703
if (SourceLength == 0 )
01704
return STATUS_SUCCESS;
01705
#endif
01706
NormalChars =
TRUE;
01707
01708
01709
01710
01711
for (i=0;i<SourceLength;i++) {
01712
if ((
USHORT)(Source[i] - 0x20) > 0x5e) {
01713 NormalChars =
FALSE;
01714
break;
01715 }
01716 }
01717
if (NormalChars) {
01718
return STATUS_SUCCESS;
01719 }
01720
01721 TempLength = SourceLength;
01722
if (TempLength >
STACK_BUFFER_SIZE) {
01723 Temp = (LPSTR)
ConsoleHeapAlloc(
MAKE_TAG(
TMP_TAG ),TempLength);
01724
if (Temp ==
NULL) {
01725
return STATUS_NO_MEMORY;
01726 }
01727 }
else {
01728 Temp = StackBuffer;
01729 }
01730
if (
CONSOLE_IS_DBCS_ENABLED()) {
01731
Status = WideCharToMultiByte(
USACP,
01732 0,
01733 Source,
01734 SourceLength,
01735 Temp,
01736 TempLength,
01737
NULL,
01738
NULL);
01739 }
else {
01740
Status =
RtlUnicodeToMultiByteN(Temp,
01741 TempLength,
01742 &Length,
01743 Source,
01744 SourceLength *
sizeof(WCHAR)
01745 );
01746 }
01747
01748
if (!
NT_SUCCESS(
Status)) {
01749
if (TempLength >
STACK_BUFFER_SIZE) {
01750
ConsoleHeapFree(Temp);
01751 }
01752
return Status;
01753 }
01754
if (Codepage ==
OEMCP) {
01755
Status =
RtlCustomCPToUnicodeN(&
GlyphCP,
01756 Source,
01757 SourceLength *
sizeof(WCHAR),
01758 &Length,
01759 Temp,
01760 TempLength
01761 );
01762 }
else {
01763
Status = MultiByteToWideChar(Codepage,
01764 MB_USEGLYPHCHARS,
01765 Temp,
01766 TempLength*
sizeof(WCHAR),
01767 Source,
01768 SourceLength);
01769 }
01770
#if defined(FE_SB)
01771
if (SourceLength >
STACK_BUFFER_SIZE) {
01772
ConsoleHeapFree(Temp);
01773 }
01774
#else
01775
if (TempLength >
STACK_BUFFER_SIZE) {
01776
ConsoleHeapFree(Temp);
01777 }
01778
#endif
01779
if (!
NT_SUCCESS(
Status)) {
01780
return Status;
01781 }
else {
01782
return STATUS_SUCCESS;
01783 }
01784 }
01785
01786
01787 BOOL InitializeCustomCP() {
01788 PPEB pPeb;
01789
01790 pPeb = NtCurrentPeb();
01791
if ((pPeb ==
NULL) || (pPeb->OemCodePageData ==
NULL)) {
01792
return FALSE;
01793 }
01794
01795
01796
01797
01798
RtlInitCodePageTable(pPeb->OemCodePageData, &
GlyphCP);
01799
01800
01801
01802
01803 RtlCopyMemory(
GlyphTable,
GlyphCP.MultiByteTable, 256 *
sizeof(
USHORT));
01804
01805
01806
01807
01808 MultiByteToWideChar(CP_OEMCP, MB_USEGLYPHCHARS,
01809
"\x20\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
01810
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",
01811 0x20,
GlyphTable, 0x20);
01812 MultiByteToWideChar(CP_OEMCP, MB_USEGLYPHCHARS,
01813
"\x7f", 1, &
GlyphTable[0x7f], 1);
01814
01815
01816
01817
01818
01819
GlyphCP.MultiByteTable =
GlyphTable;
01820
01821
#if defined(FE_SB) && defined(i386)
01822
if (ISNECPC98(gdwMachineId)) {
01823 InitializeNEC_OS2_CP();
01824 }
01825
#endif
01826
return TRUE;
01827 }
01828
01829
#if defined(FE_SB)
01830
VOID
01831 SetConsoleCPInfo(
01832 IN
PCONSOLE_INFORMATION Console,
01833 IN BOOL Output
01834 )
01835 {
01836
if (Output) {
01837
if (! GetCPInfo(Console->OutputCP,
01838 &Console->OutputCPInfo)) {
01839 Console->OutputCPInfo.LeadByte[0] = 0;
01840 }
01841 }
01842
else {
01843
if (! GetCPInfo(Console->CP,
01844 &Console->CPInfo)) {
01845 Console->CPInfo.LeadByte[0] = 0;
01846 }
01847 }
01848 }
01849
01850
BOOL
01851 CheckBisectStringW(
01852 IN
PSCREEN_INFORMATION ScreenInfo,
01853 IN DWORD CodePage,
01854 IN PWCHAR Buffer,
01855 IN DWORD NumWords,
01856 IN DWORD NumBytes
01857 )
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885 {
01886
while(NumWords && NumBytes) {
01887
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,CodePage,*Buffer)) {
01888
if (NumBytes < 2)
01889
return TRUE;
01890
else {
01891 NumWords--;
01892 NumBytes -= 2;
01893
Buffer++;
01894 }
01895 }
01896
else {
01897 NumWords--;
01898 NumBytes--;
01899
Buffer++;
01900 }
01901 }
01902
return FALSE;
01903 }
01904
01905
BOOL
01906 CheckBisectProcessW(
01907 IN
PSCREEN_INFORMATION ScreenInfo,
01908 IN DWORD CodePage,
01909 IN PWCHAR Buffer,
01910 IN DWORD NumWords,
01911 IN DWORD NumBytes,
01912 IN SHORT OriginalXPosition,
01913 IN BOOL Echo
01914 )
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 {
01945 WCHAR Char;
01946 ULONG TabSize;
01947
01948
if (ScreenInfo->OutputMode & ENABLE_PROCESSED_OUTPUT) {
01949
while(NumWords && NumBytes) {
01950 Char = *
Buffer;
01951
if (Char >= (WCHAR)
' ') {
01952
if (IsConsoleFullWidth(ScreenInfo->Console->hDC,CodePage,Char)) {
01953
if (NumBytes < 2)
01954
return TRUE;
01955
else {
01956 NumWords--;
01957 NumBytes -= 2;
01958
Buffer++;
01959 OriginalXPosition += 2;
01960 }
01961 }
01962
else {
01963 NumWords--;
01964 NumBytes--;
01965
Buffer++;
01966 OriginalXPosition++;
01967 }
01968 }
01969
else {
01970 NumWords--;
01971
Buffer++;
01972
switch (Char) {
01973
case UNICODE_BELL:
01974
if (
Echo)
01975
goto CtrlChar;
01976
break;
01977
case UNICODE_BACKSPACE:
01978
case UNICODE_LINEFEED:
01979
case UNICODE_CARRIAGERETURN:
01980
break;
01981
case UNICODE_TAB:
01982 TabSize =
NUMBER_OF_SPACES_IN_TAB(OriginalXPosition);
01983 OriginalXPosition = (
SHORT)(OriginalXPosition + TabSize);
01984
if (NumBytes < TabSize)
01985
return TRUE;
01986 NumBytes -= TabSize;
01987
break;
01988
default:
01989
if (
Echo) {
01990 CtrlChar:
01991
if (NumBytes < 2)
01992
return TRUE;
01993 NumBytes -= 2;
01994 OriginalXPosition += 2;
01995 }
else {
01996 NumBytes--;
01997 OriginalXPosition++;
01998 }
01999 }
02000 }
02001 }
02002
return FALSE;
02003 }
02004
else {
02005
return CheckBisectStringW(ScreenInfo,
02006 CodePage,
02007 Buffer,
02008 NumWords,
02009 NumBytes);
02010 }
02011 }
02012
#endif // FE_SB