From 137399ef1ad919077b996a2dd12c3b8dde87824a Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Thu, 27 Jan 2022 10:47:05 +0100 Subject: [PATCH] Style select with rendered name Fix negative volume color when dragging --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 261 ++++++++++-------- src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 5 +- src/slic3r/Utils/FontManager.cpp | 353 ++++++++++++++++++------ src/slic3r/Utils/FontManager.hpp | 101 +++++-- src/slic3r/Utils/WxFontUtils.cpp | 10 +- src/slic3r/Utils/WxFontUtils.hpp | 2 +- 6 files changed, 506 insertions(+), 226 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 4617e56294..72872a3702 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -38,9 +39,12 @@ //#define ALLOW_DEBUG_MODE #ifdef ALLOW_DEBUG_MODE #define ALLOW_ADD_FONT_BY_FILE -#endif // ALLOW_DEBUG_MODE #define ALLOW_ADD_FONT_BY_OS_SELECTOR +#define SHOW_IMGUI_ATLAS +#endif // ALLOW_DEBUG_MODE +#define ALLOW_ADD_FONT_BY_FILE +#define ALLOW_ADD_FONT_BY_OS_SELECTOR using namespace Slic3r; using namespace Slic3r::GUI; @@ -253,23 +257,37 @@ std::string GLGizmoEmboss::on_get_name() const { return _u8L("Emboss"); } void GLGizmoEmboss::on_render() { // no volume selected if (m_volume == nullptr) return; - if (m_parent.get_selection().is_empty()) return; + Selection &selection = m_parent.get_selection(); + if (selection.is_empty()) return; if (m_temp_transformation.has_value()) { // draw text volume on temporary position - const Selection &selection = m_parent.get_selection(); const GLVolume& gl_volume = *selection.get_volume(*selection.get_volume_idxs().begin()); glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(m_temp_transformation->data())); GLShaderProgram *shader = wxGetApp().get_shader("gouraud_light"); shader->start_using(); - // dragging object must be selected so draw it with selected color - shader->set_uniform("uniform_color", GLVolume::SELECTED_COLOR); + + // dragging object must be selected so draw it with correct color + //auto color = gl_volume.color; + //auto color = gl_volume.render_color; + auto color = GLVolume::SELECTED_COLOR; + // Set transparent color for NEGATIVE_VOLUME & PARAMETER_MODIFIER + + bool is_transparent = m_volume->type() != ModelVolumeType::MODEL_PART; + if (is_transparent) { + color[3] = 0.5f; + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + } + shader->set_uniform("uniform_color", color); glsafe(::glEnable(GL_DEPTH_TEST)); gl_volume.indexed_vertex_array.render(); glsafe(::glDisable(GL_DEPTH_TEST)); + if (is_transparent) glsafe(::glDisable(GL_BLEND)); + shader->stop_using(); glsafe(::glPopMatrix()); } @@ -350,6 +368,9 @@ void GLGizmoEmboss::on_set_state() } else if (GLGizmoBase::m_state == GLGizmoBase::On) { if (!m_is_initialized) initialize(); + // to reload fonts from system, when install new one + wxFontEnumerator::InvalidateCache(); + const Selection &selection = m_parent.get_selection(); bool create_new_object = selection.is_empty(); // When add Text on empty plate, Create new object with volume @@ -421,9 +442,9 @@ void GLGizmoEmboss::initialize() // calculate window size const ImGuiStyle &style = ImGui::GetStyle(); - float window_title = line_height + 2*style.FramePadding.y;// 21 - float input_height = line_height_with_spacing + 2*style.FramePadding.y; // 25 - float tree_header = line_height_with_spacing; // 19 + float window_title = line_height + 2*style.FramePadding.y; + float input_height = line_height_with_spacing + 2*style.FramePadding.y; + float tree_header = line_height_with_spacing; float window_height = window_title + // window title cfg.text_size.y + // text field @@ -433,18 +454,20 @@ void GLGizmoEmboss::initialize() float window_width = cfg.combo_font_width + style.WindowPadding.x * 2; cfg.minimal_window_size = ImVec2(window_width, window_height); - // 94 float addition_edit_height = input_height * 3 + tree_header; cfg.minimal_window_size_with_edit = ImVec2(cfg.minimal_window_size.x, cfg.minimal_window_size.y + addition_edit_height); - // 104 float advance_height = input_height * 4; cfg.minimal_window_size_with_advance = ImVec2(cfg.minimal_window_size_with_edit.x, cfg.minimal_window_size_with_edit.y + advance_height); + cfg.min_style_image_height = line_height_with_spacing; + cfg.max_style_image_width = cfg.max_font_name_width - + 2 * style.FramePadding.x; + m_gui_cfg.emplace(cfg); // TODO: What to do when icon was NOT loaded? Generate them? @@ -486,10 +509,9 @@ Slic3r::TriangleMesh GLGizmoEmboss::create_mesh() // It is neccessary to create some shape // Emboss text window is opened by creation new embosstext object std::shared_ptr& font_file = m_font_manager.get_font_file(); - if (font_file == nullptr || m_font_manager.get_fonts().empty()) - return create_default_mesh(); - const FontItem &fi = m_font_manager.get_font_item(); - TriangleMesh result = create_mesh(m_text.c_str(), *font_file, fi.prop); + if (font_file == nullptr) return create_default_mesh(); + const FontItem &fi = m_font_manager.get_font_item(); + TriangleMesh result = create_mesh(m_text.c_str(), *font_file, fi.prop); if (result.its.empty()) return create_default_mesh(); return result; } @@ -637,6 +659,11 @@ void GLGizmoEmboss::draw_window() } } m_imgui->disabled_end(); + +#ifdef SHOW_IMGUI_ATLAS + auto &atlas = m_font_manager.m_imgui_font_atlas; + ImGui::Image(atlas.TexID, ImVec2(atlas.TexWidth, atlas.TexHeight)); +#endif // SHOW_IMGUI_ATLAS } void GLGizmoEmboss::draw_text_input() @@ -644,7 +671,7 @@ void GLGizmoEmboss::draw_text_input() static const ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_AutoSelectAll; - ImFont *imgui_font = m_font_manager.get_imgui_font(); + ImFont *imgui_font = m_font_manager.get_imgui_font(m_text); bool exist_font = imgui_font != nullptr && imgui_font->IsLoaded(); if (exist_font) ImGui::PushFont(imgui_font); @@ -685,26 +712,29 @@ void GLGizmoEmboss::draw_text_input() // Extend font ranges // imgui_font has to be unused - if (exist_change) m_font_manager.get_imgui_font(m_text); + if (exist_change) m_font_manager.clear_imgui_font(); } -#include "wx/fontenum.h" void GLGizmoEmboss::draw_font_list() { class MyFontEnumerator : public wxFontEnumerator { wxArrayString m_facenames; wxFontEncoding m_encoding; + bool m_fixed_width_only; bool m_is_init; public: - MyFontEnumerator(wxFontEncoding encoding) : m_encoding(encoding), m_is_init(false){} + MyFontEnumerator(wxFontEncoding encoding, bool fixed_width_only) + : m_encoding(encoding) + , m_fixed_width_only(fixed_width_only) + , m_is_init(false) + {} const wxArrayString& get_facenames() const{ return m_facenames; } bool is_init() const { return m_is_init; } bool init() { if (m_is_init) return false; m_is_init = true; - bool fixedWidthOnly = false; - if (!wxFontEnumerator::EnumerateFacenames(m_encoding, fixedWidthOnly)) return false; + if (!wxFontEnumerator::EnumerateFacenames(m_encoding, m_fixed_width_only)) return false; if (m_facenames.empty()) return false; return true; } @@ -720,7 +750,9 @@ void GLGizmoEmboss::draw_font_list() } }; wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM; - static MyFontEnumerator fontEnumerator(encoding); + bool fixed_width_only = false; + static MyFontEnumerator fontEnumerator(encoding, fixed_width_only); + std::optional &wx_font_opt = m_font_manager.get_wx_font(); wxString actual_face_name = wx_font_opt.has_value() ? wx_font_opt->GetFaceName() : ""; @@ -729,14 +761,17 @@ void GLGizmoEmboss::draw_font_list() if (ImGui::BeginCombo("##font_selector", selected)) { if(!fontEnumerator.is_init()) fontEnumerator.init(); const wxArrayString &face_names = fontEnumerator.get_facenames(); + //const wxArrayString &face_names = wxFontEnumerator::GetFacenames(encoding, fixed_width_only); ImGui::TextColored(ImGuiWrapper::COL_GREY_LIGHT, "count %d", static_cast(face_names.size())); for (const wxString &face_name : face_names) { size_t index = &face_name - &face_names.front(); ImGui::PushID(index); bool is_selected = (actual_face_name == face_name); - if (ImGui::Selectable(face_name.ToUTF8().data(), is_selected)) { + if (ImGui::Selectable(face_name.ToUTF8().data(), is_selected) && + wxFontEnumerator::IsValidFacename(face_name)) { // Select font - wx_font_opt = wxFont(wxFontInfo().FaceName(face_name).Encoding(encoding)); + wxFont wx_font(wxFontInfo().FaceName(face_name).Encoding(encoding)); + m_font_manager.set_wx_font(wx_font); } ImGui::PopID(); } @@ -820,15 +855,15 @@ void GLGizmoEmboss::draw_model_type() } } -void GLGizmoEmboss::draw_rename_style(const std::optional& rename_index) +void GLGizmoEmboss::draw_rename_style(bool start_rename) { // rename modal window popup const char * rename_popup_id = "Rename_font"; static FontItem * rename_item; static std::string new_name; - if (rename_index.has_value() && !ImGui::IsPopupOpen(rename_popup_id)) { + if (start_rename && !ImGui::IsPopupOpen(rename_popup_id)) { ImGui::OpenPopup(rename_popup_id); - rename_item = &m_font_manager.get_font(*rename_index).font_item; + rename_item = &m_font_manager.get_font_item(); new_name = rename_item->name; // initialize with original copy } @@ -852,65 +887,72 @@ void GLGizmoEmboss::draw_rename_style(const std::optional& rename_index) bool allow_change = is_unique && !new_name.empty(); ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue; - if ((ImGui::InputText("##font name", &new_name, flags) && - allow_change) || + if ((ImGui::InputText("##font name", &new_name, flags) && allow_change) || m_imgui->button(_L("ok"), ImVec2(0.f, 0.f), allow_change)) { rename_item->name = new_name; + m_font_manager.get_truncated_name() = ""; + m_font_manager.free_style_images(); ImGui::CloseCurrentPopup(); - store_font_list_to_app_config(); } ImGui::EndPopup(); } } void GLGizmoEmboss::draw_style_list() { - const float & max_width = m_gui_cfg->max_font_name_width; - std::optional rename_index, delete_index, duplicate_index; - - const FontItem & actual_font_item = m_font_manager.get_font_item(); - const std::string ¤t_name = actual_font_item.name; - std::string trunc_name = ImGuiWrapper::trunc(current_name, max_width); - const auto &fonts = m_font_manager.get_fonts(); + const float &max_width = m_gui_cfg->max_font_name_width; + std::optional delete_index; + const FontItem &actual_font_item = m_font_manager.get_font_item(); + std::string &trunc_name = m_font_manager.get_truncated_name(); + if (trunc_name.empty()) { + // generate trunc name + const std::string ¤t_name = actual_font_item.name; + trunc_name = ImGuiWrapper::trunc(current_name, max_width); + } ImGui::Text("%s", _u8L("Style").c_str()); ImGui::SameLine(); ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width); if (ImGui::BeginCombo("##style_selector", trunc_name.c_str())) { + m_font_manager.init_style_images(m_gui_cfg->max_style_image_width); + const auto &fonts = m_font_manager.get_fonts(); for (const auto &item : fonts) { size_t index = &item - &fonts.front(); const FontItem & fi = item.font_item; const std::string &actual_style_name = fi.name; ImGui::PushID(actual_style_name.c_str()); - std::string name_truncated = ImGuiWrapper::trunc(actual_style_name, - max_width); + std::string name_truncated = + ImGuiWrapper::trunc(actual_style_name, max_width); - bool is_selected = (&fi == &actual_font_item); + bool is_selected = (&fi == &actual_font_item); ImGuiSelectableFlags_ flags = ImGuiSelectableFlags_AllowItemOverlap; // allow click buttons - if (ImGui::Selectable(name_truncated.c_str(), is_selected, - flags)) { + + const FontManager::StyleImage &img = *item.image; + ImVec2 select_size(0.f, std::max(img.tex_size.y, m_gui_cfg->min_style_image_height)); + if (ImGui::Selectable("##style_select", is_selected, flags, select_size)) { if (m_font_manager.load_font(index)) process(); } else if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", actual_style_name.c_str()); // reorder items if (ImGui::IsItemActive() && !ImGui::IsItemHovered()) { - int other_index = index + - (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : - 1); - if (other_index >= 0 && other_index < fonts.size()) { - std::swap(m_font_manager.get_font(index), - m_font_manager.get_font(other_index)); - // fix selected index - if (is_selected) - m_font_manager.select(other_index); - else if (&fonts[other_index].font_item == - &actual_font_item) - m_font_manager.select(index); + std::optional other_index; + if (ImGui::GetMouseDragDelta(0).y < 0.f) { + if (index > 0) other_index = index - 1; + } else if ((index + 1) < fonts.size()) + other_index = index + 1; + + if (other_index.has_value()) { + m_font_manager.swap(index, *other_index); ImGui::ResetMouseDragDelta(); } } + // draw style name + ImGui::SameLine(); + ImGui::Image(img.texture_id, img.tex_size, img.uv0, img.uv1); + + // delete button ImGui::SameLine(m_gui_cfg->delete_pos_x); if (draw_button(IconType::erase, is_selected) && !is_selected) delete_index = index; @@ -924,39 +966,34 @@ void GLGizmoEmboss::draw_style_list() { } ImGui::EndCombo(); } - + + // delete font item + if (delete_index.has_value()) + m_font_manager.erase(*delete_index); + ImGui::SameLine(); - if (draw_button(IconType::rename)) - rename_index = &m_font_manager.get_font() - &fonts.front(); + bool start_rename = false; + if (draw_button(IconType::rename)) start_rename = true; if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Rename actual style.").c_str()); + draw_rename_style(start_rename); ImGui::SameLine(); if (draw_button(IconType::duplicate)) - duplicate_index = &m_font_manager.get_font() - &fonts.front(); + m_font_manager.duplicate(); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", _u8L("Duplicate style.").c_str()); - - // duplicate font item - if (duplicate_index.has_value()) { - m_font_manager.duplicate(*duplicate_index); - store_font_list_to_app_config(); - } - - // delete font item - if (delete_index.has_value()) { - m_font_manager.erase(*delete_index); - store_font_list_to_app_config(); - } - - draw_rename_style(rename_index); + // TODO: Is style changed against stored one bool is_changed = false; ImGui::SameLine(); if (draw_button(IconType::save, !is_changed)) { - // TODO: make save style + // TODO: make save style + store_font_list_to_app_config(); + //store_font_item_to_app_config(); } if (ImGui::IsItemHovered()) if (is_changed) @@ -976,14 +1013,13 @@ void GLGizmoEmboss::draw_style_list() { bool GLGizmoEmboss::italic_button() { - FontManager::Item& item = m_font_manager.get_font(); - std::optional &wx_font = item.wx_font; + std::optional &wx_font = m_font_manager.get_wx_font(); if (!wx_font.has_value()) { draw_icon(IconType::italic, IconState::disabled); return false; } - std::optional &skew = item.font_item.prop.skew; + std::optional &skew = m_font_manager.get_font_prop().skew; bool is_font_italic = skew.has_value() || WxFontUtils::is_italic(*wx_font); if (is_font_italic) { if (draw_button(IconType::unitalic)) { @@ -995,7 +1031,8 @@ bool GLGizmoEmboss::italic_button() ImGui::SetTooltip("%s", _u8L("Unset italic").c_str()); } else { if (draw_button(IconType::italic)) { - std::shared_ptr &font_file = item.font_file; + std::shared_ptr &font_file = + m_font_manager.get_font_file(); bool is_set = WxFontUtils::set_italic(*wx_font, font_file); // add skew when wxFont can't set it if (!is_set) skew = 0.2f; @@ -1008,14 +1045,13 @@ bool GLGizmoEmboss::italic_button() } bool GLGizmoEmboss::bold_button() { - FontManager::Item & item = m_font_manager.get_font(); - std::optional &wx_font = item.wx_font; + std::optional &wx_font = m_font_manager.get_wx_font(); if (!wx_font.has_value()) { draw_icon(IconType::bold, IconState::disabled); return false; } - std::optional &boldness = item.font_item.prop.boldness; + std::optional &boldness = m_font_manager.get_font_prop().boldness; bool is_font_bold = boldness.has_value() || WxFontUtils::is_bold(*wx_font); if (is_font_bold) { if (draw_button(IconType::unbold)) { @@ -1027,7 +1063,8 @@ bool GLGizmoEmboss::bold_button() { ImGui::SetTooltip("%s", _u8L("Unset bold").c_str()); } else { if (draw_button(IconType::bold)) { - std::shared_ptr &font_file = item.font_file; + std::shared_ptr &font_file = + m_font_manager.get_font_file(); bool is_set = WxFontUtils::set_bold(*wx_font, font_file); // add boldness when wxFont can't set it if (!is_set) boldness = 20.f; @@ -1051,22 +1088,24 @@ void GLGizmoEmboss::draw_style_edit() { ImGui::SameLine(); exist_change |= bold_button(); - FontManager::Item &item = m_font_manager.get_font(); - FontItem & fi = item.font_item; - std::optional &wx_font = item.wx_font; + FontItem &fi = m_font_manager.get_font_item(); + std::optional &wx_font = m_font_manager.get_wx_font(); // TODO: should not be there // when actual font not loaded try to load if (!wx_font.has_value() && fi.type == WxFontUtils::get_actual_type()) wx_font = WxFontUtils::load_wxFont(fi.path); - FontProp &font_prop = fi.prop; + FontProp &font_prop = fi.prop; ImGui::Text("%s", tr.size.c_str()); ImGui::SameLine(m_gui_cfg->style_edit_text_width); ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width); if (ImGui::InputFloat("##line height", &font_prop.size_in_mm, 0.1f, 1.f, "%.1f mm")) { - if (font_prop.size_in_mm < 0.1) font_prop.size_in_mm = 10; + // size can't be zero or negative + if (font_prop.size_in_mm < std::numeric_limits::epsilon()) + font_prop.size_in_mm = 10.f; + // store font size into path if (fi.type == WxFontUtils::get_actual_type()) { if (wx_font.has_value()) { @@ -1075,13 +1114,11 @@ void GLGizmoEmboss::draw_style_edit() { fi.path = WxFontUtils::store_wxFont(*wx_font); } } - m_font_manager.load_imgui_font(m_text); exist_change = true; } if (exist_change) { - std::shared_ptr &font_file = item.font_file; - font_file->cache.clear(); - store_font_item_to_app_config(); + m_font_manager.clear_imgui_font(); + m_font_manager.free_style_images(); process(); } @@ -1109,14 +1146,13 @@ void GLGizmoEmboss::draw_advanced() return; } - FontItem &fi = m_font_manager.get_font_item(); - FontProp &font_prop = fi.prop; - bool exist_change = false; + FontProp &font_prop = m_font_manager.get_font_item().prop; + bool exist_change = false; ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width); if (ImGuiWrapper::input_optional_int(_u8L("CharGap[in font points]").c_str(), font_prop.char_gap)) { - font_file->cache.clear(); - m_font_manager.load_imgui_font(m_text); + // char gap is stored inside of imgui font atlas + m_font_manager.clear_imgui_font(); exist_change = true; } @@ -1125,28 +1161,24 @@ void GLGizmoEmboss::draw_advanced() exist_change = true; ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width); - if (m_imgui->slider_optional_float(_u8L("Boldness [in font points]").c_str(), font_prop.boldness, -200.f, 200.f, "%.0f", 1.f, false, _L("tiny / wide chars"))){ - font_file->cache.clear(); + if (m_imgui->slider_optional_float(_u8L("Boldness [in font points]").c_str(), font_prop.boldness, -200.f, 200.f, "%.0f", 1.f, false, _L("tiny / wide chars"))) exist_change = true; - } + ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width); - if (m_imgui->slider_optional_float(_u8L("Italic [Skew ratio]").c_str(), font_prop.skew, -1.f, 1.f, "%.2f", 1.f, false, _L("italic strength"))){ - font_file->cache.clear(); + if (m_imgui->slider_optional_float(_u8L("Italic [Skew ratio]").c_str(), font_prop.skew, -1.f, 1.f, "%.2f", 1.f, false, _L("italic strength"))) exist_change = true; - } - + // when more collection add selector - if (font_file != nullptr && font_file->count > 1) { + if (font_file->count > 1) { ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width); if (ImGui::BeginCombo(_u8L("Font collection").c_str(), std::to_string(font_file->index).c_str())) { for (unsigned int i = 0; i < font_file->count; ++i) { ImGui::PushID(1 << (10 + i)); - if (ImGui::Selectable(std::to_string(i).c_str(), - i == font_file->index)) { + bool is_selected = i == font_file->index; + if (ImGui::Selectable(std::to_string(i).c_str(), is_selected)) { font_file->index = i; - font_file->cache.clear(); exist_change = true; } ImGui::PopID(); @@ -1156,12 +1188,9 @@ void GLGizmoEmboss::draw_advanced() } if (exist_change) { - store_font_item_to_app_config(); + m_font_manager.free_style_images(); process(); } - - auto& atlas = m_font_manager.m_imgui_font_atlas; - ImGui::Image(atlas.TexID, ImVec2(atlas.TexWidth, atlas.TexHeight)); #ifdef ALLOW_DEBUG_MODE ImGui::Text("family = %s", (font_prop.family.has_value() ? font_prop.family->c_str() : @@ -1275,9 +1304,10 @@ bool GLGizmoEmboss::choose_true_type_file() // set first valid added font as active if (!font_loaded) { - if (!m_font_manager.load_font(m_font_manager.get_fonts().size() - 1)) { - //m_font_list.pop_back(); - } else + size_t index = m_font_manager.get_fonts().size() - 1; + if (!m_font_manager.load_font(index)) + m_font_manager.erase(index); + else font_loaded = true; } } @@ -1321,6 +1351,13 @@ bool GLGizmoEmboss::choose_svg_file() TextConfiguration GLGizmoEmboss::create_configuration() { + FontItem &fi = m_font_manager.get_font_item(); + // actualize font path + if (fi.type == WxFontUtils::get_actual_type()) { + std::optional &wx_font = m_font_manager.get_wx_font(); + if (wx_font.has_value()) + fi.path = WxFontUtils::store_wxFont(*wx_font); + } return TextConfiguration(m_font_manager.get_font_item(), m_text); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 35d13ad5f0..dffd127f25 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -103,7 +103,7 @@ private: void draw_text_input(); void draw_model_type(); void draw_style_list(); - void draw_rename_style(const std::optional& rename_index); + void draw_rename_style(bool start_rename); void draw_font_list(); void draw_style_edit(); bool italic_button(); @@ -146,6 +146,9 @@ private: float delete_pos_x = 0.f; float max_font_name_width = 0.f; float icon_width = 0.f; + + float min_style_image_height = 0.f; + int max_style_image_width = 0.f; float style_edit_text_width = 0.f; diff --git a/src/slic3r/Utils/FontManager.cpp b/src/slic3r/Utils/FontManager.cpp index 7252a8f63d..70a7f6b1b0 100644 --- a/src/slic3r/Utils/FontManager.cpp +++ b/src/slic3r/Utils/FontManager.cpp @@ -10,19 +10,29 @@ using namespace Slic3r; using namespace Slic3r::GUI; FontManager::FontManager(const ImWchar *language_glyph_range) - : m_imgui_init_glyph_range(language_glyph_range), m_font_selected(0) + : m_imgui_init_glyph_range(language_glyph_range) + , m_font_selected(std::numeric_limits::max()) + , m_exist_style_images(false) {} FontManager::~FontManager() { - free_imgui_fonts(); + free_imgui_fonts(); + free_style_images(); } -void FontManager::select(size_t index) -{ - if (index < m_font_list.size()) - m_font_selected = index; +void FontManager::swap(size_t i1, size_t i2) { + if (i1 >= m_font_list.size() && + i2 >= m_font_list.size()) return; + std::swap(m_font_list[i1], m_font_list[i2]); + // fix selected index + if (!is_activ_font()) return; + if (m_font_selected == i1) + m_font_selected = i2; + else if (m_font_selected == i2) + m_font_selected = i1; } +void FontManager::duplicate() { duplicate(m_font_selected); } void FontManager::duplicate(size_t index) { if (index >= m_font_list.size()) return; Item item = m_font_list[index]; // copy @@ -35,6 +45,7 @@ void FontManager::duplicate(size_t index) { m_font_list.insert(m_font_list.begin() + index, item); // fix selected index + if (!is_activ_font()) return; if (index < m_font_selected) ++m_font_selected; } @@ -46,7 +57,9 @@ void FontManager::erase(size_t index) { IM_DELETE(imgui_font); m_font_list.erase(m_font_list.begin() + index); + // fix selected index + if (!is_activ_font()) return; if (index < m_font_selected) --m_font_selected; } @@ -54,7 +67,7 @@ bool FontManager::load_font(size_t font_index) { if (font_index >= m_font_list.size()) return false; std::swap(font_index, m_font_selected); - bool is_loaded = load_font(); + bool is_loaded = load_activ_font(); if (!is_loaded) std::swap(font_index, m_font_selected); return is_loaded; } @@ -62,9 +75,8 @@ bool FontManager::load_font(size_t font_index) bool FontManager::load_font(size_t font_index, const wxFont &font) { if (font_index >= m_font_list.size()) return false; - m_font_list[font_index].wx_font = font; std::swap(font_index, m_font_selected); - bool is_loaded = load_font(font); + bool is_loaded = set_wx_font(font); if (!is_loaded) std::swap(font_index, m_font_selected); return is_loaded; } @@ -78,44 +90,22 @@ static std::string get_file_name(const std::string &file_path) return file_path.substr(offset, count); } -bool FontManager::load_font() -{ - // next condition may be safely removed - if (m_font_selected >= m_font_list.size()) return false; +bool FontManager::load_activ_font() +{ + return set_up_font_file(m_font_selected); +} - Item &item = m_font_list[m_font_selected]; - FontItem &fi = item.font_item; - if (fi.type == FontItem::Type::file_path) { - // fill font name after load from .3mf - if (fi.name.empty()) - fi.name = get_file_name(fi.path); - std::unique_ptr font_ptr = Emboss::load_font( - fi.path.c_str()); - if (font_ptr == nullptr) return false; - item.font_file = std::move(font_ptr); - load_imgui_font(); - return true; - } - if (fi.type != WxFontUtils::get_actual_type()) return false; - item.wx_font = WxFontUtils::load_wxFont(fi.path); - if (!item.wx_font.has_value()) return false; - - // fill font name after load from .3mf - if (fi.name.empty()) - fi.name = WxFontUtils::get_human_readable_name(*item.wx_font); - return load_font(*item.wx_font); +bool FontManager::is_activ_font() { + return m_font_selected < m_font_list.size(); } bool FontManager::load_first_valid_font() { - // try to load valid font - m_font_selected = 0; - bool is_font_loaded = load_font(); - while (!is_font_loaded && !m_font_list.empty()) { + while (!m_font_list.empty()) { + if (load_font(0)) return true; // can't load so erase it from list m_font_list.erase(m_font_list.begin()); - is_font_loaded = load_font(); } - return !m_font_list.empty(); + return false; } void FontManager::add_font(FontItem font_item) @@ -135,25 +125,28 @@ void FontManager::add_fonts(FontList font_list) std::shared_ptr &FontManager::get_font_file() { // TODO: fix not selected font - //if (m_font_selected >= m_font_list.size()) return nullptr; + //if (!is_activ_font()) return nullptr; return m_font_list[m_font_selected].font_file; } const FontItem &FontManager::get_font_item() const { // TODO: fix not selected font + //if (!is_activ_font()) return nullptr; return m_font_list[m_font_selected].font_item; } FontItem &FontManager::get_font_item() { // TODO: fix not selected font + //if (!is_activ_font()) return nullptr; return m_font_list[m_font_selected].font_item; } const FontProp &FontManager::get_font_prop() const { // TODO: fix not selected font + //if (!is_activ_font()) return nullptr; return m_font_list[m_font_selected].font_item.prop; } @@ -165,7 +158,26 @@ FontProp &FontManager::get_font_prop() std::optional &FontManager::get_wx_font() { + //if (!is_activ_font()) return {}; return m_font_list[m_font_selected].wx_font; + + //std::optional &wx_font = m_font_list[m_font_selected].wx_font; + //if (wx_font.has_value()) return wx_font; + + //const FontItem &fi = get_font_item(); + //if (fi.type != WxFontUtils::get_actual_type()) return {}; + + //wx_font = WxFontUtils::load_wxFont(fi.path); + //return wx_font; +} + +bool FontManager::set_wx_font(const wxFont &wx_font) { + return set_wx_font(m_font_selected, wx_font); +} + +std::string &FontManager::get_truncated_name() +{ + return m_font_list[m_font_selected].truncated_name; } const std::optional &FontManager::get_wx_font() const @@ -173,19 +185,27 @@ const std::optional &FontManager::get_wx_font() const return m_font_list[m_font_selected].wx_font; } +void FontManager::clear_imgui_font() { + // TODO: improove to clear only actual font + free_imgui_fonts(); + return; + ImFont *imgui_font = get_imgui_font(m_font_selected); + m_font_list[m_font_selected].imgui_font_index.reset(); + if (imgui_font != nullptr) IM_DELETE(imgui_font); +} + ImFont *FontManager::get_imgui_font(const std::string &text) { return get_imgui_font(m_font_selected, text); } ImFont *FontManager::get_imgui_font(size_t item_index, const std::string &text) -{ - // is selected font - if (item_index >= m_font_list.size()) return nullptr; - +{ Item &item = m_font_list[item_index]; // check is already loaded - if (!item.imgui_font_index.has_value()) return nullptr; + if (!item.imgui_font_index.has_value()) + return load_imgui_font(item_index, text); + size_t index = *item.imgui_font_index; auto & fonts = m_imgui_font_atlas.Fonts; @@ -194,7 +214,7 @@ ImFont *FontManager::get_imgui_font(size_t item_index, const std::string &text) if (index >= fonts.size()) return nullptr; ImFont *font = fonts[index]; if (font == nullptr) return nullptr; - + if (!font->IsLoaded()) return nullptr; if (!text.empty() && !is_text_in_ranges(font, text)) extend_imgui_font_range(item_index, text); @@ -217,32 +237,13 @@ const std::vector &FontManager::get_fonts() const return m_font_list; } -std::vector &FontManager::get_fonts() -{ - return m_font_list; -} - const FontManager::Item &FontManager::get_font() const { return m_font_list[m_font_selected]; } -FontManager::Item &FontManager::get_font() +void FontManager::make_unique_name(std::string &name) { - return m_font_list[m_font_selected]; -} - -FontManager::Item &FontManager::get_font(size_t index) -{ - return m_font_list[index]; -} - -const FontManager::Item &FontManager::get_font(size_t index) const -{ - return m_font_list[index]; -} - -void FontManager::make_unique_name(std::string &name) { auto is_unique = [&](const std::string &name) -> bool { for (const Item &it : m_font_list) if (it.font_item.name == name) return false; @@ -266,6 +267,26 @@ void FontManager::make_unique_name(std::string &name) { name = new_name; } +bool FontManager::set_up_font_file(size_t item_index) +{ + Item &item = m_font_list[item_index]; + FontItem &fi = item.font_item; + if (fi.type == FontItem::Type::file_path) { + // fill font name after load from .3mf + if (fi.name.empty()) fi.name = get_file_name(fi.path); + std::unique_ptr font_ptr = Emboss::load_font( + fi.path.c_str()); + if (font_ptr == nullptr) return false; + item.font_file = std::move(font_ptr); + return true; + } + if (fi.type != WxFontUtils::get_actual_type()) return false; + if (!item.wx_font.has_value()) + item.wx_font = WxFontUtils::load_wxFont(fi.path); + if (!item.wx_font.has_value()) return false; + return set_wx_font(item_index, *item.wx_font); +} + bool FontManager::is_text_in_ranges(const ImFont *font, const std::string &text) { if (font == nullptr) return false; @@ -312,6 +333,162 @@ void FontManager::extend_imgui_font_range(size_t index, const std::string& text) load_imgui_font(index, text); } +#include "libslic3r/SLA/AGGRaster.hpp" +void FontManager::create_texture(size_t index, const std::string &text, GLuint& tex_id, ImVec2& tex_size) +{ + if (index >= m_font_list.size()) return; + Item &item = m_font_list[index]; + const FontProp &font_prop = item.font_item.prop; + std::shared_ptr &font_file = item.font_file; + if (font_file == nullptr && !set_up_font_file(index)) return; + ExPolygons shapes = Emboss::text2shapes(*font_file, text.c_str(), font_prop); + + BoundingBox bb; + for (ExPolygon &shape : shapes) bb.merge(BoundingBox(shape.contour.points)); + for (ExPolygon &shape : shapes) shape.translate(-bb.min); + + double scale = font_prop.size_in_mm; + BoundingBoxf bb2 = unscaled(bb); + bb2.scale(scale); + tex_size.x = bb2.max.x() - bb2.min.x(); + tex_size.y = bb2.max.y() - bb2.min.y(); + sla::RasterBase::Resolution resolution(tex_size.x,tex_size.y); + sla::RasterBase::PixelDim dim(1/scale, 1/scale); + const double no_gamma = 1.; + std::unique_ptr r = + sla::create_raster_grayscale_aa(resolution, dim, no_gamma); + for (const ExPolygon &shape : shapes) r->draw(shape); + // reserve texture on GPU + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + sla::RasterEncoder encoder = [](const void *ptr, size_t w, size_t h, size_t num_components) -> sla::EncodedRaster { + GLsizei width = w, height = h; + GLint border = 0; + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, border, GL_ALPHA, GL_UNSIGNED_BYTE, ptr); + return sla::EncodedRaster(); + }; + r->encode(encoder); + glBindTexture(GL_TEXTURE_2D, 0); +} + +void FontManager::init_style_images(int max_width) { + // check already initialized + if (m_exist_style_images) return; + + // create shapes and calc size (bounding boxes) + std::vector name_shapes(m_font_list.size()); + for (Item &item : m_font_list) { + FontItem & font_item = item.font_item; + const FontProp & font_prop = font_item.prop; + std::shared_ptr &font_file = item.font_file; + size_t index = &item - &m_font_list.front(); + if (font_file == nullptr && !set_up_font_file(index)) continue; + if (font_file == nullptr) continue; + + ExPolygons &shapes = name_shapes[index]; + shapes = Emboss::text2shapes(*font_file, font_item.name.c_str(), font_prop); + // create image description + item.image = StyleImage(); + StyleImage &image = *item.image; + + BoundingBox &bounding_box = image.bounding_box; + for (ExPolygon &shape : shapes) + bounding_box.merge(BoundingBox(shape.contour.points)); + for (ExPolygon &shape : shapes) shape.translate(-bounding_box.min); + + double scale = font_prop.size_in_mm; + BoundingBoxf bb2 = unscaled(bounding_box); + bb2.scale(scale); + image.tex_size.x = bb2.max.x() - bb2.min.x(); + image.tex_size.y = bb2.max.y() - bb2.min.y(); + // crop image width + if (image.tex_size.x > max_width) + image.tex_size.x = max_width; + } + + // arrange bounding boxes + int offset_y = 0; + int width = 0; + for (Item &item : m_font_list) { + StyleImage &image = *item.image; + image.offset.y() = offset_y; + offset_y += image.tex_size.y+1; + if (width < image.tex_size.x) + width = image.tex_size.x; + } + int height = offset_y; + for (Item &item : m_font_list) { + StyleImage &image = *item.image; + const Point &o = image.offset; + const ImVec2 &s = image.tex_size; + image.uv0 = ImVec2(o.x() / (double) width, + o.y() / (double) height); + image.uv1 = ImVec2((o.x() + s.x) / (double) width, + (o.y() + s.y) / (double) height); + } + + // reserve texture on GPU + GLuint tex_id; + GLenum target = GL_TEXTURE_2D, format = GL_ALPHA, type = GL_UNSIGNED_BYTE; + GLint level = 0, border = 0; + glsafe(::glGenTextures(1, &tex_id)); + glsafe(::glBindTexture(target, tex_id)); + glsafe(::glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(::glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + // texture size + GLint w = width, h = height; + glsafe(::glTexImage2D(target, level, GL_ALPHA, w, h, border, format, type, nullptr)); + + // set up texture id + void *texture_id = (void *)(intptr_t) tex_id; + for (Item &item : m_font_list) item.image->texture_id = texture_id; + + // upload sub textures + for (Item &item : m_font_list) { + double scale = item.font_item.prop.size_in_mm; + StyleImage &image = *item.image; + sla::RasterBase::Resolution resolution(image.tex_size.x, image.tex_size.y); + sla::RasterBase::PixelDim dim(1 / scale, 1 / scale); + double gamma = 1.; + std::unique_ptr r = sla::create_raster_grayscale_aa(resolution, dim, gamma); + size_t index = &item - &m_font_list.front(); + for (const ExPolygon &shape : name_shapes[index]) r->draw(shape); + const Point& offset = image.offset; + sla::RasterEncoder encoder = + [offset, target, level, format, type] + (const void *ptr, size_t w, size_t h, size_t num_components) { + GLint sub_w = w, sub_h = h, xoffset = offset.x(), yoffset = offset.y(); + glsafe(::glTexSubImage2D(target, level, xoffset, yoffset, sub_w, sub_h, format, type, ptr)); + return sla::EncodedRaster(); + }; + // upload texture data to GPU + r->encode(encoder); + } + + // bind default texture + GLuint no_texture_id = 0; + glsafe(::glBindTexture(target, no_texture_id)); + + m_exist_style_images = true; +} + +void FontManager::free_style_images() { + std::shared_ptr &font_file = + m_font_list[m_font_selected].font_file; + if(font_file != nullptr) + font_file->cache.clear(); + + if (!m_exist_style_images) return; + GLuint tex_id = (GLuint) (intptr_t) m_font_list.front().image->texture_id; + for (Item &it : m_font_list) it.image.reset(); + + glsafe(::glDeleteTextures(1, &tex_id)); + m_exist_style_images = false; +} + + void FontManager::free_imgui_fonts() { for (auto &item : m_font_list) @@ -319,26 +496,13 @@ void FontManager::free_imgui_fonts() m_imgui_font_atlas.Clear(); } -bool FontManager::load_font(const wxFont &font) -{ - std::unique_ptr font_ptr = WxFontUtils::load_font(font); - if (font_ptr == nullptr) return false; - m_font_list[m_font_selected].font_file = std::move(font_ptr); - load_imgui_font(); - return true; -} - -void FontManager::load_imgui_font(const std::string &text) { - load_imgui_font(m_font_selected, text); -} - -void FontManager::load_imgui_font(size_t index, const std::string &text) +ImFont * FontManager::load_imgui_font(size_t index, const std::string &text) { free_imgui_fonts(); // TODO: remove it after correct initialization - if (index >= m_font_list.size()) return; + if (index >= m_font_list.size()) return nullptr; Item &item = m_font_list[index]; - if (item.font_file == nullptr) return; + if (item.font_file == nullptr) return nullptr; const Emboss::FontFile &font_file = *item.font_file; // TODO: Create glyph range @@ -399,6 +563,27 @@ void FontManager::load_imgui_font(size_t index, const std::string &text) // Store our identifier m_imgui_font_atlas.TexID = (ImTextureID) (intptr_t) font_texture; assert(!m_imgui_font_atlas.Fonts.empty()); - if (m_imgui_font_atlas.Fonts.empty()) return; + if (m_imgui_font_atlas.Fonts.empty()) return nullptr; item.imgui_font_index = m_imgui_font_atlas.Fonts.size() - 1; + return m_imgui_font_atlas.Fonts.back(); +} + +bool FontManager::set_wx_font(size_t item_index, const wxFont &wx_font) { + std::unique_ptr font_file = + WxFontUtils::create_font_file(wx_font); + if (font_file == nullptr) return false; + + Item &item = m_font_list[item_index]; + item.font_file = std::move(font_file); + item.wx_font = wx_font; + + FontItem &fi = item.font_item; + fi.type = WxFontUtils::get_actual_type(); + + // fill font name after load from .3mf + if (fi.name.empty()) + fi.name = WxFontUtils::get_human_readable_name(*item.wx_font); + + clear_imgui_font(); + return true; } diff --git a/src/slic3r/Utils/FontManager.hpp b/src/slic3r/Utils/FontManager.hpp index 82b125218b..ccae1a8932 100644 --- a/src/slic3r/Utils/FontManager.hpp +++ b/src/slic3r/Utils/FontManager.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "libslic3r/Emboss.hpp" class wxFont; @@ -13,6 +14,7 @@ namespace Slic3r::GUI { /// GUI list of loaded fonts /// Keep pointer to ImGui font pointers /// Keep file data of TTF files +/// Cache wx font objects /// class FontManager { @@ -20,21 +22,41 @@ public: FontManager(const ImWchar *language_glyph_range); ~FontManager(); - void select(size_t index); - void duplicate(size_t index); + /// + /// Change order of style item in m_font_list. + /// Fix selected font index when (i1 || i2) == m_font_selected + /// + /// First index to m_font_list + /// Second index to m_font_list + void swap(size_t i1, size_t i2); + + /// + /// Duplicate selected font style + /// + void duplicate(); + + /// + /// Remove style from m_font_list. + /// Fix selected font index when index is under m_font_selected + /// + /// Index of style to be removed void erase(size_t index); - // load actual selected font - bool load_font(); - // try to select and load font_index + /// + /// Change active font + /// When font not loaded roll back activ font + /// + /// New font index(from m_font_list range) + /// True on succes. False on fail load font bool load_font(size_t font_index); - // fastering load font on index by wxFont + // fastering load font on index by wxFont, ignore type and descriptor bool load_font(size_t font_index, const wxFont &font); - void load_imgui_font(const std::string &text = ""); - void load_imgui_font(size_t index, const std::string &text); + // remove cached imgui font for actual selected font + void clear_imgui_font(); // 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(); // add font into manager @@ -57,33 +79,48 @@ public: const std::optional &get_wx_font() const; std::optional &get_wx_font(); - // getter on acitve font pointer for imgui - // text could extend font atlas when not in glyph range - ImFont *get_imgui_font(const std::string &text = ""); + // setter of font for actual selection + bool set_wx_font(const wxFont &wx_font); - // getter on index selected font pointer for imgui - // text could extend font atlas when not in glyph range - ImFont *get_imgui_font(size_t item_index, const std::string &text = ""); + // Getter for cached trucated name for style list selector + std::string &get_truncated_name(); + + // Getter on acitve font pointer for imgui + // Initialize imgui font(generate texture) when doesn't exist yet. + // Extend font atlas when not in glyph range + ImFont *get_imgui_font(const std::string &text); // free used memory and font file data void free_except_active_font(); + /// + /// initialization texture with rendered font style + /// + void init_style_images(int max_width); + void free_style_images(); + + void create_texture(size_t font_index, const std::string &text, GLuint& tex_id, ImVec2& tex_size); + struct Item; // access to all managed fonts const std::vector &get_fonts() const; - - std::vector &get_fonts(); const Item &get_font() const; - Item &get_font(); - const Item &get_font(size_t index) const; - Item &get_font(size_t index); + + struct StyleImage + { + void* texture_id = 0; // GLuint + BoundingBox bounding_box; + ImVec2 tex_size, uv0, uv1; + Point offset = Point(0, 0); + StyleImage() = default; + }; struct Item { - FontItem font_item; + FontItem font_item; // cache for view font name with maximal width in imgui - std::string truncated_name; + std::string truncated_name; // share font file data with emboss job thread std::shared_ptr font_file = nullptr; @@ -95,12 +132,29 @@ public: // wx widget font std::optional wx_font; + + // visualization of style + std::optional image; }; // TODO: make private ImFontAtlas m_imgui_font_atlas; + bool is_activ_font(); + private: + void duplicate(size_t index); + // load actual selected font + ImFont *load_imgui_font(size_t index, const std::string &text); + + bool load_activ_font(); + + bool set_wx_font(size_t item_index, const wxFont &wx_font); + + // getter on index selected font pointer for imgui + // text could extend font atlas when not in glyph range + ImFont *get_imgui_font(size_t item_index, const std::string &text = ""); + // extend actual imgui font when exist unknown char in text // NOTE: imgui_font has to be unused void extend_imgui_font_range(size_t font_index, const std::string &text); @@ -121,8 +175,7 @@ private: int max_imgui_font_size = 60; } m_cfg; - // load actual font by wx font - bool load_font(const wxFont &font); + bool set_up_font_file(size_t item_index); void make_unique_name(std::string &name); @@ -130,6 +183,8 @@ private: std::vector m_font_list; size_t m_font_selected; // index to m_font_list + bool m_exist_style_images; + // store all font GLImages //ImFontAtlas m_imgui_font_atlas; const ImWchar *m_imgui_init_glyph_range; diff --git a/src/slic3r/Utils/WxFontUtils.cpp b/src/slic3r/Utils/WxFontUtils.cpp index c34a9e6aed..e2abd7c61b 100644 --- a/src/slic3r/Utils/WxFontUtils.cpp +++ b/src/slic3r/Utils/WxFontUtils.cpp @@ -30,7 +30,7 @@ void *WxFontUtils::can_load(const wxFont &font) return nullptr; } -std::unique_ptr WxFontUtils::load_font(const wxFont &font) +std::unique_ptr WxFontUtils::create_font_file(const wxFont &font) { #ifdef _WIN32 return Emboss::load_font(font.GetHFONT()); @@ -246,11 +246,11 @@ bool WxFontUtils::set_italic(wxFont &font, std::shared_ptr& fo wxFontStyle::wxFONTSTYLE_SLANT }; if (font_file == nullptr) - font_file = WxFontUtils::load_font(font); + font_file = WxFontUtils::create_font_file(font); for (wxFontStyle style : italic_styles) { font.SetStyle(style); - std::unique_ptr act_font_file = WxFontUtils::load_font(font); + std::unique_ptr act_font_file = WxFontUtils::create_font_file(font); if (act_font_file == nullptr) continue; // is still same font file pointer? @@ -272,11 +272,11 @@ bool WxFontUtils::set_bold(wxFont &font, std::shared_ptr& font wxFontWeight::wxFONTWEIGHT_EXTRAHEAVY }; if (font_file == nullptr) - font_file = WxFontUtils::load_font(font); + font_file = WxFontUtils::create_font_file(font); for (wxFontWeight weight : bold_weight) { font.SetWeight(weight); - std::unique_ptr act_font_file = WxFontUtils::load_font(font); + std::unique_ptr act_font_file = WxFontUtils::create_font_file(font); if (act_font_file == nullptr) continue; if (font_file != nullptr) // is still same font? diff --git a/src/slic3r/Utils/WxFontUtils.hpp b/src/slic3r/Utils/WxFontUtils.hpp index 1f5cc56486..a59c55d54d 100644 --- a/src/slic3r/Utils/WxFontUtils.hpp +++ b/src/slic3r/Utils/WxFontUtils.hpp @@ -20,7 +20,7 @@ public: static void *can_load(const wxFont &font); // os specific load of wxFont - static std::unique_ptr load_font(const wxFont &font); + static std::unique_ptr create_font_file(const wxFont &font); static FontItem::Type get_actual_type(); static FontItem get_font_item(const wxFont &font);