c语言之guitool制作的点阵显示
效果:
源码:
// guitool_demo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <stdio.h>
#include <windows.h>
#define PIXELS_PER_BYTE 8
#define FONT_INDEX_TAB_SIZE 4 //单个字符对应的字体检索信息长度为 4Byte (b0~b25: 记录点阵信息的起始地址, b26~b31: 记录当前字符的象素宽度)
#define GET_FONT_WIDTH(charinfo) (charinfo >> 26)
#define GET_FONT_OFFADDR(charinfo) (charinfo & 0x3ffffff)
#define DB2UC(c1,c2) (c1 | (((U16)c2)<<8))
#define DISPLAY_FONT_MODE 1 // 1. 表示采用 '*' 和 '_' 描出字模 0. 表示显示其点阵数据
#define MAX_GLYPH_CNT 256
#define MAX_GLYPH_LEN 9
static char strGlyphTab[MAX_GLYPH_CNT][9] = {
"________",
"_______X",
"______X_",
"______XX",
"_____X__",
"_____X_X",
"_____XX_",
"_____XXX",
"____X___",
"____X__X",
"____X_X_",
"____X_XX",
"____XX__",
"____XX_X",
"____XXX_",
"____XXXX",
"___X____",
"___X___X",
"___X__X_",
"___X__XX",
"___X_X__",
"___X_X_X",
"___X_XX_",
"___X_XXX",
"___XX___",
"___XX__X",
"___XX_X_",
"___XX_XX",
"___XXX__",
"___XXX_X",
"___XXXX_",
"___XXXXX",
"__X_____",
"__X____X",
"__X___X_",
"__X___XX",
"__X__X__",
"__X__X_X",
"__X__XX_",
"__X__XXX",
"__X_X___",
"__X_X__X",
"__X_X_X_",
"__X_X_XX",
"__X_XX__",
"__X_XX_X",
"__X_XXX_",
"__X_XXXX",
"__XX____",
"__XX___X",
"__XX__X_",
"__XX__XX",
"__XX_X__",
"__XX_X_X",
"__XX_XX_",
"__XX_XXX",
"__XXX___",
"__XXX__X",
"__XXX_X_",
"__XXX_XX",
"__XXXX__",
"__XXXX_X",
"__XXXXX_",
"__XXXXXX",
"_X______",
"_X_____X",
"_X____X_",
"_X____XX",
"_X___X__",
"_X___X_X",
"_X___XX_",
"_X___XXX",
"_X__X___",
"_X__X__X",
"_X__X_X_",
"_X__X_XX",
"_X__XX__",
"_X__XX_X",
"_X__XXX_",
"_X__XXXX",
"_X_X____",
"_X_X___X",
"_X_X__X_",
"_X_X__XX",
"_X_X_X__",
"_X_X_X_X",
"_X_X_XX_",
"_X_X_XXX",
"_X_XX___",
"_X_XX__X",
"_X_XX_X_",
"_X_XX_XX",
"_X_XXX__",
"_X_XXX_X",
"_X_XXXX_",
"_X_XXXXX",
"_XX_____",
"_XX____X",
"_XX___X_",
"_XX___XX",
"_XX__X__",
"_XX__X_X",
"_XX__XX_",
"_XX__XXX",
"_XX_X___",
"_XX_X__X",
"_XX_X_X_",
"_XX_X_XX",
"_XX_XX__",
"_XX_XX_X",
"_XX_XXX_",
"_XX_XXXX",
"_XXX____",
"_XXX___X",
"_XXX__X_",
"_XXX__XX",
"_XXX_X__",
"_XXX_X_X",
"_XXX_XX_",
"_XXX_XXX",
"_XXXX___",
"_XXXX__X",
"_XXXX_X_",
"_XXXX_XX",
"_XXXXX__",
"_XXXXX_X",
"_XXXXXX_",
"_XXXXXXX",
"X_______",
"X______X",
"X_____X_",
"X_____XX",
"X____X__",
"X____X_X",
"X____XX_",
"X____XXX",
"X___X___",
"X___X__X",
"X___X_X_",
"X___X_XX",
"X___XX__",
"X___XX_X",
"X___XXX_",
"X___XXXX",
"X__X____",
"X__X___X",
"X__X__X_",
"X__X__XX",
"X__X_X__",
"X__X_X_X",
"X__X_XX_",
"X__X_XXX",
"X__XX___",
"X__XX__X",
"X__XX_X_",
"X__XX_XX",
"X__XXX__",
"X__XXX_X",
"X__XXXX_",
"X__XXXXX",
"X_X_____",
"X_X____X",
"X_X___X_",
"X_X___XX",
"X_X__X__",
"X_X__X_X",
"X_X__XX_",
"X_X__XXX",
"X_X_X___",
"X_X_X__X",
"X_X_X_X_",
"X_X_X_XX",
"X_X_XX__",
"X_X_XX_X",
"X_X_XXX_",
"X_X_XXXX",
"X_XX____",
"X_XX___X",
"X_XX__X_",
"X_XX__XX",
"X_XX_X__",
"X_XX_X_X",
"X_XX_XX_",
"X_XX_XXX",
"X_XXX___",
"X_XXX__X",
"X_XXX_X_",
"X_XXX_XX",
"X_XXXX__",
"X_XXXX_X",
"X_XXXXX_",
"X_XXXXXX",
"XX______",
"XX_____X",
"XX____X_",
"XX____XX",
"XX___X__",
"XX___X_X",
"XX___XX_",
"XX___XXX",
"XX__X___",
"XX__X__X",
"XX__X_X_",
"XX__X_XX",
"XX__XX__",
"XX__XX_X",
"XX__XXX_",
"XX__XXXX",
"XX_X____",
"XX_X___X",
"XX_X__X_",
"XX_X__XX",
"XX_X_X__",
"XX_X_X_X",
"XX_X_XX_",
"XX_X_XXX",
"XX_XX___",
"XX_XX__X",
"XX_XX_X_",
"XX_XX_XX",
"XX_XXX__",
"XX_XXX_X",
"XX_XXXX_",
"XX_XXXXX",
"XXX_____",
"XXX____X",
"XXX___X_",
"XXX___XX",
"XXX__X__",
"XXX__X_X",
"XXX__XX_",
"XXX__XXX",
"XXX_X___",
"XXX_X__X",
"XXX_X_X_",
"XXX_X_XX",
"XXX_XX__",
"XXX_XX_X",
"XXX_XXX_",
"XXX_XXXX",
"XXXX____",
"XXXX___X",
"XXXX__X_",
"XXXX__XX",
"XXXX_X__",
"XXXX_X_X",
"XXXX_XX_",
"XXXX_XXX",
"XXXXX___",
"XXXXX__X",
"XXXXX_X_",
"XXXXX_XX",
"XXXXXX__",
"XXXXXX_X",
"XXXXXXX_",
"XXXXXXXX"
};
typedef struct tagFlSectionInfo {
WORD First;
WORD Last;
DWORD OffAddr;
} FL_SECTION_INF, * PFL_SECTION_INF;
typedef struct tagFontLibHeader {
BYTE magic[4]; //'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 被选定,否则为非选定。
char reserved[4]; // 预留字节
FL_SECTION_INF* pSection;
} FL_HEADER, * PFL_HEADER;
FL_HEADER _fl_header = { 0 };
static DWORD g_dwCharInfo = 0; // 存储当前字符的检索信息。 bit0~bit25:存放点阵信息的起始地址。 bit26~bit31:存放像素宽度。
void font_release_sections();
#ifdef WIN32
#include "stdio.h"
static FILE* g_prf = NULL;
#endif
int font_file_open(const char* file)
{
#ifdef WIN32
if ((g_prf = fopen(file, "rb")) != NULL)
return 1;
#endif
return 0;
}
int font_file_seek(long offset)
{
#ifdef WIN32
if (g_prf != NULL)
return fseek(g_prf, offset, SEEK_SET);
#endif
return -1;
}
int font_file_read(void* pdata, long size)
{
#ifdef WIN32
if (g_prf != NULL)
return fread(pdata, size,1, g_prf);
#endif
return 0;
}
void font_file_close()
{
#ifdef WIN32
if (g_prf != NULL)
fclose(g_prf);
#endif
}
int font_read_sections()
{
PFL_HEADER pfl_header = &_fl_header;
font_release_sections();
pfl_header->pSection = (FL_SECTION_INF*)malloc(pfl_header->nSection * sizeof(FL_SECTION_INF));
if (pfl_header->pSection == NULL)
{
printf("Malloc fail!\n");
return 0;
}
font_file_read(pfl_header->pSection, pfl_header->nSection * sizeof(FL_SECTION_INF));
return 1;
}
void font_release_sections()
{
if (_fl_header.pSection != 0)
{
free(_fl_header.pSection);
_fl_header.pSection = 0;
}
}
DWORD read_char_info_unicode(WORD wCode)
{
DWORD offset;
int i;
DWORD dwCharInfo = 0;
for (i = 0; i < _fl_header.nSection; i++)
{
if (wCode >= _fl_header.pSection[i].First && wCode <= _fl_header.pSection[i].Last)
break;
}
if (i >= _fl_header.nSection)
return 0;
offset = _fl_header.pSection[i].OffAddr + FONT_INDEX_TAB_SIZE * (wCode - _fl_header.pSection[i].First);
font_file_seek(offset);
font_file_read(&dwCharInfo, sizeof(DWORD));
return dwCharInfo;
}
static int ReadFontHeader(PFL_HEADER pfl_header)
{
font_file_read(pfl_header, sizeof(FL_HEADER) - 4);
//检测表示头
if ((_fl_header.magic[0] != 'U' && _fl_header.magic[0] != 'M')
|| _fl_header.magic[1] != 'F' || _fl_header.magic[2] != 'L')
{
printf("Cann't support file format!\n");
return 0;
}
if ('U' == pfl_header->magic[0]) //unicode 编码
{
return font_read_sections();
}
return 1;
}
static int OpenFontFile(char* pFontFile)
{
if (!font_file_open(pFontFile))
{
printf("Cann't open : %s\n", pFontFile);
return 0;
}
return 1;
}
/***************************************************************
功能: 初始化字体。 即打开字体文件,且读取信息头。
参数: pFontFile--字库文件名
***************************************************************/
int font_init(char* pFontFile)
{
memset(&_fl_header, 0, sizeof(FL_HEADER));
if (OpenFontFile(pFontFile))
return ReadFontHeader(&_fl_header);
else
return 0;
}
void font_exit()
{
if ('U' == _fl_header.magic[0]) //unicode 编码
font_release_sections();
font_file_close();
}
BYTE font_get_ysize()
{
return _fl_header.YSize;
}
/********************************************************************
功能: 获取当前字符的像素宽度, 且将索引信息存入一个全局变量:g_dwCharInfo。
根据索引信息,即同时能获取当前字符的点阵信息的起始地址。
参数: wCode -- 当字库为unicode编码格式时,则将wCode当unicode编码处理。
否则当内码(MBCS)处理。
********************************************************************/
int font_read_char_distX(WORD wCode)
{
if ('U' == _fl_header.magic[0]) // unicode 编码
g_dwCharInfo = read_char_info_unicode(wCode);
return GET_FONT_WIDTH(g_dwCharInfo);
}
/**********************************************************************
功能: 获取点阵信息
参数: wCode 在这里预留,主要是因为前面有保存一个全局的g_dwCharInfo,也就知道了该字符的相应信息(宽度+点阵信息的起始地址)。
fontArray 存放点阵信息
bytesPerLine 每一行占多少个字节。
**********************************************************************/
int font_read_char_dot_array(WORD wCode, BYTE* fontArray, WORD* bytesPerLine)
{
*bytesPerLine = (WORD)((GET_FONT_WIDTH(g_dwCharInfo)) + 7) / PIXELS_PER_BYTE;
if (g_dwCharInfo > 0)
{
DWORD nDataLen = *bytesPerLine * _fl_header.YSize;
DWORD dwOffset = GET_FONT_OFFADDR(g_dwCharInfo); //获取字符点阵的地址信息(低26位)
font_file_seek(dwOffset);
font_file_read(fontArray, nDataLen);
return 1;
}
return 0;
}
void display_char(int nYSize, int nBytesPerLine, unsigned char* pFontData)
{
int i, j;
printf("bytesPerLine = %d\n", nBytesPerLine);
for (i = 0; i < nYSize; i++)
{
for (j = 0; j < nBytesPerLine; j++)
{
#if(DISPLAY_FONT_MODE)
printf(strGlyphTab[pFontData[i * nBytesPerLine + j]]);
#else //显示点阵数据
printf("%x, ", pFontData[i * nBytesPerLine + j]);
#endif
}
printf("\n");
}
}
int main()
{
std::cout << "Hello World!\n";
#define MAX_FONT_SIZE 64
#define MODE_DEBUG 0
char* pfontfile = (char *)"arial_U16.bin";
WORD wCode = 97;
_fl_header.pSection;
if (font_init(pfontfile))
{
int i = 0, j = 0;
int nWidth = 0;
WORD bytesPerLine = 0;
BYTE buf[MAX_FONT_SIZE * (MAX_FONT_SIZE / PIXELS_PER_BYTE)];
nWidth = font_read_char_distX(wCode);
printf("wCode = 0x%x\n", wCode);
printf("nWidth = %d\n", nWidth);
if (font_read_char_dot_array(wCode, buf, &bytesPerLine))
display_char(font_get_ysize(), bytesPerLine, buf);
font_exit();
}
return 0;
}