Using unit per em instead of ascent

This commit is contained in:
Filip Sykala 2022-02-16 14:57:57 +01:00
parent 7208fc571e
commit bed5232a22
5 changed files with 46 additions and 16 deletions

View file

@ -38,7 +38,7 @@ public:
/// <returns>ExPolygons with only unique points</returns>
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<Emboss::Glyph> 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::FontFile> 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<int>(std::round(pixels / em_pixels));
return std::make_unique<Emboss::FontFile>(
std::move(data), collection_size, ascent, descent, linegap);
std::move(data), collection_size, ascent, descent, linegap, units_per_em);
}
std::unique_ptr<Emboss::FontFile> Emboss::load_font(const char *file_path)

View file

@ -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<unsigned char> &&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 &&

View file

@ -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<float>(*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<int>(std::round(*angle_opt / (2 * M_PI)));
*angle_opt -= static_cast<float>(count * 2 * M_PI);
}
// do not store zero
if (std::fabs(*angle_opt) < std::numeric_limits<float>::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;

View file

@ -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<Emboss::ProjectZ>(depth);
Emboss::ProjectScale project(std::move(projectZ), scale);

View file

@ -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);
}