mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-21 07:41:09 -06:00
ENH: font preview
Change-Id: I8151036cedcba9c57183414a9d134741bb2166a5 Signed-off-by: Stone Li <stone.li@bambulab.com>
This commit is contained in:
parent
4ee5dbb07f
commit
110d81f6f7
9 changed files with 372 additions and 26 deletions
|
@ -1881,6 +1881,8 @@ void GLCanvas3D::render(bool only_init)
|
|||
_render_overlays();
|
||||
|
||||
if (wxGetApp().plater()->is_render_statistic_dialog_visible()) {
|
||||
ImGui::ShowMetricsWindow();
|
||||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
imgui.begin(std::string("Render statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||
imgui.text("FPS (SwapBuffers() calls per second):");
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include <wx/dcgraph.h>
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
@ -468,7 +469,13 @@ void GLTexture::reset()
|
|||
m_original_width = m_original_height = 0;
|
||||
}
|
||||
|
||||
bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &font, wxColor background, wxColor foreground)
|
||||
bool GLTexture::generate_from_text_string(const std::string& text_str, wxFont &font, wxColor background, wxColor foreground)
|
||||
{
|
||||
int w,h,hl;
|
||||
return generate_from_text(text_str, font, background, foreground);
|
||||
}
|
||||
|
||||
bool GLTexture::generate_from_text(const std::string &text_str, wxFont &font, wxColor background, wxColor foreground)
|
||||
{
|
||||
if (text_str.empty())
|
||||
{
|
||||
|
@ -488,7 +495,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
m_original_width = (int)w;
|
||||
m_original_height = (int)h;
|
||||
m_width = (int)next_highest_power_of_2((uint32_t)w);
|
||||
m_height = (int)next_highest_power_of_2((uint32_t)h);
|
||||
m_height = (int)next_highest_power_of_2((uint32_t)h);
|
||||
|
||||
// generates bitmap
|
||||
wxBitmap bitmap(m_width, m_height);
|
||||
|
@ -499,7 +506,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
|
||||
// draw message
|
||||
memDC.SetTextForeground(*wxWHITE);
|
||||
memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER);
|
||||
memDC.DrawLabel(msg, wxRect(0, 0, m_original_width, m_original_height), wxALIGN_CENTER);
|
||||
|
||||
memDC.SelectObject(wxNullBitmap);
|
||||
|
||||
|
@ -508,7 +515,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
|
||||
// prepare buffer
|
||||
std::vector<unsigned char> data(4 * m_width * m_height, 0);
|
||||
const unsigned char *src = image.GetData();
|
||||
const unsigned char* src = image.GetData();
|
||||
/* for debug use
|
||||
std::ofstream fout;
|
||||
fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out);
|
||||
|
@ -520,7 +527,7 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
*dst++ = foreground.Red();
|
||||
*dst++ = foreground.Green();
|
||||
*dst++ = foreground.Blue();
|
||||
*dst++ = (unsigned char)std::min<int>(255, *src);
|
||||
*dst++ = (unsigned char)std::min<int>(255, *src);
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
|
@ -530,9 +537,9 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
glsafe(::glGenTextures(1, &m_id));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
|
||||
if (GLEW_EXT_texture_compression_s3tc)
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
else
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
|
@ -541,6 +548,111 @@ bool GLTexture::generate_from_text_string(const std::string &text_str, wxFont &f
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GLTexture::generate_texture_from_text(const std::string& text_str, wxFont& font, int& ww, int& hh, int& hl, wxColor background, wxColor foreground)
|
||||
{
|
||||
if (text_str.empty())
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":no text string, should not happen\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString msg = _(text_str);
|
||||
wxMemoryDC memDC;
|
||||
|
||||
memDC.SetFont(font);
|
||||
|
||||
// calculates texture size
|
||||
wxCoord w, h, ll;
|
||||
wxClientDC dc(wxGetApp().GetTopWindow());
|
||||
dc.SetFont(font);
|
||||
dc.GetMultiLineTextExtent(msg, &w, &h, &ll, &font);
|
||||
|
||||
|
||||
m_original_width = (int)w;
|
||||
m_original_height = (int)h;
|
||||
m_width = (int)next_highest_power_of_2((uint32_t)w);
|
||||
m_height = (int)next_highest_power_of_2((uint32_t)h);
|
||||
ww = m_width;
|
||||
hh = m_height;
|
||||
hl = ll;
|
||||
// generates bitmap
|
||||
wxBitmap bitmap(m_width, m_height);
|
||||
|
||||
memDC.SelectObject(bitmap);
|
||||
memDC.SetBackground(wxBrush(background));
|
||||
memDC.Clear();
|
||||
|
||||
// draw message
|
||||
memDC.SetTextForeground(*wxWHITE);
|
||||
|
||||
wxGCDC dc2(memDC);
|
||||
dc2.SetFont(font);
|
||||
dc2.SetBackground(wxBrush(background));
|
||||
dc2.SetTextForeground(*wxWHITE);
|
||||
dc2.DrawLabel(msg, wxRect(0, 0, m_width, m_height), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
memDC.SelectObject(wxNullBitmap);
|
||||
|
||||
// Convert the bitmap into a linear data ready to be loaded into the GPU.
|
||||
wxImage image = bitmap.ConvertToImage();
|
||||
|
||||
// prepare buffer
|
||||
std::vector<unsigned char> data(4 * m_width * m_height, 0);
|
||||
const unsigned char* src = image.GetData();
|
||||
/* for debug use
|
||||
std::ofstream fout;
|
||||
fout.open(text_str+std::to_string(m_width)+"_"+std::to_string(m_height)+".rgb", std::ios::out);
|
||||
fout.write((const char*)src, 3 * m_width * m_height);
|
||||
fout.close();*/
|
||||
bool found = false;
|
||||
for (int h = 0; h < m_height; ++h) {
|
||||
unsigned char* dst = data.data() + 4 * h * m_width;
|
||||
for (int w = 0; w < m_width; ++w) {
|
||||
*dst++ = foreground.Red();
|
||||
*dst++ = foreground.Green();
|
||||
*dst++ = foreground.Blue();
|
||||
*dst++ = (unsigned char)std::min<int>(255, *src);
|
||||
if ((*src) != background.Red() && !found) {
|
||||
found = true;
|
||||
if (m_height - h < font.GetPointSize())
|
||||
return false;
|
||||
}
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
found = false;
|
||||
src -= 3;
|
||||
for (int h = m_height; h > 0; --h) {
|
||||
for (int w = m_width; w > 0; --w) {
|
||||
if ((*src) != background.Red() && !found) {
|
||||
found = true;
|
||||
if (h < font.GetPointSize())
|
||||
return false;
|
||||
}
|
||||
src -= 3;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
// sends buffer to gpu
|
||||
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
glsafe(::glGenTextures(1, &m_id));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id));
|
||||
if (GLEW_EXT_texture_compression_s3tc)
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
else
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top)
|
||||
{
|
||||
|
|
|
@ -106,7 +106,10 @@ namespace GUI {
|
|||
//BBS: add generate logic for text strings
|
||||
int m_original_width;
|
||||
int m_original_height;
|
||||
bool generate_from_text_string(const std::string &text_str, wxFont &font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
|
||||
bool generate_texture_from_text(const std::string& text_str, wxFont& font, int& ww, int& hh, int &hl, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
bool generate_from_text(const std::string& text_str, wxFont& font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
bool generate_from_text_string(const std::string& text_str, wxFont& font, wxColor background = *wxBLACK, wxColor foreground = *wxWHITE);
|
||||
|
||||
unsigned int get_id() const { return m_id; }
|
||||
int get_width() const { return m_width; }
|
||||
|
|
|
@ -185,7 +185,7 @@ public:
|
|||
void render() { m_tooltip.clear(); on_render(); }
|
||||
void render_for_picking() { on_render_for_picking(); }
|
||||
void render_input_window(float x, float y, float bottom_limit);
|
||||
void on_change_color_mode(bool is_dark) { m_is_dark_mode = is_dark; }
|
||||
virtual void on_change_color_mode(bool is_dark) { m_is_dark_mode = is_dark; }
|
||||
|
||||
virtual std::string get_tooltip() const { return ""; }
|
||||
|
||||
|
|
|
@ -23,20 +23,66 @@
|
|||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
static double g_normal_precise = 0.0015;
|
||||
static const wxColour FONT_TEXTURE_BG = wxColour(0, 0, 0, 0);
|
||||
static const wxColour FONT_TEXTURE_FG = *wxWHITE;
|
||||
static const int FONT_SIZE = 12;
|
||||
|
||||
|
||||
GLGizmoText::GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||
{
|
||||
}
|
||||
|
||||
GLGizmoText::~GLGizmoText()
|
||||
{
|
||||
for (int i = 0; i < m_textures.size(); i++) {
|
||||
if (m_textures[i].texture != nullptr)
|
||||
delete m_textures[i].texture;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLGizmoText::on_init()
|
||||
{
|
||||
m_avail_font_names = init_occt_fonts();
|
||||
update_font_texture();
|
||||
m_scale = m_imgui->get_font_size();
|
||||
m_shortcut_key = WXK_CONTROL_T;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLGizmoText::update_font_texture()
|
||||
{
|
||||
for (int i = 0; i < m_textures.size(); i++) {
|
||||
if (m_textures[i].texture != nullptr)
|
||||
delete m_textures[i].texture;
|
||||
}
|
||||
m_combo_width = 0.0f;
|
||||
m_combo_height = 0.0f;
|
||||
m_textures.clear();
|
||||
m_textures.reserve(m_avail_font_names.size());
|
||||
for (int i = 0; i < m_avail_font_names.size(); i++)
|
||||
{
|
||||
GLTexture* texture = new GLTexture();
|
||||
auto face = wxString::FromUTF8(m_avail_font_names[i]);
|
||||
auto retina_scale = m_parent.get_scale();
|
||||
wxFont font { (int)round(retina_scale * FONT_SIZE), wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, face };
|
||||
int w, h, hl;
|
||||
if (texture->generate_texture_from_text(m_avail_font_names[i], font, w, h, hl, FONT_TEXTURE_BG, FONT_TEXTURE_FG)) {
|
||||
//if (h < m_imgui->scaled(2.f)) {
|
||||
TextureInfo info;
|
||||
info.texture = texture;
|
||||
info.w = w;
|
||||
info.h = h;
|
||||
info.hl = hl;
|
||||
info.font_name = m_avail_font_names[i];
|
||||
m_textures.push_back(info);
|
||||
m_combo_width = std::max(m_combo_width, static_cast<float>(texture->m_original_width));
|
||||
//}
|
||||
}
|
||||
}
|
||||
m_combo_height = m_imgui->scaled(32.f / 15.f);
|
||||
}
|
||||
|
||||
void GLGizmoText::on_set_state()
|
||||
{
|
||||
}
|
||||
|
@ -114,6 +160,8 @@ void GLGizmoText::push_combo_style(const float scale) {
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImGuiWrapper::COL_WINDOW_BG_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImGuiWrapper::COL_WINDOW_BG_DARK);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
|
||||
}
|
||||
else {
|
||||
|
@ -125,6 +173,8 @@ void GLGizmoText::push_combo_style(const float scale) {
|
|||
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarBg, ImGuiWrapper::COL_WINDOW_BG);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive, ImGuiWrapper::COL_WINDOW_BG);
|
||||
ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered, ImGuiWrapper::COL_WINDOW_BG);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { 1.00f, 1.00f, 1.00f, 0.0f });
|
||||
}
|
||||
}
|
||||
|
@ -132,12 +182,21 @@ void GLGizmoText::push_combo_style(const float scale) {
|
|||
void GLGizmoText::pop_combo_style()
|
||||
{
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(7);
|
||||
ImGui::PopStyleColor(9);
|
||||
}
|
||||
|
||||
// BBS
|
||||
void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
|
||||
{
|
||||
if (m_imgui->get_font_size() != m_scale) {
|
||||
m_scale = m_imgui->get_font_size();
|
||||
update_font_texture();
|
||||
}
|
||||
if (m_textures.size() == 0) {
|
||||
BOOST_LOG_TRIVIAL(info) << "GLGizmoText has no texture";
|
||||
return;
|
||||
}
|
||||
|
||||
const float win_h = ImGui::GetWindowHeight();
|
||||
y = std::min(y, bottom_limit - win_h);
|
||||
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
|
@ -178,35 +237,31 @@ void GLGizmoText::on_render_input_window(float x, float y, float bottom_limit)
|
|||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
const char** cstr_font_names = (const char**)calloc(m_avail_font_names.size(), sizeof(const char*));
|
||||
for (int i = 0; i < m_avail_font_names.size(); i++)
|
||||
cstr_font_names[i] = m_avail_font_names[i].c_str();
|
||||
|
||||
m_imgui->text(_L("Font"));
|
||||
ImGui::SameLine(caption_size);
|
||||
ImGui::PushItemWidth(input_text_size + ImGui::GetFrameHeight() * 2);
|
||||
push_combo_style(currt_scale);
|
||||
int font_index = m_curr_font_idx;
|
||||
m_imgui->push_font_by_name(cstr_font_names[font_index]);
|
||||
if (ImGui::BBLBeginCombo("##Font", cstr_font_names[m_curr_font_idx], 0)) {
|
||||
if (ImGui::BBLBeginCombo("##Font", m_textures[m_curr_font_idx].font_name.c_str(), 0)) {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(4.0f, 0.0f) * currt_scale);
|
||||
for (int i = 0; i < m_avail_font_names.size(); i++) {
|
||||
m_imgui->push_font_by_name(m_avail_font_names[i]);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 4));
|
||||
for (int i = 0; i < m_textures.size(); i++) {
|
||||
const bool is_selected = (m_curr_font_idx == i);
|
||||
if (ImGui::BBLSelectable((cstr_font_names[i] + std::string("##") + std::to_string(i)).c_str(), is_selected, 0, {input_text_size + ImGui::GetFrameHeight() * 2 , 0.0f})) {
|
||||
ImTextureID icon_id = (ImTextureID)(intptr_t)(m_textures[i].texture->get_id());
|
||||
ImVec4 tint_color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
|
||||
ImVec2 selectable_size(std::max((input_text_size + ImGui::GetFrameHeight() * 2), m_combo_width), m_combo_height);
|
||||
if (ImGui::BBLImageSelectable(icon_id, selectable_size, { (float)m_textures[i].w, (float)m_textures[i].h }, m_textures[i].hl, tint_color, { 0, 0 }, {1, 1}, is_selected)) {
|
||||
m_curr_font_idx = i;
|
||||
m_font_name = cstr_font_names[m_curr_font_idx];
|
||||
m_font_name = m_textures[m_curr_font_idx].font_name;
|
||||
}
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
m_imgui->pop_font_by_name(m_avail_font_names[i]);
|
||||
}
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
m_imgui->pop_font_by_name(cstr_font_names[font_index]);
|
||||
|
||||
pop_combo_style();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "slic3r/GUI/3DScene.hpp"
|
||||
|
||||
#include "../GLTexture.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -22,9 +22,27 @@ private:
|
|||
bool m_bold = true;
|
||||
bool m_italic = false;
|
||||
float m_thickness = 2.f;
|
||||
float m_combo_height = 0.0f;
|
||||
float m_combo_width = 0.0f;
|
||||
float m_scale;
|
||||
|
||||
class TextureInfo {
|
||||
public:
|
||||
GLTexture* texture { nullptr };
|
||||
int h;
|
||||
int w;
|
||||
int hl;
|
||||
|
||||
std::string font_name;
|
||||
};
|
||||
|
||||
std::vector<TextureInfo> m_textures;
|
||||
|
||||
public:
|
||||
GLGizmoText(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
|
||||
~GLGizmoText();
|
||||
|
||||
void update_font_texture();
|
||||
|
||||
protected:
|
||||
virtual bool on_init() override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue