diff --git a/rEFIt_UEFI/Platform/Platform.h b/rEFIt_UEFI/Platform/Platform.h index 95715e052..e5be50c08 100755 --- a/rEFIt_UEFI/Platform/Platform.h +++ b/rEFIt_UEFI/Platform/Platform.h @@ -11,6 +11,7 @@ Headers collection for procedures //#define DEBUG_ALL 2 #include "Posix/posix.h" +#define USE_XTHEME 1 #ifdef __cplusplus extern "C" { diff --git a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h index a67d88fb1..192636f73 100644 --- a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h +++ b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h @@ -66,8 +66,13 @@ public: static XPointer mPointer; // XPointer mPointer; UINTN ID; +#if USE_XTHEME + XStringW Title; + XImage TitleImage; +#else CONST CHAR16 *Title; //Title is not const, but *Title is. It will be better to make it XStringW EG_IMAGE *TitleImage; +#endif XStringWArray InfoLines; XObjArray Entries; INTN TimeoutSeconds; diff --git a/rEFIt_UEFI/libeg/VectorGraphics.cpp b/rEFIt_UEFI/libeg/VectorGraphics.cpp index 8f8319ece..2a23f5ed2 100755 --- a/rEFIt_UEFI/libeg/VectorGraphics.cpp +++ b/rEFIt_UEFI/libeg/VectorGraphics.cpp @@ -11,7 +11,7 @@ #define TEST_SIZEOF 0 #define TEST_FONT 0 #define TEST_DITHER 0 -#define USE_XTHEME 0 + #include "../Platform/Platform.h" @@ -64,6 +64,129 @@ NSVGparser *mainParser = NULL; //it must be global variable #if USE_XTHEME EFI_STATUS ParseSVGXIcon(NSVGparser *p, INTN Id, CONST CHAR8 *IconName, float Scale, XImage& Image) { + EFI_STATUS Status = EFI_NOT_FOUND; + NSVGimage *SVGimage; + NSVGrasterizer* rast = nsvgCreateRasterizer(); + SVGimage = p->image; + NSVGshape *shape; + NSVGgroup *group; + NSVGimage *IconImage; + NSVGshape *shapeNext, *shapesTail = NULL, *shapePrev; + + NSVGparser* p2 = nsvg__createParser(); + IconImage = p2->image; + + shape = SVGimage->shapes; + shapePrev = NULL; + while (shape) { + group = shape->group; + shapeNext = shape->next; + while (group) { + if (strcmp(group->id, IconName) == 0) { + break; + } + group = group->next; + } + + if (group) { //the shape is in the group + // keep this sample for debug purpose +/* DBG("found shape %a", shape->id); + DBG(" from group %a\n", group->id); + if ((Id == BUILTIN_SELECTION_BIG) || + (Id == BUILTIN_ICON_BACKGROUND) || + (Id == BUILTIN_ICON_BANNER)) { + shape->debug = TRUE; + } */ + if (Theme.BootCampStyle && (strstr(IconName, "selection_big") != NULL)) { + shape->opacity = 0.f; + } + if (strstr(shape->id, "BoundingRect") != NULL) { + //there is bounds after nsvgParse() + IconImage->width = shape->bounds[2] - shape->bounds[0]; + IconImage->height = shape->bounds[3] - shape->bounds[1]; + if (!IconImage->height) { + IconImage->height = 200; + } + + if ((strstr(IconName, "selection_big") != NULL) && (!Theme.SelectionOnTop)) { + Theme.MainEntriesSize = (int)(IconImage->width * Scale); //xxx + Theme.row0TileSize = Theme.MainEntriesSize + (int)(16.f * Scale); + DBG("main entry size = %d\n", Theme.MainEntriesSize); + } + if ((strstr(IconName, "selection_small") != NULL) && (!Theme.SelectionOnTop)) { + Theme.row1TileSize = (int)(IconImage->width * Scale); + } + + // not exclude BoundingRect from IconImage? + shape->flags = 0; //invisible + if (shapePrev) { + shapePrev->next = shapeNext; + } + else { + SVGimage->shapes = shapeNext; + } + shape = shapeNext; + continue; //while(shape) it is BoundingRect shape + +// shape->opacity = 0.3f; + } + shape->flags = NSVG_VIS_VISIBLE; + // Add to tail +// ClipCount += shape->clip.count; + if (IconImage->shapes == NULL) + IconImage->shapes = shape; + else + shapesTail->next = shape; + shapesTail = shape; + if (shapePrev) { + shapePrev->next = shapeNext; + } + else { + SVGimage->shapes = shapeNext; + } + shapePrev->next = shapeNext; + } //the shape in the group + else { + shapePrev = shape; + } + shape = shapeNext; + } //while shape + shapesTail->next = NULL; + + //add clipPaths //xxx + NSVGclipPath* clipPaths = SVGimage->clipPaths; + NSVGclipPath* clipNext = NULL; + while (clipPaths) { + // ClipCount += clipPaths->shapes->clip.count; + group = clipPaths->shapes->group; + clipNext = clipPaths->next; + while (group) { + if (strcmp(group->id, IconName) == 0) { + break; + } + group = group->parent; + } + if (group) { + DBG("found clipPaths for %a\n", IconName); + IconImage->clipPaths = SVGimage->clipPaths; + break; + } + clipPaths = clipNext; + } + // DBG("found %d clips for %a\n", ClipCount, IconName); + // if (ClipCount) { //Id == BUILTIN_ICON_BANNER) { + // IconImage->clipPaths = SVGimage->clipPaths; + // } + + + float bounds[4]; + bounds[0] = FLT_MAX; + bounds[1] = FLT_MAX; + bounds[2] = -FLT_MAX; + bounds[3] = -FLT_MAX; + nsvg__imageBounds(p2, bounds); + CopyMem(IconImage->realBounds, bounds, 4 * sizeof(float)); + return EFI_SUCCESS; } #endif diff --git a/rEFIt_UEFI/libeg/XTheme.cpp b/rEFIt_UEFI/libeg/XTheme.cpp index 76c695341..2cc5f98d4 100644 --- a/rEFIt_UEFI/libeg/XTheme.cpp +++ b/rEFIt_UEFI/libeg/XTheme.cpp @@ -1,12 +1,82 @@ /* * a class to keep definitions for all theme settings */ +#include "libegint.h" #include "XTheme.h" -Icon::Icon() {} +CONST CHAR8* IconsNames[] = { + "func_about", + "func_options", + "func_clover", + "func_secureboot", + "func_secureboot_config", + "func_reset", + "func_shutdown", + "func_help", + "tool_shell", //8 + "tool_part", + "tool_rescue", + "pointer",//11 + "vol_internal", + "vol_external", + "vol_optical", + "vol_firewire", + "vol_clover" , + "vol_internal_hfs" , + "vol_internal_apfs", + "vol_internal_ntfs", + "vol_internal_ext3" , + "vol_recovery",//21 +// not used? + "logo", + "selection_small", + "selection_big", + //os icons + "os_mac", //0 + 25 + "os_tiger", + "os_leo", + "os_snow", + "os_lion", + "os_cougar", + "os_mav", + "os_yos", + "os_cap", + "os_sierra", + "os_hsierra", + "os_moja", //11 + "os_cata", //12 + "os_linux", + "os_ubuntu", + "os_suse", + "os_freebsd", //16 + "os_freedos", + "os_win", + "os_vista", + "radio_button", + "radio_button_selected", + "checkbox", + "checkbox_checked", + "scrollbar_background", //24 + "scrollbar_holder" +}; + +Icon::Icon(INTN Index) : Image(0), ImageNight(0) +{ + Id = Index; + Name = XString(IconsNames[Index]); +} + Icon::~Icon() {} -XTheme::XTheme() +XTheme::XTheme() { + Init(); +} + +XTheme::~XTheme() { + //nothing todo? +} + +void XTheme::Init() { DisableFlags = 0; HideBadges = 0; @@ -98,4 +168,46 @@ XImage& XTheme::GetIcon(INTN Id, BOOLEAN Night) void XTheme::AddIcon(Icon& NewIcon) { Icons.AddCopy(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); \ +} + +#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); \ +} + + +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_ICON(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) + } \ No newline at end of file diff --git a/rEFIt_UEFI/libeg/XTheme.h b/rEFIt_UEFI/libeg/XTheme.h index 7568378f7..52ddefa08 100644 --- a/rEFIt_UEFI/libeg/XTheme.h +++ b/rEFIt_UEFI/libeg/XTheme.h @@ -3,7 +3,7 @@ #include "../cpp_foundation/XToolsCommon.h" #include "../cpp_foundation/XObjArray.h" -#include "../cpp_foundation/XStringW.h" +#include "../cpp_foundation/XString.h" #include "libeg.h" #include "XImage.h" @@ -11,11 +11,11 @@ class Icon { public: INTN Id; //for example BUILTIN_ICON_POINTER - XStringW Name; //for example "os_moja", "vol_internal" + XString Name; //for example "os_moja", "vol_internal" XImage ImageNight; XImage Image; - Icon(); + Icon(INTN Id); ~Icon(); }; @@ -71,16 +71,21 @@ public: INTN CodepageSize; float Scale; float CentreShift; + INTN row0TileSize; + INTN row1TileSize; + void Init(); XImage Background; //Background and Banner will not be in array as they live own life XImage BigBack; //not sure is needed - XImage Banner; + XImage Banner; //same as logo in the array XImage& GetIcon(XStringW& Name, BOOLEAN Night); //get by name XImage& GetIcon(INTN Id, BOOLEAN Night); //get by id void AddIcon(Icon& NewIcon); //return EFI_STATUS? + void FillByEmbedded(); + XTheme(); //default constructor ~XTheme(); diff --git a/rEFIt_UEFI/refit/lib.cpp b/rEFIt_UEFI/refit/lib.cpp index 1da09c642..abd8caade 100644 --- a/rEFIt_UEFI/refit/lib.cpp +++ b/rEFIt_UEFI/refit/lib.cpp @@ -1748,10 +1748,7 @@ VOID DbgHeader(CONST CHAR8 *str) INTN len; UINTN end = AsciiSPrint(strLog, 50, "=== [ %a ] ", str); len = 50 - end; - // it causes memset generation ^( -// for (INTN i = 0; i < len; i++) { -// strLog[i + end] = '='; -// } + SetMem(&strLog[end], len , '='); strLog[49] = '\0'; DebugLog (1, "%a\n", strLog);