/** @file One Key Battery UI function. ;****************************************************************************** ;* Copyright (c) 2020, Insyde Software Corp. All Rights Reserved. ;* ;* You may not reproduce, distribute, publish, display, perform, modify, adapt, ;* transmit, broadcast, present, recite, release, license or otherwise exploit ;* any part of this publication in any form, by any means, without the prior ;* written permission of Insyde Software Corporation. ;* ;****************************************************************************** */ #include "OneKeyBatteryDxe.h" // // Global Graphics handle for whole GUI // EFI_GRAPHICS_OUTPUT_PROTOCOL *mGraphicsOutput = NULL; EFI_PNG_DECODER_PROTOCOL *mPngDecoder = NULL; static UINTN mHorizontalResolution = 0; static UINTN mVerticalResolution = 0; // // All the picture is for 4k resolution. // static UINTN mHorizontalResolutionStandard = X_3840_2160; static UINTN mVerticalResolutionStandard = Y_3840_2160; static RECT mRectBattery; static RECT mRectCharger; static RECT mRectPhone; static RECT mRectPercent[4] = {0}; static UINT16 mRectPercentSize = 0; NG_PNG mResources[] = { {PNG_1080P_0_PERCENT, DATA_1080P_0_PERCENT_GUID}, {PNG_1080P_10_PERCENT, DATA_1080P_10_PERCENT_GUID}, {PNG_1080P_20_PERCENT, DATA_1080P_20_PERCENT_GUID}, {PNG_1080P_30_PERCENT, DATA_1080P_30_PERCENT_GUID}, {PNG_1080P_40_PERCENT, DATA_1080P_40_PERCENT_GUID}, {PNG_1080P_50_PERCENT, DATA_1080P_50_PERCENT_GUID}, {PNG_1080P_60_PERCENT, DATA_1080P_60_PERCENT_GUID}, {PNG_1080P_70_PERCENT, DATA_1080P_70_PERCENT_GUID}, {PNG_1080P_80_PERCENT, DATA_1080P_80_PERCENT_GUID}, {PNG_1080P_90_PERCENT, DATA_1080P_90_PERCENT_GUID}, {PNG_1080P_100_PERCENT, DATA_1080P_100_PERCENT_GUID}, {PNG_1080P_10_PERCENT_2, DATA_1080P_10_PERCENT_2_GUID}, {PNG_1080P_20_PERCENT_2, DATA_1080P_20_PERCENT_2_GUID}, {PNG_4K_0, DATA_4K_0_GUID}, {PNG_4K_1, DATA_4K_1_GUID}, {PNG_4K_2, DATA_4K_2_GUID}, {PNG_4K_3, DATA_4K_3_GUID}, {PNG_4K_4, DATA_4K_4_GUID}, {PNG_4K_5, DATA_4K_5_GUID}, {PNG_4K_6, DATA_4K_6_GUID}, {PNG_4K_7, DATA_4K_7_GUID}, {PNG_4K_8, DATA_4K_8_GUID}, {PNG_4K_9, DATA_4K_9_GUID}, {PNG_4K_PERCENT, DATA_4K_PERCENT_GUID}, {PNG_768P_0, DATA_768P_0_GUID}, {PNG_768P_1, DATA_768P_1_GUID}, {PNG_768P_2, DATA_768P_2_GUID}, {PNG_768P_3, DATA_768P_3_GUID}, {PNG_768P_4, DATA_768P_4_GUID}, {PNG_768P_5, DATA_768P_5_GUID}, {PNG_768P_6, DATA_768P_6_GUID}, {PNG_768P_7, DATA_768P_7_GUID}, {PNG_768P_8, DATA_768P_8_GUID}, {PNG_768P_9, DATA_768P_9_GUID}, {PNG_768P_PERCENT, DATA_768P_PERCENT_GUID}, {PNG_1080P_PHONE1, DATA_1080P_PHONE1_GUID}, {PNG_1080P_PHONE2, DATA_1080P_PHONE2_GUID}, {PNG_1080P_PHONE3, DATA_1080P_PHONE3_GUID}, {PNG_4K_CHARGER1, DATA_4K_CHARGER1_GUID}, {PNG_4K_CHARGER2, DATA_4K_CHARGER2_GUID}, {PNG_4K_CHARGER3, DATA_4K_CHARGER3_GUID}, {PNG_4K_PHONE1, DATA_4K_PHONE1_GUID}, {PNG_4K_PHONE2, DATA_4K_PHONE2_GUID}, {PNG_4K_PHONE3, DATA_4K_PHONE3_GUID}, {PNG_768P_CHARGER1, DATA_768P_CHARGER1_GUID}, {PNG_768P_CHARGER2, DATA_768P_CHARGER2_GUID}, {PNG_768P_CHARGER3, DATA_768P_CHARGER3_GUID}, {PNG_768P_PHONE1, DATA_768P_PHONE1_GUID}, {PNG_768P_PHONE2, DATA_768P_PHONE2_GUID}, {PNG_768P_PHONE3, DATA_768P_PHONE3_GUID}, {PNG_1440P_PHONE1, DATA_1440P_PHONE1_GUID}, {PNG_1440P_PHONE2, DATA_1440P_PHONE2_GUID}, {PNG_1440P_PHONE3, DATA_1440P_PHONE3_GUID} }; UINTN mNumberBase = PNG_4K_0; UINTN DATA_CHARGER1; UINTN DATA_CHARGER2; UINTN DATA_CHARGER3; UINTN DATA_PHONE1; UINTN DATA_PHONE2; UINTN DATA_PHONE3; /** Width of the rectangle @param Rect Pointer to rectangle data which will be inflated @retval TRUE Rectangle data is inflated **/ UINTN EFIAPI WidthRect ( IN OUT RECT *Rect ) { return (Rect->right - Rect->left + 1); } /** Height of the rectangle @param Rect Pointer to rectangle data which will be inflated @retval TRUE Rectangle data is inflated **/ UINTN EFIAPI HeightRect ( IN OUT RECT *Rect ) { return (Rect->bottom - Rect->top + 1); } /** Display Blt on the screen @param Blt Blt buffer. @param Mode Blt mode. @param Rect Rectangle data. @retval Status Display status. **/ EFI_STATUS DisplayBitBlt ( IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION Mode, IN RECT *Rect ) { EFI_STATUS Status; UINTN X; UINTN Y; UINTN Width; UINTN Height; Status = EFI_SUCCESS; // // 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; switch (Mode) { case EfiBltBufferToVideo: Status = mGraphicsOutput->Blt ( mGraphicsOutput, Blt, Mode, 0, 0, X, Y, Width, Height, 0 ); break; default: break; } return Status; } /** Display Blt on the screen @param PictureIndex PictureIndex for mResources []. @param PictureWidth Picture width. @param PictureHeight Picture height. @retval Status Get image length status **/ EFI_STATUS GetImageLength ( IN UINTN PictureIndex, IN UINTN *PictureWidth, IN UINTN *PictureHeight ) { EFI_STATUS Status; UINT8 *Blt; UINTN BltSize; UINTN BltWidth; UINTN BltHeight; UINT8 *PngImage; UINTN PngImageSize; EFI_GUID PictureGuid; UINTN Index; Status = EFI_UNSUPPORTED; Blt = NULL; BltSize = 0; BltWidth = 0; BltHeight = 0; PngImage = NULL; PngImageSize = 0; if (PictureIndex >= (sizeof (mResources) / sizeof (NG_PNG))) { return EFI_UNSUPPORTED; } // // Get picture file guid by PictureIndex. // for (Index = 0; Index < (sizeof (mResources) / sizeof (NG_PNG)) ; Index++) { if (mResources[Index].PictureIndex == PictureIndex) { PictureGuid = mResources[Index].PictureGuid; break; } } if (Index == (sizeof (mResources) / sizeof (NG_PNG))) { return EFI_UNSUPPORTED; } Status = GetSectionFromAnyFv ( &PictureGuid, EFI_SECTION_RAW, 0, (VOID **) &PngImage, &PngImageSize ); if (EFI_ERROR (Status)) { return Status; } Status = mPngDecoder->DecodeImage ( mPngDecoder, PngImage, PngImageSize, &Blt, &BltSize, &BltHeight, &BltWidth ); *PictureWidth = BltWidth; *PictureHeight = BltHeight; if (PngImage != NULL) { FreePool (PngImage); } if (Blt != NULL) { FreePool (Blt); } return Status; } /** Display Picture according to PictureIndex after resize and scale. @param PictureIndex PictureIndex for mResources []. @param Rect Pointer to rectangle data which will be inflated. @retval Status Draw image status **/ EFI_STATUS DrawImage ( IN UINTN PictureIndex, IN RECT *Rect ) { EFI_STATUS Status; UINT8 *Blt; UINTN BltSize; UINTN BltWidth; UINTN BltHeight; UINT8 *NewBlt; UINTN NewBltWidth; UINTN NewBltHeight; RECT ImageRect; UINT8 *PngImage; UINTN PngImageSize; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel; UINT8 Exchange; UINTN X_ratio; UINTN Y_ratio; UINTN I; UINTN J; UINTN X2; UINTN Y2; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Pixels; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Temp; EFI_GUID PictureGuid; UINTN Index; Status = EFI_UNSUPPORTED; if (Rect == NULL) { return EFI_UNSUPPORTED; } if (PictureIndex >= (sizeof (mResources) / sizeof (NG_PNG))) { return EFI_UNSUPPORTED; } Blt = NULL; BltSize = 0; BltWidth = 0; BltHeight = 0; NewBlt = NULL; NewBltWidth = 0; NewBltHeight = 0; PngImage = NULL; PngImageSize = 0; BltPixel = NULL; Exchange = 0; X_ratio = 0; Y_ratio = 0; I = 0; J = 0; X2 = 0; Y2 = 0; Pixels = NULL; Temp = NULL; Index = 0; for (Index = 0; Index < (sizeof (mResources) / sizeof (NG_PNG)); Index++) { if (mResources[Index].PictureIndex == PictureIndex) { PictureGuid = mResources[Index].PictureGuid; break; } } if (Index == (sizeof (mResources) / sizeof (NG_PNG))) { return EFI_UNSUPPORTED; } Status = GetSectionFromAnyFv ( &PictureGuid, EFI_SECTION_RAW, 0, (VOID **) &PngImage, &PngImageSize ); if (EFI_ERROR (Status)) { return Status; } Status = mPngDecoder->DecodeImage ( mPngDecoder, PngImage, PngImageSize, &Blt, &BltSize, &BltHeight, &BltWidth ); if (EFI_ERROR (Status)) { if (PngImage != NULL) { FreePool (PngImage); } return Status; } // // When the alpha data is zero, it is total transparent, so set RGB to zero. // And after decoder, need exchange the byte of blue and red. // BltPixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*) Blt; for (Index = 0; Index < (BltWidth * BltHeight); Index++, BltPixel++) { if (BltPixel->Reserved == 0) { BltPixel->Blue = 0; BltPixel->Green = 0; BltPixel->Red = 0; } } // // Resize and scale now----------------------------------- // X_ratio = ((mHorizontalResolution) << 16) / mHorizontalResolutionStandard; Y_ratio = ((mVerticalResolution) << 16) / mVerticalResolutionStandard; ImageRect.left = (Rect->left * X_ratio) >> 16; ImageRect.top = (Rect->top * Y_ratio) >> 16; ImageRect.right = (Rect->right * X_ratio) >> 16; ImageRect.bottom = (Rect->bottom * Y_ratio) >> 16; NewBltWidth = WidthRect (&ImageRect); NewBltHeight = HeightRect (&ImageRect); NewBlt = (UINT8 *) AllocateZeroPool (sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * NewBltWidth * NewBltHeight); if (NewBlt == NULL) { if (Blt != NULL) { FreePool (Blt); } if (PngImage != NULL) { FreePool (PngImage); } return EFI_ABORTED; } X_ratio = ((BltWidth) << 16) / NewBltWidth; Y_ratio = ((BltHeight) << 16) / NewBltHeight; Pixels = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Blt; Temp = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NewBlt; for (I = 0; I < NewBltHeight; I++) { for (J = 0; J < NewBltWidth; J++) { X2 = ((J * X_ratio) >> 16); Y2 = ((I * Y_ratio) >> 16); Temp [(I * NewBltWidth) + J] = Pixels [(Y2 * BltWidth) + X2]; } } Status = DisplayBitBlt ( (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) NewBlt, EfiBltBufferToVideo, &ImageRect ); if (Blt != NULL) { FreePool (Blt); } if (NewBlt != NULL) { FreePool (NewBlt); } if (PngImage != NULL) { FreePool (PngImage); } return Status; } /** Display raw picture according to PictureIndex. @param PictureIndex PictureIndex for mResources []. @param Rect Pointer to rectangle data which will be inflated. @retval Status Draw image status **/ EFI_STATUS DrawRawImage ( IN UINTN PictureIndex, IN RECT *Rect ) { EFI_STATUS Status; UINT8 *Blt; UINTN BltSize; UINTN BltWidth; UINTN BltHeight; RECT ImageRect; UINT8 *PngImage; UINTN PngImageSize; EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPixel; UINT8 Exchange; UINTN X_ratio; UINTN Y_ratio; EFI_GUID PictureGuid; UINTN Index; Status = EFI_UNSUPPORTED; if (Rect == NULL) { return EFI_UNSUPPORTED; } if (PictureIndex >= (sizeof (mResources) / sizeof (NG_PNG))) { return EFI_UNSUPPORTED; } Blt = NULL; BltSize = 0; BltWidth = 0; BltHeight = 0; PngImage = NULL; PngImageSize = 0; Exchange = 0; X_ratio = 0; Y_ratio = 0; Index = 0; for (Index = 0; Index < (sizeof (mResources) / sizeof (NG_PNG)); Index++) { if (mResources[Index].PictureIndex == PictureIndex) { PictureGuid = mResources[Index].PictureGuid; break; } } if (Index == (sizeof (mResources) / sizeof (NG_PNG))) { return EFI_UNSUPPORTED; } Status = GetSectionFromAnyFv ( &PictureGuid, EFI_SECTION_RAW, 0, (VOID **) &PngImage, &PngImageSize ); if (EFI_ERROR (Status)) { return Status; } Status = mPngDecoder->DecodeImage ( mPngDecoder, PngImage, PngImageSize, &Blt, &BltSize, &BltHeight, &BltWidth ); if (EFI_ERROR (Status)) { if (PngImage != NULL) { FreePool (PngImage); } return Status; } // // When the alpha data is zero, it is total transparent, so set RGB to zero. // And after decoder, need exchange the byte of blue and red. // BltPixel = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Blt; for(Index = 0; Index < (BltWidth * BltHeight); Index++, BltPixel++) { if (BltPixel->Reserved == 0) { BltPixel->Blue = 0; BltPixel->Green = 0; BltPixel->Red = 0; } } X_ratio = ((mHorizontalResolution) << 16) / mHorizontalResolutionStandard; Y_ratio = ((mVerticalResolution) << 16) / mVerticalResolutionStandard; ImageRect.left = (Rect->left * X_ratio) >> 16; ImageRect.top = (Rect->top * Y_ratio) >> 16; ImageRect.right = ImageRect.left + BltWidth - 1; ImageRect.bottom = ImageRect.top + BltHeight - 1; Status = DisplayBitBlt ( (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) Blt, EfiBltBufferToVideo, &ImageRect ); if (Blt != NULL) { FreePool (Blt); } if (PngImage != NULL) { FreePool (PngImage); } return Status; } /** Init for needed protocol and battery picture. @param None @retval Status Initial status **/ EFI_STATUS InitializeGUI ( VOID ) { EFI_STATUS Status; UINT32 Index; UINTN SizeOfInfo; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; Status = EFI_SUCCESS; Index = 0; SizeOfInfo = 0; Info = NULL; // // Try to locate Graphics Output Protocol. // if (mGraphicsOutput == NULL) { Status = gBS->LocateProtocol ( &gEfiGraphicsOutputProtocolGuid, NULL, &mGraphicsOutput ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } } if (mPngDecoder == NULL) { Status = gBS->LocateProtocol ( &gEfiPngDecoderProtocolGuid, NULL, &mPngDecoder ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } } for (Index = 0; Index < mGraphicsOutput->Mode->MaxMode; Index++) { SizeOfInfo = 0; Info = NULL; mGraphicsOutput->QueryMode (mGraphicsOutput, Index, &SizeOfInfo, &Info); if ((Info->HorizontalResolution == X_3840_2160 && Info->VerticalResolution == Y_3840_2160) || (Info->HorizontalResolution == X_2560_1440 && Info->VerticalResolution == Y_2560_1440) || (Info->HorizontalResolution == X_1920_1080 && Info->VerticalResolution == Y_1920_1080) || //[-start-211116-SHAONN0016-add]// #ifdef S370_SUPPORT (Info->HorizontalResolution == X_1600_900 && Info->VerticalResolution == Y_1600_900)|| #endif //[-end-211116-SHAONN0016-add]// (Info->HorizontalResolution == X_1366_768 && Info->VerticalResolution == Y_1366_768)) { 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) || (mGraphicsOutput->Mode->MaxMode == Index)) { return EFI_UNSUPPORTED; } // // Error checking on options. // mHorizontalResolution = mGraphicsOutput->Mode->Info->HorizontalResolution; mVerticalResolution = mGraphicsOutput->Mode->Info->VerticalResolution; mNumberBase = PNG_4K_0; DATA_CHARGER1 = PNG_4K_CHARGER1; DATA_CHARGER2 = PNG_4K_CHARGER2; DATA_CHARGER3 = PNG_4K_CHARGER3; if (mVerticalResolution == Y_3840_2160) { DATA_PHONE1 = PNG_4K_PHONE1; DATA_PHONE2 = PNG_4K_PHONE2; DATA_PHONE3 = PNG_4K_PHONE3; } else if (mVerticalResolution == Y_2560_1440) { DATA_PHONE1 = PNG_1440P_PHONE1; DATA_PHONE2 = PNG_1440P_PHONE2; DATA_PHONE3 = PNG_1440P_PHONE3; //[-start-211116-SHAONN0016-modify]// #ifdef S370_SUPPORT } else if (mVerticalResolution == Y_1920_1080||mVerticalResolution == Y_1600_900) { #else } else if (mVerticalResolution == Y_1920_1080) { #endif //[-end-211116-SHAONN0016-modify]// DATA_PHONE1 = PNG_1080P_PHONE1; DATA_PHONE2 = PNG_1080P_PHONE2; DATA_PHONE3 = PNG_1080P_PHONE3; } else if (mVerticalResolution == Y_1366_768) { mNumberBase = PNG_768P_0; DATA_CHARGER1 = PNG_768P_CHARGER1; DATA_CHARGER2 = PNG_768P_CHARGER2; DATA_CHARGER3 = PNG_768P_CHARGER3; DATA_PHONE1 = PNG_768P_PHONE1; DATA_PHONE2 = PNG_768P_PHONE2; DATA_PHONE3 = PNG_768P_PHONE3; } return Status; } /** Draw battery picture @param Percent Battery percent. @param AcStatus AC status. @retval Status Draw battery status. **/ EFI_STATUS DrawBattery ( IN UINTN Percent, IN BOOLEAN AcStatus ) { EFI_STATUS Status; UINTN ImageBattery; UINTN PercentWidth; UINTN PercentHeight; UINTN ImagePercent[4] = {0}; UINTN ImagePercentWidth[4] = {0}; UINTN ImagePercentWidthTotal; UINTN ImagePercentLeft; UINTN BatteryWidth; UINTN BatteryHeight; UINTN CenterOfHorizontalResolution; UINTN CenterOfVerticalResolution; UINTN Index; Status = EFI_SUCCESS; ImageBattery = PNG_MAX; PercentWidth = 0; PercentHeight = 0; ImagePercentWidthTotal = 0; ImagePercentLeft = 0; BatteryWidth = 0; BatteryHeight = 0; CenterOfHorizontalResolution = mHorizontalResolutionStandard / 2; CenterOfVerticalResolution = mVerticalResolutionStandard / 2; Index = 0; // // battery // 0% --> 0%.png // 1%-10% --> 10%.png(red),(AC online: 10%_2.png(green)) // 11%-20% --> 20%.png(orange),(AC online: 20%_2.png(green)) // 21%-30% --> 30%.png // 31%-40% --> 40%.png // 41%-50% --> 50%.png // 51%-60% --> 60%.png // 61%-70% --> 70%.png // 71%-80% --> 80%.png // 81%-95% --> 90%.png // 95%-100% --> 100%.png // if (Percent <= 90) { if(AcStatus && (Percent > 0) && (Percent <= 20)) { ImageBattery = PNG_1080P_0_PERCENT + ((Percent + 9) / 10) + 10; } else { ImageBattery = PNG_1080P_0_PERCENT + ((Percent + 9) / 10); } } else if (Percent < 95) { ImageBattery = PNG_1080P_90_PERCENT; // 90% picture } else { ImageBattery = PNG_1080P_100_PERCENT; // 100% picture } BatteryWidth = 286; BatteryHeight = 650; Status = GetImageLength ( ImageBattery, &BatteryWidth, &BatteryHeight ); if (EFI_ERROR (Status)) { return Status; } BatteryHeight = (BatteryHeight * (((mVerticalResolutionStandard) << 16) / mVerticalResolution)) >> 16; // Resize for 4k BatteryWidth = (BatteryWidth * (((mHorizontalResolutionStandard) << 16) / mHorizontalResolution)) >> 16; // Resize for 4k mRectBattery.left = CenterOfHorizontalResolution - BatteryWidth / 2; mRectBattery.top = CenterOfVerticalResolution - BatteryHeight / 2; mRectBattery.right = mRectBattery.left + BatteryWidth - 1; mRectBattery.bottom = mRectBattery.top + BatteryHeight - 1; Status = DrawImage ( ImageBattery, &mRectBattery ); if (EFI_ERROR (Status)) { return Status; } if (Percent / 100 > 0) { //100% ImagePercent [0] = mNumberBase + 1; // 1 ImagePercent [1] = mNumberBase; // 0 ImagePercent [2] = mNumberBase; // 0 ImagePercent [3] = mNumberBase + 10; // % } else if (Percent / 10 > 0) { //10% <= xy% <= 99%; ImagePercent [0] = mNumberBase + (Percent / 10); // x ImagePercent [1] = mNumberBase + (Percent % 10); // y ImagePercent [2] = mNumberBase + 10; // % ImagePercent [3] = PNG_MAX; } else { ImagePercent [0] = mNumberBase + (Percent % 10); // y ImagePercent [1] = mNumberBase + 10; // % ImagePercent [2] = PNG_MAX; ImagePercent [3] = PNG_MAX; } for (Index = 0; Index < 4; Index++) { if (ImagePercent[Index] != PNG_MAX) { PercentWidth = 0; PercentHeight = 0; Status = GetImageLength ( ImagePercent[Index], &PercentWidth, &PercentHeight ); if (!EFI_ERROR (Status)) { // // Because percent picture is for 4k already, so only resize for Y_1366_768. // if (mVerticalResolution == Y_1366_768) { PercentWidth = (PercentWidth * (((mHorizontalResolutionStandard) << 16) / mHorizontalResolution)) >> 16; // Resize for 4k PercentHeight = (PercentHeight * (((mVerticalResolutionStandard) << 16) / mVerticalResolution)) >> 16; // Resize for 4k } ImagePercentWidth[Index] = PercentWidth; } else { return Status; } } } ImagePercentWidthTotal = ImagePercentWidth[0] + ImagePercentWidth[1] + ImagePercentWidth[2] + ImagePercentWidth[3]; //xx% ImagePercentLeft = CenterOfHorizontalResolution - ImagePercentWidthTotal / 2; for (Index = 0; Index < 4; Index++) { mRectPercent [Index].left = 0; //It depends on the real number. mRectPercent [Index].top = CenterOfVerticalResolution + BatteryHeight / 2 + 72; mRectPercent [Index].right = 0; //It depends on the real number. mRectPercent [Index].bottom = mRectPercent [Index].top + PercentHeight - 1; } mRectPercent [0].left = ImagePercentLeft; mRectPercent [0].right = mRectPercent [0].left + ImagePercentWidth [0] - 1; mRectPercent [1].left = mRectPercent [0].right + 1; mRectPercent [1].right = mRectPercent [1].left + ImagePercentWidth [1] - 1; mRectPercent [2].left = mRectPercent [1].right + 1; mRectPercent [2].right = mRectPercent [2].left + ImagePercentWidth [2] - 1; mRectPercent [3].left = mRectPercent [2].right + 1; mRectPercent [3].right = mRectPercent [3].left + ImagePercentWidth [3] - 1; if ((mVerticalResolution == Y_1366_768) || (mVerticalResolution == Y_3840_2160)) { for (Index = 0; Index < 4; Index++) { if (ImagePercent[Index] != PNG_MAX && ImagePercentWidth[Index] != 0) { Status = DrawRawImage ( ImagePercent [Index], &mRectPercent [Index] ); if (EFI_ERROR (Status)) { return Status; } } } } else { for (Index = 0; Index < 4; Index++) { if (ImagePercent [Index] != PNG_MAX && ImagePercentWidth[Index] != 0) { Status = DrawImage ( ImagePercent [Index], &mRectPercent [Index] ); if (EFI_ERROR (Status)) { return Status; } } } } return Status; } /** Draw charge picture @param DynamicPicture Dynamic flag. @retval Status Draw charge picture status. **/ EFI_STATUS DrawCharger ( IN BOOLEAN DynamicPicture ) { EFI_STATUS Status; UINTN Image; UINTN CenterOfHorizontalResolution; UINTN CenterOfVerticalResolution; UINTN ChargerWidth; UINTN ChargerHeight; static UINTN Count1 = 0; Status = EFI_UNSUPPORTED; Image = DATA_CHARGER3; CenterOfHorizontalResolution = 0; CenterOfVerticalResolution = 0; ChargerWidth = 0; ChargerHeight = 0; if (DynamicPicture) { switch (Count1 % 3) { case 0: Image = DATA_CHARGER1; break; case 1: Image = DATA_CHARGER2; break; case 2: default: Image = DATA_CHARGER3; break; } } else { Image = DATA_CHARGER3; } Count1++; ChargerWidth = 128; ChargerHeight = 362; Status = GetImageLength ( Image, &ChargerWidth, &ChargerHeight ); if (EFI_ERROR (Status)) { return Status; } CenterOfHorizontalResolution = mHorizontalResolutionStandard / 2; CenterOfVerticalResolution = mVerticalResolutionStandard / 2; // // Because charger picture is for 4k already, so only resize for Y_1366_768. // if (mVerticalResolution == Y_1366_768) { ChargerHeight = (ChargerHeight * (((mVerticalResolutionStandard) << 16) / mVerticalResolution)) >> 16; // Resize for 4k ChargerWidth = (ChargerWidth * (((mHorizontalResolutionStandard) << 16) / mHorizontalResolution)) >> 16; // Resize for 4k } mRectCharger.left = CenterOfHorizontalResolution - (mRectBattery.right - mRectBattery.left + 1) / 2 - 32 - ChargerWidth; // mRectBattery.right - mRectBattery.left + 1 = mBatteryWidth mRectCharger.top = CenterOfVerticalResolution - ChargerHeight / 2; mRectCharger.right = mRectCharger.left + ChargerWidth - 1; mRectCharger.bottom = mRectCharger.top + ChargerHeight - 1; if((mVerticalResolution == Y_1366_768) || (mVerticalResolution == Y_3840_2160)) { Status = DrawRawImage ( Image, &mRectCharger ); } else { Status = DrawImage ( Image, &mRectCharger ); } return Status; } /** Draw AOU picture @param DynamicPicture Dynamic flag. @retval Status Draw AOU picture status. **/ EFI_STATUS DrawAOUDevice ( IN BOOLEAN DynamicPicture ) { EFI_STATUS Status; UINTN Image; UINTN CenterOfHorizontalResolution; UINTN CenterOfVerticalResolution; UINTN PhoneWidth; UINTN PhoneHeight; static UINTN Count = 0; Status = EFI_UNSUPPORTED; Image = DATA_PHONE3; CenterOfHorizontalResolution = 0; CenterOfVerticalResolution = 0; PhoneWidth = 0; PhoneHeight = 0; if (DynamicPicture) { switch (Count % 3) { case 0: Image = DATA_PHONE1; break; case 1: Image = DATA_PHONE2; break; case 2: default: Image = DATA_PHONE3; break; } } else { Image = DATA_PHONE3; } Count++; PhoneWidth = 156; PhoneHeight = 398; Status = GetImageLength ( Image, &PhoneWidth, &PhoneHeight ); if (EFI_ERROR (Status)) { return Status; } CenterOfHorizontalResolution = mHorizontalResolutionStandard / 2; CenterOfVerticalResolution = mVerticalResolutionStandard / 2; PhoneHeight = (PhoneHeight * (((mVerticalResolutionStandard) << 16) / mVerticalResolution)) >> 16; // Resize for 4k PhoneWidth = (PhoneWidth * (((mHorizontalResolutionStandard) << 16) / mHorizontalResolution)) >> 16; // Resize for 4k mRectPhone.left = CenterOfHorizontalResolution + (mRectBattery.right - mRectBattery.left + 1) / 2 + 16; // mRectBattery.right - mRectBattery.left + 1 = mBatteryWidth mRectPhone.top = CenterOfVerticalResolution - PhoneHeight / 2; mRectPhone.right = mRectPhone.left + PhoneWidth - 1; mRectPhone.bottom = mRectPhone.top + PhoneHeight - 1; Status = DrawRawImage ( Image, &mRectPhone ); return Status; }