?? gui_basic.c
字號(hào):
if( GUI_CmpColor(bakc,color)==0 ) return(i+1); // 若找到,則返回
}
GUI_ReadPoint(i, y0, &bakc);
if( GUI_CmpColor(bakc,color)==0 ) return(1); // 若找到,則返回
return(0);
}
/****************************************************************************
* 名稱:GUI_ReadRightPoint()
* 功能:找出指定點(diǎn)右邊最近的非color點(diǎn)。
* 入口參數(shù): x0 指定點(diǎn)的x軸坐標(biāo)值
* y0 指定點(diǎn)的y軸坐標(biāo)值
* color 指定顏色值
* 出口參數(shù):返回該點(diǎn)的x軸坐標(biāo)值。
* 說明:若沒有找出,則返回最右的x坐標(biāo)GUI_LCM_XMAX。
****************************************************************************/
uint32 GUI_ReadRightPoint(uint32 x0, uint32 y0, TCOLOR color)
{ uint32 i;
TCOLOR bakc;
for(i=x0+1; i<GUI_LCM_XMAX; i++)
{ GUI_ReadPoint(i, y0, &bakc);
if( GUI_CmpColor(bakc,color)==0 ) return(i-1); // 若找到,則返回
}
return(GUI_LCM_XMAX);
}
/****************************************************************************
* 名稱:GUI_CmpPointColor()
* 功能:判斷指定點(diǎn)上的顏色是否為某種顏色。
* 入口參數(shù):x 指定點(diǎn)的x軸坐標(biāo)值
* y 指定點(diǎn)的y軸坐標(biāo)值
* color 顏色值
* 出口參數(shù):返回1表示相同,返回0表示不相同。
* 說明:
****************************************************************************/
int GUI_CmpPointColor(uint32 x, uint32 y, TCOLOR color)
{ TCOLOR bakc;
GUI_ReadPoint(x, y, &bakc);
return( GUI_CmpColor(bakc,color) );
}
/* 定義折點(diǎn)個(gè)數(shù) */
#ifndef DOWNP_N
#define DOWNP_N 20
#endif
#ifndef UPP_N
#define UPP_N 20
#endif
/****************************************************************************
* 名稱:GUI_FloodFill()
* 功能:圖形填充,將指定點(diǎn)內(nèi)的封閉圖形進(jìn)行填充。對(duì)指定點(diǎn)的顏色區(qū)域進(jìn)行填充,即不是該顏色
* 的像素為邊界(如,指定點(diǎn)上的顏色為紅色,則其它顏色像素均為邊界)。
* 入口參數(shù): x0 指定點(diǎn)的x坐標(biāo)值
* y0 指定點(diǎn)的y坐標(biāo)值
* color 填充顏色
* 出口參數(shù):無
* 說明:操作失敗原因是指定地址超出有效范圍、指定點(diǎn)不在封閉圖形內(nèi)。
****************************************************************************/
void GUI_FloodFill(uint32 x0, uint32 y0, TCOLOR color)
{ PointXY down_point[DOWNP_N]; // 定義向下填充轉(zhuǎn)折點(diǎn)緩沖區(qū)
uint8 down_no; // 向下折點(diǎn)個(gè)數(shù)
PointXY up_point[UPP_N]; // 定義向上填充轉(zhuǎn)折點(diǎn)緩沖區(qū)
uint8 up_no; // 向上折點(diǎn)個(gè)數(shù)
TCOLOR fcolor; // 填充點(diǎn)上的顏色
uint32 xx, yy; // 填充臨時(shí)x,y變量 (當(dāng)前填充行的中點(diǎn))
uint32 xx0; // 當(dāng)前填充行的左x值變量
uint32 xx1; // 當(dāng)前填充行的右y值變量
uint32 i;
uint32 x0_bak, y0_bak;
uint32 x1_bak;
/* 參數(shù)過濾 */
if(x0>=GUI_LCM_XMAX) return;
if(y0>=GUI_LCM_YMAX) return;
/* 判斷指定點(diǎn)是否為填充顏色,若是則直接返回 */
GUI_ReadPoint(x0, y0, &fcolor); // 取得填充點(diǎn)的顏色
if( GUI_CmpColor(fcolor,color)!=0 ) return;
y0_bak = y0;
x0_bak = xx0 = GUI_ReadLeftPoint(x0, y0, fcolor); // 找出當(dāng)前y坐標(biāo)上的最左邊的點(diǎn)
x1_bak = xx1 = GUI_ReadRightPoint(x0, y0, fcolor); // 找出當(dāng)前y坐標(biāo)上的最右邊的點(diǎn)
down_point[0].x = up_point[0].x = (xx1 + xx0)/2;
down_point[0].y = up_point[0].y = y0;
down_no = 1;
up_no = 1;
/* 開始向上填充 */
FILL_UP:
if(0==up_no) goto FILL_DOWN; // 若向下掃描已完成,則退出
xx = up_point[up_no-1].x; // 否則取出下一折點(diǎn)
yy = up_point[up_no-1].y;
up_no--;
xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
while(1)
{ yy += 1; // 中心點(diǎn)向上一點(diǎn)
if( GUI_CmpPointColor(xx, yy, fcolor)==0 )
{ /* 判斷此點(diǎn)是否為終點(diǎn),若是則退出此次循環(huán) */
for(i=xx0; i<=xx1; i++) // 查找此行是否有需填充點(diǎn)
{ if( GUI_CmpPointColor(i, yy, fcolor)!=0 ) break;
}
if(i>xx1) goto FILL_UP;
/* 找出新一行中最右邊的點(diǎn) */
xx = i; // 更新xx到要填充的有效區(qū)域內(nèi)
xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
}
else
{ /* 找出新一行中最右邊的點(diǎn) */
xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
}
xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
/* 向下折點(diǎn)。使用y0作為折點(diǎn)變量,x0作為上一折點(diǎn)變量 */
if(down_no<DOWNP_N)
{ y0 = xx0;
x0 = y0-1;
for(i=y0; i<=xx1; i++)
{ if( GUI_CmpPointColor(i, yy-1, fcolor)==0 ) // 更新折點(diǎn)
{ y0 = i;
}
else
{ if(x0!=y0) // 找到新的折點(diǎn)
{ x0 = y0;
down_point[down_no].x = i;
down_point[down_no].y = yy;
down_no++;
}
}
if(down_no>=DOWNP_N) break; // 若緩沖區(qū)已保存滿,則退出
} // end of for(i=y0+1; i<xx1; i++)
} // end of if(down_no<DOWNP_N)
xx = (xx1 + xx0)/2; // 更新中心點(diǎn)
GUI_HLine(xx0, yy, xx1, color); // 填充一行
/* 向上折點(diǎn)。使用y0作為折點(diǎn)變量,x0作為上一折點(diǎn)變量 */
if(up_no<UPP_N)
{ y0 = xx0;
x0 = y0-1;
for(i=y0; i<=xx1; i++)
{ if( GUI_CmpPointColor(i, yy+1, fcolor)==0 ) // 更新折點(diǎn)
{ y0 = i;
}
else
{ if(x0!=y0) // 找到新的折點(diǎn)
{ x0 = y0;
up_point[up_no].x = i;
up_point[up_no].y = yy;
up_no++;
}
}
if(up_no>=UPP_N) break; // 若緩沖區(qū)已保存滿,則退出
}
} // end of if(up_no<UPP_N)
} // end of while(1)
/* 向下填充 */
FILL_DOWN:
if(0==down_no)
{ if(0==up_no)
{ GUI_HLine(x0_bak, y0_bak, x1_bak, color);
return; // 若向下掃描已完成,且沒有發(fā)現(xiàn)新的向上折點(diǎn),則退出
}
else
{ goto FILL_UP;
}
}
xx = down_point[down_no-1].x; // 否則取出下一折點(diǎn)
yy = down_point[down_no-1].y;
down_no--;
xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
while(1)
{ yy -= 1; // 中心點(diǎn)向上一點(diǎn)
if( GUI_CmpPointColor(xx, yy, fcolor)==0 )
{ /* 判斷此點(diǎn)是否為終點(diǎn),若是則退出此次循環(huán) */
for(i=xx0; i<=xx1; i++) // 查找下一行是否有需填充點(diǎn)
{ if( GUI_CmpPointColor(i, yy, fcolor)!=0 ) break;
}
if(i>xx1) goto FILL_DOWN;
/* 找出新一行中最右邊的點(diǎn) */
xx = i;
xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
}
else
{ /* 找出新一行中最右邊的點(diǎn) */
xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
}
xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
/* 向上折點(diǎn)。使用y0作為折點(diǎn)變量,x0作為上一折點(diǎn)變量 */
if(up_no<UPP_N)
{ y0 = xx0;
x0 = y0-1;
for(i=y0; i<=xx1; i++)
{ if( GUI_CmpPointColor(i, yy+1, fcolor)==0 ) // 更新折點(diǎn)
{ y0 = i;
}
else
{ if(x0!=y0) // 找到新的折點(diǎn)
{ x0 = y0;
up_point[up_no].x = i;
up_point[up_no].y = yy;
up_no++;
}
}
if(up_no>=UPP_N) break; // 若緩沖區(qū)已保存滿,則退出
}
}
xx = (xx1 + xx0)/2;
GUI_HLine(xx0, yy, xx1, color); // 填充一行
/* 向下折點(diǎn)。使用y0作為折點(diǎn)變量,x0作為上一折點(diǎn)變量 */
if(down_no<DOWNP_N)
{ y0 = xx0;
x0 = y0-1;
for(i=y0; i<=xx1; i++)
{ if( GUI_CmpPointColor(i, yy-1, fcolor)==0 ) // 更新折點(diǎn)
{ y0 = i;
}
else
{ if(x0!=y0) // 找到新的折點(diǎn)
{ x0 = y0;
down_point[down_no].x = i;
down_point[down_no].y = yy;
down_no++;
}
}
if(down_no>=DOWNP_N) break; // 若緩沖區(qū)已保存滿,則退出
}
} // end of if(down_no<DOWNP_N)
} // end of while(1)
GUI_HLine(x0_bak, y0_bak, x1_bak, color);
}
#endif
#if GUI_ArcX_EN==1
/****************************************************************************
* 名稱:GUI_Arc4()
* 功能:畫弧。起點(diǎn)及終點(diǎn)只能為0度-90度、90度-180度、180度-270度、270度-0度等。即分別
* 為第1-4像限的90度弧。
* 入口參數(shù): x0 圓心的x坐標(biāo)值
* y0 圓心的y坐標(biāo)值
* r 圓弧的半徑
* angle 畫弧的像限(1-4)
* color 顯示顏色
* 出口參數(shù):無
* 說明:操作失敗原因是指定地址超出有效范圍。
****************************************************************************/
void GUI_Arc4(uint32 x, uint32 y, uint32 r, uint8 angle, TCOLOR color)
{ int32 draw_x, draw_y;
int32 op_x, op_y;
int32 op_2rr;
if(r==0) return;
op_2rr = 2*r*r; // 計(jì)算r平方乖以2
switch(angle)
{ case 1:
draw_x = x+r;
draw_y = y;
op_x = r;
op_y = 0;
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_y++;
draw_y++;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_x--;
draw_x--;
}
if(op_y>=op_x) break;
}
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_x--;
draw_x--;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_y++;
draw_y++;
}
if(op_x<=0)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
break;
}
}
break;
case 2:
draw_x = x-r;
draw_y = y;
op_x = r;
op_y = 0;
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_y++;
draw_y++;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_x--;
draw_x++;
}
if(op_y>=op_x) break;
}
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_x--;
draw_x++;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_y++;
draw_y++;
}
if(op_x<=0)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
break;
}
}
break;
case 3:
draw_x = x-r;
draw_y = y;
op_x = r;
op_y = 0;
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_y++;
draw_y--;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_x--;
draw_x++;
}
if(op_y>=op_x) break;
}
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_x--;
draw_x++;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_y++;
draw_y--;
}
if(op_x<=0)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
break;
}
}
break;
case 4:
draw_x = x+r;
draw_y = y;
op_x = r;
op_y = 0;
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_y++;
draw_y--;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_x--;
draw_x--;
}
if(op_y>=op_x) break;
}
while(1)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
/* 計(jì)算下一點(diǎn) */
op_x--;
draw_x--;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_y++;
draw_y--;
}
if(op_x<=0)
{ GUI_Point(draw_x, draw_y, color); // 開始畫圖
break;
}
}
break;
default:
break;
}
}
/****************************************************************************
* 名稱:GUI_Arc()
* 功能:指定起點(diǎn)、終點(diǎn)及半徑畫弧(不能畫圓)。使用的是順時(shí)針方向畫圖。
* 入口參數(shù): x 圓心的x軸坐標(biāo)值
* y 圓心的y軸坐標(biāo)值
* stangle 起始角度(0-359度)
* endangle 終止角度(0-359度)
* r 圓的半徑終點(diǎn)
* color 顯示顏色
* 出口參數(shù):無
* 說明:操作失敗原因是指定地址超出有效范圍。
****************************************************************************/
void GUI_Arc(uint32 x, uint32 y, uint32 r, uint32 stangle, uint32 endangle, TCOLOR color)
{ int32 draw_x, draw_y; // 畫圖坐標(biāo)變量
int32 op_x, op_y; // 操作坐標(biāo)
int32 op_2rr; // 2*r*r值變量
int32 pno_angle; // 度角點(diǎn)的個(gè)數(shù)
uint8 draw_on; // 畫點(diǎn)開關(guān),為1時(shí)畫點(diǎn),為0時(shí)不畫
/* 參數(shù)過濾 */
if(r==0) return; // 半徑為0則直接退出
if(stangle==endangle) return; // 起始角度與終止角度相同,退出
if( (stangle>=360) || (endangle>=360) ) return;
op_2rr = 2*r*r; // 計(jì)算r平方乖以2
pno_angle = 0;
/* 先計(jì)算出在此半徑下的45度的圓弧的點(diǎn)數(shù) */
op_x = r;
op_y = 0;
while(1)
{ pno_angle++; // 畫點(diǎn)計(jì)數(shù)
/* 計(jì)算下一點(diǎn) */
op_y++;
if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 ) // 使用逐點(diǎn)比較法實(shí)現(xiàn)畫圓弧
{ op_x--;
}
if(op_y>=op_x) break;
}
draw_on = 0; // 最開始關(guān)畫點(diǎn)開關(guān)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -