Merge branch 'main' into feature/texture_displacement

This commit is contained in:
SoftFever
2026-08-30 13:52:54 +08:00
312 changed files with 50957 additions and 4326 deletions
+56 -12
View File
@@ -2404,6 +2404,25 @@ void ImGuiWrapper::draw(
}
}
void ImGuiWrapper::draw_gradient_ramp(ImDrawList *draw_list, const ImVec2 &top_left, const ImVec2 &bottom_right, const std::vector<wxColour> &ramp)
{
if (draw_list == nullptr || ramp.empty() || bottom_right.x <= top_left.x || bottom_right.y <= top_left.y)
return;
const int rows = std::max(1, (int) std::lround(bottom_right.y - top_left.y));
const float row_h = (bottom_right.y - top_left.y) / rows;
const size_t last = ramp.size() - 1;
for (int r = 0; r < rows; ++r) {
// Row 0 is the top of the rect and so takes the ramp's last entry, the model's top.
const double t = (rows > 1) ? (double) (rows - 1 - r) / (rows - 1) : 0.5;
const wxColour &c = ramp[(size_t) (t * last + 0.5)];
// The bottom row snaps to the rect's edge so rounding never leaves a sliver uncovered.
const float y0 = top_left.y + r * row_h;
const float y1 = (r + 1 == rows) ? bottom_right.y : top_left.y + (r + 1) * row_h;
draw_list->AddRectFilled({top_left.x, y0}, {bottom_right.x, y1}, IM_COL32(c.Red(), c.Green(), c.Blue(), c.Alpha()));
}
}
void ImGuiWrapper::draw_cross_hair(const ImVec2 &position, float radius, ImU32 color, int num_segments, float thickness) {
auto draw_list = ImGui::GetOverlayDrawList();
draw_list->AddCircle(position, radius, color, num_segments, thickness);
@@ -2463,6 +2482,19 @@ static const ImWchar ranges_keyboard_shortcuts[] =
};
#endif // __APPLE__
// Names drawn through the atlas come from file names and CAD data, not from the UI language.
// GetGlyphRangesDefault() already gives every language the CJK ideographs, which is why a
// Chinese file name renders under an English UI; these are the alphabetic scripts it omits.
// Codepoints the font lacks are skipped at build time, so only existing glyphs cost anything.
static const ImWchar ranges_language_independent[] =
{
0x0100, 0x024F, // Latin Extended-A and Extended-B
0x0370, 0x03FF, // Greek and Coptic
0x0400, 0x04FF, // Cyrillic
0x1E00, 0x1EFF, // Latin Extended Additional (Vietnamese)
0,
};
std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight)
{
@@ -2777,6 +2809,7 @@ void ImGuiWrapper::init_font(bool compress)
ImFontAtlas::GlyphRangesBuilder builder;
builder.AddRanges(m_glyph_ranges);
builder.AddRanges(ImGui::GetIO().Fonts->GetGlyphRangesDefault());
builder.AddRanges(ranges_language_independent);
#ifdef __APPLE__
if (m_font_cjk)
// Apple keyboard shortcuts are only contained in the CJK fonts.
@@ -2798,12 +2831,17 @@ void ImGuiWrapper::init_font(bool compress)
// Orca: temp fix for Korean font
auto font_name_regular = "HarmonyOS_Sans_SC_Regular.ttf";
auto font_name_bold = "HarmonyOS_Sans_SC_Bold.ttf";
// The Korean and Thai fonts cover their own script and little else, so they need the
// default font merged in behind them to reach the full range.
bool needs_glyph_fallback = false;
if(m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesKorean()) {
font_name_regular = "NanumGothic-Regular.ttf";
font_name_bold = "NanumGothic-Bold.ttf";
needs_glyph_fallback = true;
} else if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) {
font_name_regular = "Sarabun-Medium.ttf";
font_name_bold = "Sarabun-SemiBold.ttf";
needs_glyph_fallback = true;
}
default_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + font_name_regular).c_str(), m_font_size, &cfg, ranges.Data);
if (default_font == nullptr) {
@@ -2813,11 +2851,12 @@ void ImGuiWrapper::init_font(bool compress)
}
}
if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) {
// A merged font only supplies glyphs the font ahead of it lacks, so this fills the gaps
// without restyling anything the script font already covers.
if (needs_glyph_fallback) {
ImFontConfig fallback_cfg = cfg;
fallback_cfg.MergeMode = true;
static constexpr ImWchar celsius_range[] = { 0x2103, 0x2103, 0 };
io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Regular.ttf").c_str(), m_font_size, &fallback_cfg, celsius_range);
io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Regular.ttf").c_str(), m_font_size, &fallback_cfg, ranges.Data);
}
bold_font = io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/" + font_name_bold).c_str(), m_font_size, &cfg, ranges.Data);
@@ -2826,11 +2865,10 @@ void ImGuiWrapper::init_font(bool compress)
if (bold_font == nullptr) { throw Slic3r::RuntimeError("ImGui: Could not load deafult font"); }
}
if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) {
if (needs_glyph_fallback) {
ImFontConfig fallback_cfg = cfg;
fallback_cfg.MergeMode = true;
static constexpr ImWchar celsius_range[] = { 0x2103, 0x2103, 0 };
io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Bold.ttf").c_str(), m_font_size, &fallback_cfg, celsius_range);
io.Fonts->AddFontFromFileTTF((Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Bold.ttf").c_str(), m_font_size, &fallback_cfg, ranges.Data);
}
if (m_glyph_ranges == ImGui::GetIO().Fonts->GetGlyphRangesThai()) {
@@ -2882,13 +2920,18 @@ void ImGuiWrapper::init_font(bool compress)
glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_tex_size));
constexpr int max_retries = 6;
for (int attempt = 0; attempt < max_retries && io.Fonts->TexHeight > gl_max_tex_size; ++attempt) {
io.Fonts->TexDesiredWidth = (io.Fonts->TexDesiredWidth > 0 ? io.Fonts->TexDesiredWidth : io.Fonts->TexWidth) * 2;
const int width = io.Fonts->TexDesiredWidth > 0 ? io.Fonts->TexDesiredWidth : io.Fonts->TexWidth;
// Both dimensions share the same limit, so widening past it would only trade an
// illegal height for an illegal width.
if (width * 2 > gl_max_tex_size)
break;
io.Fonts->TexDesiredWidth = width * 2;
io.Fonts->Build();
}
if (io.Fonts->TexHeight > gl_max_tex_size) {
// Shouldn't really happen
BOOST_LOG_TRIVIAL(error) << "Font atlas height " << io.Fonts->TexHeight
<< " still exceeds GL_MAX_TEXTURE_SIZE (" << gl_max_tex_size << ")"
// Needs both a very large glyph set and a small GL_MAX_TEXTURE_SIZE.
BOOST_LOG_TRIVIAL(error) << "Font atlas " << io.Fonts->TexWidth << "x" << io.Fonts->TexHeight
<< " does not fit GL_MAX_TEXTURE_SIZE (" << gl_max_tex_size << ")"
<< " after " << max_retries << " attempts; rendering may be incomplete";
}
@@ -3336,8 +3379,9 @@ const char* ImGuiWrapper::clipboard_get(void* user_data)
wxTextDataObject data;
wxTheClipboard->GetData(data);
if (data.GetTextLength() > 0) {
self->m_clipboard_text = into_u8(data.GetText());
const wxString text = data.GetText();
if (text.Length() > 0) {
self->m_clipboard_text = into_u8(text);
res = self->m_clipboard_text.c_str();
}
}