// // FILENAME. // Ui.c // ----------------------------------------------------------------------- // // NOTICE. // Copyright (C) 2014 Lenovo All Rights Reserved. // // // Include standard header files. // #include "Ui.h" #include "Batt.h" #include "TrueTypeCharRes.h" #include "minilzo.h" #include "library\TrueTypeLib\TrueTypeLib.h" EFI_STRING StringsAcSatatus[] = { L"Unpluged", L"Plug in", }; EFI_STRING StringsBattSatatus[] = { L"Battery non-exist", L"Battery abnormal", L"Charging", L"Full Charged", L"DisCharging", L"Full DisCharged", L"Battery Unknown" }; // //Global Graphics handle for whole GUI // static EFI_GRAPHICS_OUTPUT_PROTOCOL *mGraphicsOutput = NULL; static UINTN mHorizontalResolution = 0; static UINTN mVerticalResolution = 0; /** Set rectangle data @param[in, out] Rect Pointer to rectangle data which will be set @param[in] Left Left value of rectangle data @param[in] Top Top value of rectangle data @param[in] Right Right value of rectangle data @param[in] Bottom Bottom value of rectangle data @retval TRUE Rectangle data is set **/ BOOLEAN EFIAPI SetRect( IN OUT RECT *Rect, IN UINTN Left, IN UINTN Top, IN UINTN Right, IN UINTN Bottom ) { Rect->left = Left; Rect->top = Top; Rect->right = Right; Rect->bottom = Bottom; return TRUE; } /** Copy rectangle data @param[out] DestRect Pointer to destination rectangle data @param[in] SrcRect Pointer to source rectangle data @retval TRUE Rectangle data is copied **/ BOOLEAN EFIAPI CopyRect( OUT RECT *DestRect, IN CONST RECT *SrcRect ) { CopyMem(DestRect, SrcRect, sizeof (RECT)); return TRUE; } /** shrink the rectangle data @param[in, out] Rect Pointer to rectangle data which will be inflated @param[in] DiffX Inflated x-axis value @param[in] DiffY Inflated y-axis value @retval TRUE Rectangle data is inflated **/ BOOLEAN EFIAPI ShrinkRect( IN OUT RECT *Rect, IN UINTN DiffX, IN UINTN DiffY ) { Rect->left += DiffX; Rect->top += DiffY; Rect->right -= DiffX; Rect->bottom -= DiffY; return TRUE; } /** Width of the rectangle @param[in, out] Rect Pointer to rectangle data which will be inflated @param[in] DiffX Inflated x-axis value @param[in] DiffY Inflated y-axis value @retval TRUE Rectangle data is inflated **/ UINTN EFIAPI WidthRect( IN OUT RECT *Rect ) { return (Rect->right - Rect->left + 1); } UINTN EFIAPI HeightRect( IN OUT RECT *Rect ) { return (Rect->bottom - Rect->top + 1); } /** Offset the rectangle data @param[in, out] Rect Pointer to rectangle data which will be offset @param[in] DiffX Offset x-axis value @param[in] DiffY Offset y-axis value @retval TRUE Rectangle data is offset **/ BOOLEAN EFIAPI OffsetRect( IN OUT RECT *Rect, IN UINTN DiffX, IN UINTN DiffY ) { Rect->left += DiffX; Rect->right += DiffX; Rect->top += DiffY; Rect->bottom += DiffY; return TRUE; } EFI_STATUS DisplayBitBlt( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION Mode, IN RECT* Rect ) { EFI_STATUS Status = EFI_SUCCESS; UINTN X; UINTN Y; UINTN Width; UINTN Height; // // Draw a one pixel width rectangle as a vertical line by Graphics Output // Protocol. Use the argument Mode to fill this rectangle. // Width = WidthRect(Rect); Height = HeightRect(Rect); X = Rect->left; Y = Rect->top; //DebugL(L"Function: DisplayBitBlt,(%d,%d, W=%d,H=%d). \n ",X,Y,Width,Height); switch (Mode) { case EfiBltVideoFill: case EfiBltBufferToVideo: Status = mGraphicsOutput->Blt( mGraphicsOutput, Blt, Mode, 0, 0, X, Y, Width, Height, 0); break; case EfiBltVideoToBltBuffer: Status = mGraphicsOutput->Blt ( mGraphicsOutput, Blt, Mode, X, Y, 0, 0, Width, Height, 0 ); break; default: break; } //DebugL(L"Function(DisplayBitBlt mode=%d,ret=%d) X=%d,Y=%d,W=%d,D=%d,color=0x%x.\n ", Mode,Status,X,Y,Width,Height); return Status; } EFI_STATUS TrueTypeStringToImage( IN CHAR16 *String, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt, IN UINT16 Width, IN UINT16 Height, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL FgColor, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL BkColor ) { EFI_STATUS Status; STATIC UINT8 *GlyphBuffer = NULL; STATIC UINTN BufferLen = 0; UINTN GlyphBufferLen = 0; EFI_HII_GLYPH_INFO Cell; // UINT16 i = 0; UINT16 X; UINT16 Y; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; UINT8 Alpha; UINT16 BltWidth; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBufferForSmooth; ASSERT(String != NULL); ASSERT(Blt != NULL); BltBuffer = Blt; BltBufferForSmooth = Blt; //for (i = 0; i < (Width*Height); i++){ // BltBuffer[i] = BkColor; //} BltWidth = Width; while (*String != 0) { GlyphBufferLen = BufferLen; Status = TrueTypeGetGlyph( *String, GlyphBuffer, &GlyphBufferLen, &Cell ); if (Status == EFI_BUFFER_TOO_SMALL) { if (GlyphBuffer != NULL) { gBS->FreePool(GlyphBuffer); } GlyphBuffer = (UINT8 *)AllocateZeroPool(GlyphBufferLen); BufferLen = GlyphBufferLen; Status = TrueTypeGetGlyph( *String, GlyphBuffer, &GlyphBufferLen, &Cell ); } if (EFI_ERROR(Status)) { String++; continue; } // // glyph to buffer // for (Y = 0; Y < Cell.Height; Y++) { if ((UINTN)(Cell.OffsetY + Y) >= Height) { continue; } for (X = 0; X < Cell.Width; X++) { if ((Cell.OffsetX + X) < 0 || ((UINTN)(Cell.OffsetX + X) >= (UINTN)Cell.AdvanceX)) { continue; } Alpha = GlyphBuffer[Y * Cell.Width + X]; if (Alpha) { FgColor.Reserved = Alpha; BltBuffer[(Y + Cell.OffsetY) * BltWidth + X + Cell.OffsetX] = FgColor; } } } if (Cell.AdvanceX >= Width) { break; } Width -= Cell.AdvanceX; BltBuffer += Cell.AdvanceX; String++; } for (Y = 0; Y < Height; Y++) { for (X = 0; X < BltWidth; X++) { if (BltBufferForSmooth[(BltWidth * Y) + X].Reserved != 0 && BltBufferForSmooth[(BltWidth * Y) + X].Reserved != 255) { BltBufferForSmooth[(BltWidth * Y) + X].Blue = BkColor.Blue + (((BltBufferForSmooth[(BltWidth * Y) + X].Blue) - BkColor.Blue) * (BltBufferForSmooth[(BltWidth * Y) + X].Reserved)) / 255; BltBufferForSmooth[(BltWidth * Y) + X].Green = BkColor.Green + (((BltBufferForSmooth[(BltWidth * Y) + X].Green) - BkColor.Green) * (BltBufferForSmooth[(BltWidth * Y) + X].Reserved)) / 255; BltBufferForSmooth[(BltWidth * Y) + X].Red = BkColor.Red + (((BltBufferForSmooth[(BltWidth * Y) + X].Red) - BkColor.Red) * (BltBufferForSmooth[(BltWidth * Y) + X].Reserved)) / 255; } } } return EFI_SUCCESS; } EFI_STATUS TrueTypeGetWidth( IN UINT16 FontSize, IN EFI_STRING String, IN OUT UINT16 *Width, IN OUT UINT16 *Height ) { EFI_STATUS Status = EFI_SUCCESS; EFI_HII_GLYPH_INFO Cell; TrueTypeSetFontSize(FontSize); while (*String != 0) { Status = TrueTypeGetGlyph( *String, NULL, NULL, &Cell ); if (EFI_ERROR (Status)) { //DebugL(L"Function: TrueTypeGetGlyph faild, font=0x%x\n ",*String); } else { *Width += Cell.AdvanceX; if (Cell.Height + Cell.OffsetY > *Height) { *Height = Cell.Height + Cell.OffsetY; } //DebugL(L"Function: TrueTypeGetGlyph width=%d,height=%d,AdvanceX=%d,offsetX=%d,offsetY=%d\n ", // Cell.Width,Cell.Height,Cell.AdvanceX,Cell.OffsetX,Cell.OffsetY); } String++; } return EFI_SUCCESS; } /** Use HiiFont to draw text to blt buffer @param [in] ImageInfo Destination Image @param [in] TextColor Text Color @param [in] BackgroundColor Background color @param [in] String Destination LineLen @param [in] TextRc Destination rectangle @return return StringToImage status **/ EFI_STATUS TrueTypeDrawText( IN UINT16 FontSize, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *TextColor, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BackgroundColor, IN EFI_STRING String, IN RECT *TextRc, IN UINTN Style, IN BOOLEAN bTransparent ) { EFI_STATUS Status = EFI_SUCCESS; UINT16 TextRCWidth = 0; UINT16 TextRCHeight = 0; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer = NULL; RECT Rect; UINTN nTry = 0; UINT16 NewFontSize = FontSize; // //let align to enter // CopyRect(&Rect,TextRc); for(nTry=0; nTry<10; nTry++) { TextRCWidth = 0; TextRCHeight = 0; Status = TrueTypeGetWidth(NewFontSize,(CHAR16 *)String,&TextRCWidth,&TextRCHeight); if (EFI_ERROR(Status)) { DebugL(L"Function: TrueTypeGetWidth faild\n "); return Status; } DebugL(L"Function: TrueTypeDrawText(%d-%d) fontsize=%d, width=%d, height=%d\n ",TextRc->left,TextRc->right,NewFontSize, TextRCWidth,TextRCHeight); if (TextRCWidth < (TextRc->right - TextRc->left) && TextRCHeight < (TextRc->bottom - TextRc->top)) { UINTN XStep = (TextRc->right - TextRc->left - TextRCWidth)/2; UINTN YStep = (TextRc->bottom - TextRc->top - TextRCHeight)/2; //find sultiable font size switch (Style) { case FRONT_STYLE_LEFT_TOP: SetRect(&Rect,TextRc->left,TextRc->top, TextRc->right-XStep*2, TextRc->bottom-YStep*2); break; case FRONT_STYLE_LEFT_BOTTOM: SetRect(&Rect,TextRc->left,TextRc->top + YStep*2,TextRc->right-XStep*2, TextRc->bottom); break; case FRONT_STYLE_LEFT_CENTER: SetRect(&Rect,TextRc->left,TextRc->top + YStep,TextRc->right-XStep*2, TextRc->bottom-YStep); break; case FRONT_STYLE_MIDLLE_TOP: SetRect(&Rect,TextRc->left+XStep,TextRc->top ,TextRc->right-XStep, TextRc->bottom-YStep*2); break; case FRONT_STYLE_MIDLLE_BOTTOM: SetRect(&Rect,TextRc->left+XStep,TextRc->top+YStep ,TextRc->right-XStep, TextRc->bottom-YStep); break; case FRONT_STYLE_MIDLLE_CENTER: ShrinkRect(&Rect,XStep, YStep); break; case FRONT_STYLE_RIGHT_TOP: SetRect(&Rect,TextRc->left+XStep*2,TextRc->top ,TextRc->right, TextRc->bottom-YStep*2); break; case FRONT_STYLE_RIGHT_BOTTOM: SetRect(&Rect,TextRc->left+XStep*2,TextRc->top+YStep*2 ,TextRc->right, TextRc->bottom); break; case FRONT_STYLE_RIGHT_CENTER: SetRect(&Rect,TextRc->left+XStep*2,TextRc->top+YStep ,TextRc->right, TextRc->bottom-YStep); break; case FRONT_STYLE_DISK_INFO: OffsetRect(&Rect, 80, YStep); break; default: ShrinkRect(&Rect,XStep, YStep); break; } break; } NewFontSize-=4; } if (nTry == 10) { DebugL(L"Function: TrueTypeDrawText area too samll\n "); return Status; } Rect.right = Rect.left + TextRCWidth - 1; Rect.bottom = Rect.top + TextRCHeight - 1; BltBuffer = AllocateZeroPool((TextRCWidth * TextRCHeight + 64) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); if (NULL == BltBuffer){ DebugL(L"Function: TrueTypeDrawText alloc memory faild\n "); return Status; } // //for transparent,capture screen first // if (bTransparent) { Status = DisplayBitBlt( (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltBuffer, EfiBltVideoToBltBuffer, &Rect ); } else { for (nTry = 0; nTry < (TextRCWidth * TextRCHeight); nTry++){ BltBuffer[nTry] = *BackgroundColor; } } Status = TrueTypeStringToImage( (CHAR16 *)String, BltBuffer, (UINT16)TextRCWidth, (UINT16)TextRCHeight, *TextColor, *BackgroundColor ); if (EFI_ERROR(Status)) { DebugL(L"Function: TrueTypeStringToImage faild\n "); gBS->FreePool(BltBuffer); return Status; } Status = DisplayBitBlt( (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltBuffer, EfiBltBufferToVideo, &Rect ); if (EFI_ERROR(Status)) { DebugL(L"Function: TrueTypeDrawText Blt faild\n "); gBS->FreePool(BltBuffer); return Status; } gBS->FreePool(BltBuffer); return Status; } EFI_STATUS InitializeTrueTypeFont( ) { #ifdef SUPPORT_FONT_IN_FV EFI_STATUS Status; UINTN FvProtocolCount; EFI_HANDLE *FvHandles; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; UINTN Index; UINT32 AuthenticationStatus; UINTN ImageSize; UINT8 *ImageData; #endif STATIC BOOLEAN FirstIn = TRUE; if (!FirstIn) { return EFI_SUCCESS; } else { FirstIn = FALSE; } #ifdef SUPPORT_FONT_IN_FV Status = gBS->LocateHandleBuffer( ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvProtocolCount, &FvHandles ); if (EFI_ERROR(Status)) { return Status; } ImageData = NULL; ImageSize = 0; for (Index = 0; Index < FvProtocolCount; Index++) { Status = gBS->HandleProtocol( FvHandles[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv ); Status = Fv->ReadSection( Fv, &gEfiTtfFontFileGuid, EFI_SECTION_RAW, 0, (VOID**)&ImageData, &ImageSize, &AuthenticationStatus ); if (!EFI_ERROR(Status)) { break; } } if (EFI_ERROR(Status)) { DebugL(L"Function: Load TTF font(FV) faild,try to use buitin font. \n "); //return Status; } TrueTypeInit(); TrueTypeLoadMemory(ImageData, (UINT32)ImageSize); #else TrueTypeInit(); #ifdef LZO_TRUE_TYPE_CHAR_RES { UINT8 *pStr = NULL; UINTN nSize = 0; pStr = (UINT8 *)AllocateZeroPool (sizeof(UINT8) * ResLen); if (NULL != pStr) { lzo1x_decompress(TrueTypeFont, sizeof(TrueTypeFont), pStr, (lzo_uintp)&nSize, NULL); if (nSize == ResLen) { DebugL(L"Function: Load TTF from LZO format. \n "); TrueTypeLoadMemory(pStr, (UINT32)nSize); } //Niote: always used, not free here //FreePool(pStr); } } #else TrueTypeLoadMemory(TrueTypeFont, (UINT32)sizeof(TrueTypeFont)); #endif #endif #if 0 { UINT16 TextRCWidth = 0; UINT16 TextRCHeight = 0; CHAR16 String[] = L"g"; UINT16 NewFontSize = 0; for (NewFontSize=12; NewFontSize<40;NewFontSize+=2) { TrueTypeGetWidth(NewFontSize,(CHAR16 *)String,&TextRCWidth,&TextRCHeight); DebugL(L"Fontsize=%d,width=%d,height=%d\n ", NewFontSize,TextRCWidth,TextRCHeight); TextRCWidth = 0; TextRCHeight = 0; } while(1); } #endif return EFI_SUCCESS; } EFI_STATUS InitializeGUI( ) { EFI_STATUS Status = EFI_SUCCESS; UINT32 Index; // // Try to open GOP. // if (NULL == mGraphicsOutput) { UINTN i; UINTN HandleCount; EFI_HANDLE *HandleBufferGop; EFI_DEVICE_PATH_PROTOCOL *DevicePath; Status = gBS->LocateHandleBuffer ( // Get all instances of GOP. ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL, &HandleCount, &HandleBufferGop); if (EFI_ERROR (Status)) { return Status; } for (i = 0; i < HandleCount; i++) { // Search for physical device. Status = gBS->HandleProtocol ( HandleBufferGop [i], &gEfiDevicePathProtocolGuid, (VOID *)&DevicePath); if (!EFI_ERROR (Status)) { gBS->HandleProtocol ( HandleBufferGop [i], &gEfiGraphicsOutputProtocolGuid, (VOID *)&mGraphicsOutput); break; } } gBS->FreePool (HandleBufferGop); if (i >= HandleCount) { DebugL(L"[BOKR_UI] HandleProtocol Error\r\n"); return EFI_NOT_FOUND; } } if (NULL != mGraphicsOutput) { UINTN SizeOfInfo; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; for (Index = 0; Index < mGraphicsOutput->Mode->MaxMode; Index++) { mGraphicsOutput->QueryMode (mGraphicsOutput, Index, &SizeOfInfo, &Info); DebugL(L"Function(InitializeGUI) Mode %d resolution is (%d * %d).\n ", Index, Info->HorizontalResolution, Info->VerticalResolution); if (DEFAULT_X == Info->HorizontalResolution && DEFAULT_Y == Info->VerticalResolution) { Status = mGraphicsOutput->SetMode (mGraphicsOutput, Index); gBS->FreePool (Info); break; } gBS->FreePool (Info); } // // Cannot find suitable GOP mode, set mode with default resolution. // if (EFI_ERROR (Status) || (Index == mGraphicsOutput->Mode->MaxMode)) { for (Index = 0; Index < mGraphicsOutput->Mode->MaxMode; Index++) { mGraphicsOutput->QueryMode (mGraphicsOutput, Index, &SizeOfInfo, &Info); if (P1080P_X <= Info->HorizontalResolution && P1080P_Y <= Info->VerticalResolution) { Status = mGraphicsOutput->SetMode (mGraphicsOutput, Index); DebugL(L"Function(InitializeGUI) Selected Mode %d resolution is (%d * %d).\n ", Index, Info->HorizontalResolution, Info->VerticalResolution); gBS->FreePool (Info); break; } gBS->FreePool (Info); } } // // Error checking on options. // mHorizontalResolution = mGraphicsOutput->Mode->Info->HorizontalResolution; mVerticalResolution = mGraphicsOutput->Mode->Info->VerticalResolution; DebugL(L"Function(InitializeGUI) Selected Mode %d resolution is (%d * %d).\n ", Index, mHorizontalResolution, mVerticalResolution); } // //init Truetype font support // Status = InitializeTrueTypeFont(); if (EFI_ERROR(Status)) { DebugL(L"[BOKR_UI] InitializeTrueTypeFont Error\r\n"); return EFI_UNSUPPORTED; } return Status; } /****************************************************************************************/ EFI_STATUS DrawBatteryInfo(UINTN Percent,UINT8 ACStatus,UINT8 BattStatus) { EFI_STATUS Status = EFI_SUCCESS; RECT Rect; UINT32 nColor,nBGColor; CHAR16 strTemp0[64] = L""; CHAR16 strTemp1[16] = L""; if(Percent > 100){ DebugL(L"Function(DrawBatteryInfo) INVALID PARAMETER.\n "); return EFI_INVALID_PARAMETER; } if(ACStatus >= MAX_AC_STATUS){ DebugL(L"Function(DrawBatteryInfo) INVALID PARAMETER.\n "); return EFI_INVALID_PARAMETER; } if(BattStatus >= MAX_BATTERY_STATUS){ DebugL(L"Function(DrawBatteryInfo) INVALID PARAMETER.\n "); return EFI_INVALID_PARAMETER; } if(Percent < 20) nColor = RED_COLOR; else nColor = GREEN_COLOR; nBGColor = BLACK_COLOR; UnicodeSPrint (strTemp0, sizeof (strTemp0), L"%s,%s", StringsAcSatatus[ACStatus],StringsBattSatatus[BattStatus]); SetRect(&Rect, 0, 0, mHorizontalResolution, mVerticalResolution*PERCENT_FONT_TOP_SIDE_SCALE); TrueTypeDrawText(AC_BATT_INFO_FONT_SIZE, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nBGColor, strTemp0, &Rect, FRONT_STYLE_MIDLLE_CENTER, FALSE ); UnicodeSPrint (strTemp1, sizeof (strTemp1), L"%02d%%", Percent); SetRect(&Rect, 0, mVerticalResolution*PERCENT_FONT_TOP_SIDE_SCALE, mHorizontalResolution, mVerticalResolution*PERCENT_FONT_BOTTOM_SIDE_SCALE); TrueTypeDrawText(PERCENT_FONT_SIZE, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor, (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nBGColor, strTemp1, &Rect, FRONT_STYLE_MIDLLE_CENTER, FALSE ); DebugL(L"Function(DrawBatteryInfo) End.\n "); return Status; } EFI_STATUS DrawBattery(UINTN Percent) { EFI_STATUS Status = EFI_SUCCESS; RECT Rect; UINT32 nColor; UINTN i = 0; DebugL(L"Function(DrawBattery) Start.\n "); DebugL(L"Function(DrawBattery) resolution is (%d * %d).\n ", mHorizontalResolution, mVerticalResolution); if(Percent < 20) nColor = RED_COLOR; else nColor = GREEN_COLOR; SetRect(&Rect,mHorizontalResolution*BATT_LEFT_SIDE_SCALE-BATT_HULL, mVerticalResolution*BATT_TOP_SIDE_SCALE-BATT_HULL, mHorizontalResolution*BATT_RIGHT_SIDE_SCALE+BATT_HULL, mVerticalResolution*BATT_BOTTOM_SIDE_SCALE+BATT_HULL); DisplayBitBlt((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor,EfiBltVideoFill,&Rect); SetRect(&Rect,mHorizontalResolution*BATT_RIGHT_SIDE_SCALE+BATT_HULL, (mVerticalResolution*BATT_TOP_SIDE_SCALE+mVerticalResolution*BATT_BOTTOM_SIDE_SCALE)/2-BATT_CAP_HALF_WIDTH, mHorizontalResolution*BATT_RIGHT_SIDE_SCALE+BATT_HULL+BATT_CAP_LENGTH, (mVerticalResolution*BATT_TOP_SIDE_SCALE+mVerticalResolution*BATT_BOTTOM_SIDE_SCALE)/2+BATT_CAP_HALF_WIDTH); DisplayBitBlt((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor,EfiBltVideoFill,&Rect); /************************************************/ nColor = BLACK_COLOR; SetRect(&Rect,mHorizontalResolution*BATT_LEFT_SIDE_SCALE, mVerticalResolution*BATT_TOP_SIDE_SCALE, mHorizontalResolution*BATT_RIGHT_SIDE_SCALE, mVerticalResolution*BATT_TOP_SIDE_SCALE+BATT_GAP); DisplayBitBlt((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor,EfiBltVideoFill,&Rect); SetRect(&Rect,mHorizontalResolution*BATT_LEFT_SIDE_SCALE, mVerticalResolution*BATT_BOTTOM_SIDE_SCALE-BATT_GAP, mHorizontalResolution*BATT_RIGHT_SIDE_SCALE, mVerticalResolution*BATT_BOTTOM_SIDE_SCALE); DisplayBitBlt((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor,EfiBltVideoFill,&Rect); SetRect(&Rect,mHorizontalResolution*BATT_LEFT_SIDE_SCALE+mHorizontalResolution*BATT_LEFT_SIDE_SCALE*Percent/100, mVerticalResolution*1/2, mHorizontalResolution*BATT_RIGHT_SIDE_SCALE, mVerticalResolution*7/10); DisplayBitBlt((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor,EfiBltVideoFill,&Rect); for(i=0;i<11;i++){ SetRect(&Rect,mHorizontalResolution*BATT_LEFT_SIDE_SCALE+mHorizontalResolution*BATT_LEFT_SIDE_SCALE*i/10, mVerticalResolution*BATT_TOP_SIDE_SCALE, mHorizontalResolution*BATT_LEFT_SIDE_SCALE+mHorizontalResolution*BATT_LEFT_SIDE_SCALE*i/10+BATT_GAP, mVerticalResolution*BATT_BOTTOM_SIDE_SCALE); DisplayBitBlt((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)&nColor,EfiBltVideoFill,&Rect); } DebugL(L"Function(DrawBattery) End.\n "); return Status; }