#include "SVGResource.h" #include "../nanosvg/nanosvg.h" #include "../nanosvg/nanosvgrast.h" #include "../Log.h" #include "../Util.h" #define DPI 96 SVGResource::SVGResource(const std::string& path, bool tile) : TextureResource(path, tile), mSVGImage(NULL) { mLastWidth = 0; mLastHeight = 0; } SVGResource::~SVGResource() { deinitSVG(); } void SVGResource::unload(std::shared_ptr<ResourceManager>& rm) { deinitSVG(); TextureResource::unload(rm); } void SVGResource::initFromMemory(const char* file, size_t length) { deinit(); deinitSVG(); // nsvgParse excepts a modifiable, null-terminated string char* copy = (char*)malloc(length + 1); memcpy(copy, file, length); copy[length] = '\0'; mSVGImage = nsvgParse(copy, "px", DPI); free(copy); if(!mSVGImage) { LOG(LogError) << "Error parsing SVG image."; return; } if(mLastWidth && mLastHeight) rasterizeAt(mLastWidth, mLastHeight); else rasterizeAt((int)round(mSVGImage->width), (int)round(mSVGImage->height)); } void SVGResource::rasterizeAt(size_t width, size_t height) { if(!mSVGImage) return; if(width != (int)round(mSVGImage->width) && height != (int)round(mSVGImage->height)) { mLastWidth = width; mLastHeight = height; } unsigned char* imagePx = (unsigned char*)malloc(width * height * 4); NSVGrasterizer* rast = nsvgCreateRasterizer(); nsvgRasterize(rast, mSVGImage, 0, 0, height / mSVGImage->height, imagePx, width, height, width * 4); nsvgDeleteRasterizer(rast); // flip the pixels unsigned int temp; unsigned int* arr = (unsigned int*)imagePx; for(size_t y = 0; y < height / 2; y++) { for(size_t x = 0; x < width; x++) { temp = arr[x + (y * width)]; arr[x + (y * width)] = arr[x + (height * width) - ((y + 1) * width)]; arr[x + (height * width) - ((y + 1) * width)] = temp; } } initFromPixels(imagePx, width, height); free(imagePx); } Eigen::Vector2i SVGResource::getImageSize() const { if(mSVGImage) return Eigen::Vector2i((int)mSVGImage->width, (int)mSVGImage->height); return Eigen::Vector2i::Zero(); } void SVGResource::deinitSVG() { if(mSVGImage) nsvgDelete(mSVGImage); mSVGImage = NULL; }