1 Star 7 Fork 2

Walkline/FontMaker Client

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
FontMaker_Cli.cpp 12.07 KB
一键复制 编辑 原始数据 按行查看 历史
Walkline 提交于 2022-08-04 16:48 . 增加字符反显相关代码
using namespace std;
#include "stdafx.h"
#include <afxwin.h>
#include <afxext.h>
#include <afxdisp.h>
#include <afxdtctl.h>
#include <afxcmn.h>
#include <iostream>
#include "FontMaker_Cli.h"
#include "resource.h"
int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX* lpelfe, NEWTEXTMETRICEX* lpntme, DWORD FontType, LPARAM lParam)
{return 100;}
static int UTF8ToUnicode(const char* input, WCHAR* output, int size)
{
return MultiByteToWideChar(CP_UTF8, 0, input, -1, output, size);
}
BOOL is_fontface_exists() {
CFont font;
if (font.CreatePointFont(12, m_cmd_parser.fontface)) {
LOGFONTW lf{};
lf.lfCharSet = DEFAULT_CHARSET;
wcscpy_s(lf.lfFaceName, min(LF_FACESIZE, m_cmd_parser.fontface.GetLength() + 1), m_cmd_parser.fontface.GetBuffer());
int iRet = EnumFontFamiliesExW(GetWindowDC(GetConsoleWindow()), &lf, (FONTENUMPROC)EnumFontFamExProc, (LPARAM)0, 0);
font.DeleteObject();
return iRet == 100 ? TRUE : FALSE;
}
return FALSE;
}
void init_font()
{
if (!is_fontface_exists()) {
wcout << L"无法找到指定的字体文件:" << m_cmd_parser.fontface.GetString() << endl;
exit(1);
}
ZeroMemory(&log_font, sizeof(log_font));
lstrcpy(log_font.lfFaceName, m_cmd_parser.fontface);
log_font.lfCharSet = DEFAULT_CHARSET;
log_font.lfWeight = m_cmd_parser.font_weight;
log_font.lfItalic = m_cmd_parser.font_itatlic;
log_font.lfHeight = m_cmd_parser.font_size;
if (m_hFont != NULL) {DeleteObject(m_hFont);}
m_hFont = CreateFontIndirect(&log_font);
m_bitfont.SetFont(m_hFont);
m_bitfont.SetSize(m_cmd_parser.font_width, m_cmd_parser.font_height);
m_bitfont.SetOffset(m_cmd_parser.font_offset_x, m_cmd_parser.font_offset_y);
}
BOOL set_charset(int resource_id)
{
m_charset.Delete();
HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(resource_id), L"CHARSET");
if (!hRsrc) {return false;}
HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
if (!hGlobal) {return false;}
LPVOID pResourceData = LockResource(hGlobal);
if (!pResourceData) {return false;}
DWORD dwSize = SizeofResource(NULL, hRsrc);
if (0 == dwSize) {return false;}
FreeResource(hGlobal);
m_charset.CreateFromResource((LPCTSTR) pResourceData, dwSize);
return true;
}
CString dedup_customized_file(WCHAR *buffer, int size)
{
int cnt;
WCHAR ch;
WCHAR *buf;
CString text;
text = CString(buffer);
cnt = 0;
buf = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size + 1) * sizeof(WCHAR));
if (buf == NULL) {
wcout << L"内存不足!" << endl;
return L"";
}
for (int i = 0; i < size; i++) {
ch = text.GetAt(i);
if (ch >= 0x20 && ch <= 0x7f) {continue;}
if (wcschr(buf, ch) == NULL) {
buf[cnt] = ch;
cnt++;
}
}
text = CString(buf);
HeapFree(GetProcessHeap(), 0, buf);
return text;
}
BOOL set_customized_charset(CString filename)
{
int len;
UINT size;
char *buffer;
WCHAR *text;
CString content;
CFile cf;
if (!cf.Open(filename, CFile::modeRead | CFile::shareDenyNone)) {
wcout << L"无法打开文件!" << endl;
return false;
}
size = (UINT) cf.GetLength();
buffer = (char *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
if (buffer == NULL) {
cf.Close();
wcout << L"内存不足!" << endl;
return false;
}
if (cf.Read(buffer, size) != size) {
cf.Close();
HeapFree(GetProcessHeap(), 0, buffer);
wcout << L"读取文件时发生错误!" << endl;
return false;
}
cf.Close();
len = UTF8ToUnicode(buffer, NULL, 0) + 1;
text = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR));
if (text == NULL) {
HeapFree(GetProcessHeap(), 0, buffer);
wcout << L"内存不足!" << endl;
return false;
}
len = UTF8ToUnicode(buffer, text, len);
content = dedup_customized_file(text, len);
len = content.GetLength();
CFile customized_index_table;
if (!customized_index_table.Open(customized_index_table_filename,
CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone)) {
wcout << L"创建目标文件 " << customized_index_table_filename.GetString() << L" 失败!" << endl;
exit(1);
}
customized_index_table.Write(content, len * 2);
customized_index_table.Close();
m_charset.Delete();
m_charset.Create(content);
HeapFree(GetProcessHeap(), 0, text);
return true;
}
BOOL make_file(CString output_filename)
{
CFile file;
if (!file.Open(output_filename,
CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone)) {
wcout << L"创建目标文件 " << output_filename.GetString() << L" 失败!" << endl;
exit(1);
}
// scan - 0: 水平, 1: 垂直
// msb - 1: 高位在前, 0: 低位在前
// var - 0: 固定宽带, 1: 可变宽度
maker.MakeBinFile(&m_bitfont, &m_charset, &file, m_cmd_parser.scan_mode, m_cmd_parser.byte_order, m_cmd_parser.char_width, m_cmd_parser.reverse_display);
m_character_count += m_charset.GetCharCount();
file.Close();
wcout << L"保存文件 " << output_filename.GetString() << L" 成功" << endl;
return true;
}
/*
* 合并的文件包括:
* 文件头 [24]:
* [4] 文件标识符 - FMUX
* [4] 文件大小
* [1] 字体宽高
* [2] 有效字符数量
* [1] 是否包含 GB2312 索引表
* [1] 扫描模式
* [1] 字节顺序
* [4] ASCII 字模起始地址
* [4] GB2312 字模起始地址
* [2] 保留字
* GB2312 索引表
* ASCII 字模数据
* GB2312 字模数据
*/
BOOL combine_files() {
CFile ascii_file, gb2312_file, customized_file, customized_index_table_file, combined_file;
DWORD index_table_size, gb2312_data_size;
LPVOID pResourceData = nullptr;
if (m_cmd_parser.using_customized_cst) {
if (!customized_file.Open(customized_output_filename,
CFile::modeRead | CFile::shareDenyNone)) {
wcout << customized_output_filename.GetString() << L" 文件不存在" << endl;
exit(1);
}
if (!customized_index_table_file.Open(m_cmd_parser.input_customized_cst,
CFile::modeRead | CFile::shareDenyNone)) {
wcout << m_cmd_parser.input_customized_cst.GetString() << L" 文件不存在" << endl;
exit(1);
}
gb2312_data_size = (DWORD) customized_file.GetLength();
index_table_size = (DWORD) customized_index_table_file.GetLength();
} else {
if (!ascii_file.Open(ascii_output_filename,
CFile::modeRead | CFile::shareDenyNone)) {
wcout << ascii_output_filename.GetString() << L" 文件不存在" << endl;
exit(1);
}
if (m_cmd_parser.using_customized_file) {
if (!customized_file.Open(customized_output_filename,
CFile::modeRead | CFile::shareDenyNone)) {
wcout << customized_output_filename.GetString() << L" 文件不存在" << endl;
exit(1);
}
if (!customized_index_table_file.Open(customized_index_table_filename,
CFile::modeRead | CFile::shareDenyNone)) {
wcout << customized_index_table_filename.GetString() << L" 文件不存在" << endl;
exit(1);
}
gb2312_data_size = (DWORD) customized_file.GetLength();
index_table_size = (DWORD) customized_index_table_file.GetLength();
} else {
if (!gb2312_file.Open(gb2312_output_filename,
CFile::modeRead | CFile::shareDenyNone)) {
wcout << gb2312_output_filename.GetString() << L" 文件不存在" << endl;
exit(1);
}
HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(IDR_NEW_GB2312), L"CHARSET");
if (!hRsrc) {return false;}
HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
if (!hGlobal) {return false;}
pResourceData = LockResource(hGlobal);
if (!pResourceData) {return false;}
index_table_size = SizeofResource(NULL, hRsrc);
if (0 == index_table_size) {return false;}
FreeResource(hGlobal);
gb2312_data_size = (DWORD) gb2312_file.GetLength();
}
}
if (!combined_file.Open(m_cmd_parser.output_file,
CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone)) {
wcout << L"创建目标文件 " << m_cmd_parser.output_file.GetString() << L" 失败!" << endl;
exit(1);
}
PFL_Header header = (PFL_Header)malloc(sizeof(FL_Header));
header->magic[0] = 'F';
header->magic[1] = 'M';
header->magic[2] = 'U';
header->magic[3] = m_cmd_parser.using_customized_file || m_cmd_parser.using_customized_cst ? 'Y' : 'X';
DWORD length = FL_Header_Size + // 文件头大小
index_table_size + // 自定义或 GB2312 索引表大小
gb2312_data_size; // 自定义或 GB2312 字符数据大小
length += m_cmd_parser.using_customized_cst ? 0 : (DWORD) ascii_file.GetLength(); // ASCII 字符数据大小
header->file_size = length;
header->font_width = m_cmd_parser.font_width;
header->font_height = m_cmd_parser.font_height;
header->char_count = m_character_count;
header->has_index_table = m_cmd_parser.has_index_table;
header->scan_mode = m_cmd_parser.scan_mode;
header->byte_order = m_cmd_parser.byte_order;
header->ascii_start = FL_Header_Size + (m_cmd_parser.has_index_table ? index_table_size : 0);
header->gb2312_start = m_cmd_parser.using_customized_cst ? FL_Header_Size + index_table_size : header->ascii_start + (DWORD) ascii_file.GetLength();
header->reserved[0] = '\0';
header->reserved[1] = '\0';
combined_file.Write(&header->magic, sizeof(header->magic));
combined_file.Write(&header->file_size, sizeof(header->file_size));
combined_file.Write(&header->font_width, sizeof(header->font_width));
combined_file.Write(&header->font_height, sizeof(header->font_height));
combined_file.Write(&header->char_count, sizeof(header->char_count));
combined_file.Write(&header->has_index_table, sizeof(header->has_index_table));
combined_file.Write(&header->scan_mode, sizeof(header->scan_mode));
combined_file.Write(&header->byte_order, sizeof(header->byte_order));
combined_file.Write(&header->ascii_start, sizeof(header->ascii_start));
combined_file.Write(&header->gb2312_start, sizeof(header->gb2312_start));
combined_file.Write(&header->reserved, sizeof(header->reserved));
free(header);
char* buffer;
DWORD file_length;
if (m_cmd_parser.using_customized_file || m_cmd_parser.using_customized_cst) {
buffer = new char[index_table_size + 1];
buffer[index_table_size] = 0;
customized_index_table_file.Read(buffer, index_table_size);
combined_file.Write(buffer, index_table_size);
} else {
combined_file.Write(pResourceData, index_table_size);
}
if (!m_cmd_parser.using_customized_cst) {
file_length = (DWORD) ascii_file.GetLength();
buffer = new char[file_length + 1];
buffer[file_length] = 0;
ascii_file.Read(buffer, file_length);
combined_file.Write(buffer, file_length);
}
buffer = new char[gb2312_data_size + 1];
buffer[gb2312_data_size] = 0;
if (m_cmd_parser.using_customized_file || m_cmd_parser.using_customized_cst) {
customized_file.Read(buffer, gb2312_data_size);
} else {
gb2312_file.Read(buffer, gb2312_data_size);
}
combined_file.Write(buffer, gb2312_data_size);
if (m_cmd_parser.using_customized_cst) {
customized_file.Close();
customized_index_table_file.Close();
} else {
if (m_cmd_parser.using_customized_file) {
customized_file.Close();
customized_index_table_file.Close();
} else {
gb2312_file.Close();
}
ascii_file.Close();
}
combined_file.Close();
return true;
}
int main()
{
wcout.imbue(locale("CHS"));
BOOL output_file_generated = false;
m_cmd_parser.parse();
// m_cmd_parser.print_params();
init_font();
if (m_cmd_parser.using_customized_cst) {
m_charset.LoadFromFile(m_cmd_parser.input_customized_cst);
output_file_generated = make_file(customized_output_filename);
} else {
if (set_charset(IDR_ASCII)) {
output_file_generated = make_file(ascii_output_filename);
}
if (m_cmd_parser.using_customized_file) {
if (set_customized_charset(m_cmd_parser.input_customized_file)) {
output_file_generated = make_file(customized_output_filename);
}
} else {
if (set_charset(IDR_NEW_GB2312)) {
output_file_generated &= make_file(gb2312_output_filename);
}
}
}
if (!output_file_generated) {
wcout << L"创建字库文件失败" << endl;
exit(1);
}
if (combine_files()) {
wcout << L"创建字库文件 " << m_cmd_parser.output_file.GetString() << L" 成功" << endl;
m_cmd_parser.print_params();
}
if (m_cmd_parser.using_customized_cst) {
DeleteFile(customized_output_filename);
} else {
DeleteFile(ascii_output_filename);
if (m_cmd_parser.using_customized_file) {
DeleteFile(customized_index_table_filename);
DeleteFile(customized_output_filename);
} else {
DeleteFile(gb2312_output_filename);
}
}
return 0;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/walkline/fontmaker-client.git
git@gitee.com:walkline/fontmaker-client.git
walkline
fontmaker-client
FontMaker Client
master

搜索帮助