从C ++ / Windows中获取名称和样式的字体文件path

我目前在我的一个项目中实现FreeType 2,因此需要我的系统上的字体文件path。 我需要一个解决scheme,只需要字体名称和所需的字体样式(例如粗体斜体 ),然后返回字体的文件path。

我已经尝试了这个堆栈溢出问题的答案,但它不能在Windows 7上(也可能在Vista上),但显然我需要一个解决scheme,在这些系统和未来的系统。

Solutions Collecting From Web of "从C ++ / Windows中获取名称和样式的字体文件path"

请问为什么你需要一个物理文件的路径?

  • 如果您只需要字体的二进制数据,则可以使用GetFontData 。
  • 如果需要字体的指标,您可以创建一个HFONT,选择HFONT到一个字体持有人HDC,并使用GetOutlineTextMetrics 。
  • 如果您需要关于字体链接的信息,请查看我的项目: font_link.cpp 。
  • 以上都是纯粹的GDI功能。 如果你真的需要字体路径,不介意使用DirectWrite,请看IDWriteFontFile :: GetReferenceKey和IDWriteLocalFontFileLoader :: GetFilePathFromKey 。 这会给你比GDI更多的未来保险。

我曾经为Windows平台编写代码来找到一个基于“Arial Bold”或这样的名字的字体文件。 代码在下面发布。 它正在扫描注册表,并尝试在Windows字体目录中找到与字体名称匹配的文件。 这可能不是防弹的,但它确实有一些工作。 一旦你有文件名,你可以将它传递给FreeType。

// Get system font file path std::string GetSystemFontFile(const std::string &faceName) { static const LPWSTR fontRegistryPath = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"; HKEY hKey; LONG result; std::wstring wsFaceName(faceName.begin(), faceName.end()); // 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(wsFaceName.c_str(), wsValueName.c_str(), wsFaceName.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 std::string(wsFontFile.begin(), wsFontFile.end()); }