Code to load SVG icons into the BitmapCache class.

This commit is contained in:
bubnikv 2019-04-04 09:20:11 +02:00
parent 43ce5accc2
commit a36bdefda5
6 changed files with 113 additions and 36 deletions

View file

@ -1,5 +1,7 @@
#include "BitmapCache.hpp"
#include "libslic3r/Utils.hpp"
#if ! defined(WIN32) && ! defined(__APPLE__)
#define BROKEN_ALPHA
#endif
@ -9,6 +11,11 @@
#include <wx/rawbmp.h>
#endif /* BROKEN_ALPHA */
#define NANOSVG_IMPLEMENTATION
#include "nanosvg/nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvg/nanosvgrast.h"
namespace Slic3r { namespace GUI {
void BitmapCache::clear()
@ -155,6 +162,72 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg
#endif
}
wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned int width, unsigned int height, const unsigned char *raw_data)
{
wxImage image(width, height);
image.InitAlpha();
unsigned char *rgb = image.GetData();
unsigned char *alpha = image.GetAlpha();
unsigned int pixels = width * height;
for (unsigned int i = 0; i < pixels; ++ i) {
*rgb ++ = *raw_data ++;
*rgb ++ = *raw_data ++;
*rgb ++ = *raw_data ++;
*alpha ++ = *raw_data ++;
}
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
}
wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned int height)
{
std::string bitmap_key = bitmap_name + "-h" + std::to_string(height);
auto it = m_map.find(bitmap_key);
if (it != m_map.end())
return it->second;
wxImage image;
if (! image.LoadFile(Slic3r::GUI::from_u8(Slic3r::var(bitmap_name + ".png")), wxBITMAP_TYPE_PNG) ||
image.GetWidth() == 0 || image.GetHeight() == 0)
return nullptr;
if (image.GetHeight() != height)
image.Rescale(int(0.5f + float(image.GetWidth()) * height / image.GetHeight()), height, wxIMAGE_QUALITY_BILINEAR);
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
}
wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned int target_height)
{
std::string bitmap_key = bitmap_name + "-h" + std::to_string(target_height);
auto it = m_map.find(bitmap_key);
if (it != m_map.end())
return it->second;
NSVGimage *image = ::nsvgParseFromFile(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f);
if (image == nullptr)
return nullptr;
float scale = (float)target_height / image->height;
int width = (int)(scale * image->width + 0.5f);
int height = (int)(scale * image->height + 0.5f);
int n_pixels = width * height;
if (n_pixels <= 0) {
::nsvgDelete(image);
return nullptr;
}
NSVGrasterizer *rast = ::nsvgCreateRasterizer();
if (rast == nullptr) {
::nsvgDelete(image);
return nullptr;
}
std::vector<unsigned char> data(n_pixels * 4, 0);
::nsvgRasterize(rast, image, 0, 0, scale, data.data(), width, height, width * 4);
::nsvgDeleteRasterizer(rast);
::nsvgDelete(image);
return this->insert_raw_rgba(bitmap_key, width, height, data.data());
}
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
{
wxImage image(width, height);