GUI_BASIC.C
上传用户:zfj3589
上传日期:2022-07-13
资源大小:635k
文件大小:53k
源码类别:

微处理器开发

开发平台:

C/C++

  1. /****************************************************************************************
  2. * 文件名:GUI_BASIC.C
  3. * 功能:GUI基本绘图函数。进行基本绘图运算,并调用相应的刷新程序更新LCD显示。
  4. * 作者:黄绍斌
  5. * 日期:2004.02.26
  6. * 备注:图形操作层,进行各种图形运算操作。
  7. ****************************************************************************************/
  8. #include "config.h"
  9. #include <math.h>
  10. /****************************************************************************
  11. * 名称:GUI_Rectangle()
  12. * 功能:画矩形。
  13. * 入口参数: x0 矩形左上角的x坐标值
  14. *           y0 矩形左上角的y坐标值
  15. *           x1      矩形右下角的x坐标值
  16. *           y1      矩形右下角的y坐标值
  17. *           color 显示颜色
  18. * 出口参数:无
  19. * 说明:操作失败原因是指定地址超出有效范围。
  20. ****************************************************************************/
  21. void  GUI_Rectangle(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
  22. {  GUI_HLine(x0, y0, x1, color);
  23.    GUI_HLine(x0, y1, x1, color);
  24.    GUI_RLine(x0, y0, y1, color);
  25.    GUI_RLine(x1, y0, y1, color);
  26. }
  27. /****************************************************************************
  28. * 名称:GUI_RectangleFill()
  29. * 功能:填充矩形。画一个填充的矩形,填充色与边框色一样。
  30. * 入口参数: x0 矩形左上角的x坐标值
  31. *           y0 矩形左上角的y坐标值
  32. *           x1      矩形右下角的x坐标值
  33. *           y1      矩形右下角的y坐标值
  34. *           color 填充颜色
  35. * 出口参数:无
  36. * 说明:操作失败原因是指定地址超出有效范围。
  37. ****************************************************************************/
  38. void  GUI_RectangleFill(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
  39. {  uint32  i;
  40.    /* 先找出矩形左上角与右下角的两个点,保存在(x0,y0),(x1,y1) */
  41.    if(x0>x1)  // 若x0>x1,则x0与x1交换
  42.    {  i = x0;
  43.       x0 = x1;
  44.       x1 = i;
  45.    }
  46.    if(y0>y1) // 若y0>y1,则y0与y1交换
  47.    {  i = y0;
  48.       y0 = y1;
  49.       y1 = i;
  50.    }
  51.    
  52.    /* 判断是否只是直线 */
  53.    if(y0==y1) 
  54.    {  GUI_HLine(x0, y0, x1, color);
  55.       return;
  56.    }
  57.    if(x0==x1) 
  58.    {  GUI_RLine(x0, y0, y1, color);
  59.       return;
  60.    }
  61.    while(y0<=y1)
  62.    {  GUI_HLine(x0, y0, x1, color); // 当前画水平线
  63.       y0++; // 下一行
  64.    }
  65. }
  66. /****************************************************************************
  67. * 名称:GUI_Square()
  68. * 功能:画正方形。
  69. * 入口参数: x0 正方形左上角的x坐标值
  70. *           y0 正方形左上角的y坐标值
  71. *           with    正方形的边长
  72. *           color 显示颜色
  73. * 出口参数:无
  74. * 说明:操作失败原因是指定地址超出有效范围。
  75. ****************************************************************************/
  76. void  GUI_Square(uint32 x0, uint32 y0, uint32  with, TCOLOR  color)
  77. {   if(with==0) return;
  78. if( (x0+with) > GUI_LCM_XMAX ) return;
  79. if( (y0+with) > GUI_LCM_YMAX ) return;
  80. GUI_Rectangle(x0, y0, x0+with, y0+with, color);
  81. }
  82. /****************************************************************************
  83. * 名称:GUI_Line()
  84. * 功能:画任意两点之间的直线。
  85. * 入口参数: x0 直线起点的x坐标值
  86. *           y0 直线起点的y坐标值
  87. *           x1      直线终点的x坐标值
  88. *           y1      直线终点的y坐标值
  89. *           color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
  90. * 出口参数:无
  91. * 说明:操作失败原因是指定地址超出有效范围。
  92. ****************************************************************************/
  93. void  GUI_Line(uint32 x0, uint32 y0, uint32 x1, uint32 y1, TCOLOR color)
  94. {  int32   dx; // 直线x轴差值变量
  95.    int32   dy;           // 直线y轴差值变量
  96.    int8    dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向
  97.    int8    dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向
  98.    int32   dx_x2; // dx*2值变量,用于加快运算速度
  99.    int32   dy_x2; // dy*2值变量,用于加快运算速度
  100.    int32   di; // 决策变量
  101.    
  102.    
  103.    dx = x1-x0; // 求取两点之间的差值
  104.    dy = y1-y0;
  105.    
  106.    /* 判断增长方向,或是否为水平线、垂直线、点 */
  107.    if(dx>0) // 判断x轴方向
  108.    {  dx_sym = 1; // dx>0,设置dx_sym=1
  109.    }
  110.    else
  111.    {  if(dx<0)
  112.       {  dx_sym = -1; // dx<0,设置dx_sym=-1
  113.       }
  114.       else
  115.       {  // dx==0,画垂直线,或一点
  116.          GUI_RLine(x0, y0, y1, color);
  117.         return;
  118.       }
  119.    }
  120.    
  121.    if(dy>0) // 判断y轴方向
  122.    {  dy_sym = 1; // dy>0,设置dy_sym=1
  123.    }
  124.    else
  125.    {  if(dy<0)
  126.       {  dy_sym = -1; // dy<0,设置dy_sym=-1
  127.       }
  128.       else
  129.       {  // dy==0,画水平线,或一点
  130.          GUI_HLine(x0, y0, x1, color);
  131.         return;
  132.       }
  133.    }
  134.     
  135.    /* 将dx、dy取绝对值 */
  136.    dx = dx_sym * dx;
  137.    dy = dy_sym * dy;
  138.  
  139.    /* 计算2倍的dx及dy值 */
  140.    dx_x2 = dx*2;
  141.    dy_x2 = dy*2;
  142.    
  143.    /* 使用Bresenham法进行画直线 */
  144.    if(dx>=dy) // 对于dx>=dy,则使用x轴为基准
  145.    {  di = dy_x2 - dx;
  146.       while(x0!=x1)
  147.       {  GUI_Point(x0, y0, color);
  148.          x0 += dx_sym;
  149.          if(di<0)
  150.          {  di += dy_x2; // 计算出下一步的决策值
  151.          }
  152.          else
  153.          {  di += dy_x2 - dx_x2;
  154.             y0 += dy_sym;
  155.          }
  156.       }
  157.       GUI_Point(x0, y0, color); // 显示最后一点
  158.    }
  159.    else // 对于dx<dy,则使用y轴为基准
  160.    {  di = dx_x2 - dy;
  161.       while(y0!=y1)
  162.       {  GUI_Point(x0, y0, color);
  163.          y0 += dy_sym;
  164.          if(di<0)
  165.          {  di += dx_x2;
  166.          }
  167.          else
  168.          {  di += dx_x2 - dy_x2;
  169.             x0 += dx_sym;
  170.          }
  171.       }
  172.       GUI_Point(x0, y0, color); // 显示最后一点
  173.    } 
  174.   
  175. }
  176. #if GUI_LineWith_EN==1
  177. /****************************************************************************
  178. * 名称:GUI_LineWith()
  179. * 功能:画任意两点之间的直线,并且可设置线的宽度。
  180. * 入口参数: x0 直线起点的x坐标值
  181. *           y0 直线起点的y坐标值
  182. *           x1      直线终点的x坐标值
  183. *           y1      直线终点的y坐标值
  184. *           with    线宽(0-50)
  185. *           color 显示颜色
  186. * 出口参数:无
  187. * 说明:操作失败原因是指定地址超出有效范围。
  188. ****************************************************************************/
  189. void  GUI_LineWith(uint32 x0, uint32 y0, uint32 x1, uint32 y1, uint8 with, TCOLOR color)
  190. {  int32   dx; // 直线x轴差值变量
  191.    int32   dy;           // 直线y轴差值变量
  192.    int8    dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向
  193.    int8    dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向
  194.    int32   dx_x2; // dx*2值变量,用于加快运算速度
  195.    int32   dy_x2; // dy*2值变量,用于加快运算速度
  196.    int32   di; // 决策变量
  197.    
  198.    int32   wx, wy; // 线宽变量
  199.    int32   draw_a, draw_b;
  200.    
  201.    /* 参数过滤 */
  202.    if(with==0) return;
  203.    if(with>50) with = 50;
  204.    
  205.    dx = x1-x0; // 求取两点之间的差值
  206.    dy = y1-y0;
  207.    
  208.    wx = with/2;
  209.    wy = with-wx-1;
  210.    
  211.    /* 判断增长方向,或是否为水平线、垂直线、点 */
  212.    if(dx>0) // 判断x轴方向
  213.    {  dx_sym = 1; // dx>0,设置dx_sym=1
  214.    }
  215.    else
  216.    {  if(dx<0)
  217.       {  dx_sym = -1; // dx<0,设置dx_sym=-1
  218.       }
  219.       else
  220.       {  /* dx==0,画垂直线,或一点 */
  221.          wx = x0-wx;
  222.          if(wx<0) wx = 0;
  223.          wy = x0+wy;
  224.          
  225.          while(1)
  226.          {  x0 = wx;
  227.             GUI_RLine(x0, y0, y1, color);
  228.             if(wx>=wy) break;
  229.             wx++;
  230.          }
  231.          
  232.         return;
  233.       }
  234.    }
  235.    
  236.    if(dy>0) // 判断y轴方向
  237.    {  dy_sym = 1; // dy>0,设置dy_sym=1
  238.    }
  239.    else
  240.    {  if(dy<0)
  241.       {  dy_sym = -1; // dy<0,设置dy_sym=-1
  242.       }
  243.       else
  244.       {  /* dy==0,画水平线,或一点 */
  245.          wx = y0-wx;
  246.          if(wx<0) wx = 0;
  247.          wy = y0+wy;
  248.          
  249.          while(1)
  250.          {  y0 = wx;
  251.             GUI_HLine(x0, y0, x1, color);
  252.             if(wx>=wy) break;
  253.             wx++;
  254.          }
  255.         return;
  256.       }
  257.    }
  258.     
  259.    /* 将dx、dy取绝对值 */
  260.    dx = dx_sym * dx;
  261.    dy = dy_sym * dy;
  262.  
  263.    /* 计算2倍的dx及dy值 */
  264.    dx_x2 = dx*2;
  265.    dy_x2 = dy*2;
  266.    
  267.    /* 使用Bresenham法进行画直线 */
  268.    if(dx>=dy) // 对于dx>=dy,则使用x轴为基准
  269.    {  di = dy_x2 - dx;
  270.       while(x0!=x1)
  271.       {  /* x轴向增长,则宽度在y方向,即画垂直线 */
  272.          draw_a = y0-wx;
  273.          if(draw_a<0) draw_a = 0;
  274.          draw_b = y0+wy;
  275.          GUI_RLine(x0, draw_a, draw_b, color);
  276.          
  277.          x0 += dx_sym;
  278.          if(di<0)
  279.          {  di += dy_x2; // 计算出下一步的决策值
  280.          }
  281.          else
  282.          {  di += dy_x2 - dx_x2;
  283.             y0 += dy_sym;
  284.          }
  285.       }
  286.       draw_a = y0-wx;
  287.       if(draw_a<0) draw_a = 0;
  288.       draw_b = y0+wy;
  289.       GUI_RLine(x0, draw_a, draw_b, color);
  290.    }
  291.    else // 对于dx<dy,则使用y轴为基准
  292.    {  di = dx_x2 - dy;
  293.       while(y0!=y1)
  294.       {  /* y轴向增长,则宽度在x方向,即画水平线 */
  295.          draw_a = x0-wx;
  296.          if(draw_a<0) draw_a = 0;
  297.          draw_b = x0+wy;
  298.          GUI_HLine(draw_a, y0, draw_b, color);
  299.          
  300.          y0 += dy_sym;
  301.          if(di<0)
  302.          {  di += dx_x2;
  303.          }
  304.          else
  305.          {  di += dx_x2 - dy_x2;
  306.             x0 += dx_sym;
  307.          }
  308.       }
  309.       draw_a = x0-wx;
  310.       if(draw_a<0) draw_a = 0;
  311.       draw_b = x0+wy;
  312.       GUI_HLine(draw_a, y0, draw_b, color);
  313.    } 
  314.   
  315. }
  316. #endif
  317. /****************************************************************************
  318. * 名称:GUI_LineS()
  319. * 功能:多个点之间的连续连线。从第一点连到第二点,再连到第三点...
  320. * 入口参数: points  多个点坐标数据的指针,数据排列为(x0,y0)、(x1,y1)、(x2,y2)...
  321. *           no      点数目,至少要大于1
  322. *           color 显示颜色
  323. * 出口参数:无
  324. * 说明:操作失败原因是指定地址超出有效范围。
  325. ****************************************************************************/
  326. void  GUI_LineS(uint32 const *points, uint8 no, TCOLOR color)
  327. {  uint32  x0, y0;
  328.    uint32  x1, y1;
  329.    uint8  i;
  330.    /* 入口参数过滤 */
  331.    if(0==no) return;
  332.    if(1==no) // 单点
  333.    {  x0 = *points++;
  334.       y0 = *points;
  335.       GUI_Point(x0, y0, color);
  336.    }
  337.    
  338.    /* 画多条线条 */
  339.    x0 = *points++; // 取出第一点坐标值,作为原起点坐标值
  340.    y0 = *points++;
  341.    for(i=1; i<no; i++)
  342.    {  x1 = *points++; // 取出下一点坐标值
  343.       y1 = *points++;
  344.       GUI_Line(x0, y0, x1, y1, color);
  345.       x0 = x1; // 更新原起点坐标
  346.       y0 = y1;
  347.    }
  348. }
  349. #if  GUI_CircleX_EN==1
  350. /****************************************************************************
  351. * 名称:GUI_Circle()
  352. * 功能:指定圆心位置及半径,画圆。
  353. * 入口参数: x0 圆心的x坐标值
  354. *           y0 圆心的y坐标值
  355. *           r       圆的半径
  356. *           color 显示颜色
  357. * 出口参数:无
  358. * 说明:操作失败原因是指定地址超出有效范围。
  359. ****************************************************************************/
  360. void  GUI_Circle(uint32 x0, uint32 y0, uint32 r, TCOLOR color)
  361. {  int32  draw_x0, draw_y0; // 刽图点坐标变量
  362.    int32  draw_x1, draw_y1;
  363.    int32  draw_x2, draw_y2;
  364.    int32  draw_x3, draw_y3;
  365.    int32  draw_x4, draw_y4;
  366.    int32  draw_x5, draw_y5;
  367.    int32  draw_x6, draw_y6;
  368.    int32  draw_x7, draw_y7;
  369.    int32  xx, yy; // 画圆控制变量
  370.  
  371.    int32  di; // 决策变量
  372.    
  373.    /* 参数过滤 */
  374.    if(0==r) return;
  375.    
  376.    /* 计算出8个特殊点(0、45、90、135、180、225、270度),进行显示 */
  377.    draw_x0 = draw_x1 = x0;
  378.    draw_y0 = draw_y1 = y0 + r;
  379.    if(draw_y0<GUI_LCM_YMAX) GUI_Point(draw_x0, draw_y0, color); // 90度
  380.    draw_x2 = draw_x3 = x0;
  381.    draw_y2 = draw_y3 = y0 - r;
  382.    if(draw_y2>=0) GUI_Point(draw_x2, draw_y2, color); // 270度
  383.    
  384.    draw_x4 = draw_x6 = x0 + r;
  385.    draw_y4 = draw_y6 = y0;
  386.    if(draw_x4<GUI_LCM_XMAX) GUI_Point(draw_x4, draw_y4, color); // 0度
  387.    
  388.    draw_x5 = draw_x7 = x0 - r;
  389.    draw_y5 = draw_y7 = y0;
  390.    if(draw_x5>=0) GUI_Point(draw_x5, draw_y5, color); // 180度   
  391.    if(1==r) return; // 若半径为1,则已圆画完
  392.    
  393.    
  394.    /* 使用Bresenham法进行画圆 */
  395.    di = 3 - 2*r; // 初始化决策变量
  396.    
  397.    xx = 0;
  398.    yy = r;
  399.    while(xx<yy)
  400.    {  if(di<0)
  401.   {  di += 4*xx + 6;       
  402.   }
  403.   else
  404.   {  di += 4*(xx - yy) + 10;
  405.   
  406.      yy--;   
  407.  draw_y0--;
  408.  draw_y1--;
  409.  draw_y2++;
  410.  draw_y3++;
  411.  draw_x4--;
  412.  draw_x5++;
  413.  draw_x6--;
  414.  draw_x7++;  
  415.   }
  416.   
  417.   xx++;   
  418.   draw_x0++;
  419.   draw_x1--;
  420.   draw_x2++;
  421.   draw_x3--;
  422.   draw_y4++;
  423.   draw_y5++;
  424.   draw_y6--;
  425.   draw_y7--;
  426.   /* 要判断当前点是否在有效范围内 */
  427.   if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )
  428.   {  GUI_Point(draw_x0, draw_y0, color);
  429.   }     
  430.   if( (draw_x1>=0)&&(draw_y1>=0) )
  431.   {  GUI_Point(draw_x1, draw_y1, color);
  432.   }
  433.   if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )
  434.   {  GUI_Point(draw_x2, draw_y2, color);   
  435.   }
  436.   if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )
  437.   {  GUI_Point(draw_x3, draw_y3, color);
  438.   }
  439.   if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )
  440.   {  GUI_Point(draw_x4, draw_y4, color);
  441.   }
  442.   if( (draw_x5>=0)&&(draw_y5>=0) )
  443.   {  GUI_Point(draw_x5, draw_y5, color);
  444.   }
  445.   if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )
  446.   {  GUI_Point(draw_x6, draw_y6, color);
  447.   }
  448.   if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )
  449.   {  GUI_Point(draw_x7, draw_y7, color);
  450.   }
  451.    }
  452. }
  453. /****************************************************************************
  454. * 名称:GUI_CircleFill()
  455. * 功能:指定圆心位置及半径,画圆并填充,填充色与边框色一样。
  456. * 入口参数: x0 圆心的x坐标值
  457. *           y0 圆心的y坐标值
  458. *           r       圆的半径
  459. *           color 填充颜色
  460. * 出口参数:无
  461. * 说明:操作失败原因是指定地址超出有效范围。
  462. ****************************************************************************/
  463. void  GUI_CircleFill(uint32 x0, uint32 y0, uint32 r, TCOLOR color)
  464. {  int32  draw_x0, draw_y0; // 刽图点坐标变量
  465.    int32  draw_x1, draw_y1;
  466.    int32  draw_x2, draw_y2;
  467.    int32  draw_x3, draw_y3;
  468.    int32  draw_x4, draw_y4;
  469.    int32  draw_x5, draw_y5;
  470.    int32  draw_x6, draw_y6;
  471.    int32  draw_x7, draw_y7;
  472.    int32  fill_x0, fill_y0; // 填充所需的变量,使用垂直线填充
  473.    int32  fill_x1;
  474.    int32  xx, yy; // 画圆控制变量
  475.  
  476.    int32  di; // 决策变量
  477.    
  478.    /* 参数过滤 */
  479.    if(0==r) return;
  480.    
  481.    /* 计算出4个特殊点(0、90、180、270度),进行显示 */
  482.    draw_x0 = draw_x1 = x0;
  483.    draw_y0 = draw_y1 = y0 + r;
  484.    if(draw_y0<GUI_LCM_YMAX)
  485.    {  GUI_Point(draw_x0, draw_y0, color); // 90度
  486.    }
  487.     
  488.    draw_x2 = draw_x3 = x0;
  489.    draw_y2 = draw_y3 = y0 - r;
  490.    if(draw_y2>=0)
  491.    {  GUI_Point(draw_x2, draw_y2, color); // 270度
  492.    }
  493.   
  494.    draw_x4 = draw_x6 = x0 + r;
  495.    draw_y4 = draw_y6 = y0;
  496.    if(draw_x4<GUI_LCM_XMAX) 
  497.    {  GUI_Point(draw_x4, draw_y4, color); // 0度
  498.       fill_x1 = draw_x4;
  499.    }
  500.    else
  501.    {  fill_x1 = GUI_LCM_XMAX;
  502.    }
  503.    fill_y0 = y0; // 设置填充线条起始点fill_x0
  504.    fill_x0 = x0 - r; // 设置填充线条结束点fill_y1
  505.    if(fill_x0<0) fill_x0 = 0;
  506.    GUI_HLine(fill_x0, fill_y0, fill_x1, color);
  507.    
  508.    draw_x5 = draw_x7 = x0 - r;
  509.    draw_y5 = draw_y7 = y0;
  510.    if(draw_x5>=0) 
  511.    {  GUI_Point(draw_x5, draw_y5, color); // 180度
  512.    }
  513.    if(1==r) return;
  514.    
  515.    
  516.    /* 使用Bresenham法进行画圆 */
  517.    di = 3 - 2*r; // 初始化决策变量
  518.    
  519.    xx = 0;
  520.    yy = r;
  521.    while(xx<yy)
  522.    {  if(di<0)
  523.   {  di += 4*xx + 6;
  524.   }
  525.   else
  526.   {  di += 4*(xx - yy) + 10;
  527.   
  528.      yy--;   
  529.  draw_y0--;
  530.  draw_y1--;
  531.  draw_y2++;
  532.  draw_y3++;
  533.  draw_x4--;
  534.  draw_x5++;
  535.  draw_x6--;
  536.  draw_x7++;  
  537.   }
  538.   
  539.   xx++;   
  540.   draw_x0++;
  541.   draw_x1--;
  542.   draw_x2++;
  543.   draw_x3--;
  544.   draw_y4++;
  545.   draw_y5++;
  546.   draw_y6--;
  547.   draw_y7--;
  548.   /* 要判断当前点是否在有效范围内 */
  549.   if( (draw_x0<=GUI_LCM_XMAX)&&(draw_y0>=0) )
  550.   {  GUI_Point(draw_x0, draw_y0, color);
  551.   }     
  552.   if( (draw_x1>=0)&&(draw_y1>=0) )
  553.   {  GUI_Point(draw_x1, draw_y1, color);
  554.   }
  555.   
  556.   /* 第二点水直线填充(下半圆的点) */
  557.   if(draw_x1>=0)
  558.   {  /* 设置填充线条起始点fill_x0 */
  559.      fill_x0 = draw_x1;
  560.      /* 设置填充线条起始点fill_y0 */
  561.      fill_y0 = draw_y1;
  562.          if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
  563.          if(fill_y0<0) fill_y0 = 0; 
  564.          /* 设置填充线条结束点fill_x1 */
  565.          fill_x1 = x0*2 - draw_x1;
  566.          if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
  567.          GUI_HLine(fill_x0, fill_y0, fill_x1, color);
  568.       }
  569.   
  570.   
  571.   if( (draw_x2<=GUI_LCM_XMAX)&&(draw_y2<=GUI_LCM_YMAX) )
  572.   {  GUI_Point(draw_x2, draw_y2, color);   
  573.   }
  574.        
  575.   if( (draw_x3>=0)&&(draw_y3<=GUI_LCM_YMAX) )
  576.   {  GUI_Point(draw_x3, draw_y3, color);
  577.   }
  578.   
  579.   /* 第四点垂直线填充(上半圆的点) */
  580.   if(draw_x3>=0)
  581.   {  /* 设置填充线条起始点fill_x0 */
  582.      fill_x0 = draw_x3;
  583.      /* 设置填充线条起始点fill_y0 */
  584.      fill_y0 = draw_y3;
  585.          if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
  586.          if(fill_y0<0) fill_y0 = 0;
  587.          /* 设置填充线条结束点fill_x1 */
  588.          fill_x1 = x0*2 - draw_x3;
  589.          if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
  590.          GUI_HLine(fill_x0, fill_y0, fill_x1, color);
  591.       }
  592.   
  593.      
  594.   if( (draw_x4<=GUI_LCM_XMAX)&&(draw_y4>=0) )
  595.   {  GUI_Point(draw_x4, draw_y4, color);
  596.   }
  597.   if( (draw_x5>=0)&&(draw_y5>=0) )
  598.   {  GUI_Point(draw_x5, draw_y5, color);
  599.   }
  600.   
  601.   /* 第六点垂直线填充(上半圆的点) */
  602.   if(draw_x5>=0)
  603.   {  /* 设置填充线条起始点fill_x0 */
  604.      fill_x0 = draw_x5;
  605.      /* 设置填充线条起始点fill_y0 */
  606.      fill_y0 = draw_y5;
  607.          if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
  608.          if(fill_y0<0) fill_y0 = 0;
  609.          /* 设置填充线条结束点fill_x1 */
  610.          fill_x1 = x0*2 - draw_x5;
  611.          if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
  612.          GUI_HLine(fill_x0, fill_y0, fill_x1, color);
  613.       }
  614.   
  615.   
  616.   if( (draw_x6<=GUI_LCM_XMAX)&&(draw_y6<=GUI_LCM_YMAX) )
  617.   {  GUI_Point(draw_x6, draw_y6, color);
  618.   }
  619.   
  620.   if( (draw_x7>=0)&&(draw_y7<=GUI_LCM_YMAX) )
  621.   {  GUI_Point(draw_x7, draw_y7, color);
  622.   }
  623.   
  624.   /* 第八点垂直线填充(上半圆的点) */
  625.   if(draw_x7>=0)
  626.   {  /* 设置填充线条起始点fill_x0 */
  627.      fill_x0 = draw_x7;
  628.      /* 设置填充线条起始点fill_y0 */
  629.      fill_y0 = draw_y7;
  630.          if(fill_y0>GUI_LCM_YMAX) fill_y0 = GUI_LCM_YMAX;
  631.          if(fill_y0<0) fill_y0 = 0;
  632.          /* 设置填充线条结束点fill_x1 */
  633.          fill_x1 = x0*2 - draw_x7;
  634.          if(fill_x1>GUI_LCM_XMAX) fill_x1 = GUI_LCM_XMAX;
  635.          GUI_HLine(fill_x0, fill_y0, fill_x1, color);
  636.       }
  637.   
  638.    }
  639. }
  640. #endif
  641. #if  GUI_EllipseX_EN==1
  642. /****************************************************************************
  643. * 名称:GUI_Ellipse()
  644. * 功能:画正椭圆。给定椭圆的四个点的参数,最左、最右点的x轴坐标值为x0、x1,最上、最下点
  645. *      的y轴坐标为y0、y1。
  646. * 入口参数: x0 最左点的x坐标值
  647. *           x1 最右点的x坐标值
  648. *           y0 最上点的y坐标值
  649. *           y1      最下点的y坐标值
  650. *           color 显示颜色
  651. * 出口参数:无
  652. * 说明:操作失败原因是指定地址超出有效范围。
  653. ****************************************************************************/
  654. void  GUI_Ellipse(uint32 x0, uint32 x1, uint32 y0, uint32 y1, TCOLOR color)
  655. {  int32  draw_x0, draw_y0; // 刽图点坐标变量
  656.    int32  draw_x1, draw_y1;
  657.    int32  draw_x2, draw_y2;
  658.    int32  draw_x3, draw_y3;
  659.    int32  xx, yy; // 画图控制变量
  660.     
  661.    int32  center_x, center_y; // 椭圆中心点坐标变量
  662.    int32  radius_x, radius_y; // 椭圆的半径,x轴半径和y轴半径
  663.    int32  radius_xx, radius_yy; // 半径乘平方值
  664.    int32  radius_xx2, radius_yy2; // 半径乘平方值的两倍
  665.    int32  di; // 定义决策变量
  666.    /* 参数过滤 */
  667.    if( (x0==x1) || (y0==y1) ) return;
  668.    
  669.    /* 计算出椭圆中心点坐标 */
  670.    center_x = (x0 + x1) >> 1;
  671.    center_y = (y0 + y1) >> 1;
  672.    
  673.    /* 计算出椭圆的半径,x轴半径和y轴半径 */
  674.    if(x0 > x1)
  675.    {  radius_x = (x0 - x1) >> 1;
  676.    }
  677.    else
  678.    {  radius_x = (x1 - x0) >> 1;
  679.    }
  680.    if(y0 > y1)
  681.    {  radius_y = (y0 - y1) >> 1;
  682.    }
  683.    else
  684.    {  radius_y = (y1 - y0) >> 1;
  685.    }
  686.    /* 计算半径平方值 */
  687.    radius_xx = radius_x * radius_x;
  688.    radius_yy = radius_y * radius_y;
  689.    /* 计算半径平方值乘2值 */
  690.    radius_xx2 = radius_xx<<1;
  691.    radius_yy2 = radius_yy<<1;
  692.    /* 初始化画图变量 */
  693.    xx = 0;
  694.    yy = radius_y;
  695.   
  696.    di = radius_yy2 + radius_xx - radius_xx2*radius_y ; // 初始化决策变量 
  697.    /* 计算出椭圆y轴上的两个端点坐标,作为作图起点 */
  698.    draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x;
  699.    draw_y0 = draw_y1 = center_y + radius_y;
  700.    draw_y2 = draw_y3 = center_y - radius_y;
  701.   
  702.  
  703.    GUI_Point(draw_x0, draw_y0, color); // 画y轴上的两个端点 
  704.    GUI_Point(draw_x2, draw_y2, color);
  705.    while( (radius_yy*xx) < (radius_xx*yy) ) 
  706.    {  if(di<0)
  707.   {  di+= radius_yy2*(2*xx+3);
  708.   }
  709.   else
  710.   {  di += radius_yy2*(2*xx+3) + 4*radius_xx - 4*radius_xx*yy;
  711.     
  712.      yy--;
  713.  draw_y0--;
  714.  draw_y1--;
  715.  draw_y2++;
  716.  draw_y3++;  
  717.   }
  718.   
  719.   xx ++; // x轴加1
  720.  
  721.   draw_x0++;
  722.   draw_x1--;
  723.   draw_x2++;
  724.   draw_x3--;
  725.   GUI_Point(draw_x0, draw_y0, color);
  726.   GUI_Point(draw_x1, draw_y1, color);
  727.   GUI_Point(draw_x2, draw_y2, color);
  728.   GUI_Point(draw_x3, draw_y3, color);
  729.    }
  730.   
  731.    di = radius_xx2*(yy-1)*(yy-1) + radius_yy2*xx*xx + radius_yy + radius_yy2*xx - radius_xx2*radius_yy;
  732.    while(yy>=0) 
  733.    {  if(di<0)
  734.   {  di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy;
  735.     
  736.      xx ++; // x轴加1  
  737.      draw_x0++;
  738.      draw_x1--;
  739.      draw_x2++;
  740.      draw_x3--;  
  741.   }
  742.   else
  743.   {  di += radius_xx2*3 - 2*radius_xx2*yy;            
  744.   }
  745.   
  746.   yy--;
  747.     draw_y0--;
  748.   draw_y1--;
  749.   draw_y2++;
  750.   draw_y3++;
  751.   GUI_Point(draw_x0, draw_y0, color);
  752.   GUI_Point(draw_x1, draw_y1, color);
  753.   GUI_Point(draw_x2, draw_y2, color);
  754.   GUI_Point(draw_x3, draw_y3, color);
  755.    }     
  756. }
  757. /****************************************************************************
  758. * 名称:GUI_EllipseFill()
  759. * 功能:画正椭圆,并填充。给定椭圆的四个点的参数,最左、最右点的x轴坐标值为x0、x1,最上、最下点
  760. *      的y轴坐标为y0、y1。
  761. * 入口参数: x0 最左点的x坐标值
  762. *           x1 最右点的x坐标值
  763. *           y0 最上点的y坐标值
  764. *           y1      最下点的y坐标值
  765. *           color 填充颜色
  766. * 出口参数:无
  767. * 说明:操作失败原因是指定地址超出有效范围。
  768. ****************************************************************************/
  769. void  GUI_EllipseFill(uint32 x0, uint32 x1, uint32 y0, uint32 y1, TCOLOR color)
  770. {  int32  draw_x0, draw_y0; // 刽图点坐标变量
  771.    int32  draw_x1, draw_y1;
  772.    int32  draw_x2, draw_y2;
  773.    int32  draw_x3, draw_y3;
  774.    int32  xx, yy; // 画图控制变量
  775.     
  776.    int32  center_x, center_y; // 椭圆中心点坐标变量
  777.    int32  radius_x, radius_y; // 椭圆的半径,x轴半径和y轴半径
  778.    int32  radius_xx, radius_yy; // 半径乘平方值
  779.    int32  radius_xx2, radius_yy2; // 半径乘平方值的两倍
  780.    int32  di; // 定义决策变量
  781.    /* 参数过滤 */
  782.    if( (x0==x1) || (y0==y1) ) return;
  783.    
  784.    /* 计算出椭圆中心点坐标 */
  785.    center_x = (x0 + x1) >> 1;
  786.    center_y = (y0 + y1) >> 1;
  787.    
  788.    /* 计算出椭圆的半径,x轴半径和y轴半径 */
  789.    if(x0 > x1)
  790.    {  radius_x = (x0 - x1) >> 1;
  791.    }
  792.    else
  793.    {  radius_x = (x1 - x0) >> 1;
  794.    }
  795.    if(y0 > y1)
  796.    {  radius_y = (y0 - y1) >> 1;
  797.    }
  798.    else
  799.    {  radius_y = (y1 - y0) >> 1;
  800.    }
  801.    /* 计算半径乘平方值 */
  802.    radius_xx = radius_x * radius_x;
  803.    radius_yy = radius_y * radius_y;
  804.    /* 计算半径乘4值 */
  805.    radius_xx2 = radius_xx<<1;
  806.    radius_yy2 = radius_yy<<1;
  807.    
  808.     /* 初始化画图变量 */
  809.    xx = 0;
  810.    yy = radius_y;
  811.   
  812.    di = radius_yy2 + radius_xx - radius_xx2*radius_y ; // 初始化决策变量 
  813.    /* 计算出椭圆y轴上的两个端点坐标,作为作图起点 */
  814.    draw_x0 = draw_x1 = draw_x2 = draw_x3 = center_x;
  815.    draw_y0 = draw_y1 = center_y + radius_y;
  816.    draw_y2 = draw_y3 = center_y - radius_y;
  817.   
  818.  
  819.    GUI_Point(draw_x0, draw_y0, color); // 画y轴上的两个端点
  820.    GUI_Point(draw_x2, draw_y2, color);
  821.    while( (radius_yy*xx) < (radius_xx*yy) ) 
  822.    {  if(di<0)
  823.   {  di+= radius_yy2*(2*xx+3);
  824.   }
  825.   else
  826.   {  di += radius_yy2*(2*xx+3) + 4*radius_xx - 4*radius_xx*yy;
  827.     
  828.      yy--;
  829.  draw_y0--;
  830.  draw_y1--;
  831.  draw_y2++;
  832.  draw_y3++;  
  833.   }
  834.   
  835.   xx ++; // x轴加1
  836.  
  837.   draw_x0++;
  838.   draw_x1--;
  839.   draw_x2++;
  840.   draw_x3--;
  841.   GUI_Point(draw_x0, draw_y0, color);
  842.   GUI_Point(draw_x1, draw_y1, color);
  843.   GUI_Point(draw_x2, draw_y2, color);
  844.   GUI_Point(draw_x3, draw_y3, color);
  845.   
  846.   /* 若y轴已变化,进行填充 */
  847.   if(di>=0)
  848.   {  GUI_HLine(draw_x0, draw_y0, draw_x1, color);
  849.      GUI_HLine(draw_x2, draw_y2, draw_x3, color);
  850.   }
  851.    }
  852.   
  853.    di = radius_xx2*(yy-1)*(yy-1) + radius_yy2*xx*xx + radius_yy + radius_yy2*xx - radius_xx2*radius_yy;
  854.    while(yy>=0) 
  855.    {  if(di<0)
  856.   {  di+= radius_xx2*3 + 4*radius_yy*xx + 4*radius_yy - 2*radius_xx2*yy;
  857.     
  858.      xx ++; // x轴加1  
  859.      draw_x0++;
  860.      draw_x1--;
  861.      draw_x2++;
  862.      draw_x3--;  
  863.   }
  864.   else
  865.   {  di += radius_xx2*3 - 2*radius_xx2*yy;            
  866.   }
  867.   
  868.   yy--;
  869.     draw_y0--;
  870.   draw_y1--;
  871.   draw_y2++;
  872.   draw_y3++;
  873.   GUI_Point(draw_x0, draw_y0, color);
  874.   GUI_Point(draw_x1, draw_y1, color);
  875.   GUI_Point(draw_x2, draw_y2, color);
  876.   GUI_Point(draw_x3, draw_y3, color);
  877.   
  878.   /* y轴已变化,进行填充 */
  879.   GUI_HLine(draw_x0, draw_y0, draw_x1, color);
  880.   GUI_HLine(draw_x2, draw_y2, draw_x3, color); 
  881.    }     
  882. }
  883. #endif
  884. #if  GUI_FloodFill_EN==1
  885. /****************************************************************************
  886. * 名称:GUI_ReadLeftPoint()
  887. * 功能:找出指定点左边最近的非color点。
  888. * 入口参数: x0 指定点的x坐标值
  889. *           y0 指定点的y坐标值
  890. *           color 指定颜色值
  891. * 出口参数:返回该点的x轴坐标值。
  892. * 说明:若没有找出,则返回最左的x坐标0。
  893. ****************************************************************************/
  894. uint32  GUI_ReadLeftPoint(uint32 x0, uint32 y0, TCOLOR color)
  895. {  uint32  i;
  896.    TCOLOR  bakc;
  897.    
  898.    for(i=x0-1; i>0; i--)
  899.    {  GUI_ReadPoint(i, y0, &bakc);
  900.       if( GUI_CmpColor(bakc,color)==0 ) return(i+1); // 若找到,则返回
  901.    }
  902.    GUI_ReadPoint(i, y0, &bakc);
  903.    if( GUI_CmpColor(bakc,color)==0 ) return(1); // 若找到,则返回
  904.    
  905.    return(0);
  906. }
  907. /****************************************************************************
  908. * 名称:GUI_ReadRightPoint()
  909. * 功能:找出指定点右边最近的非color点。
  910. * 入口参数: x0 指定点的x轴坐标值
  911. *           y0 指定点的y轴坐标值
  912. *           color 指定颜色值
  913. * 出口参数:返回该点的x轴坐标值。
  914. * 说明:若没有找出,则返回最右的x坐标GUI_LCM_XMAX。
  915. ****************************************************************************/
  916. uint32  GUI_ReadRightPoint(uint32 x0, uint32 y0, TCOLOR color)
  917. {  uint32  i;
  918.    TCOLOR  bakc;
  919.    
  920.    for(i=x0+1; i<GUI_LCM_XMAX; i++)
  921.    {  GUI_ReadPoint(i, y0, &bakc);
  922.       if( GUI_CmpColor(bakc,color)==0 ) return(i-1); // 若找到,则返回
  923.    }
  924.    return(GUI_LCM_XMAX);
  925. }
  926. /****************************************************************************
  927. * 名称:GUI_CmpPointColor()
  928. * 功能:判断指定点上的颜色是否为某种颜色。
  929. * 入口参数:x 指定点的x轴坐标值
  930. *    y 指定点的y轴坐标值
  931. *          color 颜色值
  932. * 出口参数:返回1表示相同,返回0表示不相同。
  933. * 说明:
  934. ****************************************************************************/
  935. int  GUI_CmpPointColor(uint32 x, uint32 y, TCOLOR color)
  936. {  TCOLOR  bakc;
  937.    
  938.    GUI_ReadPoint(x, y, &bakc);
  939.    return( GUI_CmpColor(bakc,color) );
  940. }
  941. /* 定义折点个数 */
  942. #ifndef  DOWNP_N
  943. #define  DOWNP_N 20
  944. #endif
  945. #ifndef  UPP_N
  946. #define  UPP_N 20
  947. #endif
  948. /****************************************************************************
  949. * 名称:GUI_FloodFill()
  950. * 功能:图形填充,将指定点内的封闭图形进行填充。对指定点的颜色区域进行填充,即不是该颜色
  951. *      的像素为边界(如,指定点上的颜色为红色,则其它颜色像素均为边界)。
  952. * 入口参数: x0 指定点的x坐标值
  953. *           y0 指定点的y坐标值
  954. *           color 填充颜色
  955. * 出口参数:无
  956. * 说明:操作失败原因是指定地址超出有效范围、指定点不在封闭图形内。
  957. ****************************************************************************/
  958. void  GUI_FloodFill(uint32 x0, uint32 y0, TCOLOR color)
  959. {  PointXY  down_point[DOWNP_N]; // 定义向下填充转折点缓冲区
  960.    uint8    down_no; // 向下折点个数
  961.    PointXY  up_point[UPP_N]; // 定义向上填充转折点缓冲区
  962.    uint8    up_no; // 向上折点个数
  963.    TCOLOR   fcolor; // 填充点上的颜色
  964.    
  965.    uint32  xx, yy; // 填充临时x,y变量 (当前填充行的中点)
  966.    uint32  xx0; // 当前填充行的左x值变量
  967.    uint32  xx1; // 当前填充行的右y值变量
  968.    uint32  i;
  969.    
  970.    uint32  x0_bak, y0_bak;
  971.    uint32  x1_bak;
  972.    
  973.    /* 参数过滤 */
  974.    if(x0>=GUI_LCM_XMAX) return;
  975.    if(y0>=GUI_LCM_YMAX) return;
  976.    
  977.    /* 判断指定点是否为填充颜色,若是则直接返回 */
  978.    GUI_ReadPoint(x0, y0, &fcolor); // 取得填充点的颜色
  979.    if( GUI_CmpColor(fcolor,color)!=0 ) return;
  980.    
  981.    y0_bak = y0;
  982.    x0_bak = xx0 = GUI_ReadLeftPoint(x0, y0, fcolor); // 找出当前y坐标上的最左边的点
  983.    x1_bak = xx1 = GUI_ReadRightPoint(x0, y0, fcolor); // 找出当前y坐标上的最右边的点
  984.    down_point[0].x = up_point[0].x = (xx1 + xx0)/2;
  985.    down_point[0].y = up_point[0].y = y0;
  986.    down_no = 1;
  987.    up_no = 1;
  988.    
  989.    /* 开始向上填充 */
  990. FILL_UP:  
  991.    if(0==up_no) goto FILL_DOWN; // 若向下扫描已完成,则退出
  992.    xx = up_point[up_no-1].x; // 否则取出下一折点
  993.    yy = up_point[up_no-1].y;
  994.    up_no--; 
  995.    xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
  996.    xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
  997.    while(1) 
  998.    {  yy += 1; // 中心点向上一点
  999.        
  1000.       if( GUI_CmpPointColor(xx, yy, fcolor)==0 )
  1001.       {  /* 判断此点是否为终点,若是则退出此次循环 */
  1002.          for(i=xx0; i<=xx1; i++)      // 查找此行是否有需填充点
  1003.          {  if( GUI_CmpPointColor(i, yy, fcolor)!=0 ) break;
  1004.          }
  1005.          if(i>xx1) goto FILL_UP; 
  1006.          
  1007.          /* 找出新一行中最右边的点 */
  1008.          xx = i; // 更新xx到要填充的有效区域内
  1009.          xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
  1010.       }
  1011.       else
  1012.       {  /* 找出新一行中最右边的点 */
  1013.          xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
  1014.       }
  1015.       xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
  1016.       
  1017.       /* 向下折点。使用y0作为折点变量,x0作为上一折点变量 */
  1018.       if(down_no<DOWNP_N)
  1019.       {  y0 = xx0;
  1020.          x0 = y0-1;
  1021.          for(i=y0; i<=xx1; i++)
  1022.          {  if( GUI_CmpPointColor(i, yy-1, fcolor)==0 ) // 更新折点
  1023.             {  y0 = i;
  1024.             }
  1025.             else
  1026.             {  if(x0!=y0) // 找到新的折点
  1027.                {  x0 = y0;
  1028.                   down_point[down_no].x = i;
  1029.                   down_point[down_no].y = yy;
  1030.                   down_no++;
  1031.                }
  1032.             }
  1033.             if(down_no>=DOWNP_N) break; // 若缓冲区已保存满,则退出
  1034.          } // end  of for(i=y0+1; i<xx1; i++)
  1035.       } // end of if(down_no<DOWNP_N)
  1036.       
  1037.       xx = (xx1 + xx0)/2; // 更新中心点
  1038.       GUI_HLine(xx0, yy, xx1, color); // 填充一行
  1039.       
  1040.       /* 向上折点。使用y0作为折点变量,x0作为上一折点变量 */
  1041.       if(up_no<UPP_N)
  1042.       {  y0 = xx0;
  1043.          x0 = y0-1;
  1044.          for(i=y0; i<=xx1; i++)
  1045.          {  if( GUI_CmpPointColor(i, yy+1, fcolor)==0 ) // 更新折点
  1046.             {  y0 = i;
  1047.             }
  1048.             else
  1049.             {  if(x0!=y0) // 找到新的折点
  1050.                {  x0 = y0;
  1051.                   up_point[up_no].x = i;
  1052.                   up_point[up_no].y = yy;
  1053.                   up_no++;
  1054.                }
  1055.             }
  1056.             if(up_no>=UPP_N) break; // 若缓冲区已保存满,则退出
  1057.          }
  1058.       } // end of if(up_no<UPP_N)
  1059.       
  1060.    } // end of while(1) 
  1061.    /* 向下填充 */
  1062. FILL_DOWN: 
  1063.    if(0==down_no) 
  1064.    {  if(0==up_no) 
  1065.       {  GUI_HLine(x0_bak, y0_bak, x1_bak, color);
  1066.          return; // 若向下扫描已完成,且没有发现新的向上折点,则退出
  1067.       }
  1068.       else
  1069.       {  goto FILL_UP;
  1070.       }
  1071.    }
  1072.    xx = down_point[down_no-1].x; // 否则取出下一折点
  1073.    yy = down_point[down_no-1].y;
  1074.    down_no--;
  1075.    xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
  1076.    xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
  1077.    
  1078.    while(1) 
  1079.    {  yy -= 1; // 中心点向上一点 
  1080.       if( GUI_CmpPointColor(xx, yy, fcolor)==0 )
  1081.       {  /* 判断此点是否为终点,若是则退出此次循环 */
  1082.          for(i=xx0; i<=xx1; i++)      // 查找下一行是否有需填充点
  1083.          {  if( GUI_CmpPointColor(i, yy, fcolor)!=0 ) break;
  1084.          }
  1085.          if(i>xx1) goto FILL_DOWN; 
  1086.          
  1087.          /* 找出新一行中最右边的点 */
  1088.          xx = i;
  1089.          xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
  1090.       }
  1091.       else
  1092.       {  /* 找出新一行中最右边的点 */
  1093.          xx1 = GUI_ReadRightPoint(xx, yy, fcolor);
  1094.       }
  1095.       xx0 = GUI_ReadLeftPoint(xx, yy, fcolor);
  1096.             
  1097.       /* 向上折点。使用y0作为折点变量,x0作为上一折点变量 */
  1098.       if(up_no<UPP_N)
  1099.       {  y0 = xx0;
  1100.          x0 = y0-1;
  1101.          for(i=y0; i<=xx1; i++)
  1102.          {  if( GUI_CmpPointColor(i, yy+1, fcolor)==0 ) // 更新折点
  1103.             {  y0 = i;
  1104.             }
  1105.             else
  1106.             {  if(x0!=y0) // 找到新的折点
  1107.                {  x0 = y0;
  1108.                   up_point[up_no].x = i;
  1109.                   up_point[up_no].y = yy;
  1110.                   up_no++;
  1111.                }
  1112.             }
  1113.             if(up_no>=UPP_N) break; // 若缓冲区已保存满,则退出
  1114.          }
  1115.       }
  1116.             
  1117.       xx = (xx1 + xx0)/2; 
  1118.       GUI_HLine(xx0, yy, xx1, color); // 填充一行
  1119.       
  1120.       /* 向下折点。使用y0作为折点变量,x0作为上一折点变量 */
  1121.       if(down_no<DOWNP_N)
  1122.       {  y0 = xx0;
  1123.          x0 = y0-1;
  1124.          for(i=y0; i<=xx1; i++)
  1125.          {  if( GUI_CmpPointColor(i, yy-1, fcolor)==0 ) // 更新折点
  1126.             {  y0 = i;
  1127.             }
  1128.             else
  1129.             {  if(x0!=y0) // 找到新的折点
  1130.                {  x0 = y0;
  1131.                   down_point[down_no].x = i;
  1132.                   down_point[down_no].y = yy;
  1133.                   down_no++;
  1134.                }
  1135.             }
  1136.             if(down_no>=DOWNP_N) break; // 若缓冲区已保存满,则退出
  1137.          }
  1138.       } // end of if(down_no<DOWNP_N)
  1139.       
  1140.    } // end of while(1) 
  1141.    
  1142.    GUI_HLine(x0_bak, y0_bak, x1_bak, color);
  1143. }
  1144. #endif
  1145. #if  GUI_ArcX_EN==1
  1146. /****************************************************************************
  1147. * 名称:GUI_Arc4()
  1148. * 功能:画弧。起点及终点只能为0度-90度、90度-180度、180度-270度、270度-0度等。即分别
  1149. *      为第1-4像限的90度弧。
  1150. * 入口参数: x0 圆心的x坐标值
  1151. *           y0 圆心的y坐标值
  1152. *           r       圆弧的半径
  1153. *           angle 画弧的像限(1-4)
  1154. *           color 显示颜色
  1155. * 出口参数:无
  1156. * 说明:操作失败原因是指定地址超出有效范围。
  1157. ****************************************************************************/
  1158. void  GUI_Arc4(uint32 x, uint32 y, uint32 r, uint8 angle, TCOLOR color)
  1159. {  int32  draw_x, draw_y;
  1160.    int32  op_x, op_y;
  1161.    int32  op_2rr;
  1162.    
  1163.    if(r==0) return;
  1164.    
  1165.    op_2rr = 2*r*r; // 计算r平方乖以2
  1166.    
  1167.    switch(angle)
  1168.    {  case  1:
  1169.             draw_x = x+r;
  1170.             draw_y = y;
  1171.             
  1172.             op_x = r;
  1173.             op_y = 0;
  1174.  
  1175.             while(1)
  1176.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1177.                  
  1178.                /* 计算下一点 */
  1179.                op_y++;
  1180.                draw_y++;
  1181.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1182.                {  op_x--;
  1183.                   draw_x--;
  1184.                }
  1185.                if(op_y>=op_x) break;
  1186.             }
  1187.             while(1)
  1188.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1189.                  
  1190.                /* 计算下一点 */
  1191.                op_x--;
  1192.                draw_x--;
  1193.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 )  // 使用逐点比较法实现画圆弧
  1194.                {  op_y++;
  1195.                   draw_y++;
  1196.                }
  1197.                if(op_x<=0)
  1198.                {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1199.                   break;
  1200.                }
  1201.             }
  1202.    
  1203.             break;      
  1204.    
  1205.       case  2:
  1206.             draw_x = x-r;
  1207.             draw_y = y;
  1208.             
  1209.             op_x = r;
  1210.             op_y = 0;
  1211.  
  1212.             while(1)
  1213.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1214.                  
  1215.                /* 计算下一点 */
  1216.                op_y++;
  1217.                draw_y++;
  1218.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1219.                {  op_x--;
  1220.                   draw_x++;
  1221.                }
  1222.                if(op_y>=op_x) break;
  1223.             }
  1224.             while(1)
  1225.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1226.                  
  1227.                /* 计算下一点 */
  1228.                op_x--;
  1229.                draw_x++;
  1230.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 )  // 使用逐点比较法实现画圆弧
  1231.                {  op_y++;
  1232.                   draw_y++;
  1233.                }
  1234.                if(op_x<=0)
  1235.                {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1236.                   break;
  1237.                }
  1238.             }
  1239.   
  1240.             break;
  1241.             
  1242.       case  3:
  1243.             draw_x = x-r;
  1244.             draw_y = y;
  1245.             
  1246.             op_x = r;
  1247.             op_y = 0;
  1248.  
  1249.             while(1)
  1250.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1251.                  
  1252.                /* 计算下一点 */
  1253.                op_y++;
  1254.                draw_y--;
  1255.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1256.                {  op_x--;
  1257.                   draw_x++;
  1258.                }
  1259.                if(op_y>=op_x) break;
  1260.             }
  1261.             while(1)
  1262.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1263.                  
  1264.                /* 计算下一点 */
  1265.                op_x--;
  1266.                draw_x++;
  1267.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 )  // 使用逐点比较法实现画圆弧
  1268.                {  op_y++;
  1269.                   draw_y--;
  1270.                }
  1271.                if(op_x<=0)
  1272.                {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1273.                   break;
  1274.                }
  1275.             }
  1276.       
  1277.             break;
  1278.             
  1279.       case  4:
  1280.             draw_x = x+r;
  1281.             draw_y = y;
  1282.             
  1283.             op_x = r;
  1284.             op_y = 0;
  1285.  
  1286.             while(1)
  1287.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1288.                  
  1289.                /* 计算下一点 */
  1290.                op_y++;
  1291.                draw_y--;
  1292.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1293.                {  op_x--;
  1294.                   draw_x--;
  1295.                }
  1296.                if(op_y>=op_x) break;
  1297.             }
  1298.             while(1)
  1299.             {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1300.                  
  1301.                /* 计算下一点 */
  1302.                op_x--;
  1303.                draw_x--;
  1304.                if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 )  // 使用逐点比较法实现画圆弧
  1305.                {  op_y++;
  1306.                   draw_y--;
  1307.                }
  1308.                if(op_x<=0)
  1309.                {  GUI_Point(draw_x, draw_y, color); // 开始画图
  1310.                   break;
  1311.                }
  1312.             }
  1313.             break;
  1314.             
  1315.       default:
  1316.             break;
  1317.       
  1318.    }
  1319. }
  1320. /****************************************************************************
  1321. * 名称:GUI_Arc()
  1322. * 功能:指定起点、终点及半径画弧(不能画圆)。使用的是顺时针方向画图。
  1323. * 入口参数: x 圆心的x轴坐标值
  1324. *           y 圆心的y轴坐标值
  1325. *           stangle  起始角度(0-359度)
  1326. *           endangle 终止角度(0-359度)
  1327. *           r   圆的半径终点
  1328. *           color 显示颜色
  1329. * 出口参数:无
  1330. * 说明:操作失败原因是指定地址超出有效范围。
  1331. ****************************************************************************/
  1332. void  GUI_Arc(uint32 x, uint32 y, uint32 r, uint32 stangle, uint32 endangle, TCOLOR color)
  1333. {  int32  draw_x, draw_y; // 画图坐标变量
  1334.    int32  op_x, op_y; // 操作坐标
  1335.    int32  op_2rr; // 2*r*r值变量
  1336.    
  1337.    int32  pno_angle; // 度角点的个数
  1338.    uint8  draw_on; // 画点开关,为1时画点,为0时不画
  1339.    
  1340.    
  1341.    /* 参数过滤 */
  1342.    if(r==0) return; // 半径为0则直接退出
  1343.    if(stangle==endangle) return; // 起始角度与终止角度相同,退出
  1344.    if( (stangle>=360) || (endangle>=360) ) return;
  1345.    op_2rr = 2*r*r; // 计算r平方乖以2
  1346.    pno_angle = 0;
  1347.    /* 先计算出在此半径下的45度的圆弧的点数 */       
  1348.    op_x = r;
  1349.    op_y = 0;
  1350.    while(1)
  1351.    {  pno_angle++;  // 画点计数         
  1352.       /* 计算下一点 */
  1353.       op_y++;
  1354.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1355.       {  op_x--;
  1356.       }
  1357.       if(op_y>=op_x) break;
  1358.    }
  1359.    
  1360.    draw_on = 0; // 最开始关画点开关
  1361.    /* 设置起始点及终点 */
  1362.    if(endangle>stangle) draw_on = 1; // 若终点大于起点,则从一开始即画点(359)
  1363.    stangle = (360-stangle)*pno_angle/45;
  1364.    endangle = (360-endangle)*pno_angle/45;
  1365.    if(stangle==0) stangle=1;
  1366.    if(endangle==0) endangle=1;
  1367.    
  1368.    /* 开始顺时针画弧,从359度开始(第4像限) */
  1369.    pno_angle = 0;
  1370.    
  1371.    draw_x = x+r;
  1372.    draw_y = y;         
  1373.    op_x = r;
  1374.    op_y = 0;
  1375.    while(1)
  1376.    {  /* 计算下一点 */
  1377.       op_y++;
  1378.       draw_y--;
  1379.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1380.       {  op_x--;
  1381.          draw_x--;
  1382.       }
  1383.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1384.       pno_angle++;
  1385.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1386.       {  draw_on = 1-draw_on;
  1387.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1388.       } 
  1389.       if(op_y>=op_x)
  1390.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1391.          break;
  1392.       }
  1393.    }
  1394.    
  1395.    while(1)
  1396.    {  /* 计算下一点 */
  1397.       op_x--;
  1398.       draw_x--;
  1399.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐点比较法实现画圆弧
  1400.       {  op_y++;
  1401.          draw_y--;
  1402.       }
  1403.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1404.       pno_angle++;
  1405.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1406.       {  draw_on = 1-draw_on;
  1407.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1408.       } 
  1409.       
  1410.       if(op_x<=0)
  1411.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1412.          break;
  1413.       }
  1414.    }
  1415.     
  1416.     
  1417.    /* 开始顺时针画弧,从269度开始(第3像限) */
  1418.    draw_y = y-r;
  1419.    draw_x = x;         
  1420.    op_y = r;
  1421.    op_x = 0;
  1422.    while(1)
  1423.    {  /* 计算下一点 */
  1424.       op_x++;
  1425.       draw_x--;
  1426.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_y +1)>0 ) // 使用逐点比较法实现画圆弧
  1427.       {  op_y--;
  1428.          draw_y++;
  1429.       }
  1430.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1431.       pno_angle++;
  1432.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1433.       {  draw_on = 1-draw_on;
  1434.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1435.       } 
  1436.       
  1437.       if(op_x>=op_y)
  1438.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1439.          break;
  1440.       }
  1441.    }
  1442.    
  1443.    while(1)
  1444.    {  /* 计算下一点 */
  1445.       op_y--;
  1446.       draw_y++;
  1447.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_x +1)<=0 ) // 使用逐点比较法实现画圆弧
  1448.       {  op_x++;
  1449.          draw_x--;
  1450.       }
  1451.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1452.       pno_angle++;
  1453.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1454.       {  draw_on = 1-draw_on;
  1455.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1456.       } 
  1457.       if(op_y<=0)
  1458.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1459.          break;
  1460.       }
  1461.    }
  1462.    
  1463.    
  1464.    /* 开始顺时针画弧,从179度开始(第2像限) */
  1465.    draw_x = x-r;
  1466.    draw_y = y;         
  1467.    op_x = r;
  1468.    op_y = 0;
  1469.    while(1)
  1470.    {  /* 计算下一点 */
  1471.       op_y++;
  1472.       draw_y++;
  1473.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1474.       {  op_x--;
  1475.          draw_x++;
  1476.       }
  1477.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1478.       pno_angle++;
  1479.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1480.       {  draw_on = 1-draw_on;
  1481.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1482.       } 
  1483.       if(op_y>=op_x)
  1484.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1485.          break;
  1486.       }
  1487.    }
  1488.    
  1489.    while(1)
  1490.    {  /* 计算下一点 */
  1491.       op_x--;
  1492.       draw_x++;
  1493.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐点比较法实现画圆弧
  1494.       {  op_y++;
  1495.          draw_y++;
  1496.       }
  1497.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1498.       pno_angle++;
  1499.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1500.       {  draw_on = 1-draw_on;
  1501.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1502.       } 
  1503.       
  1504.       if(op_x<=0)
  1505.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1506.          break;
  1507.       }
  1508.    }
  1509.   
  1510.   
  1511.    /* 开始顺时针画弧,从89度开始(第1像限) */
  1512.    draw_y = y+r;
  1513.    draw_x = x;         
  1514.    op_y = r;
  1515.    op_x = 0;
  1516.    while(1)
  1517.    {  /* 计算下一点 */
  1518.       op_x++;
  1519.       draw_x++;
  1520.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_y +1)>0 ) // 使用逐点比较法实现画圆弧
  1521.       {  op_y--;
  1522.          draw_y--;
  1523.       }
  1524.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1525.       pno_angle++;
  1526.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1527.       {  draw_on = 1-draw_on;
  1528.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1529.       } 
  1530.       
  1531.       if(op_x>=op_y)
  1532.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1533.          break;
  1534.       }
  1535.    }
  1536.    
  1537.    while(1)
  1538.    {  /* 计算下一点 */
  1539.       op_y--;
  1540.       draw_y--;
  1541.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_x +1)<=0 ) // 使用逐点比较法实现画圆弧
  1542.       {  op_x++;
  1543.          draw_x++;
  1544.       }
  1545.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1546.       pno_angle++;
  1547.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1548.       {  draw_on = 1-draw_on;
  1549.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1550.       } 
  1551.       if(op_y<=0)
  1552.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1553.          break;
  1554.       }
  1555.    }
  1556.    
  1557. }
  1558. #endif
  1559. #if  GUI_Pieslice_EN==1
  1560. /****************************************************************************
  1561. * 名称:GUI_Pieslice()
  1562. * 功能:指定起点、终点及半径扇形(不能画圆)。使用的是顺时针方向画图。
  1563. * 入口参数: x 圆心的x轴坐标值
  1564. *           y 圆心的y轴坐标值
  1565. *           stangle  起始角度(0-359度)
  1566. *           endangle 终止角度(0-359度)
  1567. *           r   圆的半径终点
  1568. *           color 显示颜色
  1569. * 出口参数:无
  1570. * 说明:操作失败原因是指定地址超出有效范围。
  1571. ****************************************************************************/
  1572. void  GUI_Pieslice(uint32 x, uint32 y, uint32 r, uint32 stangle, uint32 endangle, TCOLOR color)
  1573. {  int32  draw_x, draw_y; // 画图坐标变量
  1574.    int32  op_x, op_y; // 操作坐标
  1575.    int32  op_2rr; // 2*r*r值变量
  1576.    
  1577.    int32  pno_angle; // 度角点的个数
  1578.    uint8  draw_on; // 画点开关,为1时画点,为0时不画
  1579.    
  1580.    
  1581.    /* 参数过滤 */
  1582.    if(r==0) return; // 半径为0则直接退出
  1583.    if(stangle==endangle) return; // 起始角度与终止角度相同,退出
  1584.    if( (stangle>=360) || (endangle>=360) ) return;
  1585.    op_2rr = 2*r*r; // 计算r平方乖以2
  1586.    pno_angle = 0;
  1587.    /* 先计算出在此半径下的45度的圆弧的点数 */       
  1588.    op_x = r;
  1589.    op_y = 0;
  1590.    while(1)
  1591.    {  pno_angle++;  // 画点计数         
  1592.       /* 计算下一点 */
  1593.       op_y++;
  1594.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1595.       {  op_x--;
  1596.       }
  1597.       if(op_y>=op_x) break;
  1598.    }
  1599.    
  1600.    draw_on = 0; // 最开始关画点开关
  1601.    /* 设置起始点及终点 */
  1602.    if(endangle>stangle) draw_on = 1; // 若终点大于起点,则从一开始即画点(359)
  1603.    stangle = (360-stangle)*pno_angle/45;
  1604.    endangle = (360-endangle)*pno_angle/45;
  1605.    if(stangle==0) stangle=1;
  1606.    if(endangle==0) endangle=1;
  1607.    
  1608.    /* 开始顺时针画弧,从359度开始(第4像限) */
  1609.    pno_angle = 0;
  1610.    
  1611.    draw_x = x+r;
  1612.    draw_y = y;         
  1613.    op_x = r;
  1614.    op_y = 0;
  1615.    while(1)
  1616.    {  /* 计算下一点 */
  1617.       op_y++;
  1618.       draw_y--;
  1619.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1620.       {  op_x--;
  1621.          draw_x--;
  1622.       }
  1623.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1624.       pno_angle++;
  1625.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1626.       {  draw_on = 1-draw_on;
  1627.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1628.          GUI_Line(x, y, draw_x, draw_y, color);
  1629.       } 
  1630.       if(op_y>=op_x)
  1631.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1632.          break;
  1633.       }
  1634.    }
  1635.    
  1636.    while(1)
  1637.    {  /* 计算下一点 */
  1638.       op_x--;
  1639.       draw_x--;
  1640.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐点比较法实现画圆弧
  1641.       {  op_y++;
  1642.          draw_y--;
  1643.       }
  1644.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1645.       pno_angle++;
  1646.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1647.       {  draw_on = 1-draw_on;
  1648.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1649.          GUI_Line(x, y, draw_x, draw_y, color);
  1650.       } 
  1651.       
  1652.       if(op_x<=0)
  1653.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1654.          break;
  1655.       }
  1656.    }
  1657.     
  1658.     
  1659.    /* 开始顺时针画弧,从269度开始(第3像限) */
  1660.    draw_y = y-r;
  1661.    draw_x = x;         
  1662.    op_y = r;
  1663.    op_x = 0;
  1664.    while(1)
  1665.    {  /* 计算下一点 */
  1666.       op_x++;
  1667.       draw_x--;
  1668.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_y +1)>0 ) // 使用逐点比较法实现画圆弧
  1669.       {  op_y--;
  1670.          draw_y++;
  1671.       }
  1672.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1673.       pno_angle++;
  1674.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1675.       {  draw_on = 1-draw_on;
  1676.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1677.          GUI_Line(x, y, draw_x, draw_y, color);
  1678.       } 
  1679.       
  1680.       if(op_x>=op_y)
  1681.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1682.          break;
  1683.       }
  1684.    }
  1685.    
  1686.    while(1)
  1687.    {  /* 计算下一点 */
  1688.       op_y--;
  1689.       draw_y++;
  1690.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_x +1)<=0 ) // 使用逐点比较法实现画圆弧
  1691.       {  op_x++;
  1692.          draw_x--;
  1693.       }
  1694.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1695.       pno_angle++;
  1696.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1697.       {  draw_on = 1-draw_on;
  1698.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1699.          GUI_Line(x, y, draw_x, draw_y, color);
  1700.       } 
  1701.       if(op_y<=0)
  1702.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1703.          break;
  1704.       }
  1705.    }
  1706.    
  1707.    
  1708.    /* 开始顺时针画弧,从179度开始(第2像限) */
  1709.    draw_x = x-r;
  1710.    draw_y = y;         
  1711.    op_x = r;
  1712.    op_y = 0;
  1713.    while(1)
  1714.    {  /* 计算下一点 */
  1715.       op_y++;
  1716.       draw_y++;
  1717.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_x +1)>0 )  // 使用逐点比较法实现画圆弧
  1718.       {  op_x--;
  1719.          draw_x++;
  1720.       }
  1721.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1722.       pno_angle++;
  1723.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1724.       {  draw_on = 1-draw_on;
  1725.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1726.          GUI_Line(x, y, draw_x, draw_y, color);
  1727.       } 
  1728.       if(op_y>=op_x)
  1729.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1730.          break;
  1731.       }
  1732.    }
  1733.    
  1734.    while(1)
  1735.    {  /* 计算下一点 */
  1736.       op_x--;
  1737.       draw_x++;
  1738.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_y +1)<=0 ) // 使用逐点比较法实现画圆弧
  1739.       {  op_y++;
  1740.          draw_y++;
  1741.       }
  1742.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1743.       pno_angle++;
  1744.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1745.       {  draw_on = 1-draw_on;
  1746.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1747.          GUI_Line(x, y, draw_x, draw_y, color);
  1748.       } 
  1749.       
  1750.       if(op_x<=0)
  1751.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1752.          break;
  1753.       }
  1754.    }
  1755.   
  1756.   
  1757.    /* 开始顺时针画弧,从89度开始(第1像限) */
  1758.    draw_y = y+r;
  1759.    draw_x = x;         
  1760.    op_y = r;
  1761.    op_x = 0;
  1762.    while(1)
  1763.    {  /* 计算下一点 */
  1764.       op_x++;
  1765.       draw_x++;
  1766.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr - 2*op_y +1)>0 ) // 使用逐点比较法实现画圆弧
  1767.       {  op_y--;
  1768.          draw_y--;
  1769.       }
  1770.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1771.       pno_angle++;
  1772.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1773.       {  draw_on = 1-draw_on;
  1774.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1775.          GUI_Line(x, y, draw_x, draw_y, color);
  1776.       } 
  1777.       
  1778.       if(op_x>=op_y)
  1779.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1780.          break;
  1781.       }
  1782.    }
  1783.    
  1784.    while(1)
  1785.    {  /* 计算下一点 */
  1786.       op_y--;
  1787.       draw_y--;
  1788.       if( (2*op_x*op_x + 2*op_y*op_y - op_2rr + 2*op_x +1)<=0 ) // 使用逐点比较法实现画圆弧
  1789.       {  op_x++;
  1790.          draw_x++;
  1791.       }
  1792.       if(draw_on==1) GUI_Point(draw_x, draw_y, color); // 开始画图
  1793.       pno_angle++;
  1794.       if( (pno_angle==stangle)||(pno_angle==endangle) ) // 若遇到起点或终点,画点开关取反
  1795.       {  draw_on = 1-draw_on;
  1796.          if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1797.          GUI_Line(x, y, draw_x, draw_y, color);
  1798.       } 
  1799.       if(op_y<=0)
  1800.       {  if(draw_on==1) GUI_Point(draw_x, draw_y, color);
  1801.          break;
  1802.       }
  1803.    }
  1804.    
  1805. }
  1806. #endif