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)
, linegap(linegap)
{}
bool operator==(const FontFile &other) const {
return index == other.index &&
buffer.size() == other.buffer.size() &&
buffer == other.buffer;
}
};
/// <summary>

View File

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

View File

@ -20,36 +20,13 @@ using namespace GUI;
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
if (m_input->font_file == nullptr) return;
const TextConfiguration &cfg = m_input->text_configuration;
const std::string & text = cfg.text;
// Do NOT process empty string
if (text.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));
m_result = EmbossCreateJob::create_mesh(
cfg.text.c_str(), *m_input->font_file, cfg.font_item.prop, ctl);
if (m_result.its.empty()) return;
if (ctl.was_canceled()) return;
// center triangle mesh
@ -121,7 +98,7 @@ void EmbossCreateJob::process(Ctl &ctl) {
create_default_mesh() :
create_mesh(m_input->text_configuration.text.c_str(),
*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 (ctl.was_canceled()) return;
@ -258,12 +235,17 @@ TriangleMesh EmbossCreateJob::create_default_mesh()
TriangleMesh EmbossCreateJob::create_mesh(const char * text,
Emboss::FontFile &font,
const FontProp & font_prop)
const FontProp & font_prop,
Ctl & ctl)
{
ExPolygons shapes = Emboss::text2shapes(font, text, font_prop);
if (shapes.empty()) return {};
if (ctl.was_canceled()) return {};
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);
if (ctl.was_canceled()) return {};
return TriangleMesh(Emboss::polygons2model(shapes, project));
}

View File

@ -36,20 +36,22 @@ public:
void process(Ctl &ctl) override;
void finalize(bool canceled, std::exception_ptr &) override;
private:
static TriangleMesh create_default_mesh();
/// <summary>
// <summary>
/// Create mesh from text
/// </summary>
/// <param name="text">Text to convert on mesh</param>
/// <param name="font">Define shape of characters.
/// NOTE: Can't be const cache glyphs</param>
/// <param name="font_prop">Property of font</param>
/// <param name="ctl">Control for job, check of cancelation</param>
/// <returns>Triangle mesh model</returns>
static TriangleMesh create_mesh(const char * text,
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;
}
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 = {
wxFontStyle::wxFONTSTYLE_ITALIC,
wxFontStyle::wxFONTSTYLE_SLANT
};
if (font_file == nullptr)
font_file = WxFontUtils::create_font_file(font);
for (wxFontStyle style : italic_styles) {
font.SetStyle(style);
std::unique_ptr<Emboss::FontFile> act_font_file = WxFontUtils::create_font_file(font);
if (act_font_file == nullptr) continue;
std::unique_ptr<Emboss::FontFile> new_font_file =
WxFontUtils::create_font_file(font);
// can create italic font?
if (new_font_file == nullptr) continue;
// is still same font file pointer?
if (font_file != nullptr)
if (act_font_file->buffer == font_file->buffer) continue;
if (font_file == *new_font_file) continue;
font_file = std::move(act_font_file);
return true;
return new_font_file;
}
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 = {
wxFontWeight::wxFONTWEIGHT_BOLD,
@ -271,18 +270,19 @@ bool WxFontUtils::set_bold(wxFont &font, std::shared_ptr<Emboss::FontFile>& font
wxFontWeight::wxFONTWEIGHT_EXTRABOLD,
wxFontWeight::wxFONTWEIGHT_EXTRAHEAVY
};
if (font_file == nullptr)
font_file = WxFontUtils::create_font_file(font);
for (wxFontWeight weight : bold_weight) {
font.SetWeight(weight);
std::unique_ptr<Emboss::FontFile> act_font_file = WxFontUtils::create_font_file(font);
if (act_font_file == nullptr) continue;
if (font_file != nullptr)
// is still same font?
if (act_font_file->buffer == font_file->buffer) continue;
font_file = std::move(act_font_file);
return true;
std::unique_ptr<Emboss::FontFile> new_font_file =
WxFontUtils::create_font_file(font);
// can create bold font file?
if (new_font_file == nullptr) continue;
// 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_bold(const wxFont &font);
// Font could not support italic than return FALSE.
// For check of support is neccessary font file pointer.
// Font file is optional it could be created inside of function, but it slow down.
// To not load font file twice on success font_file contain new created font file.
static bool set_italic(wxFont &font, std::shared_ptr<Emboss::FontFile>& font_file = std::shared_ptr<Emboss::FontFile>());
/// <summary>
/// Set italic into wx font
/// When italic font is same as original return nullptr.
/// To not load font file twice on success is font_file returned.
/// </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.
// For check of support is neccessary font file pointer.
// Font file is optional it could be created inside of function, but it slow down.
// To not load font file twice on success font_file contain new created font file.
static bool set_bold(wxFont &font, std::shared_ptr<Emboss::FontFile>& font_file = std::shared_ptr<Emboss::FontFile>());
/// <summary>
/// Set boldness into wx font
/// When bolded font is same as original return nullptr.
/// To not load font file twice on success is font_file returned.
/// </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
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;
its_out.vertices.reserve(U.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));
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));
// check if algorithm is still worse than our