From 0aca20217d00795d786ecec71928e66a3e555103 Mon Sep 17 00:00:00 2001 From: SergeySlice Date: Mon, 18 May 2020 22:40:47 +0300 Subject: [PATCH] rasterize svg when needed Signed-off-by: SergeySlice --- rEFIt_UEFI/Platform/VersionString.cpp | 3 ++- rEFIt_UEFI/Platform/kernel_patcher.cpp | 4 +-- rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp | 24 +++--------------- rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h | 1 + rEFIt_UEFI/libeg/VectorGraphics.cpp | 12 +++------ rEFIt_UEFI/libeg/XTheme.cpp | 34 ++++++++++++++++++++++++-- rEFIt_UEFI/libeg/nanosvg.cpp | 18 ++++++++------ rEFIt_UEFI/libeg/nanosvg.h | 6 +++-- rEFIt_UEFI/refit.inf | 4 +-- 9 files changed, 62 insertions(+), 44 deletions(-) diff --git a/rEFIt_UEFI/Platform/VersionString.cpp b/rEFIt_UEFI/Platform/VersionString.cpp index c3b059168..fb04ff4d3 100644 --- a/rEFIt_UEFI/Platform/VersionString.cpp +++ b/rEFIt_UEFI/Platform/VersionString.cpp @@ -23,7 +23,8 @@ CHAR8 NonDetected[] = "10.10.10"; //longer string **/ -UINT64 AsciiStrVersionToUint64(const CHAR8 *Version, UINT8 MaxDigitByPart, UINT8 MaxParts) { +UINT64 AsciiStrVersionToUint64(const CHAR8 *Version, UINT8 MaxDigitByPart, UINT8 MaxParts) +{ UINT64 result = 0; UINT16 part_value = 0; UINT16 part_mult = 1; diff --git a/rEFIt_UEFI/Platform/kernel_patcher.cpp b/rEFIt_UEFI/Platform/kernel_patcher.cpp index 50a846cf3..5741add0f 100644 --- a/rEFIt_UEFI/Platform/kernel_patcher.cpp +++ b/rEFIt_UEFI/Platform/kernel_patcher.cpp @@ -14,8 +14,8 @@ #include "kext_inject.h" #include "kernel_patcher.h" -#include "sse3_patcher.h" -#include "sse3_5_patcher.h" +//#include "sse3_patcher.h" +//#include "sse3_5_patcher.h" #ifndef DEBUG_ALL #define KERNEL_DEBUG 0 diff --git a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp index 1f7611011..ae2a3f1fa 100644 --- a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp +++ b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.cpp @@ -75,23 +75,6 @@ static INTN MaxItemOnScreen = -1; #include "../Platform/Settings.h" #include "../Platform/StartupSound.h" // for audioIo -//extern REFIT_MENU_ITEM_RETURN MenuEntryReturn; -//extern UINTN ThemesNum; -//extern CONST CHAR16 *ThemesList[]; -//extern UINTN ConfigsNum; -//extern CHAR16 *ConfigsList[]; -//extern UINTN DsdtsNum; -//extern CHAR16 *DsdtsList[]; -//extern UINTN AudioNum; -//extern HDA_OUTPUTS AudioList[20]; -//extern CONST CHAR8 *AudioOutputNames[]; -//extern CHAR8 NonDetected[]; -//extern BOOLEAN GetLegacyLanAddress; -//extern UINT8 gLanMac[4][6]; // their MAC addresses -//extern EFI_AUDIO_IO_PROTOCOL *AudioIo; -// -// -//BOOLEAN SavePreBootLog = FALSE; #define SCROLL_LINE_UP (0) #define SCROLL_LINE_DOWN (1) @@ -121,14 +104,14 @@ static INTN MaxItemOnScreen = -1; // -static CHAR16 ArrowUp[2] = { ARROW_UP, 0 }; -static CHAR16 ArrowDown[2] = { ARROW_DOWN, 0 }; +const CHAR16 ArrowUp[2] = { ARROW_UP, 0 }; //defined in Simple Text Out protocol +const CHAR16 ArrowDown[2] = { ARROW_DOWN, 0 }; // //BOOLEAN MainAnime = FALSE; // ////TODO Scroll variables must be a part of REFIT_SCREEN ////BOOLEAN ScrollEnabled = FALSE; -BOOLEAN IsDragging = FALSE; +// INTN ScrollbarYMovement; // // @@ -791,6 +774,7 @@ UINTN REFIT_MENU_SCREEN::RunGenericMenu(IN MENU_STYLE_FUNC StyleFunc, IN OUT INT ScrollState.CurrentSelection = *DefaultEntryIndex; UpdateScroll(SCROLL_NONE); } + IsDragging = false; // DBG("RunGenericMenu CurrentSelection=%d MenuExit=%d\n", // State.CurrentSelection, MenuExit); diff --git a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h index bc90daa40..7c6524fed 100644 --- a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h +++ b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h @@ -94,6 +94,7 @@ public: SCROLL_STATE ScrollState; BOOLEAN ScrollEnabled; INTN TextStyle; + BOOLEAN IsDragging; //TODO scroll positions should depends on REFIT_SCREEN? // Or it just currently calculated to be global variables? diff --git a/rEFIt_UEFI/libeg/VectorGraphics.cpp b/rEFIt_UEFI/libeg/VectorGraphics.cpp index 24e80a2d2..d9226b675 100755 --- a/rEFIt_UEFI/libeg/VectorGraphics.cpp +++ b/rEFIt_UEFI/libeg/VectorGraphics.cpp @@ -178,11 +178,7 @@ EFI_STATUS XTheme::ParseSVGXIcon(INTN Id, const XString8& IconNameX, OUT XImage* // } float bounds[4]; - bounds[0] = FLT_MAX; - bounds[1] = FLT_MAX; - bounds[2] = -FLT_MAX; - bounds[3] = -FLT_MAX; - nsvg__imageBounds(p2, bounds); + nsvg__imageBounds(IconImage, bounds); CopyMem(IconImage->realBounds, bounds, 4 * sizeof(float)); if ((Id == BUILTIN_ICON_BANNER) && IconNameX.contains("Banner")) { BannerPosX = (int)(bounds[0] * Scale - CentreShift); @@ -205,7 +201,7 @@ EFI_STATUS XTheme::ParseSVGXIcon(INTN Id, const XString8& IconNameX, OUT XImage* // DBG("return empty with status=%s\n", strerror(Status)); return Status; } - + IconImage->scale = Scale; // DBG("begin rasterize %s\n", IconNameX.c_str()); float tx = 0.f, ty = 0.f; if ((Id != BUILTIN_ICON_BACKGROUND) && @@ -225,9 +221,9 @@ EFI_STATUS XTheme::ParseSVGXIcon(INTN Id, const XString8& IconNameX, OUT XImage* // nsvg__deleteParser(p2); // nsvgDelete(p2->image); //somehow we can't delete them producing memory leaks // well, we will use them later - *Image = NewImage; + *Image = NewImage; //copy array if (SVGIcon) { - *SVGIcon = (void*)IconImage; + *SVGIcon = (void*)IconImage; //copy pointer into parser } return EFI_SUCCESS; diff --git a/rEFIt_UEFI/libeg/XTheme.cpp b/rEFIt_UEFI/libeg/XTheme.cpp index 343108f78..a82e1147c 100644 --- a/rEFIt_UEFI/libeg/XTheme.cpp +++ b/rEFIt_UEFI/libeg/XTheme.cpp @@ -11,6 +11,7 @@ extern "C" { #include "../refit/lib.h" #include "XTheme.h" +#include "nanosvg.h" #ifndef DEBUG_ALL #define DEBUG_XTHEME 1 @@ -246,6 +247,35 @@ EFI_STATUS XIcon::LoadXImage(EFI_FILE *BaseDir, const XStringW& IconName) const XImage& XIcon::GetBest(bool night) const { + 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 doing new ximage we have to delete it after use + if (sImage->shapes == NULL) { + 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; + return *NewImage; + } const XImage& RetImage = (night && !ImageNight.isEmpty())? ImageNight : Image; return RetImage; } @@ -301,7 +331,7 @@ void XTheme::Init() MainEntriesSize = 128; TileXSpace = 8; TileYSpace = 24; -// IconFormat = ICON_FORMAT_DEF; + Proportional = FALSE; // ShowOptimus = FALSE; // DarkEmbedded = FALSE; //looks like redundant, we always check Night or Daylight @@ -310,7 +340,7 @@ void XTheme::Init() // CodepageSize = 0xC0; // INTN CodepageSize; //extended latin Scale = 1.0f; CentreShift = 0.0f; -// Daylight = true; + Daylight = true; LayoutHeight = 376; LayoutBannerOffset = 64; //default value if not set LayoutButtonOffset = 0; //default value if not set diff --git a/rEFIt_UEFI/libeg/nanosvg.cpp b/rEFIt_UEFI/libeg/nanosvg.cpp index 6bbdb6ddc..2aa26664a 100644 --- a/rEFIt_UEFI/libeg/nanosvg.cpp +++ b/rEFIt_UEFI/libeg/nanosvg.cpp @@ -4282,10 +4282,18 @@ int nsvg__shapesBound(/*NSVGimage* image,*/ NSVGshape *shapes, float* bounds) return count; } -void nsvg__imageBounds(NSVGparser* p, float* bounds) +void nsvg__imageBounds(NSVGimage* image, float* bounds) { - NSVGimage* image = p->image; +// NSVGimage* image = p->image; NSVGclipPath* clipPath; + if (!bounds || !image) { + return; + } + bounds[0] = FLT_MAX; + bounds[1] = FLT_MAX; + bounds[2] = -FLT_MAX; + bounds[3] = -FLT_MAX; + int count = 0; clipPath = image->clipPaths; while (clipPath != NULL) { @@ -4309,10 +4317,6 @@ NSVGparser* nsvgParse(char* input, /* const char* units,*/ float dpi, float opac NSVGclipPath* clipPath; NSVGsymbol* symbol; float bounds[4]; - bounds[0] = FLT_MAX; - bounds[1] = FLT_MAX; - bounds[2] = -FLT_MAX; - bounds[3] = -FLT_MAX; p = nsvg__createParser(); if (p == NULL) { @@ -4338,7 +4342,7 @@ NSVGparser* nsvgParse(char* input, /* const char* units,*/ float dpi, float opac symbol = symbol->next; } nsvg__assignGradients(p, p->image->shapes); - nsvg__imageBounds(p, bounds); + nsvg__imageBounds(p->image, bounds); #if 1 memcpy(p->image->realBounds, bounds, 4*sizeof(float)); diff --git a/rEFIt_UEFI/libeg/nanosvg.h b/rEFIt_UEFI/libeg/nanosvg.h index 60872f18c..5bdb97ab0 100644 --- a/rEFIt_UEFI/libeg/nanosvg.h +++ b/rEFIt_UEFI/libeg/nanosvg.h @@ -206,6 +206,7 @@ typedef struct NSVGimage float width; // Width of the image. float height; // Height of the image. float realBounds[4]; + float scale; NSVGshape* shapes; // Linked list of shapes in the image. NSVGgroup* groups; // Linked list of all groups in the image NSVGpath* paths; // Linked list of paths in the image. @@ -447,6 +448,7 @@ typedef struct NSVGparser // Parses SVG file from a null terminated string, returns SVG image as paths. // Important note: changes the string. NSVGparser* nsvgParse(char* input, /* const char* units,*/ float dpi, float opacity); +NSVGparser* nsvg__createParser(); // Deletes list of paths. void nsvgDelete(NSVGimage* image); @@ -457,7 +459,7 @@ void nsvg__xformSetScale(float* t, float sx, float sy); void nsvg__xformPremultiply(float* t, float* s); void nsvg__xformMultiply(float* t, float* s); void nsvg__deleteFont(NSVGfont* font); -void nsvg__imageBounds(NSVGparser* p, float* bounds); +void nsvg__imageBounds(NSVGimage* image, float* bounds); float addLetter(NSVGparser* p, CHAR16 letter, float x, float y, float scale, UINT32 color); VOID RenderSVGfont(NSVGfont *fontSVG, UINT32 color); @@ -484,7 +486,7 @@ void nsvgRasterize(NSVGrasterizer* r, // Deletes rasterizer context. void nsvgDeleteRasterizer(NSVGrasterizer*); -NSVGparser* nsvg__createParser(); + #define NSVG__SUBSAMPLES 5 #define NSVG__FIXSHIFT 14 diff --git a/rEFIt_UEFI/refit.inf b/rEFIt_UEFI/refit.inf index fc61d5ac8..64d8972c1 100644 --- a/rEFIt_UEFI/refit.inf +++ b/rEFIt_UEFI/refit.inf @@ -223,8 +223,8 @@ Platform/sound.cpp Platform/StartupSound.cpp Platform/StartupSound.h - Platform/sse3_patcher.h - Platform/sse3_5_patcher.h + # Platform/sse3_patcher.h + # Platform/sse3_5_patcher.h Platform/VersionString.cpp Platform/VersionString.h ../Version.h