Improve loading of default styles. Should fix issue on OSx
This commit is contained in:
parent
dac7b7e46a
commit
449267fa47
3 changed files with 115 additions and 76 deletions
|
@ -124,7 +124,7 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
|
|||
, m_volume(nullptr)
|
||||
, m_is_unknown_font(false)
|
||||
, m_rotate_gizmo(parent, GLGizmoRotate::Axis::Z) // grab id = 2 (Z axis)
|
||||
, m_style_manager(m_imgui->get_glyph_ranges())
|
||||
, m_style_manager(m_imgui->get_glyph_ranges(), create_default_styles)
|
||||
, m_job_cancel(nullptr)
|
||||
{
|
||||
m_rotate_gizmo.set_group_id(0);
|
||||
|
@ -1014,7 +1014,7 @@ void GLGizmoEmboss::initialize()
|
|||
init_icons();
|
||||
|
||||
// initialize text styles
|
||||
m_style_manager.init(wxGetApp().app_config, create_default_styles());
|
||||
m_style_manager.init(wxGetApp().app_config);
|
||||
set_default_text();
|
||||
|
||||
// Set rotation gizmo upwardrotate
|
||||
|
@ -1025,20 +1025,48 @@ EmbossStyles GLGizmoEmboss::create_default_styles()
|
|||
{
|
||||
// https://docs.wxwidgets.org/3.0/classwx_font.html
|
||||
// Predefined objects/pointers: wxNullFont, wxNORMAL_FONT, wxSMALL_FONT, wxITALIC_FONT, wxSWISS_FONT
|
||||
return {
|
||||
EmbossStyles styles = {
|
||||
WxFontUtils::create_emboss_style(*wxNORMAL_FONT, _u8L("NORMAL")), // wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
|
||||
WxFontUtils::create_emboss_style(*wxSMALL_FONT, _u8L("SMALL")), // A font using the wxFONTFAMILY_SWISS family and 2 points smaller than wxNORMAL_FONT.
|
||||
WxFontUtils::create_emboss_style(*wxITALIC_FONT, _u8L("ITALIC")), // A font using the wxFONTFAMILY_ROMAN family and wxFONTSTYLE_ITALIC style and of the same size of wxNORMAL_FONT.
|
||||
WxFontUtils::create_emboss_style(*wxSWISS_FONT, _u8L("SWISS")), // A font identic to wxNORMAL_FONT except for the family used which is wxFONTFAMILY_SWISS.
|
||||
WxFontUtils::create_emboss_style(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD), _u8L("MODERN"))
|
||||
WxFontUtils::create_emboss_style(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD), _u8L("MODERN")),
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// Could exist systems without installed font so last chance is used own file
|
||||
//EmbossStyle GLGizmoEmboss::create_default_style() {
|
||||
// std::string font_path = Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf";
|
||||
// return EmbossStyle{"Default font", font_path, EmbossStyle::Type::file_path};
|
||||
//}
|
||||
// Not all predefined font for wx must be valid TTF, but at least one style must be loadable
|
||||
styles.erase(std::remove_if(styles.begin(), styles.end(), [](const EmbossStyle& style) {
|
||||
wxFont wx_font = WxFontUtils::create_wxFont(style);
|
||||
return WxFontUtils::create_font_file(wx_font) == nullptr;
|
||||
}),styles.end()
|
||||
);
|
||||
|
||||
// exist some valid style?
|
||||
if (!styles.empty())
|
||||
return styles;
|
||||
|
||||
// No valid style in defult list
|
||||
// at least one style must contain loadable font
|
||||
wxArrayString facenames = wxFontEnumerator::GetFacenames(wxFontEncoding::wxFONTENCODING_SYSTEM);
|
||||
wxFont wx_font;
|
||||
for (const wxString &face : facenames) {
|
||||
wx_font = wxFont(face);
|
||||
if (WxFontUtils::create_font_file(wx_font) != nullptr)
|
||||
break;
|
||||
wx_font = wxFont(); // NotOk
|
||||
}
|
||||
|
||||
if (wx_font.IsOk()) {
|
||||
// use first alphabetic sorted installed font
|
||||
styles.push_back(WxFontUtils::create_emboss_style(wx_font, _u8L("First font")));
|
||||
} else {
|
||||
// On current OS is not installed any correct TTF font
|
||||
// use font packed with Slic3r
|
||||
std::string font_path = Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf";
|
||||
styles.push_back(EmbossStyle{_u8L("Default font"), font_path, EmbossStyle::Type::file_path});
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::set_default_text(){ m_text = _u8L("Embossed text"); }
|
||||
|
||||
|
@ -3650,34 +3678,25 @@ std::string GLGizmoEmboss::get_file_name(const std::string &file_path)
|
|||
|
||||
DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &style_manager, std::shared_ptr<std::atomic<bool>>& cancel)
|
||||
{
|
||||
auto create_volume_name = [&]() {
|
||||
bool contain_enter = text.find('\n') != std::string::npos;
|
||||
std::string text_fixed;
|
||||
if (contain_enter) {
|
||||
// change enters to space
|
||||
text_fixed = text; // copy
|
||||
std::replace(text_fixed.begin(), text_fixed.end(), '\n', ' ');
|
||||
}
|
||||
return ((contain_enter) ? text_fixed : text);
|
||||
};
|
||||
// create volume_name
|
||||
std::string volume_name = text; // copy
|
||||
// contain_enter?
|
||||
if (volume_name.find('\n') != std::string::npos)
|
||||
// change enters to space
|
||||
std::replace(volume_name.begin(), volume_name.end(), '\n', ' ');
|
||||
|
||||
auto create_configuration = [&]() -> TextConfiguration {
|
||||
if (!style_manager.is_active_font()) {
|
||||
std::string default_text_for_emboss = _u8L("Embossed text");
|
||||
EmbossStyle es = style_manager.get_style();
|
||||
TextConfiguration tc{es, default_text_for_emboss};
|
||||
// TODO: investigate how to initialize
|
||||
return tc;
|
||||
}
|
||||
if (!style_manager.is_active_font())
|
||||
style_manager.load_valid_style();
|
||||
assert(style_manager.is_active_font());
|
||||
|
||||
EmbossStyle &es = style_manager.get_style();
|
||||
// actualize font path - during changes in gui it could be corrupted
|
||||
// volume must store valid path
|
||||
assert(style_manager.get_wx_font().has_value());
|
||||
assert(es.path.compare(WxFontUtils::store_wxFont(*style_manager.get_wx_font())) == 0);
|
||||
// style.path = WxFontUtils::store_wxFont(*m_style_manager.get_wx_font());
|
||||
return TextConfiguration{es, text};
|
||||
};
|
||||
const EmbossStyle &es = style_manager.get_style();
|
||||
// actualize font path - during changes in gui it could be corrupted
|
||||
// volume must store valid path
|
||||
assert(style_manager.get_wx_font().has_value());
|
||||
assert(style_manager.get_wx_font()->IsOk());
|
||||
assert(es.path.compare(WxFontUtils::store_wxFont(*style_manager.get_wx_font())) == 0);
|
||||
// style.path = WxFontUtils::store_wxFont(*m_style_manager.get_wx_font());
|
||||
TextConfiguration tc{es, text};
|
||||
|
||||
// Cancel previous Job, when it is in process
|
||||
// worker.cancel(); --> Use less in this case I want cancel only previous EmbossJob no other jobs
|
||||
|
@ -3686,7 +3705,7 @@ DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &st
|
|||
cancel->store(true);
|
||||
// create new shared ptr to cancel new job
|
||||
cancel = std::make_shared<std::atomic<bool>>(false);
|
||||
return Slic3r::GUI::Emboss::DataBase{style_manager.get_font_file_with_cache(), create_configuration(), create_volume_name(), cancel};
|
||||
return Slic3r::GUI::Emboss::DataBase{style_manager.get_font_file_with_cache(), tc, volume_name, cancel};
|
||||
}
|
||||
|
||||
void priv::start_create_object_job(DataBase &emboss_data, const Vec2d &coor)
|
||||
|
|
|
@ -14,8 +14,9 @@ using namespace Slic3r;
|
|||
using namespace Slic3r::Emboss;
|
||||
using namespace Slic3r::GUI::Emboss;
|
||||
|
||||
StyleManager::StyleManager(const ImWchar *language_glyph_range)
|
||||
StyleManager::StyleManager(const ImWchar *language_glyph_range, std::function<EmbossStyles()> create_default_styles)
|
||||
: m_imgui_init_glyph_range(language_glyph_range)
|
||||
, m_create_default_styles(create_default_styles)
|
||||
, m_exist_style_images(false)
|
||||
, m_temp_style_images(nullptr)
|
||||
, m_app_config(nullptr)
|
||||
|
@ -27,13 +28,14 @@ StyleManager::~StyleManager() {
|
|||
free_style_images();
|
||||
}
|
||||
|
||||
void StyleManager::init(AppConfig *app_config, const EmbossStyles &default_styles)
|
||||
void StyleManager::init(AppConfig *app_config)
|
||||
{
|
||||
m_app_config = app_config;
|
||||
EmbossStyles styles = (app_config != nullptr) ?
|
||||
EmbossStylesSerializable::load_styles(*app_config) :
|
||||
default_styles;
|
||||
if (styles.empty()) styles = default_styles;
|
||||
EmbossStyles styles = (app_config != nullptr) ?
|
||||
EmbossStylesSerializable::load_styles(*app_config) :
|
||||
EmbossStyles{};
|
||||
if (styles.empty())
|
||||
styles = m_create_default_styles();
|
||||
for (EmbossStyle &style : styles) {
|
||||
make_unique_name(style.name);
|
||||
m_style_items.push_back({style});
|
||||
|
@ -48,23 +50,13 @@ void StyleManager::init(AppConfig *app_config, const EmbossStyles &default_style
|
|||
if (active_index >= m_style_items.size()) active_index = 0;
|
||||
|
||||
// find valid font item
|
||||
if (!load_style(active_index)) {
|
||||
m_style_items.erase(m_style_items.begin() + active_index);
|
||||
active_index = 0;
|
||||
while (m_style_items.empty() || !load_style(active_index))
|
||||
m_style_items.erase(m_style_items.begin());
|
||||
// no one style from config is loadable
|
||||
if (m_style_items.empty()) {
|
||||
// set up default font list
|
||||
for (EmbossStyle style : default_styles) {
|
||||
make_unique_name(style.name);
|
||||
m_style_items.push_back({std::move(style)});
|
||||
}
|
||||
// try to load first default font
|
||||
[[maybe_unused]] bool loaded = load_style(active_index);
|
||||
assert(loaded);
|
||||
}
|
||||
}
|
||||
if (load_style(active_index))
|
||||
return; // style is loaded
|
||||
|
||||
// Try to fix that style can't be loaded
|
||||
m_style_items.erase(m_style_items.begin() + active_index);
|
||||
|
||||
load_valid_style();
|
||||
}
|
||||
|
||||
bool StyleManager::store_styles_to_app_config(bool use_modification,
|
||||
|
@ -135,7 +127,7 @@ void StyleManager::discard_style_changes() {
|
|||
}
|
||||
|
||||
// try to save situation by load some font
|
||||
load_first_valid_font();
|
||||
load_valid_style();
|
||||
}
|
||||
|
||||
void StyleManager::erase(size_t index) {
|
||||
|
@ -161,6 +153,38 @@ void StyleManager::rename(const std::string& name) {
|
|||
}
|
||||
}
|
||||
|
||||
void StyleManager::load_valid_style()
|
||||
{
|
||||
// iterate over all known styles
|
||||
while (!m_style_items.empty()) {
|
||||
if (load_style(0))
|
||||
return;
|
||||
// can't load so erase it from list
|
||||
m_style_items.erase(m_style_items.begin());
|
||||
}
|
||||
|
||||
// no one style is loadable
|
||||
// set up default font list
|
||||
EmbossStyles def_style = m_create_default_styles();
|
||||
for (EmbossStyle &style : def_style) {
|
||||
make_unique_name(style.name);
|
||||
m_style_items.push_back({std::move(style)});
|
||||
}
|
||||
|
||||
// iterate over default styles
|
||||
// There have to be option to use build in font
|
||||
while (!m_style_items.empty()) {
|
||||
if (load_style(0))
|
||||
return;
|
||||
// can't load so erase it from list
|
||||
m_style_items.erase(m_style_items.begin());
|
||||
}
|
||||
|
||||
// This OS doesn't have TTF as default font,
|
||||
// find some loadable font out of default list
|
||||
assert(false);
|
||||
}
|
||||
|
||||
bool StyleManager::load_style(size_t style_index)
|
||||
{
|
||||
if (style_index >= m_style_items.size()) return false;
|
||||
|
@ -206,15 +230,6 @@ bool StyleManager::load_style(const EmbossStyle &style, const wxFont &font)
|
|||
|
||||
bool StyleManager::is_active_font() { return m_style_cache.font_file.has_value(); }
|
||||
|
||||
bool StyleManager::load_first_valid_font() {
|
||||
while (!m_style_items.empty()) {
|
||||
if (load_style(0)) return true;
|
||||
// can't load so erase it from list
|
||||
m_style_items.erase(m_style_items.begin());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const EmbossStyle* StyleManager::get_stored_style() const
|
||||
{
|
||||
if (m_style_cache.style_index >= m_style_items.size()) return nullptr;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <imgui/imgui.h>
|
||||
#include <wx/font.h>
|
||||
#include <GL/glew.h>
|
||||
|
@ -23,7 +24,9 @@ class StyleManager
|
|||
friend class CreateFontStyleImagesJob; // access to StyleImagesData
|
||||
|
||||
public:
|
||||
StyleManager(const ImWchar *language_glyph_range);
|
||||
/// <param name="language_glyph_range">Character to load for imgui when initialize imgui font</param>
|
||||
/// <param name="create_default_styles">Function to create default styles</param>
|
||||
StyleManager(const ImWchar *language_glyph_range, std::function<EmbossStyles()> create_default_styles);
|
||||
|
||||
/// <summary>
|
||||
/// Release imgui font and style images from GPU
|
||||
|
@ -36,8 +39,7 @@ public:
|
|||
/// </summary>
|
||||
/// <param name="app_config">Application configuration loaded from file "PrusaSlicer.ini"
|
||||
/// + cfg is stored to privat variable</param>
|
||||
/// <param name="default_styles">Used when list is not loadable from config</param>
|
||||
void init(AppConfig *app_config, const EmbossStyles &default_styles);
|
||||
void init(AppConfig *app_config);
|
||||
|
||||
/// <summary>
|
||||
/// Write font list into AppConfig
|
||||
|
@ -81,6 +83,11 @@ public:
|
|||
/// <param name="name">New name</param>
|
||||
void rename(const std::string &name);
|
||||
|
||||
/// <summary>
|
||||
/// load some valid style
|
||||
/// </summary>
|
||||
void load_valid_style();
|
||||
|
||||
/// <summary>
|
||||
/// Change active font
|
||||
/// When font not loaded roll back activ font
|
||||
|
@ -194,9 +201,7 @@ public:
|
|||
static float get_imgui_font_size(const FontProp &prop, const Slic3r::Emboss::FontFile &file, double scale);
|
||||
|
||||
private:
|
||||
// erase font when not possible to load
|
||||
// used at initialize phaze - fonts could be modified in appConfig file by user
|
||||
bool load_first_valid_font();
|
||||
std::function<EmbossStyles()> m_create_default_styles;
|
||||
|
||||
/// <summary>
|
||||
/// Cache data from style to reduce amount of:
|
||||
|
|
Loading…
Reference in a new issue