/* Display.c
*/
#include "display.h"
/*
x:0--DISPLAY_SCREEN_SIZE_WIDTH-1
y:0--DISPLAY_SCREEN_SIZE_HEIGHT-1
*/
#define display_screen_valid( x, y ) \
( (x < DISPLAY_SCREEN_SIZE_WIDTH) && (y < DISPLAY_SCREEN_SIZE_HEIGHT) )
#define display_menu_valid( x, y ) \
( (x < DISPLAY_MENU_SIZE_WIDTH) && (y < DISPLAY_MENU_SIZE_HEIGHT) )
#define display_image_menu_valid( x, y ) \
( (x < DISPLAY_IMAGE_MENU_SIZE_WIDTH) && (y < DISPLAY_IMAGE_MENU_SIZE_HEIGHT) )
#define display_screen_width_valid(x) \
( x < DISPLAY_SCREEN_SIZE_WIDTH )
#define display_screen_height_valid(y) \
( y < DISPLAY_SCREEN_SIZE_HEIGHT )
/* Set a specific bit to 1 (if it's already been 1,
then don't care) (bit_pos 0--7 from left to right) */
BOOL SetBit(unsigned char* pU8,int bit_pos){
if(bit_pos>=0 && bit_pos<8 && pU8){
(*pU8)|=(1<<(7-bit_pos));
return TRUE;
}
return FALSE;
}
/* Set a whole byte with pData,If there're some bits
having already been 1,they won't be changed */
BOOL SetByte(unsigned char* pU8,const unsigned char* pData){
if(pU8 && pData){
*pU8=*pData;
return TRUE;
}
else
return FALSE;
}
BOOL GetData(unsigned char* pU8,int data_pos,
DISPLAY_COLOR_T* pColor){
if(data_pos>=0 && data_pos<DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL
&& pU8 && pColor){
*pColor=(DISPLAY_COLOR_T)*pU8>>(8-(data_pos+1)*DISPLAY_BIT_PER_PIXEL);
*pColor&=(int)DISPLAY_ADJUST_NUMBER;
return TRUE;
}
return FALSE;
}
/* Set a specific data_pos to the data given by color
*/
BOOL SetData(unsigned char* pU8,int data_pos,
DISPLAY_COLOR_T color){
if(data_pos>=0 && data_pos<DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL
&& pU8){
(*pU8)&=~((unsigned char)DISPLAY_ADJUST_NUMBER<<(8-(data_pos+1)*DISPLAY_BIT_PER_PIXEL));
(*pU8)|=(unsigned char)color<<(8-(data_pos+1)*DISPLAY_BIT_PER_PIXEL);
return TRUE;
}
return FALSE;
}
BOOL SnapShot(DISPLAY_BUFFER Data){
unsigned int i=0;
if(Data){
for(;i<64*DISPLAY_BYTE_PER_LINE;i++)
Data[i]=Buf[i];
return TRUE;
}
else
return FALSE;
}
BOOL ClearScreen(){
/*Set the whole buffer to 0xff*/
unsigned char* pU8=(unsigned char*)Buf;
int i,j;
if(pU8){
for(i=0;i<DISPLAY_SCREEN_SIZE_HEIGHT;i++)
for(j=0;j<DISPLAY_BYTE_PER_LINE;j++){
*pU8=DISPLAY_DEFAULT_BG_COLOR;
pU8++;
}
return TRUE;
}
else
return FALSE;
}
BOOL ClearRectangle(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
DISPLAY_COORDINATE_T width,
DISPLAY_COORDINATE_T height){
DISPLAY_COORDINATE_T i,j;
if(display_screen_valid(x+width-1,y+height-1)){
for(i=y;i<y+height;i++)
for(j=x;j<x+width;j++){
DrawPoint(j,i,0xff);
}
return TRUE;
}
else
return FALSE;
}
BOOL SetRectangle(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
DISPLAY_COORDINATE_T width,
DISPLAY_COORDINATE_T height,
DISPLAY_BUFFER Data){
DISPLAY_COORDINATE_T i,j;
DISPLAY_COLOR_T color;
unsigned char* pSource=(unsigned char*)Data;
unsigned char* pDest=(unsigned char*)Buf;
int pixel_per_byte=(DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL);
int blk,pos;
if(display_screen_valid(x+width-1,y+height-1)){
for(i=y;i<y+height;i++)
for(j=x;j<x+width;j++){
blk=DISPLAY_BYTE_PER_LINE*i+j/pixel_per_byte;
pos=j%pixel_per_byte;
GetData(&pSource[blk],pos,&color);
SetData(&pDest[blk],pos,color);
}
return TRUE;
}
else
return FALSE;
}
unsigned char* GetPointHandler(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
int* pDataPos){
unsigned char* pU8=(unsigned char*)Buf;
int blk,pixel_per_byte=(DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL);
if(display_screen_valid(x, y) && pU8){
blk=DISPLAY_BYTE_PER_LINE*y+x/pixel_per_byte;
*pDataPos=x%pixel_per_byte;
return &pU8[blk];
}
else{
*pDataPos=0;
return NULL;
}
}
BOOL DrawPoint(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
DISPLAY_COLOR_T color){
unsigned char* pData;
int num=0;
if(pData=GetPointHandler(x,y,&num)){
if(SetData(pData,num,color))
return TRUE;
else
return FALSE;
}
else
return FALSE;
}
BOOL DrawVertical(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y0,
DISPLAY_COORDINATE_T y1,
DISPLAY_COLOR_T color){
DISPLAY_COORDINATE_T y;
if(display_screen_valid(x,y0) && display_screen_valid(x,y1) && Buf){
for(y=y0;y<y1;y++)
if(!DrawPoint(x,y,DISPLAY_DEFAULT_PEN_COLOR))
return FALSE;
return TRUE;
}
else
return FALSE;
}
BOOL DrawHorizontal(DISPLAY_COORDINATE_T x0,
DISPLAY_COORDINATE_T x1,
DISPLAY_COORDINATE_T y,
DISPLAY_COLOR_T color){
DISPLAY_COORDINATE_T x;
if(display_screen_valid(x0,y) && display_screen_valid(x1,y) && Buf){
for(x=x0;x<x1;x++)
if(!DrawPoint(x,y,DISPLAY_DEFAULT_PEN_COLOR))
return FALSE;
return TRUE;
}
else
return FALSE;
}
BOOL DrawLine(DISPLAY_COORDINATE_T x0,
DISPLAY_COORDINATE_T y0,
DISPLAY_COORDINATE_T x1,
DISPLAY_COORDINATE_T y1,
DISPLAY_COLOR_T color){
if(x0==x1 && Buf)
return DrawVertical(x0,y0,y1,DISPLAY_DEFAULT_PEN_COLOR);
if(y0==y1 && Buf)
return DrawHorizontal(x0,x1,y0,DISPLAY_DEFAULT_PEN_COLOR);
else
return FALSE;
}
BOOL DrawRectangle(DISPLAY_COORDINATE_T x0,
DISPLAY_COORDINATE_T y0,
DISPLAY_COORDINATE_T x1,
DISPLAY_COORDINATE_T y1,
DISPLAY_COLOR_T color){
DISPLAY_COORDINATE_T x,y;
if(display_screen_valid(x0,y0) && display_screen_valid(x0,y1)
&& display_screen_valid(x1,y0) && display_screen_valid(x1,y1) && Buf){
for(y=y0;y<=y1;y++)
for(x=x0;x<=x1;x++)
DrawPoint(x,y,color);
return TRUE;
}
else
return FALSE;
}
/*Draw Font Character*/
/*Notes: if MBCS, the code needs to be converted
with the formulor: 0xB0A1+94*(0xB9-0xB0)+(0xA6-0xA1)
(0xB9A6)
*/
BOOL DrawFontBitmap(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
unsigned long nFontID,
unsigned short nChar,
DISPLAY_COLOR_T color){
unsigned char* pFontData;
unsigned char* pU8;
unsigned long length;
int width,height;
int i,j,num,cnt,bit_pos=0;
SME_FONT_INFO_T fontInfo;
if(SmeGetFontBitmap(nFontID,nChar,&pFontData,&length) && Buf){
SmeGetFontInfo(nFontID,&fontInfo);
if(nChar<fontInfo.nStartChar || nChar>fontInfo.nEndChar)
return FALSE;
width=fontInfo.nWidth;
height=fontInfo.nHeight;
if(!display_screen_valid(x+width-1,y+height-1))
return FALSE;
pU8=(unsigned char*)Buf;
for(i=y;i<y+height;i++)
for(j=x;j<x+width;j++){
cnt=(i-y)*width+(j-x);
if((*pFontData << (bit_pos % DISPLAY_BIT_PER_BYTE)) & 0x80)
if(pU8=GetPointHandler(j,i,&num)){
SetData(pU8,num,color);
}
if((bit_pos % DISPLAY_BIT_PER_BYTE)==DISPLAY_BIT_PER_BYTE-1 || cnt%width==width-1){
pFontData++;
bit_pos=0;
}
else
bit_pos++;
}
return TRUE;
}
else
return FALSE;
}
BOOL DrawCharacterAt(int line,
int num,
unsigned long nFontID,
unsigned short nChar,
DISPLAY_COLOR_T color){
SME_FONT_INFO_T fontInfo;
DISPLAY_COORDINATE_T x,y;
int height,width;
SmeGetFontInfo(nFontID,&fontInfo);
height=fontInfo.nHeight;
width=fontInfo.nWidth;
x=(DISPLAY_COORDINATE_T)((num-1)*width);
y=(DISPLAY_COORDINATE_T)((line-1)*height)+4;
return DrawFontBitmap(x,y,nFontID,nChar,color);
}
BOOL DrawDigit(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
int digit,
DISPLAY_COLOR_T color){
if(digit>=0 && digit<=9)
return DrawFontBitmap(x,y,DEFAULT_DIGIT_FONT,(unsigned short)('0'+digit),color);
else
return FALSE;
}
BOOL DrawNumber(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
int num,
DISPLAY_COLOR_T color){
int width=GetFontWidth(DEFAULT_DIGIT_FONT);
int base=10,digit,pos=x;
while(num/base)
base*=10;
if(num<10){
DrawDigit(x,y,0,color);
x+=width;
}
while(base>=10){
num%=base;
base/=10;
digit=num/base;
DrawDigit(x,y,digit,color);
x+=width;
}
return TRUE;
}
int GetFontHeight(unsigned long nFontID){
SME_FONT_INFO_T fontInfo;
SmeGetFontInfo(nFontID,&fontInfo);
return fontInfo.nHeight;
}
int GetFontWidth(unsigned long nFontID){
SME_FONT_INFO_T fontInfo;
SmeGetFontInfo(nFontID,&fontInfo);
return fontInfo.nWidth;
}
/*Get the data of a string from its handler*/
const SME_CHAR* GetTextStr(unsigned long nRcId, unsigned char nLang){
SME_CHAR* pText;
if(SmeGetTextString(nRcId,nLang,&pText))
return pText;
else
return NULL;
}
/*Get the length of a string from its handler*/
int GetStrLen(const SME_CHAR* pText){
int len=0;
SME_CHAR* pFlag=(SME_CHAR*)pText;
if(!pText)
return 0;
while(pFlag && *pFlag){
len++;
pFlag++;
}
if(pText[0]>=0)
return len;
else
return len/2;
}
/*Get the data of a specific character in the string*/
unsigned short GetStrCh(const SME_CHAR* pText,int ch_pos){
unsigned char high,low;
if(ch_pos<GetStrLen(pText))
if(pText[0]>=0)/*ANSI*/
return pText[ch_pos];
else/*MBCS*/{
high=pText[ch_pos*2];
low=pText[ch_pos*2+1];
return 0xB0A1+94*(high-0xB0)+(low-0xA1);
}
else
return 0;
}
/*Draw text string to the screen*/
BOOL DrawTextStr(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
const SME_CHAR* pStr,
unsigned long nFontID,
DISPLAY_COLOR_T color){
SME_FONT_INFO_T fontInfo;
int width,size;
int j=x;
SME_CHAR* str=(SME_CHAR*)pStr;
SmeGetFontInfo(nFontID,&fontInfo);
width=fontInfo.nWidth;
if(Buf){
for(size=0;size<GetStrLen(pStr);size++){
if(!DrawFontBitmap(j,y,nFontID,GetStrCh(str,size),color))
break;
j+=width;
}
return TRUE;
}
else
return FALSE;
}
/*Draw a line of text string to the screen*/
/*Line:start from 1*/
BOOL DrawTextStrAt(int line,
int mode,
const SME_CHAR* pStr,
unsigned long nFontID,
DISPLAY_COLOR_T color){
SME_FONT_INFO_T fontInfo;
DISPLAY_COORDINATE_T x,y;
int height,width,length,margin;
SmeGetFontInfo(nFontID,&fontInfo);
height=fontInfo.nHeight;
width=fontInfo.nWidth;
length=GetStrLen(pStr);
margin=DISPLAY_TEXTAREA_SIZE_WIDTH-length*width;
switch(mode){
case MODE_LEFT:
x=0;
break;
case MODE_CENTER:
if(margin>0)
x=margin/2;
else
x=0;
break;
case MODE_RIGHT:
if(margin>0)
x=margin;
else
x=0;
break;
};
y=(DISPLAY_COORDINATE_T)((line-1)*height)+4;
return DrawTextStr(x,y,pStr,nFontID,color);
}
/* Get item_num,menu_pointer of nRcId */
int GetMenuData(unsigned long nRcId,int menu_pos,
POINTER_OF_MENU_DATA* pMenuData){
int i=0;
unsigned short num;
SmeGetMenuData(nRcId,&num,pMenuData);
for(;i<menu_pos;i++)
(*pMenuData)++;
return num;
}
/*pos ��1��specifying the initial position��2��return the last position been drawed
on the screen*/
BOOL DrawMenu(unsigned long nRcId,
unsigned char nLang,unsigned long nFontID,int* pPos,
DISPLAY_COLOR_T color){
int i,cnt=0,height=GetFontHeight(nFontID);
unsigned short num;
unsigned short minus='-',plus='+';
int sep=2;
SME_MENU_DATA_T* pData=NULL;
SmeGetMenuData(nRcId,&num,&pData);
if(!pPos || num<0 || *pPos>=num || *pPos<0 || !Buf)
return FALSE;
for(i=0;i<*pPos;i++)
pData++;
for(;i<num;i++){
if(display_menu_valid(15,(int)((i-*pPos+1)*height-1+3))){
if(pData->nSubMenuID>=0)
DrawFontBitmap(0,(int)((i-*pPos)*height+sep),0,plus,color);
else
DrawFontBitmap(0,(int)((i-*pPos)*height+sep),0,minus,color);
DrawTextStr(10,(int)((i-*pPos)*height+sep),GetTextStr(pData->nMenuTitleID,nLang),nFontID,color);
cnt++;
pData++;
sep++;
}
}
*pPos=(int)cnt;
return TRUE;
}
BOOL DrawImageMenu(unsigned long nMenuId,unsigned long nBitmapId,
unsigned char nLang,unsigned long nFontID,int pos,DISPLAY_COLOR_T color){
SME_MENU_DATA_T* pData=NULL;
int i;
unsigned short num;
SmeGetMenuData(nMenuId,&num,&pData);
if(!Buf || num<0 || pos>=num || pos<0)
return FALSE;
for(i=0;i<pos;i++)
pData++;
DrawBitmapAt(1,MODE_CENTER,nFontID,nBitmapId);
DrawTextStrAt(3,MODE_CENTER,GetTextStr(pData->nMenuTitleID,nLang),nFontID,color);
return TRUE;
}
/*Reverse the color of select aera*/
/*TURE:reverse , FALSE:cancel*/
BOOL DrawReverseArea(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
DISPLAY_COORDINATE_T width,
DISPLAY_COORDINATE_T height,
BOOL mode)
{
unsigned char* pDis=(unsigned char*)Buf;
int i,j,num,color;
if(pDis){
for(i=y;i<y+height;i++)
for(j=x;j<x+width;j++)
{
if(display_screen_valid(x+width-1,y+height-1))
if(pDis=GetPointHandler(j,i,&num)){
GetData(pDis,num,&color);
if(mode){
switch(color){
case 0:
color=0xff;
break;
case 0xff:
color=0xfc;
break;
};
}
else{
switch(color){
case 0xfc:
color=0xff;
break;
case 0xff:
color=0x00;
break;
};
}
SetData(pDis,num,color);
}
}
return TRUE;
}
else
return FALSE;
}
//if old pos < 0, no modification is needed
BOOL SetMenuFocus(unsigned long nRcId,
unsigned long nFontID,int old_pos,int new_pos){
int height=GetFontHeight(nFontID);
unsigned short num;
int sep=2;
SME_MENU_DATA_T* pData=NULL;
SmeGetMenuData(nRcId,&num,&pData);
if(old_pos>=0 && old_pos<num){
DrawReverseArea(0,(int)(old_pos*(height+1)+sep),80,(int)(height+2),FALSE);
}
if(new_pos>=0 && new_pos<num){
return DrawReverseArea(0,(int)(new_pos*(height+1)+sep),80,(int)(height+2),TRUE);
}
else
return FALSE;
}
int GetBitmapHeight(unsigned long nRcId){
SME_BITMAP_DATA_T bitmap_data;
if(SmeGetBitmap(nRcId,&bitmap_data))
return bitmap_data.nHeight;
else
return 0;
}
int GetBitmapWidth(unsigned long nRcId){
SME_BITMAP_DATA_T bitmap_data;
if(SmeGetBitmap(nRcId,&bitmap_data))
return bitmap_data.nWidth;
else
return 0;
}
/*Draw a bitmap to the screen*/
BOOL DrawBitmap(DISPLAY_COORDINATE_T x,
DISPLAY_COORDINATE_T y,
unsigned long nRcId){
SME_BITMAP_DATA_T bitmap_data;
unsigned char* pDis=(unsigned char*)Buf;
unsigned char* pBmp;
int i,j,color,count=0;
int bmp_bpp,bmp_width,bmp_height,data_width,
pixel_per_byte=(DISPLAY_BIT_PER_BYTE/DISPLAY_BIT_PER_PIXEL);
if(SmeGetBitmap(nRcId,&bitmap_data) && Buf){
pBmp=(unsigned char*)(bitmap_data.pData);
data_width=(int)bitmap_data.nLength/bitmap_data.nHeight;
bmp_width=bitmap_data.nWidth;
bmp_height=bitmap_data.nHeight;
bmp_bpp=bitmap_data.nBitCountPerPixel;
if(display_screen_valid(x+bmp_width-1,y+bmp_height-1)
&& bmp_bpp==DISPLAY_BIT_PER_PIXEL){
for(i=y;i<y+bitmap_data.nHeight;i++)
for(j=x;j<x+data_width*pixel_per_byte;j++){
if(j>=x+data_width*pixel_per_byte-bmp_width){
color=(*pBmp>>((count%pixel_per_byte)*DISPLAY_BIT_PER_PIXEL)) & (unsigned char)DISPLAY_ADJUST_NUMBER;
DrawPoint((int)(x+bmp_width-(j-x)-1),i,color);
}
if (count%pixel_per_byte==pixel_per_byte-1)
pBmp++;
count++;
}
return TRUE;
}
else
return FALSE;
}
else
return FALSE;
}
BOOL DrawBitmapAt(int line,
int mode,
unsigned long nFontID,
unsigned long nRcId){
DISPLAY_COORDINATE_T x,y;
int font_height,bmp_width,margin;
font_height=GetFontHeight(nFontID);
bmp_width=GetBitmapWidth(nRcId);
margin=DISPLAY_TEXTAREA_SIZE_WIDTH-bmp_width;
switch(mode){
case MODE_LEFT:
x=0;
break;
case MODE_CENTER:
if(margin>0)
x=margin/2;
else
x=0;
break;
case MODE_RIGHT:
if(margin>0)
x=margin;
else
x=0;
break;
};
y=(DISPLAY_COORDINATE_T)((line-1)*font_height)+4;
return DrawBitmap(x,y,nRcId);
}
/*Draw the softkey to the screen , but you need to Set them before you use
this function*/
BOOL DrawSoftkey(const SOFTKEY_INFO_T* pSoftkey,
unsigned char nLang,
unsigned long nFontId,
DISPLAY_COLOR_T color){
const SME_CHAR* str;
if(pSoftkey->isDefined && Buf){
str=GetTextStr(pSoftkey->sklStrId,nLang);
DrawTextStr(0,DISPLAY_SOFTKEY_SIZE_TOP+1,str,nFontId,DISPLAY_DEFAULT_PEN_COLOR);
DrawReverseArea(0,DISPLAY_SOFTKEY_SIZE_TOP,DISPLAY_SOFTKEY_SIZE_WIDTH,DISPLAY_SOFTKEY_SIZE_HEIGHT,TRUE);
str=GetTextStr(pSoftkey->skrStrId,nLang);
DrawTextStr(56,DISPLAY_SOFTKEY_SIZE_TOP+1,str,nFontId,DISPLAY_DEFAULT_PEN_COLOR);
DrawReverseArea(56,DISPLAY_SOFTKEY_SIZE_TOP,DISPLAY_SOFTKEY_SIZE_WIDTH,DISPLAY_SOFTKEY_SIZE_HEIGHT,TRUE);
return TRUE;
}
else
return FALSE;
}