Improve loading of default styles. Should fix issue on OSx

This commit is contained in:
Filip Sykala - NTB T15p 2023-01-30 17:44:14 +01:00
parent dac7b7e46a
commit 449267fa47
3 changed files with 115 additions and 76 deletions

View File

@ -124,7 +124,7 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
, m_volume(nullptr) , m_volume(nullptr)
, m_is_unknown_font(false) , m_is_unknown_font(false)
, m_rotate_gizmo(parent, GLGizmoRotate::Axis::Z) // grab id = 2 (Z axis) , 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_job_cancel(nullptr)
{ {
m_rotate_gizmo.set_group_id(0); m_rotate_gizmo.set_group_id(0);
@ -1014,7 +1014,7 @@ void GLGizmoEmboss::initialize()
init_icons(); init_icons();
// initialize text styles // initialize text styles
m_style_manager.init(wxGetApp().app_config, create_default_styles()); m_style_manager.init(wxGetApp().app_config);
set_default_text(); set_default_text();
// Set rotation gizmo upwardrotate // Set rotation gizmo upwardrotate
@ -1025,20 +1025,48 @@ EmbossStyles GLGizmoEmboss::create_default_styles()
{ {
// https://docs.wxwidgets.org/3.0/classwx_font.html // https://docs.wxwidgets.org/3.0/classwx_font.html
// Predefined objects/pointers: wxNullFont, wxNORMAL_FONT, wxSMALL_FONT, wxITALIC_FONT, wxSWISS_FONT // 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(*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(*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(*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(*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 // Not all predefined font for wx must be valid TTF, but at least one style must be loadable
//EmbossStyle GLGizmoEmboss::create_default_style() { styles.erase(std::remove_if(styles.begin(), styles.end(), [](const EmbossStyle& style) {
// std::string font_path = Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf"; wxFont wx_font = WxFontUtils::create_wxFont(style);
// return EmbossStyle{"Default font", font_path, EmbossStyle::Type::file_path}; 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"); } 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) DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &style_manager, std::shared_ptr<std::atomic<bool>>& cancel)
{ {
auto create_volume_name = [&]() { // create volume_name
bool contain_enter = text.find('\n') != std::string::npos; std::string volume_name = text; // copy
std::string text_fixed; // contain_enter?
if (contain_enter) { if (volume_name.find('\n') != std::string::npos)
// change enters to space // change enters to space
text_fixed = text; // copy std::replace(volume_name.begin(), volume_name.end(), '\n', ' ');
std::replace(text_fixed.begin(), text_fixed.end(), '\n', ' ');
}
return ((contain_enter) ? text_fixed : text);
};
auto create_configuration = [&]() -> TextConfiguration { if (!style_manager.is_active_font())
if (!style_manager.is_active_font()) { style_manager.load_valid_style();
std::string default_text_for_emboss = _u8L("Embossed text"); assert(style_manager.is_active_font());
EmbossStyle es = style_manager.get_style();
TextConfiguration tc{es, default_text_for_emboss};
// TODO: investigate how to initialize
return tc;
}
EmbossStyle &es = style_manager.get_style(); const EmbossStyle &es = style_manager.get_style();
// actualize font path - during changes in gui it could be corrupted // actualize font path - during changes in gui it could be corrupted
// volume must store valid path // volume must store valid path
assert(style_manager.get_wx_font().has_value()); assert(style_manager.get_wx_font().has_value());
assert(es.path.compare(WxFontUtils::store_wxFont(*style_manager.get_wx_font())) == 0); assert(style_manager.get_wx_font()->IsOk());
// style.path = WxFontUtils::store_wxFont(*m_style_manager.get_wx_font()); assert(es.path.compare(WxFontUtils::store_wxFont(*style_manager.get_wx_font())) == 0);
return TextConfiguration{es, text}; // style.path = WxFontUtils::store_wxFont(*m_style_manager.get_wx_font());
}; TextConfiguration tc{es, text};
// Cancel previous Job, when it is in process // Cancel previous Job, when it is in process
// worker.cancel(); --> Use less in this case I want cancel only previous EmbossJob no other jobs // 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); cancel->store(true);
// create new shared ptr to cancel new job // create new shared ptr to cancel new job
cancel = std::make_shared<std::atomic<bool>>(false); 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) void priv::start_create_object_job(DataBase &emboss_data, const Vec2d &coor)

View File

@ -14,8 +14,9 @@ using namespace Slic3r;
using namespace Slic3r::Emboss; using namespace Slic3r::Emboss;
using namespace Slic3r::GUI::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_imgui_init_glyph_range(language_glyph_range)
, m_create_default_styles(create_default_styles)
, m_exist_style_images(false) , m_exist_style_images(false)
, m_temp_style_images(nullptr) , m_temp_style_images(nullptr)
, m_app_config(nullptr) , m_app_config(nullptr)
@ -27,13 +28,14 @@ StyleManager::~StyleManager() {
free_style_images(); free_style_images();
} }
void StyleManager::init(AppConfig *app_config, const EmbossStyles &default_styles) void StyleManager::init(AppConfig *app_config)
{ {
m_app_config = app_config; m_app_config = app_config;
EmbossStyles styles = (app_config != nullptr) ? EmbossStyles styles = (app_config != nullptr) ?
EmbossStylesSerializable::load_styles(*app_config) : EmbossStylesSerializable::load_styles(*app_config) :
default_styles; EmbossStyles{};
if (styles.empty()) styles = default_styles; if (styles.empty())
styles = m_create_default_styles();
for (EmbossStyle &style : styles) { for (EmbossStyle &style : styles) {
make_unique_name(style.name); make_unique_name(style.name);
m_style_items.push_back({style}); 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; if (active_index >= m_style_items.size()) active_index = 0;
// find valid font item // find valid font item
if (!load_style(active_index)) { if (load_style(active_index))
m_style_items.erase(m_style_items.begin() + active_index); return; // style is loaded
active_index = 0;
while (m_style_items.empty() || !load_style(active_index)) // Try to fix that style can't be loaded
m_style_items.erase(m_style_items.begin()); m_style_items.erase(m_style_items.begin() + active_index);
// no one style from config is loadable
if (m_style_items.empty()) { load_valid_style();
// 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);
}
}
} }
bool StyleManager::store_styles_to_app_config(bool use_modification, 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 // try to save situation by load some font
load_first_valid_font(); load_valid_style();
} }
void StyleManager::erase(size_t index) { 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) bool StyleManager::load_style(size_t style_index)
{ {
if (style_index >= m_style_items.size()) return false; 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::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 const EmbossStyle* StyleManager::get_stored_style() const
{ {
if (m_style_cache.style_index >= m_style_items.size()) return nullptr; if (m_style_cache.style_index >= m_style_items.size()) return nullptr;

View File

@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
#include <functional>
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <wx/font.h> #include <wx/font.h>
#include <GL/glew.h> #include <GL/glew.h>
@ -23,7 +24,9 @@ class StyleManager
friend class CreateFontStyleImagesJob; // access to StyleImagesData friend class CreateFontStyleImagesJob; // access to StyleImagesData
public: 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> /// <summary>
/// Release imgui font and style images from GPU /// Release imgui font and style images from GPU
@ -36,8 +39,7 @@ public:
/// </summary> /// </summary>
/// <param name="app_config">Application configuration loaded from file "PrusaSlicer.ini" /// <param name="app_config">Application configuration loaded from file "PrusaSlicer.ini"
/// + cfg is stored to privat variable</param> /// + 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);
void init(AppConfig *app_config, const EmbossStyles &default_styles);
/// <summary> /// <summary>
/// Write font list into AppConfig /// Write font list into AppConfig
@ -81,6 +83,11 @@ public:
/// <param name="name">New name</param> /// <param name="name">New name</param>
void rename(const std::string &name); void rename(const std::string &name);
/// <summary>
/// load some valid style
/// </summary>
void load_valid_style();
/// <summary> /// <summary>
/// Change active font /// Change active font
/// When font not loaded roll back activ 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); static float get_imgui_font_size(const FontProp &prop, const Slic3r::Emboss::FontFile &file, double scale);
private: private:
// erase font when not possible to load std::function<EmbossStyles()> m_create_default_styles;
// used at initialize phaze - fonts could be modified in appConfig file by user
bool load_first_valid_font();
/// <summary> /// <summary>
/// Cache data from style to reduce amount of: /// Cache data from style to reduce amount of: