linux应用程序_1_文本浏览器_5_draw

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


发布了71 篇原创文章 · 获赞 4 · 访问量 7221

猜你喜欢

转载自blog.csdn.net/floatinglong/article/details/86635097