mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-17 11:35:56 +08:00
Store font list into App configuration
This commit is contained in:
parent
976407fdb1
commit
ffba045734
@ -39,6 +39,7 @@ static const std::string VERSION_CHECK_URL = "https://files.prusa3d.com/wp-conte
|
|||||||
|
|
||||||
const std::string AppConfig::SECTION_FILAMENTS = "filaments";
|
const std::string AppConfig::SECTION_FILAMENTS = "filaments";
|
||||||
const std::string AppConfig::SECTION_MATERIALS = "sla_materials";
|
const std::string AppConfig::SECTION_MATERIALS = "sla_materials";
|
||||||
|
const std::string AppConfig::SECTION_EMBOSS = "emboss";
|
||||||
|
|
||||||
void AppConfig::reset()
|
void AppConfig::reset()
|
||||||
{
|
{
|
||||||
|
@ -168,6 +168,7 @@ public:
|
|||||||
|
|
||||||
static const std::string SECTION_FILAMENTS;
|
static const std::string SECTION_FILAMENTS;
|
||||||
static const std::string SECTION_MATERIALS;
|
static const std::string SECTION_MATERIALS;
|
||||||
|
static const std::string SECTION_EMBOSS;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -57,15 +57,16 @@ std::optional<Emboss::Glyph> Privat::get_glyph(stbtt_fontinfo &font_info, int un
|
|||||||
if (num_verts <= 0) return glyph; // no shape
|
if (num_verts <= 0) return glyph; // no shape
|
||||||
|
|
||||||
int *contour_lengths = NULL;
|
int *contour_lengths = NULL;
|
||||||
int num_countour = 0;
|
int num_countour_int = 0;
|
||||||
|
|
||||||
stbtt__point *points = stbtt_FlattenCurves(vertices, num_verts,
|
stbtt__point *points = stbtt_FlattenCurves(vertices, num_verts,
|
||||||
flatness, &contour_lengths, &num_countour, font_info.userdata);
|
flatness, &contour_lengths, &num_countour_int, font_info.userdata);
|
||||||
|
|
||||||
|
size_t num_contour = static_cast<size_t>(num_countour_int);
|
||||||
Polygons glyph_polygons;
|
Polygons glyph_polygons;
|
||||||
glyph_polygons.reserve(num_countour);
|
glyph_polygons.reserve(num_contour);
|
||||||
size_t pi = 0; // point index
|
size_t pi = 0; // point index
|
||||||
for (size_t ci = 0; ci < num_countour; ++ci) {
|
for (size_t ci = 0; ci < num_contour; ++ci) {
|
||||||
int length = contour_lengths[ci];
|
int length = contour_lengths[ci];
|
||||||
// check minimal length for triangle
|
// check minimal length for triangle
|
||||||
if (length < 4) {
|
if (length < 4) {
|
||||||
@ -77,9 +78,8 @@ std::optional<Emboss::Glyph> Privat::get_glyph(stbtt_fontinfo &font_info, int un
|
|||||||
--length;
|
--length;
|
||||||
Points pts;
|
Points pts;
|
||||||
pts.reserve(length);
|
pts.reserve(length);
|
||||||
for (size_t i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
const stbtt__point &point = points[pi];
|
const stbtt__point &point = points[pi++];
|
||||||
++pi;
|
|
||||||
pts.emplace_back(point.x, point.y);
|
pts.emplace_back(point.x, point.y);
|
||||||
}
|
}
|
||||||
// last point is first point
|
// last point is first point
|
||||||
|
@ -15,94 +15,138 @@ const char TextConfigurationSerialization::separator = '|';
|
|||||||
|
|
||||||
std::string TextConfigurationSerialization::serialize(const TextConfiguration &text_configuration)
|
std::string TextConfigurationSerialization::serialize(const TextConfiguration &text_configuration)
|
||||||
{
|
{
|
||||||
// IMPROVE: make general and move to string utils
|
size_t size = 1 + 3 + 5;
|
||||||
auto twice_separator = [](const std::string& data) {
|
std::vector<std::string> columns;
|
||||||
// no value is one space
|
columns.reserve(size);
|
||||||
if (data.empty()) return std::string(" ");
|
columns.emplace_back(text_configuration.text);
|
||||||
std::string::size_type pos = data.find(separator);
|
to_columns(text_configuration.font_item, columns);
|
||||||
if (pos == data.npos) return data;
|
to_columns(text_configuration.font_prop, columns);
|
||||||
// twice all separator inside data
|
assert(columns.size() == size);
|
||||||
std::string copy = data;
|
return serialize(columns, separator);
|
||||||
do {
|
|
||||||
copy.insert(pos, 1, separator);
|
|
||||||
pos += 2;
|
|
||||||
} while (copy.npos != (pos = copy.find(separator, pos)));
|
|
||||||
return copy;
|
|
||||||
};
|
|
||||||
|
|
||||||
const FontItem &font_item = text_configuration.font_item;
|
|
||||||
const FontProp &font_prop = text_configuration.font_prop;
|
|
||||||
return twice_separator(text_configuration.text) + separator +
|
|
||||||
twice_separator(font_item.name) + separator +
|
|
||||||
twice_separator(font_item.path) + separator +
|
|
||||||
to_string.at(font_item.type) + separator +
|
|
||||||
std::to_string(font_prop.emboss) + separator +
|
|
||||||
std::to_string(font_prop.flatness) + separator +
|
|
||||||
std::to_string(font_prop.size_in_mm) + separator +
|
|
||||||
std::to_string(font_prop.char_gap) + separator +
|
|
||||||
std::to_string(font_prop.line_gap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<TextConfiguration> TextConfigurationSerialization::deserialize(const std::string &data)
|
std::optional<TextConfiguration> TextConfigurationSerialization::deserialize(const std::string &data)
|
||||||
{
|
{
|
||||||
// IMPROVE: make general and move to string utils
|
size_t size = 1 + 3 + 5;
|
||||||
auto reduce_separator = [](const std::string& item) {
|
std::vector<std::string> columns;
|
||||||
std::string::size_type pos = item.find(separator);
|
columns.reserve(size);
|
||||||
if (pos == item.npos) return item;
|
deserialize(data, separator, columns);
|
||||||
std::string copy = item;
|
assert(columns.size() == size);
|
||||||
do {
|
|
||||||
assert(copy[pos] == separator);
|
|
||||||
assert(copy[pos+1] == separator);
|
|
||||||
copy.erase(pos, size_t(1));
|
|
||||||
pos = copy.find(separator, pos + 1);
|
|
||||||
} while (pos != copy.npos);
|
|
||||||
return copy;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string::size_type start = 0;
|
const std::string& text = columns[0];
|
||||||
auto get_column_and_move = [&data, &start](){
|
std::optional<FontItem> font_item = get_font_item(columns, 1);
|
||||||
// IMPROVE: make function general and move to string utils
|
if (!font_item.has_value()) return {};
|
||||||
auto find_separator = [&data](std::string::size_type pos) {
|
std::optional<FontProp> font_prop = get_font_prop(columns, 4);
|
||||||
pos = data.find(separator, pos);
|
if (!font_prop.has_value()) return {};
|
||||||
while (pos != data.npos && data[pos + 1] == separator)
|
|
||||||
pos = data.find(separator, pos + 2);
|
|
||||||
return pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (start == data.npos) return std::string();
|
return TextConfiguration(*font_item, *font_prop, text);
|
||||||
std::string::size_type size = find_separator(start) - start;
|
}
|
||||||
if (size == 0) return std::string();
|
|
||||||
std::string result = data.substr(start, size);
|
std::string TextConfigurationSerialization::serialize(const FontList &font_list)
|
||||||
// move start column to next position
|
{
|
||||||
start += size + 1;
|
std::vector<std::string> columns;
|
||||||
return result;
|
columns.reserve(3 * font_list.size());
|
||||||
};
|
for (const FontItem &fi : font_list) to_columns(fi, columns);
|
||||||
|
return serialize(columns, separator);
|
||||||
auto get_float_and_move = [&get_column_and_move]() {
|
}
|
||||||
std::string column = get_column_and_move();
|
|
||||||
if (column.empty()) return 0.f;
|
FontList TextConfigurationSerialization::deserialize_font_list(const std::string &data)
|
||||||
return static_cast<float>(std::atof(column.c_str()));
|
{
|
||||||
};
|
std::vector<std::string> columns;
|
||||||
auto get_int_and_move = [&get_column_and_move]() {
|
deserialize(data, separator, columns);
|
||||||
std::string column = get_column_and_move();
|
if ((columns.size() % 3) != 0) return {};
|
||||||
if (column.empty()) return 0;
|
size_t count = columns.size() / 3;
|
||||||
return std::atoi(column.c_str());
|
FontList fl;
|
||||||
};
|
fl.reserve(count);
|
||||||
|
for (size_t i = 0; i < count; i++)
|
||||||
std::string text = reduce_separator(get_column_and_move());
|
{
|
||||||
std::string name = reduce_separator(get_column_and_move());
|
std::optional<FontItem> fi = get_font_item(columns, i * 3);
|
||||||
std::string path = reduce_separator(get_column_and_move());
|
if (!fi.has_value()) return {};
|
||||||
std::string type = reduce_separator(get_column_and_move());
|
fl.emplace_back(*fi);
|
||||||
auto it = to_type.find(type);
|
}
|
||||||
if (it == to_type.end()) return {}; // no valid type
|
return fl;
|
||||||
FontItem font_item(name,path,it->second);
|
}
|
||||||
|
|
||||||
FontProp font_prop;
|
std::string TextConfigurationSerialization::serialize(const std::vector<std::string> &columns, char separator)
|
||||||
font_prop.emboss = get_float_and_move();
|
{
|
||||||
font_prop.flatness = get_float_and_move();
|
std::string result;
|
||||||
font_prop.size_in_mm = get_float_and_move();
|
const std::string separator_str = std::string(" ") + separator + ' ';
|
||||||
font_prop.char_gap = get_int_and_move();
|
bool is_first = true;
|
||||||
if (start == data.npos) return {}; // no valid data
|
for (const std::string& column : columns) {
|
||||||
font_prop.line_gap = get_int_and_move();
|
if (is_first) is_first = false;
|
||||||
return TextConfiguration(font_item, font_prop, text);
|
else result += separator_str;
|
||||||
|
result += twice(column, separator);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextConfigurationSerialization::deserialize(const std::string &data, char separator, std::vector<std::string> &columns)
|
||||||
|
{
|
||||||
|
if (data.empty()) return;
|
||||||
|
|
||||||
|
size_t position = 0;
|
||||||
|
while (position < data.size()) {
|
||||||
|
size_t start = position;
|
||||||
|
position = find_odd(data, position+1, separator);
|
||||||
|
size_t size = position - start;
|
||||||
|
|
||||||
|
// is not last column
|
||||||
|
if (position != data.size()) {
|
||||||
|
assert(size != 0);
|
||||||
|
--size;
|
||||||
|
}
|
||||||
|
// is not first column
|
||||||
|
if (start != 0) {
|
||||||
|
// previous separator + space = 2
|
||||||
|
start+=2;
|
||||||
|
assert(size >=2);
|
||||||
|
size-=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string column = data.substr(start, size);
|
||||||
|
|
||||||
|
// heal column
|
||||||
|
columns.emplace_back(reduce(column, separator));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextConfigurationSerialization::to_columns(
|
||||||
|
const FontItem &font_item, std::vector<std::string> &columns)
|
||||||
|
{
|
||||||
|
columns.emplace_back(font_item.name);
|
||||||
|
columns.emplace_back(font_item.path);
|
||||||
|
columns.emplace_back(to_string.at(font_item.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FontItem> TextConfigurationSerialization::get_font_item(
|
||||||
|
const std::vector<std::string> &columns, size_t offset)
|
||||||
|
{
|
||||||
|
if (columns.size() <= (offset + 2)) return {}; // no enough columns
|
||||||
|
auto it = to_type.find(columns[offset+2]);
|
||||||
|
FontItem::Type type = (it != to_type.end()) ?
|
||||||
|
it->second : FontItem::Type::undefined;
|
||||||
|
return FontItem(columns[offset], columns[offset + 1], type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextConfigurationSerialization::to_columns(
|
||||||
|
const FontProp& font_prop, std::vector<std::string> &columns)
|
||||||
|
{
|
||||||
|
columns.emplace_back(std::to_string(font_prop.emboss));
|
||||||
|
columns.emplace_back(std::to_string(font_prop.flatness));
|
||||||
|
columns.emplace_back(std::to_string(font_prop.size_in_mm));
|
||||||
|
columns.emplace_back(std::to_string(font_prop.char_gap));
|
||||||
|
columns.emplace_back(std::to_string(font_prop.line_gap));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FontProp> TextConfigurationSerialization::get_font_prop(
|
||||||
|
const std::vector<std::string> &columns, size_t offset)
|
||||||
|
{
|
||||||
|
if (columns.size() <= (offset + 4)) return {}; // no enough columns
|
||||||
|
FontProp font_prop;
|
||||||
|
font_prop.emboss = static_cast<float>(std::atof(columns[offset].c_str()));
|
||||||
|
font_prop.flatness = static_cast<float>(std::atof(columns[offset+1].c_str()));
|
||||||
|
font_prop.size_in_mm = static_cast<float>(std::atof(columns[offset+2].c_str()));
|
||||||
|
font_prop.char_gap = static_cast<float>(std::atof(columns[offset+3].c_str()));
|
||||||
|
font_prop.line_gap = std::atoi(columns[offset+4].c_str());
|
||||||
|
return font_prop;
|
||||||
}
|
}
|
@ -14,16 +14,100 @@ class TextConfigurationSerialization
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextConfigurationSerialization() = delete; // only static functions
|
TextConfigurationSerialization() = delete; // only static functions
|
||||||
|
|
||||||
|
// store / load TextConfiguration - .3mf files
|
||||||
static std::string serialize(const TextConfiguration &text_configuration);
|
static std::string serialize(const TextConfiguration &text_configuration);
|
||||||
static std::optional<TextConfiguration> deserialize(const std::string &data);
|
static std::optional<TextConfiguration> deserialize(const std::string &data);
|
||||||
|
|
||||||
|
// store / load FontList - AppConfig
|
||||||
|
static std::string serialize(const FontList &font_list);
|
||||||
|
static FontList deserialize_font_list(const std::string &data);
|
||||||
|
|
||||||
|
private:
|
||||||
// convert type to string and vice versa
|
// convert type to string and vice versa
|
||||||
static const std::map<std::string, FontItem::Type> to_type;
|
static const std::map<std::string, FontItem::Type> to_type;
|
||||||
static const std::map<FontItem::Type, std::string> to_string;
|
static const std::map<FontItem::Type, std::string> to_string;
|
||||||
|
|
||||||
static const char separator;
|
static const char separator;
|
||||||
|
|
||||||
// Move to map utils
|
// store / load general connection of string into one string
|
||||||
|
static std::string serialize(const std::vector<std::string> &columns, char separator);
|
||||||
|
static void deserialize(const std::string& data, char separator, std::vector<std::string> &columns);// columns vector should be reserved on valid count
|
||||||
|
|
||||||
|
static void to_columns(const FontItem& font_item, std::vector<std::string> &columns);
|
||||||
|
static std::optional<FontItem> get_font_item(const std::vector<std::string> &columns, size_t offset);
|
||||||
|
|
||||||
|
static void to_columns(const FontProp& font_prop, std::vector<std::string> &columns);
|
||||||
|
static std::optional<FontProp> get_font_prop(const std::vector<std::string> &columns, size_t offset);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Twice all appearance of character in data.
|
||||||
|
/// Twiced character could be used as separator for this data.
|
||||||
|
/// IMPROVE: move to string utils
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">input data to twice character</param>
|
||||||
|
/// <param name="letter">Specify character to be twiced in data</param>
|
||||||
|
/// <returns>String conatin only pair continous count of specified character</returns>
|
||||||
|
static std::string twice(const std::string &data, char letter)
|
||||||
|
{
|
||||||
|
// no value is one space
|
||||||
|
if (data.empty()) return std::string(" ");
|
||||||
|
std::string::size_type pos = data.find(letter);
|
||||||
|
if (pos == data.npos) return data;
|
||||||
|
// twice all separator inside data
|
||||||
|
std::string copy = data; // copy
|
||||||
|
do {
|
||||||
|
copy.insert(pos, 1, letter);
|
||||||
|
pos += 2;
|
||||||
|
} while (copy.npos != (pos = copy.find(letter, pos)));
|
||||||
|
return copy;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reduce all twice appearance of character in data.
|
||||||
|
/// Main purpose heal after twice function.
|
||||||
|
/// IMPROVE: move to string utils
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">input data to reduce character</param>
|
||||||
|
/// <param name="letter">Specify character to be reduced</param>
|
||||||
|
/// <returns>String conatining only half letter in row</returns>
|
||||||
|
static std::string reduce(const std::string &data, char letter)
|
||||||
|
{
|
||||||
|
std::string::size_type pos = data.find(letter);
|
||||||
|
if (pos == data.npos) return data;
|
||||||
|
std::string copy = data; // copy
|
||||||
|
do {
|
||||||
|
assert(copy[pos] == letter);
|
||||||
|
assert(copy[pos + 1] == letter);
|
||||||
|
copy.erase(pos, size_t(1));
|
||||||
|
pos = copy.find(letter, pos + 1);
|
||||||
|
} while (pos != copy.npos);
|
||||||
|
return copy;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find odd position of letter in text data
|
||||||
|
/// Used with combination of twice and reduce
|
||||||
|
/// IMPROVE: move to string utils
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">Input text</param>
|
||||||
|
/// <param name="pos">Start index into data for searching odd letter</param>
|
||||||
|
/// <param name="letter">Character to find</param>
|
||||||
|
/// <returns>Index to data with next odd appearance of letter
|
||||||
|
/// OR size of data when NO next one exists</returns>
|
||||||
|
static size_t find_odd(const std::string &data, size_t pos, char letter)
|
||||||
|
{
|
||||||
|
pos = data.find(letter, pos);
|
||||||
|
while ((pos+1) <= data.size() && data[pos + 1] == letter)
|
||||||
|
pos = data.find(letter, pos + 2);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create map with swaped key-value
|
||||||
|
/// IMPROVE: Move to map utils
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="map">Input map</param>
|
||||||
|
/// <returns>Map with swapped key-value</returns>
|
||||||
template<typename Key, typename Value>
|
template<typename Key, typename Value>
|
||||||
static std::map<Value, Key> create_oposit_map(
|
static std::map<Value, Key> create_oposit_map(
|
||||||
const std::map<Key, Value> &map)
|
const std::map<Key, Value> &map)
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/ClipperUtils.hpp" // union_ex
|
#include "libslic3r/ClipperUtils.hpp" // union_ex
|
||||||
|
#include "libslic3r/AppConfig.hpp" // store/load font list
|
||||||
|
#include "libslic3r/TextConfigurationSerialization.hpp" // store/load font list
|
||||||
|
|
||||||
#include "imgui/imgui_stdlib.h" // using std::string for inputs
|
#include "imgui/imgui_stdlib.h" // using std::string for inputs
|
||||||
#include "nanosvg/nanosvg.h" // load SVG file
|
#include "nanosvg/nanosvg.h" // load SVG file
|
||||||
@ -77,7 +79,7 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
|
|||||||
, m_volume_type(ModelVolumeType::MODEL_PART)
|
, m_volume_type(ModelVolumeType::MODEL_PART)
|
||||||
, m_is_initialized(false) // initialize on first opening gizmo
|
, m_is_initialized(false) // initialize on first opening gizmo
|
||||||
{
|
{
|
||||||
// TODO: suggest to use https://fontawesome.com/
|
// TODO: add suggestion to use https://fontawesome.com/
|
||||||
// (copy & paste) unicode symbols from web
|
// (copy & paste) unicode symbols from web
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,16 +154,10 @@ void GLGizmoEmboss::initialize()
|
|||||||
if (m_is_initialized) return;
|
if (m_is_initialized) return;
|
||||||
m_is_initialized = true;
|
m_is_initialized = true;
|
||||||
|
|
||||||
|
load_font_list();
|
||||||
|
|
||||||
m_gui_cfg.emplace(GuiCfg());
|
m_gui_cfg.emplace(GuiCfg());
|
||||||
|
|
||||||
m_font_list = {{"NotoSans Regular", Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf"}
|
|
||||||
, {"NotoSans CJK", Slic3r::resources_dir() + "/fonts/NotoSansCJK-Regular.ttc"}
|
|
||||||
#ifdef USE_FONT_DIALOG
|
|
||||||
, WxFontUtils::get_font_item(wxFont(5, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL))
|
|
||||||
, WxFontUtils::get_font_item(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD))
|
|
||||||
, WxFontUtils::get_os_font()
|
|
||||||
#endif // USE_FONT_DIALOG
|
|
||||||
};
|
|
||||||
m_font_selected = 0;
|
m_font_selected = 0;
|
||||||
|
|
||||||
bool is_font_loaded = load_font();
|
bool is_font_loaded = load_font();
|
||||||
@ -177,6 +173,37 @@ void GLGizmoEmboss::initialize()
|
|||||||
set_default_configuration();
|
set_default_configuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLGizmoEmboss::load_font_list()
|
||||||
|
{
|
||||||
|
AppConfig *cfg = wxGetApp().app_config;
|
||||||
|
std::string font_list_str = cfg->get(AppConfig::SECTION_EMBOSS, M_APP_CFG_FONT_LIST);
|
||||||
|
if (!font_list_str.empty()) {
|
||||||
|
std::optional<FontList> fl = TextConfigurationSerialization::deserialize_font_list(font_list_str);
|
||||||
|
if (fl.has_value()) m_font_list = *fl;
|
||||||
|
}
|
||||||
|
if (m_font_list.empty()) m_font_list = create_default_font_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoEmboss::store_font_list()
|
||||||
|
{
|
||||||
|
AppConfig *cfg = wxGetApp().app_config;
|
||||||
|
std::string font_list_str = TextConfigurationSerialization::serialize(m_font_list);
|
||||||
|
cfg->set(AppConfig::SECTION_EMBOSS, M_APP_CFG_FONT_LIST, font_list_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
FontList GLGizmoEmboss::create_default_font_list() {
|
||||||
|
return {
|
||||||
|
{"NotoSans Regular", Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf"}
|
||||||
|
, {"NotoSans CJK", Slic3r::resources_dir() + "/fonts/NotoSansCJK-Regular.ttc"}
|
||||||
|
#ifdef USE_FONT_DIALOG
|
||||||
|
, WxFontUtils::get_font_item(wxFont(5, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL))
|
||||||
|
, WxFontUtils::get_font_item(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD))
|
||||||
|
, WxFontUtils::get_os_font()
|
||||||
|
#endif // USE_FONT_DIALOG
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::set_default_configuration() {
|
void GLGizmoEmboss::set_default_configuration() {
|
||||||
m_text = _u8L("Embossed text");
|
m_text = _u8L("Embossed text");
|
||||||
m_font_prop = FontProp();
|
m_font_prop = FontProp();
|
||||||
@ -226,10 +253,12 @@ ModelVolume *GLGizmoEmboss::get_selected_volume(const Selection &selection,
|
|||||||
const GLVolume * vol_gl = selection.get_volume(vol_id_gl);
|
const GLVolume * vol_gl = selection.get_volume(vol_id_gl);
|
||||||
const GLVolume::CompositeID &id = vol_gl->composite_id;
|
const GLVolume::CompositeID &id = vol_gl->composite_id;
|
||||||
|
|
||||||
if (id.object_id >= objects.size()) return nullptr;
|
if (id.object_id < 0 || static_cast<size_t>(id.object_id) >= objects.size())
|
||||||
|
return nullptr;
|
||||||
ModelObject *object = objects[id.object_id];
|
ModelObject *object = objects[id.object_id];
|
||||||
|
|
||||||
if (id.volume_id >= object->volumes.size()) return nullptr;
|
if (id.volume_id < 0 || static_cast<size_t>(id.volume_id) >= object->volumes.size())
|
||||||
|
return nullptr;
|
||||||
return object->volumes[id.volume_id];
|
return object->volumes[id.volume_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,12 +413,14 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
#ifdef USE_FONT_DIALOG
|
#ifdef USE_FONT_DIALOG
|
||||||
if (ImGui::Button(_L("Choose font").c_str())) {
|
if (ImGui::Button(_L("Choose font").c_str())) {
|
||||||
choose_font_by_wxdialog();
|
choose_font_by_wxdialog();
|
||||||
|
store_font_list();
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_L("Choose from installed font in dialog.").c_str());
|
} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_L("Choose from installed font in dialog.").c_str());
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
#endif // USE_FONT_DIALOG
|
#endif // USE_FONT_DIALOG
|
||||||
if (ImGui::Button(_L("Add File").c_str())) {
|
if (ImGui::Button(_L("Add File").c_str())) {
|
||||||
choose_true_type_file();
|
choose_true_type_file();
|
||||||
|
store_font_list();
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_L("add file with font(.ttf, .ttc)").c_str());
|
} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_L("add file with font(.ttf, .ttc)").c_str());
|
||||||
|
|
||||||
@ -420,6 +451,7 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
m_font_list.erase(m_font_list.begin() + index);
|
m_font_list.erase(m_font_list.begin() + index);
|
||||||
// fix selected index
|
// fix selected index
|
||||||
if (index < m_font_selected) --m_font_selected;
|
if (index < m_font_selected) --m_font_selected;
|
||||||
|
store_font_list();
|
||||||
}
|
}
|
||||||
m_imgui->disabled_end(); // exist_rename || is_selected
|
m_imgui->disabled_end(); // exist_rename || is_selected
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
@ -469,8 +501,11 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
if (ImGui::BeginPopupModal(rename_popup_id)) {
|
if (ImGui::BeginPopupModal(rename_popup_id)) {
|
||||||
ImGui::Text("Rename font name:");
|
ImGui::Text("Rename font name:");
|
||||||
FontItem &fi = m_font_list[rename_id];
|
FontItem &fi = m_font_list[rename_id];
|
||||||
if (ImGui::InputText("##font name", &fi.name, ImGuiInputTextFlags_EnterReturnsTrue) || ImGui::Button("ok"))
|
if (ImGui::InputText("##font name", &fi.name, ImGuiInputTextFlags_EnterReturnsTrue) ||
|
||||||
|
ImGui::Button("ok")){
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
|
store_font_list();
|
||||||
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -845,5 +880,7 @@ ExPolygons NSVGUtils::to_ExPolygons(NSVGimage *image,
|
|||||||
return Slic3r::union_ex(polygons);
|
return Slic3r::union_ex(polygons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string GLGizmoEmboss::M_APP_CFG_FONT_LIST = "font_list";
|
||||||
|
|
||||||
// any existing icon filename to not influence GUI
|
// any existing icon filename to not influence GUI
|
||||||
const std::string GLGizmoEmboss::M_ICON_FILENAME = "cut.svg";
|
const std::string GLGizmoEmboss::M_ICON_FILENAME = "cut.svg";
|
||||||
|
@ -34,6 +34,9 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
void load_font_list();
|
||||||
|
void store_font_list();
|
||||||
|
static FontList create_default_font_list();
|
||||||
void set_default_configuration();
|
void set_default_configuration();
|
||||||
void check_selection();
|
void check_selection();
|
||||||
// more general function --> move to select
|
// more general function --> move to select
|
||||||
@ -102,6 +105,7 @@ private:
|
|||||||
// initialize when GL is accessible
|
// initialize when GL is accessible
|
||||||
bool m_is_initialized;
|
bool m_is_initialized;
|
||||||
|
|
||||||
|
static const std::string M_APP_CFG_FONT_LIST;
|
||||||
// only temporary solution
|
// only temporary solution
|
||||||
static const std::string M_ICON_FILENAME;
|
static const std::string M_ICON_FILENAME;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user