Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1049956
  • 博文数量: 178
  • 博客积分: 10222
  • 博客等级: 上将
  • 技术积分: 2215
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-03 11:27
个人简介

有所追求

文章分类

全部博文(178)

文章存档

2012年(1)

2011年(5)

2010年(3)

2009年(78)

2008年(91)

我的朋友

分类:

2008-07-08 10:15:52

随便找个GUI中的绘图函数,就可以大致看出他的做法:

/*********************************************************************
*
*       GUI_DrawLine
*/
void GUI_DrawLine(int x0, int y0, int x1, int y1) {
  GUI_LOCK();
  #if (GUI_WINSUPPORT)
    WM_ADDORG(x0,y0);
    WM_ADDORG(x1,y1);
    WM_ITERATE_START(NULL); {
  #endif
  GL_DrawLine (x0, y0, x1, y1);
  #if (GUI_WINSUPPORT)
    } WM_ITERATE_END();
  #endif
  GUI_UNLOCK();
}

    支持窗体就是支持了剪切,简单的这么理解吧!所以WM_ADDORG()、WM_ITERATE_START()和WM_ITERATE_END()可以看作是支持裁剪需要调用的几个函数。
#define WM_ADDORGX(x)    x += GUI_Context.xOff
#define WM_ADDORGY(y)    y += GUI_Context.yOff
#define WM_ADDORG(x0,y0) WM_ADDORGX(x0); WM_ADDORGY(y0)

    这里通过WM_SelectWindow选择窗体,设置GUI_Context中的xOff和yOff。在绘制图形之前调用WM_ADDORG就可以将窗体的这个起始坐标加上去了,这样就实现了在不同窗体上的绘制。
    接着是WM_ITERATE_START:
#define WM_ITERATE_START(pRect)                   \
  {                                               \
    if (WM__InitIVRSearch(pRect))                 \
      do {

#define WM_ITERATE_END()                          \
    } while (WM__GetNextIVR());                   \
  }

    这里主要涉及到两个函数,WM__InitIVRSearch()和WM__GetNextIVR()。WM__InitIVRSearch()函数不用细看,就干最后两句:
  _ClipContext.ClientRect = r;
  return WM__GetNextIVR();
    如果是有效窗体,则直接返回存在有效区域,如果没有则找到第一个剪切区域r,保存在ClipContext.ClientRect中,然后调用WM__GetNextIVR()来找下一个有效区域。
    同样也是看最后几行:
_ClipContext.CurRect = r;
    保存在_ClipContext.CurRect 中。


◎支持GUI_WINSUPPORT才能支持区域裁剪,所以很多地方可以查找GUI_WINSUPPORT来判断哪部分代码与裁剪相关
GUI_Context这个全局变量包含了LCD相关信息、GL相关信息、字符相关信息、窗体相关信息、内存设备相关信息、抗锯齿相关信息。
◎ucgui中带裁剪的图形绘制是通过两个步骤实现,首先是IVR(无效区域)的查找,在每找到一个无效区域之后对所绘图形进行裁剪。(minigui中是找到所有之后再逐个绘制的)
_ClipContext为剪切过程中使用的一个临时变量
阅读(2665) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~