Linux字体遍历 获取支持的unicode范围
我将结合这两个代码,并将输出重定向到文本文件。以下是修改后的代码:
#include "FontConfig.h"
#include <fontconfig/fontconfig.h>
#include <iomanip>
#include <iostream>
#include <vector>
#include <fstream>
#include <set>
#include <memory>using namespace std;const std::vector<const char *> FONT_PROPERTIES = {FC_FAMILY, FC_STYLE, FC_FILE, FC_CHARSET, FC_SLANT, FC_WEIGHT,FC_SIZE, FC_ASPECT, FC_PIXEL_SIZE, FC_SPACING, FC_FOUNDRY,FC_ANTIALIAS, FC_HINTING, FC_HINT_STYLE, FC_VERTICAL_LAYOUT,FC_AUTOHINT, FC_WIDTH, FC_INDEX, FC_OUTLINE, FC_SCALABLE,FC_COLOR, FC_VARIABLE, FC_SYMBOL, FC_DPI, FC_RGBA, FC_MINSPACE,FC_FONTVERSION, FC_FULLNAME, FC_FAMILYLANG, FC_STYLELANG,FC_FULLNAMELANG, FC_CAPABILITY, FC_FONTFORMAT, FC_EMBOLDEN,FC_EMBEDDED_BITMAP, FC_DECORATIVE, FC_LCD_FILTER,FC_FONT_FEATURES, FC_FONT_VARIATIONS, FC_NAMELANG,FC_POSTSCRIPT_NAME};typedef struct {uint32_t start; // 范围起始码点uint32_t end; // 范围结束码点
} UnicodeRange;// 获取字体支持的Unicode范围
std::vector<UnicodeRange> GetFontUnicodeRanges(FcPattern *pattern) {std::vector<UnicodeRange> ranges;FcCharSet *charset = nullptr;if (FcPatternGetCharSet(pattern, FC_CHARSET, 0, &charset) == FcResultMatch) {FcChar32 pageMap[FC_CHARSET_MAP_SIZE];FcChar32 nextPage = 0;FcChar32 base = 0;while ((base = FcCharSetNextPage(charset, pageMap, &nextPage)) != FC_CHARSET_DONE) {for (int i = 0; i < FC_CHARSET_MAP_SIZE; ++i) {FcChar32 bits = pageMap[i];if (bits == 0)continue;for (int bit = 0; bit < 32; ++bit) {if (bits & (1U << bit)) {FcChar32 codePoint = base + i * 32 + bit;if (codePoint <= 0x10FFFF) { // 有效的Unicode码点if (ranges.empty() || codePoint != ranges.back().end + 1) {// 新范围ranges.push_back({codePoint, codePoint});} else {// 扩展当前范围ranges.back().end = codePoint;}}}}}}}return ranges;
}void PrintFontInfo(ofstream &outFile, FcPattern *pattern) {// 输出字体属性for (const auto &prop : FONT_PROPERTIES) {FcChar8 *strVal;int intVal;double doubleVal;FcBool boolVal;if (FcPatternGetString(pattern, prop, 0, &strVal) == FcResultMatch) {outFile << prop << ": " << strVal << endl;} else if (FcPatternGetInteger(pattern, prop, 0, &intVal) == FcResultMatch) {outFile << prop << ": " << intVal << endl;} else if (FcPatternGetDouble(pattern, prop, 0, &doubleVal) == FcResultMatch) {outFile << prop << ": " << doubleVal << endl;} else if (FcPatternGetBool(pattern, prop, 0, &boolVal) == FcResultMatch) {outFile << prop << ": " << (boolVal ? "true" : "false") << endl;}}// 输出Unicode范围auto ranges = GetFontUnicodeRanges(pattern);outFile << "Unicode Ranges:" << endl;for (const auto &range : ranges) {outFile << " U+" << hex << uppercase << setw(4) << setfill('0') << range.start << "-U+" << hex << uppercase << setw(4) << setfill('0') << range.end << endl;}outFile << dec; // 恢复十进制输出outFile << "----------------------------------------" << endl;
}int main() {ofstream outFile("font_info.txt");if (!outFile) {cerr << "Failed to open output file" << endl;return 1;}auto fontconfig_instance = PdfFontConfigWrapper::GetInstance();std::set<std::shared_ptr<FcPattern>> fontPatterns;if (!fontconfig_instance->GetFontPatterns(fontPatterns)) {cerr << "Failed to get font patterns" << endl;outFile.close();return 1;}outFile << "System Font Information" << endl;outFile << "=======================" << endl << endl;for (const auto &pattern : fontPatterns) {PrintFontInfo(outFile, pattern.get());}outFile.close();cout << "Font information has been written to font_info.txt" << endl;return 0;
}
这个修改后的版本有以下改进:
- 将输出重定向到文件 “font_info.txt” 而不是控制台
- 合并了两个功能:输出字体属性和Unicode范围
- 添加了文件头信息和分隔线,使输出更易读
- Unicode范围以十六进制格式输出(如 U+0020-U+007E)
- 添加了错误处理,确保文件能正常打开和关闭
- 程序结束时显示完成信息
输出文件将包含每个字体的所有属性信息,后面跟着该字体支持的Unicode字符范围。每个字体之间用分隔线隔开,方便阅读。
注意:确保你有写入当前目录的权限,否则文件创建可能会失败。