电子书---点阵子模块

一、点阵子模块介绍
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_H */
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,
};
/*
 * 省略 8x16 的点阵数组,太占篇幅了,或者分离到一个文件  extern 声明即可
 * static const unsigned char fontdata_8x16[FONTDATAMAX] = {
 *   /* ... */
 * }
 */
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);
    /* error handling omitted */
    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的坐标系原点在左上角,看下图

位图坐标与LCD坐标转换图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值