Skip to content

Commit

Permalink
XIcon::GetBest now returns a reference, which save time and memory.
Browse files Browse the repository at this point in the history
Added some const.
Remove GetIconP from XTheme.
  • Loading branch information
jief committed Nov 7, 2023
1 parent dbb93ab commit 8de61a2
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 120 deletions.
2 changes: 1 addition & 1 deletion MdePkg/Include/Protocol/GraphicsOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN JCONST EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
Expand Down
118 changes: 117 additions & 1 deletion Xcode/cpp_tests/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
#include "../../../PosixCompilation/xcode_utf_fixed.h"

#include "../../../rEFIt_UEFI/cpp_unit_test/all_tests.h"
#include "../../../rEFIt_UEFI/cpp_foundation/XToolsCommon.h"
//#include "../../../rEFIt_UEFI/cpp_foundation/XToolsCommon.h"
#include "../../../rEFIt_UEFI/libeg/XImage.h"
//#include "../../../rEFIt_UEFI/Platform/platformdata.h"

//class Boolean
Expand All @@ -34,13 +35,128 @@
// void setValue(bool a) {flag = a;}
//};

// The following is by no means a FULL solution!
#include <functional>
#include <iostream>
#include <cassert>

template<typename T>
class Property {
public:
Property(){}
operator const T& () const {
// Call override getter if we have it
if (getter) return getter();
return get();
}
const T& operator = (const T& other) {
// Call override setter if we have it
if (setter) return setter(other);
return set(other);
}
bool operator == (const T& other) const {
// Static cast makes sure our getter operator is called, so we could use overrides if those are in place
return static_cast<const T&>(*this) == other;
}
// Use this to always get without overrides, useful for use with overriding implementations
const T& get() const {
return t;
}
// Use this to always set without overrides, useful for use with overriding implementations
const T& set(const T& other) {
return t = other;
}
// Assign getter and setter to these properties
std::function<const T&()> getter;
std::function<const T&(const T&)> setter;
private:
T t;
};

// Basic usage, no override
struct Test {
Property<int> prop;
};

// Override getter and setter
struct TestWithOverride {
TestWithOverride(){
prop.setter = [&](const int& other){
std::cout << "Custom setter called" << std::endl;
return prop.set(other);
};
prop.setter = std::bind(&TestWithOverride::setProp,this,std::placeholders::_1);
prop.getter = std::bind(&TestWithOverride::getProp,this);
}
Property<int> prop;
private:
const int& getProp() const {
std::cout << "Custom getter called" << std::endl;
return prop.get();
}
const int& setProp(const int& other){
std::cout << "Custom setter called" << std::endl;
return prop.set(other);
}
};

class MyFloat {
public:
float f;
MyFloat() { f = 0.0f; }
MyFloat(float _f) : f(_f) {}
float get() { return 1; }
};
template<typename T>
class MutableRef : public T {
public:
T* t;
const T& operator = (const T* other) {
t = other;
return *t;
}
operator T& () {
return *t;
}
};


extern "C" int main(int argc, const char * argv[])
{
(void)argc;
(void)argv;
setlocale(LC_ALL, "en_US"); // to allow printf unicode char

MyFloat test = 5.0f;

MutableRef<MyFloat> Background;

Background = &test;
test = 6;
float test2 = Background.get();

Test t;
TestWithOverride t1;
t.prop = 1;
assert(t.prop == 1);
t1.prop = 1;
assert(t1.prop == 1);
/*
Expected output:
1. No aborts on assertions
2. Text:
Custom setter called
Custom getter called
*/









// xcode_utf_fixed_tests();
const int i = 2;
(void)i;
Expand Down
4 changes: 4 additions & 0 deletions rEFIt_UEFI/Platform/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ UINT32 GetCrc32(UINT8 *Buffer, UINTN Size)
return x;
}

#ifndef UNIT_TESTS_MACOS

extern "C" {
#include <Library/OcMemoryLib.h>
}
Expand All @@ -155,6 +157,8 @@ void displayFreeMemory(const XString8& prefix)
DebugLog(1, "--> %s: Firmware has %llu free pages (%llu in lower 4 GB)\n", prefix.c_str(), TotalMemory, LowMemory);
}

#endif


XBool haveError = false;

3 changes: 2 additions & 1 deletion rEFIt_UEFI/Platform/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,10 @@ extern XBool haveError;

#endif // __cplusplus


#ifndef UNIT_TESTS_MACOS
extern "C" {
void displayFreeMemory(const XString8& prefix);
}
#endif

#endif // _UTILS_H_
2 changes: 1 addition & 1 deletion rEFIt_UEFI/entry_scan/lockedgraphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static LOCKED_GRAPHICS *LockedGraphics;
// The screen lock
static XBool ScreenIsLocked;

static EFI_STATUS EFIAPI LockedGOPBlt(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL)
static EFI_STATUS EFIAPI LockedGOPBlt(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL)
{
return EFI_SUCCESS;
}
Expand Down
36 changes: 13 additions & 23 deletions rEFIt_UEFI/gui/REFIT_MAINMENU_SCREEN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,9 @@ void REFIT_MAINMENU_SCREEN::DrawMainMenuLabel(IN CONST XStringW& Text, IN INTN X
INTN X = XPos - (TextWidth >> 1) - (BadgeDim + 16);
INTN Y = YPos - ((BadgeDim - ThemeX->TextHeight) >> 1);
Back.CopyRect(ThemeX->Background, X, Y);
XBool free = false;
XImage *CurrSel = Entries[ScrollState.CurrentSelection].Image.GetBest(!Daylight, &free);
Back.Compose(0, 0, *CurrSel, false, BadgeDim/128.f);
const XImage& CurrSel = Entries[ScrollState.CurrentSelection].Image.GetBest(!Daylight);
Back.Compose(0, 0, CurrSel, false, BadgeDim/128.f);
Back.DrawOnBack(X, Y, Back);
if (free) {
delete CurrSel;
}
}

OldX = XPos;
Expand Down Expand Up @@ -238,8 +234,7 @@ void REFIT_MAINMENU_SCREEN::DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry,
}

// const XImage& MainImage = (!ThemeX->Daylight && !MainIcon.ImageNight.isEmpty())? MainIcon.ImageNight : MainIcon.Image;
XBool free = false;
XImage *MainImage = MainIcon.GetBest(!Daylight, &free);
const XImage& MainImage = MainIcon.GetBest(!Daylight);

INTN CompWidth = (Entry->Row == 0) ? ThemeX->row0TileSize : ThemeX->row1TileSize;
INTN CompHeight = CompWidth;
Expand All @@ -264,9 +259,9 @@ void REFIT_MAINMENU_SCREEN::DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry,
XImage Back(CompWidth, CompHeight);
Back.CopyRect(ThemeX->Background, XPos, YPos);

INTN OffsetX = (CompWidth - MainImage->GetWidth()) / 2;
INTN OffsetX = (CompWidth - MainImage.GetWidth()) / 2;
OffsetX = (OffsetX > 0) ? OffsetX: 0;
INTN OffsetY = (CompHeight - MainImage->GetHeight()) / 2;
INTN OffsetY = (CompHeight - MainImage.GetHeight()) / 2;
OffsetY = (OffsetY > 0) ? OffsetY: 0;

INTN OffsetTX = (CompWidth - TopImage.GetWidth()) / 2;
Expand All @@ -279,28 +274,24 @@ void REFIT_MAINMENU_SCREEN::DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry,
float composeScale = (ThemeX->NonSelectedGrey && !selected)? -1.f: 1.f;
if(ThemeX->SelectionOnTop) {
//place main image in centre. It may be OS or Drive
Back.Compose(OffsetX, OffsetY, *MainImage, false, composeScale);
Back.Compose(OffsetX, OffsetY, MainImage, false, composeScale);
} else {
Back.Compose(OffsetTX, OffsetTY, TopImage, false); //selection first
Back.Compose(OffsetX, OffsetY, *MainImage, false, composeScale);
Back.Compose(OffsetX, OffsetY, MainImage, false, composeScale);
}

Entry->Place.XPos = XPos;
Entry->Place.YPos = YPos;
Entry->Place.Width = MainImage->GetWidth();
Entry->Place.Height = MainImage->GetHeight();
Entry->Place.Width = MainImage.GetWidth();
Entry->Place.Height = MainImage.GetHeight();

if (free) {
delete MainImage;
}
// place the badge image
float fBadgeScale = ThemeX->BadgeScale/16.f;
if ((Entry->Row == 0) && BadgeIcon && !BadgeIcon->isEmpty()) {
// const XImage& BadgeImage = (!ThemeX->Daylight && !BadgeIcon->ImageNight.isEmpty()) ? &BadgeIcon->ImageNight : BadgeImage = &BadgeIcon->Image;
free = false;
XImage* BadgeImage = BadgeIcon->GetBest(!Daylight, &free);
INTN BadgeWidth = (INTN)(BadgeImage->GetWidth() * fBadgeScale);
INTN BadgeHeight = (INTN)(BadgeImage->GetHeight() * fBadgeScale);
const XImage& BadgeImage = BadgeIcon->GetBest(!Daylight);
INTN BadgeWidth = (INTN)(BadgeImage.GetWidth() * fBadgeScale);
INTN BadgeHeight = (INTN)(BadgeImage.GetHeight() * fBadgeScale);

if ((BadgeWidth + 8) < CompWidth && (BadgeHeight + 8) < CompHeight) {

Expand All @@ -319,8 +310,7 @@ void REFIT_MAINMENU_SCREEN::DrawMainMenuEntry(REFIT_ABSTRACT_MENU_ENTRY *Entry,
OffsetY += CompHeight - 8 - BadgeHeight;
}
// DBG(" badge offset=[%lld,%lld]\n", OffsetX, OffsetY);
Back.Compose(OffsetX, OffsetY, *BadgeImage, false, fBadgeScale);
if (free) delete BadgeImage;
Back.Compose(OffsetX, OffsetY, BadgeImage, false, fBadgeScale);
}
}

Expand Down
10 changes: 4 additions & 6 deletions rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1608,20 +1608,18 @@ void REFIT_MENU_SCREEN::GraphicsMenuStyle(IN UINTN Function, IN CONST CHAR16 *Pa
if (!TitleImage.isEmpty()) {
INTN FilmXPos = (INTN)(EntriesPosX - (TitleImage.Image.GetWidth() + (int)(TITLEICON_SPACING * ThemeX->Scale)));
INTN FilmYPos = (INTN)EntriesPosY;
XBool free;
XImage *tImage = TitleImage.GetBest(!Daylight, &free);
const XImage& tImage = TitleImage.GetBest(!Daylight);
// TitleImage.Image.Draw(FilmXPos, FilmYPos); //TODO - account night and svg

// update FilmPlace only if not set by InitAnime
if (FilmC->FilmPlace.Width == 0 || FilmC->FilmPlace.Height == 0) {
FilmC->FilmPlace.XPos = FilmXPos;
FilmC->FilmPlace.YPos = FilmYPos;
FilmC->FilmPlace.Width = tImage->GetWidth();
FilmC->FilmPlace.Height = tImage->GetHeight();
FilmC->FilmPlace.Width = tImage.GetWidth();
FilmC->FilmPlace.Height = tImage.GetHeight();
}

tImage->Draw(FilmXPos, FilmYPos);
if (free) delete tImage;
tImage.Draw(FilmXPos, FilmYPos);
}

if (InfoLines.size() > 0) {
Expand Down
8 changes: 4 additions & 4 deletions rEFIt_UEFI/libeg/VectorGraphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,13 @@ if ( nsvg__nbDanglingPtr() > 0 ) {
SelectionBackgroundPixel.Blue = (SelectionColor >> 8) & 0xFF;
SelectionBackgroundPixel.Reserved = (SelectionColor >> 0) & 0xFF;
//TODO make SelectionImages to be XIcon
SelectionImages[0] = *GetIconP(BUILTIN_SELECTION_BIG)->GetBest(!Daylight);
SelectionImages[2] = *GetIconP(BUILTIN_SELECTION_SMALL)->GetBest(!Daylight);
SelectionImages[4] = *GetIconP(BUILTIN_ICON_SELECTION)->GetBest(!Daylight);
SelectionImages[0] = GetIcon(BUILTIN_SELECTION_BIG).GetBest(!Daylight);
SelectionImages[2] = GetIcon(BUILTIN_SELECTION_SMALL).GetBest(!Daylight);
SelectionImages[4] = GetIcon(BUILTIN_ICON_SELECTION).GetBest(!Daylight);

//buttons
for (INTN i = BUILTIN_RADIO_BUTTON; i <= BUILTIN_CHECKBOX_CHECKED; ++i) {
Buttons[i - BUILTIN_RADIO_BUTTON] = *GetIconP(i)->GetBest(!Daylight);
Buttons[i - BUILTIN_RADIO_BUTTON] = GetIcon(i).GetBest(!Daylight);
}
//for (int i=0 ; i<6 ; i+=2 ) {
//SelectionImages[i].Draw(i*100, 0);
Expand Down
38 changes: 2 additions & 36 deletions rEFIt_UEFI/libeg/XIcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,43 +250,9 @@ EFI_STATUS XIcon::LoadXImage(const EFI_FILE *BaseDir, const XStringW& IconName)
return Status;
}

XImage* XIcon::GetBest(XBool night, XBool *free)
const XImage& XIcon::GetBest(XBool night) const
{
#if 1
if (ImageSVG) {
NSVGimage* sImage = (NSVGimage*)ImageSVGnight;
if (!night || !ImageSVGnight) sImage = (NSVGimage*)ImageSVG;
float Scale = sImage->scale;
NSVGrasterizer* rast = nsvgCreateRasterizer();
float Height = sImage->height * Scale;
float Width = sImage->width * Scale;
int iWidth = (int)(Width + 0.5f);
int iHeight = (int)(Height + 0.5f);
XImage* NewImage = new XImage(iWidth, iHeight); //TODO creating new XImage we have to delete it after use
if (sImage->shapes == NULL) {
if (free) *free = true;
return NewImage;
}
float bounds[4];
nsvg__imageBounds(sImage, bounds);

float tx = 0.f, ty = 0.f;
float realWidth = (bounds[2] - bounds[0]) * Scale;
float realHeight = (bounds[3] - bounds[1]) * Scale;
tx = (Width - realWidth) * 0.5f;
ty = (Height - realHeight) * 0.5f;

nsvgRasterize(rast, sImage, tx, ty, Scale, Scale, (UINT8*)NewImage->GetPixelPtr(0,0), iWidth, iHeight, iWidth*4);
nsvgDeleteRasterizer(rast);
// if (night) ImageNight = *NewImage;
// else Image = *NewImage;
// delete NewImage;
if (free) *free = true;
return NewImage;
}
#endif
XImage* RetImage = (night && !ImageNight.isEmpty())? &ImageNight : &Image;
if (free) *free = false;
const XImage& RetImage = (night && !ImageNight.isEmpty())? ImageNight : Image;
return RetImage;
}

Expand Down
2 changes: 1 addition & 1 deletion rEFIt_UEFI/libeg/XIcon.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class XIcon
// Default are not valid, as usual. We delete them. If needed, proper ones can be created
// Icon(const Icon&) = delete;
XIcon& operator=(const XIcon&); // = delete;
XImage* GetBest(XBool night, XBool *free = nullptr);
const XImage& GetBest(XBool night) const;
};


Expand Down
Loading

0 comments on commit 8de61a2

Please sign in to comment.