一、点阵子模块介绍
1) 点阵子模块的文件组成:
|--------fonts
|--------------fonts_manager.c
|--------------ascii_font.c
|--------------gbk_font.c
|--------------freetype_cont.c
|-------include
|-------------fonts_manager.h
|-------------config.h
2) 点阵子模块框架图

注解: 点阵子模块与显示子模块,以及后面要将的编码子模块,框架都是一样的。
这里只展示出各文件的联系与所处层次关系,具体实现看下面源码。
二、源码实现与编译检查
贴出代码前,需澄清的事,以下代码我都没注释,一方面代码不难理解,难理解的在于位图坐标与LCD坐标
转换那里,这点下面会有图解。另一方面,我懒 (好吧,这才是主要原因,哈哈,原谅我,有不清楚的可以提出呀)
fonts_manager.h 文件
#ifndef _FONTS_MANAGER_H
#define _FONTS_MANAGER_H
typedef struct FontBitMap{
int iXLeft;
int iYTop;
int iXMax;
int iYMax;
int iBpp;
int iPitch;
int iCurOriginX;
int iCurOriginY;
int iNextOriginX;
int iNextOriginY;
unsigned char* pucBuffer;
}T_FontBitMap, *PT_FontBitMap;
typedef struct FontOpr{
char* name;
int (*FontInit)(char* pcFontFile, unsigned int dwFontSize);
int (*GetFontBitmap)(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
struct FontOpr* ptNext;
}T_FontOpr, *PT_FontOpr;
int RegisterFontOpr(PT_FontOpr ptFontOpr);
void ShowFontOpr(void);
int FontsInit(void);
int ASCIIInit(void);
int GBKInit(void);
int FreeTypeInit(void);
PT_FontOpr GetFontOpr(char *pcName);
#endif
fonts_manager.c 文件
#include <config.h>
#include <fonts_manager.h>
#include <string.h>
static PT_FontOpr g_ptFontOprHead = NULL;
int RegisterFontOpr(PT_FontOpr ptFontOpr)
{
PT_FontOpr ptTmp;
if(!g_ptFontOprHead)
{
g_ptFontOprHead->ptNext = ptFontOpr;
ptFontOpr->ptNext = NULL;
}
else
{
ptTmp = g_ptFontOprHead;
while(ptTmp->ptNext)
{
ptTmp = ptTmp->ptNext;
}
ptTmp->ptNext = ptFontOpr;
ptFontOpr->ptNext = NULL;
}
return 0;
}
void ShowFontOpr(void)
{
int i = 0;
PT_FontOpr ptTmp = g_ptFontOprHead;
while (ptTmp)
{
printf("%02d %s\n", i++, ptTmp->name);
ptTmp = ptTmp->ptNext;
}
}
PT_FontOpr GetFontOpr(char* pcName)
{
PT_FontOpr ptTmp = g_ptFontOprHead;
while(ptTmp)
{
if(strcmp(ptTmp->name, pcName) == 0)
{
return ptTmp;
}
ptTmp = ptTmp->ptNext;
}
return NULL;
}
int FontsInit(void)
{
int iError;
iError = ASCIIInit();
if(iError)
{
DBG_PRINTF("ASCIIInit error!\n");
return -1;
}
iError = GBKInit();
if(iError)
{
DBG_PRINTF("GBKInit error!\n");
return -1;
}
iError = FreeTypeInit();
if (iError)
{
DBG_PRINTF("FreeTypeInit error!\n");
return -1;
}
return 0;
}
下面是底层文件,从简到难依次贴出。
ascii_font.c 文件
#include <config.h>
#include <fonts_manager.h>
#define FONTDATAMAX 4096
static int ASCIIFontInit(char *pcFontFile, unsigned int dwFontSize);
static int ASCIIGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
static T_FontOpr g_tASCIIFontOpr = {
.name = "ascii",
.FontInit = ASCIIFontInit,
.GetFontBitmap = ASCIIGetFontBitmap,
};
* }
*/
static int ASCIIFontInit(char * pcFontFile, unsigned int dwFontSize)
{
if(dwFontSize != 16)
{
DBG_PRINTF("ASCII can't support %d font size \n",dwFontSize);
return -1;
}
return 0;
}
static int ASCIIGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
int iPenX = ptFontBitMap->iCurOriginX;
int iPenY = ptFontBitMap->iCurOriginY;
if(dwCode > (unsigned int)0x80)
{
DBG_PRINTF("ASCII don't support this code : 0x%x\n",dwCode);
return -1;
}
ptFontBitMap->iXLeft = iPenX;
ptFontBitMap->iYTop = iPenY - 16;
ptFontBitMap->iXMax = iPenX + 8;
ptFontBitMap->iYMax = iPenY;
ptFontBitMap->iBpp = 1;
ptFontBitMap->iPitch = 1;
ptFontBitMap->pucBuffer = (unsigned char*)&fontdata_8x16[dwCode * 16];
ptFontBitMap->iNextOriginX = iPenX + 8;
ptFontBitMap->iNextOriginY = iPenY;
return 0;
}
int ASCIIInit(void)
{
return RegisterFontOpr(&g_tASCIIFontOpr);
}
gbk_font.c 文件
#include <config.h>
#include <fonts_manager.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
static int GBKFontInit(char *pcFontFile, unsigned int dwFontSize);
static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
static T_FontOpr g_tGBKFontOpr = {
.name = "gbk",
.FontInit = GBKFontInit,
.GetFontBitmap = GBKGetFontBitmap,
};
static int g_iFdHZK;
static unsigned char* g_pucHZKMem;
static unsigned char* g_pucHZKMemEnd;
static int GBKFontInit(char * pcFontFile, unsigned int dwFontSize)
{
struct stat tStat;
if(16 != dwFontSize)
{
DBG_PRINTF("GBK can't support %d fontsize\n", dwFontSize);
return -1;
}
g_iFdHZK = open(pcFontFile, O_RDONLY);
if(g_iFdHZK < 0)
{
DBG_PRINTF("can't open %s\n", pcFontFile);
return -1;
}
if(fstat(g_iFdHZK, &tStat))
{
DBG_PRINTF("can't get fstat\n");
return -1;
}
g_pucHZKMem = (unsigned char*)mmap(NULL, tStat.st_size, PROT_READ, MAP_SHARED, g_iFdHZK, 0);
if (g_pucHZKMem == (unsigned char *)-1)
{
DBG_PRINTF("can't mmap for hzk16\n");
return -1;
}
g_pucHZKMemEnd = g_pucHZKMem + tStat.st_size;
return 0;
}
static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
int iArea;
int iWhere;
int iPenX = ptFontBitMap->iCurOriginX;
int iPenY = ptFontBitMap->iCurOriginY;
DBG_PRINTF("%s %s %d\n",__FILE__, __FUNCTION__,__LINE__);
if(dwCode & 0xffff0000)
{
DBG_PRINTF("GBK don't support this code: 0x%x\n", dwCode);
return -1;
}
iArea = (int)(dwCode & 0xff) - 0xA1;
iWhere = (int)((dwCode >> 8) & 0xff) - 0xA1;
if ((iArea < 0) || (iWhere < 0))
{
DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return -1;
}
ptFontBitMap->iXLeft = iPenX;
ptFontBitMap->iYTop = iPenY - 16;
ptFontBitMap->iXMax = iPenX + 16;
ptFontBitMap->iYMax = iPenY;
ptFontBitMap->iBpp = 1;
ptFontBitMap->iPitch = 2;
ptFontBitMap->pucBuffer = g_pucHZKMem + (iArea * 94 + iWhere)*32;
if(ptFontBitMap->pucBuffer >= g_pucHZKMemEnd)
{
return -1;
}
DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
return 0;
}
int GBKInit(void)
{
return RegisterFontOpr(&g_tGBKFontOpr);
}
freetype_font.c 文件
#include <config.h>
#include <fonts_manager.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
static int FreeTypeFontInit(char *pcFontFile, unsigned int dwFontSize);
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap);
static T_FontOpr g_tFreeTypeOpr = {
.name = "freetype",
.FontInit = FreeTypeFontInit,
.GetFontBitmap = FreeTypeGetFontBitmap,
};
static FT_Library g_tLibrary;
static FT_Face g_tFace;
static FT_GlyphSlot g_tSlot;
static int FreeTypeFontInit(char * pcFontFile, unsigned int dwFontSize)
{
int iError;
iError = FT_Init_FreeType(&g_tLibrary);
if (iError)
{
DBG_PRINTF("FT_Init_FreeType failed\n");
return -1;
}
iError = FT_New_Face(g_tLibrary, pcFontFile, 0, &g_tFace);
if (iError)
{
DBG_PRINTF("FT_Init_FreeType failed\n");
return -1;
}
g_tSlot = g_tFace->glyph;
iError = FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
if (iError)
{
DBG_PRINTF("FT_Set_Pixel_Sizes failed : %d\n", dwFontSize);
return -1;
}
return 0;
}
static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap)
{
int iError;
int iPenX = ptFontBitMap->iCurOriginX;
int iPenY = ptFontBitMap->iCurOriginY;
iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
if (iError)
{
DBG_PRINTF("FT_Load_Char error for code : 0x%x\n", dwCode);
return -1;
}
ptFontBitMap->iXLeft = iPenX + g_tSlot->bitmap_left;
ptFontBitMap->iYTop = iPenY - g_tSlot->bitmap_top;
ptFontBitMap->iXMax = ptFontBitMap->iXLeft + g_tSlot->bitmap.width;
ptFontBitMap->iYMax = ptFontBitMap->iYTop + g_tSlot->bitmap.rows;
ptFontBitMap->iBpp = 1;
ptFontBitMap->iPitch = g_tSlot->bitmap.pitch;
ptFontBitMap->pucBuffer = g_tSlot->bitmap.buffer;
ptFontBitMap->iNextOriginX = iPenX + g_tSlot->advance.x / 64;
ptFontBitMap->iNextOriginY = iPenY;
return 0;
}
int FreeTypeInit(void)
{
return RegisterFontOpr(&g_tFreeTypeOpr);
}
接着,编译检查下有无手写或语法错误

三、位图坐标与LCD坐标转换
对于FreeType获取的位图,使用的是笛卡尔坐标(从小到大学数学一直在使用的坐标 : )
而LCD的坐标系原点在左上角,看下图
