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)
|
||||
{
|
||||
// Limit for opened font files at one moment
|
||||
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());
|
||||
// set to pixel 0,0 in texture
|
||||
ImVec2 uv0(0.f, 0.f), uv1(1.f / size.x, 1.f / size.y / m_face_names.count_cached_textures);
|
||||
ImTextureID tex_id = (void *) (intptr_t) m_face_names.texture_id;
|
||||
float count_cached_textures_f = static_cast<float>(m_face_names.count_cached_textures);
|
||||
std::string state_text;
|
||||
// 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) {
|
||||
// not created preview
|
||||
if (*face.is_created) {
|
||||
// Already created preview
|
||||
size_t texture_index = face.texture_index;
|
||||
uv0 = ImVec2(0.f, texture_index / (float) m_face_names.count_cached_textures),
|
||||
uv1 = ImVec2(1.f, (texture_index + 1) / (float) m_face_names.count_cached_textures);
|
||||
} else if (!is_visible) {
|
||||
face.is_created = nullptr;
|
||||
face.cancel->store(true);
|
||||
uv0 = ImVec2(0.f, texture_index / count_cached_textures_f);
|
||||
uv1 = ImVec2(1.f, (texture_index + 1) / count_cached_textures_f);
|
||||
} 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.cancel->store(true);
|
||||
}
|
||||
}
|
||||
} else if (is_visible && count_opened_fonts < m_gui_cfg->max_count_opened_font_files) {
|
||||
++count_opened_fonts;
|
||||
face.cancel = std::make_shared<std::atomic_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;
|
||||
// format type and level must match to texture data
|
||||
const GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE;
|
||||
const GLint level = 0;
|
||||
// select next texture index
|
||||
size_t texture_index = (m_face_names.texture_index + 1) % m_face_names.count_cached_textures;
|
||||
|
||||
// set previous cach as deleted
|
||||
for (FaceName &f : m_face_names.faces)
|
||||
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;
|
||||
face.texture_index = texture_index;
|
||||
|
||||
// clear texture
|
||||
|
||||
|
||||
// render text to texture
|
||||
FontImageData data{
|
||||
text,
|
||||
m_text,
|
||||
face.wx_name,
|
||||
m_face_names.encoding,
|
||||
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 &worker = wxGetApp().plater()->get_ui_job_worker();
|
||||
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);
|
||||
ImTextureID tex_id = (void *) (intptr_t) m_face_names.texture_id;
|
||||
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());
|
||||
return;
|
||||
}
|
||||
|
||||
bool exist_stored_style = m_style_manager.exist_stored_style();
|
||||
bool exist_change_in_font = is_font_changed(m_style_manager);
|
||||
const GuiCfg::Translations &tr = m_gui_cfg->translations;
|
||||
|
@ -258,6 +258,7 @@ private:
|
||||
|
||||
// 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)
|
||||
// This variable must exist until no CreateFontImageJob is running
|
||||
unsigned int count_opened_font_files = 0;
|
||||
|
||||
// Configuration for texture height
|
||||
|
@ -19,10 +19,11 @@
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
const std::string CreateFontImageJob::default_text = "AaBbCc 123";
|
||||
|
||||
CreateFontImageJob::CreateFontImageJob(FontImageData &&input)
|
||||
: m_input(std::move(input))
|
||||
{
|
||||
assert(!m_input.text.empty());
|
||||
assert(wxFontEnumerator::IsValidFacename(m_input.font_name));
|
||||
assert(m_input.gray_level > 0 && m_input.gray_level < 255);
|
||||
assert(m_input.texture_id != 0);
|
||||
@ -41,9 +42,11 @@ void CreateFontImageJob::process(Ctl &ctl)
|
||||
if (font_file == nullptr) return;
|
||||
|
||||
Emboss::FontFileWithCache font_file_with_cache(std::move(font_file));
|
||||
FontProp fp;
|
||||
// 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');
|
||||
if (enter_pos < text.size()) {
|
||||
// text start with enter
|
||||
@ -57,24 +60,39 @@ void CreateFontImageJob::process(Ctl &ctl)
|
||||
if (cancel->load()) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
FontProp fp; // create default font parameters
|
||||
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
|
||||
BoundingBox bounding_box;
|
||||
for (ExPolygon &shape : shapes)
|
||||
bounding_box.merge(BoundingBox(shape.contour.points));
|
||||
if (bounding_box.size().x() < 1 || bounding_box.size().y() < 1) return;
|
||||
double scale = m_input.size.y() / (double) bounding_box.size().y();
|
||||
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();
|
||||
BoundingBoxf bb2(bounding_box.min.cast<double>(),
|
||||
bounding_box.max.cast<double>());
|
||||
bb2.scale(scale);
|
||||
Vec2d size_f = bb2.size();
|
||||
m_tex_size = Point(std::ceil(size_f.x()), std::ceil(size_f.y()));
|
||||
m_tex_size = Point(std::ceil(size_f.x()), std::ceil(size_f.y()));
|
||||
// crop image width
|
||||
if (m_tex_size.x() > m_input.size.x()) m_tex_size.x() = m_input.size.x();
|
||||
if (m_tex_size.y() > m_input.size.y()) m_tex_size.y() = m_input.size.y();
|
||||
|
||||
// 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());
|
||||
double pixel_dim = SCALING_FACTOR / scale;
|
||||
@ -123,13 +141,17 @@ void CreateFontImageJob::finalize(bool canceled, std::exception_ptr &)
|
||||
const GLenum target = GL_TEXTURE_2D;
|
||||
glsafe(::glBindTexture(target, m_input.texture_id));
|
||||
|
||||
GLint
|
||||
w = m_tex_size.x(), h = m_tex_size.y(),
|
||||
xoffset = m_input.size.x() - m_tex_size.x(), // arrange right
|
||||
yoffset = m_input.size.y() * m_input.index;
|
||||
GLsizei w = m_tex_size.x(), h = m_tex_size.y();
|
||||
GLint xoffset = m_input.size.x() - m_tex_size.x(), // arrange right
|
||||
yoffset = m_input.size.y() * m_input.index;
|
||||
glsafe(::glTexSubImage2D(target, m_input.level, xoffset, yoffset, w, h,
|
||||
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
|
||||
GLuint no_texture_id = 0;
|
||||
glsafe(::glBindTexture(target, no_texture_id));
|
||||
|
@ -68,6 +68,12 @@ public:
|
||||
/// <param name="canceled"></param>
|
||||
/// <param name=""></param>
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user