bin是什么格式的文件(BIN格式文件图文详解一)

bin是什么格式的文件(BIN格式文件图文详解一)

  精简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 "..includetypedef.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

  日期:20090516

  MSN: wujianguo19@hotmail.com

  qq:9599598

  *************************************************************/

  #include "..includefont.h"

  #include "..includefont_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;

  }

推荐阅读