From 1248bf2c71d5631a955c1c32e3f8167b0c741879 Mon Sep 17 00:00:00 2001 From: Sergey Isakov Date: Sat, 18 Apr 2020 09:39:47 +0300 Subject: [PATCH] use embedded icon with same id if theme native absent Signed-off-by: Sergey Isakov --- rEFIt_UEFI/libeg/VectorGraphics.cpp | 23 +++++++++-------------- rEFIt_UEFI/libeg/XTheme.cpp | 29 ++++++++++++++++++++++++++--- rEFIt_UEFI/libeg/XTheme.h | 2 ++ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/rEFIt_UEFI/libeg/VectorGraphics.cpp b/rEFIt_UEFI/libeg/VectorGraphics.cpp index 7d81bea1a..aa2b3adbb 100755 --- a/rEFIt_UEFI/libeg/VectorGraphics.cpp +++ b/rEFIt_UEFI/libeg/VectorGraphics.cpp @@ -231,15 +231,13 @@ EFI_STATUS XTheme::ParseSVGXIcon(INTN Id, const XString& IconNameX, XImage* Imag EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer) { EFI_STATUS Status; - NSVGimage *SVGimage; - NSVGparser *mainParser; Icons.Empty(); // --- Parse theme.svg --- low case - SVGParser = (void *)nsvgParse((CHAR8*)buffer, 72, 1.f); //the buffer will be modified, it is how nanosvg works - mainParser = (NSVGparser*)SVGParser; - SVGimage = mainParser->image; + NSVGparser *mainParser = nsvgParse((CHAR8*)buffer, 72, 1.f); //the buffer will be modified, it is how nanosvg works + SVGParser = (void *)mainParser; //store the pointer for future use + NSVGimage *SVGimage = mainParser->image; if (!SVGimage) { DBG("Theme not parsed!\n"); return EFI_NOT_STARTED; @@ -247,7 +245,7 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer) // --- Get scale as theme design height vs screen height - // must be svg view-box + // must be svg view-box. This is Design Width and Heigth float vbx = mainParser->viewWidth; float vby = mainParser->viewHeight; DBG("Theme view-bounds: w=%f h=%f units=px\n", vbx, vby); //Theme view-bounds: w=1600.000000 h=900.000000 units=px @@ -261,10 +259,6 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer) Scale = ScaleF; CentreShift = (vbx * Scale - (float)UGAWidth) * 0.5f; -// if (mainParser->font) { //this is strange like last found font -// DBG("theme contains font-family=%s\n", mainParser->font->fontFamily); -// } - Background = XImage(UGAWidth, UGAHeight); if (!BigBack.isEmpty()) { BigBack.setEmpty(); @@ -286,22 +280,23 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer) if (EFI_ERROR(Status)) { Status = ParseSVGXIcon(BUILTIN_ICON_BANNER, "Banner"_XS, &Banner); } - DBG("Banner parsed\n"); +// DBG("Banner parsed\n"); BanHeight = (int)(Banner.GetHeight() * Scale + 1.f); DBG(" parsed banner->width=%lld height=%lld\n", Banner.GetWidth(), BanHeight); //parsed banner->width=467 height=89 // --- Make other icons for (INTN i = BUILTIN_ICON_FUNC_ABOUT; i <= BUILTIN_CHECKBOX_CHECKED; ++i) { - if (i == BUILTIN_ICON_BANNER) { //exclude "logo" as it done other way + if (i == BUILTIN_ICON_BANNER) { //exclude "logo" as it done as Banner continue; } Icon* NewIcon = new Icon(i, false); //initialize without embedded Status = ParseSVGXIcon(i, NewIcon->Name, &NewIcon->Image); + NewIcon->Native = !EFI_ERROR(Status); if (EFI_ERROR(Status) && (i >= BUILTIN_ICON_VOL_INTERNAL_HFS) && (i <= BUILTIN_ICON_VOL_INTERNAL_REC)) { - NewIcon->Image = GetIcon(BUILTIN_ICON_VOL_INTERNAL); //copy existing + NewIcon->Image = GetIconAlt(i, BUILTIN_ICON_VOL_INTERNAL); //copy existing } // DBG("parse %s status %s\n", NewIcon->Name.c_str(), strerror(Status)); Status = ParseSVGXIcon(i, NewIcon->Name + "_night"_XS, &NewIcon->ImageNight); @@ -309,7 +304,7 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer) if (EFI_ERROR(Status) && (i >= BUILTIN_ICON_VOL_INTERNAL_HFS) && (i <= BUILTIN_ICON_VOL_INTERNAL_REC)) { - NewIcon->ImageNight = GetIcon(BUILTIN_ICON_VOL_INTERNAL); //copy existing + NewIcon->ImageNight = GetIconAlt(i, BUILTIN_ICON_VOL_INTERNAL); //copy existing } Icons.AddReference(NewIcon, true); } diff --git a/rEFIt_UEFI/libeg/XTheme.cpp b/rEFIt_UEFI/libeg/XTheme.cpp index 8261ea5c2..edaf8922a 100644 --- a/rEFIt_UEFI/libeg/XTheme.cpp +++ b/rEFIt_UEFI/libeg/XTheme.cpp @@ -97,6 +97,7 @@ Icon::Icon(INTN Index, bool TakeEmbedded) : Image(), ImageNight() { Id = Index; Name.setEmpty(); + Native = false; if (Index >= BUILTIN_ICON_FUNC_ABOUT && Index <= BUILTIN_CHECKBOX_CHECKED) { Name.takeValueFrom(IconsNames[Index]); } @@ -307,7 +308,19 @@ const XImage& XTheme::GetIcon(const XString& Name) return NullIcon; //if name is not found } -const XImage& XTheme::GetIcon(INTN Id) +bool XTheme::CheckNative(INTN Id) +{ + for (size_t i = 0; i < Icons.size(); i++) + { + if (Icons[i].Id == Id) + { + return Icons[i].Native; + } + } + return false; +} + +const XImage& XTheme::GetIcon(INTN Id) //if not found then take embedded { for (size_t i = 0; i < Icons.size(); i++) { @@ -342,6 +355,12 @@ const XImage& XTheme::GetIcon(INTN Id) return NullIcon; //such Id is not found in the database } +/* + * Get Icon with this ID=id, for example vol_internal_hfs + * if not found then search for ID=Alt, for example vol_internal + * if not found then check embedded with ID=id + * if not found then check embedded with ID=Alt + */ const XImage& XTheme::GetIconAlt(INTN Id, INTN Alt) { for (size_t i = 0; i < Icons.size(); i++) @@ -355,8 +374,11 @@ const XImage& XTheme::GetIconAlt(INTN Id, INTN Alt) if (!Icons[i].Image.isEmpty()) { return Icons[i].Image; } - //if daylight or night icon absent - return GetIcon(Alt); //including NullIcon + if (CheckNative(Alt)) { + return GetIcon(Alt); + } + //if Id and Alt native absent return embedded + return GetIcon(Id); //including embedded } } return NullIcon; //such Id is not found in the database @@ -748,6 +770,7 @@ void XTheme::FillByDir() //assume ThemeDir is defined by InitTheme() procedure for (INTN i = 0; i <= BUILTIN_CHECKBOX_CHECKED; ++i) { Icon* NewIcon = new Icon(i); //initialize without embedded Status = NewIcon->Image.LoadXImage(ThemeDir, IconsNames[i]); + NewIcon->Native = !EFI_ERROR(Status); if (EFI_ERROR(Status) && (i >= BUILTIN_ICON_VOL_INTERNAL_HFS) && (i <= BUILTIN_ICON_VOL_INTERNAL_REC)) { diff --git a/rEFIt_UEFI/libeg/XTheme.h b/rEFIt_UEFI/libeg/XTheme.h index 862a90f20..4c1f13805 100644 --- a/rEFIt_UEFI/libeg/XTheme.h +++ b/rEFIt_UEFI/libeg/XTheme.h @@ -19,6 +19,7 @@ public: XString Name; //for example "os_moja", "vol_internal" XImage Image; XImage ImageNight; + bool Native; Icon(INTN Id, bool Embedded = false); ~Icon(); @@ -131,6 +132,7 @@ public: const XImage& GetIconAlt(INTN Id, INTN Alt); //if id not found const XImage& LoadOSIcon(const CHAR16* OSIconName); //TODO make XString provider const XImage& LoadOSIcon(const XString& Full); + bool CheckNative(INTN Id); //fonts void LoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols);