首页 > 代码库 > uCGUI字符串显示过程分析

uCGUI字符串显示过程分析

GUI_DispString()函数源码                                          

 1 void GUI_DispString(const char GUI_UNI_PTR *s) { 2   int xAdjust, yAdjust, xOrg; 3   int FontSizeY; 4   if (!s) 5     return; 6   GUI_LOCK(); 7   FontSizeY = GUI_GetFontDistY();         //获取字体的高度 8   xOrg = GUI_Context.DispPosX;            //获取当前显示的x坐标 9  /* Adjust vertical position */10   yAdjust = GUI_GetYAdjust();                    11   GUI_Context.DispPosY -= yAdjust;        //根据Y方向上的对齐方式对y进行调整12   for (; *s; s++) {13     GUI_RECT r;14     int LineNumChars = GUI__GetLineNumChars(s, 0x7fff);           //当前一行要显示几个字符15     int xLineSize    = GUI__GetLineDistX(s, LineNumChars);        //当前一行在x方向上的像素数16   /* Check if x-position needs to be changed due to h-alignment */17     switch (GUI_Context.TextAlign & GUI_TA_HORIZONTAL) {18       case GUI_TA_CENTER: xAdjust = xLineSize / 2; break;19       case GUI_TA_RIGHT:  xAdjust = xLineSize; break;20       default:            xAdjust = 0;21     }22     /* 计算出每一行显示内容的矩形区域 */23     r.x0 = GUI_Context.DispPosX -= xAdjust;          //根据水平方向的对齐方式对x坐标进行调整24     r.x1 = r.x0 + xLineSize - 1;    25     r.y0 = GUI_Context.DispPosY;26     r.y1 = r.y0 + FontSizeY - 1;27         28     GUI__DispLine(s, LineNumChars, &r);              //以计算好的矩形区域显示当前行字符29     GUI_Context.DispPosY = r.y0;30     s += GUI_UC__NumChars2NumBytes(s, LineNumChars); //从第一个字符开始,地址加1,可以遍历整行字符串31     if ((*s == \n) || (*s == \r)) {32       switch (GUI_Context.TextAlign & GUI_TA_HORIZONTAL) { 33       case GUI_TA_CENTER:34       case GUI_TA_RIGHT:35         GUI_Context.DispPosX = xOrg;36         break;37       default:38         GUI_Context.DispPosX = GUI_Context.LBorder;39         break;40       }41       if (*s == \n)42         GUI_Context.DispPosY += FontSizeY;43     } else {44       GUI_Context.DispPosX = r.x0 + xLineSize;45     }46     if (*s == 0)    /* end of string (last line) reached ? */47       break;48   }49   GUI_Context.DispPosY += yAdjust;                //50   GUI_Context.TextAlign &= ~GUI_TA_HORIZONTAL;    //51   GUI_UNLOCK();52 }

 字符串显示过程概括                                                

<1> 获取选择字体的高度、宽度

<2> 从所传字符串参数中,依次读出一行的字符数,最终得到一行显示所对应的矩形区域

<3> 将一行所得到的详细信息传给行显示函数,行显示函数会从字库中找到匹配的字依次将一行的字符进行显示,完成一行的显示

<4> 如果不是只有一行,重新计算下一行显示的坐标,重复<1、2、3>的工作,直到将字符串显示完毕。

============================================================================================

                   重要细节分析

============================================================================================

 1、GUI运行的全局变量                                             

  GUI_Context是GUI保存运行环境的全局变量,它的类型GUI_CONTEXT在GUI.h中被定义。

struct GUI_CONTEXT {/* Variables in LCD module */  LCD_COLORINDEX_UNION LCD;  LCD_RECT       ClipRect;  U8             DrawMode;  U8             SelLayer;  U8             TextStyle;/* Variables in GL module */  GUI_RECT* pClipRect_HL;                /* High level clip rectangle ... Speed optimization so drawing routines can optimize */  U8        PenSize;  U8        PenShape;  U8        LineStyle;  U8        FillStyle;/* Variables in GUICHAR module */  const GUI_FONT           GUI_UNI_PTR * pAFont;  //指向当前选择的字体  #if GUI_SUPPORT_UNICODE    const GUI_UC_ENC_APILIST * pUC_API;    /* Unicode encoding API */  #endif  I16P LBorder;  I16P DispPosX, DispPosY;  I16P DrawPosX, DrawPosY;  I16P TextMode, TextAlign;                       //对齐方式  GUI_COLOR Color, BkColor;           /* Required only when changing devices and for speed opt (caching) *//* Variables in WM module */  #if GUI_WINSUPPORT    const GUI_RECT* WM__pUserClipRect;    GUI_HWIN hAWin;    int xOff, yOff;  #endif/* Variables in MEMDEV module (with memory devices only) */  #if GUI_SUPPORT_DEVICES    const tLCDDEV_APIList* pDeviceAPI;  /* function pointers only */    GUI_HMEM    hDevData;    GUI_RECT    ClipRectPrev;  #endif/* Variables in Anitaliasing module */  #if GUI_SUPPORT_AA    const tLCD_HL_APIList* pLCD_HL;     /* Required to reroute drawing (HLine & Pixel) to the AA module */    U8 AA_Factor;    U8 AA_HiResEnable;  #endif};

2、GUI_FONT的定义                                                 

     一种字库想要被uCGUI所调用,需要将其定义成GUI_GONT类型的一个常量,当我们需要自己制作字库的时候,就需要这样做。GUI_FONT类型的定义在GUIType.h文件中。

struct GUI_FONT {  GUI_DISPCHAR*     pfDispChar;             //显示一个属于当前字库字符的函数  GUI_GETCHARDISTX* pfGetCharDistX;         //获取字库中某字符的宽度  GUI_GETFONTINFO*  pfGetFontInfo;          //获取字库信息  GUI_ISINFONT*     pfIsInFont;             //查询字库中是否存在此字符  const tGUI_ENC_APIList* pafEncode;        //  U8 YSize;                        //高度  U8 YDist;                        //对应的像素点  U8 XMag;                         //X方向上的放大系数  U8 YMag;                         //Y方向上的放大系数  union {                          //此共用体主要是提供字库数据的访问地址,                                   //对于不同的字库,其从字库中查找字模的方法,是不一样的                                   //这里主要分成三种情况,对应三种类型的指针            const void          GUI_UNI_PTR * pFontData;    const GUI_FONT_MONO GUI_UNI_PTR * pMono;    const GUI_FONT_PROP GUI_UNI_PTR * pProp;  } p;  U8 Baseline;                                //  U8 LHeight;     /* height of a small lower case character (a,x) */    //小写高度  U8 CHeight;     /* height of a small upper case character (A,X) */    //大写高度};

(1)

 

uCGUI字符串显示过程分析