To fix blurred icons under OSX there is implemented PresetBitmapComboBox, derived from wxBitmapComboBox,

which now will be used for preset choosers on sidebar a preset tabs.

+ for BitmapCache class added m_scale used for correct scaling of SVG images on Retina displays

+ some code clearing from unused functions or function's parameters
This commit is contained in:
YuSanka 2020-01-31 16:50:11 +01:00
parent 378321231f
commit 1472ad9b14
17 changed files with 319 additions and 177 deletions

View file

@ -1,6 +1,7 @@
#include "BitmapCache.hpp"
#include "libslic3r/Utils.hpp"
#include "../Utils/MacDarkMode.hpp"
#include <boost/filesystem.hpp>
#if ! defined(WIN32) && ! defined(__APPLE__)
@ -20,6 +21,16 @@
namespace Slic3r { namespace GUI {
BitmapCache::BitmapCache()
{
#ifdef __APPLE__
// Note: win->GetContentScaleFactor() is not used anymore here because it tends to
// return bogus results quite often (such as 1.0 on Retina or even 0.0).
// We're using the max scaling factor across all screens because it's very likely to be good enough.
m_scale = mac_max_scaling_factor();
#endif
}
void BitmapCache::clear()
{
for (std::pair<const std::string, wxBitmap*> &bitmap : m_map)
@ -49,7 +60,7 @@ static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image, float scale = 1.
#endif
}
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height, float scale/* = 1.0f*/)
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height)
{
wxBitmap *bitmap = nullptr;
auto it = m_map.find(bitmap_key);
@ -61,7 +72,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_
// So, We need to let the Mac OS wxBitmap implementation
// know that the image may already be scaled appropriately for Retina,
// and thereby that it's not supposed to upscale it.
bitmap->CreateScaled(width, height, -1, scale);
bitmap->CreateScaled(width, height, -1, m_scale);
#endif
m_map[bitmap_key] = bitmap;
} else {
@ -103,13 +114,18 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp
return this->insert(bitmap_key, bmps, bmps + 3);
}
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *begin, const wxBitmap *end, float scale/* = 1.0f*/)
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) {
#ifdef __APPLE__
width += bmp->GetScaledWidth();
height = std::max<size_t>(height, bmp->GetScaledHeight());
#else
width += bmp->GetWidth();
height = std::max<size_t>(height, bmp->GetHeight());
#endif
}
#ifdef BROKEN_ALPHA
@ -166,13 +182,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg
#else
#ifdef __APPLE__
// Note, for this moment width and height are scaled, so divide them by scale to avoid one more multiplication inside CreateScaled()
width *= 1.0 / scale;
height *= 1.0 / scale;
#endif
wxBitmap *bitmap = this->insert(bitmap_key, width, height, scale);
wxBitmap *bitmap = this->insert(bitmap_key, width, height);
wxMemoryDC memDC;
memDC.SelectObject(*bitmap);
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
@ -181,8 +191,12 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
if (bmp->GetWidth() > 0)
memDC.DrawBitmap(*bmp, x, 0, true);
#ifdef __APPLE__
// we should "move" with step equal to non-scaled width
x += bmp->GetWidth()/scale;
x += bmp->GetScaledWidth();
#else
x += bmp->GetWidth();
#endif
}
memDC.SelectObject(wxNullBitmap);
return bitmap;
@ -190,7 +204,7 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *beg
#endif
}
wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, float scale /* = 1.0f */, const bool grayscale/* = false*/)
wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned width, unsigned height, const unsigned char *raw_data, const bool grayscale/* = false*/)
{
wxImage image(width, height);
image.InitAlpha();
@ -207,7 +221,7 @@ wxBitmap* BitmapCache::insert_raw_rgba(const std::string &bitmap_key, unsigned w
if (grayscale)
image = image.ConvertToGreyscale(m_gs, m_gs, m_gs);
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image), scale));
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image), m_scale));
}
wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned width, unsigned height,
@ -242,12 +256,12 @@ wxBitmap* BitmapCache::load_png(const std::string &bitmap_name, unsigned width,
}
wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_width, unsigned target_height,
float scale /* = 1.0f */, const bool grayscale/* = false*/, const bool dark_mode/* = false*/)
const bool grayscale/* = false*/, const bool dark_mode/* = false*/)
{
std::string bitmap_key = bitmap_name + ( target_height !=0 ?
"-h" + std::to_string(target_height) :
"-w" + std::to_string(target_width))
+ (scale != 1.0f ? "-s" + std::to_string(scale) : "")
+ (m_scale != 1.0f ? "-s" + std::to_string(m_scale) : "")
+ (grayscale ? "-gs" : "");
/* For the Dark mode of any platform, we should draw icons in respect to OS background
@ -287,7 +301,7 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_
if (image == nullptr)
return nullptr;
target_height != 0 ? target_height *= scale : target_width *= scale;
target_height != 0 ? target_height *= m_scale : target_width *= m_scale;
float svg_scale = target_height != 0 ?
(float)target_height / image->height : target_width != 0 ?
@ -312,11 +326,16 @@ wxBitmap* BitmapCache::load_svg(const std::string &bitmap_name, unsigned target_
::nsvgDeleteRasterizer(rast);
::nsvgDelete(image);
return this->insert_raw_rgba(bitmap_key, width, height, data.data(), scale, grayscale);
return this->insert_raw_rgba(bitmap_key, width, height, data.data(), grayscale);
}
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
//we make scaled solid bitmaps only for the cases, when its will be used with scaled SVG icon in one output bitmap
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency, bool suppress_scaling/* = false*/)
{
double scale = suppress_scaling ? 1.0f : m_scale;
width *= scale;
height *= scale;
wxImage image(width, height);
image.InitAlpha();
unsigned char* imgdata = image.GetData();
@ -327,7 +346,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi
*imgdata ++ = b;
*imgalpha ++ = transparency;
}
return wxImage_to_wxBitmap_with_alpha(std::move(image));
return wxImage_to_wxBitmap_with_alpha(std::move(image), scale);
}
} // namespace GUI