@@ -1351,15 +1351,6 @@ std::unique_ptr<Emboss::DataBase> GLGizmoText::create_emboss_data_base(
13511351 assert (style_manager.get_wx_font ().IsOk ());
13521352 assert (style.path .compare (WxFontUtils::store_wxFont (style_manager.get_wx_font ())) == 0 );
13531353
1354- // Multiline placement uses the Emboss 2D layout, so character spacing must live in FontProp.
1355- // Single-line text still applies m_text_gap in GenerateTextJob::calc_position_points.
1356- if (get_count_lines (text) > 1 ) {
1357- if (std::abs (m_text_gap) > 1e-4f )
1358- style.prop .char_gap = static_cast <int >(std::lround (m_text_gap));
1359- else
1360- style.prop .char_gap .reset ();
1361- }
1362-
13631354 bool is_outside = (type == ModelVolumeType::MODEL_PART );
13641355
13651356 // Cancel previous Job, when it is in process
@@ -1378,7 +1369,28 @@ std::unique_ptr<Emboss::DataBase> GLGizmoText::create_emboss_data_base(
13781369 base.from_surface = style.distance ;
13791370
13801371 FontFileWithCache &font = style_manager.get_font_file_with_cache ();
1381- TextConfiguration tc{static_cast <EmbossStyle>(style), text};
1372+
1373+ // Apply auto-wrap / shrink into the shape string; keep UI m_text as the editable source.
1374+ std::string shape_text = text;
1375+ if ((m_wrap_text || m_auto_shrink) && font.has_value ()) {
1376+ FontProp fit_prop = style.prop ;
1377+ fit_prop.size_in_mm = m_font_size;
1378+ shape_text = fit_text_to_box (font, fit_prop, text, m_wrap_width_mm, m_wrap_height_mm, m_wrap_text, m_auto_shrink);
1379+ style.prop .size_in_mm = fit_prop.size_in_mm ;
1380+ m_font_size = fit_prop.size_in_mm ;
1381+ m_style_manager.get_font_prop ().size_in_mm = fit_prop.size_in_mm ;
1382+ }
1383+
1384+ // Multiline placement uses the Emboss 2D layout, so character spacing must live in FontProp.
1385+ // Single-line text still applies m_text_gap in GenerateTextJob::calc_position_points.
1386+ if (get_count_lines (shape_text) > 1 ) {
1387+ if (std::abs (m_text_gap) > 1e-4f )
1388+ style.prop .char_gap = static_cast <int >(std::lround (m_text_gap));
1389+ else
1390+ style.prop .char_gap .reset ();
1391+ }
1392+
1393+ TextConfiguration tc{static_cast <EmbossStyle>(style), shape_text};
13821394 auto td_ptr = std::make_unique<TextDataBase>(std::move (base), font, std::move (tc), style.projection );
13831395 return td_ptr;
13841396}
@@ -2366,6 +2378,38 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
23662378
23672379
23682380
2381+ ImGui::AlignTextToFramePadding ();
2382+ bool wrap_changed = ImGui::Checkbox ((_L (" Auto wrap" )).c_str (), &m_wrap_text);
2383+ ImGui::SameLine ();
2384+ bool shrink_changed = ImGui::Checkbox ((_L (" Auto shrink" )).c_str (), &m_auto_shrink);
2385+ if (wrap_changed || shrink_changed)
2386+ m_need_update_text = true ;
2387+ if (m_wrap_text || m_auto_shrink) {
2388+ ImGui::AlignTextToFramePadding ();
2389+ m_imgui->text (_L (" Wrap width" ));
2390+ ImGui::SameLine (caption_size);
2391+ ImGui::PushItemWidth (temp_input_width);
2392+ float old_wrap_w = m_wrap_width_mm;
2393+ if (ImGui::InputFloat (" ###text_wrap_width" , &m_wrap_width_mm, 0 .0f , 0 .0f , " %.2f" )) {
2394+ m_wrap_width_mm = ImClamp (m_wrap_width_mm, 1 .f , 1000 .f );
2395+ if (old_wrap_w != m_wrap_width_mm)
2396+ m_need_update_text = true ;
2397+ }
2398+ ImGui::SameLine ();
2399+ m_imgui->text (_L (" Wrap height" ));
2400+ ImGui::SameLine ();
2401+ ImGui::PushItemWidth (temp_input_width);
2402+ float old_wrap_h = m_wrap_height_mm;
2403+ if (ImGui::InputFloat (" ###text_wrap_height" , &m_wrap_height_mm, 0 .0f , 0 .0f , " %.2f" )) {
2404+ m_wrap_height_mm = ImClamp (m_wrap_height_mm, 0 .f , 1000 .f );
2405+ if (old_wrap_h != m_wrap_height_mm)
2406+ m_need_update_text = true ;
2407+ }
2408+ if (ImGui::IsItemHovered ())
2409+ m_imgui->tooltip (_u8L (" Optional max height in mm. 0 means no height limit. With Auto shrink, font size is reduced to fit the box." ),
2410+ m_gui_cfg->max_tooltip_width );
2411+ }
2412+
23692413 ImGui::AlignTextToFramePadding ();
23702414 m_imgui->text (_L (" Text Gap" ));
23712415 ImGui::SameLine (caption_size);
@@ -3096,6 +3140,10 @@ void GLGizmoText::reset_text_info()
30963140 m_embeded_depth = m_style_manager.get_style ().projection .embeded_depth ;
30973141 m_rotate_angle = get_angle_from_current_style ();
30983142 m_text_gap = m_style_manager.get_style ().prop .char_gap .value_or (0 );
3143+ m_wrap_text = false ;
3144+ m_wrap_width_mm = 40 .f ;
3145+ m_wrap_height_mm = 0 .f ;
3146+ m_auto_shrink = false ;
30993147 m_surface_type = TextInfo::TextType::SURFACE ;
31003148 m_rr = RaycastResult ();
31013149 m_last_text_mv = nullptr ;
@@ -3399,6 +3447,11 @@ bool GLGizmoText::generate_text_volume()
33993447 input_info.m_thickness = m_thickness;
34003448 input_info.m_cut_plane_dir_in_world = m_cut_plane_dir_in_world;
34013449 input_info.use_surface = m_surface_type == TextInfo::TextType::SURFACE_CHAR ? true : false ;
3450+ if (m_style_manager.is_active_font () && m_style_manager.get_font_file_with_cache ().has_value ()) {
3451+ input_info.font_file = m_style_manager.get_font_file_with_cache ().font_file ;
3452+ input_info.font_prop = m_style_manager.get_font_prop ();
3453+ input_info.font_prop .size_in_mm = m_font_size;
3454+ }
34023455 TextInfo text_info = get_text_info ();
34033456
34043457 ModelObject *model_object = selection.get_model ()->objects [m_object_idx];
@@ -3445,6 +3498,10 @@ TextInfo GLGizmoText::get_text_info()
34453498 text_info.m_rr .mesh_id = m_rr.mesh_id ;
34463499 text_info.m_rotate_angle = m_rotate_angle;
34473500 text_info.m_text_gap = m_text_gap;
3501+ text_info.m_wrap_text = m_wrap_text;
3502+ text_info.m_wrap_width_mm = m_wrap_width_mm;
3503+ text_info.m_wrap_height_mm = m_wrap_height_mm;
3504+ text_info.m_auto_shrink = m_auto_shrink;
34483505 text_info.m_surface_type = m_surface_type;
34493506 text_info.text_configuration = m_ui_text_configuration;
34503507 text_info.text_configuration .style .prop .line_gap = m_style_manager.get_font_prop ().line_gap ;
@@ -3472,6 +3529,10 @@ void GLGizmoText::load_from_text_info(const TextInfo &text_info)
34723529 m_rotate_angle = (float ) Geometry::rad2deg (limit_angle);
34733530
34743531 m_text_gap = text_info.m_text_gap ;
3532+ m_wrap_text = text_info.m_wrap_text ;
3533+ m_wrap_width_mm = text_info.m_wrap_width_mm ;
3534+ m_wrap_height_mm = text_info.m_wrap_height_mm ;
3535+ m_auto_shrink = text_info.m_auto_shrink ;
34753536 m_surface_type = (TextInfo::TextType) text_info.m_surface_type ;
34763537
34773538 if (is_old_text_info (text_info)) { // compatible with older versions
0 commit comments