c语言之guitool制作的点阵显示

效果:
image
源码:

// 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;
}

posted @ 2025-08-26 16:56  我不是萧海哇~~~  阅读(8)  评论(0)    收藏  举报