OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::BitmapCache Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/BitmapCache.hpp>

Collaboration diagram for Slic3r::GUI::BitmapCache:

Public Member Functions

 BitmapCache ()
 ~BitmapCache ()
void clear ()
double scale ()
wxBitmap * find (const std::string &name)
const wxBitmap * find (const std::string &name) const
wxBitmap * insert (const std::string &name, size_t width, size_t height)
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, const std::vector< wxBitmap > &bmps)
wxBitmap * insert (const std::string &name, const wxBitmap *begin, const wxBitmap *end)
wxBitmap * insert_raw_rgba (const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, const bool grayscale=false)
wxBitmap * load_png (const std::string &bitmap_key, unsigned width=0, unsigned height=0, const bool grayscale=false, const float scale_in_center=0.f)
wxBitmap * load_svg (const std::string &bitmap_key, unsigned width=0, unsigned height=0, const bool grayscale=false, const bool dark_mode=false, const std::string &new_color="", const float scale_in_center=0.f)
wxBitmap * load_svg2 (const std::string &bitmap_key, unsigned width=0, unsigned height=0, const bool grayscale=false, const bool dark_mode=false, const std::vector< std::string > &array_new_color=std::vector< std::string >(), const float scale_in_center=0.0f)
wxBitmap mksolid (size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling=false, size_t border_width=0, bool dark_mode=false)
wxBitmap mksolid (size_t width, size_t height, const unsigned char rgb[3], bool suppress_scaling=false, size_t border_width=0, bool dark_mode=false)
wxBitmap mksolid (size_t width, size_t height, const ColorRGB &rgb, bool suppress_scaling=false, size_t border_width=0, bool dark_mode=false)
wxBitmap mkclear (size_t width, size_t height)

Static Public Member Functions

static NSVGimage * nsvgParseFromFileWithReplace (const char *filename, const char *units, float dpi, const std::map< std::string, std::string > &replaces)
static bool parse_color (const std::string &scolor, unsigned char *rgb_out)
static bool parse_color4 (const std::string &scolor, unsigned char *rgba_out)
static bool load_from_svg_file_change_color (const std::string &filename, unsigned width, unsigned height, ImTextureID &texture_id, const char *hexColor)

Private Attributes

std::map< std::string, wxBitmap * > m_map
double m_gs = 0.2
double m_scale = 1.0

Detailed Description

Constructor & Destructor Documentation

◆ BitmapCache()

Slic3r::GUI::BitmapCache::BitmapCache ( )
42{
43#ifdef __APPLE__
44 // Note: win->GetContentScaleFactor() is not used anymore here because it tends to
45 // return bogus results quite often (such as 1.0 on Retina or even 0.0).
46 // We're using the max scaling factor across all screens because it's very likely to be good enough.
48#endif
49}
double m_scale
Definition BitmapCache.hpp:67
double mac_max_scaling_factor()
Definition MacDarkMode.mm:35

References m_scale, and Slic3r::GUI::mac_max_scaling_factor().

Referenced by find().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~BitmapCache()

Slic3r::GUI::BitmapCache::~BitmapCache ( )
inline
25{ clear(); }
void clear()
Definition BitmapCache.cpp:51

References clear().

Here is the call graph for this function:

Member Function Documentation

◆ clear()

void Slic3r::GUI::BitmapCache::clear ( )
52{
53 for (std::pair<const std::string, wxBitmap*> &bitmap : m_map)
54 delete bitmap.second;
55
56 m_map.clear();
57}
std::map< std::string, wxBitmap * > m_map
Definition BitmapCache.hpp:65

References m_map.

Referenced by ~BitmapCache().

Here is the caller graph for this function:

◆ find() [1/2]

wxBitmap * Slic3r::GUI::BitmapCache::find ( const std::string & name)
inline
29{ auto it = m_map.find(name); return (it == m_map.end()) ? nullptr : it->second; }

References m_map.

Referenced by Slic3r::GUI::PresetComboBox::get_bmp(), Slic3r::GUI::PresetComboBox::get_bmp(), Slic3r::GUI::PresetComboBox::get_bmp(), get_default_extruder_color_icon(), get_extruder_color_icon(), and get_extruder_color_icon().

Here is the caller graph for this function:

◆ find() [2/2]

const wxBitmap * Slic3r::GUI::BitmapCache::find ( const std::string & name) const
inline
30{ return const_cast<BitmapCache*>(this)->find(name); }
BitmapCache()
Definition BitmapCache.cpp:41
wxBitmap * find(const std::string &name)
Definition BitmapCache.hpp:29

References BitmapCache(), and find().

Referenced by find().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert() [1/6]

wxBitmap * Slic3r::GUI::BitmapCache::insert ( const std::string & name,
const std::vector< wxBitmap > & bmps )
inline
36{ return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); }
wxBitmap * insert(const std::string &name, size_t width, size_t height)
Definition BitmapCache.cpp:81

References insert().

Referenced by insert().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert() [2/6]

wxBitmap * Slic3r::GUI::BitmapCache::insert ( const std::string & name,
const wxBitmap & bmp )
113{
114 wxBitmap *bitmap = nullptr;
115 auto it = m_map.find(bitmap_key);
116 if (it == m_map.end()) {
117 bitmap = new wxBitmap(bmp);
118 m_map[bitmap_key] = bitmap;
119 } else {
120 bitmap = it->second;
121 *bitmap = bmp;
122 }
123 return bitmap;
124}

References m_map.

◆ insert() [3/6]

wxBitmap * Slic3r::GUI::BitmapCache::insert ( const std::string & name,
const wxBitmap & bmp,
const wxBitmap & bmp2 )
127{
128 // Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
129 const wxBitmap bmps[2] = { bmp, bmp2 };
130 return this->insert(bitmap_key, bmps, bmps + 2);
131}

References insert().

Here is the call graph for this function:

◆ insert() [4/6]

wxBitmap * Slic3r::GUI::BitmapCache::insert ( const std::string & name,
const wxBitmap & bmp,
const wxBitmap & bmp2,
const wxBitmap & bmp3 )
134{
135 // Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
136 const wxBitmap bmps[3] = { bmp, bmp2, bmp3 };
137 return this->insert(bitmap_key, bmps, bmps + 3);
138}

References insert().

Here is the call graph for this function:

◆ insert() [5/6]

wxBitmap * Slic3r::GUI::BitmapCache::insert ( const std::string & name,
const wxBitmap * begin,
const wxBitmap * end )
141{
142 size_t width = 0;
143 size_t height = 0;
144 for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
145#ifdef __APPLE__
146 width += bmp->GetScaledWidth();
147 height = std::max<size_t>(height, bmp->GetScaledHeight());
148#else
149 width += bmp->GetWidth();
150 height = std::max<size_t>(height, bmp->GetHeight());
151#endif
152 }
153
154#ifdef __WXGTK2__
155 // Broken alpha workaround
156 wxImage image(width, height);
157 image.InitAlpha();
158 // Fill in with a white color.
159 memset(image.GetData(), 0x0ff, width * height * 3);
160 // Fill in with full transparency.
161 memset(image.GetAlpha(), 0, width * height);
162 size_t x = 0;
163 for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
164 if (bmp->GetWidth() > 0) {
165 if (bmp->GetDepth() == 32) {
166 wxAlphaPixelData data(*const_cast<wxBitmap*>(bmp));
167 //FIXME The following method is missing from wxWidgets 3.1.1.
168 // It looks like the wxWidgets 3.0.3 called the wrapped bitmap's UseAlpha().
169 //data.UseAlpha();
170 if (data) {
171 for (int r = 0; r < bmp->GetHeight(); ++ r) {
172 wxAlphaPixelData::Iterator src(data);
173 src.Offset(data, 0, r);
174 unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
175 unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
176 for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
177 *dst_pixels ++ = src.Red();
178 *dst_pixels ++ = src.Green();
179 *dst_pixels ++ = src.Blue();
180 *dst_alpha ++ = src.Alpha();
181 }
182 }
183 }
184 } else if (bmp->GetDepth() == 24) {
185 wxNativePixelData data(*const_cast<wxBitmap*>(bmp));
186 if (data) {
187 for (int r = 0; r < bmp->GetHeight(); ++ r) {
188 wxNativePixelData::Iterator src(data);
189 src.Offset(data, 0, r);
190 unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
191 unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
192 for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
193 *dst_pixels ++ = src.Red();
194 *dst_pixels ++ = src.Green();
195 *dst_pixels ++ = src.Blue();
196 *dst_alpha ++ = wxALPHA_OPAQUE;
197 }
198 }
199 }
200 }
201 }
202 x += bmp->GetWidth();
203 }
204 return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
205
206#else
207
208 wxBitmap *bitmap = this->insert(bitmap_key, width, height);
209 wxMemoryDC memDC;
210 memDC.SelectObject(*bitmap);
211 memDC.SetBackground(*wxTRANSPARENT_BRUSH);
212 memDC.Clear();
213 size_t x = 0;
214 for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
215 if (bmp->GetWidth() > 0)
216 memDC.DrawBitmap(*bmp, x, 0, true);
217#ifdef __APPLE__
218 // we should "move" with step equal to non-scaled width
219 x += bmp->GetScaledWidth();
220#else
221 x += bmp->GetWidth();
222#endif
223 }
224 memDC.SelectObject(wxNullBitmap);
225 return bitmap;
226
227#endif
228}
T * end(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:841
static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image, float scale=1.0f)
Definition BitmapCache.cpp:59
coord_t width(const BoundingBox &box)
Definition Arrange.cpp:1184
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:1185

References insert(), and Slic3r::GUI::wxImage_to_wxBitmap_with_alpha().

Here is the call graph for this function:

◆ insert() [6/6]

wxBitmap * Slic3r::GUI::BitmapCache::insert ( const std::string & name,
size_t width,
size_t height )
82{
83 wxBitmap *bitmap = nullptr;
84 auto it = m_map.find(bitmap_key);
85 if (it == m_map.end()) {
86 bitmap = new wxBitmap(width, height
87#ifdef __WXGTK3__
88 , 32
89#endif
90 );
91#ifdef __APPLE__
92 // Contrary to intuition, the `scale` argument isn't "please scale this to such and such"
93 // but rather "the wxImage is sized for backing scale such and such".
94 // So, We need to let the Mac OS wxBitmap implementation
95 // know that the image may already be scaled appropriately for Retina,
96 // and thereby that it's not supposed to upscale it.
97 bitmap->CreateScaled(width, height, -1, m_scale);
98#endif
99 m_map[bitmap_key] = bitmap;
100 } else {
101 bitmap = it->second;
102 if (size_t(bitmap->GetWidth()) != width || size_t(bitmap->GetHeight()) != height)
103 bitmap->Create(width, height);
104 }
105#if defined(WIN32) || defined(__APPLE__)
106 // Not needed or harmful for GTK2 and GTK3.
107 bitmap->UseAlpha();
108#endif
109 return bitmap;
110}

References m_map, and m_scale.

Referenced by Slic3r::GUI::PresetComboBox::get_bmp(), Slic3r::GUI::PresetComboBox::get_bmp(), Slic3r::GUI::PresetComboBox::get_bmp(), get_default_extruder_color_icon(), get_extruder_color_icon(), get_extruder_color_icon(), insert(), insert(), insert(), insert_raw_rgba(), and load_png().

Here is the caller graph for this function:

◆ insert_raw_rgba()

wxBitmap * Slic3r::GUI::BitmapCache::insert_raw_rgba ( const std::string & bitmap_key,
unsigned width,
unsigned height,
const unsigned char * raw_data,
const bool grayscale = false )
231{
232 wxImage image(width, height);
233 image.InitAlpha();
234 unsigned char *rgb = image.GetData();
235 unsigned char *alpha = image.GetAlpha();
236 unsigned int pixels = width * height;
237 for (unsigned int i = 0; i < pixels; ++ i) {
238 *rgb ++ = *raw_data ++;
239 *rgb ++ = *raw_data ++;
240 *rgb ++ = *raw_data ++;
241 *alpha ++ = *raw_data ++;
242 }
243
244 if (grayscale)
245 image = image.ConvertToGreyscale(m_gs, m_gs, m_gs);
246
247 return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image), m_scale));
248}
double m_gs
Definition BitmapCache.hpp:66

References insert(), m_gs, m_scale, and Slic3r::GUI::wxImage_to_wxBitmap_with_alpha().

Referenced by load_svg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_from_svg_file_change_color()

bool Slic3r::GUI::BitmapCache::load_from_svg_file_change_color ( const std::string & filename,
unsigned width,
unsigned height,
ImTextureID & texture_id,
const char * hexColor )
static
576{
577 NSVGimage* image = nsvgParseFromFile(filename.c_str(), "px", 96.0f);
578 if (image == nullptr) {
579 return false;
580 }
581 char temp_color[8];
582 strncpy(temp_color, hexColor, 7);
583 temp_color[7] = '\0';
584 unsigned int change_color = nsvg__parseColorHex(temp_color);
585 change_color |= (unsigned int) (1.0f * 255) << 24; // opacity
586 unsigned int green_color = 0xFF889600; // #009688
587 for (NSVGshape* shape = image->shapes; shape != nullptr; shape = shape->next) {
588 // find green color
589 if (shape->fill.color == green_color) {
590 shape->fill.color = change_color;
591 }
592 }
593
594 float scale = (float)width / image->width;
595
596 int n_pixels = width * height;
597
598 if (n_pixels <= 0) {
599 nsvgDelete(image);
600 return false;
601 }
602
603 NSVGrasterizer* rast = nsvgCreateRasterizer();
604 if (rast == nullptr) {
605 nsvgDelete(image);
606 return false;
607 }
608 std::vector<unsigned char> data(n_pixels * 4, 0);
609 nsvgRasterize(rast, image, 0, 0, scale, data.data(), width, height, width * 4);
610
611 bool compress = false;
612 GLint last_texture;
613 unsigned m_image_texture{ 0 };
614 unsigned char* pixels = (unsigned char*)(&data[0]);
615
617 glsafe(::glGenTextures(1, &m_image_texture));
618 glsafe(::glBindTexture(GL_TEXTURE_2D, m_image_texture));
622 glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
623
624 // Store our identifier
625 texture_id = (ImTextureID)(intptr_t)m_image_texture;
626
627 // Restore state
628 glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
629
630 nsvgDeleteRasterizer(rast);
631 nsvgDelete(image);
632
633 return true;
634}
#define glsafe(cmd)
Definition OpenGLUtils.hpp:25
double scale()
Definition BitmapCache.hpp:27
#define GL_TEXTURE_MIN_FILTER
Definition gl.h:1828
#define glPixelStorei
Definition gl.h:4451
#define GL_LINEAR
Definition gl.h:930
#define glTexParameteri
Definition gl.h:4911
int GLint
Definition gl.h:2062
#define glGetIntegerv
Definition gl.h:3873
#define glTexImage2D
Definition gl.h:4895
#define GL_UNSIGNED_BYTE
Definition gl.h:1937
#define glGenTextures
Definition gl.h:3787
#define glBindTexture
Definition gl.h:3299
#define GL_RGBA
Definition gl.h:1493
#define GL_TEXTURE_MAG_FILTER
Definition gl.h:1822
#define GL_TEXTURE_2D
Definition gl.h:1739
#define GL_TEXTURE_BINDING_2D
Definition gl.h:1749
#define GL_UNPACK_ROW_LENGTH
Definition gl.h:1931
NSVGimage_ptr nsvgParseFromFile(const std::string &filename, const char *units, float dpi)
Definition NSVGUtils.cpp:106

References GL_LINEAR, GL_RGBA, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_UNPACK_ROW_LENGTH, GL_UNSIGNED_BYTE, glBindTexture, glGenTextures, glGetIntegerv, glPixelStorei, glsafe, glTexImage2D, glTexParameteri, Slic3r::nsvgParseFromFile(), and scale().

Referenced by Slic3r::GUI::ImGuiWrapper::filament_group().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_png()

wxBitmap * Slic3r::GUI::BitmapCache::load_png ( const std::string & bitmap_key,
unsigned width = 0,
unsigned height = 0,
const bool grayscale = false,
const float scale_in_center = 0.f )
252{
253 std::string bitmap_key = bitmap_name + ( height !=0 ?
254 "-h" + std::to_string(height) :
255 "-w" + std::to_string(width))
256 + (grayscale ? "-gs" : "");
257
258 auto it = m_map.find(bitmap_key);
259 if (it != m_map.end())
260 return it->second;
261
262 wxImage image;
263 if (! image.LoadFile(Slic3r::GUI::from_u8(Slic3r::var(bitmap_name + ".png")), wxBITMAP_TYPE_PNG) ||
264 image.GetWidth() == 0 || image.GetHeight() == 0)
265 return nullptr;
266
267 if (height == 0 && width == 0)
268 height = image.GetHeight();
269
270 if (height != 0 && unsigned(image.GetHeight()) != height)
271 width = unsigned(0.5f + float(image.GetWidth()) * height / image.GetHeight());
272 else if (width != 0 && unsigned(image.GetWidth()) != width)
273 height = unsigned(0.5f + float(image.GetHeight()) * width / image.GetWidth());
274
275 if (height != 0 && width != 0) {
276 // BBS: support resize by fill border
277 if (scale_in_center > 0)
278 image.Resize({ (int)width, (int)height }, { (int)(width - image.GetWidth()) / 2, (int)(height - image.GetHeight()) / 2 });
279 else
280 image.Rescale(width, height, wxIMAGE_QUALITY_BILINEAR);
281 }
282
283 if (grayscale)
284 image = image.ConvertToGreyscale(m_gs, m_gs, m_gs);
285
286 return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
287}
static std::string to_string(libvgcode::EMoveType type)
Definition GCodeViewer.cpp:377
wxString from_u8(const std::string &str)
Definition GUI.cpp:544
std::string var(const std::string &file_name)
Definition utils.cpp:278

References Slic3r::GUI::from_u8(), insert(), m_gs, m_map, Slic3r::var(), and Slic3r::GUI::wxImage_to_wxBitmap_with_alpha().

Referenced by create_scaled_bitmap(), and Slic3r::GUI::StatusBasePanel::init_bitmaps().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_svg()

wxBitmap * Slic3r::GUI::BitmapCache::load_svg ( const std::string & bitmap_key,
unsigned width = 0,
unsigned height = 0,
const bool grayscale = false,
const bool dark_mode = false,
const std::string & new_color = "",
const float scale_in_center = 0.f )
328{
329 std::string bitmap_key = bitmap_name + ( target_height !=0 ?
330 "-h" + std::to_string(target_height) :
331 "-w" + std::to_string(target_width))
332 + (m_scale != 1.0f ? "-s" + float_to_string_decimal_point(m_scale) : "")
333 + (dark_mode ? "-dm" : "")
334 + (grayscale ? "-gs" : "")
335 + new_color;
336
337 auto it = m_map.find(bitmap_key);
338 if (it != m_map.end())
339 return it->second;
340
341 // map of color replaces
342 std::map<std::string, std::string> replaces;
343 replaces["\"#0x00AE42\""] = "\"#009688\"";
344 replaces["\"#00FF00\""] = "\"#52c7b8\"";
345 if (dark_mode) {
346 replaces["\"#262E30\""] = "\"#EFEFF0\"";
347 replaces["\"#323A3D\""] = "\"#B3B3B5\"";
348 replaces["\"#808080\""] = "\"#818183\"";
349 //replaces["\"#ACACAC\""] = "\"#54545A\"";
350 replaces["\"#CECECE\""] = "\"#54545B\"";
351 replaces["\"#6B6B6B\""] = "\"#818182\"";
352 replaces["\"#909090\""] = "\"#FFFFFF\"";
353 replaces["\"#00FF00\""] = "\"#FF0000\"";
354 replaces["\"#009688\""] = "\"#00675b\"";
355 replaces["\"#F1F1F1\""] = "\"#36363B\"";
356 replaces["#DBDBDB"] = "#4A4A51"; // ORCA border color
357 replaces["#F0F0F1"] = "#333337"; // ORCA disabled background color
358 replaces["#262E30"] = "#EFEFF0"; // ORCA
359 } else {
360 replaces["#949494"] = "#7C8282"; // ORCA replace icon line color for light theme
361 }
362
363 if (strstr(bitmap_name.c_str(), "toggle_on") != NULL && dark_mode) // ORCA only replace color of toggle button
364 replaces["#009688"] = "#00675b";
365
366 if (!new_color.empty())
367 replaces["\"#009688\""] = "\"" + new_color + "\"";
368
369 NSVGimage *image = nullptr;
370 if (strstr(bitmap_name.c_str(), "printer_thumbnail") == NULL) {
371 image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, replaces);
372 }
373 else {
374 std::map<std::string, std::string> temp_replaces;
375 image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, temp_replaces);
376 }
377
378 if (image == nullptr)
379 return nullptr;
380
381 if (target_height == 0 && target_width == 0)
382 target_height = image->height;
383
384 target_height != 0 ? target_height *= m_scale : target_width *= m_scale;
385
386 float svg_scale = target_height != 0 ?
387 (float)target_height / image->height : target_width != 0 ?
388 (float)target_width / image->width : 1;
389
390 int width = (int)(svg_scale * image->width + 0.5f);
391 int height = (int)(svg_scale * image->height + 0.5f);
392 int n_pixels = width * height;
393 if (n_pixels <= 0) {
394 ::nsvgDelete(image);
395 return nullptr;
396 }
397
398 NSVGrasterizer *rast = ::nsvgCreateRasterizer();
399 if (rast == nullptr) {
400 ::nsvgDelete(image);
401 return nullptr;
402 }
403
404 std::vector<unsigned char> data(n_pixels * 4, 0);
405 // BBS: support resize by fill border
406 if (scale_in_center > 0 && scale_in_center < svg_scale) {
407 int w = (int)(image->width * scale_in_center);
408 int h = (int)(image->height * scale_in_center);
409 ::nsvgRasterize(rast, image, 0, 0, scale_in_center, data.data() + int(height - h) / 2 * width * 4 + int(width - w) / 2 * 4, w, h, width * 4);
410 } else
411 ::nsvgRasterize(rast, image, 0, 0, svg_scale, data.data(), width, height, width * 4);
412 ::nsvgDeleteRasterizer(rast);
413 ::nsvgDelete(image);
414
415 return this->insert_raw_rgba(bitmap_key, width, height, data.data(), grayscale);
416}
wxBitmap * insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, const bool grayscale=false)
Definition BitmapCache.cpp:230
std::string float_to_string_decimal_point(double value, int precision)
Definition LocalesUtils.cpp:108

References Slic3r::float_to_string_decimal_point(), insert_raw_rgba(), m_map, m_scale, nsvgParseFromFileWithReplace(), and Slic3r::var().

Referenced by Slic3r::GUI::SplashScreen::SplashScreen(), create_scaled_bitmap(), get_extruder_color_icon(), Slic3r::GUI::ColorPanel::OnPaint(), and Slic3r::GUI::anonymous_namespace{UVEditorCanvas.cpp}::pane_icon().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_svg2()

wxBitmap * Slic3r::GUI::BitmapCache::load_svg2 ( const std::string & bitmap_key,
unsigned width = 0,
unsigned height = 0,
const bool grayscale = false,
const bool dark_mode = false,
const std::vector< std::string > & array_new_color = std::vector<std::string>(),
const float scale_in_center = 0.0f )
420{
421
422 std::map<std::string, std::string> replaces;
423 if (array_new_color.size() == 2) {
424 replaces["#D9D9D9"] = array_new_color[0];
425 replaces["fill-opacity=\"1.0"] = array_new_color[1];
426 }
427
428
429 NSVGimage* image = nullptr;
430 image = nsvgParseFromFileWithReplace(Slic3r::var(bitmap_name + ".svg").c_str(), "px", 96.0f, replaces);
431
432 if (image == nullptr)
433 return nullptr;
434
435 if (target_height == 0 && target_width == 0)
436 target_height = image->height;
437
438 target_height != 0 ? target_height *= m_scale : target_width *= m_scale;
439
440 float svg_scale = target_height != 0 ?
441 (float)target_height / image->height : target_width != 0 ?
442 (float)target_width / image->width : 1;
443
444 int width = (int)(svg_scale * image->width + 0.5f);
445 int height = (int)(svg_scale * image->height + 0.5f);
446 int n_pixels = width * height;
447 if (n_pixels <= 0) {
448 ::nsvgDelete(image);
449 return nullptr;
450 }
451
452 NSVGrasterizer* rast = ::nsvgCreateRasterizer();
453 if (rast == nullptr) {
454 ::nsvgDelete(image);
455 return nullptr;
456 }
457
458 std::vector<unsigned char> data(n_pixels * 4, 0);
459 // BBS: support resize by fill border
460 if (scale_in_center > 0 && scale_in_center < svg_scale) {
461 int w = (int)(image->width * scale_in_center);
462 int h = (int)(image->height * scale_in_center);
463 ::nsvgRasterize(rast, image, 0, 0, scale_in_center, data.data() + int(height - h) / 2 * width * 4 + int(width - w) / 2 * 4, w, h, width * 4);
464 }
465 else
466 ::nsvgRasterize(rast, image, 0, 0, svg_scale, data.data(), width, height, width * 4);
467 ::nsvgDeleteRasterizer(rast);
468 ::nsvgDelete(image);
469
470 const unsigned char * raw_data = data.data();
471 wxImage wx_image(width, height);
472 wx_image.InitAlpha();
473 unsigned char* rgb = wx_image.GetData();
474 unsigned char* alpha = wx_image.GetAlpha();
475 unsigned int pixels = width * height;
476 for (unsigned int i = 0; i < pixels; ++i) {
477 *rgb++ = *raw_data++;
478 *rgb++ = *raw_data++;
479 *rgb++ = *raw_data++;
480 *alpha++ = *raw_data++;
481 }
482
483 if (grayscale)
484 wx_image = wx_image.ConvertToGreyscale(m_gs, m_gs, m_gs);
485 auto result = new wxBitmap(wxImage_to_wxBitmap_with_alpha(std::move(wx_image), m_scale));
486 return result;
487
488}
static NSVGimage * nsvgParseFromFileWithReplace(const char *filename, const char *units, float dpi, const std::map< std::string, std::string > &replaces)
Definition BitmapCache.cpp:289

References m_gs, m_scale, nsvgParseFromFileWithReplace(), Slic3r::var(), and Slic3r::GUI::wxImage_to_wxBitmap_with_alpha().

Referenced by create_scaled_bitmap2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mkclear()

wxBitmap Slic3r::GUI::BitmapCache::mkclear ( size_t width,
size_t height )
inline
56{ return mksolid(width, height, 0, 0, 0, wxALPHA_TRANSPARENT); }
wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling=false, size_t border_width=0, bool dark_mode=false)
Definition BitmapCache.cpp:491

References mksolid().

Here is the call graph for this function:

◆ mksolid() [1/3]

wxBitmap Slic3r::GUI::BitmapCache::mksolid ( size_t width,
size_t height,
const ColorRGB & rgb,
bool suppress_scaling = false,
size_t border_width = 0,
bool dark_mode = false )
inline
55{ return mksolid(width, height, rgb.r_uchar(), rgb.g_uchar(), rgb.b_uchar(), wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); }

References Slic3r::ColorRGB::b_uchar(), Slic3r::ColorRGB::g_uchar(), mksolid(), and Slic3r::ColorRGB::r_uchar().

Referenced by mksolid().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mksolid() [2/3]

wxBitmap Slic3r::GUI::BitmapCache::mksolid ( size_t width,
size_t height,
const unsigned char rgb[3],
bool suppress_scaling = false,
size_t border_width = 0,
bool dark_mode = false )
inline
54{ return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE, suppress_scaling, border_width, dark_mode); }

References mksolid().

Referenced by mksolid().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mksolid() [3/3]

wxBitmap Slic3r::GUI::BitmapCache::mksolid ( size_t width,
size_t height,
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char transparency,
bool suppress_scaling = false,
size_t border_width = 0,
bool dark_mode = false )
492{
493 double scale = suppress_scaling ? 1.0f : m_scale;
494 width *= scale;
495 height *= scale;
496
497 wxImage image(width, height);
498 image.InitAlpha();
499 unsigned char* imgdata = image.GetData();
500 unsigned char* imgalpha = image.GetAlpha();
501 for (size_t i = 0; i < width * height; ++ i) {
502 *imgdata ++ = r;
503 *imgdata ++ = g;
504 *imgdata ++ = b;
505 *imgalpha ++ = transparency;
506 }
507
508 // Add border, make white/light spools easier to see
509 if (border_width > 0) {
510
511 // Restrict to width of image
512 if (border_width > height) border_width = height - 1;
513 if (border_width > width) border_width = width - 1;
514
515 auto px_data = (uint8_t*)image.GetData();
516 auto a_data = (uint8_t*)image.GetAlpha();
517
518 for (size_t x = 0; x < width; ++x) {
519 for (size_t y = 0; y < height; ++y) {
520 if (x < border_width || y < border_width ||
521 x >= (width - border_width) || y >= (height - border_width)) {
522 const size_t idx = (x + y * width);
523 const size_t idx_rgb = (x + y * width) * 3;
524 px_data[idx_rgb] = px_data[idx_rgb + 1] = px_data[idx_rgb + 2] = dark_mode ? 245u : 110u;
525 a_data[idx] = 255u;
526 }
527 }
528 }
529 }
530
531 return wxImage_to_wxBitmap_with_alpha(std::move(image), scale);
532}

References m_scale, scale(), and Slic3r::GUI::wxImage_to_wxBitmap_with_alpha().

Referenced by Slic3r::GUI::ModelNode::get_bitmap(), and mkclear().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ nsvgParseFromFileWithReplace()

NSVGimage * Slic3r::GUI::BitmapCache::nsvgParseFromFileWithReplace ( const char * filename,
const char * units,
float dpi,
const std::map< std::string, std::string > & replaces )
static
290{
291 std::string str;
292 FILE* fp = NULL;
293 size_t size;
294 char* data = NULL;
295 NSVGimage* image = NULL;
296
297 fp = boost::nowide::fopen(filename, "rb");
298 if (!fp) goto error;
299 fseek(fp, 0, SEEK_END);
300 size = ftell(fp);
301 fseek(fp, 0, SEEK_SET);
302 data = (char*)malloc(size + 1);
303 if (data == NULL) goto error;
304 if (fread(data, 1, size, fp) != size) goto error;
305 data[size] = '\0'; // Must be null terminated.
306 fclose(fp);
307
308 if (replaces.empty())
309 image = nsvgParse(data, units, dpi);
310 else {
311 str.assign(data);
312 for (auto val : replaces)
313 boost::replace_all(str, val.first, val.second);
314 image = nsvgParse(str.data(), units, dpi);
315 }
316 free(data);
317 return image;
318
319error:
320 if (fp) fclose(fp);
321 if (data) free(data);
322 if (image) nsvgDelete(image);
323 return NULL;
324}
NSVGimage_ptr nsvgParse(const std::string &file_data, const char *units, float dpi)
Definition NSVGUtils.cpp:122

References Slic3r::nsvgParse().

Referenced by load_svg(), Slic3r::GUI::ImGuiWrapper::load_svg(), and load_svg2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_color()

bool Slic3r::GUI::BitmapCache::parse_color ( const std::string & scolor,
unsigned char * rgb_out )
static
535{
536 if (scolor.size() == 9) {
537 unsigned char rgba[4];
538 parse_color4(scolor, rgba);
539 rgb_out[0] = rgba[0];
540 rgb_out[1] = rgba[1];
541 rgb_out[2] = rgba[2];
542 return true;
543 }
544 rgb_out[0] = rgb_out[1] = rgb_out[2] = 0;
545 if (scolor.size() != 7 || scolor.front() != '#')
546 return false;
547 const char* c = scolor.data() + 1;
548 for (size_t i = 0; i < 3; ++i) {
549 int digit1 = hex_digit_to_int(*c++);
550 int digit2 = hex_digit_to_int(*c++);
551 if (digit1 == -1 || digit2 == -1)
552 return false;
553 rgb_out[i] = (unsigned char)(digit1 * 16 + digit2);
554 }
555
556 return true;
557}
static bool parse_color4(const std::string &scolor, unsigned char *rgba_out)
Definition BitmapCache.cpp:559
int hex_digit_to_int(const char c)
Definition GUI_Utils.hpp:452

References Slic3r::GUI::hex_digit_to_int(), and parse_color4().

Here is the call graph for this function:

◆ parse_color4()

bool Slic3r::GUI::BitmapCache::parse_color4 ( const std::string & scolor,
unsigned char * rgba_out )
static
560{
561 rgba_out[0] = rgba_out[1] = rgba_out[2] = 0; rgba_out[3] = 255;
562 if ((scolor.size() != 7 && scolor.size() != 9) || scolor.front() != '#')
563 return false;
564 const char* c = scolor.data() + 1;
565 for (size_t i = 0; i < scolor.size() / 2; ++i) {
566 int digit1 = hex_digit_to_int(*c++);
567 int digit2 = hex_digit_to_int(*c++);
568 if (digit1 == -1 || digit2 == -1)
569 return false;
570 rgba_out[i] = (unsigned char)(digit1 * 16 + digit2);
571 }
572 return true;
573}

References Slic3r::GUI::hex_digit_to_int().

Referenced by Slic3r::GUI::ImGuiWrapper::filament_group(), Slic3r::GUI::SyncAmsInfoDialog::generate_override_fix_ams_list(), Slic3r::GUI::Plater::get_extruders_colors(), parse_color(), Slic3r::GUI::SelectMachineDialog::reset_and_sync_ams_list(), Slic3r::GUI::SyncAmsInfoDialog::reset_and_sync_ams_list(), Slic3r::CLI::run(), and Slic3r::GUI::SendMultiMachinePage::sync_ams_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scale()

double Slic3r::GUI::BitmapCache::scale ( )
inline
27{ return m_scale; }

References m_scale.

Referenced by load_from_svg_file_change_color(), and mksolid().

Here is the caller graph for this function:

Member Data Documentation

◆ m_gs

double Slic3r::GUI::BitmapCache::m_gs = 0.2
private

◆ m_map

std::map<std::string, wxBitmap*> Slic3r::GUI::BitmapCache::m_map
private

◆ m_scale

double Slic3r::GUI::BitmapCache::m_scale = 1.0
private

The documentation for this class was generated from the following files: