设置选项:Simple Unicode + Height Fixed

一 、分段图解

紧张分4段:文件头,编码表,检索表,点阵信息。

dwphp中文乱码精简UnicodeBIN格局文件图文详解一 NoSQL

补充解释:字符数决定编码表和检索表的大小。

适宜场景:编码不连续,且字符数少。

文件头构造体

/针对 height fixed 存储格式/typedef struct gui_font_head_height_fixed{ BYTE magic[4]; //'S'('U'or ’M’), 'F', 'L', X---Unicode(or MBCS) Font Library, X: 表示版本号. 定胜败4位。
如 0x12表示 Ver 1.2 DWORD Size; // 文件大小 BYTE nSection; // 共分几段数据,紧张针对 UNICODE 编码有效。
BYTE YSize; // 字体高度 WORD wCpFlag; // codepageflag: bit0~bit13 每个bit分别代表一个CodePage 标志,如果是1,则表示当前CodePage 当选定,否则为非选定。
WORD nTotalChars; // 总的字符数 BYTE ScanMode; // 扫描模式 BYTE bpp; // 位深度 } GUI_FONT_HEAD_HF, PGUI_FONT_HEAD_HF;

要点:字体高度,字符数,扫描办法,位深度。

二、图例详解

1、文件头

解释:上图蓝色标记部分(16字节)为文件头。
详解如下:

55 46 4C 12 - 标识头,判断是否为合法的字库文件。

53 = ‘S’,表示文件为Simple Unicode编码格式。

46 = ‘F’ , 4C = 'L'

12 表示该字库文件版本信息为 V1.2

20 6B 03 00 - 文件总长度。
即文件长 = 0x00036B20

00 - 表示包含几个段。
00则表示 0个段。

0C - 表示字体高度。
0C = 12,表示12像素。

02 00 - 表示当前字库包含了哪些字符集。

38 1D - 表示有效字符数。
0x1D38 = 7480 个字符。

00 - 表示扫描模式(比对工具设置选项就明白了)

01 - 表示位深度 (参考值:1,2,4,8),bpp = 1

2、编码表

解释:蓝色标记部分为编码表数据。
按小端字节序存放,升序排列,2个字节为1个编码。
如 A4 00 A7 00 A8 00 ...,则表示第一个编码为 0x00A4,第二个编码为 0x00A7,第三个编码为 0x00A8,以此类推。

3、检索表

一条检索信息占4个字节,包含了字符宽度和点阵信息的起始偏移地址。
检索信息构造体如下:

typedef struct tagUflCharInfo{ DWORD OffAddr : 26; // 当前字符点阵数据的起始地址 DWORD Width : 6; // 字符点阵的像素宽度( 目前最大支持点阵 < 64)} UFL_CHAR_INDEX;

解释:高 6bit 记录字符宽度,低 26bit 记录点阵信息起始偏移地址。

4、点阵信息

当前字库中所有包含字符的点阵数据凑集,数据存储办法与扫描办法有关,分横向,纵向,详细视情形而定。
如:B3 1A, 即为 10110011 00011010,合营位深度,逐个处理即可。

三、参考代码

1、simple unicode.h

// unicode_simple.h //#if !defined(__FONT_UNICODE_SIMPLE_H__)#define __FONT_UNICODE_SIMPLE_H__#include "..\include\typedef.h"/Func:读取编码列表, Param: nCodeNum:编码数量 dwHeadLen:文件头长度Return:成功返回“0”, 否则返回“非0”./int font_unicode_simple_read_codes(int nCodeNum, DWORD dwHeadLen);// 开释编码列表干系内存void font_unicode_simple_release_codes();/Func:定位字符,成功返回检索信息,否则返回0.Param: nCode:编码 dwHeadLen:文件头长度Return:返回指定字符的偏移地址,若找到有效字符,则返回大于0的检索信息,否则返回0./DWORD font_unicode_simple_find_char(WORD wCode, DWORD dwHeadLen);#endif // (__FONT_UNICODE_SIMPLE_H__)

2、simple unicode.c

/描述:用c措辞写的一个如何从unicode编码格式的点阵字库中读取字符信息(像素宽 +点阵信息) 至于容错性和效率方面还得利用者自行改进。
感激您的参阅!
作者:wujianguo日期:20090516MSN: wujianguo19@hotmail.comqq:9599598/#include "..\include\font.h"#include "..\include\font_file.h"#include "..\include\unicode_simple.h" #ifdef WIN32#include <stdio.h&gt;#include <stdlib.h>#endif#define MAX_FIND_LIMIT 31 // 是否二分查找临界值static int g_nCodeNum = 0;WORD g_pCodes = NULL; // 读取编码列表int font_unicode_simple_read_codes(int nCodeNum, DWORD dwHeadLen){ font_unicode_simple_release_codes(); g_nCodeNum = nCodeNum; g_pCodes = (WORD )malloc(nCodeNumsizeof(WORD)); if(g_pCodes == NULL) { printf("Malloc is fail!\n"); return -1; } font_file_seek(dwHeadLen); font_file_read(g_pCodes, nCodeNumsizeof(WORD)); return 0;}// 开释动态分配的内存void font_unicode_simple_release_codes(){ if(g_pCodes != NULL) { free(g_pCodes); g_pCodes = NULL; }}// 定位编码位置,若找到返回 >= 0的值,否则返回 -1.int font_unicode_simple_find_code(WORD wCode){ if(g_nCodeNum > 0) { if(g_nCodeNum > MAX_FIND_LIMIT) // 二分查找 { int low, high, mid; low = 0; high = g_nCodeNum -1; while(low <= high) { mid = (high + low)/2; if(g_pCodes[mid] == wCode) return mid; else if(wCode > g_pCodes[mid]) low = mid + 1; else high = mid - 1; } } else // 顺序查找 { int i = 0; for(i = 0; i < g_nCodeNum; i++) { if(wCode == g_pCodes[i]) return i; } } } return -1;}// 根据编码获取检索信息DWORD font_unicode_simple_find_char(WORD wCode, DWORD dwHeadLen){ DWORD offset = 0; DWORD dwCharInfo = 0; int nIdx = font_unicode_simple_find_code(wCode); if(nIdx == -1) // 未找到该编码 return 0; offset = dwHeadLen + g_nCodeNum 2 + nIdx 4; //dwHeadLen:文件头长度;g_nCodeNum 2: 编码表长度;nIdx4:检索表偏移 printf("offset = 0x%X\n", offset); font_file_seek(offset); font_file_read(&dwCharInfo, sizeof(DWORD)); return dwCharInfo;}