mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-12 23:29:02 +08:00
Fix position of base line for per glyph position to be on the half of ascent in all vertical alignment
This commit is contained in:
parent
5d37932b4d
commit
331bfaa556
@ -1929,22 +1929,22 @@ PolygonPoints Emboss::sample_slice(const TextLine &slice, const BoundingBoxes &b
|
||||
}
|
||||
|
||||
namespace {
|
||||
int32_t get_align_y_offset(FontProp::VerticalAlign align, int count_lines, int line_height)
|
||||
template<typename T> T get_align_y_offset(FontProp::VerticalAlign align, unsigned count_lines, T line_height)
|
||||
{
|
||||
if (count_lines == 0)
|
||||
return 0;
|
||||
|
||||
// direction of Y in 2d is from top to bottom
|
||||
// zero is on base line of first line
|
||||
switch (align) {
|
||||
case FontProp::VerticalAlign::center:
|
||||
return ((count_lines-1) / 2) * line_height
|
||||
+ ((count_lines % 2 == 0) ? (line_height / 2) : 0);
|
||||
case FontProp::VerticalAlign::bottom:
|
||||
return (count_lines-1) * line_height;
|
||||
case FontProp::VerticalAlign::center: return ((count_lines - 1) / 2) * line_height + ((count_lines % 2 == 0) ? (line_height / 2) : 0);
|
||||
case FontProp::VerticalAlign::bottom: return (count_lines - 1) * line_height;
|
||||
case FontProp::VerticalAlign::top: // no change
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t get_align_x_offset(FontProp::HorizontalAlign align, const BoundingBox &shape_bb, const BoundingBox &line_bb)
|
||||
{
|
||||
switch (align) {
|
||||
@ -1990,6 +1990,10 @@ void align_shape(FontProp::Align type, std::vector<ExPolygons> &shapes, const st
|
||||
}
|
||||
} // namespace
|
||||
|
||||
double Emboss::get_align_y_offset(FontProp::VerticalAlign align, unsigned count_lines, double line_height){
|
||||
return ::get_align_y_offset<double>(align, count_lines, line_height);
|
||||
}
|
||||
|
||||
#ifdef REMOVE_SPIKES
|
||||
#include <Geometry.hpp>
|
||||
void priv::remove_spikes(Polygon &polygon, const SpikeDesc &spike_desc)
|
||||
|
@ -236,6 +236,16 @@ namespace Emboss
|
||||
/// <returns>Line height with spacing in ExPolygon size</returns>
|
||||
int get_line_height(const FontFile &font, const FontProp &prop);
|
||||
|
||||
/// <summary>
|
||||
/// Calculate Vertical align
|
||||
/// </summary>
|
||||
/// <typeparam name="T">double for mm</typeparam>
|
||||
/// <param name="align">type</param>
|
||||
/// <param name="count_lines"></param>
|
||||
/// <param name="line_height"></param>
|
||||
/// <returns>In same unit as line height</returns>
|
||||
double get_align_y_offset(FontProp::VerticalAlign align, unsigned count_lines, double line_height);
|
||||
|
||||
/// <summary>
|
||||
/// Project spatial point
|
||||
/// </summary>
|
||||
|
@ -264,26 +264,7 @@ namespace {
|
||||
// for existing volume which is selected(could init different(to volume text) lines count when edit text)
|
||||
void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /* const*/ StyleManager &style_manager, unsigned count_lines=0);
|
||||
// before text volume is created
|
||||
void init_new_text_line(TextLinesModel &text_lines, const Transform3d& new_text_tr, const ModelObject& mo, /* const*/ StyleManager &style_manager)
|
||||
{
|
||||
// prepare volumes to slice
|
||||
ModelVolumePtrs volumes;
|
||||
volumes.reserve(mo.volumes.size());
|
||||
for (ModelVolume *volume : mo.volumes) {
|
||||
// only part could be surface for volumes
|
||||
if (!volume->is_model_part())
|
||||
continue;
|
||||
volumes.push_back(volume);
|
||||
}
|
||||
|
||||
double line_height = style_manager.get_line_height();
|
||||
if (line_height < 0)
|
||||
return;
|
||||
|
||||
FontProp::Align align = style_manager.get_font_prop().align;
|
||||
unsigned count_lines = 1;
|
||||
text_lines.init(new_text_tr, volumes, align, line_height, count_lines);
|
||||
}
|
||||
void init_new_text_line(TextLinesModel &text_lines, const Transform3d& new_text_tr, const ModelObject& mo, /* const*/ StyleManager &style_manager);
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mouse_pos)
|
||||
@ -1098,12 +1079,42 @@ EmbossStyles GLGizmoEmboss::create_default_styles()
|
||||
}
|
||||
|
||||
namespace {
|
||||
void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /* const*/ StyleManager &style_manager, unsigned count_lines)
|
||||
|
||||
bool get_line_height_offset(/* const*/ StyleManager &style_manager, double &line_height_mm, double &line_offset_mm)
|
||||
{
|
||||
double line_height = style_manager.get_line_height();
|
||||
if (line_height < 0)
|
||||
return;
|
||||
|
||||
assert(style_manager.is_active_font());
|
||||
if (!style_manager.is_active_font())
|
||||
return false;
|
||||
const auto &ffc = style_manager.get_font_file_with_cache();
|
||||
assert(ffc.has_value());
|
||||
if (!ffc.has_value())
|
||||
return false;
|
||||
const auto &ff_ptr = ffc.font_file;
|
||||
assert(ff_ptr != nullptr);
|
||||
if (ff_ptr == nullptr)
|
||||
return false;
|
||||
const FontProp &fp = style_manager.get_font_prop();
|
||||
const FontFile &ff = *ff_ptr;
|
||||
|
||||
double half_ascent_shape_size = ff.infos[fp.collection_number.value_or(0)].ascent / 2.;
|
||||
int line_height_shape_size = get_line_height(ff, fp); // In shape size
|
||||
|
||||
double scale = get_shape_scale(fp, ff);
|
||||
line_offset_mm = half_ascent_shape_size * scale / SHAPE_SCALE;
|
||||
line_height_mm = line_height_shape_size * scale;
|
||||
|
||||
if (line_height_mm < 0)
|
||||
return false;
|
||||
|
||||
// fix for bad filled ascent in font file
|
||||
if (line_offset_mm <= 0)
|
||||
line_offset_mm = line_height_mm / 3;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /* const*/ StyleManager &style_manager, unsigned count_lines)
|
||||
{
|
||||
const GLVolume *gl_volume_ptr = selection.get_first_volume();
|
||||
if (gl_volume_ptr == nullptr)
|
||||
return;
|
||||
@ -1149,10 +1160,35 @@ void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /*
|
||||
}
|
||||
|
||||
// For interactivity during drag over surface it must be from gl_volume not volume.
|
||||
const Transform3d &mv_trafo = gl_volume.get_volume_transformation().get_matrix();
|
||||
const FontProp &fp = style_manager.get_font_prop();
|
||||
text_lines.init(mv_trafo, volumes, fp.align, line_height, count_lines);
|
||||
const Transform3d &mv_trafo = gl_volume.get_volume_transformation().get_matrix();
|
||||
FontProp::VerticalAlign align = style_manager.get_font_prop().align.second;
|
||||
double line_height_mm, line_offset_mm;
|
||||
if (!get_line_height_offset(style_manager, line_height_mm, line_offset_mm))
|
||||
return;
|
||||
|
||||
text_lines.init(mv_trafo, volumes, align, line_height_mm, line_offset_mm, count_lines);
|
||||
}
|
||||
|
||||
void init_new_text_line(TextLinesModel &text_lines, const Transform3d& new_text_tr, const ModelObject& mo, /* const*/ StyleManager &style_manager)
|
||||
{
|
||||
// prepare volumes to slice
|
||||
ModelVolumePtrs volumes;
|
||||
volumes.reserve(mo.volumes.size());
|
||||
for (ModelVolume *volume : mo.volumes) {
|
||||
// only part could be surface for volumes
|
||||
if (!volume->is_model_part())
|
||||
continue;
|
||||
volumes.push_back(volume);
|
||||
}
|
||||
|
||||
FontProp::VerticalAlign align = style_manager.get_font_prop().align.second;
|
||||
double line_height_mm, line_offset_mm;
|
||||
if (!get_line_height_offset(style_manager, line_height_mm, line_offset_mm))
|
||||
return;
|
||||
unsigned count_lines = 1;
|
||||
text_lines.init(new_text_tr, volumes, align, line_height_mm, line_offset_mm, count_lines);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::reinit_text_lines(unsigned count_lines) {
|
||||
@ -1617,6 +1653,8 @@ void GLGizmoEmboss::draw_text_input()
|
||||
append_warning(_u8L("Too tall, diminished font height inside text input."));
|
||||
if (imgui_size < StyleManager::min_imgui_font_size)
|
||||
append_warning(_u8L("Too small, enlarged font height inside text input."));
|
||||
if (prop.align.first == FontProp::HorizontalAlign::center || prop.align.first == FontProp::HorizontalAlign::right)
|
||||
append_warning(_u8L("Text doesn't show current horizontal alignment."));
|
||||
}
|
||||
|
||||
// flag for extend font ranges if neccessary
|
||||
|
@ -251,12 +251,17 @@ GLModel::Geometry create_geometry(const TextLines &lines)
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void TextLinesModel::init(const Transform3d &text_tr, const ModelVolumePtrs &volumes_to_slice, FontProp::Align align, double line_height, unsigned count_lines)
|
||||
void TextLinesModel::init(const Transform3d &text_tr,
|
||||
const ModelVolumePtrs &volumes_to_slice,
|
||||
FontProp::VerticalAlign align,
|
||||
double line_height,
|
||||
double offset,
|
||||
unsigned count_lines)
|
||||
{
|
||||
m_model.reset();
|
||||
m_lines.clear();
|
||||
|
||||
double first_line_center = offset + (count_lines / 2) * line_height - ((count_lines % 2 == 0) ? line_height / 2. : 0.);
|
||||
double first_line_center = offset + this->offset + get_align_y_offset(align, count_lines, line_height);
|
||||
std::vector<float> line_centers(count_lines);
|
||||
for (size_t i = 0; i < count_lines; ++i)
|
||||
line_centers[i] = static_cast<float>(first_line_center - i * line_height);
|
||||
|
@ -26,8 +26,9 @@ public:
|
||||
/// <param name="volumes_to_slice">Vector of volumes to be sliced</param>
|
||||
/// <param name="align">Vertical (Y) align of the text</param>
|
||||
/// <param name="line_height">Distance between lines [in mm]</param>
|
||||
/// <param name="line_height">Offset from baseline [in mm]</param>
|
||||
/// <param name="count_lines">Count lines(slices over volumes)</param>
|
||||
void init(const Transform3d &text_tr, const ModelVolumePtrs& volumes_to_slice, FontProp::Align align, double line_height, unsigned count_lines);
|
||||
void init(const Transform3d &text_tr, const ModelVolumePtrs& volumes_to_slice, FontProp::VerticalAlign align, double line_height, double offset, unsigned count_lines);
|
||||
|
||||
void render(const Transform3d &text_world);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user