linux应用程序_1_文本浏览器_5_draw
在draw.c中主要完成以下工作:
1、使用各子目录提供的接口,解析字符、获取位图、显示位图等
2、翻页控制
抽象页面结构体依据:
1、应具有双向链表,与上页、下页建立链接
2、应具有页码、当前页的缓存指针在文件的位置
页面结构体:
typedef struct PageDesc{
int iPage;
unsigned char *pucCurPosAtFile;
struct PageDesc *ptPrePage;
struct PageDesc *ptNextPage;
}T_PageDesc, *PT_PageDesc;
打开文本:
打开文本文件
分配缓存
获取文本文件信息(首地址、文件大小)
解析文本标识符,选择编码结构体
int OpenTextFile(char *pcFileName)
{
struct stat tStat;
g_iFd = open(pcFileName, O_RDONLY);
if(g_iFd < 0)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
fstat(g_iFd, &tStat);
g_pucFileStart = mmap(NULL, tStat.st_size, PROT_READ, MAP_SHARED, g_iFd, 0);
if(g_pucFileStart == (unsigned char *)-1)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -2;
}
g_pucFileEnd = g_pucFileStart + tStat.st_size;
g_ptEncodingOpr = SelectEncodingOpr(g_pucFileStart);
if(!g_ptEncodingOpr)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -3;
}
return 0;
}
设置字库信息
遍历被选中的编码结构体中所支持的字库,从中去除无法使用的字库,设置字体大小
int SetFontsDetail(char *pcHzkFile, char *pcFreetypeFile, int iFontSize)
{
PT_FontOpr ptFontOprTmp;
PT_FontOpr ptFontOpr = g_ptEncodingOpr->ptFontOprSupportHead;
int iError = 0, iRet = 1;
g_iFontSize = iFontSize;
DBG_PRINT("%s support\r\n",g_ptEncodingOpr->pcName);
while(ptFontOpr)
{
if(strcmp(ptFontOpr->pcName, "ascii") == 0)
{
iError = ptFontOpr->FontInit(NULL, iFontSize);
if(iError)
DBG_PRINT("%s can't support %s\r\n", g_ptEncodingOpr->pcName, "ascii");
}
else if(strcmp(ptFontOpr->pcName, "gbk") == 0)
{
iError = ptFontOpr->FontInit(pcHzkFile, iFontSize);
if(iError)
DBG_PRINT("%s can't support %s\r\n", g_ptEncodingOpr->pcName, "gbk");
}
else
{
iError = ptFontOpr->FontInit(pcFreetypeFile, iFontSize);
if(iError)
DBG_PRINT("%s can't support %s\r\n", g_ptEncodingOpr->pcName, "freetype");
}
ptFontOprTmp = ptFontOpr->ptNext;
if(!iError)
{
iRet = 0;
}
else
{
DBG_PRINT("Need to Del at SetFontsDetail : %s\r\n",ptFontOpr->pcName);
DelFontOprFrmEncoding(g_ptEncodingOpr, ptFontOpr);
}
ptFontOpr = ptFontOprTmp;
}
return iRet;
}
选中显示设备
int SelectAndInitDisplay(char *pcName)
{
int iError;
g_ptDispOpr = GetDispOpr(pcName);
if(!g_ptDispOpr)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = g_ptDispOpr->DeviceInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -2;
}
return 0;
}
位置变换:
将位图位置信息转换到显示设备上
static int RelocateFontPos(PT_BitMap ptBitMap)
{
int iY;
int iDltX, iDltY;
if(ptBitMap->iYMax > g_ptDispOpr->iYres)
return -1;
if(ptBitMap->iXMax > g_ptDispOpr->iXres)
{
iY = IncY(ptBitMap->iCurOriginY);
if(!iY)
{
return -1;
}
iDltX = 0 - ptBitMap->iCurOriginX;
iDltY = iY - ptBitMap->iCurOriginY;
ptBitMap->iCurOriginX += iDltX;
ptBitMap->iCurOriginY += iDltY;
ptBitMap->iNextOriginX += iDltX;
ptBitMap->iNextOriginY += iDltY;
ptBitMap->iXLeft += iDltX;
ptBitMap->iYTop += iDltY;
ptBitMap->iXMax += iDltX;
ptBitMap->iYMax += iDltY;
}
return 0;
}
显示一个字符的位图
static int ReallyShowOneCode(PT_BitMap ptBitMap)
{
int iX, iY;
int iBit,iCnt;
unsigned char cVal = 7;
if(ptBitMap->iBpp == 1)
{
for(iY = ptBitMap->iYTop;iY < ptBitMap->iYMax;iY++)
{
iCnt = (iY - ptBitMap->iYTop) * ptBitMap->iPitch;
for(iX = ptBitMap->iXLeft, iBit = 7;iX < ptBitMap->iXMax;iX++)
{
if(iBit == 7)
cVal = ptBitMap->pucBuf[iCnt++];
if(cVal & (1<<iBit))
g_ptDispOpr->ShowPixel(iX, iY, COLOR_FOREGROUND);
else
;// g_ptDispOpr->ShowPixel(iX, iY, COLOR_BACKGROUND);
if((--iBit) < 0)
{
iBit = 7;
}
}
}
}
else if(ptBitMap->iBpp == 8)
{
for(iY = ptBitMap->iYTop;iY < ptBitMap->iYMax;iY++)
for(iX = ptBitMap->iXLeft;iX < ptBitMap->iXMax;iX++)
g_ptDispOpr->ShowPixel(iX, iY, COLOR_FOREGROUND);
}
else
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
DBG_PRINT("don't suppot bpp %d \r\n", ptBitMap->iBpp);
return -1;
}
return 0;
}
根据传入的起始地址显示一页
获取字符信息(字符编码、字节数)
从被选中的编码中遍历字库,选择支持该字符的字库
根据字符信息从字库获取位图
调用显示设备,显示位图
static int ShowOnePage(unsigned char *pucNowPos)
{
unsigned int dwCodeLen;
unsigned int dwCode;
int iHasGetCode = 0, iHasCleanSrceen = 1;
PT_FontOpr ptFontOprTmp;
int iError;
unsigned char *pucBufStart = pucNowPos;
T_BitMap tBitMap;
tBitMap.iCurOriginX = 0;
tBitMap.iCurOriginY = g_iFontSize;
while(1)
{
dwCode = 0;
dwCodeLen = g_ptEncodingOpr->GetCode(pucBufStart, g_pucFileEnd, &dwCode);
if(!dwCodeLen)
{
if(iHasGetCode)
{
printf("Page :%03d\r\n",g_ptPageDesc->iPage);
return 0;
}
else
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
}
pucBufStart += dwCodeLen;
iHasGetCode = 1;
if(dwCode == '\r')
{
continue;
}
else if(dwCode == '\t')
{
dwCode = ' ';
}
else if(dwCode == '\n')
{
g_pucNextPosAtFile = pucBufStart;
tBitMap.iCurOriginX = 0;
tBitMap.iCurOriginY = IncY(tBitMap.iCurOriginY);
if(tBitMap.iCurOriginY == 0)
{
printf("Page :%03d\r\n",g_ptPageDesc->iPage);
return 0;
}
continue;
}
ptFontOprTmp = g_ptEncodingOpr->ptFontOprSupportHead;
while(ptFontOprTmp)
{
iError = ptFontOprTmp->GetBitMap(dwCode, &tBitMap);
if(iError)
{
ptFontOprTmp = ptFontOprTmp->ptNext;
continue;
}
iError = RelocateFontPos(&tBitMap);
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return 0;
}
if(iHasCleanSrceen)
{
g_ptDispOpr->CleanScreen(COLOR_BACKGROUND);
iHasCleanSrceen = 0;
}
iError = ReallyShowOneCode(&tBitMap);
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
tBitMap.iCurOriginX = tBitMap.iNextOriginX;
tBitMap.iCurOriginY = tBitMap.iNextOriginY;
g_pucNextPosAtFile = pucBufStart;
break;
}
}
return 0;
}
总的初始化
调用显示设备、字库、编码的初始化函数
int DrawInit(void)
{
int iError;
iError = DisplaysInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = FontsInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = EncodingsInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
return 0;
}
完整代码:
draw.h
#ifndef _DRAW_H
#define _DRAW_H
#define COLOR_BACKGROUND 0xE7DBB5
#define COLOR_FOREGROUND 0x514438
int OpenTextFile(char *pucFileName);
int SetFontsDetail(char *pcHzkFile, char *pcFreetypeFile, int iFontSize);
int SelectAndInitDisplay(char *pcName);
int ShowNextPage(void);
int ShowPrePage(void);
int DrawInit(void);
#endif
draw.c
#include <config.h>
//#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <encoding_manager.h>
#include <fonts_manager.h>
#include <disp_manager.h>
#include <fcntl.h>
#include <string.h>
#include <draw.h>
typedef struct PageDesc{
int iPage;
unsigned char *pucCurPosAtFile;
struct PageDesc *ptPrePage;
struct PageDesc *ptNextPage;
}T_PageDesc, *PT_PageDesc;
static PT_PageDesc g_ptPageDesc;
static unsigned char *g_pucNextPosAtFile;
static int g_iFd;
static unsigned char *g_pucFileStart;
static unsigned char *g_pucFileEnd;
static PT_EncodingOpr g_ptEncodingOpr;
static PT_DispOpr g_ptDispOpr;
static int g_iFontSize;
int OpenTextFile(char *pcFileName)
{
struct stat tStat;
g_iFd = open(pcFileName, O_RDONLY);
if(g_iFd < 0)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
fstat(g_iFd, &tStat);
g_pucFileStart = mmap(NULL, tStat.st_size, PROT_READ, MAP_SHARED, g_iFd, 0);
if(g_pucFileStart == (unsigned char *)-1)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -2;
}
g_pucFileEnd = g_pucFileStart + tStat.st_size;
g_ptEncodingOpr = SelectEncodingOpr(g_pucFileStart);
if(!g_ptEncodingOpr)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -3;
}
return 0;
}
int SetFontsDetail(char *pcHzkFile, char *pcFreetypeFile, int iFontSize)
{
PT_FontOpr ptFontOprTmp;
PT_FontOpr ptFontOpr = g_ptEncodingOpr->ptFontOprSupportHead;
int iError = 0, iRet = 1;
g_iFontSize = iFontSize;
DBG_PRINT("%s support\r\n",g_ptEncodingOpr->pcName);
while(ptFontOpr)
{
if(strcmp(ptFontOpr->pcName, "ascii") == 0)
{
iError = ptFontOpr->FontInit(NULL, iFontSize);
if(iError)
DBG_PRINT("%s can't support %s\r\n", g_ptEncodingOpr->pcName, "ascii");
}
else if(strcmp(ptFontOpr->pcName, "gbk") == 0)
{
iError = ptFontOpr->FontInit(pcHzkFile, iFontSize);
if(iError)
DBG_PRINT("%s can't support %s\r\n", g_ptEncodingOpr->pcName, "gbk");
}
else
{
iError = ptFontOpr->FontInit(pcFreetypeFile, iFontSize);
if(iError)
DBG_PRINT("%s can't support %s\r\n", g_ptEncodingOpr->pcName, "freetype");
}
ptFontOprTmp = ptFontOpr->ptNext;
if(!iError)
{
iRet = 0;
}
else
{
DBG_PRINT("Need to Del at SetFontsDetail : %s\r\n",ptFontOpr->pcName);
DelFontOprFrmEncoding(g_ptEncodingOpr, ptFontOpr);
}
ptFontOpr = ptFontOprTmp;
}
return iRet;
}
int SelectAndInitDisplay(char *pcName)
{
int iError;
g_ptDispOpr = GetDispOpr(pcName);
if(!g_ptDispOpr)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = g_ptDispOpr->DeviceInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -2;
}
return 0;
}
static int IncY(int iY)
{
if(iY + g_iFontSize >= g_ptDispOpr->iYres)
return 0;
return (iY + g_iFontSize);
}
static int RelocateFontPos(PT_BitMap ptBitMap)
{
int iY;
int iDltX, iDltY;
if(ptBitMap->iYMax > g_ptDispOpr->iYres)
return -1;
if(ptBitMap->iXMax > g_ptDispOpr->iXres)
{
iY = IncY(ptBitMap->iCurOriginY);
if(!iY)
{
return -1;
}
iDltX = 0 - ptBitMap->iCurOriginX;
iDltY = iY - ptBitMap->iCurOriginY;
ptBitMap->iCurOriginX += iDltX;
ptBitMap->iCurOriginY += iDltY;
ptBitMap->iNextOriginX += iDltX;
ptBitMap->iNextOriginY += iDltY;
ptBitMap->iXLeft += iDltX;
ptBitMap->iYTop += iDltY;
ptBitMap->iXMax += iDltX;
ptBitMap->iYMax += iDltY;
}
return 0;
}
static int ReallyShowOneCode(PT_BitMap ptBitMap)
{
int iX, iY;
int iBit,iCnt;
unsigned char cVal = 7;
if(ptBitMap->iBpp == 1)
{
for(iY = ptBitMap->iYTop;iY < ptBitMap->iYMax;iY++)
{
iCnt = (iY - ptBitMap->iYTop) * ptBitMap->iPitch;
for(iX = ptBitMap->iXLeft, iBit = 7;iX < ptBitMap->iXMax;iX++)
{
if(iBit == 7)
cVal = ptBitMap->pucBuf[iCnt++];
if(cVal & (1<<iBit))
g_ptDispOpr->ShowPixel(iX, iY, COLOR_FOREGROUND);
else
;// g_ptDispOpr->ShowPixel(iX, iY, COLOR_BACKGROUND);
if((--iBit) < 0)
{
iBit = 7;
}
}
}
}
else if(ptBitMap->iBpp == 8)
{
for(iY = ptBitMap->iYTop;iY < ptBitMap->iYMax;iY++)
for(iX = ptBitMap->iXLeft;iX < ptBitMap->iXMax;iX++)
g_ptDispOpr->ShowPixel(iX, iY, COLOR_FOREGROUND);
}
else
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
DBG_PRINT("don't suppot bpp %d \r\n", ptBitMap->iBpp);
return -1;
}
return 0;
}
static int ShowOnePage(unsigned char *pucNowPos)
{
unsigned int dwCodeLen;
unsigned int dwCode;
int iHasGetCode = 0, iHasCleanSrceen = 1;
PT_FontOpr ptFontOprTmp;
int iError;
unsigned char *pucBufStart = pucNowPos;
T_BitMap tBitMap;
tBitMap.iCurOriginX = 0;
tBitMap.iCurOriginY = g_iFontSize;
while(1)
{
dwCode = 0;
dwCodeLen = g_ptEncodingOpr->GetCode(pucBufStart, g_pucFileEnd, &dwCode);
if(!dwCodeLen)
{
if(iHasGetCode)
{
printf("Page :%03d\r\n",g_ptPageDesc->iPage);
return 0;
}
else
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
}
pucBufStart += dwCodeLen;
iHasGetCode = 1;
if(dwCode == '\r')
{
continue;
}
else if(dwCode == '\t')
{
dwCode = ' ';
}
else if(dwCode == '\n')
{
g_pucNextPosAtFile = pucBufStart;
tBitMap.iCurOriginX = 0;
tBitMap.iCurOriginY = IncY(tBitMap.iCurOriginY);
if(tBitMap.iCurOriginY == 0)
{
printf("Page :%03d\r\n",g_ptPageDesc->iPage);
return 0;
}
continue;
}
ptFontOprTmp = g_ptEncodingOpr->ptFontOprSupportHead;
while(ptFontOprTmp)
{
iError = ptFontOprTmp->GetBitMap(dwCode, &tBitMap);
if(iError)
{
ptFontOprTmp = ptFontOprTmp->ptNext;
continue;
}
iError = RelocateFontPos(&tBitMap);
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return 0;
}
if(iHasCleanSrceen)
{
g_ptDispOpr->CleanScreen(COLOR_BACKGROUND);
iHasCleanSrceen = 0;
}
iError = ReallyShowOneCode(&tBitMap);
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
tBitMap.iCurOriginX = tBitMap.iNextOriginX;
tBitMap.iCurOriginY = tBitMap.iNextOriginY;
g_pucNextPosAtFile = pucBufStart;
break;
}
}
return 0;
}
int ShowNextPage(void)
{
int iError;
PT_PageDesc ptOnePage;
if(!g_ptPageDesc)
{
g_ptPageDesc = malloc(sizeof(T_PageDesc));
if(!g_ptPageDesc)
return -1;
g_ptPageDesc->iPage = 1;
g_ptPageDesc->ptNextPage = NULL;
g_ptPageDesc->ptPrePage = NULL;
g_ptPageDesc->pucCurPosAtFile = g_pucFileStart + g_ptEncodingOpr->iHeadLen;
}
else
{
if(g_pucNextPosAtFile == g_pucFileEnd)
{
return 0;
}
if(!(g_ptPageDesc->ptNextPage))
{
ptOnePage = malloc(sizeof(T_PageDesc));
if(!ptOnePage)
return -1;
ptOnePage->ptNextPage = NULL;
ptOnePage->pucCurPosAtFile = g_pucNextPosAtFile;
ptOnePage->iPage = g_ptPageDesc->iPage + 1;
g_ptPageDesc->ptNextPage = ptOnePage;
ptOnePage->ptPrePage = g_ptPageDesc;
g_ptPageDesc = ptOnePage;
}
else
{
g_ptPageDesc = g_ptPageDesc->ptNextPage;
}
}
iError = ShowOnePage(g_ptPageDesc->pucCurPosAtFile);
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
return 0;
}
int ShowPrePage(void)
{
int iError;
if(!g_ptPageDesc || !g_ptPageDesc->ptPrePage)
{
return -1;
}
g_ptPageDesc = g_ptPageDesc->ptPrePage;
iError = ShowOnePage(g_ptPageDesc->pucCurPosAtFile);
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
return 0;
}
int DrawInit(void)
{
int iError;
iError = DisplaysInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = FontsInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
iError = EncodingsInit();
if(iError)
{
DBG_PRINT("Error at %s,%d\r\n", __FILE__, __LINE__);
return -1;
}
return 0;
}