create XImage from svg

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-02-28 17:08:40 +03:00
parent a2534ee4f8
commit b6f2478cff
3 changed files with 54 additions and 3 deletions

View File

@ -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)

View File

@ -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 <Platform.h>
#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);

View File

@ -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));