add Enumerate fonts. not Finished
This commit is contained in:
parent
770a5c5501
commit
d55f09d75b
8 changed files with 121 additions and 31 deletions
|
@ -521,6 +521,42 @@ std::unique_ptr<Emboss::FontFile> Emboss::load_font(const char *file_path)
|
|||
|
||||
|
||||
#ifdef _WIN32
|
||||
static bool load_hfont(void* hfont, DWORD &dwTable, DWORD &dwOffset, size_t& size, HDC hdc = nullptr){
|
||||
bool del_hdc = false;
|
||||
if (hdc == nullptr) {
|
||||
del_hdc = true;
|
||||
hdc = ::CreateCompatibleDC(NULL);
|
||||
if (hdc == NULL) return false;
|
||||
}
|
||||
|
||||
// To retrieve the data from the beginning of the file for TrueType
|
||||
// Collection files specify 'ttcf' (0x66637474).
|
||||
dwTable = 0x66637474;
|
||||
dwOffset = 0;
|
||||
|
||||
::SelectObject(hdc, hfont);
|
||||
size = ::GetFontData(hdc, dwTable, dwOffset, NULL, 0);
|
||||
if (size == GDI_ERROR) {
|
||||
// HFONT is NOT TTC(collection)
|
||||
dwTable = 0;
|
||||
size = ::GetFontData(hdc, dwTable, dwOffset, NULL, 0);
|
||||
}
|
||||
|
||||
if (size == 0 || size == GDI_ERROR) {
|
||||
if (del_hdc) ::DeleteDC(hdc);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void * Emboss::can_load(HFONT hfont)
|
||||
{
|
||||
DWORD dwTable=0, dwOffset=0;
|
||||
size_t size = 0;
|
||||
if (!load_hfont(hfont, dwTable, dwOffset, size)) return nullptr;
|
||||
return hfont;
|
||||
}
|
||||
|
||||
std::unique_ptr<Emboss::FontFile> Emboss::load_font(HFONT hfont)
|
||||
{
|
||||
HDC hdc = ::CreateCompatibleDC(NULL);
|
||||
|
@ -529,23 +565,11 @@ std::unique_ptr<Emboss::FontFile> Emboss::load_font(HFONT hfont)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// To retrieve the data from the beginning of the file for TrueType
|
||||
// Collection files specify 'ttcf' (0x66637474).
|
||||
DWORD dwTable = 0x66637474;
|
||||
DWORD dwOffset = 0;
|
||||
|
||||
::SelectObject(hdc, hfont);
|
||||
size_t size = ::GetFontData(hdc, dwTable, dwOffset, NULL, 0);
|
||||
if (size == GDI_ERROR) {
|
||||
// HFONT is NOT TTC(collection)
|
||||
dwTable = 0;
|
||||
size = ::GetFontData(hdc, dwTable, dwOffset, NULL, 0);
|
||||
}
|
||||
|
||||
if (size == 0 || size == GDI_ERROR) {
|
||||
std::cerr << "HFONT doesn't have size." << std::endl;
|
||||
DWORD dwTable=0,dwOffset = 0;
|
||||
size_t size;
|
||||
if (!load_hfont(hfont, dwTable, dwOffset, size, hdc)) {
|
||||
::DeleteDC(hdc);
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<unsigned char> buffer(size);
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
#ifdef _WIN32
|
||||
// fix for unknown pointer HFONT
|
||||
using HFONT = void*;
|
||||
static void * can_load(HFONT hfont);
|
||||
static std::unique_ptr<FontFile> load_font(HFONT hfont);
|
||||
#endif // _WIN32
|
||||
|
||||
|
|
|
@ -688,20 +688,55 @@ void GLGizmoEmboss::draw_text_input()
|
|||
if (exist_change) m_font_manager.get_imgui_font(m_text);
|
||||
}
|
||||
|
||||
#include "wx/fontenum.h"
|
||||
void GLGizmoEmboss::draw_font_list()
|
||||
{
|
||||
if (ImGui::BeginCombo("##font_selector", "Actual selected font")) {
|
||||
std::vector<int> fonts = {1, 3, 5, 8};
|
||||
for (const auto &item : fonts) {
|
||||
size_t index = &item - &fonts.front();
|
||||
class MyFontEnumerator : public wxFontEnumerator
|
||||
{
|
||||
wxArrayString m_facenames;
|
||||
wxFontEncoding m_encoding;
|
||||
bool m_is_init;
|
||||
public:
|
||||
MyFontEnumerator(wxFontEncoding encoding) : m_encoding(encoding), m_is_init(false){}
|
||||
const wxArrayString& get_facenames() const{ return m_facenames; }
|
||||
bool is_init() const { return m_is_init; }
|
||||
bool init() {
|
||||
if (m_is_init) return false;
|
||||
m_is_init = true;
|
||||
bool fixedWidthOnly = false;
|
||||
if (!wxFontEnumerator::EnumerateFacenames(m_encoding, fixedWidthOnly)) return false;
|
||||
if (m_facenames.empty()) return false;
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
virtual bool OnFacename(const wxString& facename) wxOVERRIDE {
|
||||
// vertical font start with @, we will filter it out
|
||||
if (facename.empty() || facename[0] == '@') return true;
|
||||
wxFont wx_font(wxFontInfo().FaceName(facename).Encoding(m_encoding));
|
||||
void *addr = WxFontUtils::can_load(wx_font);
|
||||
if (addr == nullptr) return true; // can't load
|
||||
m_facenames.Add(facename);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM;
|
||||
static MyFontEnumerator fontEnumerator(encoding);
|
||||
std::optional<wxFont> &wx_font_opt = m_font_manager.get_wx_font();
|
||||
wxString actual_face_name = wx_font_opt.has_value() ?
|
||||
wx_font_opt->GetFaceName() : "";
|
||||
const char * selected = (!actual_face_name.empty()) ?
|
||||
actual_face_name.ToUTF8().data() : " --- ";
|
||||
if (ImGui::BeginCombo("##font_selector", selected)) {
|
||||
if(!fontEnumerator.is_init()) fontEnumerator.init();
|
||||
const wxArrayString &face_names = fontEnumerator.get_facenames();
|
||||
ImGui::TextColored(ImGuiWrapper::COL_GREY_LIGHT, "count %d", static_cast<int>(face_names.size()));
|
||||
for (const wxString &face_name : face_names) {
|
||||
size_t index = &face_name - &face_names.front();
|
||||
ImGui::PushID(index);
|
||||
|
||||
bool is_selected = false;
|
||||
ImGuiSelectableFlags_ flags =
|
||||
ImGuiSelectableFlags_AllowItemOverlap; // allow click buttons
|
||||
if (ImGui::Selectable(("font name" + std::to_string(item)).c_str(),
|
||||
is_selected)) {
|
||||
bool is_selected = (actual_face_name == face_name);
|
||||
if (ImGui::Selectable(face_name.ToUTF8().data(), is_selected)) {
|
||||
// Select font
|
||||
wx_font_opt = wxFont(wxFontInfo().FaceName(face_name).Encoding(encoding));
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
@ -1035,6 +1070,7 @@ void GLGizmoEmboss::draw_style_edit() {
|
|||
// store font size into path
|
||||
if (fi.type == WxFontUtils::get_actual_type()) {
|
||||
if (wx_font.has_value()) {
|
||||
// TODO: check difference wx_font->Scale(float x)
|
||||
wx_font->SetPointSize(font_prop.size_in_mm);
|
||||
fi.path = WxFontUtils::store_wxFont(*wx_font);
|
||||
}
|
||||
|
|
|
@ -17,10 +17,15 @@ const std::string FontListSerializable::APP_CONFIG_FONT_LINE_GAP = "line_gap"
|
|||
|
||||
FontList FontListSerializable::create_default_font_list()
|
||||
{
|
||||
// https://docs.wxwidgets.org/3.0/classwx_font.html
|
||||
// Predefined objects/pointers: wxNullFont, wxNORMAL_FONT, wxSMALL_FONT, wxITALIC_FONT, wxSWISS_FONT
|
||||
return {
|
||||
WxFontUtils::get_font_item(wxFont(5, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL))
|
||||
, WxFontUtils::get_font_item(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD))
|
||||
, WxFontUtils::get_os_font()
|
||||
WxFontUtils::get_font_item(*wxNORMAL_FONT), // wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)
|
||||
WxFontUtils::get_font_item(*wxSMALL_FONT), // A font using the wxFONTFAMILY_SWISS family and 2 points smaller than wxNORMAL_FONT.
|
||||
WxFontUtils::get_font_item(*wxITALIC_FONT), // A font using the wxFONTFAMILY_ROMAN family and wxFONTSTYLE_ITALIC style and of the same size of wxNORMAL_FONT.
|
||||
WxFontUtils::get_font_item(*wxSWISS_FONT), // A font identic to wxNORMAL_FONT except for the family used which is wxFONTFAMILY_SWISS.
|
||||
WxFontUtils::get_font_item(wxFont(10, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD))
|
||||
//, WxFontUtils::get_os_font() == wxNORMAL_FONT
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ void FontManager::free_imgui_fonts()
|
|||
|
||||
bool FontManager::load_font(const wxFont &font)
|
||||
{
|
||||
auto font_ptr = WxFontUtils::load_font(font);
|
||||
std::unique_ptr<Emboss::FontFile> font_ptr = WxFontUtils::load_font(font);
|
||||
if (font_ptr == nullptr) return false;
|
||||
m_font_list[m_font_selected].font_file = std::move(font_ptr);
|
||||
load_imgui_font();
|
||||
|
@ -334,6 +334,8 @@ void FontManager::load_imgui_font(const std::string &text) {
|
|||
|
||||
void FontManager::load_imgui_font(size_t index, const std::string &text)
|
||||
{
|
||||
free_imgui_fonts(); // TODO: remove it after correct initialization
|
||||
|
||||
if (index >= m_font_list.size()) return;
|
||||
Item &item = m_font_list[index];
|
||||
if (item.font_file == nullptr) return;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef slic3r_FontManager_hpp_
|
||||
#define slic3r_FontManager_hpp_
|
||||
|
||||
#include <optional>
|
||||
#include <imgui/imgui.h>
|
||||
#include "libslic3r/Emboss.hpp"
|
||||
|
||||
|
|
|
@ -12,9 +12,26 @@
|
|||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
std::unique_ptr<Emboss::FontFile> WxFontUtils::load_font(const wxFont &font)
|
||||
void *WxFontUtils::can_load(const wxFont &font)
|
||||
{
|
||||
if (!font.IsOk()) return nullptr;
|
||||
#ifdef _WIN32
|
||||
return Emboss::can_load(font.GetHFONT());
|
||||
#elif defined(__APPLE__)
|
||||
// use file path
|
||||
return font.GetNativeFontInfo();
|
||||
#elif defined(__linux__)
|
||||
// TODO: find better way
|
||||
static FontConfigHelp help;
|
||||
std::string font_path = help.get_font_path(font);
|
||||
if (font_path.empty()) return nullptr;
|
||||
return Emboss::load_font(font_path.c_str());
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Emboss::FontFile> WxFontUtils::load_font(const wxFont &font)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return Emboss::load_font(font.GetHFONT());
|
||||
#elif defined(__APPLE__)
|
||||
|
|
|
@ -15,6 +15,10 @@ public:
|
|||
// only static functions
|
||||
WxFontUtils() = delete;
|
||||
|
||||
// check if exist file for wxFont
|
||||
// return pointer on data or nullptr when can't load
|
||||
static void *can_load(const wxFont &font);
|
||||
|
||||
// os specific load of wxFont
|
||||
static std::unique_ptr<Slic3r::Emboss::FontFile> load_font(const wxFont &font);
|
||||
|
||||
|
|
Loading…
Reference in a new issue