Magpie/tools/CJKCharacterSetForImGui/main.cpp
刘旭 b7e7be7f56
为游戏内叠加层添加本地化支持 (#600)
* feat: 游戏内覆盖本地化 1

* feat: 加载西班牙语、葡萄牙语、俄语、乌克兰语和土耳其语的字符集

* perf: 缓存字符范围

* feat: 简体中文、繁体中文和日语加载额外的字体

* fix: 加载正确的字体

* perf: 删除不必要的 ImVector<ImWchar>

* perf: 额外字体体积巨大,不能让它驻留内存

* perf: 启用 ImFontAtlasFlags_NoPowerOfTwoHeight
以及格式优化

* feat: 不再显示 CPU 名称
CPU 不是性能瓶颈

* perf: 按需构造字体

* fix: 打开 FPS 右键菜单时构建 UI 字体

* perf: 更改简中和繁中的字符表
来自 541544292a/core/rend/gui_util.cpp

* feat: 添加 CJKCharacterSetForImGui 用于生成供 ImGui 使用的字符表,现在简体中文使用通用规范汉字表中的一级字表(3500字)

* chore: 为 CJKCharacterSetForImGui 添加 README

* feat: 添加字符串本地化

* UI: 优化 FPS 菜单字体

* UI: 优化布局
2023-05-15 18:55:46 +08:00

106 lines
2.7 KiB
C++

#include <SDKDDKVer.h>
#include <Windows.h>
#include <iostream>
#include <cstdio>
#include <string>
#include <string_view>
#include <vector>
#include <cassert>
struct HandleCloser { void operator()(HANDLE h) noexcept { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } };
using ScopedHandle = std::unique_ptr<std::remove_pointer<HANDLE>::type, HandleCloser>;
static HANDLE SafeHandle(HANDLE h) noexcept {
return (h == INVALID_HANDLE_VALUE) ? nullptr : h;
}
static std::vector<BYTE> ReadFile(const wchar_t* fileName) noexcept {
CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {};
extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN;
extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParams.lpSecurityAttributes = nullptr;
extendedParams.hTemplateFile = nullptr;
ScopedHandle hFile(SafeHandle(CreateFile2(fileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extendedParams)));
if (!hFile) {
return {};
}
DWORD size = GetFileSize(hFile.get(), nullptr);
std::vector<BYTE> result(size, 0);
DWORD readed;
if (!::ReadFile(hFile.get(), result.data(), size, &readed, nullptr)) {
return {};
}
return result;
}
static std::wstring UTF8ToUTF16(std::string_view str) noexcept {
if (str.empty()) {
return {};
}
int convertResult = MultiByteToWideChar(CP_UTF8, 0,
str.data(), (int)str.size(), nullptr, 0);
if (convertResult <= 0) {
assert(false);
return {};
}
std::wstring result(convertResult + 10, L'\0');
convertResult = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(),
result.data(), (int)result.size());
if (convertResult <= 0) {
assert(false);
return {};
}
result.resize(convertResult);
return result;
}
// 输入: input.txt
// 将输出输入文件中所有汉字组成的字符表
int main() {
std::vector<BYTE> input = ReadFile(L"input.txt");
input.push_back(0);
std::wstring utf16 = UTF8ToUTF16(std::string_view((const char*)input.data(), input.size() - 1));
static constexpr std::pair<wchar_t, wchar_t> CJK_RANGE{ 0x4E00, 0x9FAF };
std::vector<bool> bitSet(CJK_RANGE.second - CJK_RANGE.first + 1);
for (wchar_t character : utf16) {
if (character < CJK_RANGE.first || character > CJK_RANGE.second) {
continue;
}
bitSet[character - CJK_RANGE.first] = true;
}
std::vector<uint16_t> index;
int prevIdx = 0;
for (int i = 0; i < CJK_RANGE.second - CJK_RANGE.first + 1; ++i) {
if (bitSet[i]) {
index.push_back(uint16_t(i - prevIdx));
prevIdx = i;
}
}
if (index.empty()) {
return 0;
}
std::string out = std::to_string(index[0]);
for (int i = 1; i < index.size(); ++i) {
out += ',';
out += std::to_string(index[i]);
}
std::cout << out;
}