mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 04:02:52 -06:00 
			
		
		
		
	Added @bubnikv's changes to BitmapCache
This commit is contained in:
		
							parent
							
								
									120c1978ae
								
							
						
					
					
						commit
						64976c249d
					
				
					 2 changed files with 121 additions and 68 deletions
				
			
		|  | @ -1,5 +1,14 @@ | |||
| #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 { | ||||
| 
 | ||||
| void BitmapCache::clear() | ||||
|  | @ -8,19 +17,31 @@ void BitmapCache::clear() | |||
|         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 *bitmap = nullptr; | ||||
| 	auto 	  it     = m_map.find(bitmap_key); | ||||
| 	if (it == m_map.end()) { | ||||
| 		bitmap = new wxBitmap(width, height); | ||||
|     	m_map[bitmap_key] = bitmap; | ||||
| 	} else { | ||||
| 		bitmap = it->second; | ||||
| 		if (bitmap->GetWidth() != width || bitmap->GetHeight() != height) | ||||
| 			bitmap->Create(width, height); | ||||
| 	} | ||||
| #if defined(__APPLE__) || defined(_MSC_VER) | ||||
|     wxBitmap *bitmap = nullptr; | ||||
|     auto      it     = m_map.find(bitmap_key); | ||||
|     if (it == m_map.end()) { | ||||
|         bitmap = new wxBitmap(width, height); | ||||
|         m_map[bitmap_key] = bitmap; | ||||
|     } else { | ||||
|         bitmap = it->second; | ||||
|         if (bitmap->GetWidth() != width || bitmap->GetHeight() != height) | ||||
|             bitmap->Create(width, height); | ||||
|     } | ||||
| #ifndef BROKEN_ALPHA | ||||
|     bitmap->UseAlpha(); | ||||
| #endif | ||||
|     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 *bitmap = this->insert(bitmap_key, bmp.GetWidth(), bmp.GetHeight()); | ||||
| 
 | ||||
|     wxMemoryDC memDC; | ||||
|     memDC.SelectObject(*bitmap); | ||||
|     memDC.SetBackground(*wxTRANSPARENT_BRUSH); | ||||
|     memDC.Clear(); | ||||
|     memDC.DrawBitmap(bmp, 0, 0, true); | ||||
|     memDC.SelectObject(wxNullBitmap); | ||||
| 
 | ||||
| 	return bitmap; | ||||
|     wxBitmap *bitmap = nullptr; | ||||
|     auto      it     = m_map.find(bitmap_key); | ||||
|     if (it == m_map.end()) { | ||||
|         bitmap = new wxBitmap(bmp); | ||||
|         m_map[bitmap_key] = bitmap; | ||||
|     } else { | ||||
|         bitmap = it->second; | ||||
|         *bitmap = bmp; | ||||
|     } | ||||
|     return bitmap; | ||||
| } | ||||
| 
 | ||||
| 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())); | ||||
| 
 | ||||
|     wxMemoryDC memDC; | ||||
|     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; | ||||
|     // Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
 | ||||
|     const wxBitmap bmps[2] = { bmp, bmp2 }; | ||||
|     return this->insert(bitmap_key, bmps, bmps + 2); | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
|     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); | ||||
|     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; | ||||
| 	for (wxBitmap &bmp : bmps) { | ||||
| 	    if (bmp.GetWidth() > 0) | ||||
| 		    memDC.DrawBitmap(bmp, x, 0, true); | ||||
| 		x += bmp.GetWidth(); | ||||
| 	} | ||||
|     for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) { | ||||
|         if (bmp->GetWidth() > 0) | ||||
|             memDC.DrawBitmap(*bmp, x, 0, true); | ||||
|         x += bmp->GetWidth(); | ||||
|     } | ||||
|     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) | ||||
|  | @ -113,7 +165,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi | |||
|         *imgdata ++ = b; | ||||
|         *imgalpha ++ = transparency; | ||||
|     } | ||||
|     return wxBitmap(std::move(image)); | ||||
|     return wxImage_to_wxBitmap_with_alpha(std::move(image)); | ||||
| } | ||||
| 
 | ||||
| } // 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, const wxBitmap &bmp2); | ||||
| 	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, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 YuSanka
						YuSanka