emboss do not twice copy glyph when acess to cache

This commit is contained in:
Filip Sykala 2022-03-25 09:15:41 +01:00
parent f68d03eb87
commit 87fc2c4298

View File

@ -24,7 +24,9 @@ public:
Private() = delete; Private() = delete;
static std::optional<stbtt_fontinfo> load_font_info(const unsigned char *data, unsigned int index = 0); static std::optional<stbtt_fontinfo> load_font_info(const unsigned char *data, unsigned int index = 0);
static std::optional<Emboss::Glyph> get_glyph(const stbtt_fontinfo &font_info, int unicode_letter, float flatness); static std::optional<Emboss::Glyph> get_glyph(const stbtt_fontinfo &font_info, int unicode_letter, float flatness);
static std::optional<Emboss::Glyph> get_glyph(int unicode, const Emboss::FontFile &font, const FontProp &font_prop,
// take glyph from cache
static const Emboss::Glyph* get_glyph(int unicode, const Emboss::FontFile &font, const FontProp &font_prop,
Emboss::Glyphs &cache, std::optional<stbtt_fontinfo> &font_info_opt); 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);
@ -124,7 +126,7 @@ std::optional<Emboss::Glyph> Private::get_glyph(const stbtt_fontinfo &font_info,
return glyph; return glyph;
} }
std::optional<Emboss::Glyph> Private::get_glyph( const Emboss::Glyph* Private::get_glyph(
int unicode, int unicode,
const Emboss::FontFile & font, const Emboss::FontFile & font,
const FontProp & font_prop, const FontProp & font_prop,
@ -133,16 +135,15 @@ std::optional<Emboss::Glyph> Private::get_glyph(
{ {
const double RESOLUTION = 0.0125; // TODO: read from printer configuration const double RESOLUTION = 0.0125; // TODO: read from printer configuration
auto glyph_item = cache.find(unicode); auto glyph_item = cache.find(unicode);
if (glyph_item != cache.end()) if (glyph_item != cache.end()) return &glyph_item->second;
return glyph_item->second;
if (!font_info_opt.has_value()) { if (!font_info_opt.has_value()) {
unsigned int font_index = font_prop.collection_number.has_value()? unsigned int font_index = font_prop.collection_number.has_value()?
*font_prop.collection_number : 0; *font_prop.collection_number : 0;
if (font_index >= font.count) return {}; if (font_index >= font.count) return nullptr;
font_info_opt = Private::load_font_info(font.data->data(), font_index); font_info_opt = Private::load_font_info(font.data->data(), font_index);
// can load font info? // can load font info?
if (!font_info_opt.has_value()) return {}; if (!font_info_opt.has_value()) return nullptr;
} }
float flatness = static_cast<float>( float flatness = static_cast<float>(
font.ascent * RESOLUTION / font_prop.size_in_mm); font.ascent * RESOLUTION / font_prop.size_in_mm);
@ -151,7 +152,7 @@ std::optional<Emboss::Glyph> Private::get_glyph(
// IMPROVE: multiple loadig glyph without data // IMPROVE: multiple loadig glyph without data
// has definition inside of font? // has definition inside of font?
if (!glyph_opt.has_value()) return {}; if (!glyph_opt.has_value()) return nullptr;
if (font_prop.char_gap.has_value()) if (font_prop.char_gap.has_value())
glyph_opt->advance_width += *font_prop.char_gap; glyph_opt->advance_width += *font_prop.char_gap;
@ -184,10 +185,9 @@ std::optional<Emboss::Glyph> Private::get_glyph(
glyph_opt->shape = Slic3r::union_ex(glyph_opt->shape); glyph_opt->shape = Slic3r::union_ex(glyph_opt->shape);
// unify multipoints with similar position. Could appear after union // unify multipoints with similar position. Could appear after union
dilate_to_unique_points(glyph_opt->shape); dilate_to_unique_points(glyph_opt->shape);
auto it = cache.insert({unicode, std::move(*glyph_opt)});
cache[unicode] = *glyph_opt; assert(it.second);
return &it.first->second;
return glyph_opt;
} }
FontItem Private::create_font_item(std::wstring name, std::wstring path) { FontItem Private::create_font_item(std::wstring name, std::wstring path) {
@ -619,24 +619,24 @@ ExPolygons Emboss::text2shapes(FontFileWithCache &font_with_cache,
if (wc == '\t') { if (wc == '\t') {
// '\t' = 4*space => same as imgui // '\t' = 4*space => same as imgui
const int count_spaces = 4; const int count_spaces = 4;
std::optional<Glyph> space_opt = Private::get_glyph(int(' '), font, font_prop, cache, font_info_opt); const Glyph* space = Private::get_glyph(int(' '), font, font_prop, cache, font_info_opt);
if (!space_opt.has_value()) continue; if (space == nullptr) continue;
cursor.x() += count_spaces * space_opt->advance_width; cursor.x() += count_spaces * space->advance_width;
continue; continue;
} }
if (wc == '\r') continue; if (wc == '\r') continue;
int unicode = static_cast<int>(wc); int unicode = static_cast<int>(wc);
std::optional<Glyph> glyph_opt = Private::get_glyph(unicode, font, font_prop, cache, font_info_opt); const Glyph* glyph_ptr = Private::get_glyph(unicode, font, font_prop, cache, font_info_opt);
if (!glyph_opt.has_value()) continue; if (glyph_ptr == nullptr) continue;
// move glyph to cursor position // move glyph to cursor position
ExPolygons expolygons = glyph_opt->shape; // copy ExPolygons expolygons = glyph_ptr->shape; // copy
for (ExPolygon &expolygon : expolygons) for (ExPolygon &expolygon : expolygons)
expolygon.translate(cursor); expolygon.translate(cursor);
cursor.x() += glyph_opt->advance_width; cursor.x() += glyph_ptr->advance_width;
expolygons_append(result, expolygons); expolygons_append(result, std::move(expolygons));
} }
result = Slic3r::union_ex(result); result = Slic3r::union_ex(result);
return Private::dilate_to_unique_points(result); return Private::dilate_to_unique_points(result);