/*--------------------------------------------------------------------*/ int mbr_dem_hsurivax(int verbose, void *mbio_ptr, int *error) { char *function_name = "mbr_dem_hsurivax"; int status = MB_SUCCESS; struct mb_io_struct *mb_io_ptr; /* print input debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> called\n",function_name); fprintf(stderr,"dbg2 Input arguments:\n"); fprintf(stderr,"dbg2 verbose: %d\n",verbose); fprintf(stderr,"dbg2 mbio_ptr: %lu\n",(size_t)mbio_ptr); } /* get pointer to mbio descriptor */ mb_io_ptr = (struct mb_io_struct *) mbio_ptr; /* deallocate memory for data descriptor */ status = mb_free(verbose,&mb_io_ptr->raw_data,error); status = mb_free(verbose,&mb_io_ptr->store_data,error); /* print output debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> completed\n",function_name); fprintf(stderr,"dbg2 Return values:\n"); fprintf(stderr,"dbg2 error: %d\n",*error); fprintf(stderr,"dbg2 Return status:\n"); fprintf(stderr,"dbg2 status: %d\n",status); } /* return status */ return(status); }
//----合并区域简化版----------------------------------------------------------- //功能: 把给定的剪切域队列中可合并的区域合并,简化版的意思是,队列中的区域已经按 // 左->右,从上->下的顺序排列,合并后,多余的clip将被释放。 //参数: clipq: 指向待合并的队列首 //返回: 无 //----------------------------------------------------------------------------- struct clip_rect * __gk_combine_clip_s(struct clip_rect *clipq) { struct clip_rect *clip,*clip1,*tempclip; if(clipq == NULL) return NULL; //合并剪切域 clip = clipq; clip1 = clipq->next; //执行水平合并,由于clip是按照先横后纵的方式划分的,因此水平合并只需要查 //看相邻矩形是否可以合并即可 while(clip1 != clipq) { if((clip1->rect.top == clip->rect.top) &&(clip1->rect.bottom == clip->rect.bottom) &&(clip1->rect.left == clip->rect.right)) //可合并 { clip->rect.right = clip1->rect.right; clip->next = clip1->next; clip1->next->previous = clip; mb_free(pg_clip_rect_pool,clip1); clip1 = clip->next; } else if((clip1->rect.top == clip->rect.top) //存在剪切域相同的情况 &&(clip1->rect.bottom == clip->rect.bottom) &&(clip1->rect.left == clip->rect.left) &&(clip1->rect.right== clip->rect.right)) { clip->next = clip1->next; clip1->next->previous = clip; mb_free(pg_clip_rect_pool,clip1); clip1 = clip->next; }else { clip = clip1; clip1 = clip1->next; } } //执行垂直合并,可合并的矩形可能不相邻,故需两重循环才能完成。 clip = clipq; 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 = clip1->rect.bottom; clip1->previous->next = clip1->next; clip1->next->previous = clip1->previous; tempclip = clip1; clip1 = clip1->next; mb_free(pg_clip_rect_pool,tempclip); }else clip1 = clip1->next; } clip = clip->next; }while(clip != clipq); return clipq; }
/*--------------------------------------------------------------------*/ int mbsys_surf_deall(int verbose, void *mbio_ptr, void **store_ptr, int *error) { char *function_name = "mbsys_surf_deall"; int status = MB_SUCCESS; /* print input debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> called\n",function_name); fprintf(stderr,"dbg2 Revision id: %s\n",rcs_id); fprintf(stderr,"dbg2 Input arguments:\n"); fprintf(stderr,"dbg2 verbose: %d\n",verbose); fprintf(stderr,"dbg2 mbio_ptr: %p\n",(void *)mbio_ptr); fprintf(stderr,"dbg2 store_ptr: %p\n",(void *)*store_ptr); } /* deallocate memory for data structure */ status = mb_free(verbose,store_ptr,error); /* print output debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> completed\n",function_name); fprintf(stderr,"dbg2 Return values:\n"); fprintf(stderr,"dbg2 error: %d\n",*error); fprintf(stderr,"dbg2 Return status:\n"); fprintf(stderr,"dbg2 status: %d\n",status); } /* return status */ return(status); }
void ospf_lsack_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa, struct ospf_neighbor *n) { struct proto *p = &ifa->oa->po->proto; struct ospf_lsa_header lsa; struct top_hash_entry *en; unsigned int i, lsano; unsigned int size = ntohs(ps_i->length); if (size < sizeof(struct ospf_lsack_packet)) { log(L_ERR "Bad OSPF LSACK packet from %I - too short (%u B)", n->ip, size); return; } struct ospf_lsack_packet *ps = (void *) ps_i; OSPF_PACKET(ospf_dump_lsack, ps, "LSACK packet received from %I via %s", n->ip, ifa->iface->name); ospf_neigh_sm(n, INM_HELLOREC); if (n->state < NEIGHBOR_EXCHANGE) return; lsano = (size - sizeof(struct ospf_lsack_packet)) / sizeof(struct ospf_lsa_header); for (i = 0; i < lsano; i++) { ntohlsah(ps->lsh + i, &lsa); u32 dom = ospf_lsa_domain(lsa.type, n->ifa); if ((en = ospf_hash_find_header(n->lsrth, dom, &lsa)) == NULL) continue; /* pg 155 */ if (lsa_comp(&lsa, &en->lsa) != CMP_SAME) /* pg 156 */ { if ((lsa.sn == LSA_MAXSEQNO) && (lsa.age == LSA_MAXAGE)) continue; OSPF_TRACE(D_PACKETS, "Strange LSACK from %I", n->ip); OSPF_TRACE(D_PACKETS, "Type: %04x, Id: %R, Rt: %R", lsa.type, lsa.id, lsa.rt); OSPF_TRACE(D_PACKETS, "I have: Age: %4u, Seq: %08x, Sum: %04x", en->lsa.age, en->lsa.sn, en->lsa.checksum); OSPF_TRACE(D_PACKETS, "He has: Age: %4u, Seq: %08x, Sum: %04x", lsa.age, lsa.sn, lsa.checksum); continue; } DBG("Deleting LS Id: %R RT: %R Type: %u from LS Retl for neighbor %R\n", lsa.id, lsa.rt, lsa.type, n->rid); s_rem_node(SNODE en); if (en->lsa_body != NULL) mb_free(en->lsa_body); en->lsa_body = NULL; ospf_hash_delete(n->lsrth, en); } }
/*--------------------------------------------------------------------*/ int mb_buffer_close(int verbose, void **buff_ptr, void *mbio_ptr, int *error) { char *function_name = "mb_buffer_close"; int status = MB_SUCCESS; struct mb_buffer_struct *buff; int i; /* print input debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> called\n",function_name); fprintf(stderr,"dbg2 Revision id: %s\n",rcs_id); fprintf(stderr,"dbg2 Input arguments:\n"); fprintf(stderr,"dbg2 verbose: %d\n",verbose); fprintf(stderr,"dbg2 buff_ptr: %p\n",(void *)*buff_ptr); fprintf(stderr,"dbg2 mb_ptr: %p\n",(void *)mbio_ptr); } /* get buffer structure */ buff = (struct mb_buffer_struct *) *buff_ptr; /* deal with any remaining records in the buffer */ if (buff->nbuffer > 0) { if (verbose >= 4) { fprintf(stderr,"\ndbg4 Remaining records in buffer: %d\n",buff->nbuffer); for (i=0;i<buff->nbuffer;i++) fprintf(stderr,"dbg4 Record[%d] pointer: %p\n",i,(void *)(buff->buffer[i])); } for (i=0;i<buff->nbuffer;i++) status = mb_deall(verbose,mbio_ptr, &buff->buffer[i],error); } /* deallocate memory for data structure */ status = mb_free(verbose,buff_ptr,error); /* print output debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> completed\n",function_name); fprintf(stderr,"dbg2 Revision id: %s\n",rcs_id); fprintf(stderr,"dbg2 Return values:\n"); fprintf(stderr,"dbg2 error: %d\n",*error); fprintf(stderr,"dbg2 Return status:\n"); fprintf(stderr,"dbg2 status: %d\n",status); } /* return status */ return(status); }
static void proto_free_ahooks(struct proto *p) { struct announce_hook *h, *hn; for(h = p->ahooks; h; h = hn) { hn = h->next; mb_free(h); } p->ahooks = NULL; p->main_ahook = NULL; }
//----释放clip队列------------------------------------------------------------- //功能: 释放一个clip队列的所有节点,该队列是一个双向循环队列。 //参数: clip,指向待释放队列的一个节点的指针 //返回: 无 //----------------------------------------------------------------------------- struct clip_rect *__gk_free_clip_queue(struct clip_rect *clip) { struct clip_rect *temp,*temp1; if(clip != NULL) { temp = clip; do { temp1 = temp->next; mb_free(pg_clip_rect_pool,temp); temp = temp1; }while(temp != clip); } return NULL; }
static void cli_free_out(struct cli *c) { struct cli_out *o, *p; if (o = c->tx_buf) { o->wpos = o->outpos = o->buf; while (p = o->next) { o->next = p->next; mb_free(p); } } c->tx_write = c->tx_pos = NULL; c->async_msg_size = 0; }
//----备份clip_link--------------------------------------------------------- //功能: 备份剪切域队列。 //参数: clip_link,被备份的剪切域队列 //返回: 备份的队列,出错则返回NULL //----------------------------------------------------------------------------- struct clip_rect * __gk_copy_clip_link(struct clip_rect *clip_link) { struct clip_rect *clip1,*clip2,*clip_rsc,*result = NULL; clip_rsc = clip_link; if(clip_rsc == NULL) return NULL; //创建第一个节点 clip1 = (struct clip_rect*)mb_malloc(pg_clip_rect_pool,0); if(clip1 == NULL) return NULL; clip1->rect = clip_rsc->rect; result = clip1; clip1->next = NULL; clip_rsc = clip_rsc->next; while(clip_rsc != clip_link) { clip2 = (struct clip_rect*)mb_malloc(pg_clip_rect_pool,0); if(clip2 == NULL) goto error_exit; clip2->rect = clip_rsc->rect; clip_rsc = clip_rsc->next; clip1->next = clip2; clip2->previous = clip1; clip2->next = NULL; clip1 = clip2; } //以下两句使copy_clip链表形成闭环 result->previous = clip1; clip1->next = result; return result; error_exit: clip1 = result; do { clip2 = clip1->next; mb_free(pg_clip_rect_pool,clip1); clip1 = clip2; }while(clip2 != NULL); return NULL; }
/*--------------------------------------------------------------------*/ int mbr_dem_gsfgenmb(int verbose, void *mbio_ptr, int *error) { char *function_name = "mbr_dem_gsfgenmb"; int status = MB_SUCCESS; struct mb_io_struct *mb_io_ptr; struct mbf_gsfgenmb_struct *data; gsfRecords *records; /* print input debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> called\n",function_name); fprintf(stderr,"dbg2 Revision id: %s\n",rcs_id); fprintf(stderr,"dbg2 Input arguments:\n"); fprintf(stderr,"dbg2 verbose: %d\n",verbose); fprintf(stderr,"dbg2 mbio_ptr: %p\n",(void *)mbio_ptr); } /* get pointer to mbio descriptor */ mb_io_ptr = (struct mb_io_struct *) mbio_ptr; data = (struct mbf_gsfgenmb_struct *) mb_io_ptr->raw_data; records = &(data->records); /* deallocate memory for data descriptor */ /*gsfFree(records);*/ status = mb_free(verbose,&mb_io_ptr->raw_data,error); status = mbsys_gsf_deall(verbose,mbio_ptr, &mb_io_ptr->store_data,error); /* print output debug statements */ if (verbose >= 2) { fprintf(stderr,"\ndbg2 MBIO function <%s> completed\n",function_name); fprintf(stderr,"dbg2 Return values:\n"); fprintf(stderr,"dbg2 error: %d\n",*error); fprintf(stderr,"dbg2 Return status:\n"); fprintf(stderr,"dbg2 status: %d\n",status); } /* return status */ return(status); }
void cli_set_log_echo(struct cli *c, uint mask, uint size) { if (c->ring_buf) { mb_free(c->ring_buf); c->ring_buf = c->ring_end = c->ring_read = c->ring_write = NULL; rem_node(&c->n); } c->log_mask = mask; if (mask && size) { c->ring_buf = mb_alloc(c->pool, size); c->ring_end = c->ring_buf + size; c->ring_read = c->ring_write = c->ring_buf; add_tail(&cli_log_hooks, &c->n); c->log_threshold = size / 8; } c->ring_overflow = 0; }
static void ospf_prepare_dbdes(struct ospf_proto *p, struct ospf_neighbor *n) { struct ospf_iface *ifa = n->ifa; struct ospf_packet *pkt; uint length; u16 iface_mtu = (ifa->type == OSPF_IT_VLINK) ? 0 : ifa->iface->mtu; /* Update DBDES buffer */ if (n->ldd_bsize != ifa->tx_length) { mb_free(n->ldd_buffer); n->ldd_buffer = mb_allocz(n->pool, ifa->tx_length); n->ldd_bsize = ifa->tx_length; } pkt = n->ldd_buffer; ospf_pkt_fill_hdr(ifa, pkt, DBDES_P); if (ospf_is_v2(p)) { struct ospf_dbdes2_packet *ps = (void *) pkt; ps->iface_mtu = htons(iface_mtu); ps->options = ifa->oa->options; ps->imms = 0; /* Will be set later */ ps->ddseq = htonl(n->dds); length = sizeof(struct ospf_dbdes2_packet); } else /* OSPFv3 */ { struct ospf_dbdes3_packet *ps = (void *) pkt; ps->options = htonl(ifa->oa->options); ps->iface_mtu = htons(iface_mtu); ps->padding = 0; ps->imms = 0; /* Will be set later */ ps->ddseq = htonl(n->dds); length = sizeof(struct ospf_dbdes3_packet); } /* Prepare DBDES body */ if (!(n->myimms & DBDES_I) && (n->myimms & DBDES_M)) { struct ospf_lsa_header *lsas; struct top_hash_entry *en; uint i = 0, lsa_max; ospf_dbdes_body(p, pkt, &lsas, &lsa_max); en = (void *) s_get(&(n->dbsi)); while (i < lsa_max) { if (!SNODE_VALID(en)) { n->myimms &= ~DBDES_M; /* Unset More bit */ break; } if ((en->lsa.age < LSA_MAXAGE) && lsa_flooding_allowed(en->lsa_type, en->domain, ifa)) { lsa_hton_hdr(&(en->lsa), lsas + i); i++; } en = SNODE_NEXT(en); } s_put(&(n->dbsi), SNODE en); length += i * sizeof(struct ospf_lsa_header); } if (ospf_is_v2(p)) ((struct ospf_dbdes2_packet *) pkt)->imms = n->myimms; else ((struct ospf_dbdes3_packet *) pkt)->imms = n->myimms; pkt->length = htons(length); }
void ospf_lsack_send(struct ospf_neighbor *n, int queue) { struct ospf_packet *op; struct ospf_lsack_packet *pk; u16 len, i = 0; struct ospf_lsa_header *h; struct lsah_n *no; struct ospf_iface *ifa = n->ifa; struct proto *p = &n->ifa->oa->po->proto; if (EMPTY_LIST(n->ackl[queue])) return; pk = (struct ospf_lsack_packet *) ifa->sk->tbuf; op = (struct ospf_packet *) ifa->sk->tbuf; ospf_pkt_fill_hdr(n->ifa, pk, LSACK_P); h = pk->lsh; while (!EMPTY_LIST(n->ackl[queue])) { no = (struct lsah_n *) HEAD(n->ackl[queue]); memcpy(h + i, &no->lsa, sizeof(struct ospf_lsa_header)); DBG("Iter %u ID: %R, RT: %R, Type: %04x\n", i, ntohl((h + i)->id), ntohl((h + i)->rt), (h + i)->type); i++; rem_node(NODE no); mb_free(no); if ((i * sizeof(struct ospf_lsa_header) + sizeof(struct ospf_lsack_packet)) > ospf_pkt_maxsize(n->ifa)) { if (!EMPTY_LIST(n->ackl[queue])) { len = sizeof(struct ospf_lsack_packet) + i * sizeof(struct ospf_lsa_header); op->length = htons(len); DBG("Sending and continuing! Len=%u\n", len); OSPF_PACKET(ospf_dump_lsack, (struct ospf_lsack_packet *) ifa->sk->tbuf, "LSACK packet sent via %s", ifa->iface->name); if (ifa->type == OSPF_IT_BCAST) { if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) ospf_send_to(ifa, AllSPFRouters); else ospf_send_to(ifa, AllDRouters); } else { if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE); else ospf_send_to_bdr(ifa); } ospf_pkt_fill_hdr(n->ifa, pk, LSACK_P); i = 0; } } } len = sizeof(struct ospf_lsack_packet) + i * sizeof(struct ospf_lsa_header); op->length = htons(len); DBG("Sending! Len=%u\n", len); OSPF_PACKET(ospf_dump_lsack, (struct ospf_lsack_packet *) ifa->sk->tbuf, "LSACK packet sent via %s", ifa->iface->name); if (ifa->type == OSPF_IT_BCAST) { if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP)) ospf_send_to(ifa, AllSPFRouters); else ospf_send_to(ifa, AllDRouters); } else ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE); }
//----获取被修改区域----------------------------------------------------------- //功能: 获取一个窗口的被修改部分的剪切域,形成双向循环链表,链表中的clip以先 // 左->右,再上->下的顺序排列,并清零changed_msk数组。 //参数: gkwin,目标窗口 //返回: 链表指针,NULL表示窗口未被修改 //----------------------------------------------------------------------------- struct clip_rect *__gk_get_changed_clip(struct gkwin_rsc *gkwin) { struct clip_rect *clip=NULL,*clip1,*tempclip,*clip_head = NULL; u8 *msk; u32 offset_bit,offset,msk_line_words; s16 loopx,loopy,loopz,loop=0; bool_t start; s32 width,height; if(gkwin->change_flag == cn_gkwin_change_all) //整个窗口均被修改 { clip = (struct clip_rect *)mb_malloc(pg_clip_rect_pool,0); clip->rect.left = gkwin->limit_left + gkwin->absx0; clip->rect.top = gkwin->limit_top + gkwin->absy0; clip->rect.right = gkwin->limit_right; clip->rect.bottom = gkwin->limit_bottom; clip->next = clip; clip->previous = clip; gkwin->change_flag = cn_gkwin_change_none; return clip; //把整个窗口的可显示区域当作一个剪切域返回 }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 clip_rect*)mb_malloc(pg_clip_rect_pool,0); 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 //changed block持续 { clip->rect.right += 8; } }else //如果本行的最后一块也是被改写的块,则程序不会走到这里 { if(start == true) //changed block结束 { __gk_clip_connect(&clip_head,clip); start = false; } } offset_bit++; } //本行最后一块是被改写块,需要在这里把该区域加入被修改区域 if(start == true) __gk_clip_connect(&clip_head,clip); for(loopz = 0; loopz < (s16)msk_line_words; loopz++) //changed_msk清零 msk[loopz+loop] = 0; loop += msk_line_words; 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(pg_clip_rect_pool,tempclip); }else clip1 = clip1->next; } clip = clip->next; }while(clip != clip_head); gkwin->change_flag = cn_gkwin_change_none; } return clip_head; }
static void free_mem(void) { mb_free(&wrkmem); mb_free(&block2); mb_free(&block1); }
bool blkmgr_free(blkmgr_t *blkmgr, void *memory)/*{{{*/ { DEBUG("\033[37;1mRequested to free block at $%.8x.\033[0m\n", (uint32_t)memory); /* define actions on area */ void *cut_addr = NULL; uint32_t cut_pages = 0; uint32_t shrink_left_pages = 0; uint32_t shrink_right_pages = 0; bool result = FALSE; arealst_wrlock(&blkmgr->blklst); area_t *area = arealst_find_area_by_addr(&blkmgr->blklst, memory, DONTLOCK); if (area) { mb_list_t *list = mb_list_from_area(area); mb_free_t *free = mb_free(list, memory); result = TRUE; /* is area completely empty (has exactly one block and it's free) */ if ((blkmgr->blklst.areacnt > 1) && mb_is_first(list->next) && mb_is_last(list->next)) { arealst_remove_area(&blkmgr->blklst, (void *)area, DONTLOCK); areamgr_free_area(blkmgr->areamgr, area); } else { /* can area be shrinked at the end ? */ shrink_right_pages = mb_list_can_shrink_at_end(list, sizeof(area_t)); if (shrink_right_pages > 0) { mb_list_shrink_at_end(list, shrink_right_pages, sizeof(area_t)); areamgr_shrink_area(blkmgr->areamgr, &area, SIZE_IN_PAGES(area->size) - shrink_right_pages, RIGHT); } /* can area be shrinked at the beginning ? */ shrink_left_pages = mb_list_can_shrink_at_beginning(list, sizeof(area_t)); if (shrink_left_pages > 0) { mb_list_shrink_at_beginning(&list, shrink_left_pages, sizeof(area_t)); areamgr_shrink_area(blkmgr->areamgr, &area, SIZE_IN_PAGES(area->size) - shrink_left_pages, LEFT); } /* can area be splitted ? */ cut_pages = mb_list_find_split(list, &free, &cut_addr, sizeof(area_t)); if (cut_pages > 1) { area_t *leftover = NULL; mb_list_split(mb_list_from_area(area), free, cut_pages, sizeof(area_t)); arealst_split_area(&blkmgr->areamgr->global, &area, &leftover, SIZE_IN_PAGES(cut_addr - area_begining(area)), LOCK); areamgr_shrink_area(blkmgr->areamgr, &leftover, SIZE_IN_PAGES(leftover->size) - cut_pages, LEFT); arealst_insert_area_by_addr(&blkmgr->blklst, leftover, DONTLOCK); } } } arealst_unlock(&blkmgr->blklst); return result; }/*}}}*/
//----提取剪切域队列重叠部分--------------------------------------------------- //功能: 提取src队列中的所有矩形与sub队列中重叠的部分,用ins参数返回; // src中非重叠的部分也形成新的剪切域队列,从different返回。 //参数: src,被减的队列指针,执行后,本队列将被释放或转移 // sub,减数队列指针 // ins,src与sub相交的部分 // different,src与sub不相交的部分 //返回: 无 //----------------------------------------------------------------------------- void __gk_cliplink_sub(struct clip_rect *src,struct clip_rect *sub, struct clip_rect **ins,struct clip_rect **different) { struct clip_rect *difftemp = NULL; //不重叠的部分暂存 struct clip_rect *worksrc; //src中矩形被减产生的工作子队列 struct clip_rect *end; struct clip_rect *workloop; //工作子队列的循环遍历指针 struct clip_rect *subloop; //减数队列的循环遍历指针 struct clip_rect *clip_ints=NULL; //用于收集重叠的区域 struct clip_rect *temp1; //临时变量 struct st_rect ints_rect,src_rect; bool_t endloop; 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; return; } } //被减数队列、减数队列都不为空 src->previous->next = NULL; while(src != NULL) { worksrc = src; src = src->next; worksrc->next = worksrc; worksrc->previous = worksrc; subloop = sub; do{ workloop = worksrc; end = worksrc->previous; endloop = false; //此处用循环是必要的,减sub中第一个矩形时worksrc只有一个矩形,可 //以不用循环来处理,但减第二个矩形时,worksrc可能分裂成一个队列。 do{ if(workloop == end) endloop = true; if(__gk_get_rect_ints(&workloop->rect,&subloop->rect,&ints_rect)) {//矩形相交 temp1 = (struct clip_rect *)mb_malloc(pg_clip_rect_pool,0); temp1->rect = ints_rect; //把相交区域加入clip_ints __gk_clip_connect(&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 clip_rect *)mb_malloc(pg_clip_rect_pool,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_clip_connect(&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 clip_rect *)mb_malloc(pg_clip_rect_pool,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_clip_connect(&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 clip_rect *)mb_malloc(pg_clip_rect_pool,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_clip_connect(&workloop,temp1); } uftemp++; } if(uftemp == 0) //源矩形被完全覆盖, { if(worksrc->next == worksrc) //源队列只有一个矩形 { mb_free(pg_clip_rect_pool,worksrc); worksrc = NULL; workloop = NULL; }else { temp1 = workloop; workloop = workloop->next; temp1->previous->next = workloop; workloop->previous = temp1->previous; if(worksrc == temp1) worksrc = workloop; mb_free(pg_clip_rect_pool,temp1); } } } else //矩形不相交 workloop = workloop->next; }while(!endloop); if(worksrc == NULL) break; subloop = subloop->next; }while(subloop != sub); __gk_cliplink_connect(&difftemp,worksrc); } *different = difftemp; *ins = clip_ints; }
static void free_mem(void) { mb_free(&wrkmem); mb_free(&blocks[1]); mb_free(&blocks[0]); }