create emboss text mesh on same place as update

fix:
Un Itelic redraw
../src/slic3r/Utils/WxFontUtils.hpp:49:77: error: non-const lvalue reference to type 'shared_ptr<...>' cannot bind to a temporary of type 'shared_ptr<...>'
../src/slic3r/Utils/WxFontUtils.hpp:55:75: error: non-const lvalue reference to type 'shared_ptr<...>' cannot bind to a temporary of type 'shared_ptr<...>'
This commit is contained in:
Filip Sykala 2022-01-31 13:17:24 +01:00
parent d10fd37b2f
commit af69a4f2de
7 changed files with 105 additions and 90 deletions

View File

@ -82,6 +82,11 @@ public:
, descent(descent) , descent(descent)
, linegap(linegap) , linegap(linegap)
{} {}
bool operator==(const FontFile &other) const {
return index == other.index &&
buffer.size() == other.buffer.size() &&
buffer == other.buffer;
}
}; };
/// <summary> /// <summary>

View File

@ -738,7 +738,8 @@ void GLGizmoEmboss::draw_font_list()
wxFontEnumerator::IsValidFacename(face_name)) { wxFontEnumerator::IsValidFacename(face_name)) {
// Select font // Select font
wxFont wx_font(wxFontInfo().FaceName(face_name).Encoding(encoding)); wxFont wx_font(wxFontInfo().FaceName(face_name).Encoding(encoding));
m_font_manager.set_wx_font(wx_font); if(m_font_manager.set_wx_font(wx_font))
process();
} }
ImGui::PopID(); ImGui::PopID();
} }
@ -963,10 +964,11 @@ void GLGizmoEmboss::draw_style_list() {
//store_font_item_to_app_config(); //store_font_item_to_app_config();
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
if (is_changed) if (is_changed) {
ImGui::SetTooltip("%s", _u8L("Save current settings to selected style").c_str()); ImGui::SetTooltip("%s", _u8L("Save current settings to selected style").c_str());
else } else {
ImGui::SetTooltip("%s", _u8L("No changes to save into style").c_str()); ImGui::SetTooltip("%s", _u8L("No changes to save into style").c_str());
}
if (is_changed) { if (is_changed) {
ImGui::SameLine(); ImGui::SameLine();
@ -981,7 +983,8 @@ void GLGizmoEmboss::draw_style_list() {
bool GLGizmoEmboss::italic_button() bool GLGizmoEmboss::italic_button()
{ {
std::optional<wxFont> &wx_font = m_font_manager.get_wx_font(); std::optional<wxFont> &wx_font = m_font_manager.get_wx_font();
if (!wx_font.has_value()) { std::shared_ptr<Emboss::FontFile> &font_file = m_font_manager.get_font_file();
if (!wx_font.has_value() || font_file == nullptr) {
draw_icon(IconType::italic, IconState::disabled); draw_icon(IconType::italic, IconState::disabled);
return false; return false;
} }
@ -991,18 +994,24 @@ bool GLGizmoEmboss::italic_button()
if (is_font_italic) { if (is_font_italic) {
if (draw_button(IconType::unitalic)) { if (draw_button(IconType::unitalic)) {
skew.reset(); skew.reset();
wx_font->SetStyle(wxFontStyle::wxFONTSTYLE_NORMAL); if (wx_font->GetStyle() != wxFontStyle::wxFONTSTYLE_NORMAL) {
wx_font->SetStyle(wxFontStyle::wxFONTSTYLE_NORMAL);
font_file = WxFontUtils::create_font_file(*wx_font);
}
return true; return true;
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Unset italic").c_str()); ImGui::SetTooltip("%s", _u8L("Unset italic").c_str());
} else { } else {
if (draw_button(IconType::italic)) { if (draw_button(IconType::italic)) {
std::shared_ptr<Emboss::FontFile> &font_file = auto new_ff = WxFontUtils::set_italic(*wx_font, *font_file);
m_font_manager.get_font_file(); if (new_ff) {
bool is_set = WxFontUtils::set_italic(*wx_font, font_file); font_file = std::move(new_ff);
// add skew when wxFont can't set it } else {
if (!is_set) skew = 0.2f; // italic font doesn't exist
// add skew when wxFont can't set it
skew = 0.2f;
}
return true; return true;
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
@ -1013,7 +1022,8 @@ bool GLGizmoEmboss::italic_button()
bool GLGizmoEmboss::bold_button() { bool GLGizmoEmboss::bold_button() {
std::optional<wxFont> &wx_font = m_font_manager.get_wx_font(); std::optional<wxFont> &wx_font = m_font_manager.get_wx_font();
if (!wx_font.has_value()) { std::shared_ptr<Emboss::FontFile> &font_file = m_font_manager.get_font_file();
if (!wx_font.has_value() || font_file==nullptr) {
draw_icon(IconType::bold, IconState::disabled); draw_icon(IconType::bold, IconState::disabled);
return false; return false;
} }
@ -1023,18 +1033,24 @@ bool GLGizmoEmboss::bold_button() {
if (is_font_bold) { if (is_font_bold) {
if (draw_button(IconType::unbold)) { if (draw_button(IconType::unbold)) {
boldness.reset(); boldness.reset();
wx_font->SetWeight(wxFontWeight::wxFONTWEIGHT_NORMAL); if (wx_font->GetWeight() != wxFontWeight::wxFONTWEIGHT_NORMAL) {
wx_font->SetWeight(wxFontWeight::wxFONTWEIGHT_NORMAL);
font_file = WxFontUtils::create_font_file(*wx_font);
}
return true; return true;
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
ImGui::SetTooltip("%s", _u8L("Unset bold").c_str()); ImGui::SetTooltip("%s", _u8L("Unset bold").c_str());
} else { } else {
if (draw_button(IconType::bold)) { if (draw_button(IconType::bold)) {
std::shared_ptr<Emboss::FontFile> &font_file = auto new_ff = WxFontUtils::set_bold(*wx_font, *font_file);
m_font_manager.get_font_file(); if (new_ff) {
bool is_set = WxFontUtils::set_bold(*wx_font, font_file); font_file = std::move(new_ff);
// add boldness when wxFont can't set it } else {
if (!is_set) boldness = 20.f; // bold font can't be loaded
// set up boldness
boldness = 20.f;
}
return true; return true;
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
@ -1182,13 +1198,13 @@ void GLGizmoEmboss::set_minimal_window_size(bool is_edit_style,
{ {
ImVec2 window_size = ImGui::GetWindowSize(); ImVec2 window_size = ImGui::GetWindowSize();
const ImVec2& min_win_size_prev = get_minimal_window_size(); const ImVec2& min_win_size_prev = get_minimal_window_size();
ImVec2 diff(window_size.x - min_win_size_prev.x, //ImVec2 diff(window_size.x - min_win_size_prev.x,
window_size.y - min_win_size_prev.y); // window_size.y - min_win_size_prev.y);
float diff_y = ImGui::GetWindowSize().y - get_minimal_window_size().y; float diff_y = ImGui::GetWindowSize().y - get_minimal_window_size().y;
m_is_edit_style = is_edit_style; m_is_edit_style = is_edit_style;
m_is_advanced_edit_style = is_advance_edit_style; m_is_advanced_edit_style = is_advance_edit_style;
const ImVec2 &min_win_size = get_minimal_window_size(); const ImVec2 &min_win_size = get_minimal_window_size();
ImGui::SetWindowSize(ImVec2(0.f, min_win_size.y + diff.y), ImGui::SetWindowSize(ImVec2(0.f, min_win_size.y + diff_y),
ImGuiCond_Always); ImGuiCond_Always);
} }

View File

@ -20,36 +20,13 @@ using namespace GUI;
void EmbossUpdateJob::process(Ctl &ctl) void EmbossUpdateJob::process(Ctl &ctl)
{ {
// Changing cursor to busy must be inside main thread
// GTK is not thread safe.
//wxBeginBusyCursor();
//ScopeGuard sg([]() { wxEndBusyCursor(); });
// only for sure
assert(m_input != nullptr);
// check if exist valid font // check if exist valid font
if (m_input->font_file == nullptr) return; if (m_input->font_file == nullptr) return;
const TextConfiguration &cfg = m_input->text_configuration; const TextConfiguration &cfg = m_input->text_configuration;
const std::string & text = cfg.text; m_result = EmbossCreateJob::create_mesh(
// Do NOT process empty string cfg.text.c_str(), *m_input->font_file, cfg.font_item.prop, ctl);
if (text.empty()) return; if (m_result.its.empty()) return;
const FontProp &prop = cfg.font_item.prop;
ExPolygons shapes = Emboss::text2shapes(*m_input->font_file, text.c_str(), prop);
if (ctl.was_canceled()) return;
// exist 2d shape made by text ?
// (no shape means that font hasn't any of text symbols)
if (shapes.empty()) return;
float scale = prop.size_in_mm / m_input->font_file->ascent;
auto projectZ = std::make_unique<Emboss::ProjectZ>(prop.emboss / scale);
Emboss::ProjectScale project(std::move(projectZ), scale);
m_result = TriangleMesh(Emboss::polygons2model(shapes, project));
if (ctl.was_canceled()) return; if (ctl.was_canceled()) return;
// center triangle mesh // center triangle mesh
@ -121,7 +98,7 @@ void EmbossCreateJob::process(Ctl &ctl) {
create_default_mesh() : create_default_mesh() :
create_mesh(m_input->text_configuration.text.c_str(), create_mesh(m_input->text_configuration.text.c_str(),
*m_input->font_file, *m_input->font_file,
m_input->text_configuration.font_item.prop); m_input->text_configuration.font_item.prop, ctl);
if (m_result.its.empty()) m_result = create_default_mesh(); if (m_result.its.empty()) m_result = create_default_mesh();
if (ctl.was_canceled()) return; if (ctl.was_canceled()) return;
@ -258,12 +235,17 @@ TriangleMesh EmbossCreateJob::create_default_mesh()
TriangleMesh EmbossCreateJob::create_mesh(const char * text, TriangleMesh EmbossCreateJob::create_mesh(const char * text,
Emboss::FontFile &font, Emboss::FontFile &font,
const FontProp & font_prop) const FontProp & font_prop,
Ctl & ctl)
{ {
ExPolygons shapes = Emboss::text2shapes(font, text, font_prop); ExPolygons shapes = Emboss::text2shapes(font, text, font_prop);
float scale = font_prop.size_in_mm / font.ascent; if (shapes.empty()) return {};
float depth = font_prop.emboss / scale; if (ctl.was_canceled()) return {};
auto projectZ = std::make_unique<Emboss::ProjectZ>(depth);
float scale = font_prop.size_in_mm / font.ascent;
float depth = font_prop.emboss / scale;
auto projectZ = std::make_unique<Emboss::ProjectZ>(depth);
Emboss::ProjectScale project(std::move(projectZ), scale); Emboss::ProjectScale project(std::move(projectZ), scale);
if (ctl.was_canceled()) return {};
return TriangleMesh(Emboss::polygons2model(shapes, project)); return TriangleMesh(Emboss::polygons2model(shapes, project));
} }

View File

@ -36,20 +36,22 @@ public:
void process(Ctl &ctl) override; void process(Ctl &ctl) override;
void finalize(bool canceled, std::exception_ptr &) override; void finalize(bool canceled, std::exception_ptr &) override;
private: // <summary>
static TriangleMesh create_default_mesh();
/// <summary>
/// Create mesh from text /// Create mesh from text
/// </summary> /// </summary>
/// <param name="text">Text to convert on mesh</param> /// <param name="text">Text to convert on mesh</param>
/// <param name="font">Define shape of characters. /// <param name="font">Define shape of characters.
/// NOTE: Can't be const cache glyphs</param> /// NOTE: Can't be const cache glyphs</param>
/// <param name="font_prop">Property of font</param> /// <param name="font_prop">Property of font</param>
/// <param name="ctl">Control for job, check of cancelation</param>
/// <returns>Triangle mesh model</returns> /// <returns>Triangle mesh model</returns>
static TriangleMesh create_mesh(const char * text, static TriangleMesh create_mesh(const char * text,
Emboss::FontFile &font, Emboss::FontFile &font,
const FontProp & font_prop); const FontProp & font_prop,
Ctl & ctl);
private:
static TriangleMesh create_default_mesh();
}; };

View File

@ -239,31 +239,30 @@ bool WxFontUtils::is_bold(const wxFont &font) {
return wx_weight != wxFONTWEIGHT_NORMAL; return wx_weight != wxFONTWEIGHT_NORMAL;
} }
bool WxFontUtils::set_italic(wxFont &font, std::shared_ptr<Emboss::FontFile>& font_file) std::unique_ptr<Emboss::FontFile> WxFontUtils::set_italic(wxFont &font, const Emboss::FontFile &font_file)
{ {
static std::vector<wxFontStyle> italic_styles = { static std::vector<wxFontStyle> italic_styles = {
wxFontStyle::wxFONTSTYLE_ITALIC, wxFontStyle::wxFONTSTYLE_ITALIC,
wxFontStyle::wxFONTSTYLE_SLANT wxFontStyle::wxFONTSTYLE_SLANT
}; };
if (font_file == nullptr)
font_file = WxFontUtils::create_font_file(font);
for (wxFontStyle style : italic_styles) { for (wxFontStyle style : italic_styles) {
font.SetStyle(style); font.SetStyle(style);
std::unique_ptr<Emboss::FontFile> act_font_file = WxFontUtils::create_font_file(font); std::unique_ptr<Emboss::FontFile> new_font_file =
if (act_font_file == nullptr) continue; WxFontUtils::create_font_file(font);
// can create italic font?
if (new_font_file == nullptr) continue;
// is still same font file pointer? // is still same font file pointer?
if (font_file != nullptr) if (font_file == *new_font_file) continue;
if (act_font_file->buffer == font_file->buffer) continue;
font_file = std::move(act_font_file); return new_font_file;
return true;
} }
return false; return nullptr;
} }
bool WxFontUtils::set_bold(wxFont &font, std::shared_ptr<Emboss::FontFile>& font_file) std::unique_ptr<Emboss::FontFile> WxFontUtils::set_bold(wxFont &font, const Emboss::FontFile& font_file)
{ {
static std::vector<wxFontWeight> bold_weight = { static std::vector<wxFontWeight> bold_weight = {
wxFontWeight::wxFONTWEIGHT_BOLD, wxFontWeight::wxFONTWEIGHT_BOLD,
@ -271,18 +270,19 @@ bool WxFontUtils::set_bold(wxFont &font, std::shared_ptr<Emboss::FontFile>& font
wxFontWeight::wxFONTWEIGHT_EXTRABOLD, wxFontWeight::wxFONTWEIGHT_EXTRABOLD,
wxFontWeight::wxFONTWEIGHT_EXTRAHEAVY wxFontWeight::wxFONTWEIGHT_EXTRAHEAVY
}; };
if (font_file == nullptr)
font_file = WxFontUtils::create_font_file(font);
for (wxFontWeight weight : bold_weight) { for (wxFontWeight weight : bold_weight) {
font.SetWeight(weight); font.SetWeight(weight);
std::unique_ptr<Emboss::FontFile> act_font_file = WxFontUtils::create_font_file(font); std::unique_ptr<Emboss::FontFile> new_font_file =
if (act_font_file == nullptr) continue; WxFontUtils::create_font_file(font);
if (font_file != nullptr)
// is still same font? // can create bold font file?
if (act_font_file->buffer == font_file->buffer) continue; if (new_font_file == nullptr) continue;
font_file = std::move(act_font_file);
return true; // is still same font file pointer?
if (font_file == *new_font_file) continue;
return new_font_file;
} }
return false; return nullptr;
} }

View File

@ -42,17 +42,25 @@ public:
static bool is_italic(const wxFont &font); static bool is_italic(const wxFont &font);
static bool is_bold(const wxFont &font); static bool is_bold(const wxFont &font);
// Font could not support italic than return FALSE. /// <summary>
// For check of support is neccessary font file pointer. /// Set italic into wx font
// Font file is optional it could be created inside of function, but it slow down. /// When italic font is same as original return nullptr.
// To not load font file twice on success font_file contain new created font file. /// To not load font file twice on success is font_file returned.
static bool set_italic(wxFont &font, std::shared_ptr<Emboss::FontFile>& font_file = std::shared_ptr<Emboss::FontFile>()); /// </summary>
/// <param name="font">wx descriptor of font</param>
/// <param name="font_file">file described in wx font</param>
/// <returns>New created font fileon success otherwise nullptr</returns>
static std::unique_ptr<Emboss::FontFile> set_italic(wxFont &font, const Emboss::FontFile& prev_font_file);
// Font could not support bold than return FALSE. /// <summary>
// For check of support is neccessary font file pointer. /// Set boldness into wx font
// Font file is optional it could be created inside of function, but it slow down. /// When bolded font is same as original return nullptr.
// To not load font file twice on success font_file contain new created font file. /// To not load font file twice on success is font_file returned.
static bool set_bold(wxFont &font, std::shared_ptr<Emboss::FontFile>& font_file = std::shared_ptr<Emboss::FontFile>()); /// </summary>
/// <param name="font">wx descriptor of font</param>
/// <param name="font_file">file described in wx font</param>
/// <returns>New created font fileon success otherwise nullptr</returns>
static std::unique_ptr<Emboss::FontFile> set_bold(wxFont &font, const Emboss::FontFile& font_file);
// map to convert wxFont type to string and vice versa // map to convert wxFont type to string and vice versa
static const std::map<wxFontFamily, std::string> from_family; static const std::map<wxFontFamily, std::string> from_family;

View File

@ -272,9 +272,11 @@ TEST_CASE("Simplify frog_legs.obj to 5% by IGL/qslim", "[]")
indexed_triangle_set its_out; indexed_triangle_set its_out;
its_out.vertices.reserve(U.size()/3); its_out.vertices.reserve(U.size()/3);
its_out.indices.reserve(G.size()/3); its_out.indices.reserve(G.size()/3);
for (size_t i = 0; i < U.size()/3; i++) size_t U_size = U.size() / 3;
for (size_t i = 0; i < U_size; i++)
its_out.vertices.emplace_back(U(i, 0), U(i, 1), U(i, 2)); its_out.vertices.emplace_back(U(i, 0), U(i, 1), U(i, 2));
for (size_t i = 0; i < G.size()/3; i++) size_t G_size = G.size() / 3;
for (size_t i = 0; i < G_size; i++)
its_out.indices.emplace_back(G(i, 0), G(i, 1), G(i, 2)); its_out.indices.emplace_back(G(i, 0), G(i, 1), G(i, 2));
// check if algorithm is still worse than our // check if algorithm is still worse than our