mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 22:40:37 +08:00
Partialy fix align:
whitechar in center enters at begining enters at end Align
This commit is contained in:
parent
bf9bf2c626
commit
4be73de02f
@ -1271,32 +1271,30 @@ const int CANCEL_CHECK = 10;
|
||||
|
||||
ExPolygons Emboss::text2shapes(FontFileWithCache &font_with_cache, const char *text, const FontProp &font_prop, const std::function<bool()>& was_canceled)
|
||||
{
|
||||
assert(font_with_cache.has_value());
|
||||
const FontFile& font = *font_with_cache.font_file;
|
||||
unsigned int font_index = font_prop.collection_number.value_or(0);
|
||||
if (!priv::is_valid(font, font_index)) return {};
|
||||
|
||||
unsigned counter = 0;
|
||||
Point cursor(0, 0);
|
||||
std::wstring text_w = boost::nowide::widen(text);
|
||||
std::vector<ExPolygons> vshapes = text2vshapes(font_with_cache, text_w, font_prop, was_canceled);
|
||||
// unify to one expolygon
|
||||
ExPolygons result;
|
||||
fontinfo_opt font_info_cache;
|
||||
std::wstring ws = boost::nowide::widen(text);
|
||||
for (wchar_t wc: ws){
|
||||
if (++counter == CANCEL_CHECK) {
|
||||
counter = 0;
|
||||
if (was_canceled())
|
||||
return {};
|
||||
}
|
||||
ExPolygons expolygons = letter2shapes(wc, cursor, font_with_cache, font_prop, font_info_cache);
|
||||
if (expolygons.empty())
|
||||
for (ExPolygons &shapes : vshapes) {
|
||||
if (shapes.empty())
|
||||
continue;
|
||||
expolygons_append(result, std::move(expolygons));
|
||||
expolygons_append(result, std::move(shapes));
|
||||
}
|
||||
result = Slic3r::union_ex(result);
|
||||
heal_shape(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// <summary>
|
||||
/// Align expolygons by type
|
||||
/// </summary>
|
||||
/// <param name="type">Type of alignement</param>
|
||||
/// <param name="shape">shapes to align</param>
|
||||
/// <param name="text">Same size as shape for align per line(detect of end line - '\n')</param>
|
||||
void align_shape(FontProp::Align type, std::vector<ExPolygons> &shape, const std::wstring &text);
|
||||
}
|
||||
|
||||
std::vector<ExPolygons> Emboss::text2vshapes(FontFileWithCache &font_with_cache, const std::wstring& text, const FontProp &font_prop, const std::function<bool()>& was_canceled){
|
||||
assert(font_with_cache.has_value());
|
||||
const FontFile &font = *font_with_cache.font_file;
|
||||
@ -1307,8 +1305,8 @@ std::vector<ExPolygons> Emboss::text2vshapes(FontFileWithCache &font_with_cache,
|
||||
unsigned counter = 0;
|
||||
Point cursor(0, 0);
|
||||
|
||||
std::vector<ExPolygons> result;
|
||||
fontinfo_opt font_info_cache;
|
||||
std::vector<ExPolygons> result;
|
||||
result.reserve(text.size());
|
||||
for (wchar_t letter : text) {
|
||||
if (++counter == CANCEL_CHECK) {
|
||||
@ -1318,6 +1316,8 @@ std::vector<ExPolygons> Emboss::text2vshapes(FontFileWithCache &font_with_cache,
|
||||
}
|
||||
result.emplace_back(letter2shapes(letter, cursor, font_with_cache, font_prop, font_info_cache));
|
||||
}
|
||||
|
||||
align_shape(font_prop.align, result, text);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1326,26 +1326,27 @@ unsigned Emboss::get_count_lines(const std::wstring& ws)
|
||||
{
|
||||
if (ws.empty())
|
||||
return 0;
|
||||
unsigned prev_count = 0;
|
||||
for (wchar_t wc : ws)
|
||||
if (wc == '\n')
|
||||
++prev_count;
|
||||
else
|
||||
break;
|
||||
|
||||
unsigned post_count = 0;
|
||||
for (wchar_t wc : boost::adaptors::reverse(ws))
|
||||
if (wc == '\n')
|
||||
++post_count;
|
||||
else
|
||||
break;
|
||||
|
||||
unsigned count = 1;
|
||||
for (wchar_t wc : ws)
|
||||
if (wc == '\n')
|
||||
++count;
|
||||
return count;
|
||||
|
||||
return count - prev_count - post_count;
|
||||
// unsigned prev_count = 0;
|
||||
// for (wchar_t wc : ws)
|
||||
// if (wc == '\n')
|
||||
// ++prev_count;
|
||||
// else
|
||||
// break;
|
||||
//
|
||||
// unsigned post_count = 0;
|
||||
// for (wchar_t wc : boost::adaptors::reverse(ws))
|
||||
// if (wc == '\n')
|
||||
// ++post_count;
|
||||
// else
|
||||
// break;
|
||||
//return count - prev_count - post_count;
|
||||
}
|
||||
|
||||
unsigned Emboss::get_count_lines(const std::string &text)
|
||||
@ -1875,11 +1876,12 @@ PolygonPoints Emboss::sample_slice(const TextLine &slice, const BoundingBoxes &b
|
||||
// find BB in center of line
|
||||
size_t first_right_index = 0;
|
||||
for (const BoundingBox &bb : bbs)
|
||||
if (bb.min.x() >= 0) {
|
||||
break;
|
||||
} else {
|
||||
if (!bb.defined) // white char do not have bb
|
||||
continue;
|
||||
else if (bb.min.x() < 0)
|
||||
++first_right_index;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
PolygonPoints samples(bbs.size());
|
||||
int32_t shapes_x_cursor = 0;
|
||||
@ -1925,71 +1927,76 @@ PolygonPoints Emboss::sample_slice(const TextLine &slice, const BoundingBoxes &b
|
||||
}
|
||||
|
||||
namespace {
|
||||
Point get_align_offset(FontProp::Align type, const BoundingBox &bb)
|
||||
{
|
||||
Point offset;
|
||||
int32_t get_align_y_offset(FontProp::Align type, const BoundingBox &bb){
|
||||
switch (type) {
|
||||
// case Slic3r::FontProp::Align::start_first_line: break;
|
||||
case Slic3r::FontProp::Align::first_line_left:
|
||||
case Slic3r::FontProp::Align::first_line_right:
|
||||
case Slic3r::FontProp::Align::first_line_center: break; // No change
|
||||
case Slic3r::FontProp::Align::center_left:
|
||||
case Slic3r::FontProp::Align::center_right:
|
||||
case Slic3r::FontProp::Align::center_center: offset.y() = bb.center().y(); break;
|
||||
case Slic3r::FontProp::Align::center_center: return -bb.center().y();
|
||||
case Slic3r::FontProp::Align::top_left:
|
||||
case Slic3r::FontProp::Align::top_right:
|
||||
case Slic3r::FontProp::Align::top_center: offset.y() = bb.min.y(); break;
|
||||
case Slic3r::FontProp::Align::top_center: return -bb.max.y(); break; // direction of Y in 2d is from top to bottom
|
||||
case Slic3r::FontProp::Align::bottom_left:
|
||||
case Slic3r::FontProp::Align::bottom_right:
|
||||
case Slic3r::FontProp::Align::bottom_center: offset.y() = bb.max.y(); break;
|
||||
case Slic3r::FontProp::Align::bottom_center: return -bb.min.y(); // direction of Y in 2d is from top to bottom
|
||||
default: break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int32_t get_align_x_offset(FontProp::Align type, const BoundingBox &shape_bb, const BoundingBox &line_bb)
|
||||
{
|
||||
switch (type) {
|
||||
// case Slic3r::FontProp::Align::start_first_line: break;
|
||||
case Slic3r::FontProp::Align::first_line_center:
|
||||
case Slic3r::FontProp::Align::center_center:
|
||||
case Slic3r::FontProp::Align::top_center:
|
||||
case Slic3r::FontProp::Align::bottom_center: offset.x() = bb.center().x(); break;
|
||||
case Slic3r::FontProp::Align::bottom_center: return -shape_bb.center().x() + (shape_bb.size().x() - line_bb.size().x())/2;
|
||||
case Slic3r::FontProp::Align::first_line_left: break; // special case do not use offset
|
||||
case Slic3r::FontProp::Align::center_left:
|
||||
case Slic3r::FontProp::Align::top_left:
|
||||
case Slic3r::FontProp::Align::bottom_left: offset.x() = bb.min.x(); break;
|
||||
case Slic3r::FontProp::Align::bottom_left: return -shape_bb.min.x();
|
||||
case Slic3r::FontProp::Align::first_line_right:
|
||||
case Slic3r::FontProp::Align::center_right:
|
||||
case Slic3r::FontProp::Align::top_right:
|
||||
case Slic3r::FontProp::Align::bottom_right: offset.x() = bb.max.x(); break;
|
||||
case Slic3r::FontProp::Align::bottom_right: return -shape_bb.max.x() + (shape_bb.size().x() - line_bb.size().x());
|
||||
default: break;
|
||||
}
|
||||
return -offset;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Emboss::align_shape(FontProp::Align type, ExPolygons &shape, BoundingBox *bb)
|
||||
{
|
||||
if (type == FontProp::Align::start_first_line)
|
||||
return; // no alignement
|
||||
|
||||
BoundingBox shape_bb_data;
|
||||
BoundingBox &shape_bb = (bb != nullptr) ? *bb : shape_bb_data;
|
||||
if (!shape_bb.defined)
|
||||
shape_bb = get_extents(shape);
|
||||
|
||||
Point offset = get_align_offset(type, shape_bb);
|
||||
for (ExPolygon &s : shape)
|
||||
s.translate(offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Emboss::align_shape(FontProp::Align type, std::vector<ExPolygons> &shapes, BoundingBox *bb)
|
||||
void align_shape(FontProp::Align type, std::vector<ExPolygons> &shapes, const std::wstring &text)
|
||||
{
|
||||
if (type == FontProp::Align::start_first_line)
|
||||
if (type == FontProp::Align::first_line_left)
|
||||
return; // no alignement
|
||||
|
||||
BoundingBox shape_bb_data;
|
||||
BoundingBox &shape_bb = (bb != nullptr) ? *bb : shape_bb_data;
|
||||
if (!shape_bb.defined)
|
||||
BoundingBox shape_bb;
|
||||
for (const ExPolygons& shape: shapes)
|
||||
shape_bb.merge(get_extents(shape));
|
||||
|
||||
Point offset = get_align_offset(type, shape_bb);
|
||||
for (ExPolygons &shape : shapes)
|
||||
auto get_line_bb = [&](size_t j) {
|
||||
BoundingBox line_bb;
|
||||
for (; j < text.length() && text[j] != '\n'; ++j)
|
||||
line_bb.merge(get_extents(shapes[j]));
|
||||
return line_bb;
|
||||
};
|
||||
|
||||
Point offset(
|
||||
get_align_x_offset(type, shape_bb, get_line_bb(0)),
|
||||
get_align_y_offset(type, shape_bb));
|
||||
assert(shapes.size() == text.length());
|
||||
for (size_t i = 0; i < shapes.size(); ++i) {
|
||||
wchar_t letter = text[i];
|
||||
if (letter == '\n'){
|
||||
offset.x() = get_align_x_offset(type, shape_bb, get_line_bb(i+1));
|
||||
continue;
|
||||
}
|
||||
ExPolygons &shape = shapes[i];
|
||||
for (ExPolygon &s : shape)
|
||||
s.translate(offset);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
#ifdef REMOVE_SPIKES
|
||||
#include <Geometry.hpp>
|
||||
|
@ -441,15 +441,6 @@ namespace Emboss
|
||||
double calculate_angle(int32_t distance, PolygonPoint polygon_point, const Polygon &polygon);
|
||||
std::vector<double> calculate_angles(int32_t distance, const PolygonPoints& polygon_points, const Polygon &polygon);
|
||||
|
||||
/// <summary>
|
||||
/// Align expolygons by type
|
||||
/// </summary>
|
||||
/// <param name="type">Type of alignement</param>
|
||||
/// <param name="shape">shapes to align</param>
|
||||
/// <param name="bb">extents of shape</param>
|
||||
void align_shape(FontProp::Align type, ExPolygons& shape, BoundingBox* bb = nullptr);
|
||||
void align_shape(FontProp::Align type, std::vector<ExPolygons> &shape, BoundingBox *bb = nullptr);
|
||||
|
||||
} // namespace Emboss
|
||||
} // namespace Slic3r
|
||||
#endif // slic3r_Emboss_hpp_
|
||||
|
@ -64,7 +64,9 @@ struct FontProp
|
||||
bool per_glyph;
|
||||
|
||||
enum class Align {
|
||||
start_first_line, // it depends on position of zero for first letter
|
||||
first_line_left, // it depends on position of zero for first letter (no shape move)
|
||||
first_line_right, // use Y zero same as first letter
|
||||
first_line_center, // use Y zero same as first letter
|
||||
center_left,
|
||||
center_right,
|
||||
center_center,
|
||||
@ -77,7 +79,7 @@ struct FontProp
|
||||
};
|
||||
// change pivot of text
|
||||
// When not set, center is used and is not stored
|
||||
Align align = Align::center_center;
|
||||
Align align = Align::first_line_center;
|
||||
|
||||
//////
|
||||
// Duplicit data to wxFontDescriptor
|
||||
|
@ -447,7 +447,7 @@ bool GLGizmoEmboss::on_mouse_for_translate(const wxMouseEvent &mouse_event)
|
||||
if (gl_volume == nullptr || !m_style_manager.is_active_font())
|
||||
return res;
|
||||
|
||||
m_style_manager.get_style().prop.angle = calc_up(gl_volume->world_matrix(), priv::up_limit);
|
||||
m_style_manager.get_font_prop().angle = calc_up(gl_volume->world_matrix(), priv::up_limit);
|
||||
}
|
||||
|
||||
volume_transformation_changing();
|
||||
@ -559,7 +559,7 @@ void GLGizmoEmboss::volume_transformation_changing()
|
||||
}
|
||||
const FontProp &prop = m_volume->text_configuration->style.prop;
|
||||
if (prop.per_glyph)
|
||||
init_text_lines();
|
||||
init_text_lines(m_text_lines.get_lines().size());
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::volume_transformation_changed()
|
||||
@ -571,7 +571,7 @@ void GLGizmoEmboss::volume_transformation_changed()
|
||||
|
||||
const FontProp &prop = m_volume->text_configuration->style.prop;
|
||||
if (prop.per_glyph)
|
||||
init_text_lines();
|
||||
init_text_lines(m_text_lines.get_lines().size());
|
||||
|
||||
// Update surface by new position
|
||||
if (prop.use_surface || prop.per_glyph)
|
||||
@ -1047,7 +1047,7 @@ EmbossStyles GLGizmoEmboss::create_default_styles()
|
||||
return styles;
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::init_text_lines(){
|
||||
void GLGizmoEmboss::init_text_lines(unsigned count_lines){
|
||||
assert(m_style_manager.is_active_font());
|
||||
if (!m_style_manager.is_active_font())
|
||||
return;
|
||||
@ -1067,7 +1067,7 @@ void GLGizmoEmboss::init_text_lines(){
|
||||
const FontFile &ff = *ff_ptr;
|
||||
|
||||
double line_height = TextLinesModel::calc_line_height(ff, fp);
|
||||
m_text_lines.init(m_parent.get_selection(), line_height);
|
||||
m_text_lines.init(m_parent.get_selection(), line_height, count_lines);
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::set_volume_by_selection()
|
||||
@ -1306,6 +1306,9 @@ bool GLGizmoEmboss::process()
|
||||
if (use_surface && is_object)
|
||||
use_surface = false;
|
||||
|
||||
assert(!data.text_configuration.style.prop.per_glyph ||
|
||||
get_count_lines(m_text) == m_text_lines.get_lines().size());
|
||||
|
||||
if (use_surface) {
|
||||
// Model to cut surface from.
|
||||
SurfaceVolumeData::ModelSources sources = create_volume_sources(m_volume);
|
||||
@ -1540,6 +1543,12 @@ void GLGizmoEmboss::draw_text_input()
|
||||
ImVec2 input_size(m_gui_cfg->text_size.x, m_gui_cfg->text_size.y + extra_height);
|
||||
const ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_AutoSelectAll;
|
||||
if (ImGui::InputTextMultiline("##Text", &m_text, input_size, flags)) {
|
||||
if (m_style_manager.get_font_prop().per_glyph) {
|
||||
unsigned count_lines = get_count_lines(m_text);
|
||||
if (count_lines != m_text_lines.get_lines().size())
|
||||
// Necesarry to initialize count by given number (differ from stored in volume at the moment)
|
||||
init_text_lines(count_lines);
|
||||
}
|
||||
process();
|
||||
range_text = create_range_text_prep();
|
||||
}
|
||||
@ -2801,7 +2810,7 @@ bool GLGizmoEmboss::rev_checkbox(const std::string &name,
|
||||
}
|
||||
|
||||
bool GLGizmoEmboss::set_height() {
|
||||
float &value = m_style_manager.get_style().prop.size_in_mm;
|
||||
float &value = m_style_manager.get_font_prop().size_in_mm;
|
||||
|
||||
// size can't be zero or negative
|
||||
priv::Limits::apply(value, priv::limits.size_in_mm);
|
||||
@ -2829,7 +2838,7 @@ bool GLGizmoEmboss::set_height() {
|
||||
|
||||
void GLGizmoEmboss::draw_height(bool use_inch)
|
||||
{
|
||||
float &value = m_style_manager.get_style().prop.size_in_mm;
|
||||
float &value = m_style_manager.get_font_prop().size_in_mm;
|
||||
const EmbossStyle* stored_style = m_style_manager.get_stored_style();
|
||||
const float *stored = (stored_style != nullptr)? &stored_style->prop.size_in_mm : nullptr;
|
||||
const char *size_format = use_inch ? "%.2f in" : "%.1f mm";
|
||||
@ -2842,7 +2851,7 @@ void GLGizmoEmboss::draw_height(bool use_inch)
|
||||
|
||||
bool GLGizmoEmboss::set_depth()
|
||||
{
|
||||
float &value = m_style_manager.get_style().prop.emboss;
|
||||
float &value = m_style_manager.get_font_prop().emboss;
|
||||
|
||||
// size can't be zero or negative
|
||||
priv::Limits::apply(value, priv::limits.emboss);
|
||||
@ -2853,7 +2862,7 @@ bool GLGizmoEmboss::set_depth()
|
||||
|
||||
void GLGizmoEmboss::draw_depth(bool use_inch)
|
||||
{
|
||||
float &value = m_style_manager.get_style().prop.emboss;
|
||||
float &value = m_style_manager.get_font_prop().emboss;
|
||||
const EmbossStyle* stored_style = m_style_manager.get_stored_style();
|
||||
const float *stored = ((stored_style)? &stored_style->prop.emboss : nullptr);
|
||||
const std::string revert_emboss_depth = _u8L("Revert embossed depth.");
|
||||
@ -2971,7 +2980,7 @@ void GLGizmoEmboss::draw_advanced()
|
||||
return;
|
||||
}
|
||||
|
||||
FontProp &font_prop = m_style_manager.get_style().prop;
|
||||
FontProp &font_prop = m_style_manager.get_font_prop();
|
||||
const auto &cn = m_style_manager.get_font_prop().collection_number;
|
||||
unsigned int font_index = (cn.has_value()) ? *cn : 0;
|
||||
const auto &font_info = ff.font_file->infos[font_index];
|
||||
@ -3210,7 +3219,7 @@ void GLGizmoEmboss::draw_advanced()
|
||||
if (ImGui::Button(_u8L("Set text to face camera").c_str())) {
|
||||
assert(get_selected_volume(m_parent.get_selection()) == m_volume);
|
||||
const Camera &cam = wxGetApp().plater()->get_camera();
|
||||
bool use_surface = m_style_manager.get_style().prop.use_surface;
|
||||
bool use_surface = m_style_manager.get_font_prop().use_surface;
|
||||
if (priv::apply_camera_dir(cam, m_parent, m_keep_up) && use_surface)
|
||||
process();
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
@ -3239,14 +3248,15 @@ void GLGizmoEmboss::draw_advanced()
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(100);
|
||||
if (ImGui::SliderFloat("##base_line_y_offset", &m_text_lines.offset, -10.f, 10.f, "%f mm")) {
|
||||
init_text_lines();
|
||||
init_text_lines(m_text_lines.get_lines().size());
|
||||
process();
|
||||
} else if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", _u8L("Move base line (up/down) for allign letters").c_str());
|
||||
|
||||
// order must match align enum
|
||||
const char* align_names[] = {
|
||||
"start_first_line",
|
||||
const char* align_names[] = {"first_line_left",
|
||||
"first_line_right",
|
||||
"first_line_center",
|
||||
"center_left",
|
||||
"center_right",
|
||||
"center_center",
|
||||
@ -3255,8 +3265,7 @@ void GLGizmoEmboss::draw_advanced()
|
||||
"top_center",
|
||||
"bottom_left",
|
||||
"bottom_right",
|
||||
"bottom_center"
|
||||
};
|
||||
"bottom_center"};
|
||||
int selected_align = static_cast<int>(font_prop.align);
|
||||
if (ImGui::Combo("align", &selected_align, align_names, IM_ARRAYSIZE(align_names))) {
|
||||
font_prop.align = static_cast<FontProp::Align>(selected_align);
|
||||
@ -3359,7 +3368,7 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
|
||||
const auto&ff = m_style_manager.get_font_file_with_cache();
|
||||
if (WxFontUtils::is_italic(wx_font) &&
|
||||
!Emboss::is_italic(*ff.font_file, font_collection)) {
|
||||
m_style_manager.get_style().prop.skew = 0.2;
|
||||
m_style_manager.get_font_prop().skew = 0.2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -3428,7 +3437,7 @@ bool GLGizmoEmboss::choose_svg_file()
|
||||
|
||||
BoundingBox bb;
|
||||
for (const auto &p : polys) bb.merge(p.contour.points);
|
||||
const FontProp &fp = m_style_manager.get_style().prop;
|
||||
const FontProp &fp = m_style_manager.get_font_prop();
|
||||
float scale = fp.size_in_mm / std::max(bb.max.x(), bb.max.y());
|
||||
auto project = std::make_unique<ProjectScale>(
|
||||
std::make_unique<ProjectZ>(fp.emboss / scale), scale);
|
||||
|
@ -317,7 +317,7 @@ private:
|
||||
|
||||
// Keep information about curvature of text line around surface
|
||||
TextLinesModel m_text_lines;
|
||||
void init_text_lines();
|
||||
void init_text_lines(unsigned count_lines = 0);
|
||||
|
||||
// Rotation gizmo
|
||||
GLGizmoRotate m_rotate_gizmo;
|
||||
|
@ -362,10 +362,15 @@ bool priv::check(const DataBase &input, bool check_fontfile, bool use_surface)
|
||||
res &= !input.text_configuration.text.empty();
|
||||
assert(!input.volume_name.empty());
|
||||
res &= !input.volume_name.empty();
|
||||
assert(input.text_configuration.style.prop.use_surface == use_surface);
|
||||
res &= input.text_configuration.style.prop.use_surface == use_surface;
|
||||
assert(input.text_configuration.style.prop.per_glyph == !input.text_lines.empty());
|
||||
res &= input.text_configuration.style.prop.per_glyph == !input.text_lines.empty();
|
||||
const FontProp& prop = input.text_configuration.style.prop;
|
||||
assert(prop.use_surface == use_surface);
|
||||
res &= prop.use_surface == use_surface;
|
||||
assert(prop.per_glyph == !input.text_lines.empty());
|
||||
res &= prop.per_glyph == !input.text_lines.empty();
|
||||
if (prop.per_glyph) {
|
||||
assert(get_count_lines(input.text_configuration.text) == input.text_lines.size());
|
||||
res &= get_count_lines(input.text_configuration.text) == input.text_lines.size();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
bool priv::check(const DataCreateVolume &input, bool is_main_thread) {
|
||||
@ -432,7 +437,6 @@ ExPolygons priv::create_shape(DataBase &input, Fnc was_canceled) {
|
||||
if (shapes.empty())
|
||||
return {};
|
||||
|
||||
align_shape(input.text_configuration.style.prop.align, shapes);
|
||||
return shapes;
|
||||
}
|
||||
|
||||
@ -452,7 +456,6 @@ std::vector<ExPolygons> priv::create_shapes(DataBase &input, Fnc was_canceled) {
|
||||
if (shapes.empty())
|
||||
return {};
|
||||
|
||||
align_shape(prop.align, shapes);
|
||||
if (was_canceled())
|
||||
return {};
|
||||
|
||||
@ -591,8 +594,8 @@ TriangleMesh priv::try_create_mesh(DataBase &input, Fnc was_canceled)
|
||||
{
|
||||
if (!input.text_lines.empty()) {
|
||||
TriangleMesh tm = create_mesh_per_glyph(input, was_canceled);
|
||||
if (!tm.empty())
|
||||
return tm;
|
||||
if (was_canceled()) return {};
|
||||
if (!tm.empty()) return tm;
|
||||
}
|
||||
|
||||
ExPolygons shapes = priv::create_shape(input, was_canceled);
|
||||
|
@ -251,7 +251,7 @@ GLModel::Geometry create_geometry(const TextLines &lines)
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void TextLinesModel::init(const Selection &selection, double line_height)
|
||||
void TextLinesModel::init(const Selection &selection, double line_height, unsigned count_lines)
|
||||
{
|
||||
const GLVolume *gl_volume_ptr = selection.get_first_volume();
|
||||
if (gl_volume_ptr == nullptr)
|
||||
@ -268,13 +268,15 @@ void TextLinesModel::init(const Selection &selection, double line_height)
|
||||
return;
|
||||
const ModelVolume &mv = *mv_ptr;
|
||||
|
||||
// calculate count lines when not set
|
||||
if (count_lines == 0) {
|
||||
const std::optional<TextConfiguration> tc_opt = mv.text_configuration;
|
||||
if (!tc_opt.has_value())
|
||||
return;
|
||||
|
||||
unsigned count_lines = Emboss::get_count_lines(tc_opt->text);
|
||||
count_lines = Emboss::get_count_lines(tc_opt->text);
|
||||
if (count_lines == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
double first_line_center = offset + (count_lines / 2) * line_height - ((count_lines % 2 == 0) ? line_height / 2. : 0.);
|
||||
std::vector<float> line_centers(count_lines);
|
||||
|
@ -20,7 +20,8 @@ public:
|
||||
/// <param name="selection">Must be selected text volume</param>
|
||||
/// <param name="line_height">Height of text line with spacing [in mm]</param>
|
||||
/// <param name="line_offset">Offset of base line from center [in mm]</param>
|
||||
void init(const Selection &selection, double line_height);
|
||||
/// <param name="count_lines">[Optional] Count lines when not set it is calculated from vodel volume text</param>
|
||||
void init(const Selection &selection, double line_height, unsigned count_lines = 0);
|
||||
void render(const Transform3d &text_world);
|
||||
|
||||
bool is_init() const { return m_model.is_initialized(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user