Separate actual style from styles
(save button will save only actual style no others)
This commit is contained in:
parent
e9d65da046
commit
f7eef00abb
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ namespace Slic3r{
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
class MeshRaycaster;
|
||||
struct EmbossDataBase;
|
||||
|
||||
class GLGizmoEmboss : public GLGizmoBase
|
||||
{
|
||||
@ -121,18 +122,18 @@ private:
|
||||
/// TODO: make more general, static and move to ImGuiWrapper
|
||||
/// </summary>
|
||||
/// <returns>True when value changed otherwise FALSE.</returns>
|
||||
bool rev_input(const std::string &name, float &value, float *default_value,
|
||||
bool rev_input(const std::string &name, float &value, const float *default_value,
|
||||
const std::string &undo_tooltip, float step, float step_fast, const char *format,
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
bool rev_checkbox(const std::string &name, bool &value, bool* default_value, const std::string &undo_tooltip);
|
||||
bool rev_slider(const std::string &name, std::optional<int>& value, std::optional<int> *default_value,
|
||||
bool rev_checkbox(const std::string &name, bool &value, const bool* default_value, const std::string &undo_tooltip);
|
||||
bool rev_slider(const std::string &name, std::optional<int>& value, const std::optional<int> *default_value,
|
||||
const std::string &undo_tooltip, int v_min, int v_max, const std::string &format, const wxString &tooltip);
|
||||
bool rev_slider(const std::string &name, std::optional<float>& value, std::optional<float> *default_value,
|
||||
bool rev_slider(const std::string &name, std::optional<float>& value, const std::optional<float> *default_value,
|
||||
const std::string &undo_tooltip, float v_min, float v_max, const std::string &format, const wxString &tooltip);
|
||||
bool rev_slider(const std::string &name, float &value, float *default_value,
|
||||
bool rev_slider(const std::string &name, float &value, const float *default_value,
|
||||
const std::string &undo_tooltip, float v_min, float v_max, const std::string &format, const wxString &tooltip);
|
||||
template<typename T, typename Draw>
|
||||
bool revertible(const std::string &name, T &value, T *default_value, const std::string &undo_tooltip, float undo_offset, Draw draw);
|
||||
bool revertible(const std::string &name, T &value, const T *default_value, const std::string &undo_tooltip, float undo_offset, Draw draw);
|
||||
|
||||
void set_minimal_window_size(bool is_advance_edit_style);
|
||||
const ImVec2 &get_minimal_window_size() const;
|
||||
@ -145,8 +146,8 @@ private:
|
||||
bool choose_true_type_file();
|
||||
bool choose_svg_file();
|
||||
|
||||
// Create object described how to make a Volume
|
||||
TextConfiguration create_configuration();
|
||||
// prepare base data for emboss text
|
||||
EmbossDataBase create_emboss_data_base();
|
||||
bool load_configuration(ModelVolume *volume);
|
||||
|
||||
// Create notification when unknown font type is used
|
||||
@ -154,8 +155,6 @@ private:
|
||||
void create_notification_not_valid_font(const TextConfiguration& tc);
|
||||
void remove_notification_not_valid_font();
|
||||
|
||||
std::string create_volume_name();
|
||||
|
||||
// This configs holds GUI layout size given by translated texts.
|
||||
// etc. When language changes, GUI is recreated and this class constructed again,
|
||||
// so the change takes effect. (info by GLGizmoFdmSupports.hpp)
|
||||
@ -212,7 +211,7 @@ private:
|
||||
std::optional<ImVec2> m_set_window_offset;
|
||||
bool m_is_advanced_edit_style = false;
|
||||
|
||||
FontManager m_font_manager;
|
||||
FontManager m_style_manager;
|
||||
|
||||
// Keep sorted list of loadable face names
|
||||
struct Facenames
|
||||
@ -227,15 +226,12 @@ private:
|
||||
std::vector<bool> exist_textures = {};
|
||||
} m_face_names;
|
||||
|
||||
// Track stored values in AppConfig
|
||||
std::optional<FontItem> m_stored_font_item;
|
||||
std::optional<wxFont> m_stored_wx_font; // cache for stored wx font to not create every frame
|
||||
std::map<std::string, FontItem> m_stored_font_items;
|
||||
void fill_stored_font_items();
|
||||
void select_stored_font_item();
|
||||
|
||||
// Text to emboss
|
||||
std::string m_text;
|
||||
|
||||
// actual volume
|
||||
ModelVolume *m_volume;
|
||||
|
||||
// True when m_text contain character unknown by selected font
|
||||
bool m_text_contain_unknown_glyph = false;
|
||||
|
||||
@ -245,9 +241,6 @@ private:
|
||||
// cancel for rendering font name
|
||||
bool m_allow_update_rendered_font;
|
||||
|
||||
// actual volume
|
||||
ModelVolume *m_volume;
|
||||
|
||||
// Rotation gizmo
|
||||
GLGizmoRotate m_rotate_gizmo;
|
||||
|
||||
@ -290,11 +283,6 @@ private:
|
||||
bool draw_clickable(IconType icon, IconState state, IconType hover_icon, IconState hover_state);
|
||||
bool draw_button(IconType icon, bool disable = false);
|
||||
|
||||
// load / store appConfig
|
||||
static FontList load_font_list_from_app_config(const AppConfig *cfg, size_t &activ_font_index);
|
||||
void store_font_list_to_app_config();
|
||||
//void store_font_item_to_app_config() const;
|
||||
|
||||
// only temporary solution
|
||||
static const std::string M_ICON_FILENAME;
|
||||
|
||||
|
@ -19,6 +19,8 @@ const std::string FontListSerializable::APP_CONFIG_FONT_COLLECTION = "collectio
|
||||
const std::string FontListSerializable::APP_CONFIG_FONT_CHAR_GAP = "char_gap";
|
||||
const std::string FontListSerializable::APP_CONFIG_FONT_LINE_GAP = "line_gap";
|
||||
|
||||
const std::string FontListSerializable::APP_CONFIG_ACTIVE_FONT = "activ_font";
|
||||
|
||||
std::string FontListSerializable::create_section_name(unsigned index)
|
||||
{
|
||||
return AppConfig::SECTION_FONT + ':' + std::to_string(index);
|
||||
@ -142,4 +144,60 @@ void FontListSerializable::store_font_item(AppConfig & cfg,
|
||||
cfg.set(section_name, APP_CONFIG_FONT_CHAR_GAP, std::to_string(*fp.char_gap));
|
||||
if (fp.line_gap.has_value())
|
||||
cfg.set(section_name, APP_CONFIG_FONT_LINE_GAP, std::to_string(*fp.line_gap));
|
||||
}
|
||||
|
||||
void FontListSerializable::store_font_index(AppConfig &cfg, unsigned index) {
|
||||
// store actual font index
|
||||
cfg.clear_section(AppConfig::SECTION_FONT);
|
||||
// activ font first index is +1 to correspond with section name
|
||||
std::string activ_font = std::to_string(index);
|
||||
cfg.set(AppConfig::SECTION_FONT, APP_CONFIG_ACTIVE_FONT, activ_font);
|
||||
}
|
||||
|
||||
std::optional<size_t> FontListSerializable::load_font_index(const AppConfig &cfg)
|
||||
{
|
||||
if (!cfg.has_section(AppConfig::SECTION_FONT)) return {};
|
||||
|
||||
auto section = cfg.get_section(AppConfig::SECTION_FONT);
|
||||
auto it = section.find(APP_CONFIG_ACTIVE_FONT);
|
||||
if (it == section.end()) return {};
|
||||
|
||||
size_t active_font = static_cast<size_t>(std::atoi(it->second.c_str()));
|
||||
// order in config starts with number 1
|
||||
return active_font - 1;
|
||||
}
|
||||
|
||||
FontList FontListSerializable::load_font_list(const AppConfig &cfg)
|
||||
{
|
||||
FontList result;
|
||||
// human readable index inside of config starts from 1 !!
|
||||
unsigned index = 1;
|
||||
std::string section_name = create_section_name(
|
||||
index);
|
||||
while (cfg.has_section(section_name)) {
|
||||
std::optional<FontItem> fi = load_font_item(cfg.get_section(section_name));
|
||||
if (fi.has_value()) result.emplace_back(*fi);
|
||||
section_name = create_section_name(++index);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void FontListSerializable::store_font_list(AppConfig &cfg, const FontList font_list)
|
||||
{
|
||||
// store styles
|
||||
unsigned index = 1;
|
||||
for (const FontItem &fi : font_list) {
|
||||
// skip file paths + fonts from other OS(loaded from .3mf)
|
||||
assert(fi.type == WxFontUtils::get_actual_type());
|
||||
// if (fi.type != WxFontUtils::get_actual_type()) continue;
|
||||
store_font_item(cfg, fi, index++);
|
||||
}
|
||||
|
||||
// remove rest of font sections (after deletation)
|
||||
std::string section_name = create_section_name(index);
|
||||
while (cfg.has_section(section_name)) {
|
||||
cfg.clear_section(section_name);
|
||||
section_name = create_section_name(++index);
|
||||
}
|
||||
cfg.save();
|
||||
}
|
@ -29,14 +29,22 @@ class FontListSerializable
|
||||
static const std::string APP_CONFIG_FONT_COLLECTION;
|
||||
static const std::string APP_CONFIG_FONT_CHAR_GAP;
|
||||
static const std::string APP_CONFIG_FONT_LINE_GAP;
|
||||
|
||||
static const std::string APP_CONFIG_ACTIVE_FONT;
|
||||
public:
|
||||
FontListSerializable() = delete;
|
||||
|
||||
static void store_font_index(AppConfig &cfg, unsigned index);
|
||||
static std::optional<size_t> load_font_index(const AppConfig &cfg);
|
||||
|
||||
static FontList load_font_list(const AppConfig &cfg);
|
||||
static void store_font_list(AppConfig &cfg, const FontList font_list);
|
||||
|
||||
private:
|
||||
static std::string create_section_name(unsigned index);
|
||||
static std::optional<FontItem> load_font_item(const std::map<std::string, std::string> &app_cfg_section);
|
||||
static void store_font_item(AppConfig &cfg, const FontItem &fi, unsigned index);
|
||||
|
||||
private:
|
||||
// TODO: move to app config like read from section
|
||||
static bool read(const std::map<std::string, std::string>& section, const std::string& key, bool& value);
|
||||
static bool read(const std::map<std::string, std::string>& section, const std::string& key, float& value);
|
||||
|
@ -9,62 +9,103 @@
|
||||
#include "slic3r/GUI/Jobs/CreateFontStyleImagesJob.hpp"
|
||||
#include "slic3r/GUI/ImGuiWrapper.hpp" // check of font ranges
|
||||
|
||||
#include "slic3r/Utils/FontListSerializable.hpp"
|
||||
|
||||
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(std::numeric_limits<size_t>::max())
|
||||
, m_exist_style_images(false)
|
||||
, m_temp_style_images(nullptr)
|
||||
{}
|
||||
|
||||
FontManager::~FontManager() {
|
||||
free_imgui_fonts();
|
||||
clear_imgui_font();
|
||||
free_style_images();
|
||||
}
|
||||
|
||||
void FontManager::init(const AppConfig *cfg, const FontList &default_font_list)
|
||||
{
|
||||
FontList font_list = (cfg != nullptr) ?
|
||||
FontListSerializable::load_font_list(*cfg) :
|
||||
default_font_list;
|
||||
if (font_list.empty()) font_list = default_font_list;
|
||||
for (FontItem &fi : font_list) {
|
||||
make_unique_name(fi.name);
|
||||
m_font_list.push_back({fi});
|
||||
}
|
||||
|
||||
std::optional<size_t> activ_index_opt = (cfg != nullptr) ?
|
||||
FontListSerializable::load_font_index(*cfg) :
|
||||
std::optional<size_t>{};
|
||||
size_t activ_index = activ_index_opt.has_value() ? *activ_index_opt : 0;
|
||||
if (activ_index >= m_font_list.size()) activ_index = 0;
|
||||
|
||||
// find valid font item
|
||||
if (!load_font(activ_index)) {
|
||||
m_font_list.erase(m_font_list.begin() + activ_index);
|
||||
activ_index = 0;
|
||||
while (m_font_list.empty() || !load_font(activ_index))
|
||||
m_font_list.erase(m_font_list.begin());
|
||||
// no one style from config is loadable
|
||||
if (m_font_list.empty()) {
|
||||
// set up default font list
|
||||
for (FontItem fi : default_font_list) {
|
||||
make_unique_name(fi.name);
|
||||
m_font_list.push_back({std::move(fi)});
|
||||
}
|
||||
// try to load first default font
|
||||
bool loaded = load_font(activ_index);
|
||||
assert(loaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FontManager::store_font_list_to_app_config(AppConfig *cfg)
|
||||
{
|
||||
assert(cfg != nullptr);
|
||||
if (cfg == nullptr) return false;
|
||||
if (exist_stored_style()) {
|
||||
// update stored item
|
||||
m_font_list[m_style_cache.font_index].font_item = m_style_cache.font_item;
|
||||
} else {
|
||||
// add new into stored list
|
||||
FontItem &fi = m_style_cache.font_item;
|
||||
make_unique_name(fi.name);
|
||||
m_style_cache.font_index = m_font_list.size();
|
||||
m_font_list.push_back({fi});
|
||||
}
|
||||
|
||||
FontListSerializable::store_font_index(*cfg, m_style_cache.font_index);
|
||||
FontList font_list;
|
||||
font_list.reserve(m_font_list.size());
|
||||
for (const Item &item : m_font_list) font_list.push_back(item.font_item);
|
||||
FontListSerializable::store_font_list(*cfg, font_list);
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!exist_stored_style()) return;
|
||||
if (m_style_cache.font_index == i1) {
|
||||
m_style_cache.font_index = i2;
|
||||
} else if (m_style_cache.font_index == i2) {
|
||||
m_style_cache.font_index = 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
|
||||
make_unique_name(item.font_item.name);
|
||||
item.truncated_name.clear();
|
||||
|
||||
// take original font imgui pointer
|
||||
//ImFont *imgui_font = get_imgui_font(index);
|
||||
//if (imgui_font != nullptr)
|
||||
// m_font_list[index].imgui_font_index.reset();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void FontManager::erase(size_t index) {
|
||||
if (index >= m_font_list.size()) return;
|
||||
//ImFont *imgui_font = get_imgui_font(index);
|
||||
//if (imgui_font != nullptr)
|
||||
// IM_DELETE(imgui_font);
|
||||
|
||||
// fix selected index
|
||||
if (is_activ_font() && index < m_font_selected)
|
||||
--m_font_selected;
|
||||
if (exist_stored_style() &&
|
||||
index < m_style_cache.font_index)
|
||||
--m_style_cache.font_index;
|
||||
|
||||
m_font_list.erase(m_font_list.begin() + index);
|
||||
}
|
||||
@ -79,9 +120,7 @@ bool FontManager::wx_font_changed(std::unique_ptr<Emboss::FontFile> font_file)
|
||||
font_file = WxFontUtils::create_font_file(*wx_font);
|
||||
if (font_file == nullptr) return false;
|
||||
}
|
||||
m_font_list[m_font_selected].font_file_with_cache =
|
||||
Emboss::FontFileWithCache(std::move(font_file));
|
||||
|
||||
m_style_cache.font_file = Emboss::FontFileWithCache(std::move(font_file));
|
||||
auto &fi = get_font_item();
|
||||
fi.type = WxFontUtils::get_actual_type();
|
||||
fi.path = WxFontUtils::store_wxFont(*wx_font);
|
||||
@ -93,38 +132,41 @@ bool FontManager::wx_font_changed(std::unique_ptr<Emboss::FontFile> font_file)
|
||||
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_active_font();
|
||||
if (!is_loaded) std::swap(font_index, m_font_selected);
|
||||
return is_loaded;
|
||||
if (!load_font(m_font_list[font_index].font_item)) return false;
|
||||
m_style_cache.font_index = font_index;
|
||||
m_style_cache.stored_wx_font = m_style_cache.wx_font;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FontManager::load_font(size_t font_index, const wxFont &font)
|
||||
bool FontManager::load_font(const FontItem &fi) {
|
||||
if (fi.type == FontItem::Type::file_path) {
|
||||
std::unique_ptr<Emboss::FontFile> font_ptr =
|
||||
Emboss::create_font_file(fi.path.c_str());
|
||||
if (font_ptr == nullptr) return false;
|
||||
m_style_cache.wx_font = {};
|
||||
m_style_cache.font_file =
|
||||
Emboss::FontFileWithCache(std::move(font_ptr));
|
||||
m_style_cache.font_item = fi; // copy
|
||||
m_style_cache.font_index = std::numeric_limits<size_t>::max();
|
||||
m_style_cache.stored_wx_font = {};
|
||||
return true;
|
||||
}
|
||||
if (fi.type != WxFontUtils::get_actual_type()) return false;
|
||||
std::optional<wxFont> wx_font_opt = WxFontUtils::load_wxFont(fi.path);
|
||||
if (!wx_font_opt.has_value()) return false;
|
||||
return load_font(fi, *wx_font_opt);
|
||||
}
|
||||
|
||||
bool FontManager::load_font(const FontItem &fi, const wxFont &font)
|
||||
{
|
||||
if (font_index >= m_font_list.size()) return false;
|
||||
std::swap(font_index, m_font_selected);
|
||||
bool is_loaded = set_wx_font(font);
|
||||
if (!is_loaded) std::swap(font_index, m_font_selected);
|
||||
return is_loaded;
|
||||
if (!set_wx_font(font)) return false;
|
||||
m_style_cache.font_item = fi; // copy
|
||||
m_style_cache.font_index = std::numeric_limits<size_t>::max();
|
||||
m_style_cache.stored_wx_font = {};
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string get_file_name(const std::string &file_path)
|
||||
{
|
||||
size_t pos_last_delimiter = file_path.find_last_of("/\\");
|
||||
size_t pos_point = file_path.find_last_of('.');
|
||||
size_t offset = pos_last_delimiter + 1;
|
||||
size_t count = pos_point - pos_last_delimiter - 1;
|
||||
return file_path.substr(offset, count);
|
||||
}
|
||||
|
||||
bool FontManager::load_active_font()
|
||||
{
|
||||
return set_up_font_file(m_font_selected);
|
||||
}
|
||||
|
||||
bool FontManager::is_activ_font() {
|
||||
return m_font_selected < m_font_list.size();
|
||||
}
|
||||
bool FontManager::is_activ_font() { return m_style_cache.font_file.has_value(); }
|
||||
|
||||
bool FontManager::load_first_valid_font() {
|
||||
while (!m_font_list.empty()) {
|
||||
@ -135,127 +177,47 @@ bool FontManager::load_first_valid_font() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FontManager::add_font(FontItem font_item)
|
||||
{
|
||||
make_unique_name(font_item.name);
|
||||
Item item;
|
||||
item.font_item = font_item;
|
||||
m_font_list.push_back(item);
|
||||
}
|
||||
|
||||
void FontManager::add_fonts(FontList font_list)
|
||||
const FontItem* FontManager::get_stored_font_item() const
|
||||
{
|
||||
for (const FontItem &fi : font_list)
|
||||
add_font(fi);
|
||||
if (m_style_cache.font_index >= m_font_list.size()) return nullptr;
|
||||
return &m_font_list[m_style_cache.font_index].font_item;
|
||||
}
|
||||
|
||||
std::shared_ptr<const Emboss::FontFile> &FontManager::get_font_file()
|
||||
{
|
||||
// TODO: fix not selected font
|
||||
//if (!is_activ_font()) return nullptr;
|
||||
return m_font_list[m_font_selected].font_file_with_cache.font_file;
|
||||
}
|
||||
const std::optional<wxFont> &FontManager::get_stored_wx_font() const { return m_style_cache.stored_wx_font; }
|
||||
|
||||
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;
|
||||
}
|
||||
const FontItem &FontManager::get_font_item() const { return m_style_cache.font_item; }
|
||||
FontItem &FontManager::get_font_item() { return m_style_cache.font_item; }
|
||||
const FontProp &FontManager::get_font_prop() const { return get_font_item().prop; }
|
||||
FontProp &FontManager::get_font_prop() { return get_font_item().prop; }
|
||||
const std::optional<wxFont> &FontManager::get_wx_font() const { return m_style_cache.wx_font; }
|
||||
std::optional<wxFont> &FontManager::get_wx_font() { return m_style_cache.wx_font; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
FontProp &FontManager::get_font_prop()
|
||||
{
|
||||
// TODO: fix not selected font
|
||||
return m_font_list[m_font_selected].font_item.prop;
|
||||
}
|
||||
|
||||
std::optional<wxFont> &FontManager::get_wx_font()
|
||||
{
|
||||
//if (!is_activ_font()) return {};
|
||||
return m_font_list[m_font_selected].wx_font;
|
||||
|
||||
//std::optional<wxFont> &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<wxFont> &FontManager::get_wx_font() const
|
||||
{
|
||||
return m_font_list[m_font_selected].wx_font;
|
||||
}
|
||||
bool FontManager::exist_stored_style() const { return m_style_cache.font_index != std::numeric_limits<size_t>::max(); }
|
||||
size_t FontManager::get_style_index() const { return m_style_cache.font_index; }
|
||||
Emboss::FontFileWithCache &FontManager::get_font_file_with_cache() { return m_style_cache.font_file; }
|
||||
std::string &FontManager::get_truncated_name() { return m_style_cache.truncated_name; }
|
||||
|
||||
void FontManager::clear_glyphs_cache()
|
||||
{
|
||||
if (!is_activ_font()) return;
|
||||
Emboss::FontFileWithCache &ff = m_font_list[m_font_selected].font_file_with_cache;
|
||||
Emboss::FontFileWithCache &ff = m_style_cache.font_file;
|
||||
if (!ff.has_value()) return;
|
||||
ff.cache = std::make_shared<Emboss::Glyphs>();
|
||||
}
|
||||
|
||||
void FontManager::clear_imgui_font() {
|
||||
// TODO: improove to clear only actual font
|
||||
if (!is_activ_font()) return;
|
||||
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);
|
||||
}
|
||||
void FontManager::clear_imgui_font() { m_style_cache.atlas.Clear(); }
|
||||
|
||||
ImFont *FontManager::get_imgui_font()
|
||||
{
|
||||
return get_imgui_font(m_font_selected);
|
||||
}
|
||||
|
||||
ImFont *FontManager::create_imgui_font(const std::string &text)
|
||||
{
|
||||
return create_imgui_font(m_font_selected, text);
|
||||
}
|
||||
|
||||
ImFont *FontManager::get_imgui_font(size_t item_index)
|
||||
{
|
||||
if (!is_activ_font()) return nullptr;
|
||||
Item &item = m_font_list[item_index];
|
||||
// check is already loaded
|
||||
if (!item.imgui_font_index.has_value()) return nullptr;
|
||||
|
||||
size_t index = *item.imgui_font_index;
|
||||
ImVector<ImFont *> &fonts = m_imgui_font_atlas.Fonts;
|
||||
|
||||
ImVector<ImFont *> &fonts = m_style_cache.atlas.Fonts;
|
||||
if (fonts.empty()) return nullptr;
|
||||
|
||||
// check correct index
|
||||
int f_size = fonts.size();
|
||||
assert(f_size > 0 && index < (size_t) f_size);
|
||||
if (f_size <= 0 || index >= (size_t) f_size) return nullptr;
|
||||
ImFont *font = fonts[index];
|
||||
assert(f_size == 1);
|
||||
if (f_size != 1) return nullptr;
|
||||
ImFont *font = fonts.front();
|
||||
if (font == nullptr) return nullptr;
|
||||
if (!font->IsLoaded()) return nullptr;
|
||||
if (font->Scale <= 0.f) return nullptr;
|
||||
@ -264,25 +226,13 @@ ImFont *FontManager::get_imgui_font(size_t item_index)
|
||||
return font;
|
||||
}
|
||||
|
||||
void FontManager::free_except_active_font() {
|
||||
free_imgui_fonts();
|
||||
const std::vector<FontManager::Item> &FontManager::get_styles() const{ return m_font_list; }
|
||||
|
||||
// free font_files
|
||||
const Item &act_item = m_font_list[m_font_selected];
|
||||
for (auto &item : m_font_list) {
|
||||
if (&item == &act_item) continue; // keep alive actual font file
|
||||
item.font_file_with_cache = {};
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<FontManager::Item> &FontManager::get_styles() const
|
||||
ImFont* FontManager::extend_imgui_font_range(size_t index, const std::string& text)
|
||||
{
|
||||
return m_font_list;
|
||||
}
|
||||
|
||||
const FontManager::Item &FontManager::get_activ_style() const
|
||||
{
|
||||
return m_font_list[m_font_selected];
|
||||
// TODO: start using merge mode
|
||||
// ImFontConfig::MergeMode = true;
|
||||
return create_imgui_font(text);
|
||||
}
|
||||
|
||||
void FontManager::make_unique_name(std::string &name)
|
||||
@ -310,46 +260,10 @@ 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<Emboss::FontFile> font_ptr =
|
||||
Emboss::create_font_file(fi.path.c_str());
|
||||
if (font_ptr == nullptr) return false;
|
||||
item.font_file_with_cache =
|
||||
Emboss::FontFileWithCache(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);
|
||||
}
|
||||
|
||||
ImFont* FontManager::extend_imgui_font_range(size_t index, const std::string& text)
|
||||
{
|
||||
auto &font_index_opt = m_font_list[m_font_selected].imgui_font_index;
|
||||
if (!font_index_opt.has_value())
|
||||
return create_imgui_font(index, text);
|
||||
|
||||
// TODO: start using merge mode
|
||||
// ImFontConfig::MergeMode = true;
|
||||
|
||||
free_imgui_fonts();
|
||||
return create_imgui_font(index, text);
|
||||
}
|
||||
|
||||
|
||||
void FontManager::init_trunc_names(float max_width) {
|
||||
for (auto &s : m_font_list) {
|
||||
for (auto &s : m_font_list)
|
||||
if (s.truncated_name.empty())
|
||||
s.truncated_name = ImGuiWrapper::trunc(s.font_item.name, max_width);
|
||||
}
|
||||
}
|
||||
|
||||
#include "slic3r/GUI/Jobs/CreateFontStyleImagesJob.hpp"
|
||||
@ -396,17 +310,19 @@ void FontManager::init_style_images(const Vec2i &max_size,
|
||||
m_temp_style_images = std::make_shared<StyleImagesData::StyleImages>();
|
||||
StyleImagesData::Items styles;
|
||||
styles.reserve(m_font_list.size());
|
||||
for (Item &item : m_font_list) {
|
||||
size_t index = &item - &m_font_list.front();
|
||||
if (!item.font_file_with_cache.has_value() && !set_up_font_file(index))
|
||||
continue;
|
||||
for (const Item &item : m_font_list) {
|
||||
const FontItem &fi = item.font_item;
|
||||
std::optional<wxFont> wx_font_opt = WxFontUtils::load_wxFont(fi.path);
|
||||
if (!wx_font_opt.has_value()) continue;
|
||||
std::unique_ptr<Emboss::FontFile> font_file =
|
||||
WxFontUtils::create_font_file(*wx_font_opt);
|
||||
if (font_file == nullptr) continue;
|
||||
styles.push_back({
|
||||
item.font_file_with_cache,
|
||||
item.font_item.name,
|
||||
item.font_item.prop
|
||||
Emboss::FontFileWithCache(std::move(font_file)),
|
||||
fi.name,
|
||||
fi.prop
|
||||
});
|
||||
}
|
||||
|
||||
auto &worker = wxGetApp().plater()->get_ui_job_worker();
|
||||
StyleImagesData data{std::move(styles), max_size, text, m_temp_style_images};
|
||||
queue_job(worker, std::make_unique<CreateFontStyleImagesJob>(std::move(data)));
|
||||
@ -428,13 +344,6 @@ void FontManager::free_style_images() {
|
||||
m_exist_style_images = false;
|
||||
}
|
||||
|
||||
void FontManager::free_imgui_fonts()
|
||||
{
|
||||
for (auto &item : m_font_list)
|
||||
item.imgui_font_index.reset();
|
||||
m_imgui_font_atlas.Clear();
|
||||
}
|
||||
|
||||
float FontManager::min_imgui_font_size = 18.f;
|
||||
float FontManager::max_imgui_font_size = 60.f;
|
||||
float FontManager::get_imgui_font_size(const FontProp &prop,
|
||||
@ -452,28 +361,26 @@ float FontManager::get_imgui_font_size(const FontProp &prop,
|
||||
return c1 * std::abs(prop.size_in_mm) / 0.3528f;
|
||||
}
|
||||
|
||||
ImFont *FontManager::create_imgui_font(size_t index, const std::string &text)
|
||||
ImFont *FontManager::create_imgui_font(const std::string &text)
|
||||
{
|
||||
free_imgui_fonts(); // TODO: remove it after correct initialization
|
||||
|
||||
if (index >= m_font_list.size()) return nullptr;
|
||||
Item &item = m_font_list[index];
|
||||
if (!item.font_file_with_cache.has_value()) return nullptr;
|
||||
const Emboss::FontFile &font_file = *item.font_file_with_cache.font_file;
|
||||
auto& ff = m_style_cache.font_file;
|
||||
if (!ff.has_value()) return nullptr;
|
||||
const Emboss::FontFile &font_file = *ff.font_file;
|
||||
|
||||
// TODO: Create glyph range
|
||||
ImFontGlyphRangesBuilder builder;
|
||||
builder.AddRanges(m_imgui_init_glyph_range);
|
||||
if (!text.empty())
|
||||
builder.AddText(text.c_str());
|
||||
item.font_ranges.clear();
|
||||
|
||||
builder.BuildRanges(&item.font_ranges);
|
||||
ImVector<ImWchar> &ranges = m_style_cache.ranges;
|
||||
ranges.clear();
|
||||
builder.BuildRanges(&ranges);
|
||||
|
||||
m_imgui_font_atlas.Flags |= ImFontAtlasFlags_NoMouseCursors |
|
||||
m_style_cache.atlas.Flags |= ImFontAtlasFlags_NoMouseCursors |
|
||||
ImFontAtlasFlags_NoPowerOfTwoHeight;
|
||||
|
||||
const FontProp &font_prop = item.font_item.prop;
|
||||
const FontProp &font_prop = m_style_cache.font_item.prop;
|
||||
float font_size = get_imgui_font_size(font_prop, font_file);
|
||||
if (font_size < min_imgui_font_size)
|
||||
font_size = min_imgui_font_size;
|
||||
@ -499,12 +406,12 @@ ImFont *FontManager::create_imgui_font(size_t index, const std::string &text)
|
||||
font_config.FontDataOwnedByAtlas = false;
|
||||
|
||||
const std::vector<unsigned char> &buffer = *font_file.data;
|
||||
ImFont * font = m_imgui_font_atlas.AddFontFromMemoryTTF(
|
||||
(void *) buffer.data(), buffer.size(), font_size, &font_config, item.font_ranges.Data);
|
||||
ImFont * font = m_style_cache.atlas.AddFontFromMemoryTTF(
|
||||
(void *) buffer.data(), buffer.size(), font_size, &font_config, m_style_cache.ranges.Data);
|
||||
|
||||
unsigned char *pixels;
|
||||
int width, height;
|
||||
m_imgui_font_atlas.GetTexDataAsAlpha8(&pixels, &width, &height);
|
||||
m_style_cache.atlas.GetTexDataAsAlpha8(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
GLint last_texture;
|
||||
@ -523,32 +430,23 @@ ImFont *FontManager::create_imgui_font(size_t index, const std::string &text)
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// 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 nullptr;
|
||||
assert(font == m_imgui_font_atlas.Fonts.back());
|
||||
item.imgui_font_index = m_imgui_font_atlas.Fonts.size() - 1;
|
||||
m_style_cache.atlas.TexID = (ImTextureID) (intptr_t) font_texture;
|
||||
assert(!m_style_cache.atlas.Fonts.empty());
|
||||
if (m_style_cache.atlas.Fonts.empty()) return nullptr;
|
||||
assert(font == m_style_cache.atlas.Fonts.back());
|
||||
assert(font->IsLoaded());
|
||||
return font;
|
||||
}
|
||||
|
||||
bool FontManager::set_wx_font(size_t item_index, const wxFont &wx_font) {
|
||||
bool FontManager::set_wx_font(const wxFont &wx_font) {
|
||||
std::unique_ptr<Emboss::FontFile> font_file =
|
||||
WxFontUtils::create_font_file(wx_font);
|
||||
if (font_file == nullptr) return false;
|
||||
|
||||
Item &item = m_font_list[item_index];
|
||||
item.font_file_with_cache =
|
||||
m_style_cache.font_file =
|
||||
Emboss::FontFileWithCache(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);
|
||||
|
||||
m_style_cache.wx_font = wx_font; // copy
|
||||
FontItem &fi = m_style_cache.font_item;
|
||||
fi.type = WxFontUtils::get_actual_type();
|
||||
clear_imgui_font();
|
||||
return true;
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
#ifndef slic3r_FontManager_hpp_
|
||||
#define slic3r_FontManager_hpp_
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <imgui/imgui.h>
|
||||
#include <GL/glew.h>
|
||||
#include <libslic3r/Emboss.hpp>
|
||||
#include <libslic3r/AppConfig.hpp>
|
||||
|
||||
class wxFont;
|
||||
|
||||
@ -23,6 +26,21 @@ public:
|
||||
FontManager(const ImWchar *language_glyph_range);
|
||||
~FontManager();
|
||||
|
||||
/// <summary>
|
||||
/// Load font style list from config
|
||||
/// Also select actual activ font
|
||||
/// </summary>
|
||||
/// <param name="cfg">Application configuration loaded from file "PrusaSlicer.ini"</param>
|
||||
/// <param name="default_font_list">Used when list is not loadable from config</param>
|
||||
void init(const AppConfig *cfg, const FontList &default_font_list);
|
||||
|
||||
/// <summary>
|
||||
/// Write font list into AppConfig
|
||||
/// </summary>
|
||||
/// <param name="cfg">Stor into this configuration</param>
|
||||
/// <param name="item_to_store">Configuration</param>
|
||||
bool store_font_list_to_app_config(AppConfig *cfg);
|
||||
|
||||
/// <summary>
|
||||
/// Change order of style item in m_font_list.
|
||||
/// Fix selected font index when (i1 || i2) == m_font_selected
|
||||
@ -31,11 +49,6 @@ public:
|
||||
/// <param name="i2">Second index to m_font_list</param>
|
||||
void swap(size_t i1, size_t i2);
|
||||
|
||||
/// <summary>
|
||||
/// Duplicate selected font style
|
||||
/// </summary>
|
||||
void duplicate();
|
||||
|
||||
/// <summary>
|
||||
/// Remove style from m_font_list.
|
||||
/// Fix selected font index when index is under m_font_selected
|
||||
@ -57,8 +70,10 @@ public:
|
||||
/// <param name="font_index">New font index(from m_font_list range)</param>
|
||||
/// <returns>True on succes. False on fail load font</returns>
|
||||
bool load_font(size_t font_index);
|
||||
// load font style not stored in list
|
||||
bool load_font(const FontItem &fi);
|
||||
// fastering load font on index by wxFont, ignore type and descriptor
|
||||
bool load_font(size_t font_index, const wxFont &font);
|
||||
bool load_font(const FontItem &fi, const wxFont &font);
|
||||
|
||||
// clear actual selected glyphs cache
|
||||
void clear_glyphs_cache();
|
||||
@ -70,13 +85,11 @@ public:
|
||||
// used at initialize phaze - fonts could be modified in appConfig file by user
|
||||
bool load_first_valid_font();
|
||||
|
||||
// add font into manager
|
||||
void add_font(FontItem font_item);
|
||||
// add multiple font into manager
|
||||
void add_fonts(FontList font_list);
|
||||
// getter on stored fontItem
|
||||
const FontItem *get_stored_font_item() const;
|
||||
|
||||
// getter on active font file for access to glyphs
|
||||
std::shared_ptr<const Emboss::FontFile> &get_font_file();
|
||||
// getter on stored wxFont
|
||||
const std::optional<wxFont> &get_stored_wx_font() const;
|
||||
|
||||
// getter on active font item for access to font property
|
||||
const FontItem &get_font_item() const;
|
||||
@ -90,11 +103,18 @@ public:
|
||||
const std::optional<wxFont> &get_wx_font() const;
|
||||
std::optional<wxFont> &get_wx_font();
|
||||
|
||||
// setter of font for actual selection
|
||||
bool set_wx_font(const wxFont &wx_font);
|
||||
bool exist_stored_style() const;
|
||||
size_t get_style_index() const;
|
||||
|
||||
// getter on font file with cache
|
||||
Emboss::FontFileWithCache &get_font_file_with_cache();
|
||||
|
||||
// Getter for cached trucated name for style list selector
|
||||
std::string &get_truncated_name();
|
||||
|
||||
// setter of font for actual selection
|
||||
bool set_wx_font(const wxFont &wx_font);
|
||||
|
||||
|
||||
// Getter on acitve font pointer for imgui
|
||||
// Initialize imgui font(generate texture) when doesn't exist yet.
|
||||
@ -102,9 +122,6 @@ public:
|
||||
ImFont *get_imgui_font();
|
||||
// initialize font range by unique symbols in text
|
||||
ImFont *create_imgui_font(const std::string& text);
|
||||
|
||||
// free used memory and font file data
|
||||
void free_except_active_font();
|
||||
|
||||
// init truncated names of styles
|
||||
void init_trunc_names(float max_width);
|
||||
@ -120,7 +137,6 @@ public:
|
||||
struct Item;
|
||||
// access to all managed font styles
|
||||
const std::vector<Item> &get_styles() const;
|
||||
const Item &get_activ_style() const; // TODO: rename to style
|
||||
|
||||
/// <summary>
|
||||
/// Describe image in GPU to show settings of style
|
||||
@ -140,25 +156,15 @@ public:
|
||||
/// </summary>
|
||||
struct Item
|
||||
{
|
||||
// define font, style and other property of text
|
||||
FontItem font_item;
|
||||
|
||||
// cache for view font name with maximal width in imgui
|
||||
std::string truncated_name;
|
||||
|
||||
// share font file data with emboss job thread
|
||||
Emboss::FontFileWithCache font_file_with_cache;
|
||||
|
||||
std::optional<size_t> imgui_font_index;
|
||||
|
||||
// must live same as imgui_font inside of atlas
|
||||
ImVector<ImWchar> font_ranges;
|
||||
|
||||
// wx widget font
|
||||
std::optional<wxFont> wx_font;
|
||||
|
||||
// visualization of style
|
||||
std::optional<StyleImage> image;
|
||||
};
|
||||
};
|
||||
|
||||
// check if exist selected font style in manager
|
||||
bool is_activ_font();
|
||||
@ -168,35 +174,51 @@ public:
|
||||
static float min_imgui_font_size;
|
||||
static float max_imgui_font_size;
|
||||
static float get_imgui_font_size(const FontProp& prop, const Emboss::FontFile& file);
|
||||
|
||||
private:
|
||||
ImFontAtlas m_imgui_font_atlas;
|
||||
/// <summary>
|
||||
/// Cache data from style to reduce amount of:
|
||||
/// 1) loading font from file
|
||||
/// 2) Create atlas of symbols for imgui
|
||||
/// 3) Keep loaded(and modified by style) glyphs from font
|
||||
/// </summary>
|
||||
struct StyleCache
|
||||
{
|
||||
// share font file data with emboss job thread
|
||||
Emboss::FontFileWithCache font_file = {};
|
||||
|
||||
void duplicate(size_t index);
|
||||
// load actual selected font
|
||||
ImFont *create_imgui_font(size_t index, const std::string &text);
|
||||
// must live same as imgui_font inside of atlas
|
||||
ImVector<ImWchar> ranges = {};
|
||||
|
||||
bool load_active_font();
|
||||
// Keep only actual style in atlas
|
||||
ImFontAtlas atlas = {};
|
||||
|
||||
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);
|
||||
// wx widget font
|
||||
std::optional<wxFont> wx_font = {};
|
||||
|
||||
// cache for view font name with maximal width in imgui
|
||||
std::string truncated_name;
|
||||
|
||||
// actual used font item
|
||||
FontItem font_item = {};
|
||||
|
||||
// cache for stored wx font to not create every frame
|
||||
std::optional<wxFont> stored_wx_font;
|
||||
|
||||
// index into m_font_list
|
||||
size_t font_index = std::numeric_limits<size_t>::max();
|
||||
|
||||
} m_style_cache;
|
||||
|
||||
// extend actual imgui font when exist unknown char in text
|
||||
// NOTE: imgui_font has to be unused
|
||||
// return true when extend range otherwise FALSE
|
||||
ImFont *extend_imgui_font_range(size_t font_index, const std::string &text);
|
||||
|
||||
void free_imgui_fonts();
|
||||
|
||||
bool set_up_font_file(size_t item_index);
|
||||
|
||||
void make_unique_name(std::string &name);
|
||||
|
||||
// Privat member
|
||||
std::vector<Item> m_font_list;
|
||||
size_t m_font_selected; // index to m_font_list
|
||||
|
||||
/// <summary>
|
||||
/// Keep data needed to create Font Style Images in Job
|
||||
|
Loading…
Reference in New Issue
Block a user