mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-15 06:26:00 +08:00
Constness improvmenet of Emboss::FontFile / FontManager.
FontFile is returned by shared_ptr<const FontFile>, which makes it clear that the FontFile must not be modified. Because FontFile caches glyphs, a global mutex for all FontFile instances was added guarding the glyph cache. FIXME change true type font index in collection atomically, by duplicating the font! font_file->index = i;
This commit is contained in:
parent
1648ae853d
commit
df9220e5a8
@ -24,9 +24,8 @@ public:
|
||||
|
||||
static std::optional<stbtt_fontinfo> load_font_info(const Emboss::FontFile &font);
|
||||
static std::optional<stbtt_fontinfo> load_font_info(const unsigned char *data, unsigned int index = 0);
|
||||
static std::optional<Emboss::Glyph> get_glyph(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,
|
||||
Emboss::Glyphs &cache, std::optional<stbtt_fontinfo> &font_info_opt);
|
||||
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, std::optional<stbtt_fontinfo> &font_info_opt);
|
||||
|
||||
static FontItem create_font_item(std::wstring name, std::wstring path);
|
||||
|
||||
@ -63,7 +62,7 @@ std::optional<stbtt_fontinfo> Private::load_font_info(
|
||||
return font_info;
|
||||
}
|
||||
|
||||
std::optional<Emboss::Glyph> Private::get_glyph(stbtt_fontinfo &font_info, int unicode_letter, float flatness)
|
||||
std::optional<Emboss::Glyph> Private::get_glyph(const stbtt_fontinfo &font_info, int unicode_letter, float flatness)
|
||||
{
|
||||
int glyph_index = stbtt_FindGlyphIndex(&font_info, unicode_letter);
|
||||
if (glyph_index == 0) {
|
||||
@ -128,13 +127,9 @@ std::optional<Emboss::Glyph> Private::get_glyph(
|
||||
int unicode,
|
||||
const Emboss::FontFile & font,
|
||||
const FontProp & font_prop,
|
||||
Emboss::Glyphs & cache,
|
||||
std::optional<stbtt_fontinfo> &font_info_opt)
|
||||
{
|
||||
const double RESOLUTION = 0.0125; // TODO: read from printer configuration
|
||||
auto glyph_item = cache.find(unicode);
|
||||
if (glyph_item != cache.end())
|
||||
return glyph_item->second;
|
||||
|
||||
if (!font_info_opt.has_value()) {
|
||||
font_info_opt = Private::load_font_info(font);
|
||||
@ -182,8 +177,6 @@ std::optional<Emboss::Glyph> Private::get_glyph(
|
||||
// unify multipoints with similar position. Could appear after union
|
||||
dilate_to_unique_points(glyph_opt->shape);
|
||||
|
||||
cache[unicode] = *glyph_opt;
|
||||
|
||||
return glyph_opt;
|
||||
}
|
||||
|
||||
@ -593,7 +586,7 @@ std::optional<Emboss::Glyph> Emboss::letter2glyph(const FontFile &font,
|
||||
return Private::get_glyph(*font_info_opt, letter, flatness);
|
||||
}
|
||||
|
||||
ExPolygons Emboss::text2shapes(FontFile & font,
|
||||
ExPolygons Emboss::text2shapes(const FontFile &font,
|
||||
const char * text,
|
||||
const FontProp &font_prop)
|
||||
{
|
||||
@ -617,14 +610,26 @@ ExPolygons Emboss::text2shapes(FontFile & font,
|
||||
if (wc == '\t') {
|
||||
// '\t' = 4*space => same as imgui
|
||||
const int count_spaces = 4;
|
||||
std::optional<Glyph> space_opt = Private::get_glyph(int(' '), font, font_prop, font.cache, font_info_opt);
|
||||
auto space = int(' ');
|
||||
std::optional<Glyph> space_opt = font.get_glyph(space);
|
||||
if (! space_opt) {
|
||||
space_opt = Private::get_glyph(space, font, font_prop, font_info_opt);
|
||||
if (space_opt)
|
||||
font.cache_glyph(space, *space_opt);
|
||||
}
|
||||
if (!space_opt.has_value()) continue;
|
||||
cursor.x() += count_spaces * space_opt->advance_width;
|
||||
continue;
|
||||
}
|
||||
|
||||
int unicode = static_cast<int>(wc);
|
||||
std::optional<Glyph> glyph_opt = Private::get_glyph(unicode, font, font_prop, font.cache, font_info_opt);
|
||||
std::optional<Glyph> glyph_opt = font.get_glyph(unicode);
|
||||
if (! glyph_opt) {
|
||||
glyph_opt = Private::get_glyph(unicode, font, font_prop, font_info_opt);
|
||||
if (glyph_opt)
|
||||
font.cache_glyph(unicode, *glyph_opt);
|
||||
}
|
||||
|
||||
if (!glyph_opt.has_value()) continue;
|
||||
|
||||
// move glyph to cursor position
|
||||
@ -652,7 +657,7 @@ void Emboss::apply_transformation(const FontProp &font_prop,
|
||||
}
|
||||
}
|
||||
|
||||
bool Emboss::is_italic(FontFile &font) {
|
||||
bool Emboss::is_italic(const FontFile &font) {
|
||||
std::optional<stbtt_fontinfo> font_info_opt =
|
||||
Private::load_font_info(font);
|
||||
|
||||
@ -814,3 +819,32 @@ Transform3d Emboss::create_transformation_onto_surface(const Vec3f &position,
|
||||
transform.rotate(up_rot);
|
||||
return transform;
|
||||
}
|
||||
|
||||
static std::mutex FontFile_cache_mutex;
|
||||
|
||||
std::optional<Emboss::Glyph> Emboss::FontFile::get_glyph(int unicode) const
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(FontFile_cache_mutex);
|
||||
auto glyph_item = m_cache.find(unicode);
|
||||
if (glyph_item != m_cache.end())
|
||||
return glyph_item->second;
|
||||
return {};
|
||||
}
|
||||
|
||||
void Emboss::FontFile::cache_glyph(int unicode, Emboss::Glyph glyph) const
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(FontFile_cache_mutex);
|
||||
m_cache[unicode] = std::move(glyph);
|
||||
}
|
||||
|
||||
void Emboss::FontFile::clear_glyph_cache() const
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(FontFile_cache_mutex);
|
||||
m_cache.clear();
|
||||
}
|
||||
|
||||
size_t Emboss::FontFile::glyph_cache_size() const
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(FontFile_cache_mutex);
|
||||
return m_cache.size();
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include <set>
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <admesh/stl.h> // indexed_triangle_set
|
||||
#include "Polygon.hpp"
|
||||
#include "ExPolygon.hpp"
|
||||
@ -75,8 +76,6 @@ public:
|
||||
// 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,
|
||||
@ -97,6 +96,17 @@ public:
|
||||
buffer.size() == other.buffer.size() &&
|
||||
buffer == other.buffer;
|
||||
}
|
||||
|
||||
std::optional<Emboss::Glyph> get_glyph(int unicode) const;
|
||||
// These two methods modifying cache are marked as const, because their
|
||||
// access to the cache is guarded by a global mutex specific to all FontFile instances.
|
||||
void cache_glyph(int unicode, Emboss::Glyph glyph) const;
|
||||
void clear_glyph_cache() const;
|
||||
size_t glyph_cache_size() const;
|
||||
|
||||
private:
|
||||
// Cache of glyphs, guarded by a global mutex specific to all FontFile instances.
|
||||
mutable Emboss::Glyphs m_cache;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@ -130,7 +140,7 @@ public:
|
||||
/// <param name="text">Characters to convert</param>
|
||||
/// <param name="font_prop">User defined property of the font</param>
|
||||
/// <returns>Inner polygon cw(outer ccw)</returns>
|
||||
static ExPolygons text2shapes(FontFile & font,
|
||||
static ExPolygons text2shapes(const FontFile &font,
|
||||
const char * text,
|
||||
const FontProp &font_prop);
|
||||
|
||||
@ -149,7 +159,7 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="font">Selector of font</param>
|
||||
/// <returns>True when the font description contains italic/obligue otherwise False</returns>
|
||||
static bool is_italic(FontFile &font);
|
||||
static bool is_italic(const FontFile &font);
|
||||
|
||||
/// <summary>
|
||||
/// Project 2d point into space
|
||||
|
@ -662,7 +662,7 @@ bool GLGizmoEmboss::process()
|
||||
if (m_volume == nullptr) return false;
|
||||
|
||||
// exist loaded font?
|
||||
std::shared_ptr<Emboss::FontFile>& font_file = m_font_manager.get_font_file();
|
||||
std::shared_ptr<const Emboss::FontFile>& font_file = m_font_manager.get_font_file();
|
||||
if (font_file == nullptr) return false;
|
||||
auto data = std::make_unique<EmbossDataUpdate>(font_file,
|
||||
create_configuration(),
|
||||
@ -1224,7 +1224,7 @@ void GLGizmoEmboss::draw_style_list() {
|
||||
bool GLGizmoEmboss::italic_button()
|
||||
{
|
||||
std::optional<wxFont> &wx_font = m_font_manager.get_wx_font();
|
||||
std::shared_ptr<Emboss::FontFile> &font_file = m_font_manager.get_font_file();
|
||||
std::shared_ptr<const 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;
|
||||
@ -1266,7 +1266,7 @@ bool GLGizmoEmboss::italic_button()
|
||||
|
||||
bool GLGizmoEmboss::bold_button() {
|
||||
std::optional<wxFont> &wx_font = m_font_manager.get_wx_font();
|
||||
std::shared_ptr<Emboss::FontFile> &font_file = m_font_manager.get_font_file();
|
||||
std::shared_ptr<const 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;
|
||||
@ -1576,7 +1576,7 @@ void GLGizmoEmboss::do_rotate(float relative_z_angle)
|
||||
|
||||
void GLGizmoEmboss::draw_advanced()
|
||||
{
|
||||
std::shared_ptr<Emboss::FontFile>& font_file = m_font_manager.get_font_file();
|
||||
std::shared_ptr<const Emboss::FontFile>& font_file = m_font_manager.get_font_file();
|
||||
if (font_file == nullptr) {
|
||||
ImGui::Text("%s", _u8L("Advanced font options could be change only for corect font.\nStart with select correct font.").c_str());
|
||||
return;
|
||||
@ -1589,7 +1589,7 @@ void GLGizmoEmboss::draw_advanced()
|
||||
", 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)";
|
||||
", cache(" + std::to_string(font_file->glyph_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);
|
||||
@ -1698,7 +1698,8 @@ void GLGizmoEmboss::draw_advanced()
|
||||
ImGui::PushID(1 << (10 + i));
|
||||
bool is_selected = i == font_file->index;
|
||||
if (ImGui::Selectable(std::to_string(i).c_str(), is_selected)) {
|
||||
font_file->index = i;
|
||||
//FIXME change true type font index in collection atomically, by duplicating the font!
|
||||
// font_file->index = i;
|
||||
exist_change = true;
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
@ -241,7 +241,7 @@ TriangleMesh EmbossCreateJob::create_default_mesh()
|
||||
}
|
||||
|
||||
TriangleMesh EmbossCreateJob::create_mesh(const char * text,
|
||||
Emboss::FontFile &font,
|
||||
const Emboss::FontFile &font,
|
||||
const FontProp & font_prop,
|
||||
Ctl & ctl)
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
/// <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 Emboss::FontFile &font,
|
||||
const FontProp & font_prop,
|
||||
Ctl & ctl);
|
||||
|
||||
@ -62,12 +62,12 @@ private:
|
||||
struct EmbossDataBase
|
||||
{
|
||||
// Pointer on Data of font (glyph shapes)
|
||||
std::shared_ptr<Emboss::FontFile> font_file;
|
||||
std::shared_ptr<const Emboss::FontFile> font_file;
|
||||
// font item is not used for create object
|
||||
TextConfiguration text_configuration;
|
||||
// new volume name created from text
|
||||
std::string volume_name;
|
||||
EmbossDataBase(std::shared_ptr<Emboss::FontFile> font_file,
|
||||
EmbossDataBase(std::shared_ptr<const Emboss::FontFile> font_file,
|
||||
TextConfiguration text_configuration,
|
||||
std::string volume_name)
|
||||
: font_file(std::move(font_file))
|
||||
@ -88,7 +88,7 @@ struct EmbossDataUpdate : public EmbossDataBase
|
||||
// unique identifier of volume to change
|
||||
// Change of volume change id, last change could disapear
|
||||
// ObjectID volume_id;
|
||||
EmbossDataUpdate(std::shared_ptr<Emboss::FontFile> font_file,
|
||||
EmbossDataUpdate(std::shared_ptr<const Emboss::FontFile> font_file,
|
||||
TextConfiguration text_configuration,
|
||||
std::string volume_name,
|
||||
ModelVolume * volume)
|
||||
@ -125,7 +125,7 @@ struct EmbossDataCreate: public EmbossDataBase
|
||||
// It is inside of GLGizmoEmboss object,
|
||||
// so I hope it will survive
|
||||
|
||||
EmbossDataCreate(std::shared_ptr<Emboss::FontFile> font_file,
|
||||
EmbossDataCreate(std::shared_ptr<const Emboss::FontFile> font_file,
|
||||
const TextConfiguration & text_configuration,
|
||||
const std::string & volume_name,
|
||||
ModelVolumeType volume_type,
|
||||
|
@ -146,7 +146,7 @@ void FontManager::add_fonts(FontList font_list)
|
||||
add_font(fi);
|
||||
}
|
||||
|
||||
std::shared_ptr<Emboss::FontFile> &FontManager::get_font_file()
|
||||
std::shared_ptr<const Emboss::FontFile> &FontManager::get_font_file()
|
||||
{
|
||||
// TODO: fix not selected font
|
||||
//if (!is_activ_font()) return nullptr;
|
||||
@ -367,7 +367,7 @@ void FontManager::create_texture(size_t index, const std::string &text, GLuint&
|
||||
if (index >= m_font_list.size()) return;
|
||||
Item &item = m_font_list[index];
|
||||
const FontProp &font_prop = item.font_item.prop;
|
||||
std::shared_ptr<Emboss::FontFile> &font_file = item.font_file;
|
||||
std::shared_ptr<const Emboss::FontFile> &font_file = item.font_file;
|
||||
if (font_file == nullptr && !set_up_font_file(index)) return;
|
||||
ExPolygons shapes = Emboss::text2shapes(*font_file, text.c_str(), font_prop);
|
||||
|
||||
@ -415,7 +415,7 @@ void FontManager::init_style_images(int max_width) {
|
||||
for (Item &item : m_font_list) {
|
||||
FontItem & font_item = item.font_item;
|
||||
const FontProp & font_prop = font_item.prop;
|
||||
std::shared_ptr<Emboss::FontFile> &font_file = item.font_file;
|
||||
std::shared_ptr<const Emboss::FontFile> &font_file = item.font_file;
|
||||
size_t index = &item - &m_font_list.front();
|
||||
if (font_file == nullptr && !set_up_font_file(index)) continue;
|
||||
if (font_file == nullptr) continue;
|
||||
@ -520,10 +520,10 @@ void FontManager::init_style_images(int max_width) {
|
||||
|
||||
void FontManager::free_style_images() {
|
||||
if (!is_activ_font()) return;
|
||||
std::shared_ptr<Emboss::FontFile> &font_file =
|
||||
std::shared_ptr<const Emboss::FontFile> &font_file =
|
||||
m_font_list[m_font_selected].font_file;
|
||||
if(font_file != nullptr)
|
||||
font_file->cache.clear();
|
||||
if (font_file != nullptr)
|
||||
font_file->clear_glyph_cache();
|
||||
|
||||
if (!m_exist_style_images) return;
|
||||
GLuint tex_id = (GLuint) (intptr_t) m_font_list.front().image->texture_id;
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
void add_fonts(FontList font_list);
|
||||
|
||||
// getter on active font file for access to glyphs
|
||||
std::shared_ptr<Emboss::FontFile> &get_font_file();
|
||||
std::shared_ptr<const Emboss::FontFile> &get_font_file();
|
||||
|
||||
// getter on active font item for access to font property
|
||||
const FontItem &get_font_item() const;
|
||||
@ -137,7 +137,7 @@ public:
|
||||
std::string truncated_name;
|
||||
|
||||
// share font file data with emboss job thread
|
||||
std::shared_ptr<Emboss::FontFile> font_file = nullptr;
|
||||
std::shared_ptr<const Emboss::FontFile> font_file;
|
||||
|
||||
std::optional<size_t> imgui_font_index;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user