mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 23:06:13 +08:00
Enumerate fonts
This commit is contained in:
parent
028f04f8a1
commit
84488ba6df
@ -86,6 +86,166 @@ std::optional<Privat::Glyph> Privat::get_glyph(stbtt_fontinfo &font_info, int un
|
|||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wingdi.h>
|
||||||
|
#include <windef.h>
|
||||||
|
#include <WinUser.h>
|
||||||
|
|
||||||
|
// Get system font file path
|
||||||
|
std::optional<std::wstring> 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<std::wstring, std::wstring>;
|
||||||
|
using FontList = std::vector<FontInfo>;
|
||||||
|
|
||||||
|
bool CALLBACK EnumFamCallBack(LPLOGFONT lplf,
|
||||||
|
LPNEWTEXTMETRIC lpntm,
|
||||||
|
DWORD FontType,
|
||||||
|
LPVOID aFontList)
|
||||||
|
{
|
||||||
|
std::vector<std::wstring> *fontList = (std::vector<std::wstring> *) (aFontList);
|
||||||
|
if (FontType & TRUETYPE_FONTTYPE) {
|
||||||
|
std::wstring name = lplf->lfFaceName;
|
||||||
|
fontList->push_back(name);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
//UNREFERENCED_PARAMETER(lplf);
|
||||||
|
UNREFERENCED_PARAMETER(lpntm);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <commdlg.h>
|
||||||
|
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<std::wstring> 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<std::wstring> Emboss::get_font_path(const std::wstring &font_face_name){
|
||||||
|
// not implemented
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::optional<Emboss::Font> Emboss::load_font(const char *file_path)
|
std::optional<Emboss::Font> Emboss::load_font(const char *file_path)
|
||||||
{
|
{
|
||||||
FILE *file = fopen(file_path, "rb");
|
FILE *file = fopen(file_path, "rb");
|
||||||
|
@ -19,6 +19,18 @@ class Emboss
|
|||||||
public:
|
public:
|
||||||
Emboss() = delete;
|
Emboss() = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Collect fonts registred inside OS
|
||||||
|
/// </summary>
|
||||||
|
static void get_font_list();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OS dependent function to get location of font by its name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="font_face_name">Unique identificator for font</param>
|
||||||
|
/// <returns>File path to font when found</returns>
|
||||||
|
static std::optional<std::wstring> get_font_path(const std::wstring &font_face_name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// keep information from file about font
|
/// keep information from file about font
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,10 +47,7 @@ public:
|
|||||||
// user defined unscaled char space
|
// user defined unscaled char space
|
||||||
int extra_char_space = 0;
|
int extra_char_space = 0;
|
||||||
|
|
||||||
// unscaled precision of lettter outline curve in conversion to lines
|
// TODO: add enum class Align: center/left/right
|
||||||
float flatness = 2.;
|
|
||||||
|
|
||||||
// enum class Align: center/left/right
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -28,6 +28,7 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D & parent,
|
|||||||
{
|
{
|
||||||
load_font();
|
load_font();
|
||||||
// TODO: suggest to use https://fontawesome.com/
|
// TODO: suggest to use https://fontawesome.com/
|
||||||
|
// (copy & paste) unicode symbols from web
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (char &c : _u8L("Embossed text")) { m_text[index++] = c; }
|
for (char &c : _u8L("Embossed text")) { m_text[index++] = c; }
|
||||||
m_text[index] = '\0';
|
m_text[index] = '\0';
|
||||||
@ -187,7 +188,7 @@ void GLGizmoEmboss::process() {
|
|||||||
void GLGizmoEmboss::close() {
|
void GLGizmoEmboss::close() {
|
||||||
// close gizmo == open it again
|
// close gizmo == open it again
|
||||||
GLGizmosManager &gizmos_mgr = m_parent.get_gizmos_manager();
|
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() {
|
void GLGizmoEmboss::draw_add_button() {
|
||||||
|
@ -69,6 +69,7 @@ public:
|
|||||||
FdmSupports,
|
FdmSupports,
|
||||||
Seam,
|
Seam,
|
||||||
MmuSegmentation,
|
MmuSegmentation,
|
||||||
|
Emboss,
|
||||||
Simplify,
|
Simplify,
|
||||||
Undefined
|
Undefined
|
||||||
};
|
};
|
||||||
|
@ -54,8 +54,7 @@ TEST_CASE("Add TriangleMeshes", "[MeshBoolean]")
|
|||||||
Polygons ttf2polygons(const char * font_name, char letter, float flatness = 1.f) {
|
Polygons ttf2polygons(const char * font_name, char letter, float flatness = 1.f) {
|
||||||
auto font = Emboss::load_font(font_name);
|
auto font = Emboss::load_font(font_name);
|
||||||
if (!font.has_value()) return Polygons();
|
if (!font.has_value()) return Polygons();
|
||||||
font->flatness = flatness;
|
return Emboss::letter2polygons(*font, letter, flatness);
|
||||||
return Emboss::letter2polygons(*font, letter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "libslic3r/SVG.hpp"
|
#include "libslic3r/SVG.hpp"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user