From b6f2478cff4e6730e9d289f184ca22ab731d6a7d Mon Sep 17 00:00:00 2001 From: Sergey Isakov Date: Fri, 28 Feb 2020 17:08:40 +0300 Subject: [PATCH] create XImage from svg Signed-off-by: Sergey Isakov --- rEFIt_UEFI/libeg/XImage.cpp | 51 ++++++++++++++++++++++++++++++-- rEFIt_UEFI/libeg/XImage.h | 4 +++ rEFIt_UEFI/libeg/nanosvgrast.cpp | 2 +- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/rEFIt_UEFI/libeg/XImage.cpp b/rEFIt_UEFI/libeg/XImage.cpp index 209a2d19f..b985e976f 100644 --- a/rEFIt_UEFI/libeg/XImage.cpp +++ b/rEFIt_UEFI/libeg/XImage.cpp @@ -1,5 +1,17 @@ #include "XImage.h" +#ifndef DEBUG_ALL +#define DEBUG_XIMAGE 1 +#else +#define DEBUG_XIMAGE DEBUG_ALL +#endif + +#if DEBUG_XIMAGE == 0 +#define DBG(...) +#else +#define DBG(...) DebugLog(DEBUG_XIMAGE, __VA_ARGS__) +#endif + XImage::XImage() { @@ -13,13 +25,12 @@ XImage::XImage(UINTN W, UINTN H) Height = H; PixelData.CheckSize(GetWidth()*GetHeight()); } -#if 1 + UINT8 Smooth(const UINT8* p, int a01, int a10, int a21, int a12, int dx, int dy, float scale) { return (UINT8)((*(p + a01) * (scale - dx) * 3.f + *(p + a10) * (scale - dy) * 3.f + *(p + a21) * dx * 3.f + *(p + a12) * dy * 3.f + *(p) * 2.f *scale) / (scale * 8.f)); } -#endif XImage::XImage(const XImage& Image, float scale) { @@ -51,6 +62,7 @@ XImage::XImage(const XImage& Image, float scale) dst.Blue = Smooth(&Source[lx + ly * SrcWidth].Blue, a01, a10, a21, a12, dx, dy, scale); dst.Green = Smooth(&Source[lx + ly * SrcWidth].Green, a01, a10, a21, a12, dx, dy, scale); dst.Red = Smooth(&Source[lx + ly * SrcWidth].Red, a01, a10, a21, a12, dx, dy, scale); + dst.Reserved = Source[lx + ly * SrcWidth].Reserved; } } @@ -245,6 +257,41 @@ unsigned XImage::ToPNG(uint8_t** Data, UINTN& OutSize) return Error; } +/* + * fill XImage object by rater data described in SVG + * 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 + */ +unsigned XImage::FromSVG(const CHAR8 *SVGData, UINTN FileDataLength, float scale) +{ + NSVGimage *SVGimage; + NSVGparser* p; + EFI_STATUS Status; + + NSVGrasterizer* rast = nsvgCreateRasterizer(); + if (!rast) return 1; + char *input = AsciiStrCpy(SVGData); + if (!input) return 2; + + p = nsvgParse(input, 72, 1.f); //the parse will change input contents + SVGimage = p->image; + if (SVGimage) { + float ScaleX = Width / SVGimage->width; + float ScaleY = Height / SVGimage->height; + float Scale = (ScaleX > ScaleY) ? ScaleY : ScaleX; + Scale *= scale; + + DBG("Test image width=%d heigth=%d\n", (int)(SVGimage->width), (int)(SVGimage->height)); + nsvgRasterize(rast, SVGimage, 0.f, 0.f, Scale, Scale, (UINT8*)&PixelData[0], (int)Width, (int)Height, (int)Width * sizeof(PixelData[0])); + FreePool(SVGimage); + } + nsvg__deleteParser(p); + nsvgDeleteRasterizer(rast); + FreePool(input); + return 0; +} + // Screen operations /* * The function to get image from screen. Used in screenshot (full screen), Pointer (small area) and Draw (small area) diff --git a/rEFIt_UEFI/libeg/XImage.h b/rEFIt_UEFI/libeg/XImage.h index b31d633c7..9163c2442 100644 --- a/rEFIt_UEFI/libeg/XImage.h +++ b/rEFIt_UEFI/libeg/XImage.h @@ -8,7 +8,10 @@ This class will replace EG_IMAGE structure and methods #include "../cpp_foundation/XToolsCommon.h" #include "../cpp_foundation/XArray.h" #include "lodepng.h" + +#include "nanosvg.h" #include "FloatLib.h" + #include #if 0 //ndef EFI_GRAPHICS_OUTPUT_BLT_PIXEL @@ -64,6 +67,7 @@ public: void FlipRB(bool WantAlpha); unsigned FromPNG(const uint8_t * Data, UINTN Lenght); unsigned ToPNG(uint8_t** Data, UINTN& OutSize); + unsigned FromSVG(const CHAR8 *SVGData, UINTN SVGDataLength, float scale); void GetArea(const EgRect& Rect); void GetArea(UINTN x, UINTN y, UINTN W, UINTN H); void Draw(int x, int y, float scale); diff --git a/rEFIt_UEFI/libeg/nanosvgrast.cpp b/rEFIt_UEFI/libeg/nanosvgrast.cpp index 3b2c4c875..4a21b4d96 100644 --- a/rEFIt_UEFI/libeg/nanosvgrast.cpp +++ b/rEFIt_UEFI/libeg/nanosvgrast.cpp @@ -117,7 +117,7 @@ void qsort(void* Array, int Num, INTN Size, nsvg_qsort((NSVGedge*)Array, 0, Num - 1); } - +//caller is responsible for free memory NSVGrasterizer* nsvgCreateRasterizer() { NSVGrasterizer* r = (NSVGrasterizer*)AllocateZeroPool(sizeof(NSVGrasterizer));