mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-09-21 02:51:04 +02:00
implemented LoadXImage
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
parent
c64788a19e
commit
054898eef3
@ -294,13 +294,16 @@ void XImage::FlipRB(bool WantAlpha)
|
||||
* Error = 0 - Success
|
||||
* Error = 28 - invalid signature
|
||||
*/
|
||||
unsigned XImage::FromPNG(const UINT8 * Data, UINTN Length)
|
||||
EFI_STATUS XImage::FromPNG(const UINT8 * Data, UINTN Length)
|
||||
{
|
||||
if (Data == NULL) return EFI_INVALID_PARAMETER;
|
||||
UINT8 * PixelPtr = (UINT8 *)&PixelData[0];
|
||||
unsigned Error = eglodepng_decode(&PixelPtr, &Width, &Height, Data, Length);
|
||||
|
||||
if (Error != 0 && Error != 28) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
FlipRB(true);
|
||||
return Error;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -309,31 +312,33 @@ unsigned XImage::FromPNG(const UINT8 * Data, UINTN Length)
|
||||
* The caller is responsible to free the array.
|
||||
*/
|
||||
|
||||
unsigned XImage::ToPNG(UINT8** Data, UINTN& OutSize)
|
||||
EFI_STATUS XImage::ToPNG(UINT8** Data, UINTN& OutSize)
|
||||
{
|
||||
size_t FileDataLength = 0;
|
||||
FlipRB(false);
|
||||
UINT8 * PixelPtr = (UINT8 *)&PixelData[0];
|
||||
unsigned Error = eglodepng_encode(Data, &FileDataLength, PixelPtr, Width, Height);
|
||||
OutSize = FileDataLength;
|
||||
return Error;
|
||||
if (Error) return EFI_UNSUPPORTED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* fill XImage object by raster data described in SVG
|
||||
* fill XImage object by raster data described in SVG file
|
||||
* caller should create the object with Width and Height and calculate scale
|
||||
* scale = 1 correspond to fill the rect with the image
|
||||
* scale = 0.5 will reduce image
|
||||
* scale = 0.5 will reduce image
|
||||
* but this procedure is mostly for testing purpose. Real SVG theme can't be divided to separate SVG files
|
||||
*/
|
||||
unsigned XImage::FromSVG(const CHAR8 *SVGData, float scale)
|
||||
EFI_STATUS XImage::FromSVG(const CHAR8 *SVGData, float scale)
|
||||
{
|
||||
NSVGimage *SVGimage;
|
||||
NSVGparser* p;
|
||||
|
||||
NSVGrasterizer* rast = nsvgCreateRasterizer();
|
||||
if (!rast) return 1;
|
||||
if (!rast) return EFI_UNSUPPORTED;
|
||||
char *input = (__typeof__(input))AllocateCopyPool(AsciiStrSize(SVGData), SVGData);
|
||||
if (!input) return 2;
|
||||
if (!input) return EFI_DEVICE_ERROR;
|
||||
|
||||
p = nsvgParse(input, 72, 1.f); //the parse will change input contents
|
||||
SVGimage = p->image;
|
||||
@ -350,7 +355,7 @@ unsigned XImage::FromSVG(const CHAR8 *SVGData, float scale)
|
||||
// nsvg__deleteParser(p); //can't delete raster until we make imageChain
|
||||
nsvgDeleteRasterizer(rast);
|
||||
FreePool(input);
|
||||
return 0;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
// Screen operations
|
||||
@ -491,30 +496,59 @@ void XImage::Draw(INTN x, INTN y, float scale)
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS XImage::LoadXImage(EFI_FILE *BaseDir, const XStringW& FileName)
|
||||
/*
|
||||
* IconName is just func_about for example
|
||||
* will search files
|
||||
* icons/iconname.icns - existing themes
|
||||
* icons/iconname.png - it will be more correct
|
||||
* iconname.png - for example checkbox.png
|
||||
* if not found use embedded. It should be decoded again after theme change
|
||||
* SVG themes filled separately after ThemeName defined so the procedure just return EFI_SUCCESS
|
||||
* The function always create new image and will not be used to get a link to existing image
|
||||
*/
|
||||
EFI_STATUS XImage::LoadXImage(EFI_FILE *BaseDir, const char* IconName)
|
||||
{
|
||||
return LoadXImage(BaseDir, XStringWP(IconName));
|
||||
}
|
||||
//dont call this procedure for SVG theme BaseDir == NULL?
|
||||
EFI_STATUS XImage::LoadXImage(EFI_FILE *BaseDir, const XStringW& IconName)
|
||||
{
|
||||
EFI_STATUS Status = EFI_NOT_FOUND;
|
||||
UINT8 *FileData = NULL;
|
||||
UINTN FileDataLength = 0;
|
||||
|
||||
// if (TypeSVG) {
|
||||
// if (TypeSVG) { //make a copy of SVG image
|
||||
// XImage NewImage = Theme.GetIcon(IconName);
|
||||
// setSizeInPixels(NewImage.GetWidth(), NewImage.GetHeight());
|
||||
// CopyMem(&PixelData[0], &NewImage.PixelData[0], GetSizeInBytes());
|
||||
// return EFI_SUCCESS;
|
||||
// }
|
||||
|
||||
if (BaseDir == NULL || FileName.isEmpty())
|
||||
if (BaseDir == NULL || IconName.isEmpty())
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
// load file
|
||||
XStringW FileName = L"icons\\" + IconName + L".icns";
|
||||
Status = egLoadFile(BaseDir, FileName.data(), &FileData, &FileDataLength);
|
||||
if (EFI_ERROR(Status))
|
||||
return Status;
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
FileName = L"icons\\" + IconName + L".png";
|
||||
Status = egLoadFile(BaseDir, FileName.data(), &FileData, &FileDataLength);
|
||||
if (EFI_ERROR(Status)) {
|
||||
FileName = IconName + L".png";
|
||||
if (EFI_ERROR(Status)) {
|
||||
FileName = IconName; //may be it already contain extension, for example Logo.png
|
||||
Status = egLoadFile(BaseDir, FileName.data(), &FileData, &FileDataLength);
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// decode it
|
||||
unsigned ret = FromPNG(FileData, FileDataLength);
|
||||
|
||||
if (ret) {
|
||||
DBG("%s not decoded\n", FileName.data());
|
||||
Status = EFI_UNSUPPORTED;
|
||||
Status = FromPNG(FileData, FileDataLength);
|
||||
if (EFI_ERROR(Status)) {
|
||||
DBG("%s not decoded\n", IconName.data());
|
||||
}
|
||||
FreePool(FileData);
|
||||
return Status;
|
||||
|
@ -84,9 +84,9 @@ public:
|
||||
void CopyScaled(const XImage& Image, float scale);
|
||||
void Compose(INTN PosX, INTN PosY, const XImage& TopImage, bool Lowest); //instead of compose we often can Back.Draw(...) + Top.Draw(...)
|
||||
void FlipRB(bool WantAlpha);
|
||||
unsigned FromPNG(const UINT8 * Data, UINTN Lenght);
|
||||
unsigned ToPNG(UINT8** Data, UINTN& OutSize);
|
||||
unsigned FromSVG(const CHAR8 *SVGData, float scale);
|
||||
EFI_STATUS FromPNG(const UINT8 * Data, UINTN Lenght);
|
||||
EFI_STATUS ToPNG(UINT8** Data, UINTN& OutSize);
|
||||
EFI_STATUS FromSVG(const CHAR8 *SVGData, float scale);
|
||||
void GetArea(const EG_RECT& Rect);
|
||||
void GetArea(INTN x, INTN y, UINTN W, UINTN H);
|
||||
void Draw(INTN x, INTN y, float scale);
|
||||
@ -94,6 +94,7 @@ public:
|
||||
//I changed the name because LoadImage is too widely used
|
||||
// will be used instead of old egLoadImage
|
||||
EFI_STATUS LoadXImage(EFI_FILE *Dir, const XStringW& FileName); //for example LoadImage(ThemeDir, L"icons\\" + Name);
|
||||
EFI_STATUS LoadXImage(EFI_FILE *BaseDir, const char* IconName);
|
||||
void EnsureImageSize(IN UINTN Width, IN UINTN Height, IN CONST EFI_GRAPHICS_OUTPUT_BLT_PIXEL& Color);
|
||||
|
||||
};
|
||||
|
@ -59,9 +59,9 @@ CONST CHAR8* IconsNames[] = {
|
||||
"os_freedos",
|
||||
"os_win",
|
||||
"os_vista",
|
||||
"radio_button",
|
||||
"radio_button", //20
|
||||
"radio_button_selected",
|
||||
"checkbox",
|
||||
"checkbox", //22
|
||||
"checkbox_checked",
|
||||
"scrollbar_background", //24
|
||||
"scrollbar_holder"
|
||||
@ -184,44 +184,106 @@ void XTheme::AddIcon(Icon& NewIcon)
|
||||
|
||||
//if ImageNight is not set then Image should be used
|
||||
#define DEC_BUILTIN_ICON(id, ico) { \
|
||||
Icon NewIcon(id); \
|
||||
NewIcon.Image.FromPNG(ACCESS_EMB_DATA(ico), ACCESS_EMB_SIZE(ico)); \
|
||||
Icons.AddCopy(NewIcon); \
|
||||
Image.FromPNG(ACCESS_EMB_DATA(ico), ACCESS_EMB_SIZE(ico)); \
|
||||
}
|
||||
|
||||
#define DEC_BUILTIN_ICON2(id, ico, dark) { \
|
||||
Icon NewIcon(id); \
|
||||
NewIcon.Image.FromPNG(ACCESS_EMB_DATA(ico), ACCESS_EMB_SIZE(ico)); \
|
||||
NewIcon.ImageNight.FromPNG(ACCESS_EMB_DATA(dark), ACCESS_EMB_SIZE(dark)); \
|
||||
Icons.AddCopy(NewIcon); \
|
||||
Image.FromPNG(ACCESS_EMB_DATA(ico), ACCESS_EMB_SIZE(ico)); \
|
||||
ImageNight.FromPNG(ACCESS_EMB_DATA(dark), ACCESS_EMB_SIZE(dark)); \
|
||||
}
|
||||
|
||||
Icon::Icon(INTN Index, BOOLEAN Embedded) : Image(0), ImageNight(0)
|
||||
{
|
||||
Id = Index;
|
||||
if (Index < BUILTIN_ICON_FUNC_ABOUT || Index >=BUILTIN_ICON_COUNT || !Embedded) {
|
||||
Name.setEmpty();
|
||||
return;
|
||||
}
|
||||
Name.takeValueFrom(IconsNames[Index]);
|
||||
switch (Id) {
|
||||
case BUILTIN_ICON_FUNC_ABOUT:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_ABOUT, emb_func_about, emb_dark_func_about)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_OPTIONS:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_OPTIONS, emb_func_options, emb_dark_func_options)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_CLOVER:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_CLOVER, emb_func_clover, emb_dark_func_clover)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_SECURE_BOOT:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_SECURE_BOOT, emb_func_secureboot, emb_dark_func_secureboot)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_SECURE_BOOT_CONFIG:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_SECURE_BOOT_CONFIG, emb_func_secureboot_config, emb_dark_func_secureboot_config)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_RESET:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_RESET, emb_func_reset, emb_dark_func_reset)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_EXIT:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_EXIT, emb_func_exit, emb_dark_func_exit)
|
||||
break;
|
||||
case BUILTIN_ICON_FUNC_HELP:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_FUNC_HELP, emb_func_help, emb_dark_func_help)
|
||||
break;
|
||||
case BUILTIN_ICON_TOOL_SHELL:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_TOOL_SHELL, emb_func_shell, emb_dark_func_shell)
|
||||
break;
|
||||
case BUILTIN_ICON_BANNER:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_ICON_BANNER, emb_logo, emb_dark_logo)
|
||||
break;
|
||||
case BUILTIN_SELECTION_SMALL:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_SELECTION_SMALL, emb_selection_small, emb_dark_selection_small)
|
||||
break;
|
||||
case BUILTIN_SELECTION_BIG:
|
||||
DEC_BUILTIN_ICON2(BUILTIN_SELECTION_BIG, emb_selection_big, emb_dark_selection_big)
|
||||
break;
|
||||
//next icons have no dark image
|
||||
case BUILTIN_ICON_POINTER:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_POINTER, emb_pointer)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_INTERNAL:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_INTERNAL, emb_vol_internal)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_EXTERNAL:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_EXTERNAL, emb_vol_external)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_OPTICAL:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_OPTICAL, emb_vol_optical)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_BOOTER:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_BOOTER, emb_vol_internal_booter)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_INTERNAL_HFS:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_INTERNAL_HFS, emb_vol_internal_hfs)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_INTERNAL_APFS:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_INTERNAL_APFS, emb_vol_internal_apfs)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_INTERNAL_NTFS:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_INTERNAL_NTFS, emb_vol_internal_ntfs)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_INTERNAL_EXT3:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_INTERNAL_EXT3, emb_vol_internal_ext)
|
||||
break;
|
||||
case BUILTIN_ICON_VOL_INTERNAL_REC:
|
||||
DEC_BUILTIN_ICON(BUILTIN_ICON_VOL_INTERNAL_REC, emb_vol_internal_recovery)
|
||||
break;
|
||||
|
||||
default:
|
||||
Name.setEmpty();
|
||||
break;
|
||||
}
|
||||
//something to do else?
|
||||
}
|
||||
|
||||
|
||||
|
||||
void XTheme::FillByEmbedded()
|
||||
{
|
||||
DEC_BUILTIN_ICON2(0, emb_func_about, emb_dark_func_about)
|
||||
DEC_BUILTIN_ICON2(1, emb_func_options, emb_dark_func_options)
|
||||
DEC_BUILTIN_ICON2(2, emb_func_clover, emb_dark_func_clover)
|
||||
DEC_BUILTIN_ICON2(3, emb_func_secureboot, emb_dark_func_secureboot)
|
||||
DEC_BUILTIN_ICON2(4, emb_func_secureboot_config, emb_dark_func_secureboot_config)
|
||||
DEC_BUILTIN_ICON2(5, emb_func_reset, emb_dark_func_reset)
|
||||
DEC_BUILTIN_ICON2(6, emb_func_exit, emb_dark_func_exit)
|
||||
DEC_BUILTIN_ICON2(7, emb_func_help, emb_dark_func_help)
|
||||
DEC_BUILTIN_ICON2(8, emb_func_shell, emb_dark_func_shell)
|
||||
DEC_BUILTIN_ICON(11, emb_pointer)
|
||||
DEC_BUILTIN_ICON(12, emb_vol_internal)
|
||||
DEC_BUILTIN_ICON(13, emb_vol_external)
|
||||
DEC_BUILTIN_ICON(14, emb_vol_optical)
|
||||
DEC_BUILTIN_ICON(16, emb_vol_internal_booter)
|
||||
DEC_BUILTIN_ICON(17, emb_vol_internal_hfs)
|
||||
DEC_BUILTIN_ICON(18, emb_vol_internal_apfs)
|
||||
DEC_BUILTIN_ICON(19, emb_vol_internal_ntfs)
|
||||
DEC_BUILTIN_ICON(20, emb_vol_internal_ext)
|
||||
DEC_BUILTIN_ICON(21, emb_vol_internal_recovery)
|
||||
DEC_BUILTIN_ICON2(22, emb_logo, emb_dark_logo)
|
||||
DEC_BUILTIN_ICON2(23, emb_selection_small, emb_dark_selection_small)
|
||||
DEC_BUILTIN_ICON2(24, emb_selection_big, emb_dark_selection_big)
|
||||
|
||||
for (INTN i = 0; i < BUILTIN_ICON_COUNT; ++i) {
|
||||
Icon NewIcon(i, true);
|
||||
Icons.AddCopy(NewIcon);
|
||||
}
|
||||
}
|
||||
|
||||
void XTheme::ClearScreen() //and restore background and banner
|
||||
@ -333,20 +395,21 @@ void XTheme::ClearScreen() //and restore background and banner
|
||||
|
||||
void XTheme::InitSelection()
|
||||
{
|
||||
|
||||
EFI_STATUS Status;
|
||||
if (!AllowGraphicsMode)
|
||||
return;
|
||||
//used to fill TextBuffer if selected
|
||||
SelectionBackgroundPixel.r = (SelectionColor >> 24) & 0xFF;
|
||||
SelectionBackgroundPixel.g = (SelectionColor >> 16) & 0xFF;
|
||||
SelectionBackgroundPixel.b = (SelectionColor >> 8) & 0xFF;
|
||||
SelectionBackgroundPixel.a = (SelectionColor >> 0) & 0xFF;
|
||||
|
||||
if (!SelectionImages[0].isEmpty()) {
|
||||
if (!SelectionImages[0].isEmpty()) { //already presents
|
||||
return;
|
||||
}
|
||||
// load small selection image
|
||||
if (SelectionSmallFileName.isEmpty()){
|
||||
SelectionImages[2].LoadImage(ThemeDir, SelectionSmallFileName);
|
||||
SelectionImages[2].LoadXImage(ThemeDir, SelectionSmallFileName);
|
||||
}
|
||||
if (SelectionImages[2].isEmpty()){
|
||||
// SelectionImages[2] = BuiltinIcon(BUILTIN_SELECTION_SMALL);
|
||||
@ -367,7 +430,7 @@ void XTheme::InitSelection()
|
||||
|
||||
// load big selection image
|
||||
if (!TypeSVG && !SelectionBigFileName.isEmpty()) {
|
||||
SelectionImages[0].LoadImage(ThemeDir, SelectionBigFileName);
|
||||
SelectionImages[0].LoadXImage(ThemeDir, SelectionBigFileName);
|
||||
// SelectionImages[0].EnsureImageSize(row0TileSize, row0TileSize, &MenuBackgroundPixel);
|
||||
}
|
||||
if (SelectionImages[0].isEmpty()) {
|
||||
@ -394,7 +457,7 @@ void XTheme::InitSelection()
|
||||
if (BootCampStyle) {
|
||||
// load indicator selection image
|
||||
if (!SelectionIndicatorName.isEmpty()) {
|
||||
SelectionImages[4].LoadImage(ThemeDir, SelectionIndicatorName);
|
||||
SelectionImages[4].LoadXImage(ThemeDir, SelectionIndicatorName);
|
||||
}
|
||||
if (!SelectionImages[4].isEmpty()) {
|
||||
SelectionImages[4].FromPNG(ACCESS_EMB_DATA(emb_selection_indicator), ACCESS_EMB_SIZE(emb_selection_indicator));
|
||||
@ -427,11 +490,30 @@ void XTheme::InitSelection()
|
||||
//it was a nonsense egLoadImage is just inluded into egLoadIcon.
|
||||
// will be corrected with XTheme support
|
||||
//the procedure loadIcon should also check embedded icons
|
||||
//DECLARE_EMB_EXTERN_WITH_SIZE(emb_radio_button_selected)
|
||||
//DECLARE_EMB_EXTERN_WITH_SIZE(emb_radio_button)
|
||||
//DECLARE_EMB_EXTERN_WITH_SIZE(emb_checkbox)
|
||||
//DECLARE_EMB_EXTERN_WITH_SIZE(emb_checkbox_checked)
|
||||
|
||||
Button[0] = GetIcon("radio_button");
|
||||
Button[1] = GetIcon("radio_button_selected"));
|
||||
Button[2] = GetIcon("checkbox");
|
||||
Button[3] = GetIcon("checkbox_checked");
|
||||
DECLARE_EMB_EXTERN_WITH_SIZE(emb_dark_font_data)
|
||||
|
||||
|
||||
Status = Button[0].LoadXImage(ThemeDir, "radio_button");
|
||||
if (EFI_ERROR(Status)) {
|
||||
Button[0].FromPNG(ACCESS_EMB_DATA(emb_radio_button), ACCESS_EMB_SIZE(emb_radio_button));
|
||||
}
|
||||
Status = Button[1].LoadXImage(ThemeDir, "radio_button_selected"));
|
||||
if (EFI_ERROR(Status)) {
|
||||
Button[0].FromPNG(ACCESS_EMB_DATA(emb_radio_button_selected), ACCESS_EMB_SIZE(emb_radio_button_selected));
|
||||
}
|
||||
Status = Button[2].LoadXImage(ThemeDir, "checkbox");
|
||||
if (EFI_ERROR(Status)) {
|
||||
Button[0].FromPNG(ACCESS_EMB_DATA(emb_checkbox), ACCESS_EMB_SIZE(emb_checkbox));
|
||||
}
|
||||
Status = Button[3].LoadXImage(ThemeDir, "checkbox_checked");
|
||||
if (EFI_ERROR(Status)) {
|
||||
Button[0].FromPNG(ACCESS_EMB_DATA(emb_checkbox_checked), ACCESS_EMB_SIZE(emb_checkbox_checked));
|
||||
}
|
||||
|
||||
// non-selected background images
|
||||
|
||||
@ -450,13 +532,25 @@ void XTheme::InitSelection()
|
||||
|
||||
}
|
||||
|
||||
//use this only for PNG theme
|
||||
void XTheme::FillByDir() //assume ThemeDir is defined by InitTheme() procedure
|
||||
{
|
||||
for (INTN i=0; i<BUILTIN_ICON_COUNT; ++i) {
|
||||
Icon NewIcon(i);
|
||||
NewIcon.Image.LoadImage(ThemeDir, XStringWP(IconsNames[i]));
|
||||
NewIcon.ImageNight.LoadImage(ThemeDir, XStringWP(IconsNames[i]) + "_night");
|
||||
for (INTN i = 0; i < BUILTIN_ICON_COUNT; ++i) {
|
||||
Icon NewIcon(i, true); //initialize with embedded but further replace by loaded
|
||||
NewIcon.Image.LoadXImage(ThemeDir, IconsNames[i]));
|
||||
NewIcon.ImageNight.LoadXImage(ThemeDir, XStringWP(IconsNames[i]) + "_night");
|
||||
Icons.AddCopy(NewIcon);
|
||||
}
|
||||
//to be continued
|
||||
|
||||
for (INTN i = BUILTIN_ICON_COUNT; i < 45; ++i) {
|
||||
Icon NewIcon(i); //there is no embedded
|
||||
NewIcon.Image.LoadXImage(ThemeDir, IconsNames[i])); //all os_***
|
||||
Icons.AddCopy(NewIcon);
|
||||
}
|
||||
|
||||
InitSelection(); //initialize selections, buttons
|
||||
|
||||
//load banner
|
||||
Banner.LoadXImage(ThemeDir, BannerFileName);
|
||||
|
||||
}
|
||||
|
@ -637,7 +637,16 @@ EFI_STATUS egScreenShot(VOID)
|
||||
//convert to PNG
|
||||
UINT8 *FileData = NULL;
|
||||
UINTN FileDataLength = 0U;
|
||||
Screen.ToPNG(&FileData, FileDataLength);
|
||||
Status = Screen.ToPNG(&FileData, FileDataLength);
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (FileData != NULL) {
|
||||
FreePool(FileData);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
if (!FileData) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
//save file with a first unoccupied name
|
||||
XStringWP CommonName(L"EFI\\CLOVER\\misc\\screenshot");
|
||||
for (UINTN Index = 0; Index < 60; Index++) {
|
||||
|
Loading…
Reference in New Issue
Block a user