From 7d1de0113a1464f0721e3801f11acba1239d8269 Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Tue, 12 Oct 2021 19:19:09 +0200 Subject: [PATCH] Show multi line text box with selected font, add letter --- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 100 +++++++++++++++++++++--- src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp | 23 ++++-- src/slic3r/GUI/ImGuiWrapper.cpp | 2 +- src/slic3r/GUI/ImGuiWrapper.hpp | 3 +- 4 files changed, 108 insertions(+), 20 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 8171a83574..aa47ba9220 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -173,6 +173,9 @@ void GLGizmoEmboss::initialize() m_gui_cfg->delete_pos_x = m_gui_cfg->rename_pos_x + m_gui_cfg->icon_width_with_spacing; + m_gui_cfg->text_size = + ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * m_gui_cfg->count_line_of_text); + // TODO: What to do when icon was NOT loaded? bool success = init_icons(); @@ -381,7 +384,6 @@ void GLGizmoEmboss::draw_window() if (!m_font.has_value()) { ImGui::Text(_L("Warning: No font is selected. Select correct one.").c_str()); } - if (ImGui::Button("process")) process(); draw_font_list(); //ImGui::SameLine(); @@ -396,16 +398,7 @@ void GLGizmoEmboss::draw_window() //if (ImGui::Button("add svg")) choose_svg_file(); - - ImVec2 input_size(-FLT_MIN, ImGui::GetTextLineHeight() * 6); - ImGuiInputTextFlags flags = - ImGuiInputTextFlags_::ImGuiInputTextFlags_AllowTabInput | - ImGuiInputTextFlags_::ImGuiInputTextFlags_AutoSelectAll - //| ImGuiInputTextFlags_::ImGuiInputTextFlags_CallbackResize - //|ImGuiInputTextFlags_::ImGuiInputTextFlags_CtrlEnterForNewLine - ; - - if (ImGui::InputTextMultiline("##Text", &m_text, input_size, flags)) process(); + draw_text_input(); static bool advanced = false; ImGui::Checkbox(_L("Advance").c_str(), &advanced); @@ -500,9 +493,31 @@ void GLGizmoEmboss::draw_font_list() } } +void GLGizmoEmboss::draw_text_input() { + check_imgui_font_range(); + + static const ImGuiInputTextFlags flags = + ImGuiInputTextFlags_AllowTabInput | + ImGuiInputTextFlags_AutoSelectAll ; + + ImVector &fonts = m_imgui_font_atlas.Fonts; + ImFont *imgui_font = fonts.empty()? nullptr : fonts.front(); + bool exist_font = imgui_font != nullptr && imgui_font->IsLoaded(); + if (exist_font) ImGui::PushFont(imgui_font); + + if (ImGui::InputTextMultiline("##Text", &m_text, m_gui_cfg->text_size, flags)) { + process(); + } + + if (exist_font) ImGui::PopFont(); + // debug font texture + //ImGui::Image(m_imgui_font_atlas.TexID, ImVec2(m_imgui_font_atlas.TexWidth, m_imgui_font_atlas.TexHeight)); +} + void GLGizmoEmboss::draw_advanced() { if (ImGui::InputFloat(_L("Size[in mm]").c_str(), &m_font_prop.size_in_mm)) { if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10; + load_imgui_font(); process(); } if (ImGui::InputFloat(_L("Emboss[in mm]").c_str(), &m_font_prop.emboss)) process(); @@ -551,9 +566,72 @@ bool GLGizmoEmboss::load_font() { auto font = WxFontUtils::load_font(m_font_list[m_font_selected]); if (!font.has_value()) return false; m_font = font; + + load_imgui_font(); + return true; } +void GLGizmoEmboss::check_imgui_font_range() { + + const char *text = m_text.c_str(); + const ImFont* font = m_imgui_font_atlas.Fonts.front(); + bool exist_unknown = false; + while (*text) { + unsigned int c = 0; + int c_len = ImTextCharFromUtf8(&c, text, NULL); + text += c_len; + if (c_len == 0) break; + ImWchar wc = c; + if (font->FindGlyphNoFallback(wc) == NULL) { + exist_unknown = true; + break; + } + } + if (exist_unknown) load_imgui_font(); +} + +void GLGizmoEmboss::load_imgui_font() { + if (!m_font.has_value()) return; + + ImFontGlyphRangesBuilder builder; + builder.AddRanges(m_imgui->get_glyph_ranges()); + builder.AddText(m_text.c_str()); + + ImVector glyph_ranges; + builder.BuildRanges(&glyph_ranges); + int font_size = static_cast( + std::round(std::abs(m_font_prop.size_in_mm / 0.3528))); + ImFontConfig font_config; + font_config.FontDataOwnedByAtlas = false; + m_imgui_font_atlas.Clear(); + m_imgui_font_atlas.AddFontFromMemoryTTF( + (void *) m_font->buffer.data(), m_font->buffer.size(), + font_size, &font_config, glyph_ranges.Data); + + unsigned char *pixels; + int width, height; + m_imgui_font_atlas.GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture)); + ScopeGuard sg([last_texture]() { glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));}); + + GLuint font_texture; + glsafe(::glGenTextures(1, &font_texture)); + glsafe(::glBindTexture(GL_TEXTURE_2D, font_texture)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR)); glsafe(::glTexParameteri(GL_TEXTURE_2D, + GL_TEXTURE_MAG_FILTER, GL_LINEAR)); + glsafe(::glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, + GL_ALPHA, GL_UNSIGNED_BYTE, pixels)); + + // Store our identifier + m_imgui_font_atlas.TexID = (ImTextureID) (intptr_t) font_texture; +} + bool GLGizmoEmboss::choose_font_by_wxdialog() { wxFontData data; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index 3dd71192ba..c8a3e672c1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -14,6 +14,8 @@ #include "libslic3r/Point.hpp" #include "libslic3r/Model.hpp" +#include + namespace Slic3r::GUI { class GLGizmoEmboss : public GLGizmoBase { @@ -48,11 +50,14 @@ private: void close(); void draw_window(); void draw_font_list(); + void draw_text_input(); void draw_advanced(); bool load_font(); // try to set font_index bool load_font(size_t font_index); + void load_imgui_font(); + void check_imgui_font_range(); bool choose_font_by_wxdialog(); bool choose_true_type_file(); @@ -80,13 +85,16 @@ private: struct GuiCfg { size_t max_count_char_in_volume_name = 20; + int count_line_of_text = 6; + // Zero means it is calculated in init function - float combo_font_width = 0.f; - float rename_pos_x = 0.f; - float delete_pos_x = 0.f; - float max_font_name_width = 0.f; - float icon_width = 0.; - float icon_width_with_spacing = 0.; + float combo_font_width = 0.f; + float rename_pos_x = 0.f; + float delete_pos_x = 0.f; + float max_font_name_width = 0.f; + float icon_width = 0.f; + float icon_width_with_spacing = 0.f; + ImVec2 text_size; GuiCfg() = default; }; std::optional m_gui_cfg; @@ -119,6 +127,9 @@ private: // initialize when GL is accessible bool m_is_initialized; + // imgui font + ImFontAtlas m_imgui_font_atlas; + // drawing icons GLTexture m_icons_texture; bool init_icons(); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 03e5bdc092..22c575f4c6 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -960,7 +960,7 @@ void ImGuiWrapper::init_font(bool compress) // Create ranges of characters from m_glyph_ranges, possibly adding some OS specific special characters. ImVector ranges; - ImFontAtlas::GlyphRangesBuilder builder; + ImFontGlyphRangesBuilder builder; builder.AddRanges(m_glyph_ranges); #ifdef __APPLE__ if (m_font_cjk) diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index 441d26ccc6..6d3d3218af 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -37,8 +37,6 @@ public: ImGuiWrapper(); ~ImGuiWrapper(); - void read_glsl_version(); - void set_language(const std::string &language); void set_display_size(float w, float h); void set_scaling(float font_size, float scale_style, float scale_both); @@ -47,6 +45,7 @@ public: float get_font_size() const { return m_font_size; } float get_style_scaling() const { return m_style_scaling; } + const ImWchar *get_glyph_ranges() const { return m_glyph_ranges; } // language specific void new_frame(); void render();