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;} 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; } 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_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, combined_file; if (!ascii_file.Open(ascii_output_filename, CFile::modeRead | CFile::shareDenyNone)) { wcout << ascii_output_filename.GetString() << L" 文件不存在" << endl; exit(1); } 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_GB2312), 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); 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] = 'X'; DWORD length = FL_Header_Size + dwSize + (DWORD) ascii_file.GetLength() + (DWORD) gb2312_file.GetLength(); header->file_size = length; header->font_height = m_cmd_parser.font_size; 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; if (m_cmd_parser.has_index_table) { header->ascii_start = FL_Header_Size + dwSize; } else { header->ascii_start = FL_Header_Size; } header->gb2312_start = 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_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; combined_file.Write(pResourceData, dwSize); 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); file_length = (DWORD) gb2312_file.GetLength(); buffer = new char[file_length + 1]; buffer[file_length] = 0; gb2312_file.Read(buffer, file_length); combined_file.Write(buffer, file_length); ascii_file.Close(); gb2312_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 (set_charset(IDR_ASCII)) { output_file_generated = make_file(ascii_output_filename); } if (set_charset(IDR_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(); } DeleteFile(ascii_output_filename); DeleteFile(gb2312_output_filename); system("pause"); return 0; }