GUICirc.c
上传用户:zbk8730
上传日期:2017-08-10
资源大小:12168k
文件大小:7k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2. *********************************************************************************************************
  3. *                                                uC/GUI
  4. *                        Universal graphic software for embedded applications
  5. *
  6. *                       (c) Copyright 2002, Micrium Inc., Weston, FL
  7. *                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
  8. *
  9. *              礐/GUI is protected by international copyright laws. Knowledge of the
  10. *              source code may not be used to write a similar product. This file may
  11. *              only be used in accordance with a license and should not be redistributed
  12. *              in any way. We appreciate your understanding and fairness.
  13. *
  14. ----------------------------------------------------------------------
  15. File        : GUICirc.C
  16. Purpose     : Circle and ellipse drawing functions
  17. ----------------------------------------------------------------------
  18. Version-Date---Author-Explanation
  19. ----------------------------------------------------------------------
  20. 1.00.02 011115 JE     a) GL_FillEllipse, GL_FillCircle, GL_DrawCircle changed
  21. 1.00.01 011113 JE     a) GL_DrawEllipse changed
  22. 1.00.00 991206 RS     First release
  23. ----------------------------------------------------------------------
  24. Known problems or limitations with current version
  25. ----------------------------------------------------------------------
  26. None.
  27. ----------------------------------------------------------------------
  28. Open issues
  29. ----------------------------------------------------------------------
  30. None
  31. ---------------------------END-OF-HEADER------------------------------
  32. */
  33. #include <stddef.h>           /* needed for definition of NULL */
  34. #include "GUI_Private.H"
  35. /*
  36.       *************************************************
  37.       *                                               *
  38.       *            Draw Circle                        *
  39.       *                                               *
  40.       *************************************************
  41. */
  42. static  void Draw8Point(int x0,int y0, int xoff, int yoff) {
  43.   LCD_HL_DrawPixel(x0+xoff,y0+yoff);
  44.   LCD_HL_DrawPixel(x0-xoff,y0+yoff);
  45.   LCD_HL_DrawPixel(x0+yoff,y0+xoff);
  46.   LCD_HL_DrawPixel(x0+yoff,y0-xoff);
  47.   if (yoff) {
  48.     LCD_HL_DrawPixel(x0+xoff,y0-yoff);
  49.     LCD_HL_DrawPixel(x0-xoff,y0-yoff);
  50.     LCD_HL_DrawPixel(x0-yoff,y0+xoff);
  51.     LCD_HL_DrawPixel(x0-yoff,y0-xoff);
  52.   }
  53. }
  54. void GL_DrawCircle(int x0, int y0, int r) {
  55.   I32 i;
  56.   int imax = ((I32)((I32)r*707))/1000+1;
  57.   I32 sqmax = (I32)r*(I32)r+(I32)r/2;
  58.   I32 y=r;
  59.   Draw8Point(x0,y0,r,0);
  60.   for (i=1; i<= imax; i++) {
  61.     if ((i*i+y*y) >sqmax) {
  62.       Draw8Point(x0,y0,i,y);
  63.       y--;
  64.     }
  65.     Draw8Point(x0,y0,i,y);
  66.   }
  67. }
  68. void GUI_DrawCircle       (int x0, int y0, int r) {
  69.   #if (GUI_WINSUPPORT)
  70.     GUI_RECT Rect;
  71.   #endif
  72.   GUI_LOCK();
  73.   #if (GUI_WINSUPPORT)
  74.     WM_ADDORG(x0,y0);
  75.     Rect.x0 = x0-r;
  76.     Rect.x1 = x0+r;
  77.     Rect.y0 = y0-r;
  78.     Rect.y1 = y0+r;
  79.     WM_ITERATE_START(&Rect); {
  80.   #endif
  81.     GL_DrawCircle( x0, y0, r);
  82.   #if (GUI_WINSUPPORT)
  83.     } WM_ITERATE_END();
  84.   #endif
  85.   GUI_UNLOCK();
  86. }
  87. /*
  88.       *************************************************
  89.       *                                               *
  90.       *            Fill Circle                        *
  91.       *                                               *
  92.       *************************************************
  93. */
  94. void GL_FillCircle       (int x0, int y0, int r) {
  95.   I32 i;
  96.   int imax = ((I32)((I32)r*707))/1000+1;
  97.   I32 sqmax = (I32)r*(I32)r+(I32)r/2;
  98.   I32 x=r;
  99.   LCD_HL_DrawHLine(x0-r,y0,x0+r);
  100.   for (i=1; i<= imax; i++) {
  101.     if ((i*i+x*x) >sqmax) {
  102.       /* draw lines from outside */
  103.       if (x>imax) {
  104.         LCD_HL_DrawHLine (x0-i+1,y0+x, x0+i-1);
  105.         LCD_HL_DrawHLine (x0-i+1,y0-x, x0+i-1);
  106.       }
  107.       x--;
  108.     }
  109.     /* draw lines from inside (center) */
  110.     LCD_HL_DrawHLine(x0-x,y0+i, x0+x);
  111.     LCD_HL_DrawHLine(x0-x,y0-i, x0+x);
  112.   }
  113. }
  114. void GUI_FillCircle       (int x0, int y0, int r) {
  115.   GUI_LOCK();
  116.   #if (GUI_WINSUPPORT)
  117.     WM_ADDORG(x0,y0);
  118.     WM_ITERATE_START(NULL); {
  119.   #endif
  120.   GL_FillCircle(x0,y0,r);
  121.   #if (GUI_WINSUPPORT)
  122.     } WM_ITERATE_END();
  123.   #endif
  124.   GUI_UNLOCK();
  125. }
  126. /*
  127.         *********************************************************
  128.         *                                                       *
  129.         *               Ellipse drawing / filling               *
  130.         *                                                       *
  131.         *********************************************************
  132. The most efficient way to calculate the ellipse positions
  133. is using the knowledge that the ellipse is just circle which has
  134. compressed (or stretched) in one direction. For a circle, the
  135. following equation holds true for all points located on the border of
  136. it:
  137.                x^2 + y(x)^2 = r^2 = const
  138. Therefor, for an ellipse we can make use of the following equation:
  139.                (ry*x)^2 + (rx*y(x))^2 = (ry*rx)^2 = const
  140. */
  141. void GL_FillEllipse      (int x0, int y0, int rx, int ry) {
  142.   I32 OutConst, Sum, SumY;
  143.   int x,y;
  144.   U32 _rx = rx;
  145.   U32 _ry = ry;
  146.   OutConst = _rx*_rx*_ry*_ry  /* Constant as explaint above */
  147.             +(_rx*_rx*_ry>>1); /* To compensate for rounding */
  148.   x = rx;
  149.   for (y=0; y<=ry; y++) {
  150.     SumY =((I32)(rx*rx))*((I32)(y*y)); /* Does not change in loop */
  151.     while (Sum = SumY + ((I32)(ry*ry))*((I32)(x*x)),
  152.            (x>0) && (Sum>OutConst))
  153.     {
  154.       x--;
  155.     }
  156.     LCD_HL_DrawHLine(x0-x, y0+y, x0+x);
  157.     if (y)
  158.       LCD_HL_DrawHLine(x0-x, y0-y, x0+x);
  159.   }
  160. }
  161. void GUI_FillEllipse      (int x0, int y0, int rx, int ry) {
  162.   #if (GUI_WINSUPPORT)
  163.     GUI_RECT r;
  164.   #endif
  165.   GUI_LOCK();
  166.   #if (GUI_WINSUPPORT)
  167.     WM_ADDORG(x0,y0);
  168.     /* Calc rectangle in order to avoid unnecessary drawing ops. */
  169.     r.x0 = x0-rx; r.x1 = x0+rx; r.y0 = y0-ry; r.y1 = y0+ry;
  170.     WM_ITERATE_START(&r); {
  171.   #endif
  172.   GL_FillEllipse (x0,y0, rx, ry);
  173.   #if (GUI_WINSUPPORT)
  174.     } WM_ITERATE_END();
  175.   #endif
  176.   GUI_UNLOCK();
  177. }
  178. void GL_DrawEllipse      (int x0, int y0, int rx, int ry) {
  179.   I32 OutConst, Sum, SumY;
  180.   int x,y;
  181.   int xOld;
  182.   U32 _rx = rx;
  183.   U32 _ry = ry;
  184.   OutConst = _rx*_rx*_ry*_ry  /* Constant as explaint above */
  185.             +(_rx*_rx*_ry>>1); /* To compensate for rounding */
  186.   xOld = x = rx;
  187.   for (y=0; y<=ry; y++) {
  188.     if (y==ry) {
  189.       x=0;
  190.     } else {
  191.       SumY =((I32)(rx*rx))*((I32)(y*y)); /* Does not change in loop */
  192.       while (Sum = SumY + ((I32)(ry*ry))*((I32)(x*x)),
  193.              (x>0) && (Sum>OutConst)) x--;
  194.     }
  195. /* Since we draw lines, we can not draw on the first
  196.     iteration
  197. */
  198.     if (y) {
  199.       GL_DrawLine1(x0-xOld,y0-y+1,x0-x,y0-y);
  200.       GL_DrawLine1(x0-xOld,y0+y-1,x0-x,y0+y);
  201.       GL_DrawLine1(x0+xOld,y0-y+1,x0+x,y0-y);
  202.       GL_DrawLine1(x0+xOld,y0+y-1,x0+x,y0+y);
  203.     }
  204.     xOld = x;
  205.   }
  206. }
  207. void GUI_DrawEllipse      (int x0, int y0, int rx, int ry) {
  208.   #if (GUI_WINSUPPORT)
  209.     GUI_RECT r;
  210.   #endif
  211.   GUI_LOCK();
  212.   #if (GUI_WINSUPPORT)
  213.     WM_ADDORG(x0,y0);
  214.   /* Calc rectangle in order to avoid unnecessary drawing ops. */
  215.     r.x0 = x0-rx; r.x1 = x0+rx; r.y0 = y0-ry; r.y1 = y0+ry;
  216.     WM_ITERATE_START(&r); {
  217.   #endif
  218.   GL_DrawEllipse(x0, y0, rx, ry);
  219.   #if (GUI_WINSUPPORT)
  220.     } WM_ITERATE_END();
  221.   #endif
  222.   GUI_UNLOCK();
  223. }