add Enumerate fonts. not Finished

This commit is contained in:
Filip Sykala 2022-01-21 20:19:06 +01:00
parent 770a5c5501
commit d55f09d75b
8 changed files with 121 additions and 31 deletions

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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
};
}

View file

@ -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;

View file

@ -1,6 +1,7 @@
#ifndef slic3r_FontManager_hpp_
#define slic3r_FontManager_hpp_
#include <optional>
#include <imgui/imgui.h>
#include "libslic3r/Emboss.hpp"

View file

@ -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__)

View file

@ -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);