?? gui_basic.c
字號:
/*
================================================================================
File Name : GUI_Basic.c
Author : LiYOng
Date : 2008-12-12 15:51
Version : 1.0
Decription: This file contains some basic functions for GUI, It need the LCD
Drive functions
================================================================================
*/
#include "GUI_Basic.H"
#include "GUI_Type.H"
#include "fontlib.h"
/*
================================================================================
Function : GUI_DrawRectangle( )
Description : Draw a rectangle
Input : -pRect, point to a rectangle structure
output : None
================================================================================
*/
void GUI_DrawRectangle( RECT* pRect )
{
LINE line;
line.xs = pRect->xs;
line.xe = pRect->xe;
line.ys = pRect->ys;
line.ye = pRect->ys;
line.Color = pRect->Color;
LCDDrawHRLine( &line );
line.xe = pRect->xs;
line.ye = pRect->ye;
LCDDrawHRLine( &line );
line.xs = pRect->xe;
line.ys = pRect->ye;
LCDDrawHRLine( &line );
line.xe = pRect->xe;
line.ye = pRect->ys;
LCDDrawHRLine( &line );
}
/*
================================================================================
Function : GUI_DrawLine( )
Description : Draw a line
Input : -pLine, point to a line structure
output : None
================================================================================
*/
void GUI_DrawLine( LINE* pLine )
{
INT32S dx; // 直線x軸差值變量
INT32S dy; // 直線y軸差值變量
INT32S dx_sym; // x軸增長方向,為-1時減值方向,為1時增值方向
INT32S dy_sym; // y軸增長方向,為-1時減值方向,為1時增值方向
INT32S dx_x2; // dx*2值變量,用于加快運算速度
INT32S dy_x2; // dy*2值變量,用于加快運算速度
INT32S di; // 決策變量
POINT point;
LINE line;
line.xs = pLine->xs;
line.ys = pLine->ys;
line.xe = pLine->xe;
line.ye = pLine->ye;
line.Color = pLine->Color;
point.Color = pLine->Color;
dx = line.xe - line.xs;
dy = line.ye - line.ys;
/* 判斷增長方向,或是否為水平線、垂直線、點 */
if( dx > 0 ) // 判斷x軸方向
{
dx_sym = 1; // dx>0,設置dx_sym=1
}
else
{
if( dx < 0 )
{
dx_sym = -1; // dx<0,設置dx_sym=-1
}
else
{
LCDDrawHRLine( &line );
return;
}
}
if( dy > 0 ) // 判斷y軸方向
{
dy_sym = 1; // dy>0,設置dy_sym=1
}
else
{
if( dy < 0 )
{
dy_sym = -1; // dy<0,設置dy_sym=-1
}
else
{ // dy==0,畫水平線,或一點
LCDDrawHRLine( &line );
return;
}
}
/* 將dx、dy取絕對值 */
dx = dx_sym * dx;
dy = dy_sym * dy;
/* 計算2倍的dx及dy值 */
dx_x2 = dx*2;
dy_x2 = dy*2;
/* 使用Bresenham法進行畫直線 */
if( dx >= dy ) // 對于dx>=dy,則使用x軸為基準
{
di = dy_x2 - dx;
while( line.xs != line.xe )
{
point.x = line.xs;
point.y = line.ys;
LCDDrawPoint( &point );
line.xs += dx_sym;
if( di < 0 )
{
di += dy_x2; // 計算出下一步的決策值
}
else
{
di += dy_x2 - dx_x2;
line.ys += dy_sym;
}
}
LCDDrawPoint( &point ); // 顯示最后一點
}
else // 對于dx<dy,則使用y軸為基準
{
di = dx_x2 - dy;
while( line.ys != line.ye )
{
point.x = line.xs;
point.y = line.ys;
LCDDrawPoint( &point );
line.ys += dy_sym;
if(di<0)
{
di += dx_x2;
}
else
{
di += dx_x2 - dy_x2;
line.xs += dx_sym;
}
}
LCDDrawPoint( &point ); // 顯示最后一點
}
}
/*
================================================================================
Name: PrintFont
Function: Display a character at a special area
Input: 1.Xs : Start position X
2.Ys : Start position Y
3.pFont : A pointer of a font structure
4.Character : The ASCII code of the character.
Output: None
Note: The start position is inputted as a parameter, And the end position is calculated by the FONT
structure.
Author: LiYong
Date : 2008.08.09
================================================================================
*/
void GUI_DisplayFont( INT8U Xs, INT8U Ys, FONT* pFont, char Character )
{
BitBlock Block;
INT32U Bytes;
INT8U DataBuffer[64];
INT8U i;
const unsigned char *offset;
Block.Height = pFont->Height;
Block.Width = pFont->Width;
Block.Color = pFont->Color;
Block.BackColor = pFont->BackColor;
Block.xs = Xs;
Block.ys = Ys;
Bytes = pFont->Width >> 3;
if( pFont->Width & 0x07 )
{
Bytes ++;
}
Bytes *= pFont->Height;
Bytes *= Character - ' ';
if( pFont->Height == 18 )
{
offset = (const unsigned char*)&FontLib_18;
}
else if( pFont->Height == 14 )
{
offset = (const unsigned char*)&FontLib_14;
}
else
{
return;
}
offset += Bytes;
for( i = 0; i < 36; i ++ )
{
//DataBuffer[i] = pgm_read_byte( offset + i );
}
Block.pData = DataBuffer;
PrintBitBlock( &Block );
}
/*
========================================================================================================
Name: DisplayStr
Function: Display a character at a special area
Input:
1.Xs : Start position X
2.Ys : Start position Y
3.pFont : A pointer of a font structure
4.Str : The start address of a string
Output: None
Note: The start position is inputted as a parameter, And the end position is calculated by the FONT
structure.
Author: LiYong
Date : 2008.08.09
========================================================================================================
*/
void GUI_DisplayStr( INT8U xs, INT8U ys, FONT* pFont, char* Str )
{
while( *Str )
{
GUI_DisplayFont( xs, ys, pFont, *Str );
Str ++;
xs += pFont->Width;
}
}
/*
================================================================================
Name: GUI_DrawCircle( )
Function: Display a cycle at a special area
Input: -pCycle, A pinter point to a cycle structure
Output: None
Author: LiYong
Date : 2008.08.09
================================================================================
*/
void GUI_DrawCircle( CIRCLE* pCircle )
{
INT8S draw_x0, draw_y0; // 劊圖點坐標變量
INT8S draw_x1, draw_y1;
INT8S draw_x2, draw_y2;
INT8S draw_x3, draw_y3;
INT8S draw_x4, draw_y4;
INT8S draw_x5, draw_y5;
INT8S draw_x6, draw_y6;
INT8S draw_x7, draw_y7;
INT8S xx, yy; // 畫圓控制變量
INT8S di; // 決策變量
POINT point;
point.Color = pCircle->Color;
/* 參數過濾 */
if(0 == pCircle->r ) return;
/* 計算出8個特殊點(0、45、90、135、180、225、270度),進行顯示 */
point.x = draw_x0 = draw_x1 = pCircle->x;
point.y = draw_y0 = draw_y1 = pCircle->y + pCircle->r;
if( draw_y0 < GUI_LCM_YMAX ) LCDDrawPoint( &point ); // 90度
point.x = draw_x2 = draw_x3 = pCircle->x;
point.y = draw_y2 = draw_y3 = pCircle->y - pCircle->r;
if( draw_y2 >= 0 ) LCDDrawPoint( &point ); // 270度
point.x = draw_x4 = draw_x6 = pCircle->x + pCircle->r;
point.y = draw_y4 = draw_y6 = pCircle->y;
if(draw_x4<GUI_LCM_XMAX) LCDDrawPoint( &point ); // 0度
point.x = draw_x5 = draw_x7 = pCircle->x - pCircle->r;
point.y = draw_y5 = draw_y7 = pCircle->y;
if(draw_x5>=0) LCDDrawPoint( &point ); // 180度
if(1==pCircle->r) return; // 若半徑為1,則已圓畫完
/* 使用Bresenham法進行畫圓 */
di = 3 - 2*pCircle->r; // 初始化決策變量
xx = 0;
yy = pCircle->r;
while(xx<yy)
{ if(di<0)
{ di += 4*xx + 6;
}
else
{ di += 4*(xx - yy) + 10;
yy--;
draw_y0--;
draw_y1--;
draw_y2++;
draw_y3++;
draw_x4--;
draw_x5++;
draw_x6--;
draw_x7++;
}
xx++;
draw_x0++;
draw_x1--;
draw_x2++;
draw_x3--;
draw_y4++;
draw_y5++;
draw_y6--;
draw_y7--;
/* 要判斷當前點是否在有效范圍內 */
if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )
{
point.x = draw_x0;
point.y = draw_y0;
LCDDrawPoint( &point );
}
if( (draw_x1>=0)&&(draw_y1>=0) )
{
point.x = draw_x1;
point.y = draw_y1;
LCDDrawPoint( &point );
}
if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )
{
point.x = draw_x2;
point.y = draw_y2;
LCDDrawPoint( &point );
}
if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )
{
point.x = draw_x3;
point.y = draw_y3;
LCDDrawPoint( &point );
}
if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )
{
point.x = draw_x4;
point.y = draw_y4;
LCDDrawPoint( &point );
}
if( (draw_x5>=0)&&(draw_y5>=0) )
{
point.x = draw_x5;
point.y = draw_y5;
LCDDrawPoint( &point );
}
if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )
{
point.x = draw_x6;
point.y = draw_y6;
LCDDrawPoint( &point );
}
if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )
{
point.x = draw_x7;
point.y = draw_y7;
LCDDrawPoint( &point );
}
}
}
/*
================================================================================
Name: GUI_DrawCircleFill( )
Function: Display a cycle at a special area and fill its area
Input: -pCycle, A pinter point to a cycle structure
Output: None
Author: LiYong
Date : 2008.08.09
================================================================================
*/
void GUI_DrawCircleFill( CIRCLE* pCircle )
{
INT8S draw_x0, draw_y0; // 劊圖點坐標變量
INT8S draw_x1, draw_y1;
INT8S draw_x2, draw_y2;
INT8S draw_x3, draw_y3;
INT8S draw_x4, draw_y4;
INT8S draw_x5, draw_y5;
INT8S draw_x6, draw_y6;
INT8S draw_x7, draw_y7;
INT8S fill_x0, fill_y0; // 填充所需的變量,使用垂直線填充
INT8S fill_x1;
INT8S xx, yy; // 畫圓控制變量
INT8S di; // 決策變量
POINT point;
LINE line;
point.Color = pCircle->Color;
line.Color = pCircle->Color;
/* 參數過濾 */
if(0==pCircle->r) return;
/* 計算出4個特殊點(0、90、180、270度),進行顯示 */
point.x = draw_x0 = draw_x1 = pCircle->x;
point.y = draw_y0 = draw_y1 = pCircle->y + pCircle->r;
if(draw_y0<GUI_LCM_YMAX)
{
LCDDrawPoint( &point );
}
point.x = draw_x2 = draw_x3 = pCircle->x;
point.y = draw_y2 = draw_y3 = pCircle->y - pCircle->r;
if(draw_y2>=0)
{
LCDDrawPoint( &point );
}
point.x = draw_x4 = draw_x6 = pCircle->x + pCircle->r;
point.y = draw_y4 = draw_y6 = pCircle->y;
if(draw_x4<GUI_LCM_XMAX)
{
LCDDrawPoint( &point ); // 0度
fill_x1 = draw_x4;
}
else
{
fill_x1 = GUI_LCM_XMAX;
}
fill_y0 = pCircle->y; // 設置填充線條起始點fill_x0
fill_x0 = pCircle->x - pCircle->r; // 設置填充線條結束點fill_y1
if(fill_x0<0) fill_x0 = 0;
line.xs = fill_x0;
line.ys = fill_y0;
line.ye = fill_y0;
line.xe = fill_x1;
LCDDrawHRLine( &line );
point.x = draw_x5 = draw_x7 = pCircle->x - pCircle->r;
point.y = draw_y5 = draw_y7 = pCircle->y;
if(draw_x5>=0)
{
LCDDrawPoint( &point ); // 180度
}
if(1==pCircle->r) return;
/* 使用Bresenham法進行畫圓 */
di = 3 - 2*pCircle->r; // 初始化決策變量
xx = 0;
yy = pCircle->r;
while(xx<yy)
{ if(di<0)
{ di += 4*xx + 6;
}
else
{ di += 4*(xx - yy) + 10;
yy--;
draw_y0--;
draw_y1--;
draw_y2++;
draw_y3++;
draw_x4--;
draw_x5++;
draw_x6--;
draw_x7++;
}
xx++;
draw_x0++;
draw_x1--;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -