mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-19 08:37:38 +08:00
Added @bubnikv's changes to BitmapCache
This commit is contained in:
parent
120c1978ae
commit
64976c249d
@ -1,5 +1,14 @@
|
|||||||
#include "BitmapCache.hpp"
|
#include "BitmapCache.hpp"
|
||||||
|
|
||||||
|
#if ! defined(WIN32) && ! defined(__APPLE__)
|
||||||
|
#define BROKEN_ALPHA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BROKEN_ALPHA
|
||||||
|
#include <wx/mstream.h>
|
||||||
|
#include <wx/rawbmp.h>
|
||||||
|
#endif /* BROKEN_ALPHA */
|
||||||
|
|
||||||
namespace Slic3r { namespace GUI {
|
namespace Slic3r { namespace GUI {
|
||||||
|
|
||||||
void BitmapCache::clear()
|
void BitmapCache::clear()
|
||||||
@ -8,19 +17,31 @@ void BitmapCache::clear()
|
|||||||
delete bitmap.second;
|
delete bitmap.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image)
|
||||||
|
{
|
||||||
|
#ifdef BROKEN_ALPHA
|
||||||
|
wxMemoryOutputStream stream;
|
||||||
|
image.SaveFile(stream, wxBITMAP_TYPE_PNG);
|
||||||
|
wxStreamBuffer *buf = stream.GetOutputStreamBuffer();
|
||||||
|
return wxBitmap::NewFromPNGData(buf->GetBufferStart(), buf->GetBufferSize());
|
||||||
|
#else
|
||||||
|
return wxBitmap(std::move(image));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height)
|
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height)
|
||||||
{
|
{
|
||||||
wxBitmap *bitmap = nullptr;
|
wxBitmap *bitmap = nullptr;
|
||||||
auto it = m_map.find(bitmap_key);
|
auto it = m_map.find(bitmap_key);
|
||||||
if (it == m_map.end()) {
|
if (it == m_map.end()) {
|
||||||
bitmap = new wxBitmap(width, height);
|
bitmap = new wxBitmap(width, height);
|
||||||
m_map[bitmap_key] = bitmap;
|
m_map[bitmap_key] = bitmap;
|
||||||
} else {
|
} else {
|
||||||
bitmap = it->second;
|
bitmap = it->second;
|
||||||
if (bitmap->GetWidth() != width || bitmap->GetHeight() != height)
|
if (bitmap->GetWidth() != width || bitmap->GetHeight() != height)
|
||||||
bitmap->Create(width, height);
|
bitmap->Create(width, height);
|
||||||
}
|
}
|
||||||
#if defined(__APPLE__) || defined(_MSC_VER)
|
#ifndef BROKEN_ALPHA
|
||||||
bitmap->UseAlpha();
|
bitmap->UseAlpha();
|
||||||
#endif
|
#endif
|
||||||
return bitmap;
|
return bitmap;
|
||||||
@ -28,77 +49,108 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_
|
|||||||
|
|
||||||
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp)
|
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp)
|
||||||
{
|
{
|
||||||
wxBitmap *bitmap = this->insert(bitmap_key, bmp.GetWidth(), bmp.GetHeight());
|
wxBitmap *bitmap = nullptr;
|
||||||
|
auto it = m_map.find(bitmap_key);
|
||||||
wxMemoryDC memDC;
|
if (it == m_map.end()) {
|
||||||
memDC.SelectObject(*bitmap);
|
bitmap = new wxBitmap(bmp);
|
||||||
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
|
m_map[bitmap_key] = bitmap;
|
||||||
memDC.Clear();
|
} else {
|
||||||
memDC.DrawBitmap(bmp, 0, 0, true);
|
bitmap = it->second;
|
||||||
memDC.SelectObject(wxNullBitmap);
|
*bitmap = bmp;
|
||||||
|
}
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2)
|
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2)
|
||||||
{
|
{
|
||||||
wxBitmap *bitmap = this->insert(bitmap_key, bmp.GetWidth() + bmp2.GetWidth(), std::max(bmp.GetHeight(), bmp2.GetHeight()));
|
// Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
|
||||||
|
const wxBitmap bmps[2] = { bmp, bmp2 };
|
||||||
wxMemoryDC memDC;
|
return this->insert(bitmap_key, bmps, bmps + 2);
|
||||||
memDC.SelectObject(*bitmap);
|
|
||||||
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
|
|
||||||
memDC.Clear();
|
|
||||||
if (bmp.GetWidth() > 0)
|
|
||||||
memDC.DrawBitmap(bmp, 0, 0, true);
|
|
||||||
if (bmp2.GetWidth() > 0)
|
|
||||||
memDC.DrawBitmap(bmp2, bmp.GetWidth(), 0, true);
|
|
||||||
memDC.SelectObject(wxNullBitmap);
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3)
|
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3)
|
||||||
{
|
{
|
||||||
wxBitmap *bitmap = this->insert(bitmap_key, bmp.GetWidth() + bmp2.GetWidth() + bmp3.GetWidth(), std::max(std::max(bmp.GetHeight(), bmp2.GetHeight()), bmp3.GetHeight()));
|
// Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
|
||||||
|
const wxBitmap bmps[3] = { bmp, bmp2, bmp3 };
|
||||||
|
return this->insert(bitmap_key, bmps, bmps + 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *begin, const wxBitmap *end)
|
||||||
|
{
|
||||||
|
size_t width = 0;
|
||||||
|
size_t height = 0;
|
||||||
|
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
|
||||||
|
width += bmp->GetWidth();
|
||||||
|
height = std::max<size_t>(height, bmp->GetHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BROKEN_ALPHA
|
||||||
|
|
||||||
|
wxImage image(width, height);
|
||||||
|
image.InitAlpha();
|
||||||
|
// Fill in with a white color.
|
||||||
|
memset(image.GetData(), 0x0ff, width * height * 3);
|
||||||
|
// Fill in with full transparency.
|
||||||
|
memset(image.GetAlpha(), 0, width * height);
|
||||||
|
size_t x = 0;
|
||||||
|
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
|
||||||
|
if (bmp->GetWidth() > 0) {
|
||||||
|
if (bmp->GetDepth() == 32) {
|
||||||
|
wxAlphaPixelData data(*const_cast<wxBitmap*>(bmp));
|
||||||
|
data.UseAlpha();
|
||||||
|
if (data) {
|
||||||
|
for (int r = 0; r < bmp->GetHeight(); ++ r) {
|
||||||
|
wxAlphaPixelData::Iterator src(data);
|
||||||
|
src.Offset(data, 0, r);
|
||||||
|
unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
|
||||||
|
unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
|
||||||
|
for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
|
||||||
|
*dst_pixels ++ = src.Red();
|
||||||
|
*dst_pixels ++ = src.Green();
|
||||||
|
*dst_pixels ++ = src.Blue();
|
||||||
|
*dst_alpha ++ = src.Alpha();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (bmp->GetDepth() == 24) {
|
||||||
|
wxNativePixelData data(*const_cast<wxBitmap*>(bmp));
|
||||||
|
if (data) {
|
||||||
|
for (int r = 0; r < bmp->GetHeight(); ++ r) {
|
||||||
|
wxNativePixelData::Iterator src(data);
|
||||||
|
src.Offset(data, 0, r);
|
||||||
|
unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
|
||||||
|
unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
|
||||||
|
for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
|
||||||
|
*dst_pixels ++ = src.Red();
|
||||||
|
*dst_pixels ++ = src.Green();
|
||||||
|
*dst_pixels ++ = src.Blue();
|
||||||
|
*dst_alpha ++ = wxALPHA_OPAQUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x += bmp->GetWidth();
|
||||||
|
}
|
||||||
|
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
wxBitmap *bitmap = this->insert(bitmap_key, width, height);
|
||||||
wxMemoryDC memDC;
|
wxMemoryDC memDC;
|
||||||
memDC.SelectObject(*bitmap);
|
memDC.SelectObject(*bitmap);
|
||||||
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
|
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
|
||||||
memDC.Clear();
|
memDC.Clear();
|
||||||
if (bmp.GetWidth() > 0)
|
|
||||||
memDC.DrawBitmap(bmp, 0, 0, true);
|
|
||||||
if (bmp2.GetWidth() > 0)
|
|
||||||
memDC.DrawBitmap(bmp2, bmp.GetWidth(), 0, true);
|
|
||||||
if (bmp3.GetWidth() > 0)
|
|
||||||
memDC.DrawBitmap(bmp3, bmp.GetWidth() + bmp2.GetWidth(), 0, true);
|
|
||||||
memDC.SelectObject(wxNullBitmap);
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, std::vector<wxBitmap> &bmps)
|
|
||||||
{
|
|
||||||
size_t width = 0;
|
|
||||||
size_t height = 0;
|
|
||||||
for (wxBitmap &bmp : bmps) {
|
|
||||||
width += bmp.GetWidth();
|
|
||||||
height = std::max<size_t>(height, bmp.GetHeight());
|
|
||||||
}
|
|
||||||
wxBitmap *bitmap = this->insert(bitmap_key, width, height);
|
|
||||||
|
|
||||||
wxMemoryDC memDC;
|
|
||||||
memDC.SelectObject(*bitmap);
|
|
||||||
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
|
|
||||||
memDC.Clear();
|
|
||||||
size_t x = 0;
|
size_t x = 0;
|
||||||
for (wxBitmap &bmp : bmps) {
|
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
|
||||||
if (bmp.GetWidth() > 0)
|
if (bmp->GetWidth() > 0)
|
||||||
memDC.DrawBitmap(bmp, x, 0, true);
|
memDC.DrawBitmap(*bmp, x, 0, true);
|
||||||
x += bmp.GetWidth();
|
x += bmp->GetWidth();
|
||||||
}
|
}
|
||||||
memDC.SelectObject(wxNullBitmap);
|
memDC.SelectObject(wxNullBitmap);
|
||||||
|
return bitmap;
|
||||||
|
|
||||||
return bitmap;
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
|
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
|
||||||
@ -113,7 +165,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi
|
|||||||
*imgdata ++ = b;
|
*imgdata ++ = b;
|
||||||
*imgalpha ++ = transparency;
|
*imgalpha ++ = transparency;
|
||||||
}
|
}
|
||||||
return wxBitmap(std::move(image));
|
return wxImage_to_wxBitmap_with_alpha(std::move(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
@ -27,7 +27,8 @@ public:
|
|||||||
wxBitmap* insert(const std::string &name, const wxBitmap &bmp);
|
wxBitmap* insert(const std::string &name, const wxBitmap &bmp);
|
||||||
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2);
|
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2);
|
||||||
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3);
|
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3);
|
||||||
wxBitmap* insert(const std::string &name, std::vector<wxBitmap> &bmps);
|
wxBitmap* insert(const std::string &name, const std::vector<wxBitmap> &bmps) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); }
|
||||||
|
wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end);
|
||||||
|
|
||||||
static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency);
|
static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency);
|
||||||
static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); }
|
static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user