More info for user in preview of font in combo box.
+ Clear rest of texture when short text is used
This commit is contained in:
parent
09fc025cd5
commit
2b31fa7d4a
@ -1768,33 +1768,46 @@ void GLGizmoEmboss::init_font_name_texture() {
|
|||||||
|
|
||||||
void GLGizmoEmboss::draw_font_preview(FaceName& face, bool is_visible)
|
void GLGizmoEmboss::draw_font_preview(FaceName& face, bool is_visible)
|
||||||
{
|
{
|
||||||
|
// Limit for opened font files at one moment
|
||||||
unsigned int &count_opened_fonts = m_face_names.count_opened_font_files;
|
unsigned int &count_opened_fonts = m_face_names.count_opened_font_files;
|
||||||
|
// Size of texture
|
||||||
ImVec2 size(m_gui_cfg->face_name_size.x(), m_gui_cfg->face_name_size.y());
|
ImVec2 size(m_gui_cfg->face_name_size.x(), m_gui_cfg->face_name_size.y());
|
||||||
// set to pixel 0,0 in texture
|
float count_cached_textures_f = static_cast<float>(m_face_names.count_cached_textures);
|
||||||
ImVec2 uv0(0.f, 0.f), uv1(1.f / size.x, 1.f / size.y / m_face_names.count_cached_textures);
|
std::string state_text;
|
||||||
ImTextureID tex_id = (void *) (intptr_t) m_face_names.texture_id;
|
// uv0 and uv1 set to pixel 0,0 in texture
|
||||||
|
ImVec2 uv0(0.f, 0.f), uv1(1.f / size.x, 1.f / size.y / count_cached_textures_f);
|
||||||
if (face.is_created != nullptr) {
|
if (face.is_created != nullptr) {
|
||||||
|
// not created preview
|
||||||
if (*face.is_created) {
|
if (*face.is_created) {
|
||||||
|
// Already created preview
|
||||||
size_t texture_index = face.texture_index;
|
size_t texture_index = face.texture_index;
|
||||||
uv0 = ImVec2(0.f, texture_index / (float) m_face_names.count_cached_textures),
|
uv0 = ImVec2(0.f, texture_index / count_cached_textures_f);
|
||||||
uv1 = ImVec2(1.f, (texture_index + 1) / (float) m_face_names.count_cached_textures);
|
uv1 = ImVec2(1.f, (texture_index + 1) / count_cached_textures_f);
|
||||||
} else if (!is_visible) {
|
} else {
|
||||||
|
// Not finished preview
|
||||||
|
if (is_visible) {
|
||||||
|
// when not canceled still loading
|
||||||
|
state_text = (face.cancel->load())?
|
||||||
|
_u8L(" No symbol"):
|
||||||
|
_u8L(" ... Loading");
|
||||||
|
} else {
|
||||||
|
// not finished and not visible cancel job
|
||||||
face.is_created = nullptr;
|
face.is_created = nullptr;
|
||||||
face.cancel->store(true);
|
face.cancel->store(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (is_visible && count_opened_fonts < m_gui_cfg->max_count_opened_font_files) {
|
} else if (is_visible && count_opened_fonts < m_gui_cfg->max_count_opened_font_files) {
|
||||||
++count_opened_fonts;
|
++count_opened_fonts;
|
||||||
face.cancel = std::make_shared<std::atomic_bool>(false);
|
face.cancel = std::make_shared<std::atomic_bool>(false);
|
||||||
face.is_created = std::make_shared<bool>(false);
|
face.is_created = std::make_shared<bool>(false);
|
||||||
|
|
||||||
std::string text = m_text.empty() ? "AaBbCc" : m_text;
|
|
||||||
|
|
||||||
const unsigned char gray_level = 5;
|
const unsigned char gray_level = 5;
|
||||||
// format type and level must match to texture data
|
// format type and level must match to texture data
|
||||||
const GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE;
|
const GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE;
|
||||||
const GLint level = 0;
|
const GLint level = 0;
|
||||||
// select next texture index
|
// select next texture index
|
||||||
size_t texture_index = (m_face_names.texture_index + 1) % m_face_names.count_cached_textures;
|
size_t texture_index = (m_face_names.texture_index + 1) % m_face_names.count_cached_textures;
|
||||||
|
|
||||||
// set previous cach as deleted
|
// set previous cach as deleted
|
||||||
for (FaceName &f : m_face_names.faces)
|
for (FaceName &f : m_face_names.faces)
|
||||||
if (f.texture_index == texture_index) {
|
if (f.texture_index == texture_index) {
|
||||||
@ -1805,12 +1818,9 @@ void GLGizmoEmboss::draw_font_preview(FaceName& face, bool is_visible)
|
|||||||
m_face_names.texture_index = texture_index;
|
m_face_names.texture_index = texture_index;
|
||||||
face.texture_index = texture_index;
|
face.texture_index = texture_index;
|
||||||
|
|
||||||
// clear texture
|
|
||||||
|
|
||||||
|
|
||||||
// render text to texture
|
// render text to texture
|
||||||
FontImageData data{
|
FontImageData data{
|
||||||
text,
|
m_text,
|
||||||
face.wx_name,
|
face.wx_name,
|
||||||
m_face_names.encoding,
|
m_face_names.encoding,
|
||||||
m_face_names.texture_id,
|
m_face_names.texture_id,
|
||||||
@ -1827,9 +1837,18 @@ void GLGizmoEmboss::draw_font_preview(FaceName& face, bool is_visible)
|
|||||||
auto job = std::make_unique<CreateFontImageJob>(std::move(data));
|
auto job = std::make_unique<CreateFontImageJob>(std::move(data));
|
||||||
auto &worker = wxGetApp().plater()->get_ui_job_worker();
|
auto &worker = wxGetApp().plater()->get_ui_job_worker();
|
||||||
queue_job(worker, std::move(job));
|
queue_job(worker, std::move(job));
|
||||||
|
} else {
|
||||||
|
// cant start new thread at this moment so wait in queue
|
||||||
|
state_text = _u8L(" ... In queue");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state_text.empty()) {
|
||||||
|
ImGui::SameLine(m_gui_cfg->face_name_texture_offset_x);
|
||||||
|
m_imgui->text(state_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SameLine(m_gui_cfg->face_name_texture_offset_x);
|
ImGui::SameLine(m_gui_cfg->face_name_texture_offset_x);
|
||||||
|
ImTextureID tex_id = (void *) (intptr_t) m_face_names.texture_id;
|
||||||
ImGui::Image(tex_id, size, uv0, uv1);
|
ImGui::Image(tex_id, size, uv0, uv1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2674,7 +2693,6 @@ void GLGizmoEmboss::draw_style_edit() {
|
|||||||
ImGui::TextColored(ImGuiWrapper::COL_ORANGE_DARK, "%s", _u8L("WxFont is not loaded properly.").c_str());
|
ImGui::TextColored(ImGuiWrapper::COL_ORANGE_DARK, "%s", _u8L("WxFont is not loaded properly.").c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exist_stored_style = m_style_manager.exist_stored_style();
|
bool exist_stored_style = m_style_manager.exist_stored_style();
|
||||||
bool exist_change_in_font = is_font_changed(m_style_manager);
|
bool exist_change_in_font = is_font_changed(m_style_manager);
|
||||||
const GuiCfg::Translations &tr = m_gui_cfg->translations;
|
const GuiCfg::Translations &tr = m_gui_cfg->translations;
|
||||||
|
@ -258,6 +258,7 @@ private:
|
|||||||
|
|
||||||
// protection for open too much font files together
|
// protection for open too much font files together
|
||||||
// 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)
|
||||||
|
// This variable must exist until no CreateFontImageJob is running
|
||||||
unsigned int count_opened_font_files = 0;
|
unsigned int count_opened_font_files = 0;
|
||||||
|
|
||||||
// Configuration for texture height
|
// Configuration for texture height
|
||||||
|
@ -19,10 +19,11 @@
|
|||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
using namespace Slic3r::GUI;
|
using namespace Slic3r::GUI;
|
||||||
|
|
||||||
|
const std::string CreateFontImageJob::default_text = "AaBbCc 123";
|
||||||
|
|
||||||
CreateFontImageJob::CreateFontImageJob(FontImageData &&input)
|
CreateFontImageJob::CreateFontImageJob(FontImageData &&input)
|
||||||
: m_input(std::move(input))
|
: m_input(std::move(input))
|
||||||
{
|
{
|
||||||
assert(!m_input.text.empty());
|
|
||||||
assert(wxFontEnumerator::IsValidFacename(m_input.font_name));
|
assert(wxFontEnumerator::IsValidFacename(m_input.font_name));
|
||||||
assert(m_input.gray_level > 0 && m_input.gray_level < 255);
|
assert(m_input.gray_level > 0 && m_input.gray_level < 255);
|
||||||
assert(m_input.texture_id != 0);
|
assert(m_input.texture_id != 0);
|
||||||
@ -41,9 +42,11 @@ void CreateFontImageJob::process(Ctl &ctl)
|
|||||||
if (font_file == nullptr) return;
|
if (font_file == nullptr) return;
|
||||||
|
|
||||||
Emboss::FontFileWithCache font_file_with_cache(std::move(font_file));
|
Emboss::FontFileWithCache font_file_with_cache(std::move(font_file));
|
||||||
FontProp fp;
|
|
||||||
// use only first line of text
|
// use only first line of text
|
||||||
std::string text = m_input.text;
|
std::string& text = m_input.text;
|
||||||
|
if (text.empty())
|
||||||
|
text = default_text; // copy
|
||||||
|
|
||||||
size_t enter_pos = text.find('\n');
|
size_t enter_pos = text.find('\n');
|
||||||
if (enter_pos < text.size()) {
|
if (enter_pos < text.size()) {
|
||||||
// text start with enter
|
// text start with enter
|
||||||
@ -57,12 +60,26 @@ void CreateFontImageJob::process(Ctl &ctl)
|
|||||||
if (cancel->load()) return true;
|
if (cancel->load()) return true;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FontProp fp; // create default font parameters
|
||||||
ExPolygons shapes = Emboss::text2shapes(font_file_with_cache, text.c_str(), fp, was_canceled);
|
ExPolygons shapes = Emboss::text2shapes(font_file_with_cache, text.c_str(), fp, was_canceled);
|
||||||
|
|
||||||
|
// select some character from font e.g. default text
|
||||||
|
if (shapes.empty())
|
||||||
|
shapes = Emboss::text2shapes(font_file_with_cache, default_text.c_str(), fp, was_canceled);
|
||||||
|
if (shapes.empty()) {
|
||||||
|
m_input.cancel->store(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// normalize height of font
|
// normalize height of font
|
||||||
BoundingBox bounding_box;
|
BoundingBox bounding_box;
|
||||||
for (ExPolygon &shape : shapes)
|
for (ExPolygon &shape : shapes)
|
||||||
bounding_box.merge(BoundingBox(shape.contour.points));
|
bounding_box.merge(BoundingBox(shape.contour.points));
|
||||||
if (bounding_box.size().x() < 1 || bounding_box.size().y() < 1) return;
|
if (bounding_box.size().x() < 1 || bounding_box.size().y() < 1) {
|
||||||
|
m_input.cancel->store(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
double scale = m_input.size.y() / (double) bounding_box.size().y();
|
double scale = m_input.size.y() / (double) bounding_box.size().y();
|
||||||
BoundingBoxf bb2(bounding_box.min.cast<double>(),
|
BoundingBoxf bb2(bounding_box.min.cast<double>(),
|
||||||
bounding_box.max.cast<double>());
|
bounding_box.max.cast<double>());
|
||||||
@ -74,7 +91,8 @@ void CreateFontImageJob::process(Ctl &ctl)
|
|||||||
if (m_tex_size.y() > m_input.size.y()) m_tex_size.y() = m_input.size.y();
|
if (m_tex_size.y() > m_input.size.y()) m_tex_size.y() = m_input.size.y();
|
||||||
|
|
||||||
// Set up result
|
// Set up result
|
||||||
m_result = std::vector<unsigned char>(m_tex_size.x() * m_tex_size.y() * 4, {255});
|
unsigned bit_count = 4; // RGBA
|
||||||
|
m_result = std::vector<unsigned char>(m_tex_size.x() * m_tex_size.y() * bit_count, {255});
|
||||||
|
|
||||||
sla::Resolution resolution(m_tex_size.x(), m_tex_size.y());
|
sla::Resolution resolution(m_tex_size.x(), m_tex_size.y());
|
||||||
double pixel_dim = SCALING_FACTOR / scale;
|
double pixel_dim = SCALING_FACTOR / scale;
|
||||||
@ -123,13 +141,17 @@ void CreateFontImageJob::finalize(bool canceled, std::exception_ptr &)
|
|||||||
const GLenum target = GL_TEXTURE_2D;
|
const GLenum target = GL_TEXTURE_2D;
|
||||||
glsafe(::glBindTexture(target, m_input.texture_id));
|
glsafe(::glBindTexture(target, m_input.texture_id));
|
||||||
|
|
||||||
GLint
|
GLsizei w = m_tex_size.x(), h = m_tex_size.y();
|
||||||
w = m_tex_size.x(), h = m_tex_size.y(),
|
GLint xoffset = m_input.size.x() - m_tex_size.x(), // arrange right
|
||||||
xoffset = m_input.size.x() - m_tex_size.x(), // arrange right
|
|
||||||
yoffset = m_input.size.y() * m_input.index;
|
yoffset = m_input.size.y() * m_input.index;
|
||||||
glsafe(::glTexSubImage2D(target, m_input.level, xoffset, yoffset, w, h,
|
glsafe(::glTexSubImage2D(target, m_input.level, xoffset, yoffset, w, h,
|
||||||
m_input.format, m_input.type, m_result.data()));
|
m_input.format, m_input.type, m_result.data()));
|
||||||
|
|
||||||
|
// clear rest of texture
|
||||||
|
std::vector<unsigned char> empty_data(xoffset * h * 4, {0});
|
||||||
|
glsafe(::glTexSubImage2D(target, m_input.level, 0, yoffset, xoffset, h,
|
||||||
|
m_input.format, m_input.type, empty_data.data()));
|
||||||
|
|
||||||
// bind default texture
|
// bind default texture
|
||||||
GLuint no_texture_id = 0;
|
GLuint no_texture_id = 0;
|
||||||
glsafe(::glBindTexture(target, no_texture_id));
|
glsafe(::glBindTexture(target, no_texture_id));
|
||||||
|
@ -68,6 +68,12 @@ public:
|
|||||||
/// <param name="canceled"></param>
|
/// <param name="canceled"></param>
|
||||||
/// <param name=""></param>
|
/// <param name=""></param>
|
||||||
void finalize(bool canceled, std::exception_ptr &) override;
|
void finalize(bool canceled, std::exception_ptr &) override;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text used for generate preview for empty text
|
||||||
|
/// and when no glyph for given m_input.text
|
||||||
|
/// </summary>
|
||||||
|
static const std::string default_text;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r::GUI
|
} // namespace Slic3r::GUI
|
||||||
|
Loading…
Reference in New Issue
Block a user