Example #1
0
//----取得新增可视域-----------------------------------------------------------
//功能: 出现在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;
    }
}
Example #2
0
//----取得新增可视域-----------------------------------------------------------
//功能: 出现在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;
    }
}
Example #3
0
//----获取被修改区域-----------------------------------------------------------
//功能: 获取一个窗口的被修改部分的剪切域,形成双向循环链表,链表中的clip以先
//      左->右,再上->下的顺序排列,并清零changed_msk数组。
//参数: gkwin,目标窗口
//返回: 链表指针,NULL表示窗口未被修改
//-----------------------------------------------------------------------------
struct tagClipRect *__GK_GetChangedClip(struct tagGkWinRsc *gkwin)
{
    struct tagClipRect *clip=NULL,*clip1,*tempclip,*clip_head = NULL;
    u8 *msk;
    u32 offset_bit,offset,msk_line_words;
    s16 loopx,loopy;
    bool_t start;
    s32 width,height;

    if(gkwin->change_flag == CN_GKWIN_CHANGE_ALL)   //整个窗口均被修改
    {
        clip = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0);
        if(clip != NULL)
        {
            clip->rect.left = gkwin->limit_left + gkwin->absx0;
            clip->rect.top = gkwin->limit_top + gkwin->absy0;
            clip->rect.right = gkwin->limit_right + gkwin->absx0;
            clip->rect.bottom = gkwin->limit_bottom + gkwin->absy0;
            clip->next = clip;
            clip->previous = clip;
            gkwin->change_flag = CN_GKWIN_CHANGE_NONE;
            return clip;            //把整个窗口的可显示区域当作一个剪切域返回
        }
        else
            return NULL;
    }else if(gkwin->change_flag == CN_GKWIN_CHANGE_NONE)    //没有修改
    {
        return NULL;
    }else       //部分修改,先按x方向取得剪切域,再按y方向合并
    {
        offset = 0;                 //首行字偏移量
        msk = gkwin->changed_msk.bm_bits;
        width = gkwin->wm_bitmap->width;
        height = gkwin->wm_bitmap->height;
        msk_line_words = gkwin->changed_msk.linebytes;
        for(loopy = 0; loopy < height; loopy +=8)
        {
            start = false;      //开始一段连续的被修改区域
            offset_bit = 0;     //起始块的位偏移
            for(loopx = 0; loopx < width; loopx+=8)
            {
                if(msk[offset+offset_bit/8]&(u8)(1<<(8-(offset_bit%8)-1)))
                {   //该块的changed flag为true。
                    if(start == false)      //changed block开始被修改
                    {
                        start = true;
                        clip =(struct tagClipRect*)Mb_Malloc(g_ptClipRectPool,0);
                        if(clip != NULL)
                        {
                            clip->rect.left = gkwin->absx0 + offset_bit*8;
                            clip->rect.top = loopy + gkwin->absy0;
                            clip->rect.right = clip->rect.left + 8;
                            clip->rect.bottom = clip->rect.top + 8;
                        }
                        else
                        {
                            __GK_FreeClipQueue(clip_head);
                            return NULL;
                        }
                    }else                   //changed block持续
                    {
                        clip->rect.right += 8;
                    }
                }else     //如果本行的最后一块也是被改写的块,则程序不会走到这里
                {
                    if(start == true)     //changed block结束
                    {
                        __GK_ClipConnect(&clip_head,clip);
                        start = false;
                    }
                }
                offset_bit++;
            }
            //本行最后一块是被改写块,需要在这里把该区域加入被修改区域
            if(start == true)
                __GK_ClipConnect(&clip_head,clip);
            offset += msk_line_words;
        }

        //至此,x方向条状clip已经生成,现在沿y方向合并
        clip = clip_head;
        do{
            clip1 = clip->next;
            while(clip1 != clip)
            {
                if((clip1->rect.left == clip->rect.left)
                    &&(clip1->rect.right == clip->rect.right)
                    &&((clip->rect.bottom)== clip1->rect.top))//可合并
                {
                    clip->rect.bottom += 8;
                    clip1->previous->next = clip1->next;
                    clip1->next->previous = clip1->previous;
                    tempclip = clip1;
                    clip1 = clip1->next;
                    Mb_Free(g_ptClipRectPool,tempclip);
                }else
                    clip1 = clip1->next;
            }
            clip = clip->next;
        }while(clip != clip_head);
        gkwin->change_flag = CN_GKWIN_CHANGE_NONE;
    }
    memset(msk,0,msk_line_words * gkwin->changed_msk.height);
    return clip_head;
}
Example #4
0
//----扫描可视域---------------------------------------------------------------
//功能: 1、把visible_clip备份到visible_bak中。
//      2、所有窗口生成新的visible_clip
//参数: display,被扫描的显示器
//返回: false=失败,一般是因为剪切域池容量不够
//-----------------------------------------------------------------------------
bool_t __GK_ScanNewVisibleClip(struct tagDisplayRsc *display)
{
    struct tagGkWinRsc *tempwin;
    struct tagRectangle *rect;
    struct tagClipRect *clip,*clip1,*clip_head = NULL;
    s32 num,rect_left,rect_top,rect_right,rect_bottom,loop,temp;
    u8 *sort_array_x,*sort_array_y;

    num = (display->width+1)*sizeof(u8) + (display->height+1)*sizeof(u8);
    sort_array_x = M_MallocLc(num,0);
    if(sort_array_x == NULL)
        return false;
    sort_array_y = sort_array_x + display->width+1;
    memset(sort_array_x,0,num);
    tempwin = display->z_topmost;
//    rect_left = 0;
//    rect_top = 0;
    while(1)
    {     //取窗口可视边框,该边框是窗口受祖先窗口限制后的矩形
        temp = tempwin->limit_left-tempwin->left + tempwin->absx0;
        if(sort_array_x[temp] == 0)
        {
            sort_array_x[temp] = 1;
//            rect_left++;
        }

        temp = tempwin->limit_right-tempwin->left+tempwin->absx0;
        if(sort_array_x[temp] == 0)
        {
            sort_array_x[temp] = 1;
//            rect_left++;
        }

        temp = tempwin->limit_top-tempwin->top + tempwin->absy0;
        if(sort_array_y[temp] == 0)
        {
            sort_array_y[temp] = 1;
//            rect_top++;
        }

        temp = tempwin->limit_bottom-tempwin->top+tempwin->absy0;
        if(sort_array_y[temp] == 0)
        {
            sort_array_y[temp] = 1;
//            rect_top++;
        }

        //执行__GK_GetRedrawClipAll函数注释中的step1
        //保存窗口原来的可视域
        tempwin->visible_bak = tempwin->visible_clip;
        tempwin->visible_clip = NULL;
        if(tempwin != display->desktop)
            tempwin = tempwin->z_back;
        else
            break;
    }
    //处理桌面下的窗口,这些窗口肯定没有可视域
    while(1)
    {
        tempwin = tempwin->z_back;
        if(tempwin == display->z_topmost)
            break;
        tempwin->visible_bak = tempwin->visible_clip;
        tempwin->visible_clip = NULL;
    }
    //按从左到右,从上到下的顺序(顺序不能改变)把所有垂直线、水平线围成的小clip
    //串成双向链表,由clip_head做链表头
    rect_top = 0;
    temp = 0;
    for(rect_bottom =1;rect_bottom <= display->height; rect_bottom++)
    {
        if(sort_array_y[rect_bottom] == 0)
            continue;
        rect_left = 0;
        for(rect_right =1;rect_right <= display->width; rect_right++)
        {
            if(sort_array_x[rect_right] == 0)
                continue;
            clip = (struct tagClipRect*)Mb_Malloc(g_ptClipRectPool,0);
            if(clip != NULL)
            {
                clip->rect.left = rect_left;
                clip->rect.right = rect_right;
                clip->rect.top = rect_top;
                clip->rect.bottom = rect_bottom;
                rect_left = rect_right;
                __GK_ClipConnect(&clip_head,clip);      //把小clip加入到链接起来
                temp++;
            }
            else
            {
                __GK_FreeClipQueue(clip_head);
                free(sort_array_x);
                return false;           //内存池不足,无法生成可视域队列
            }
        }
        rect_top = rect_bottom;
    }
    free(sort_array_x);

    //下面判断小clip的归属,并把他们加入到所属win的new_clip队列中
    tempwin = display->z_topmost;
    while(1)
    {
        clip = clip_head;
        for(loop = temp; loop >0; loop--)
        {
            rect = &(clip->rect);
            if((rect->left>=tempwin->limit_left-tempwin->left+tempwin->absx0)
               &&(rect->top>=tempwin->limit_top-tempwin->top+tempwin->absy0)
               &&(rect->right<=tempwin->limit_right-tempwin->left+tempwin->absx0)
               &&(rect->bottom<=tempwin->limit_bottom-tempwin->top+tempwin->absy0))
            {   //矩形在tempwin的可显示范围内,若不在则无需处理
                //允许alpha或透明,区域将加入窗口可视域,但不从临时链表中删除。
                if(tempwin->dest_blend)
                {
                    clip1 = (struct tagClipRect*)Mb_Malloc(g_ptClipRectPool,0);
                    if(clip1 != NULL)
                    {
                        *clip1 = *clip;
                    }
                    else
                    {
                        __GK_FreeClipQueue(clip_head);
                        return false;           //内存池不足,无法生成可视域队列
                    }
                }else   //不允许透明和alpha,区域加入窗口可视域,从临时链表删除
                {
                    if(clip == clip_head)
                        clip_head = clip_head->next;
                    clip1 = clip;
                    clip->previous->next = clip->next;
                    clip->next->previous = clip->previous;
                    temp--;
                }
                clip = clip->next;
                //把小clip加入到visible_clip队列中
                __GK_ClipConnect(&tempwin->visible_clip,clip1);
            }else       //矩形不在tpwin的可显示范围内,无需处理。
            {
                clip = clip->next;
            }
        }
        __GK_CombineClip_s(tempwin->visible_clip);//合并clip,按先x后y的顺序合并
        if(tempwin != display->desktop)
            tempwin = tempwin->z_back;
        else
            break;
    }
    return true;
}
Example #5
0
//----生成重绘区域-------------------------------------------------------------
//功能: 扫描整个窗口链表,重新生成全部窗口的可视域,以及待重绘的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;
}