00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "precomp.h"
00024
#pragma hdrstop
00025
00026
#if defined(FE_SB)
00027
00028
00029
VOID
00030 RebaseFontImageList(
00031 IN
PFONT_IMAGE NewFontImage,
00032 IN PBYTE OldFontImage
00033 )
00034 {
00035 PLIST_ENTRY ImageList;
00036
PBYTE BaseImage = (
PBYTE)NewFontImage;
00037
00038
do {
00039 ImageList = &NewFontImage->ImageList;
00040
if (ImageList->Blink)
00041 ImageList->Blink = (PLIST_ENTRY)((
PBYTE)ImageList->Blink - OldFontImage + BaseImage);
00042
if (ImageList->Flink)
00043 ImageList->Flink = (PLIST_ENTRY)((
PBYTE)ImageList->Flink - OldFontImage + BaseImage);
00044 }
while (NewFontImage = (
PFONT_IMAGE)ImageList->Flink);
00045 }
00046
00047
00048
00049
00050
00051 ULONG
00052
CreateFontCache(
00053 OUT
PFONT_CACHE_INFORMATION *FontCache
00054 )
00055 {
00056
00057
00058
00059
00060 *FontCache =
ConsoleHeapAlloc(HEAP_ZERO_MEMORY,
sizeof(
FONT_CACHE_INFORMATION));
00061
if (*FontCache ==
NULL) {
00062
return (ULONG)STATUS_NO_MEMORY;
00063 }
00064
00065
return (ULONG)(STATUS_SUCCESS);
00066 }
00067
00068
00069 ULONG
00070
DestroyFontCache(
00071 IN
PFONT_CACHE_INFORMATION FontCache
00072 )
00073 {
00074
if (FontCache !=
NULL)
00075 {
00076
PFONT_HIGHLOW_OFFSET FontOffsetHighLow;
00077
PFONT_LOW_OFFSET FontOffsetLow;
00078
PFONT_IMAGE FontImage;
00079
UINT i, j, k;
00080
00081
for (i=0;
00082 i <
sizeof(FontCache->FontTable.FontOffsetHighHigh)/
sizeof(
PFONT_HIGHLOW_OFFSET);
00083 i++)
00084 {
00085
if (FontOffsetHighLow = FontCache->FontTable.FontOffsetHighHigh[i])
00086 {
00087
for (j=0;
00088 j <
sizeof(FontOffsetHighLow->
FontOffsetHighLow)/
sizeof(
PFONT_LOW_OFFSET);
00089 j++)
00090 {
00091
if (FontOffsetLow = FontOffsetHighLow->
FontOffsetHighLow[j])
00092 {
00093
for (k=0;
00094 k <
sizeof(FontOffsetLow->
FontOffsetLow)/
sizeof(
PFONT_IMAGE);
00095 k++)
00096 {
00097
if (FontImage = FontOffsetLow->
FontOffsetLow[k])
00098 {
00099
ConsoleHeapFree(FontImage);
00100 }
00101 }
00102
ConsoleHeapFree(FontOffsetLow);
00103 }
00104 }
00105
ConsoleHeapFree(FontOffsetHighLow);
00106 }
00107 }
00108
if (FontCache->BaseImageBits) {
00109
ConsoleHeapFree(FontCache->BaseImageBits);
00110 }
00111
ConsoleHeapFree(FontCache);
00112 }
00113
return (ULONG)(STATUS_SUCCESS);
00114 }
00115
00116 ULONG
00117 RebaseFontCache(
00118 IN
PFONT_CACHE_INFORMATION FontCache,
00119 IN PBYTE OldBaseImage
00120 )
00121 {
00122
if (FontCache !=
NULL)
00123 {
00124
PFONT_HIGHLOW_OFFSET FontOffsetHighLow;
00125
PFONT_LOW_OFFSET FontOffsetLow;
00126
PFONT_IMAGE FontImage;
00127
UINT i, j, k;
00128
00129
for (i=0;
00130 i <
sizeof(FontCache->FontTable.FontOffsetHighHigh)/
sizeof(
PFONT_HIGHLOW_OFFSET);
00131 i++)
00132 {
00133
if (FontOffsetHighLow = FontCache->FontTable.FontOffsetHighHigh[i])
00134 {
00135
for (j=0;
00136 j <
sizeof(FontOffsetHighLow->
FontOffsetHighLow)/
sizeof(
PFONT_LOW_OFFSET);
00137 j++)
00138 {
00139
if (FontOffsetLow = FontOffsetHighLow->
FontOffsetHighLow[j])
00140 {
00141
for (k=0;
00142 k <
sizeof(FontOffsetLow->
FontOffsetLow)/
sizeof(
PFONT_IMAGE);
00143 k++)
00144 {
00145
if (FontImage = FontOffsetLow->
FontOffsetLow[k])
00146 {
00147 LIST_ENTRY ImageList;
00148
00149
do {
00150 ImageList = FontImage->
ImageList;
00151
if (FontImage->
ImageBits) {
00152 FontImage->
ImageBits = FontImage->
ImageBits - OldBaseImage
00153 + FontCache->BaseImageBits;
00154 }
00155 }
while (FontImage = (
PFONT_IMAGE)ImageList.Flink);
00156 }
00157 }
00158 }
00159 }
00160 }
00161 }
00162 }
00163
return (ULONG)(STATUS_SUCCESS);
00164 }
00165
00166
00167
00168
#define CALC_BITMAP_BITS_FOR_X( FontSizeX, dwAlign ) \
00169
( ( ( FontSizeX * BITMAP_BITS_PIXEL + (dwAlign-1) ) & ~(dwAlign-1)) >> BITMAP_ARRAY_BYTE )
00170
00171
00172
00173
00174
DWORD
00175
CalcBitmapBufferSize(
00176 IN COORD FontSize,
00177 IN DWORD dwAlign
00178 )
00179 {
00180
DWORD uiCount;
00181
00182 uiCount =
CALC_BITMAP_BITS_FOR_X(FontSize.X,
00183 (dwAlign==BYTE_ALIGN ? BITMAP_BITS_BYTE_ALIGN : BITMAP_BITS_WORD_ALIGN));
00184 uiCount = uiCount *
BITMAP_PLANES * FontSize.Y;
00185
return uiCount;
00186 }
00187
00188
VOID
00189
AlignCopyMemory(
00190 OUT PBYTE pDestBits,
00191 IN DWORD dwDestAlign,
00192 IN PBYTE pSrcBits,
00193 IN DWORD dwSrcAlign,
00194 IN COORD FontSize
00195 )
00196 {
00197
DWORD dwDestBufferSize;
00198 COORD coord;
00199
00200
if (dwDestAlign == dwSrcAlign) {
00201 dwDestBufferSize =
CalcBitmapBufferSize(FontSize, dwDestAlign);
00202 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize);
00203
return;
00204 }
00205
00206
switch (dwDestAlign) {
00207
default:
00208
case WORD_ALIGN:
00209
switch (dwSrcAlign) {
00210
default:
00211
00212
00213
00214
case WORD_ALIGN:
00215 dwDestBufferSize =
CalcBitmapBufferSize(FontSize, dwDestAlign);
00216 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize);
00217
break;
00218
00219
00220
00221
case BYTE_ALIGN:
00222 dwDestBufferSize =
CalcBitmapBufferSize(FontSize, dwDestAlign);
00223
if (((FontSize.X %
BITMAP_BITS_BYTE_ALIGN) == 0) &&
00224 ((FontSize.X %
BITMAP_BITS_WORD_ALIGN) == 0) ) {
00225 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize);
00226 }
00227
else {
00228 RtlZeroMemory(pDestBits, dwDestBufferSize);
00229
for (coord.Y=0; coord.Y < FontSize.Y; coord.Y++) {
00230
for (coord.X=0;
00231 coord.X <
CALC_BITMAP_BITS_FOR_X(FontSize.X, BITMAP_BITS_BYTE_ALIGN);
00232 coord.X++) {
00233 *pDestBits++ = *pSrcBits++;
00234 }
00235
if (
CALC_BITMAP_BITS_FOR_X(FontSize.X, BITMAP_BITS_BYTE_ALIGN) & 1)
00236 pDestBits++;
00237 }
00238 }
00239
break;
00240 }
00241
break;
00242
case BYTE_ALIGN:
00243
switch (dwSrcAlign) {
00244
00245
00246
00247
case BYTE_ALIGN:
00248 dwDestBufferSize =
CalcBitmapBufferSize(FontSize, dwDestAlign);
00249 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize);
00250
break;
00251
default:
00252
00253
00254
00255
case WORD_ALIGN:
00256 dwDestBufferSize =
CalcBitmapBufferSize(FontSize, dwDestAlign);
00257
if (((FontSize.X %
BITMAP_BITS_BYTE_ALIGN) == 0) &&
00258 ((FontSize.X %
BITMAP_BITS_WORD_ALIGN) == 0) ) {
00259 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize);
00260 }
00261
else {
00262 RtlZeroMemory(pDestBits, dwDestBufferSize);
00263
for (coord.Y=0; coord.Y < FontSize.Y; coord.Y++) {
00264
for (coord.X=0;
00265 coord.X <
CALC_BITMAP_BITS_FOR_X(FontSize.X, BITMAP_BITS_BYTE_ALIGN);
00266 coord.X++) {
00267 *pDestBits++ = *pSrcBits++;
00268 }
00269
if (
CALC_BITMAP_BITS_FOR_X(FontSize.X, BITMAP_BITS_BYTE_ALIGN) & 1)
00270 pSrcBits++;
00271 }
00272 }
00273
break;
00274 }
00275
break;
00276 }
00277 }
00278
00279
00280
00281
NTSTATUS
00282 GetStretchImage(
00283 IN COORD FontSize,
00284 IN
PFONT_IMAGE FontImage,
00285 OUT
PFONT_IMAGE *pFontImage
00286 )
00287 {
00288
PFONT_IMAGE NearFont;
00289
DWORD Find;
00290 COORD FontDelta;
00291 HDC hDC;
00292 HDC hSrcMemDC, hDestMemDC;
00293 HBITMAP hSrcBmp, hDestBmp;
00294
DWORD BufferSize;
00295
00296 Find = (
DWORD)-1;
00297 NearFont =
NULL;
00298
do {
00299 FontDelta.X =
abs(FontSize.X - FontImage->FontSize.X);
00300 FontDelta.Y =
abs(FontSize.Y - FontImage->FontSize.Y);
00301
if (Find > (
DWORD)(FontDelta.X + FontDelta.Y))
00302 {
00303 Find = (
DWORD)(FontDelta.X + FontDelta.Y);
00304 NearFont = FontImage;
00305 }
00306 }
00307
while (FontImage = (
PFONT_IMAGE)FontImage->ImageList.Flink);
00308
00309
if (NearFont ==
NULL)
00310
return STATUS_ACCESS_DENIED;
00311
00312 hDC = CreateDC(TEXT(
"DISPLAY"),NULL,NULL,NULL);
00313
00314 hSrcMemDC = CreateCompatibleDC(hDC);
00315 hDestMemDC = CreateCompatibleDC(hDC);
00316
00317 hSrcBmp = CreateBitmap(NearFont->
FontSize.X,
00318 NearFont->
FontSize.Y,
00319 BITMAP_PLANES, BITMAP_BITS_PIXEL,
00320 NearFont->
ImageBits);
00321 hDestBmp = CreateBitmap(FontSize.X,
00322 FontSize.Y,
00323 BITMAP_PLANES, BITMAP_BITS_PIXEL,
00324 NULL);
00325
00326 SelectObject(hSrcMemDC, hSrcBmp);
00327 SelectObject(hDestMemDC, hDestBmp);
00328
00329
if (! StretchBlt(hDestMemDC, 0, 0, FontSize.X, FontSize.Y,
00330 hSrcMemDC, 0, 0, NearFont->
FontSize.X, NearFont->
FontSize.Y,
00331 SRCCOPY)) {
00332
return GetLastError();
00333 }
00334
00335
BufferSize =
CalcBitmapBufferSize(FontSize, WORD_ALIGN);
00336 GetBitmapBits(hDestBmp, BufferSize, (*pFontImage)->ImageBits);
00337
00338 DeleteDC(hSrcMemDC);
00339 DeleteDC(hDestMemDC);
00340 DeleteObject(hSrcBmp);
00341 DeleteObject(hDestBmp);
00342 DeleteDC(hDC);
00343
00344
return STATUS_SUCCESS;
00345 }
00346
00347
00348
00349
NTSTATUS
00350 GetFontImageInternal(
00351 IN
PFONT_CACHE_INFORMATION FontCache,
00352 IN WCHAR wChar,
00353 IN COORD FontSize,
00354 OUT
PFONT_IMAGE *pFontImage,
00355 IN DWORD GetFlag
00356 )
00357 {
00358
PFONT_HIGHLOW_OFFSET FontOffsetHighLow;
00359
PFONT_LOW_OFFSET FontOffsetLow;
00360
PFONT_IMAGE FontImage;
00361 WORD HighHighIndex, HighLowIndex;
00362 WORD LowIndex;
00363
DWORD Flag;
00364
00365 HighHighIndex = (
HIBYTE(wChar)) >> 4;
00366 HighLowIndex = (
HIBYTE(wChar)) & 0x0f;
00367 LowIndex =
LOBYTE(wChar);
00368
00369 FontOffsetHighLow = FontCache->FontTable.FontOffsetHighHigh[HighHighIndex];
00370
if (FontOffsetHighLow ==
NULL)
00371
return STATUS_ACCESS_DENIED;
00372
00373 FontOffsetLow = FontOffsetHighLow->
FontOffsetHighLow[HighLowIndex];
00374
if (FontOffsetLow ==
NULL)
00375
return STATUS_ACCESS_DENIED;
00376
00377 FontImage = FontOffsetLow->
FontOffsetLow[LowIndex];
00378
if (FontImage ==
NULL)
00379
return STATUS_ACCESS_DENIED;
00380
00381
00382 Flag =
ADD_IMAGE;
00383
do {
00384
if (FontImage->
FontSize.X == FontSize.X &&
00385 FontImage->
FontSize.Y == FontSize.Y ) {
00386
00387
00388
00389 Flag =
REPLACE_IMAGE;
00390
break;
00391 }
00392 }
00393
while (FontImage = (
PFONT_IMAGE)FontImage->
ImageList.Flink);
00394
00395
switch (GetFlag)
00396 {
00397
00398
00399
00400
case FONT_MATCHED:
00401
if (Flag !=
REPLACE_IMAGE)
00402
return STATUS_ACCESS_DENIED;
00403
00404 *pFontImage = FontImage;
00405
break;
00406
00407
00408
00409
00410
case FONT_STRETCHED:
00411
if (Flag ==
REPLACE_IMAGE &&
00412 FontImage->ImageBits !=
NULL) {
00413
00414 *pFontImage = FontImage;
00415
00416 }
00417
else {
00418 GetStretchImage(FontSize,
00419 FontOffsetLow->
FontOffsetLow[LowIndex],
00420 pFontImage
00421 );
00422 }
00423
break;
00424 }
00425
00426
return STATUS_SUCCESS;
00427 }
00428
00429
00430
00431
00432
00433
VOID UnlinkAndShrinkFontImagesByOne(
00434
PFONT_IMAGE* ppFontImage,
00435
PFONT_IMAGE pFontImageRemove)
00436 {
00437
PFONT_IMAGE OldFontImage = *ppFontImage;
00438 SIZE_T OldFontSize =
ConsoleHeapSize(OldFontImage);
00439
PFONT_IMAGE NewFontImage;
00440
00441 RIPMSG0(RIP_WARNING,
"UnlinkAndShrinkFontImagesByOne entered.");
00442
00443
if (OldFontImage==
NULL) {
00444 RIPMSG0(RIP_ERROR,
"UnlinkAndShrinkFontImagesByOne: *ppFontImage is NULL.");
00445
00446
00447
00448
return;
00449 }
00450
00451
if (OldFontImage == pFontImageRemove) {
00452 RIPMSG0(RIP_WARNING,
"UnlinkAndShrinkFontImagesByOne: unshrinking just one element.");
00453
00454
00455
00456
00457 UserAssert(OldFontSize <
sizeof(
FONT_IMAGE) * 2);
00458
00459 *ppFontImage =
NULL;
00460
ConsoleHeapFree(OldFontImage);
00461
return;
00462 }
00463
00464
#if DBG
00465
00466
00467
00468 {
00469
PFONT_IMAGE FontImageTmp;
00470
00471
00472
00473
00474
for (FontImageTmp = OldFontImage; FontImageTmp->
ImageList.Flink; FontImageTmp = (
PFONT_IMAGE)FontImageTmp->
ImageList.Flink)
00475 ;
00476
00477 UserAssert(FontImageTmp == pFontImageRemove);
00478 }
00479
#endif
00480
00481
00482
00483
00484 pFontImageRemove->
ImageList.Blink->Flink =
NULL;
00485
00486
00487
00488
00489
00490
00491
00492
00493 NewFontImage =
ConsoleHeapReAlloc(HEAP_ZERO_MEMORY,
00494 OldFontImage,
00495 OldFontSize -
sizeof(
FONT_IMAGE));
00496
if (NewFontImage ==
NULL) {
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 RIPMSG0(RIP_WARNING,
"UnlinkAndShrinkFontImagesByOne: failed to shrink ppFontImage.");
00512
return;
00513 }
00514 UserAssert(
ConsoleHeapSize(NewFontImage) != OldFontSize);
00515
00516
if (NewFontImage != OldFontImage) {
00517
00518
00519
00520 RebaseFontImageList(NewFontImage, (PBYTE)OldFontImage);
00521 *ppFontImage = NewFontImage;
00522 }
00523 }
00524
00525
NTSTATUS
00526 SetFontImageInternal(
00527 IN
PFONT_CACHE_INFORMATION FontCache,
00528 IN WCHAR wChar,
00529 IN COORD FontSize,
00530 IN DWORD dwAlign,
00531 IN CONST VOID *ImageBits
00532 )
00533 {
00534
PFONT_HIGHLOW_OFFSET FontOffsetHighLow;
00535
PFONT_LOW_OFFSET FontOffsetLow;
00536
PFONT_IMAGE FontImage;
00537
PFONT_IMAGE FontImageTmp;
00538 WORD HighHighIndex, HighLowIndex;
00539 WORD LowIndex;
00540
DWORD Flag;
00541
DWORD BufferSize;
00542
00543 HighHighIndex = (
HIBYTE(wChar)) >> 4;
00544 HighLowIndex = (
HIBYTE(wChar)) & 0x0f;
00545 LowIndex =
LOBYTE(wChar);
00546
00547
00548
00549
00550
00551
00552
00553
00554 FontOffsetHighLow = FontCache->FontTable.FontOffsetHighHigh[HighHighIndex];
00555
if (FontOffsetHighLow ==
NULL) {
00556 FontOffsetHighLow =
ConsoleHeapAlloc( HEAP_ZERO_MEMORY,
sizeof(
FONT_HIGHLOW_OFFSET));
00557
if (FontOffsetHighLow ==
NULL) {
00558 RIPMSG1(RIP_WARNING,
"SetFontImageInternal: cannot allocate memory (%d bytes)",
00559
sizeof(
FONT_HIGHLOW_OFFSET));
00560
return STATUS_NO_MEMORY;
00561 }
00562
00563 FontCache->FontTable.FontOffsetHighHigh[HighHighIndex] = FontOffsetHighLow;
00564 }
00565
00566 FontOffsetLow = FontOffsetHighLow->
FontOffsetHighLow[HighLowIndex];
00567
if (FontOffsetLow ==
NULL) {
00568 FontOffsetLow =
ConsoleHeapAlloc( HEAP_ZERO_MEMORY,
sizeof(
FONT_LOW_OFFSET));
00569
if (FontOffsetLow ==
NULL) {
00570 RIPMSG0(RIP_WARNING,
"SetFontImageInternal: failed to allocate FontOffsetLow.");
00571
return STATUS_NO_MEMORY;
00572 }
00573
00574 FontOffsetHighLow->
FontOffsetHighLow[HighLowIndex] = FontOffsetLow;
00575 }
00576
00577 FontImage = FontOffsetLow->
FontOffsetLow[LowIndex];
00578
if (FontImage ==
NULL) {
00579 FontImage =
ConsoleHeapAlloc( HEAP_ZERO_MEMORY,
sizeof(
FONT_IMAGE));
00580
if (FontImage ==
NULL) {
00581 RIPMSG0(RIP_WARNING,
"SetFontImageInternal: failed to allocate FontImage");
00582
return STATUS_NO_MEMORY;
00583 }
00584 }
00585
00586
if (FontSize.X == 0 &&
00587 FontSize.Y == 0 ) {
00588
00589
00590
00591
if (FontImage !=
NULL)
00592 {
00593
ConsoleHeapFree(FontImage);
00594 FontOffsetLow->
FontOffsetLow[LowIndex] =
NULL;
00595 }
00596
return STATUS_SUCCESS;
00597 }
00598
00599 Flag =
ADD_IMAGE;
00600 FontImageTmp = FontImage;
00601
do {
00602
if (FontImageTmp->
FontSize.X == FontSize.X &&
00603 FontImageTmp->
FontSize.Y == FontSize.Y ) {
00604
00605
00606
00607 Flag =
REPLACE_IMAGE;
00608 FontImage = FontImageTmp;
00609
break;
00610 }
00611 }
00612
while (FontImageTmp = (
PFONT_IMAGE)FontImageTmp->
ImageList.Flink);
00613
00614
switch (Flag) {
00615
case ADD_IMAGE:
00616
if (FontOffsetLow->
FontOffsetLow[LowIndex] !=
NULL)
00617 {
00618
PFONT_IMAGE OldFontImage = FontOffsetLow->
FontOffsetLow[LowIndex];
00619 SIZE_T OldFontSize =
ConsoleHeapSize(OldFontImage);
00620
PFONT_IMAGE NewFontImage;
00621
00622 NewFontImage =
ConsoleHeapReAlloc(HEAP_ZERO_MEMORY,
00623 OldFontImage,
00624 OldFontSize +
sizeof(
FONT_IMAGE));
00625
if (NewFontImage ==
NULL) {
00626 RIPMSG0(RIP_WARNING,
"SetFontImageInternal: failed to allocate NewFontImage");
00627
return STATUS_NO_MEMORY;
00628 }
00629
00630 FontOffsetLow->
FontOffsetLow[LowIndex] = NewFontImage;
00631
00632
00633 RebaseFontImageList(NewFontImage, (PBYTE)OldFontImage);
00634
00635 NewFontImage = (
PFONT_IMAGE)((
PBYTE)NewFontImage + OldFontSize);
00636
00637 NewFontImage->
FontSize = FontSize;
00638
00639
00640
00641
00642 (NewFontImage-1)->ImageList.Flink = (PLIST_ENTRY)NewFontImage;
00643 NewFontImage->
ImageList.Blink = (PLIST_ENTRY)(NewFontImage-1);
00644
00645 FontImage = NewFontImage;
00646 }
00647
else
00648 {
00649 FontImage->
FontSize = FontSize;
00650 FontOffsetLow->
FontOffsetLow[LowIndex] = FontImage;
00651 }
00652
00653
00654
00655
00656
BufferSize =
CalcBitmapBufferSize(FontSize,WORD_ALIGN);
00657
00658
if (FontCache->BaseImageBits ==
NULL)
00659 {
00660 FontCache->BaseImageBits =
ConsoleHeapAlloc( HEAP_ZERO_MEMORY, BufferSize);
00661
if (FontCache->BaseImageBits ==
NULL) {
00662 RIPMSG0(RIP_WARNING,
"SetFontImageInternal: failed to allocate FontCache->BaseImageBits");
00663 UnlinkAndShrinkFontImagesByOne(&FontOffsetLow->
FontOffsetLow[LowIndex], FontImage);
00664
return STATUS_NO_MEMORY;
00665 }
00666
00667 FontImage->ImageBits = FontCache->BaseImageBits;
00668 }
00669
else
00670 {
00671
PBYTE OldBaseImage = FontCache->BaseImageBits;
00672 SIZE_T OldImageSize =
ConsoleHeapSize(OldBaseImage);
00673 FontCache->BaseImageBits =
ConsoleHeapReAlloc(HEAP_ZERO_MEMORY,
00674 OldBaseImage,
00675 OldImageSize + BufferSize);
00676
if (FontCache->BaseImageBits ==
NULL) {
00677 RIPMSG0(RIP_WARNING,
"SetFontImageInternal: failed to reallocate FontCache->BaseImageBits");
00678
00679
00680
00681
00682 FontCache->BaseImageBits = OldBaseImage;
00683
00684
00685
00686 UnlinkAndShrinkFontImagesByOne(&FontOffsetLow->
FontOffsetLow[LowIndex], FontImage);
00687
return STATUS_NO_MEMORY;
00688 }
00689
00690
00691 RebaseFontCache(FontCache, OldBaseImage);
00692
00693 FontImage->ImageBits = FontCache->BaseImageBits + OldImageSize;
00694 }
00695
00696
AlignCopyMemory(FontImage->ImageBits,
00697 WORD_ALIGN,
00698 (PVOID)ImageBits,
00699 dwAlign,
00700 FontSize);
00701
00702
break;
00703
00704
case REPLACE_IMAGE:
00705
if (FontImage->ImageBits ==
NULL) {
00706 RIPMSG0(RIP_WARNING,
"SetFontImageInternal: FontImage->ImageBits is NULL.");
00707
return STATUS_NO_MEMORY;
00708 }
00709
00710
AlignCopyMemory(FontImage->ImageBits,
00711 WORD_ALIGN,
00712 (PVOID)ImageBits,
00713 dwAlign,
00714 FontSize);
00715
00716
break;
00717 }
00718
00719
return STATUS_SUCCESS;
00720 }
00721
00722
00723
00724
00725
00726 ULONG
00727
GetFontImage(
00728 IN
PFONT_CACHE_INFORMATION FontCache,
00729 IN WCHAR wChar,
00730 IN COORD FontSize,
00731 IN DWORD dwAlign,
00732 OUT VOID *ImageBits
00733 )
00734 {
00735
NTSTATUS Status;
00736
PFONT_IMAGE FontImage;
00737
00738
if (FontSize.X == 0 &&
00739 FontSize.Y == 0 ) {
00740
return (ULONG)(STATUS_INVALID_PARAMETER);
00741 }
00742
00743
Status = GetFontImageInternal(FontCache,wChar,FontSize,&FontImage,FONT_MATCHED);
00744
if (!
NT_SUCCESS(Status) )
00745
return (ULONG)
Status;
00746
00747
if (FontImage->
ImageBits ==
NULL ||
00748 ImageBits ==
NULL)
00749
return STATUS_SUCCESS;
00750
00751
AlignCopyMemory((PVOID)ImageBits,
00752 dwAlign,
00753 FontImage->
ImageBits,
00754 WORD_ALIGN,
00755 FontSize);
00756
00757
return STATUS_SUCCESS;
00758 }
00759
00760 ULONG
00761
GetStretchedFontImage(
00762 IN
PFONT_CACHE_INFORMATION FontCache,
00763 IN WCHAR wChar,
00764 IN COORD FontSize,
00765 IN DWORD dwAlign,
00766 OUT VOID *ImageBits
00767 )
00768 {
00769
NTSTATUS Status;
00770
PFONT_IMAGE FontImage;
00771
FONT_IMAGE FontBuff;
00772
DWORD BufferSize;
00773
00774
if (FontSize.X == 0 &&
00775 FontSize.Y == 0 ) {
00776
return (ULONG)(STATUS_INVALID_PARAMETER);
00777 }
00778
00779 FontImage = &FontBuff;
00780
00781
BufferSize =
CalcBitmapBufferSize(FontSize,WORD_ALIGN);
00782 FontImage->
ImageBits =
ConsoleHeapAlloc( HEAP_ZERO_MEMORY, BufferSize);
00783
if (FontImage->
ImageBits ==
NULL) {
00784 RIPMSG0(RIP_WARNING,
"GetStretchedFontImage: failed to allocate FontImage->ImageBits");
00785
return (ULONG)STATUS_NO_MEMORY;
00786 }
00787
00788
Status = GetFontImageInternal(FontCache,wChar,FontSize,&FontImage,FONT_STRETCHED);
00789
if (!
NT_SUCCESS(Status) )
00790 {
00791
ConsoleHeapFree(FontBuff.ImageBits);
00792
return (ULONG)
Status;
00793 }
00794
00795
if (FontImage->
ImageBits ==
NULL)
00796 {
00797
ConsoleHeapFree(FontBuff.ImageBits);
00798
return (ULONG)STATUS_SUCCESS;
00799 }
00800
00801
AlignCopyMemory((PVOID)ImageBits,
00802 dwAlign,
00803 FontImage->
ImageBits,
00804 WORD_ALIGN,
00805 FontSize);
00806
00807
ConsoleHeapFree(FontBuff.ImageBits);
00808
00809
return (ULONG)STATUS_SUCCESS;
00810 }
00811
00812 ULONG
00813
GetFontImagePointer(
00814 IN
PFONT_CACHE_INFORMATION FontCache,
00815 IN WCHAR wChar,
00816 IN COORD FontSize,
00817 OUT
PFONT_IMAGE *FontImage
00818 )
00819 {
00820
NTSTATUS Status;
00821
00822
if (FontSize.X == 0 &&
00823 FontSize.Y == 0 ) {
00824
return (ULONG)(STATUS_INVALID_PARAMETER);
00825 }
00826
00827
Status = GetFontImageInternal(FontCache,wChar,FontSize,(
PFONT_IMAGE*)FontImage,FONT_MATCHED);
00828
if (!
NT_SUCCESS(Status) )
00829
return (ULONG)
Status;
00830
00831
if ((*FontImage)->ImageBits ==
NULL)
00832
return (ULONG)STATUS_ACCESS_DENIED;
00833
00834
return Status;
00835 }
00836
00837 ULONG
00838
SetFontImage(
00839 IN
PFONT_CACHE_INFORMATION FontCache,
00840 IN WCHAR wChar,
00841 IN COORD FontSize,
00842 IN DWORD dwAlign,
00843 IN CONST VOID *ImageBits
00844 )
00845 {
00846
return SetFontImageInternal(FontCache,wChar,FontSize,dwAlign,ImageBits);
00847 }
00848
00849
00850
NTSTATUS
00851 GetExpandImage(
00852 COORD InputFontSize,
00853 PWORD InputFontImage,
00854 COORD OutputFontSize,
00855 PWORD OutputFontImage
00856 )
00857 {
00858
NTSTATUS Status;
00859
DWORD InputRow =
CALC_BITMAP_BITS_FOR_X(InputFontSize.X, BITMAP_BITS_WORD_ALIGN);
00860
DWORD OutputRow =
CALC_BITMAP_BITS_FOR_X(OutputFontSize.X, BITMAP_BITS_WORD_ALIGN);
00861
DWORD InputBufferSize =
CalcBitmapBufferSize(InputFontSize,WORD_ALIGN);
00862
DWORD OutputBufferSize =
CalcBitmapBufferSize(OutputFontSize,WORD_ALIGN);
00863
00864
Status = STATUS_NO_MEMORY;
00865
00866 RtlZeroMemory(OutputFontImage,OutputBufferSize);
00867
00868
ASSERT(InputRow==OutputRow);
00869
00870
if (InputFontSize.Y < OutputFontSize.Y)
00871 RtlCopyMemory(OutputFontImage, InputFontImage, InputBufferSize);
00872
else
00873 RtlCopyMemory(OutputFontImage, InputFontImage, OutputBufferSize);
00874
00875
return STATUS_SUCCESS;
00876 }
00877
00878
NTSTATUS
00879
GetExpandFontImage(
00880
PFONT_CACHE_INFORMATION FontCache,
00881 WCHAR wChar,
00882 COORD InputFontSize,
00883 COORD OutputFontSize,
00884 PWORD OutputFontImage
00885 )
00886 {
00887
NTSTATUS Status;
00888
DWORD InputBufferSize;
00889 PWORD InputFontImage;
00890
00891
if (InputFontSize.X == 0 &&
00892 InputFontSize.Y == 0 ) {
00893
return (ULONG)(STATUS_INVALID_PARAMETER);
00894 }
00895
00896
if (OutputFontSize.X == 0 &&
00897 OutputFontSize.Y == 0 ) {
00898
return (ULONG)(STATUS_INVALID_PARAMETER);
00899 }
00900
00901 InputBufferSize =
CalcBitmapBufferSize(InputFontSize,WORD_ALIGN);
00902 InputFontImage =
ConsoleHeapAlloc( HEAP_ZERO_MEMORY, InputBufferSize);
00903
if (InputFontImage==
NULL)
00904
return STATUS_NO_MEMORY;
00905
00906
00907
Status =
GetFontImage(FontCache,
00908 wChar,
00909 InputFontSize,
00910 WORD_ALIGN,
00911 InputFontImage);
00912
if (!
NT_SUCCESS(Status) )
00913 {
00914
ConsoleHeapFree(InputFontImage);
00915
return Status;
00916 }
00917
00918
Status = GetExpandImage(InputFontSize,
00919 InputFontImage,
00920 OutputFontSize,
00921 OutputFontImage);
00922
00923
ConsoleHeapFree(InputFontImage);
00924
00925
return Status;
00926 }
00927
#endif