//----取得新增可视域----------------------------------------------------------- //功能: 出现在visible_clip中且不在visible_bak的区域,加入redraw_clip。 // 同时出现在visible_clip和visible_bak中的部分,留在visible_clip中 // 如果dest_blend==true,则仅在visible_bak出现的部分留在visible_bak // 否则,释放visiblvisible_bak //参数: gkwin,目标窗口 //返回: 无 //----------------------------------------------------------------------------- void __GK_GetNewClip(struct tagGkWinRsc *gkwin) { struct tagClipRect *redraw; //visible_clip-visible_bak多出的部分 struct tagClipRect *res; //visible_clip与visible_bak相交的clip if(gkwin->visible_bak != NULL) { __GK_ClipLinkSub(gkwin->visible_clip,gkwin->visible_bak,&res,&redraw); __GK_ClipLinkConnect(&gkwin->redraw_clip,redraw); gkwin->visible_clip = res; if(gkwin->dest_blend) { __GK_ClipLinkSub(gkwin->visible_bak,gkwin->visible_clip, &res,&redraw); gkwin->visible_bak = redraw; __GK_FreeClipQueue(res); } else { gkwin->visible_bak = __GK_FreeClipQueue(gkwin->visible_bak); } } else { __GK_ClipLinkConnect(&gkwin->redraw_clip,gkwin->visible_clip); gkwin->visible_clip = NULL; } }
//----取得新增可视域----------------------------------------------------------- //功能: 出现在visible_clip中且不在visible_bak的区域,加入redraw_clip。 // 同时出现在visible_clip和visible_bak中的部分,留在visible_clip中 // 如果dest_blend==true,则仅在visible_bak出现的部分留在visible_bak // 否则,释放visiblvisible_bak //参数: gkwin,目标窗口 //返回: 无 //----------------------------------------------------------------------------- void __GK_GetNewClip(struct GkWinRsc *gkwin) { struct ClipRect *redraw; //visible_clip-visible_bak多出的部分 struct ClipRect *res; //visible_clip与visible_bak相交的clip if(gkwin->visible_bak != NULL) { __GK_ClipLinkSub(gkwin->visible_clip,gkwin->visible_bak,&res,&redraw); __GK_ClipLinkConnect(&gkwin->redraw_clip,redraw); gkwin->visible_clip = res; if(gkwin->WinProperty.DestBlend == CN_GKWIN_DEST_VISIBLE) { __GK_ClipLinkSub(gkwin->visible_bak,gkwin->visible_clip, &res,&redraw); gkwin->visible_bak = redraw; __GK_FreeClipQueue(res); } else { gkwin->visible_bak = __GK_FreeClipQueue(gkwin->visible_bak); } } else { __GK_ClipLinkConnect(&gkwin->redraw_clip,gkwin->visible_clip); gkwin->visible_clip = NULL; } }
//----提取剪切域队列重叠部分--------------------------------------------------- //功能: 提取src队列中的所有矩形与sub队列中重叠的部分,用ins参数返回; // src中非重叠的部分也形成新的剪切域队列,从different返回。 //参数: src,被减的队列指针,执行后,本队列将被释放或转移 // sub,减数队列指针 // ins,src与sub相交的部分 // different,src与sub不相交的部分 //返回: 无 //----------------------------------------------------------------------------- void __GK_ClipLinkSub(struct tagClipRect *src,struct tagClipRect *sub, struct tagClipRect **ins,struct tagClipRect **different) { struct tagClipRect *difftemp = NULL; //不重叠的部分暂存 struct tagClipRect *worksrc; //src中矩形被减产生的工作子队列 struct tagClipRect *LoopSrc; struct tagClipRect *EndLoop; struct tagClipRect *workloop; //工作子队列的循环遍历指针 struct tagClipRect *subloop; //减数队列的循环遍历指针 struct tagClipRect *clip_ints=NULL; //用于收集重叠的区域 struct tagClipRect *temp1; //临时变量 struct tagRectangle ints_rect,src_rect; bool_t EndSub; ufast_t uftemp; //减数队列为空 if(sub == NULL) { //被减数队列为空 if(src == NULL) {//src与sub相交、不相交的部分都为空 *ins = NULL; *different = NULL; return; }else {//src与sub相交部分为空、不相交的部分为src *ins = NULL; *different = src; return; } }else //减数队列不为空 { //被减数队列为空 if(src == NULL) {//src与sub相交、不相交的部分都为空 *ins = NULL; *different = NULL;// // *different = sub; return; } } //被减数队列、减数队列都不为空 LoopSrc = src; do{ worksrc = LoopSrc; LoopSrc = LoopSrc->next; worksrc->next = worksrc; worksrc->previous = worksrc; subloop = sub; do{ workloop = worksrc; EndLoop = worksrc->previous; EndSub = false; //此处用循环是必要的,减sub中第一个矩形时worksrc只有一个矩形,可 //以不用循环来处理,但减第二个矩形时,worksrc可能分裂成一个队列。 do { if(__GK_GetRectInts(&workloop->rect,&subloop->rect,&ints_rect)) {//矩形相交 temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect = ints_rect; //把相交区域加入clip_ints __GK_ClipConnect(&clip_ints,temp1); src_rect = workloop->rect; uftemp = 0; //以下提取workloop中与subloop中不相交的部分,直接替代src队列 //中workloop的位置 if(subloop->rect.top > src_rect.top) //上部矩形 { //首个矩形,覆盖原结点 workloop->rect.bottom = subloop->rect.top; workloop = workloop->next; uftemp++; } if(subloop->rect.left > src_rect.left) //左部矩形 { //首个矩形,覆盖原结点 if(uftemp == 0) { workloop->rect.right = subloop->rect.left; if(src_rect.bottom < subloop->rect.bottom) workloop->rect.bottom = src_rect.bottom; else workloop->rect.bottom = subloop->rect.bottom; workloop = workloop->next; }else { temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect.left = src_rect.left; temp1->rect.top = subloop->rect.top; temp1->rect.right = subloop->rect.left; if(src_rect.bottom < subloop->rect.bottom) temp1->rect.bottom = src_rect.bottom; else temp1->rect.bottom = subloop->rect.bottom; __GK_ClipConnect(&workloop,temp1); } uftemp++; } if(subloop->rect.right < src_rect.right) //右部矩形 { //首个矩形,覆盖原结点 if(uftemp == 0) { workloop->rect.left = subloop->rect.right; if(src_rect.bottom < subloop->rect.bottom) workloop->rect.bottom = src_rect.bottom; else workloop->rect.bottom = subloop->rect.bottom; workloop = workloop->next; }else { temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect.left = subloop->rect.right; if(src_rect.top < subloop->rect.top) temp1->rect.top = subloop->rect.top; else temp1->rect.top = src_rect.top; temp1->rect.right = src_rect.right; if(src_rect.bottom < subloop->rect.bottom) temp1->rect.bottom = src_rect.bottom; else temp1->rect.bottom = subloop->rect.bottom; __GK_ClipConnect(&workloop,temp1); } uftemp++; } if(subloop->rect.bottom < src_rect.bottom) //下部矩形 { //首个矩形,覆盖原结点 if(uftemp == 0) { workloop->rect.top = subloop->rect.bottom; workloop = workloop->next; }else { temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect.left = src_rect.left; temp1->rect.top = subloop->rect.bottom; temp1->rect.right = src_rect.right; temp1->rect.bottom = src_rect.bottom; __GK_ClipConnect(&workloop,temp1); } uftemp++; } if(uftemp == 0) //源矩形被完全覆盖, { if(worksrc->next == worksrc) //源队列只有一个矩形 { Mb_Free(g_ptClipRectPool,worksrc); worksrc = NULL; // workloop = NULL; EndSub = true; }else { temp1 = workloop; workloop = workloop->next; temp1->previous->next = workloop; workloop->previous = temp1->previous; if(worksrc == temp1) worksrc = workloop; if(EndLoop == temp1) EndSub = true; Mb_Free(g_ptClipRectPool,temp1); } } else { workloop = workloop->next; } } else //矩形不相交 { workloop = workloop->next; } if(workloop->previous == EndLoop) EndSub = true; }while(EndSub == false); if(worksrc == NULL) break; subloop = subloop->next; }while(subloop != sub); __GK_ClipLinkConnect(&difftemp,worksrc); }while(src != LoopSrc); *different = difftemp; *ins = clip_ints; }
//----生成重绘区域------------------------------------------------------------- //功能: 扫描整个窗口链表,重新生成全部窗口的可视域,以及待重绘的clip,方法和过程: // 1、释放所有的visible_bak,把visible_clip转到visible_bak中。 // 2、重新生成所有win的visible_clip,并复制到 copy_clip 中临时保存。 // 3、visible_clip减去中visible_bak所得加入redraw_clip队列。剩余部分保留在 // visible_clip中。如果窗口的dest_blend == true,则visible_bak中保存 // 由可见变为不可见的部分,否则visible_bak将被释放。 // 4、从changed msk中提取changed_clip。 // 5、取visible_clip与changed_clip的交集,加入redraw_clip队列。 // 6、从z_top起,取visible_bak,扫描其后窗口的可视域,与其重叠的部分,加入 // redraw域。符合此条件的visible_bak,必定是因为窗口移开所致。 // 7、从z_top起,对dest_blend == true的win,扫描z轴中在其后面的 // win的visible_clip,与其需重绘部分重叠的,加入redraw_clip队列。 // 此后dest_blend != true的win的visible_clip可释放。 // 8、合并前几步产生的redraw_clip队列。 // 9、从z_top起,对任一dest_blend == true的win的visible_clip,扫描z轴中在其 // 后面的win的redraw_clip,重叠的部分加入redraw_clip队列,并合并之。 //参数: display,被扫描的显示器 //返回: false=失败,一般是因为剪切域池容量不够 //----------------------------------------------------------------------------- bool_t __GK_GetRedrawClipAll(struct tagDisplayRsc *display) { struct tagGkWinRsc *tempwin; struct tagGkWinRsc *special_win; struct tagClipRect *changed_clip,*tempclip1; if(display->reset_clip == true) //看是否需要重新生成可视域 { if(__GK_GetVisibleClip(display) == false) //完成step1、step2、step3 return false; display->reset_clip = false; } tempwin = display->desktop; while(1) { //扫描desktop到z_topmost之间的全部窗口,完成step4~5,在desktop后面的 //窗口不显示,或者在step1~3中已经全部转移到 redraw_clip 中,无需处理。 if(tempwin->visible_clip != NULL) { //备份visible_clip if(tempwin->copy_clip == NULL) //copy_clip可能已经在step1~3中设置了 tempwin->copy_clip = __GK_CopyClipLink(tempwin->visible_clip); //整个窗口全部被修改,整体绘制、窗口移动、拉伸、压缩会导致全体修改 //reset_clip == true成立的话,cn_gkwin_change_all的情况在 //__gk_get_visible_clip函数中已经完成,在该函数中完成,可以减轻不少 //运算量,而且对这里没有影响。 if(tempwin->change_flag == CN_GKWIN_CHANGE_ALL) { //全部可视域需重绘 __GK_ClipLinkConnect(&tempwin->redraw_clip, tempwin->visible_clip); tempwin->visible_clip = NULL; //可视域已经全部加入重绘域 tempwin->change_flag = CN_GKWIN_CHANGE_NONE; }else { //有部分修改 if(tempwin->change_flag == CN_GKWIN_CHANGE_PART) { //取得修改域 changed_clip = __GK_GetChangedClip(tempwin); //提取可视域中修改的区域 tempclip1 = __GK_GetClipLinkInts( &tempwin->visible_clip,changed_clip); __GK_FreeClipQueue(changed_clip); //把修改区域加入到redraw_clip中 __GK_ClipLinkConnect(&tempwin->redraw_clip,tempclip1); tempwin->change_flag = CN_GKWIN_CHANGE_NONE; } } // tempwin->visible_bak = NULL; } else tempwin->change_flag = CN_GKWIN_CHANGE_NONE; //清除changed_msk __GK_ShadingClear(tempwin); if(tempwin != display->z_topmost) tempwin = tempwin->z_top; else break; } //执行step6,改变位置的、dest_blend=true的窗口,改变前遮挡的其他窗口的 //可视域,加入redraw域。 special_win = display->z_topmost; while(1) { //窗口移动,伸缩会导致visible_bak != NULL if((special_win->dest_blend) && (special_win->visible_bak != NULL)) { tempwin = special_win->z_back; while(1) { // tempclip2 = __GK_CopyClipLink(special_win->visible_bak); //取得背景窗口需要重绘的区域 tempclip1 = __GK_GetClipLinkInts(&tempwin->visible_clip, special_win->visible_bak); // __GK_FreeClipQueue(tempclip2); //把修改区域加入到背景窗口redraw_clip中 __GK_ClipLinkConnect(&tempwin->redraw_clip,tempclip1); if(tempwin != display->desktop) tempwin = tempwin->z_back; else break; } special_win->visible_bak = __GK_FreeClipQueue(special_win->visible_bak); } if(special_win != display->desktop) special_win = special_win->z_back; else break; } //执行step7,窗口需要背景参与运算,此窗口内容有改变 special_win = display->z_topmost; while(1) { //hjj,step7和step9存在先后执行的情况,调用__gk_get_cliplink_ints_res //会对参数有影响(可能导致参数值改变),使用时应多做考虑 if(special_win->dest_blend) {//special_win需要背景参与运算才执行下面的程序 if(special_win->redraw_clip != NULL) { tempwin = special_win->z_back; while(1) { //取得背景窗口需要重绘的区域 tempclip1 = __GK_GetClipLinkInts(&tempwin->visible_clip, special_win->redraw_clip); //把修改区域加入到背景窗口redraw_clip中 __GK_ClipLinkConnect(&tempwin->redraw_clip,tempclip1); if(tempwin != display->desktop) tempwin = tempwin->z_back; else break; } } } else {//释放掉不需要背景参与运算的窗口的可视域 special_win->visible_clip = __GK_FreeClipQueue(special_win->visible_clip); } if(special_win != display->desktop) special_win = special_win->z_back; else break; } //执行step8,合并前几步产生的redraw_clip队列 tempwin = display->z_topmost; while(1) { //合并redraw_clip tempwin->redraw_clip = __GK_CombineClip(tempwin->redraw_clip); if(tempwin != display->desktop) tempwin = tempwin->z_back; else break; } //执行step9,本步骤无须判断desktop,故循环体有所不同 //需要背景参与运算的窗口,其背景改变 special_win = display->z_topmost; do{ if((special_win->dest_blend)&&(special_win->visible_clip != NULL)) {//special_win需要背景窗口参与运算,才执行下面的程序 tempwin = special_win; do{ tempwin = tempwin->z_back; //取得背景窗口的修改域 tempclip1 = __GK_GetClipLinkInts(&special_win->visible_clip, tempwin->redraw_clip); //把修改区域加入到窗口的redraw_clip中 __GK_ClipLinkConnect(&special_win->redraw_clip,tempclip1); }while(tempwin != display->desktop); //释放掉不需要使用的区域 special_win->visible_clip = __GK_FreeClipQueue(special_win->visible_clip); //合并redraw_clip special_win->redraw_clip = __GK_CombineClip(special_win->redraw_clip); } special_win = special_win->z_back; }while(special_win != display->desktop); //恢复visible_clip tempwin = display->z_topmost; while(1) { tempwin->visible_clip = tempwin->copy_clip; tempwin->copy_clip = NULL; if(tempwin != display->desktop) tempwin = tempwin->z_back; else break; } return true; }