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

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        : GUIChar.C
  16. Purpose     : Implementation of character and string services
  17. ---------------------------END-OF-HEADER------------------------------
  18. */
  19. #include <stddef.h>           /* needed for definition of NULL */
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include "GUI_Private.H"
  23.  
  24. /**********************************************************
  25. *
  26. *        Public code
  27. *
  28. ***********************************************************
  29. */
  30. /***********************************************************
  31. *
  32. *       GUI_DispChar
  33. */
  34. void GL_DispChar(U16 c) {
  35.   /* check for control characters */
  36.   if (c == 'n') {
  37.     GUI_DispNextLine();
  38.   } else {
  39.     if (c != 'r') {
  40.       GUI_Context.pAFont->pfDispChar(c);
  41.     }
  42.   }
  43. }
  44. /*************** GUI_GetStringDistX ****************************
  45. This routine is used to calculate the length of a string in pixels.
  46. */
  47. int GUI_GetLineDistX(const char GUI_FAR *s, int Len) {
  48.   int Dist =0;
  49.   if (s) {
  50.     if (GUI_Context.pAFont->pafEncode) {
  51.       return GUI_Context.pAFont->pafEncode->pfGetLineDistX(s, Len);
  52.     }
  53. #if (GUI_SUPPORT_UNICODE)
  54.     {
  55.       U8 c0;
  56.       char UCActive=0;
  57.       while (((c0=*(U8*)s) !=0) && Len >0) {
  58.         s++; Len--;
  59.         if (UCActive) {
  60.           if (c0 == GUI_UC_ENDCHAR)
  61.             UCActive = 0;
  62.           else {
  63.             U8  c1 = *(U8*)s++;
  64.             Len--;
  65.             Dist += GUI_GetCharDistX(GUI_DB2UC(c0, c1));
  66.           }
  67.         } else { /* Unicode not active */
  68.           if (c0 == GUI_UC_STARTCHAR)
  69.             UCActive = 1;
  70.           else
  71.             Dist += GUI_GetCharDistX(c0);
  72.         }
  73.       }
  74.     }
  75. #else
  76.     while (--Len>=0) {
  77.       Dist += GUI_GetCharDistX(*(U8*)s++);
  78.     }
  79. #endif
  80.   }
  81.   return Dist;
  82. }
  83. /*************** GUI_GetLineLen ****************************
  84. Returns the number of characters in a string
  85. Note: The return value can be used as offset into the
  86. string, which means that double characters count double
  87. */
  88. int GUI__GetLineLen(const char GUI_FAR *s, int MaxLen) {
  89.   int Len =0;
  90.   if (!s)
  91.     return 0;
  92.   if (GUI_Context.pAFont->pafEncode) {
  93.     return GUI_Context.pAFont->pafEncode->pfGetLineLen(s, MaxLen);
  94.   }
  95. #if (GUI_SUPPORT_UNICODE)
  96.   {
  97.     U8 c0;
  98.     char UCActive=0;
  99.     while (((c0=*(U8*)s) !=0) && Len < MaxLen) {
  100.       s++;
  101.       if (UCActive) {
  102.         switch (c0) {
  103.         case GUI_UC_ENDCHAR: UCActive = 0; break;
  104.         default: Len++; s++;
  105.         }
  106.       } else { /* Unicode not active */
  107.         switch (c0) {
  108.         case GUI_UC_STARTCHAR: UCActive = 1; break;
  109.         case 'n': return Len;
  110.         case 'r': return Len;
  111.         }
  112.       }
  113.       Len++;
  114.     }
  115.   }
  116. #else
  117.   for (;Len<MaxLen; Len++) {
  118.     U8 Data = *(U8*)s++;
  119.     if ((Data == 0) || (Data == 'n'))
  120.       break;
  121.   }
  122. #endif
  123.   return Len;
  124. }
  125. /**********************************************************************
  126. *
  127. *       "GET"   routines    (information retrieval)
  128. *
  129. ***********************************************************************
  130. These routines all return a value like selected font, current display
  131. position in x/y direction, window size in x/y direction,
  132. font size and matrix in x/y.
  133. The routines prefixed with GUI_ can be called from the application
  134. program or emWin internally, while the routines without that prefix
  135. are not supposed to be called from outside emWin.
  136. The main reason is that GUI_LOCK has to be called before these
  137. values can be reliably retrieved in a multitasking environment.
  138. */
  139. /*------------------------------------------------------------------
  140.   GUI_GetYAdjust  --- returns adjustment in vertical (Y) direction
  141.                   The return value needs to be subtracted from
  142.                   the y-position of the character
  143. */
  144. int GUI_GetYAdjust(void) {
  145.   switch (GUI_Context.TextAlign&GUI_TA_VERTICAL) {
  146. case GUI_TA_BOTTOM:
  147. return GUI_Context.pAFont->YSize-1;
  148. case GUI_TA_VCENTER:
  149. return GUI_Context.pAFont->YSize/2;
  150. case GUI_TA_BASELINE:
  151. return GUI_Context.pAFont->YSize/2;
  152. }
  153.   return 0;
  154. }
  155. /*
  156.         *******************************************
  157.         *                                         *
  158.         *        Get Font Spacing routines        *
  159.         *                                         *
  160.         *******************************************
  161. */
  162. int GUI_GetFontDistY(void) {
  163.   int r;
  164.   GUI_LOCK();
  165.   r = GUI_Context.pAFont->YDist * GUI_Context.pAFont->YMag;
  166.   GUI_UNLOCK();
  167.   return r;
  168. }
  169. /*
  170.         *******************************************
  171.         *                                         *
  172.         *        Get Char spacing routines        *
  173.         *                                         *
  174.         *******************************************
  175. */
  176. int GUI_GetCharDistX(U16 c) {
  177.   int r;
  178.   GUI_LOCK();
  179.   r = GUI_Context.pAFont->pfGetCharDistX(c);
  180.   GUI_UNLOCK();
  181.   return r;
  182. }
  183. /*
  184.       *********************************
  185.       *                               *
  186.       *       Linefeed                *
  187.       *                               *
  188.       *********************************
  189. */
  190. void GUI_DispNextLine(void) {
  191.   GUI_Context.DispPosY +=GUI_GetFontDistY();
  192.   GUI_Context.DispPosX = GUI_Context.LBorder;
  193. }
  194. /*
  195.         ************************************************************
  196.         *                                                          *
  197.         *             Set the write position                       *
  198.         *                                                          *
  199.         ************************************************************
  200. Sets the write position. The routines routine 1 if it is clear that
  201. the current write position is in an area outside the current window
  202. and will therefor not be written.
  203. */
  204. static char _GotoY(int y) {
  205.   GUI_Context.DispPosY = y;
  206.   return 0;
  207. }
  208. static char _GotoX(int x) {
  209.   GUI_Context.DispPosX = x;
  210.   return 0;
  211. }
  212. char GUI_GotoY(int y) {
  213.   char r;
  214.   GUI_LOCK();
  215.   r = _GotoY(y);
  216.   GUI_UNLOCK();
  217.   return r;
  218. }
  219. char GUI_GotoX(int x) {
  220.   char r;
  221.   GUI_LOCK();
  222.   r = _GotoX(x);
  223.   GUI_UNLOCK();
  224.   return r;
  225. }
  226. char GUI_GotoXY(int x, int y) {
  227.   char r;
  228.   GUI_LOCK();
  229.   r  = GUI_GotoX(x);
  230.   r |= GUI_GotoY(y);
  231.   GUI_UNLOCK();
  232.   return r;
  233. }
  234. /*
  235. ********************************************************
  236. *
  237. *                Display line
  238. *
  239. ********************************************************
  240. */
  241. void GL_DispLine(const char GUI_FAR *s, int Len, const GUI_RECT *pRect) {
  242.   /*
  243.     Check if we have anything to do at all ...
  244.     If the window manager has already set the clipping rect, it does not
  245.     make sense to due this. So it makes sense only if
  246.     a) The window manager is not used (-> Configuration)
  247.       or
  248.     b) The window manager is inactive (-> Memory device active)
  249.   */
  250.   if (GUI_Context.pClipRect_HL) {
  251.     if (GUI_RectsIntersect(GUI_Context.pClipRect_HL, pRect) == 0)
  252.       return;
  253.   }
  254.   if (GUI_Context.pAFont->pafEncode) {
  255.     GUI_Context.pAFont->pafEncode->pfDispLine(s, Len);
  256.     return;
  257.   }
  258. #if (GUI_SUPPORT_UNICODE)
  259.   {
  260.     U8 c0;
  261.     char UCActive=0;
  262.     while (--Len >=0) {
  263.       c0=*(U8*)s++;
  264.       if (UCActive) {
  265.         if (c0 == GUI_UC_ENDCHAR)
  266.           UCActive = 0;
  267.         else {
  268.           U8  c1 = *(U8*)s++;
  269.           Len--;
  270.           GL_DispChar (GUI_DB2UC(c0, c1));
  271.         }
  272.       } else { /* Unicode not active */
  273.         if (c0 == GUI_UC_STARTCHAR)
  274.           UCActive = 1;
  275.         else
  276.           GL_DispChar(c0);
  277.       }
  278.     }
  279.   }
  280. #else
  281.   {
  282.     while (--Len >=0) {
  283.       GL_DispChar(*(U8*)s++);
  284.     }
  285.   }
  286. #endif
  287. }
  288. void GUI__DispLine(const char GUI_FAR *s, int Len, const GUI_RECT* pr) {
  289.   GUI_RECT r;
  290.   r = *pr;
  291.   #if GUI_WINSUPPORT
  292.   WM_ADDORG(r.x0,r.y0);
  293.   WM_ADDORG(r.x1,r.y1);
  294.   WM_ITERATE_START(&r) {
  295.   #endif
  296.      GUI_Context.DispPosX = r.x0;
  297.      GUI_Context.DispPosY = r.y0;
  298.   /* Do the actual drawing via routine call. */
  299.      GL_DispLine(s, Len, &r);
  300.   #if GUI_WINSUPPORT
  301.   } WM_ITERATE_END();
  302.   WM_SUBORG(GUI_Context.DispPosX, GUI_Context.DispPosY);
  303.   #endif
  304. }
  305. /********************************************************************
  306. *
  307. *                Display String
  308. *
  309. *********************************************************************
  310. */
  311. void GUI_DispString(const char GUI_FAR *s) {
  312.   int xAdjust, yAdjust, xOrg;
  313.   int FontSizeY;
  314.   if (!s)
  315.     return;
  316.   GUI_LOCK();
  317.   FontSizeY = GUI_Context.pAFont->YDist;
  318.   xOrg = GUI_Context.DispPosX;
  319.  /* Adjust vertical position */
  320.   yAdjust = GUI_GetYAdjust();
  321.   GUI_Context.DispPosY -= yAdjust;
  322.   for (; *s; s++) {
  323.     GUI_RECT r;
  324.     int LineLen= GUI__GetLineLen(s,0x7fff);
  325.     int xLineSize = GUI_GetLineDistX(s, LineLen);
  326.   /* Check if x-position needs to be changed due to h-alignment */
  327.     switch (GUI_Context.TextAlign & GUI_TA_HORIZONTAL) { 
  328.     case GUI_TA_CENTER: xAdjust= xLineSize/2; break;
  329.     case GUI_TA_RIGHT:  xAdjust= xLineSize; break;
  330.     default:            xAdjust= 0;
  331.     }
  332.     r.x0 = GUI_Context.DispPosX -= xAdjust;
  333.     r.x1 = r.x0 + xLineSize-1;    
  334.     r.y0 = GUI_Context.DispPosY;
  335.     r.y1 = r.y0 + FontSizeY-1;    
  336.     GUI__DispLine(s, LineLen, &r);
  337.     GUI_Context.DispPosY = r.y0;
  338.     s += LineLen;
  339.     if ((*s=='n') || (*s=='r')) {
  340.       switch (GUI_Context.TextAlign & GUI_TA_HORIZONTAL) { 
  341.       case GUI_TA_CENTER:
  342.       case GUI_TA_RIGHT:
  343.         GUI_Context.DispPosX = xOrg;
  344.         break;
  345.       default:
  346.         GUI_Context.DispPosX = GUI_Context.LBorder;
  347.         break;
  348.       }
  349.       if (*s=='n')
  350.         GUI_Context.DispPosY += GUI_GetFontDistY();
  351.     } else {
  352.       GUI_Context.DispPosX = r.x0+xLineSize;
  353.     }
  354.     if (*s==0)    /* end of string (last line) reached ? */
  355.       break;
  356.   }
  357.   GUI_Context.DispPosY += yAdjust;
  358.   GUI_Context.TextAlign &= ~GUI_TA_HORIZONTAL;
  359.   GUI_UNLOCK();
  360. }