精简Unicode,按unicode编码方式存储检索,又称为SimpleUnicode。主要目的:极致优化检索表空间。
设置选项:SimpleUnicode+HeightFixed
一、分段图解
主要分4段:文件头,编码表,检索表,点阵信息。
补充说明:字符数决定编码表和检索表的大小。
适宜场景:编码不连续,且字符数少。
文件头结构体
/*针对heightfixed存储格式*/typedefstructgui_font_head_height_fixed{BYTEmagic[4];//'S'('U'or’M’),'F','L',X---Unicode(orMBCS)FontLibrary,X:表示版本号.分高低4位。如0x12表示Ver1.2DWORDSize;//文件大小BYTEnSection;//共分几段数据,主要针对UNICODE编码有效。BYTEYSize;//字体高度WORDwCpFlag;//codepageflag:bit0~bit13每个bit分别代表一个CodePage标志,如果是1,则表示当前CodePage被选定,否则为非选定。WORDnTotalChars;//总的字符数BYTEScanMode;//扫描模式BYTEbpp;//位深度}GUI_FONT_HEAD_HF,*PGUI_FONT_HEAD_HF;
要点:字体高度,字符数,扫描方式,位深度。
二、图例详解
1、文件头
说明:上图蓝色标记部分(16字节)为文件头。详解如下:
55464C12-标识头,判断是否为合法的字库文件。
53=‘S’,表示文件为SimpleUnicode编码格式。
46=‘F’,4C='L'
12表示该字库文件版本信息为V1.2
206B0300-文件总长度。即文件长=0x00036B20
00-表示包含几个段。00则表示0个段。
0C-表示字体高度。0C=12,表示12像素。
0200-表示当前字库包含了哪些字符集。
381D-表示有效字符数。0x1D38=7480个字符。
00-表示扫描模式(比对工具设置选项就明白了)
01-表示位深度(参考值:1,2,4,8),bpp=1
2、编码表
说明:蓝色标记部分为编码表数据。按小端字节序存放,升序排列,2个字节为1个编码。如A400A700A800...,则表示第一个编码为0x00A4,第二个编码为0x00A7,第三个编码为0x00A8,以此类推。
3、检索表
一条检索信息占4个字节,包含了字符宽度和点阵信息的起始偏移地址。检索信息结构体如下:
typedefstructtagUflCharInfo{DWORDOffAddr:26;//当前字符点阵数据的起始地址DWORDWidth:6;//字符点阵的像素宽度(目前最大支持点阵<64)}UFL_CHAR_INDEX;
说明:高6bit记录字符宽度,低26bit记录点阵信息起始偏移地址。
4、点阵信息
当前字库中所有包含字符的点阵数据集合,数据存储方式与扫描方式有关,分横向,纵向,具体视情况而定。如:B31A,即为1011001100011010,配合位深度,逐个处理即可。
三、参考代码
1、simpleunicode.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”.****************************************/intfont_unicode_simple_read_codes(intnCodeNum,DWORDdwHeadLen);//释放编码列表相关内存voidfont_unicode_simple_release_codes();/***************************************Func:定位字符,成功返回检索信息,否则返回0.Param:nCode:编码dwHeadLen:文件头长度Return:返回指定字符的偏移地址,若找到有效字符,则返回大于0的检索信息,否则返回0.****************************************/DWORDfont_unicode_simple_find_char(WORDwCode,DWORDdwHeadLen);#endif//(__FONT_UNICODE_SIMPLE_H__)
2、simpleunicode.c
/***********************************************************描述:用c语言写的一个如何从unicode编码格式的点阵字库中读取字符信息(像素宽+点阵信息)至于容错性和效率方面还得使用者自行改善。谢谢您的参阅!作者:wujianguo日期:20090516MSN:wujianguo19@hotmail.comqq:9599598*************************************************************/#include"..\include\font.h"#include"..\include\font_file.h"#include"..\include\unicode_simple.h"#ifdefWIN32#include<stdio.h>#include<stdlib.h>#endif#defineMAX_FIND_LIMIT31//是否二分查找临界值staticintg_nCodeNum=0;WORD*g_pCodes=NULL;//读取编码列表intfont_unicode_simple_read_codes(intnCodeNum,DWORDdwHeadLen){font_unicode_simple_release_codes();g_nCodeNum=nCodeNum;g_pCodes=(WORD*)malloc(nCodeNum*sizeof(WORD));if(g_pCodes==NULL){printf("Mallocisfail!\n");return-1;}font_file_seek(dwHeadLen);font_file_read(g_pCodes,nCodeNum*sizeof(WORD));return0;}//释放动态分配的内存voidfont_unicode_simple_release_codes(){if(g_pCodes!=NULL){free(g_pCodes);g_pCodes=NULL;}}//定位编码位置,若找到返回>=0的值,否则返回-1.intfont_unicode_simple_find_code(WORDwCode){if(g_nCodeNum>0){if(g_nCodeNum>MAX_FIND_LIMIT)//二分查找{intlow,high,mid;low=0;high=g_nCodeNum-1;while(low<=high){mid=(high+low)/2;if(g_pCodes[mid]==wCode)returnmid;elseif(wCode>g_pCodes[mid])low=mid+1;elsehigh=mid-1;}}else//顺序查找{inti=0;for(i=0;i<g_nCodeNum;i++){if(wCode==g_pCodes[i])returni;}}}return-1;}//根据编码获取检索信息DWORDfont_unicode_simple_find_char(WORDwCode,DWORDdwHeadLen){DWORDoffset=0;DWORDdwCharInfo=0;intnIdx=font_unicode_simple_find_code(wCode);if(nIdx==-1)//未找到该编码return0;offset=dwHeadLen+g_nCodeNum*2+nIdx*4;//dwHeadLen:文件头长度;g_nCodeNum*2:编码表长度;nIdx*4:检索表偏移printf("offset=0x%X\n",offset);font_file_seek(offset);font_file_read(&dwCharInfo,sizeof(DWORD));returndwCharInfo;}