mirror of
https://github.com/Blinue/Magpie.git
synced 2026-06-24 02:04:10 +00:00
* 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: 优化布局
106 lines
2.7 KiB
C++
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;
|
|
}
|