精簡Unicode,按unicode編碼方式存儲檢索,又稱為Simple Unicode。主要目的:極致優化檢索表空間。
設置選項:Simple Unicode + Height Fixed
一 、分段圖解
主要分4段:文件頭,編碼表,檢索表,點陣信息。
補充說明:字符數決定編碼表和檢索表的大小。
適宜場景:編碼不連續,且字符數少。
文件頭結構體
/*針對 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 ypedef.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編碼格式的點陣字庫中讀取字符信息(像素寬 +點陣信息)
至于容錯性和效率方面還得使用者自行改善。謝謝您的參閱!
日期:20090516
MSN: wujianguo19@hotmail.com
qq:9599598
*************************************************************/
#include "..\include\font.h"
#include "..\include\font_file.h"
#include "..\include苘de_simple.h"
#ifdef WIN32
#include
#include
#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(nCodeNum*sizeof(WORD));
if(g_pCodes==NULL)
{
printf("Malloc is fail!
");
return -1;
}
font_file_seek(dwHeadLen);
font_file_read(g_pCodes, nCodeNum*sizeof(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: 編碼表長度;nIdx*4:檢索表偏移
printf("offset=0x%X
", offset);
font_file_seek(offset);
font_file_read(&dwCharInfo, sizeof(DWORD));
return dwCharInfo;
}
版權聲明:本文來自互聯網整理發布,如有侵權,聯系刪除
原文鏈接:http://www.freetextsend.comhttp://www.freetextsend.com/tiyuzhishi/21003.html