mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-10 23:01:51 +08:00
Add checking of new installed font into list on each open combo box
This commit is contained in:
parent
d2da63db41
commit
5daf8818c9
@ -1226,58 +1226,13 @@ void GLGizmoEmboss::draw_text_input()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#include <boost/functional/hash.hpp>
|
||||||
/// Keep list of loadable OS fonts
|
#include "wx/hashmap.h"
|
||||||
/// Filtrate which can be loaded.
|
std::size_t hash_value(wxString const &s)
|
||||||
/// Sort alphanumerical.
|
|
||||||
/// </summary>
|
|
||||||
class MyFontEnumerator : public wxFontEnumerator
|
|
||||||
{
|
{
|
||||||
wxFontEncoding m_encoding;
|
boost::hash<std::string> hasher;
|
||||||
bool m_fixed_width_only = false;
|
return hasher(s.ToStdString());
|
||||||
std::vector<wxString> m_facenames;
|
}
|
||||||
std::vector<wxString> m_facenames_bad;
|
|
||||||
public:
|
|
||||||
MyFontEnumerator(wxFontEncoding encoding) : m_encoding(encoding) {}
|
|
||||||
void enumerate() {
|
|
||||||
m_facenames.clear();
|
|
||||||
m_facenames_bad.clear();
|
|
||||||
EnumerateFacenames(m_encoding, m_fixed_width_only);
|
|
||||||
std::sort(m_facenames.begin(), m_facenames.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<wxString> &get_face_names() const { return m_facenames; }
|
|
||||||
const std::vector<wxString> &get_bad_face_names() const { return m_facenames_bad; }
|
|
||||||
protected:
|
|
||||||
/// <summary>
|
|
||||||
/// Called by wxFontEnumerator::EnumerateFacenames() for each match.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="facename">name identificator to load face by wxFont</param>
|
|
||||||
/// <returns> True to continue enumeration or false to stop it.</returns>
|
|
||||||
virtual bool OnFacename(const wxString& facename) wxOVERRIDE {
|
|
||||||
// vertical font start with @, we will filter it out
|
|
||||||
if (facename.empty() || facename[0] == '@') return true;
|
|
||||||
wxFont wx_font(wxFontInfo().FaceName(facename).Encoding(m_encoding));
|
|
||||||
|
|
||||||
//*
|
|
||||||
// Faster chech if wx_font is loadable but not 100%
|
|
||||||
// names could contain not loadable font
|
|
||||||
if (!WxFontUtils::can_load(wx_font)) {
|
|
||||||
m_facenames_bad.emplace_back(facename);
|
|
||||||
return true; // can't load
|
|
||||||
}
|
|
||||||
/*/
|
|
||||||
// Slow copy of font files to try load font
|
|
||||||
// After this all files are loadable
|
|
||||||
auto font_file = WxFontUtils::create_font_file(wx_font);
|
|
||||||
if (font_file == nullptr) {
|
|
||||||
m_facenames_bad.emplace_back(facename.c_str());
|
|
||||||
return true; // can't create font file
|
|
||||||
} // */
|
|
||||||
m_facenames.push_back(facename);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool GLGizmoEmboss::select_facename(const wxString &facename) {
|
bool GLGizmoEmboss::select_facename(const wxString &facename) {
|
||||||
if (!wxFontEnumerator::IsValidFacename(facename)) return false;
|
if (!wxFontEnumerator::IsValidFacename(facename)) return false;
|
||||||
@ -1303,27 +1258,57 @@ static std::string concat(std::vector<wxString> data) {
|
|||||||
void GLGizmoEmboss::init_face_names() {
|
void GLGizmoEmboss::init_face_names() {
|
||||||
Timer t("enumerate_fonts");
|
Timer t("enumerate_fonts");
|
||||||
if (m_face_names.is_init) return;
|
if (m_face_names.is_init) return;
|
||||||
m_face_names.is_init = true;
|
m_face_names.is_init = true;
|
||||||
MyFontEnumerator font_enumerator(m_face_names.encoding);
|
|
||||||
|
|
||||||
{ using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
steady_clock::time_point enumerate_start = steady_clock::now();
|
steady_clock::time_point enumerate_start = steady_clock::now();
|
||||||
ScopeGuard sg([&enumerate_start, &font_enumerator]() {
|
ScopeGuard sg([&enumerate_start, &face_names = m_face_names]() {
|
||||||
steady_clock::time_point enumerate_end = steady_clock::now();
|
steady_clock::time_point enumerate_end = steady_clock::now();
|
||||||
long long enumerate_duration = duration_cast<milliseconds>(enumerate_end - enumerate_start).count();
|
long long enumerate_duration = duration_cast<milliseconds>(enumerate_end - enumerate_start).count();
|
||||||
BOOST_LOG_TRIVIAL(info) << "OS enumerate " << font_enumerator.get_face_names().size() << " fonts "
|
BOOST_LOG_TRIVIAL(info) << "OS enumerate " << face_names.faces.size() << " fonts "
|
||||||
<< "(+ " << font_enumerator.get_bad_face_names().size() << " can't load "
|
<< "(+ " << face_names.bad.size() << " can't load "
|
||||||
<< "= " << font_enumerator.get_face_names().size() + font_enumerator.get_bad_face_names().size() << " fonts) "
|
<< "= " << face_names.faces.size() + face_names.bad.size() << " fonts) "
|
||||||
<< "in " << enumerate_duration << " ms\n" << concat(font_enumerator.get_bad_face_names());
|
<< "in " << enumerate_duration << " ms\n" << concat(face_names.bad);
|
||||||
});
|
});
|
||||||
|
wxArrayString facenames = wxFontEnumerator::GetFacenames(m_face_names.encoding);
|
||||||
font_enumerator.enumerate();
|
size_t hash = boost::hash_range(facenames.begin(), facenames.end());
|
||||||
}// End Time measures
|
// check if it is same as last time
|
||||||
|
if (m_face_names.hash == hash) return; // no new installed font
|
||||||
|
m_face_names.hash = hash;
|
||||||
|
|
||||||
const std::vector<wxString> &names = font_enumerator.get_face_names();
|
// validation lambda
|
||||||
|
auto is_valid_font = [encoding = m_face_names.encoding](const wxString &name) {
|
||||||
|
if (name.empty()) return false;
|
||||||
|
|
||||||
|
// vertical font start with @, we will filter it out
|
||||||
|
// Not sure if it is only in Windows so filtering is on all platforms
|
||||||
|
if (name[0] == '@') return false;
|
||||||
|
|
||||||
|
wxFont wx_font(wxFontInfo().FaceName(name).Encoding(encoding));
|
||||||
|
|
||||||
|
//*
|
||||||
|
// Faster chech if wx_font is loadable but not 100%
|
||||||
|
// names could contain not loadable font
|
||||||
|
if (!WxFontUtils::can_load(wx_font)) return false;
|
||||||
|
|
||||||
|
/*/
|
||||||
|
// Slow copy of font files to try load font
|
||||||
|
// After this all files are loadable
|
||||||
|
auto font_file = WxFontUtils::create_font_file(wx_font);
|
||||||
|
if (font_file == nullptr)
|
||||||
|
return false; // can't create font file
|
||||||
|
// */
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const float &width = m_gui_cfg->face_name_max_width;
|
const float &width = m_gui_cfg->face_name_max_width;
|
||||||
m_face_names.faces.reserve(names.size());
|
m_face_names.faces.reserve(facenames.size());
|
||||||
for (const wxString &name : names) {
|
for (const wxString &name : facenames) {
|
||||||
|
if (!is_valid_font(name)) {
|
||||||
|
m_face_names.bad.push_back(name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
FaceName face_name = {name};
|
FaceName face_name = {name};
|
||||||
std::string name_str(name.ToUTF8().data());
|
std::string name_str(name.ToUTF8().data());
|
||||||
face_name.name_truncated = ImGuiWrapper::trunc(name_str, width);
|
face_name.name_truncated = ImGuiWrapper::trunc(name_str, width);
|
||||||
@ -1482,10 +1467,11 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
static_cast<int>(m_face_names.names.size()));
|
static_cast<int>(m_face_names.names.size()));
|
||||||
#endif // SHOW_FONT_COUNT
|
#endif // SHOW_FONT_COUNT
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
allow_update_rendered_font = true;
|
} else if (m_face_names.is_init) {
|
||||||
} else if (allow_update_rendered_font) {
|
// Just one after close combo box
|
||||||
// free texture and set id to zero
|
// free texture and set id to zero
|
||||||
allow_update_rendered_font = false;
|
|
||||||
|
m_face_names.is_init = false;
|
||||||
// cancel all process for generation of texture
|
// cancel all process for generation of texture
|
||||||
for (FaceName &face : m_face_names.faces)
|
for (FaceName &face : m_face_names.faces)
|
||||||
if (face.cancel != nullptr) face.cancel->store(true);
|
if (face.cancel != nullptr) face.cancel->store(true);
|
||||||
|
@ -244,8 +244,13 @@ private:
|
|||||||
{
|
{
|
||||||
// flag if face names was enumerated from OS
|
// flag if face names was enumerated from OS
|
||||||
bool is_init = false;
|
bool is_init = false;
|
||||||
|
// data of can_load() faces
|
||||||
std::vector<FaceName> faces = {};
|
std::vector<FaceName> faces = {};
|
||||||
|
// Not valid face names
|
||||||
|
std::vector<wxString> bad = {};
|
||||||
|
|
||||||
|
// Configuration of font encoding
|
||||||
|
const wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM;
|
||||||
|
|
||||||
// Identify if preview texture exists
|
// Identify if preview texture exists
|
||||||
GLuint texture_id = 0;
|
GLuint texture_id = 0;
|
||||||
@ -254,14 +259,15 @@ private:
|
|||||||
// Gtk:ERROR:../../../../gtk/gtkiconhelper.c:494:ensure_surface_for_gicon: assertion failed (error == NULL): Failed to load /usr/share/icons/Yaru/48x48/status/image-missing.png: Error opening file /usr/share/icons/Yaru/48x48/status/image-missing.png: Too many open files (g-io-error-quark, 31)
|
// Gtk:ERROR:../../../../gtk/gtkiconhelper.c:494:ensure_surface_for_gicon: assertion failed (error == NULL): Failed to load /usr/share/icons/Yaru/48x48/status/image-missing.png: Error opening file /usr/share/icons/Yaru/48x48/status/image-missing.png: Too many open files (g-io-error-quark, 31)
|
||||||
unsigned int count_opened_font_files = 0;
|
unsigned int count_opened_font_files = 0;
|
||||||
|
|
||||||
// Configuration of font encoding
|
|
||||||
const wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM;
|
|
||||||
|
|
||||||
// Configuration for texture height
|
// Configuration for texture height
|
||||||
const int count_cached_textures = 32;
|
const int count_cached_textures = 32;
|
||||||
|
|
||||||
// index for new generated texture index(must be lower than count_cached_textures)
|
// index for new generated texture index(must be lower than count_cached_textures)
|
||||||
size_t texture_index = 0;
|
size_t texture_index = 0;
|
||||||
|
|
||||||
|
// hash created from enumerated font from OS
|
||||||
|
// check when new font was installed
|
||||||
|
size_t hash = 0;
|
||||||
} m_face_names;
|
} m_face_names;
|
||||||
|
|
||||||
// Text to emboss
|
// Text to emboss
|
||||||
|
@ -73,6 +73,8 @@ bool WxFontUtils::can_load(const wxFont &font)
|
|||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
return is_valid_ttf(get_file_path(font));
|
return is_valid_ttf(get_file_path(font));
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
|
return true;
|
||||||
|
// font config check file path take about 4000ms for chech them all
|
||||||
std::string font_path = Slic3r::GUI::get_font_path(font);
|
std::string font_path = Slic3r::GUI::get_font_path(font);
|
||||||
return !font_path.empty();
|
return !font_path.empty();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user