From 84488ba6df744ba9268f437205b66b4ef78e3cfa Mon Sep 17 00:00:00 2001 From: Filip Sykala Date: Fri, 3 Sep 2021 12:22:44 +0200 Subject: [PATCH] Enumerate fonts --- src/libslic3r/Emboss.cpp | 160 ++++++++++++++++++++++ src/libslic3r/Emboss.hpp | 17 ++- src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp | 3 +- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 1 + tests/libslic3r/test_meshboolean.cpp | 3 +- 5 files changed, 177 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/Emboss.cpp b/src/libslic3r/Emboss.cpp index 945a57b7b..62abc125c 100644 --- a/src/libslic3r/Emboss.cpp +++ b/src/libslic3r/Emboss.cpp @@ -86,6 +86,166 @@ std::optional Privat::get_glyph(stbtt_fontinfo &font_info, int un return glyph; } + +#ifdef _WIN32 +#include +#include +#include +#include + +// Get system font file path +std::optional Emboss::get_font_path(const std::wstring &font_face_name) +{ + static const LPWSTR fontRegistryPath = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; + HKEY hKey; + LONG result; + + // Open Windows font registry key + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, fontRegistryPath, 0, KEY_READ, &hKey); + if (result != ERROR_SUCCESS) return {}; + + DWORD maxValueNameSize, maxValueDataSize; + result = RegQueryInfoKey(hKey, 0, 0, 0, 0, 0, 0, 0, &maxValueNameSize, &maxValueDataSize, 0, 0); + if (result != ERROR_SUCCESS) return {}; + + DWORD valueIndex = 0; + LPWSTR valueName = new WCHAR[maxValueNameSize]; + LPBYTE valueData = new BYTE[maxValueDataSize]; + DWORD valueNameSize, valueDataSize, valueType; + std::wstring wsFontFile; + + // Look for a matching font name + do { + wsFontFile.clear(); + valueDataSize = maxValueDataSize; + valueNameSize = maxValueNameSize; + + result = RegEnumValue(hKey, valueIndex, valueName, &valueNameSize, 0, &valueType, valueData, &valueDataSize); + + valueIndex++; + if (result != ERROR_SUCCESS || valueType != REG_SZ) { + continue; + } + + std::wstring wsValueName(valueName, valueNameSize); + + // Found a match + if (_wcsnicmp(font_face_name.c_str(), wsValueName.c_str(), font_face_name.length()) == 0) { + + wsFontFile.assign((LPWSTR)valueData, valueDataSize); + break; + } + }while (result != ERROR_NO_MORE_ITEMS); + + delete[] valueName; + delete[] valueData; + + RegCloseKey(hKey); + + if (wsFontFile.empty()) return {}; + + // Build full font file path + WCHAR winDir[MAX_PATH]; + GetWindowsDirectory(winDir, MAX_PATH); + + std::wstringstream ss; + ss << winDir << "\\Fonts\\" << wsFontFile; + wsFontFile = ss.str(); + + return wsFontFile; +} + +// family-name, file-path; +using FontInfo = std::pair; +using FontList = std::vector; + +bool CALLBACK EnumFamCallBack(LPLOGFONT lplf, + LPNEWTEXTMETRIC lpntm, + DWORD FontType, + LPVOID aFontList) +{ + std::vector *fontList = (std::vector *) (aFontList); + if (FontType & TRUETYPE_FONTTYPE) { + std::wstring name = lplf->lfFaceName; + fontList->push_back(name); + } + return true; + //UNREFERENCED_PARAMETER(lplf); + UNREFERENCED_PARAMETER(lpntm); +} + +#include +void choose_font_dlg() { + HWND hwnd = (HWND)GetFocus(); // owner window + HDC hdc = GetDC(NULL); // display device context of owner window + + CHOOSEFONT cf; // common dialog box structure + static LOGFONT lf; // logical font structure + static DWORD rgbCurrent; // current text color + HFONT hfont, hfontPrev; + DWORD rgbPrev; + + // Initialize CHOOSEFONT + ZeroMemory(&cf, sizeof(cf)); + cf.lStructSize = sizeof(cf); + cf.hwndOwner = hwnd; + cf.lpLogFont = &lf; + cf.rgbColors = rgbCurrent; + cf.Flags = CF_SCREENFONTS | CF_EFFECTS; + + if (ChooseFont(&cf) == TRUE) { + std::wcout << "selected font is " + << (std::wstring) cf.lpLogFont->lfFaceName + << std::endl; + + //hfont = CreateFontIndirect(cf.lpLogFont); + //hfontPrev = SelectObject(hdc, hfont); + //rgbCurrent = cf.rgbColors; + //rgbPrev = SetTextColor(hdc, rgbCurrent); + //... + } else { + std::cout << "Font was not selected"; + } +} + +void get_OS_font() +{ + HGDIOBJ g_hfFont = GetStockObject(DEFAULT_GUI_FONT); + LOGFONT lf; + GetObject(g_hfFont, sizeof(LOGFONT), &lf); + std::wcout << "Default WIN font is " << (std::wstring) lf.lfFaceName + << std::endl; +} + +void Emboss::get_font_list() { + get_OS_font(); + choose_font_dlg(); + + HDC hDC = GetDC(NULL); + std::vector font_names; + EnumFontFamilies(hDC, (LPCTSTR) NULL, (FONTENUMPROC) EnumFamCallBack, (LPARAM) &font_names); + + FontList font_list; + for (const std::wstring &font_name : font_names) { + std::cout << "Font name: "; + std::wcout << font_name; + //auto font_path_opt = get_font_path(font_name); + //if (font_path_opt.has_value()) { + // std::wcout << " path: "<< *font_path_opt; + //} + std::cout << std::endl; + //font_list.emplace_back(font_name, ) + } +} +#else +void Emboss::get_font_list() {} + +std::optional Emboss::get_font_path(const std::wstring &font_face_name){ + // not implemented + return {}; +} +#endif + std::optional Emboss::load_font(const char *file_path) { FILE *file = fopen(file_path, "rb"); diff --git a/src/libslic3r/Emboss.hpp b/src/libslic3r/Emboss.hpp index d3867ecc3..6e5936cea 100644 --- a/src/libslic3r/Emboss.hpp +++ b/src/libslic3r/Emboss.hpp @@ -19,6 +19,18 @@ class Emboss public: Emboss() = delete; + /// + /// Collect fonts registred inside OS + /// + static void get_font_list(); + + /// + /// OS dependent function to get location of font by its name + /// + /// Unique identificator for font + /// File path to font when found + static std::optional get_font_path(const std::wstring &font_face_name); + /// /// keep information from file about font /// @@ -35,10 +47,7 @@ public: // user defined unscaled char space int extra_char_space = 0; - // unscaled precision of lettter outline curve in conversion to lines - float flatness = 2.; - - // enum class Align: center/left/right + // TODO: add enum class Align: center/left/right }; /// diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 736f5c277..f665b7fea 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -28,6 +28,7 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D & parent, { load_font(); // TODO: suggest to use https://fontawesome.com/ + // (copy & paste) unicode symbols from web int index = 0; for (char &c : _u8L("Embossed text")) { m_text[index++] = c; } m_text[index] = '\0'; @@ -187,7 +188,7 @@ void GLGizmoEmboss::process() { void GLGizmoEmboss::close() { // close gizmo == open it again GLGizmosManager &gizmos_mgr = m_parent.get_gizmos_manager(); - gizmos_mgr.open_gizmo(GLGizmosManager::EType::Simplify); + gizmos_mgr.open_gizmo(GLGizmosManager::EType::Emboss); } void GLGizmoEmboss::draw_add_button() { diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 188c9e914..e84c14936 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -69,6 +69,7 @@ public: FdmSupports, Seam, MmuSegmentation, + Emboss, Simplify, Undefined }; diff --git a/tests/libslic3r/test_meshboolean.cpp b/tests/libslic3r/test_meshboolean.cpp index 9f799373e..7d60054ad 100644 --- a/tests/libslic3r/test_meshboolean.cpp +++ b/tests/libslic3r/test_meshboolean.cpp @@ -54,8 +54,7 @@ TEST_CASE("Add TriangleMeshes", "[MeshBoolean]") Polygons ttf2polygons(const char * font_name, char letter, float flatness = 1.f) { auto font = Emboss::load_font(font_name); if (!font.has_value()) return Polygons(); - font->flatness = flatness; - return Emboss::letter2polygons(*font, letter); + return Emboss::letter2polygons(*font, letter, flatness); } #include "libslic3r/SVG.hpp"