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