From bed5232a224060ebf9d0fbc5edc14be49015b3f7 Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Wed, 16 Feb 2022 14:57:57 +0100 Subject: [PATCH] Using unit per em instead of ascent --- src/libslic3r/Emboss.cpp | 11 +++++++++-- src/libslic3r/Emboss.hpp | 12 +++++++++++- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 24 +++++++++++++++++++----- src/slic3r/GUI/Jobs/EmbossJob.cpp | 2 +- src/slic3r/Utils/FontManager.cpp | 13 ++++++------- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index c64269ce17..e4f3853366 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -38,7 +38,7 @@ public: /// ExPolygons with only unique points static ExPolygons dilate_to_unique_points(ExPolygons &expolygons); - // scale and convert flota to int coordinate + // scale and convert float to int coordinate static Point to_point(const stbtt__point &point); }; @@ -118,6 +118,9 @@ std::optional Private::get_glyph(stbtt_fontinfo &font_info, int u } // fix for bad defined fonts glyph.shape = Slic3r::union_ex(glyph_polygons); + + BoundingBox bb(glyph.shape.front().contour.points); + // inner cw - hole // outer ccw - contour return glyph; @@ -481,8 +484,12 @@ std::unique_ptr Emboss::load_font( // load information about line gap int ascent, descent, linegap; stbtt_GetFontVMetrics(info, &ascent, &descent, &linegap); + + float pixels = 1000.; // value is irelevant + float em_pixels = stbtt_ScaleForMappingEmToPixels(info, pixels); + int units_per_em = static_cast(std::round(pixels / em_pixels)); return std::make_unique( - std::move(data), collection_size, ascent, descent, linegap); + std::move(data), collection_size, ascent, descent, linegap, units_per_em); } std::unique_ptr Emboss::load_font(const char *file_path) diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index f18f123bbc..6b7473fb7d 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -45,7 +45,11 @@ public: // description of one letter struct Glyph { + // NOTE: shape is scaled by SHAPE_SCALE + // to be able store points without floating points ExPolygons shape; + + // values are in font points int advance_width=0, left_side_bearing=0; }; // cache for glyph by unicode @@ -68,19 +72,25 @@ public: // vertical position is "scale*(ascent - descent + lineGap)" const int ascent, descent, linegap; + // for convert font units to pixel + int unit_per_em; + Emboss::Glyphs cache; // cache of glyphs FontFile(std::vector &&buffer, unsigned int count, int ascent, int descent, - int linegap) + int linegap, + int unit_per_em + ) : buffer(std::move(buffer)) , index(0) // select default font on index 0 , count(count) , ascent(ascent) , descent(descent) , linegap(linegap) + , unit_per_em(unit_per_em) {} bool operator==(const FontFile &other) const { return index == other.index && diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index b6da157ec1..4c1e1feb04 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -41,7 +41,8 @@ #ifdef ALLOW_DEBUG_MODE #define ALLOW_ADD_FONT_BY_FILE #define ALLOW_ADD_FONT_BY_OS_SELECTOR -#define SHOW_WX_FONT_DESCRIPTOR +#define SHOW_WX_FONT_DESCRIPTOR // OS specific descriptor | file path +#define SHOW_FONT_FILE_PROPERTY // ascent, descent, line gap, cache #define SHOW_IMGUI_ATLAS #define SHOW_ICONS_TEXTURE #define SHOW_FINE_POSITION @@ -51,6 +52,7 @@ #endif // ALLOW_DEBUG_MODE #define SHOW_WX_FONT_DESCRIPTOR +#define SHOW_FONT_FILE_PROPERTY #define ALLOW_ADD_FONT_BY_FILE #define ALLOW_ADD_FONT_BY_OS_SELECTOR #define ALLOW_REVERT_ALL_STYLES @@ -200,10 +202,9 @@ bool GLGizmoEmboss::on_mouse_for_rotation(const wxMouseEvent &mouse_event) // propagate angle into property angle_opt = static_cast(*start_angle + angle); // move to range <-M_PI, M_PI> - if (*angle_opt > M_PI) { - *angle_opt -= 2 * M_PI; - } else if (*angle_opt < -M_PI) { - *angle_opt += 2 * M_PI; + if (*angle_opt > M_PI || *angle_opt < -M_PI) { + int count = static_cast(std::round(*angle_opt / (2 * M_PI))); + *angle_opt -= static_cast(count * 2 * M_PI); } // do not store zero if (std::fabs(*angle_opt) < std::numeric_limits::epsilon()) @@ -1340,6 +1341,19 @@ void GLGizmoEmboss::draw_advanced() ImGui::Text("%s", _u8L("Advanced font options could be change only for corect font.\nStart with select correct font.").c_str()); return; } + +#ifdef SHOW_FONT_FILE_PROPERTY + ImGui::SameLine(); + std::string ff_property = + "ascent=" + std::to_string(font_file->ascent) + + ", descent=" + std::to_string(font_file->descent) + + ", lineGap=" + std::to_string(font_file->linegap) + + ", unitPerEm=" + std::to_string(font_file->unit_per_em) + + ", cache(" + std::to_string(font_file->cache.size()) + " glyphs)"; + if (font_file->count > 1) ff_property += + ", collect=" + std::to_string(font_file->index + 1) + "/" + std::to_string(font_file->count); + m_imgui->text_colored(ImGuiWrapper::COL_GREY_DARK, ff_property); +#endif // SHOW_FONT_FILE_PROPERTY FontProp &font_prop = m_font_manager.get_font_item().prop; bool exist_change = false; diff --git a/src/slic3r/GUI/Jobs/EmbossJob.cpp b/src/slic3r/GUI/Jobs/EmbossJob.cpp index 1d4f5c498c..994568c1d1 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.cpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.cpp @@ -242,7 +242,7 @@ TriangleMesh EmbossCreateJob::create_mesh(const char * text, if (shapes.empty()) return {}; if (ctl.was_canceled()) return {}; - float scale = font_prop.size_in_mm / font.ascent; + float scale = font_prop.size_in_mm / font.unit_per_em; float depth = font_prop.emboss / scale; auto projectZ = std::make_unique(depth); Emboss::ProjectScale project(std::move(projectZ), scale); diff --git a/src/slic3r/Utils/FontManager.cpp b/src/slic3r/Utils/FontManager.cpp index d225a81d87..dc417b90ac 100644 --- a/src/slic3r/Utils/FontManager.cpp +++ b/src/slic3r/Utils/FontManager.cpp @@ -437,7 +437,7 @@ void FontManager::init_style_images(int max_width) { // dot per inch for monitor int dpi = get_dpi_for_window(mf); double ppm = dpi / 25.4; // pixel per milimeter - double scale = font_prop.size_in_mm / font_file->ascent * Emboss::SHAPE_SCALE * ppm; + double scale = font_prop.size_in_mm / font_file->unit_per_em * Emboss::SHAPE_SCALE * ppm; scales[index] = scale; //double scale = font_prop.size_in_mm * SCALING_FACTOR; @@ -494,9 +494,6 @@ void FontManager::init_style_images(int max_width) { sla::Resolution resolution(image.tex_size.x, image.tex_size.y); size_t index = &item - &m_font_list.front(); - //double scale = item.font_item.prop.size_in_mm / SCALING_FACTOR / item.font_file->ascent; - //double scale = item.font_item.prop.size_in_mm; - //sla::PixelDim dim(1 / scale, 1 / scale); double pixel_dim = SCALING_FACTOR / scales[index]; sla::PixelDim dim(pixel_dim, pixel_dim); double gamma = 1.; @@ -567,7 +564,9 @@ ImFont * FontManager::load_imgui_font(size_t index, const std::string &text) const FontProp &font_prop = item.font_item.prop; - float c1 = (font_file.ascent - font_file.descent + font_file.linegap) / (float)font_file.ascent; + // coeficient for convert line height to font size + float c1 = (font_file.ascent - font_file.descent + font_file.linegap) / (float) font_file.unit_per_em; + // The point size is defined as 1/72 of the Anglo-Saxon inch (25.4 mm): // it is approximately 0.0139 inch or 352.8 um. // But it is too small, so I decide use point size as mm for emboss @@ -581,11 +580,11 @@ ImFont * FontManager::load_imgui_font(size_t index, const std::string &text) // TODO: start using merge mode //font_config.MergeMode = true; if (font_prop.char_gap.has_value()) { - float coef = font_size / (double) font_file.ascent; + float coef = font_size / (double) font_file.unit_per_em; font_config.GlyphExtraSpacing.x = coef * (*font_prop.char_gap); } if (font_prop.line_gap.has_value()) { - float coef = font_size / (double) font_file.ascent; + float coef = font_size / (double) font_file.unit_per_em; font_config.GlyphExtraSpacing.y = coef * (*font_prop.line_gap); }