Fix add '\t' functionality

This commit is contained in:
Filip Sykala 2021-09-22 12:07:40 +02:00
parent b7d136d205
commit a812f74ca3
3 changed files with 50 additions and 30 deletions

View File

@ -18,7 +18,8 @@ public:
static std::optional<stbtt_fontinfo> load_font_info(const Emboss::Font &font); static std::optional<stbtt_fontinfo> load_font_info(const Emboss::Font &font);
static std::optional<Emboss::Glyph> get_glyph(stbtt_fontinfo &font_info, int unicode_letter, float flatness = 2.f); static std::optional<Emboss::Glyph> get_glyph(stbtt_fontinfo &font_info, int unicode_letter, float flatness = 2.f);
static std::optional<Emboss::Glyph> get_glyph(int unicode, const Emboss::Font &font, const FontProp &font_prop,
Emboss::Glyphs &cache, std::optional<stbtt_fontinfo> &font_info_opt);
static FontItem create_font_item(std::wstring name, std::wstring path); static FontItem create_font_item(std::wstring name, std::wstring path);
}; };
@ -89,12 +90,39 @@ std::optional<Emboss::Glyph> Privat::get_glyph(stbtt_fontinfo &font_info, int un
glyph_polygons.emplace_back(pts); glyph_polygons.emplace_back(pts);
} }
// fix for bad defined fonts // fix for bad defined fonts
glyph.polygons = union_ex(glyph_polygons); glyph.shape = union_ex(glyph_polygons);
// inner cw - hole // inner cw - hole
// outer ccw - contour // outer ccw - contour
return glyph; return glyph;
} }
std::optional<Emboss::Glyph> Privat::get_glyph(
int unicode,
const Emboss::Font & font,
const FontProp & font_prop,
Emboss::Glyphs & cache,
std::optional<stbtt_fontinfo> &font_info_opt)
{
auto glyph_item = cache.find(unicode);
if (glyph_item != cache.end())
return glyph_item->second;
if (!font_info_opt.has_value()) {
font_info_opt = Privat::load_font_info(font);
// can load font info?
if (!font_info_opt.has_value()) return {};
}
std::optional<Emboss::Glyph> glyph_opt =
Privat::get_glyph(*font_info_opt, unicode, font_prop.flatness);
// IMPROVE: multiple loadig glyph without data
// has definition inside of font?
if (!glyph_opt.has_value()) return {};
cache[unicode] = *glyph_opt;
return glyph_opt;
}
FontItem Privat::create_font_item(std::wstring name, std::wstring path) { FontItem Privat::create_font_item(std::wstring name, std::wstring path) {
return FontItem(boost::nowide::narrow(name.c_str()), return FontItem(boost::nowide::narrow(name.c_str()),
boost::nowide::narrow(path.c_str())); boost::nowide::narrow(path.c_str()));
@ -496,31 +524,25 @@ ExPolygons Emboss::text2shapes(Font & font,
cursor.y() -= font.ascent - font.descent + font.linegap + font_prop.line_gap; cursor.y() -= font.ascent - font.descent + font.linegap + font_prop.line_gap;
continue; continue;
} }
int unicode = static_cast<int>(wc); if (wc == '\t') {
std::optional<Glyph> glyph_opt; // '\t' = 4*space => same as imgui
auto glyph_item = font.cache.find(unicode); const int count_spaces = 4;
if (glyph_item != font.cache.end()) std::optional<Glyph> space_opt = Privat::get_glyph(int(' '), font, font_prop, font.cache, font_info_opt);
glyph_opt = glyph_item->second; if (!space_opt.has_value()) continue;
else { cursor.x() += count_spaces *(space_opt->advance_width + font_prop.char_gap);
if (!font_info_opt.has_value()) { continue;
font_info_opt = Privat::load_font_info(font);
// can load font info?
if (!font_info_opt.has_value()) return {};
}
glyph_opt = Privat::get_glyph(*font_info_opt, unicode,
font_prop.flatness);
// IMPROVE: multiple loadig glyph without data
// has definition inside of font?
if (!glyph_opt.has_value()) continue;
font.cache[unicode] = *glyph_opt;
} }
int unicode = static_cast<int>(wc);
std::optional<Glyph> glyph_opt = Privat::get_glyph(unicode, font, font_prop, font.cache, font_info_opt);
if (!glyph_opt.has_value()) continue;
// move glyph to cursor position // move glyph to cursor position
ExPolygons polygons = glyph_opt->polygons; // copy ExPolygons expolygons = glyph_opt->shape; // copy
for (ExPolygon &polygon : polygons) for (ExPolygon &expolygon : expolygons)
polygon.translate(cursor); expolygon.translate(cursor);
cursor.x() += glyph_opt->advance_width + font_prop.char_gap; cursor.x() += glyph_opt->advance_width + font_prop.char_gap;
expolygons_append(result, polygons); expolygons_append(result, expolygons);
} }
return union_ex(result); return union_ex(result);
// TODO: simplify after union! Do NOT create 2 close vertices (may cause problem in triangulation) // TODO: simplify after union! Do NOT create 2 close vertices (may cause problem in triangulation)

View File

@ -41,8 +41,8 @@ public:
// description of one letter // description of one letter
struct Glyph struct Glyph
{ {
ExPolygons polygons; ExPolygons shape;
int advance_width, left_side_bearing; int advance_width, left_side_bearing;
}; };
// cache for glyph by unicode // cache for glyph by unicode
using Glyphs = std::map<int, Glyph>; using Glyphs = std::map<int, Glyph>;

View File

@ -87,13 +87,11 @@ void GLGizmoEmboss::on_render_for_picking() {}
void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit) void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
{ {
check_selection(); check_selection();
int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoCollapse; ImGuiWindowFlags_NoCollapse;
m_imgui->begin(on_get_name(), flag); m_imgui->begin(on_get_name(), flag);
draw_window(); draw_window();
m_imgui->end();
m_imgui->end(); //
} }
void GLGizmoEmboss::on_set_state() void GLGizmoEmboss::on_set_state()
@ -341,7 +339,7 @@ void GLGizmoEmboss::draw_window()
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
if (ImGui::Button("add svg")) choose_svg_file(); //if (ImGui::Button("add svg")) choose_svg_file();
if (ImGui::InputFloat("Size[in mm]", &m_font_prop.size_in_mm)) { if (ImGui::InputFloat("Size[in mm]", &m_font_prop.size_in_mm)) {
if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10; if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10;
@ -361,7 +359,7 @@ void GLGizmoEmboss::draw_window()
// if (ImGui::InputFloat3("Normal", m_normal.data())) m_normal.normalize(); // if (ImGui::InputFloat3("Normal", m_normal.data())) m_normal.normalize();
// if (ImGui::InputFloat3("Up", m_up.data())) m_up.normalize(); // if (ImGui::InputFloat3("Up", m_up.data())) m_up.normalize();
ImVec2 input_size(-FLT_MIN, ImGui::GetTextLineHeight() * 6); ImVec2 input_size(-FLT_MIN, ImGui::GetTextLineHeight() * 6);
ImGuiInputTextFlags flags = ImGuiInputTextFlags flags =
ImGuiInputTextFlags_::ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_::ImGuiInputTextFlags_AllowTabInput |
ImGuiInputTextFlags_::ImGuiInputTextFlags_AutoSelectAll ImGuiInputTextFlags_::ImGuiInputTextFlags_AutoSelectAll