Move font property inside of font item to store together with font
This commit is contained in:
parent
ce1df3eada
commit
ef6860d4ee
@ -148,14 +148,48 @@ 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 {};
|
||||||
|
|
||||||
|
if (font_prop.char_gap.has_value())
|
||||||
|
glyph_opt->advance_width += *font_prop.char_gap;
|
||||||
|
|
||||||
|
// scale glyph size
|
||||||
|
glyph_opt->advance_width =
|
||||||
|
static_cast<int>(glyph_opt->advance_width / Emboss::SHAPE_SCALE);
|
||||||
|
glyph_opt->left_side_bearing =
|
||||||
|
static_cast<int>(glyph_opt->left_side_bearing / Emboss::SHAPE_SCALE);
|
||||||
|
|
||||||
|
if (font_prop.boldness.has_value()) {
|
||||||
|
float delta = *font_prop.boldness / Emboss::SHAPE_SCALE;
|
||||||
|
glyph_opt->shape = offset_ex(glyph_opt->shape, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font_prop.skew.has_value()) {
|
||||||
|
const float &ratio = *font_prop.skew;
|
||||||
|
auto skew = [&ratio](Slic3r::Polygon &polygon) {
|
||||||
|
for (Slic3r::Point &p : polygon.points) { p.x() += p.y() * ratio; }
|
||||||
|
};
|
||||||
|
for (ExPolygon &expolygon : glyph_opt->shape) {
|
||||||
|
skew(expolygon.contour);
|
||||||
|
for (Slic3r::Polygon &hole : expolygon.holes) skew(hole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// union of shape
|
||||||
|
// (for sure) I do not believe in font corectness
|
||||||
|
// modification like bold or skew could create artefacts
|
||||||
|
glyph_opt->shape = Slic3r::union_ex(glyph_opt->shape);
|
||||||
|
// unify multipoints with similar position. Could appear after union
|
||||||
|
dilate_to_unique_points(glyph_opt->shape);
|
||||||
|
|
||||||
cache[unicode] = *glyph_opt;
|
cache[unicode] = *glyph_opt;
|
||||||
|
|
||||||
return glyph_opt;
|
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) {
|
||||||
return FontItem(boost::nowide::narrow(name.c_str()),
|
return FontItem(boost::nowide::narrow(name.c_str()),
|
||||||
boost::nowide::narrow(path.c_str()),
|
boost::nowide::narrow(path.c_str()),
|
||||||
FontItem::Type::file_path);
|
FontItem::Type::file_path, FontProp());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExPolygons Private::dilate_to_unique_points(ExPolygons &expolygons)
|
ExPolygons Private::dilate_to_unique_points(ExPolygons &expolygons)
|
||||||
@ -549,8 +583,10 @@ ExPolygons Emboss::text2shapes(Font & font,
|
|||||||
int line_height = font.ascent - font.descent + font.linegap;
|
int line_height = font.ascent - font.descent + font.linegap;
|
||||||
if (font_prop.line_gap.has_value())
|
if (font_prop.line_gap.has_value())
|
||||||
line_height += *font_prop.line_gap;
|
line_height += *font_prop.line_gap;
|
||||||
|
line_height = static_cast<int>(line_height / SHAPE_SCALE);
|
||||||
|
|
||||||
cursor.x() = 0;
|
cursor.x() = 0;
|
||||||
cursor.y() -= static_cast<int>(line_height / SHAPE_SCALE);
|
cursor.y() -= line_height;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (wc == '\t') {
|
if (wc == '\t') {
|
||||||
@ -558,10 +594,7 @@ ExPolygons Emboss::text2shapes(Font & font,
|
|||||||
const int count_spaces = 4;
|
const int count_spaces = 4;
|
||||||
std::optional<Glyph> space_opt = Private::get_glyph(int(' '), font, font_prop, font.cache, font_info_opt);
|
std::optional<Glyph> space_opt = Private::get_glyph(int(' '), font, font_prop, font.cache, font_info_opt);
|
||||||
if (!space_opt.has_value()) continue;
|
if (!space_opt.has_value()) continue;
|
||||||
int width = space_opt->advance_width;
|
cursor.x() += count_spaces * space_opt->advance_width;
|
||||||
if (font_prop.char_gap.has_value())
|
|
||||||
width += *font_prop.char_gap;
|
|
||||||
cursor.x() += static_cast<int>((count_spaces * width) / SHAPE_SCALE);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,29 +607,7 @@ ExPolygons Emboss::text2shapes(Font & font,
|
|||||||
for (ExPolygon &expolygon : expolygons)
|
for (ExPolygon &expolygon : expolygons)
|
||||||
expolygon.translate(cursor);
|
expolygon.translate(cursor);
|
||||||
|
|
||||||
if (font_prop.boldness.has_value()) {
|
cursor.x() += glyph_opt->advance_width;
|
||||||
float delta = *font_prop.boldness / SHAPE_SCALE;
|
|
||||||
expolygons = offset_ex(expolygons, delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (font_prop.skew.has_value()) {
|
|
||||||
const float& ratio = *font_prop.skew;
|
|
||||||
auto skew = [&ratio](Polygon &polygon) {
|
|
||||||
for (Point &p : polygon.points) {
|
|
||||||
p.x() += p.y() * ratio;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for (ExPolygon &expolygon : expolygons) {
|
|
||||||
skew(expolygon.contour);
|
|
||||||
for (Polygon &hole : expolygon.holes)
|
|
||||||
skew(hole);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int width = glyph_opt->advance_width;
|
|
||||||
if (font_prop.char_gap.has_value())
|
|
||||||
width += *font_prop.char_gap;
|
|
||||||
cursor.x() += static_cast<int>(width / SHAPE_SCALE);
|
|
||||||
expolygons_append(result, expolygons);
|
expolygons_append(result, expolygons);
|
||||||
}
|
}
|
||||||
result = Slic3r::union_ex(result);
|
result = Slic3r::union_ex(result);
|
||||||
|
@ -46,13 +46,15 @@ public:
|
|||||||
struct Glyph
|
struct Glyph
|
||||||
{
|
{
|
||||||
ExPolygons shape;
|
ExPolygons shape;
|
||||||
int advance_width, left_side_bearing;
|
int advance_width=0, left_side_bearing=0;
|
||||||
};
|
};
|
||||||
// cache for glyph by unicode
|
// cache for glyph by unicode
|
||||||
using Glyphs = std::map<int, Glyph>;
|
using Glyphs = std::map<int, Glyph>;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// keep information from file about font
|
/// keep information from file about font
|
||||||
|
/// + cache shape of glyphs (optionaly modified)
|
||||||
|
/// + user defined modification of font
|
||||||
/// </summary>
|
/// </summary>
|
||||||
struct Font
|
struct Font
|
||||||
{
|
{
|
||||||
@ -65,6 +67,10 @@ public:
|
|||||||
// vertical position is "scale*(ascent - descent + lineGap)"
|
// vertical position is "scale*(ascent - descent + lineGap)"
|
||||||
const int ascent, descent, linegap;
|
const int ascent, descent, linegap;
|
||||||
|
|
||||||
|
// user defined font modification
|
||||||
|
// + emboss parameter
|
||||||
|
FontProp prop;
|
||||||
|
|
||||||
Emboss::Glyphs cache; // cache of glyphs
|
Emboss::Glyphs cache; // cache of glyphs
|
||||||
|
|
||||||
Font(std::vector<unsigned char> &&buffer,
|
Font(std::vector<unsigned char> &&buffer,
|
||||||
@ -78,9 +84,21 @@ public:
|
|||||||
, ascent(ascent)
|
, ascent(ascent)
|
||||||
, descent(descent)
|
, descent(descent)
|
||||||
, linegap(linegap)
|
, linegap(linegap)
|
||||||
|
, prop(7.f, 1.f)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct UserFont
|
||||||
|
{
|
||||||
|
// description of file
|
||||||
|
Font file_font;
|
||||||
|
// user defined font modification
|
||||||
|
FontProp prop;
|
||||||
|
// cache of glyphs
|
||||||
|
Emboss::Glyphs cache;
|
||||||
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load font file into buffer
|
/// Load font file into buffer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -3255,7 +3255,7 @@ void TextConfigurationSerialization::to_xml(std::stringstream &stream, const Tex
|
|||||||
stream << FONT_DESCRIPTOR_TYPE_ATTR << "=\"" << TextConfigurationSerialization::to_string.at(fi.type) << "\" ";
|
stream << FONT_DESCRIPTOR_TYPE_ATTR << "=\"" << TextConfigurationSerialization::to_string.at(fi.type) << "\" ";
|
||||||
|
|
||||||
// font property
|
// font property
|
||||||
const FontProp &fp = tc.font_prop;
|
const FontProp &fp = tc.font_item.prop;
|
||||||
if (fp.char_gap.has_value())
|
if (fp.char_gap.has_value())
|
||||||
stream << CHAR_GAP_ATTR << "=\"" << *fp.char_gap << "\" ";
|
stream << CHAR_GAP_ATTR << "=\"" << *fp.char_gap << "\" ";
|
||||||
if (fp.line_gap.has_value())
|
if (fp.line_gap.has_value())
|
||||||
@ -3282,13 +3282,6 @@ void TextConfigurationSerialization::to_xml(std::stringstream &stream, const Tex
|
|||||||
|
|
||||||
std::optional<TextConfiguration> TextConfigurationSerialization::read(const char **attributes, unsigned int num_attributes)
|
std::optional<TextConfiguration> TextConfigurationSerialization::read(const char **attributes, unsigned int num_attributes)
|
||||||
{
|
{
|
||||||
std::string text = get_attribute_value_string(attributes, num_attributes, TEXT_DATA_ATTR);
|
|
||||||
std::string font_name = "";
|
|
||||||
std::string font_descriptor = get_attribute_value_string(attributes, num_attributes, FONT_DESCRIPTOR_ATTR);
|
|
||||||
std::string type_str = get_attribute_value_string(attributes, num_attributes, FONT_DESCRIPTOR_TYPE_ATTR);
|
|
||||||
FontItem::Type type = TextConfigurationSerialization::get_type(type_str);
|
|
||||||
FontItem fi(font_name, font_descriptor, type);
|
|
||||||
|
|
||||||
FontProp fp;
|
FontProp fp;
|
||||||
int char_gap = get_attribute_value_int(attributes, num_attributes, CHAR_GAP_ATTR);
|
int char_gap = get_attribute_value_int(attributes, num_attributes, CHAR_GAP_ATTR);
|
||||||
if (char_gap != 0) fp.char_gap = char_gap;
|
if (char_gap != 0) fp.char_gap = char_gap;
|
||||||
@ -3313,7 +3306,14 @@ std::optional<TextConfiguration> TextConfigurationSerialization::read(const char
|
|||||||
std::string weight = get_attribute_value_string(attributes, num_attributes, FONT_WEIGHT_ATTR);
|
std::string weight = get_attribute_value_string(attributes, num_attributes, FONT_WEIGHT_ATTR);
|
||||||
if (!weight.empty()) fp.weight = weight;
|
if (!weight.empty()) fp.weight = weight;
|
||||||
|
|
||||||
return TextConfiguration(fi, fp, text);
|
std::string font_name = "";
|
||||||
|
std::string font_descriptor = get_attribute_value_string(attributes, num_attributes, FONT_DESCRIPTOR_ATTR);
|
||||||
|
std::string type_str = get_attribute_value_string(attributes, num_attributes, FONT_DESCRIPTOR_TYPE_ATTR);
|
||||||
|
FontItem::Type type = TextConfigurationSerialization::get_type(type_str);
|
||||||
|
FontItem fi(font_name, font_descriptor, type, fp);
|
||||||
|
|
||||||
|
std::string text = get_attribute_value_string(attributes, num_attributes, TEXT_DATA_ATTR);
|
||||||
|
return TextConfiguration(fi, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,6 +7,45 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// user defined font property
|
||||||
|
struct FontProp
|
||||||
|
{
|
||||||
|
// define extra space between letters, negative mean closer letter
|
||||||
|
std::optional<int> char_gap;
|
||||||
|
// define extra space between lines, negative mean closer lines
|
||||||
|
std::optional<int> line_gap;
|
||||||
|
// Z depth of text [in mm]
|
||||||
|
float emboss;
|
||||||
|
|
||||||
|
// positive value mean wider character shape
|
||||||
|
// negative value mean tiner character shape
|
||||||
|
std::optional<float> boldness; // [in mm]
|
||||||
|
|
||||||
|
// positive value mean italic of character (CW)
|
||||||
|
// negative value mean CCW skew (unItalic)
|
||||||
|
std::optional<float> skew;
|
||||||
|
|
||||||
|
// TODO: add enum class Align: center/left/right
|
||||||
|
|
||||||
|
//////
|
||||||
|
// Duplicit data to wxFontDescriptor
|
||||||
|
// used for store/load .3mf file
|
||||||
|
//////
|
||||||
|
|
||||||
|
// Height of letter [in mm],
|
||||||
|
// duplicit to wxFont::PointSize
|
||||||
|
float size_in_mm;
|
||||||
|
// Define type of font
|
||||||
|
std::optional<std::string> family;
|
||||||
|
std::optional<std::string> face_name;
|
||||||
|
std::optional<std::string> style;
|
||||||
|
std::optional<std::string> weight;
|
||||||
|
|
||||||
|
FontProp(float line_height = 10.f, float depth = 2.f)
|
||||||
|
: emboss(depth), size_in_mm(line_height)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
// represent selected font
|
// represent selected font
|
||||||
// Name must be human readable is visible in gui
|
// Name must be human readable is visible in gui
|
||||||
// (Path + Type) must define how to open font for using on different OS
|
// (Path + Type) must define how to open font for using on different OS
|
||||||
@ -16,10 +55,17 @@ struct FontItem
|
|||||||
std::string path;
|
std::string path;
|
||||||
enum class Type;
|
enum class Type;
|
||||||
Type type;
|
Type type;
|
||||||
|
FontProp prop;
|
||||||
|
|
||||||
FontItem() : type(Type::undefined){} // set undefined type
|
FontItem() : type(Type::undefined){} // set undefined type
|
||||||
FontItem(const std::string &name, const std::string &path, Type type)
|
|
||||||
: name(name), path(path), type(type)
|
// when name is empty than Font item was loaded from .3mf file
|
||||||
|
// and potentionaly it is not reproducable
|
||||||
|
FontItem(const std::string &name,
|
||||||
|
const std::string &path,
|
||||||
|
Type type,
|
||||||
|
const FontProp & prop)
|
||||||
|
: name(name), path(path), type(type), prop(prop)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// define data stored in path
|
// define data stored in path
|
||||||
@ -32,60 +78,19 @@ struct FontItem
|
|||||||
wx_mac_font_descr // path is font descriptor generated by wxWidgets on windows
|
wx_mac_font_descr // path is font descriptor generated by wxWidgets on windows
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
using FontList = std::vector<FontItem>;
|
using FontList = std::vector<FontItem>;
|
||||||
|
|
||||||
// user defined font property
|
|
||||||
struct FontProp
|
|
||||||
{
|
|
||||||
// define extra space between letters, negative mean closer letter
|
|
||||||
std::optional<int> char_gap = 0;
|
|
||||||
// define extra space between lines, negative mean closer lines
|
|
||||||
std::optional<int> line_gap = 0;
|
|
||||||
// Z depth of text [in mm]
|
|
||||||
float emboss = 5;
|
|
||||||
|
|
||||||
// positive value mean wider character shape
|
|
||||||
// negative value mean tiner character shape
|
|
||||||
std::optional<float> boldness = 0.f; // [in mm]
|
|
||||||
|
|
||||||
// positive value mean italic of character (CW)
|
|
||||||
// negative value mean CCW skew (unItalic)
|
|
||||||
std::optional<float> skew = 0.f;
|
|
||||||
|
|
||||||
// TODO: add enum class Align: center/left/right
|
|
||||||
|
|
||||||
//////
|
|
||||||
// Duplicit data to wxFontDescriptor
|
|
||||||
// used for store/load .3mf file
|
|
||||||
//////
|
|
||||||
|
|
||||||
// Height of letter [in mm],
|
|
||||||
// duplicit to wxFont::PointSize
|
|
||||||
float size_in_mm = 10;
|
|
||||||
// Define type of font
|
|
||||||
std::optional<std::string> family;
|
|
||||||
std::optional<std::string> face_name;
|
|
||||||
std::optional<std::string> style;
|
|
||||||
std::optional<std::string> weight;
|
|
||||||
|
|
||||||
FontProp() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
// define how to create 'Text volume'
|
// define how to create 'Text volume'
|
||||||
struct TextConfiguration
|
struct TextConfiguration
|
||||||
{
|
{
|
||||||
// define font
|
// define font
|
||||||
FontItem font_item;
|
FontItem font_item;
|
||||||
// user modification of font
|
|
||||||
FontProp font_prop;
|
|
||||||
|
|
||||||
std::string text = "None";
|
std::string text = "None";
|
||||||
|
|
||||||
TextConfiguration() = default; // optional needs empty constructor
|
TextConfiguration() = default; // optional needs empty constructor
|
||||||
TextConfiguration(const FontItem & font_item,
|
TextConfiguration(const FontItem &font_item, const std::string &text)
|
||||||
const FontProp & font_prop,
|
: font_item(font_item), text(text)
|
||||||
const std::string &text)
|
|
||||||
: font_item(font_item), font_prop(font_prop), text(text)
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ void GLGizmoEmboss::set_fine_position()
|
|||||||
const Camera &camera = wxGetApp().plater()->get_camera();
|
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||||
Polygon hull = CameraUtils::create_hull2d(camera, *volume);
|
Polygon hull = CameraUtils::create_hull2d(camera, *volume);
|
||||||
|
|
||||||
// TODO: fix width
|
// TODO: fix width - showing scroll bar during first show advanced
|
||||||
ImVec2 windows_size = m_gui_cfg->draw_advanced ?
|
ImVec2 windows_size = m_gui_cfg->draw_advanced ?
|
||||||
m_gui_cfg->minimal_window_size_with_advance :
|
m_gui_cfg->minimal_window_size_with_advance :
|
||||||
m_gui_cfg->minimal_window_size;
|
m_gui_cfg->minimal_window_size;
|
||||||
@ -371,8 +371,8 @@ void GLGizmoEmboss::on_set_state()
|
|||||||
set_fine_position();
|
set_fine_position();
|
||||||
|
|
||||||
// when open by hyperlink it needs to show up
|
// when open by hyperlink it needs to show up
|
||||||
|
// or after key 'T' windows doesn't appear
|
||||||
m_parent.reload_scene(true);
|
m_parent.reload_scene(true);
|
||||||
// TODO: after key T windows doesn't appear
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,9 +453,8 @@ FontList GLGizmoEmboss::create_default_font_list() {
|
|||||||
|
|
||||||
void GLGizmoEmboss::set_default_configuration()
|
void GLGizmoEmboss::set_default_configuration()
|
||||||
{
|
{
|
||||||
m_text = _u8L("Embossed text");
|
m_text = _u8L("Embossed text");
|
||||||
m_font_prop = FontProp();
|
//load_font(); // reload actual font - because of font size
|
||||||
load_font(); // reload actual font - because of font size
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Slic3r::TriangleMesh GLGizmoEmboss::create_default_mesh()
|
Slic3r::TriangleMesh GLGizmoEmboss::create_default_mesh()
|
||||||
@ -475,8 +474,8 @@ Slic3r::TriangleMesh GLGizmoEmboss::create_mesh()
|
|||||||
// It is neccessary to create some shape
|
// It is neccessary to create some shape
|
||||||
// Emboss text window is opened by creation new embosstext object
|
// Emboss text window is opened by creation new embosstext object
|
||||||
if (m_font == nullptr) return create_default_mesh();
|
if (m_font == nullptr) return create_default_mesh();
|
||||||
|
const FontItem &fi = m_font_list[m_font_selected];
|
||||||
TriangleMesh result = create_mesh(m_text.c_str(), *m_font, m_font_prop);
|
TriangleMesh result = create_mesh(m_text.c_str(), *m_font, fi.prop);
|
||||||
if (result.its.empty()) return create_default_mesh();
|
if (result.its.empty()) return create_default_mesh();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -511,7 +510,6 @@ void GLGizmoEmboss::check_selection()
|
|||||||
// successfull load volume for editing
|
// successfull load volume for editing
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
// behave like adding new text
|
// behave like adding new text
|
||||||
m_volume = nullptr;
|
m_volume = nullptr;
|
||||||
set_default_configuration();
|
set_default_configuration();
|
||||||
@ -659,16 +657,9 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
std::string name = ImGuiWrapper::trunc(f.name, max_width);
|
std::string name = ImGuiWrapper::trunc(f.name, max_width);
|
||||||
size_t index = &f - &m_font_list.front();
|
size_t index = &f - &m_font_list.front();
|
||||||
bool is_selected = index == m_font_selected;
|
bool is_selected = index == m_font_selected;
|
||||||
auto flags =
|
auto flags = ImGuiSelectableFlags_AllowItemOverlap; // allow click buttons
|
||||||
ImGuiSelectableFlags_AllowItemOverlap; // allow clic buttons
|
|
||||||
if (ImGui::Selectable(name.c_str(), is_selected, flags)) {
|
if (ImGui::Selectable(name.c_str(), is_selected, flags)) {
|
||||||
size_t prev_font_selected = m_font_selected;
|
if (load_font(index)) process();
|
||||||
m_font_selected = index;
|
|
||||||
if (!load_font()) {
|
|
||||||
m_font_selected = prev_font_selected;
|
|
||||||
} else {
|
|
||||||
process();
|
|
||||||
}
|
|
||||||
} else if (ImGui::IsItemHovered())
|
} else if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("%s", f.name.c_str());
|
ImGui::SetTooltip("%s", f.name.c_str());
|
||||||
|
|
||||||
@ -745,16 +736,19 @@ void GLGizmoEmboss::draw_text_input()
|
|||||||
|
|
||||||
void GLGizmoEmboss::draw_advanced()
|
void GLGizmoEmboss::draw_advanced()
|
||||||
{
|
{
|
||||||
|
FontItem &fi = m_font_list[m_font_selected];
|
||||||
|
FontProp &font_prop = fi.prop;
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
||||||
if (ImGui::InputFloat(_u8L("Size[in mm]").c_str(),
|
if (ImGui::InputFloat(_u8L("Size[in mm]").c_str(),
|
||||||
&m_font_prop.size_in_mm)) {
|
&font_prop.size_in_mm)) {
|
||||||
if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10;
|
if (font_prop.size_in_mm < 0.1) font_prop.size_in_mm = 10;
|
||||||
// store font size into path
|
// store font size into path
|
||||||
FontItem &fi = m_font_list[m_font_selected];
|
FontItem &fi = m_font_list[m_font_selected];
|
||||||
if (fi.type == WxFontUtils::get_actual_type()) {
|
if (fi.type == WxFontUtils::get_actual_type()) {
|
||||||
std::optional<wxFont> wx_font = WxFontUtils::load_wxFont(fi.path);
|
std::optional<wxFont> wx_font = WxFontUtils::load_wxFont(fi.path);
|
||||||
if (wx_font.has_value()) {
|
if (wx_font.has_value()) {
|
||||||
wx_font->SetPointSize(m_font_prop.size_in_mm);
|
wx_font->SetPointSize(font_prop.size_in_mm);
|
||||||
fi.path = WxFontUtils::store_wxFont(*wx_font);
|
fi.path = WxFontUtils::store_wxFont(*wx_font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -763,24 +757,30 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
||||||
if (ImGui::InputFloat(_u8L("Emboss[in mm]").c_str(), &m_font_prop.emboss))
|
if (ImGui::InputFloat(_u8L("Emboss[in mm]").c_str(), &font_prop.emboss))
|
||||||
process();
|
process();
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width);
|
||||||
if(ImGuiWrapper::input_optional_int(_u8L("CharGap[in font points]").c_str(), m_font_prop.char_gap))
|
if (ImGuiWrapper::input_optional_int(_u8L("CharGap[in font points]").c_str(), font_prop.char_gap)) {
|
||||||
|
m_font->cache.clear();
|
||||||
process();
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(2*m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(2*m_gui_cfg->advanced_input_width);
|
||||||
if (ImGuiWrapper::input_optional_int(_u8L("LineGap[in font points]").c_str(), m_font_prop.line_gap))
|
if (ImGuiWrapper::input_optional_int(_u8L("LineGap[in font points]").c_str(), font_prop.line_gap))
|
||||||
process();
|
process();
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width);
|
||||||
if (m_imgui->slider_optional_float(_u8L("Boldness[in font points]").c_str(), m_font_prop.boldness, -200.f, 200.f, "%.0f", 1.f, false, _L("tiny / wide chars")))
|
if (m_imgui->slider_optional_float(_u8L("Boldness[in font points]").c_str(), font_prop.boldness, -200.f, 200.f, "%.0f", 1.f, false, _L("tiny / wide chars"))){
|
||||||
|
m_font->cache.clear();
|
||||||
process();
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(2 * m_gui_cfg->advanced_input_width);
|
||||||
if (m_imgui->slider_optional_float(_u8L("Skew ratio").c_str(), m_font_prop.skew, -1.f, 1.f, "%.2f", 1.f, false, _L("italic strength")))
|
if (m_imgui->slider_optional_float(_u8L("Skew ratio").c_str(), font_prop.skew, -1.f, 1.f, "%.2f", 1.f, false, _L("italic strength"))){
|
||||||
|
m_font->cache.clear();
|
||||||
process();
|
process();
|
||||||
|
}
|
||||||
|
|
||||||
// when more collection add selector
|
// when more collection add selector
|
||||||
if (m_font != nullptr && m_font->count > 1) {
|
if (m_font != nullptr && m_font->count > 1) {
|
||||||
@ -804,17 +804,17 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
|
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
std::string descriptor = m_font_list[m_font_selected].path;
|
std::string descriptor = m_font_list[m_font_selected].path;
|
||||||
ImGui::Text("family = %s", (m_font_prop.family.has_value() ?
|
ImGui::Text("family = %s", (font_prop.family.has_value() ?
|
||||||
m_font_prop.family->c_str() :
|
font_prop.family->c_str() :
|
||||||
" --- "));
|
" --- "));
|
||||||
ImGui::Text("face name = %s", (m_font_prop.face_name.has_value() ?
|
ImGui::Text("face name = %s", (font_prop.face_name.has_value() ?
|
||||||
m_font_prop.face_name->c_str() :
|
font_prop.face_name->c_str() :
|
||||||
" --- "));
|
" --- "));
|
||||||
ImGui::Text("style = %s",
|
ImGui::Text("style = %s",
|
||||||
(m_font_prop.style.has_value() ? m_font_prop.style->c_str() :
|
(font_prop.style.has_value() ? font_prop.style->c_str() :
|
||||||
" --- "));
|
" --- "));
|
||||||
ImGui::Text("weight = %s", (m_font_prop.weight.has_value() ?
|
ImGui::Text("weight = %s", (font_prop.weight.has_value() ?
|
||||||
m_font_prop.weight->c_str() :
|
font_prop.weight->c_str() :
|
||||||
" --- "));
|
" --- "));
|
||||||
ImGui::Text("descriptor = %s", descriptor.c_str());
|
ImGui::Text("descriptor = %s", descriptor.c_str());
|
||||||
ImGui::Image(m_imgui_font_atlas.TexID,
|
ImGui::Image(m_imgui_font_atlas.TexID,
|
||||||
@ -825,6 +825,7 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
|
|
||||||
bool GLGizmoEmboss::load_font(size_t font_index)
|
bool GLGizmoEmboss::load_font(size_t font_index)
|
||||||
{
|
{
|
||||||
|
if (font_index >= m_font_list.size()) return false;
|
||||||
std::swap(font_index, m_font_selected);
|
std::swap(font_index, m_font_selected);
|
||||||
bool is_loaded = load_font();
|
bool is_loaded = load_font();
|
||||||
if (!is_loaded) std::swap(font_index, m_font_selected);
|
if (!is_loaded) std::swap(font_index, m_font_selected);
|
||||||
@ -860,20 +861,6 @@ bool GLGizmoEmboss::load_font(const wxFont &font)
|
|||||||
auto font_ptr = WxFontUtils::load_font(font);
|
auto font_ptr = WxFontUtils::load_font(font);
|
||||||
if (font_ptr == nullptr) return false;
|
if (font_ptr == nullptr) return false;
|
||||||
m_font = std::move(font_ptr);
|
m_font = std::move(font_ptr);
|
||||||
WxFontUtils::update_property(m_font_prop, font);
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
// dynamic creation of italic, on linux is italic made by skew of normal font
|
|
||||||
wxFontStyle style = font.GetStyle();
|
|
||||||
if (style == wxFONTSTYLE_ITALIC &&
|
|
||||||
!Emboss::is_italic(*m_font) ) {
|
|
||||||
m_font_prop.skew = 0.2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: decide when rewrite emboss depth
|
|
||||||
m_font_prop.emboss = m_font_prop.size_in_mm / 2.f;
|
|
||||||
|
|
||||||
load_imgui_font();
|
load_imgui_font();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -926,8 +913,9 @@ void GLGizmoEmboss::load_imgui_font()
|
|||||||
m_imgui_font_ranges.clear();
|
m_imgui_font_ranges.clear();
|
||||||
|
|
||||||
builder.BuildRanges(&m_imgui_font_ranges);
|
builder.BuildRanges(&m_imgui_font_ranges);
|
||||||
|
const FontProp &font_prop = m_font_list[m_font_selected].prop;
|
||||||
int font_size = static_cast<int>(
|
int font_size = static_cast<int>(
|
||||||
std::round(std::abs(m_font_prop.size_in_mm / 0.3528)));
|
std::round(std::abs(font_prop.size_in_mm / 0.3528)));
|
||||||
if (font_size < m_gui_cfg->min_imgui_font_size)
|
if (font_size < m_gui_cfg->min_imgui_font_size)
|
||||||
font_size = m_gui_cfg->min_imgui_font_size;
|
font_size = m_gui_cfg->min_imgui_font_size;
|
||||||
if (font_size > m_gui_cfg->max_imgui_font_size)
|
if (font_size > m_gui_cfg->max_imgui_font_size)
|
||||||
@ -988,7 +976,6 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
|
|||||||
size_t font_index = m_font_list.size();
|
size_t font_index = m_font_list.size();
|
||||||
FontItem font_item = WxFontUtils::get_font_item(font);
|
FontItem font_item = WxFontUtils::get_font_item(font);
|
||||||
m_font_list.emplace_back(font_item);
|
m_font_list.emplace_back(font_item);
|
||||||
FontProp old_font_prop = m_font_prop; // copy
|
|
||||||
|
|
||||||
// Check that deserialization NOT influence font
|
// Check that deserialization NOT influence font
|
||||||
// false - use direct selected wxFont in dialog
|
// false - use direct selected wxFont in dialog
|
||||||
@ -1002,8 +989,6 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
|
|||||||
std::swap(font_index, m_font_selected); // when not process
|
std::swap(font_index, m_font_selected); // when not process
|
||||||
// remove form font list
|
// remove form font list
|
||||||
m_font_list.pop_back();
|
m_font_list.pop_back();
|
||||||
// reverse property
|
|
||||||
m_font_prop = old_font_prop; // when not process
|
|
||||||
wxString message = GUI::format_wxstr(
|
wxString message = GUI::format_wxstr(
|
||||||
_L("Font '%1%' can't be used. Please select another."),
|
_L("Font '%1%' can't be used. Please select another."),
|
||||||
font_item.name);
|
font_item.name);
|
||||||
@ -1029,7 +1014,7 @@ bool GLGizmoEmboss::choose_true_type_file()
|
|||||||
for (auto &input_file : input_files) {
|
for (auto &input_file : input_files) {
|
||||||
std::string path = std::string(input_file.c_str());
|
std::string path = std::string(input_file.c_str());
|
||||||
std::string name = get_file_name(path);
|
std::string name = get_file_name(path);
|
||||||
m_font_list.emplace_back(name, path, FontItem::Type::file_path);
|
m_font_list.emplace_back(name, path, FontItem::Type::file_path, FontProp());
|
||||||
|
|
||||||
// set first valid added font as active
|
// set first valid added font as active
|
||||||
if (!font_loaded) {
|
if (!font_loaded) {
|
||||||
@ -1064,9 +1049,10 @@ bool GLGizmoEmboss::choose_svg_file()
|
|||||||
|
|
||||||
BoundingBox bb;
|
BoundingBox bb;
|
||||||
for (const auto &p : polys) bb.merge(p.contour.points);
|
for (const auto &p : polys) bb.merge(p.contour.points);
|
||||||
float scale = m_font_prop.size_in_mm / std::max(bb.max.x(), bb.max.y());
|
const FontProp &fp = m_font_list[m_font_selected].prop;
|
||||||
|
float scale = fp.size_in_mm / std::max(bb.max.x(), bb.max.y());
|
||||||
auto project = std::make_unique<Emboss::ProjectScale>(
|
auto project = std::make_unique<Emboss::ProjectScale>(
|
||||||
std::make_unique<Emboss::ProjectZ>(m_font_prop.emboss / scale), scale);
|
std::make_unique<Emboss::ProjectZ>(fp.emboss / scale), scale);
|
||||||
indexed_triangle_set its = Emboss::polygons2model(polys, *project);
|
indexed_triangle_set its = Emboss::polygons2model(polys, *project);
|
||||||
return false;
|
return false;
|
||||||
// test store:
|
// test store:
|
||||||
@ -1078,8 +1064,7 @@ bool GLGizmoEmboss::choose_svg_file()
|
|||||||
|
|
||||||
TextConfiguration GLGizmoEmboss::create_configuration()
|
TextConfiguration GLGizmoEmboss::create_configuration()
|
||||||
{
|
{
|
||||||
return TextConfiguration(m_font_list[m_font_selected], m_font_prop,
|
return TextConfiguration(m_font_list[m_font_selected], m_text);
|
||||||
m_text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
||||||
@ -1108,18 +1093,16 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
|||||||
m_font_selected = it - m_font_list.begin();
|
m_font_selected = it - m_font_list.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_font_prop = configuration.font_prop;
|
|
||||||
m_text = configuration.text;
|
m_text = configuration.text;
|
||||||
m_volume = volume;
|
m_volume = volume;
|
||||||
|
|
||||||
if (!load_font()) {
|
if (!load_font()) {
|
||||||
// create similar font
|
// create similar font
|
||||||
auto wx_font = WxFontUtils::create_wxFont(c_font_item,
|
auto wx_font = WxFontUtils::create_wxFont(c_font_item, configuration.font_item.prop);
|
||||||
configuration.font_prop);
|
|
||||||
if (wx_font.has_value()) {
|
if (wx_font.has_value()) {
|
||||||
// fix not loadable font item
|
// fix not loadable font item
|
||||||
m_font_list[m_font_selected] = WxFontUtils::get_font_item(
|
m_font_list[m_font_selected] = WxFontUtils::get_font_item(*wx_font);
|
||||||
*wx_font);
|
m_font_list[m_font_selected].prop = configuration.font_item.prop;
|
||||||
if (!load_font(*wx_font)) return false;
|
if (!load_font(*wx_font)) return false;
|
||||||
} else {
|
} else {
|
||||||
// can't create similar font use previous
|
// can't create similar font use previous
|
||||||
@ -1143,9 +1126,9 @@ void GLGizmoEmboss::create_notification_not_valid_font(
|
|||||||
auto level =
|
auto level =
|
||||||
NotificationManager::NotificationLevel::WarningNotificationLevel;
|
NotificationManager::NotificationLevel::WarningNotificationLevel;
|
||||||
|
|
||||||
const auto &origin_family = tc.font_prop.face_name;
|
|
||||||
const auto &actual_family = m_font_prop.face_name;
|
|
||||||
const auto &fi = m_font_list[m_font_selected];
|
const auto &fi = m_font_list[m_font_selected];
|
||||||
|
const auto &origin_family = tc.font_item.prop.face_name;
|
||||||
|
const auto &actual_family = fi.prop.face_name;
|
||||||
|
|
||||||
const std::string &origin_font_name = origin_family.has_value() ?
|
const std::string &origin_font_name = origin_family.has_value() ?
|
||||||
*origin_family :
|
*origin_family :
|
||||||
@ -1308,12 +1291,59 @@ void GLGizmoEmboss::store_font_list()
|
|||||||
|
|
||||||
const std::string GLGizmoEmboss::APP_CONFIG_FONT_NAME = "name";
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_NAME = "name";
|
||||||
const std::string GLGizmoEmboss::APP_CONFIG_FONT_DESCRIPTOR = "descriptor";
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_DESCRIPTOR = "descriptor";
|
||||||
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_LINE_HEIGHT = "line_height";
|
||||||
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_DEPTH = "depth";
|
||||||
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_BOLDNESS = "boldness";
|
||||||
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_SKEW = "skew";
|
||||||
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_CHAR_GAP = "char_gap";
|
||||||
|
const std::string GLGizmoEmboss::APP_CONFIG_FONT_LINE_GAP = "line_gap";
|
||||||
|
|
||||||
std::string GLGizmoEmboss::get_app_config_font_section(unsigned index)
|
std::string GLGizmoEmboss::get_app_config_font_section(unsigned index)
|
||||||
{
|
{
|
||||||
return AppConfig::SECTION_FONT + ':' + std::to_string(index);
|
return AppConfig::SECTION_FONT + ':' + std::to_string(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "fast_float/fast_float.h"
|
||||||
|
static bool read(const std::map<std::string, std::string>& section, const std::string& key, float& value){
|
||||||
|
auto item = section.find(key);
|
||||||
|
if (item == section.end()) return false;
|
||||||
|
const std::string &data = item->second;
|
||||||
|
if (data.empty()) return false;
|
||||||
|
float value_;
|
||||||
|
fast_float::from_chars(data.c_str(), data.c_str() + data.length(), value_);
|
||||||
|
// read only non zero value
|
||||||
|
if (fabs(value_) <= std::numeric_limits<float>::epsilon()) return false;
|
||||||
|
|
||||||
|
value = value_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read(const std::map<std::string, std::string>& section, const std::string& key, std::optional<int>& value){
|
||||||
|
auto item = section.find(key);
|
||||||
|
if (item == section.end()) return false;
|
||||||
|
const std::string &data = item->second;
|
||||||
|
if (data.empty()) return false;
|
||||||
|
int value_ = std::atoi(data.c_str());
|
||||||
|
if (value_ == 0) return false;
|
||||||
|
|
||||||
|
value = value_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool read(const std::map<std::string, std::string>& section, const std::string& key, std::optional<float>& value){
|
||||||
|
auto item = section.find(key);
|
||||||
|
if (item == section.end()) return false;
|
||||||
|
const std::string &data = item->second;
|
||||||
|
if (data.empty()) return false;
|
||||||
|
float value_;
|
||||||
|
fast_float::from_chars(data.c_str(), data.c_str() + data.length(), value_);
|
||||||
|
// read only non zero value
|
||||||
|
if (fabs(value_) <= std::numeric_limits<float>::epsilon()) return false;
|
||||||
|
|
||||||
|
value = value_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<FontItem> GLGizmoEmboss::get_font_item(
|
std::optional<FontItem> GLGizmoEmboss::get_font_item(
|
||||||
const std::map<std::string, std::string> &app_cfg_section)
|
const std::map<std::string, std::string> &app_cfg_section)
|
||||||
{
|
{
|
||||||
@ -1323,10 +1353,20 @@ std::optional<FontItem> GLGizmoEmboss::get_font_item(
|
|||||||
|
|
||||||
auto name_it = app_cfg_section.find(APP_CONFIG_FONT_NAME);
|
auto name_it = app_cfg_section.find(APP_CONFIG_FONT_NAME);
|
||||||
static const std::string default_name = "font_name";
|
static const std::string default_name = "font_name";
|
||||||
const std::string & name = (name_it == app_cfg_section.end()) ?
|
const std::string &name =
|
||||||
default_name :
|
(name_it == app_cfg_section.end()) ?
|
||||||
name_it->second;
|
default_name : name_it->second;
|
||||||
return FontItem(name, path, WxFontUtils::get_actual_type());
|
|
||||||
|
FontProp fp;
|
||||||
|
read(app_cfg_section, APP_CONFIG_FONT_LINE_HEIGHT, fp.size_in_mm);
|
||||||
|
read(app_cfg_section, APP_CONFIG_FONT_DEPTH, fp.emboss);
|
||||||
|
read(app_cfg_section, APP_CONFIG_FONT_BOLDNESS, fp.boldness);
|
||||||
|
read(app_cfg_section, APP_CONFIG_FONT_SKEW, fp.skew);
|
||||||
|
read(app_cfg_section, APP_CONFIG_FONT_CHAR_GAP, fp.char_gap);
|
||||||
|
read(app_cfg_section, APP_CONFIG_FONT_LINE_GAP, fp.line_gap);
|
||||||
|
|
||||||
|
FontItem::Type type = WxFontUtils::get_actual_type();
|
||||||
|
return FontItem(name, path, type, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::set_font_item(AppConfig & cfg,
|
void GLGizmoEmboss::set_font_item(AppConfig & cfg,
|
||||||
@ -1337,6 +1377,17 @@ void GLGizmoEmboss::set_font_item(AppConfig & cfg,
|
|||||||
cfg.clear_section(section_name);
|
cfg.clear_section(section_name);
|
||||||
cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name);
|
cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name);
|
||||||
cfg.set(section_name, APP_CONFIG_FONT_DESCRIPTOR, fi.path);
|
cfg.set(section_name, APP_CONFIG_FONT_DESCRIPTOR, fi.path);
|
||||||
|
const FontProp &fp = fi.prop;
|
||||||
|
cfg.set(section_name, APP_CONFIG_FONT_LINE_HEIGHT, std::to_string(fp.size_in_mm));
|
||||||
|
cfg.set(section_name, APP_CONFIG_FONT_DEPTH, std::to_string(fp.emboss));
|
||||||
|
if (fp.boldness.has_value())
|
||||||
|
cfg.set(section_name, APP_CONFIG_FONT_BOLDNESS, std::to_string(*fp.boldness));
|
||||||
|
if (fp.skew.has_value())
|
||||||
|
cfg.set(section_name, APP_CONFIG_FONT_SKEW, std::to_string(*fp.skew));
|
||||||
|
if (fp.char_gap.has_value())
|
||||||
|
cfg.set(section_name, APP_CONFIG_FONT_CHAR_GAP, std::to_string(*fp.char_gap));
|
||||||
|
if (fp.line_gap.has_value())
|
||||||
|
cfg.set(section_name, APP_CONFIG_FONT_LINE_GAP, std::to_string(*fp.line_gap));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLGizmoEmboss::get_file_name(const std::string &file_path)
|
std::string GLGizmoEmboss::get_file_name(const std::string &file_path)
|
||||||
|
@ -167,7 +167,6 @@ private:
|
|||||||
// to share data with job thread
|
// to share data with job thread
|
||||||
std::shared_ptr<Emboss::Font> m_font;
|
std::shared_ptr<Emboss::Font> m_font;
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
FontProp m_font_prop;
|
|
||||||
|
|
||||||
// actual volume
|
// actual volume
|
||||||
ModelVolume *m_volume;
|
ModelVolume *m_volume;
|
||||||
@ -199,8 +198,16 @@ private:
|
|||||||
// load / store appConfig
|
// load / store appConfig
|
||||||
void load_font_list();
|
void load_font_list();
|
||||||
void store_font_list();
|
void store_font_list();
|
||||||
|
|
||||||
|
// app config Attribute names
|
||||||
static const std::string APP_CONFIG_FONT_NAME;
|
static const std::string APP_CONFIG_FONT_NAME;
|
||||||
static const std::string APP_CONFIG_FONT_DESCRIPTOR;
|
static const std::string APP_CONFIG_FONT_DESCRIPTOR;
|
||||||
|
static const std::string APP_CONFIG_FONT_LINE_HEIGHT;
|
||||||
|
static const std::string APP_CONFIG_FONT_DEPTH;
|
||||||
|
static const std::string APP_CONFIG_FONT_BOLDNESS;
|
||||||
|
static const std::string APP_CONFIG_FONT_SKEW;
|
||||||
|
static const std::string APP_CONFIG_FONT_CHAR_GAP;
|
||||||
|
static const std::string APP_CONFIG_FONT_LINE_GAP;
|
||||||
std::string get_app_config_font_section(unsigned index);
|
std::string get_app_config_font_section(unsigned index);
|
||||||
std::optional<FontItem> get_font_item(const std::map<std::string, std::string> &app_cfg_section);
|
std::optional<FontItem> get_font_item(const std::map<std::string, std::string> &app_cfg_section);
|
||||||
void set_font_item(AppConfig &cfg, const FontItem &fi, unsigned index);
|
void set_font_item(AppConfig &cfg, const FontItem &fi, unsigned index);
|
||||||
|
@ -31,7 +31,7 @@ void EmbossJob::process(Ctl &ctl) {
|
|||||||
// Do NOT process empty string
|
// Do NOT process empty string
|
||||||
if (text.empty()) return;
|
if (text.empty()) return;
|
||||||
|
|
||||||
const FontProp &prop = cfg.font_prop;
|
const FontProp &prop = cfg.font_item.prop;
|
||||||
ExPolygons shapes = Emboss::text2shapes(*m_input->font, text.c_str(), prop);
|
ExPolygons shapes = Emboss::text2shapes(*m_input->font, text.c_str(), prop);
|
||||||
|
|
||||||
if (ctl.was_canceled()) return;
|
if (ctl.was_canceled()) return;
|
||||||
|
@ -63,8 +63,11 @@ FontItem WxFontUtils::get_font_item(const wxFont &font)
|
|||||||
std::string name = get_human_readable_name(font);
|
std::string name = get_human_readable_name(font);
|
||||||
std::string fontDesc = store_wxFont(font);
|
std::string fontDesc = store_wxFont(font);
|
||||||
FontItem::Type type = get_actual_type();
|
FontItem::Type type = get_actual_type();
|
||||||
// wxFont f = font; // copy
|
|
||||||
return FontItem(name, fontDesc, type);
|
// synchronize font property with actual font
|
||||||
|
FontProp font_prop;
|
||||||
|
WxFontUtils::update_property(font_prop, font);
|
||||||
|
return FontItem(name, fontDesc, type, font_prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
FontItem WxFontUtils::get_os_font()
|
FontItem WxFontUtils::get_os_font()
|
||||||
@ -183,6 +186,7 @@ void WxFontUtils::update_property(FontProp &font_prop, const wxFont &font)
|
|||||||
// is approximately 0.0139 inch or 352.8 um. But it is too small, so I
|
// is approximately 0.0139 inch or 352.8 um. But it is too small, so I
|
||||||
// decide use point size as mm for emboss
|
// decide use point size as mm for emboss
|
||||||
font_prop.size_in_mm = font.GetPointSize(); // *0.3528f;
|
font_prop.size_in_mm = font.GetPointSize(); // *0.3528f;
|
||||||
|
font_prop.emboss = font_prop.size_in_mm / 2.f;
|
||||||
|
|
||||||
wxString wx_face_name = font.GetFaceName();
|
wxString wx_face_name = font.GetFaceName();
|
||||||
std::string face_name((const char *) wx_face_name.ToUTF8());
|
std::string face_name((const char *) wx_face_name.ToUTF8());
|
||||||
@ -206,5 +210,12 @@ void WxFontUtils::update_property(FontProp &font_prop, const wxFont &font)
|
|||||||
if (it != from_weight.end()) font_prop.weight = it->second;
|
if (it != from_weight.end()) font_prop.weight = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
// dynamic creation of italic, on linux is italic made by skew of normal font
|
||||||
|
wxFontStyle style = font.GetStyle();
|
||||||
|
if ((style == wxFONTSTYLE_ITALIC || style == wxFONTSTYLE_SLANT) &&
|
||||||
|
!Emboss::is_italic(*m_font)) {
|
||||||
|
font_prop.skew = 0.2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user