Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

foncache.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1985 - 1999, Microsoft Corporation 00004 00005 Module Name: 00006 00007 foncache.c 00008 00009 Abstract: 00010 00011 This file is EUDC font cache 00012 00013 Author: 00014 00015 Kazuhiko Matsubara 21-June-1994 00016 00017 Revision History: 00018 00019 Notes: 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 // allocate font cache data 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 // pDest = WORD, pSrc = WORD 00213 // 00214 case WORD_ALIGN: 00215 dwDestBufferSize = CalcBitmapBufferSize(FontSize, dwDestAlign); 00216 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize); 00217 break; 00218 // 00219 // pDest = WORD, pSrc = BYTE 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 // pDest = BYTE, pSrc = BYTE 00246 // 00247 case BYTE_ALIGN: 00248 dwDestBufferSize = CalcBitmapBufferSize(FontSize, dwDestAlign); 00249 RtlCopyMemory(pDestBits, pSrcBits, dwDestBufferSize); 00250 break; 00251 default: 00252 // 00253 // pDest = BYTE, pSrc = WORD 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 // Replace font image 00388 // 00389 Flag = REPLACE_IMAGE; 00390 break; 00391 } 00392 } 00393 while (FontImage = (PFONT_IMAGE)FontImage->ImageList.Flink); 00394 00395 switch (GetFlag) 00396 { 00397 // 00398 // Get matched size font. 00399 // 00400 case FONT_MATCHED: 00401 if (Flag != REPLACE_IMAGE) 00402 return STATUS_ACCESS_DENIED; 00403 00404 *pFontImage = FontImage; 00405 break; 00406 00407 // 00408 // Get stretched size font. 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 // See Raid #362907, stress failure 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 // There's nothing to shrink. 00447 // 00448 return; 00449 } 00450 00451 if (OldFontImage == pFontImageRemove) { 00452 RIPMSG0(RIP_WARNING, "UnlinkAndShrinkFontImagesByOne: unshrinking just one element."); 00453 // 00454 // There's just one entry. Let's free it and set 00455 // ppFontImage as NULL, and bail out. 00456 // 00457 UserAssert(OldFontSize < sizeof(FONT_IMAGE) * 2); 00458 00459 *ppFontImage = NULL; 00460 ConsoleHeapFree(OldFontImage); 00461 return; 00462 } 00463 00464 #if DBG 00465 // 00466 // Double check the integrity of the linked list. 00467 // 00468 { 00469 PFONT_IMAGE FontImageTmp; 00470 00471 // 00472 // Search the tail element 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 // Remove the tail element 00483 // 00484 pFontImageRemove->ImageList.Blink->Flink = NULL; 00485 00486 // 00487 // Shrink the contiguous memory chunk 00488 // 00489 // Note: this code assumes sizeof(FONT_IMAGE) is larger than 00490 // HEAP_GRANULARITY. If not, the heap block actually does not 00491 // shrink, and the assert below will hit. 00492 // 00493 NewFontImage = ConsoleHeapReAlloc(HEAP_ZERO_MEMORY, 00494 OldFontImage, 00495 OldFontSize - sizeof(FONT_IMAGE)); 00496 if (NewFontImage == NULL) { 00497 // 00498 // Win32HeapRealloc firstly allocates a new memory and then 00499 // copies the content. If the allocation fails, it leaves the 00500 // original heap as is. 00501 // 00502 // Even though the realloc fails, the last element (pFontImageRemove) is 00503 // already removed from the linked list. The next time SetImageFontInternal 00504 // is called, a new FontImage might be added to this memory chunk, but the 00505 // the code always links the newly extended memory. 00506 // This leaves the sizeof(FONT_IMAGE) memory unused, but it's safe. Assuming 00507 // sizeof(FONT_IMAGE) is small, memory waste should be minimum. 00508 // 00509 // It's OK for us to just bail out here. 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 // Rebase Font Image Linked List 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 * When Console is being destroyed, all font cache information 00549 * will be freed (see DestroyFontCache), so no memory leak 00550 * is expected on those, even if we cleanup everything on 00551 * error return... 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 // Reset registered font 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 // Replace font image 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 // Rebase Font Image List 00633 RebaseFontImageList(NewFontImage, (PBYTE)OldFontImage); 00634 00635 NewFontImage = (PFONT_IMAGE)((PBYTE)NewFontImage + OldFontSize); 00636 00637 NewFontImage->FontSize = FontSize; 00638 00639 // 00640 // Connect link list. 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 // Allocate Image Buffer 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 // When reallocation fails, we preserve the old baseImageBits 00680 // so that other FontImage->ImageBits can be still valid. 00681 // 00682 FontCache->BaseImageBits = OldBaseImage; 00683 // 00684 // Remove the tail element that we failed to add image. 00685 // 00686 UnlinkAndShrinkFontImagesByOne(&FontOffsetLow->FontOffsetLow[LowIndex], FontImage); 00687 return STATUS_NO_MEMORY; 00688 } 00689 00690 // Rebase font image pointer 00691 RebaseFontCache(FontCache, OldBaseImage); 00692 00693 FontImage->ImageBits = FontCache->BaseImageBits + OldImageSize; 00694 } 00695 00696 AlignCopyMemory(FontImage->ImageBits,// pDestBits 00697 WORD_ALIGN, // dwDestAlign 00698 (PVOID)ImageBits, // pSrcBits 00699 dwAlign, // dwSrcAlign 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,// pDestBits 00711 WORD_ALIGN, // dwDestAlign 00712 (PVOID)ImageBits, // pSrcBits 00713 dwAlign, // dwSrcAlign 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, // pDestBits 00752 dwAlign, // dwDestAlign 00753 FontImage->ImageBits,// pSrcBits 00754 WORD_ALIGN, // dwSrcAlign 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, // pDestBits 00802 dwAlign, // dwDestAlign 00803 FontImage->ImageBits,// pSrcBits 00804 WORD_ALIGN, // dwSrcAlign 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

Generated on Sat May 15 19:40:03 2004 for test by doxygen 1.3.7