6 void MergeRects(const CAtlList
<CRect
>& input
, CAtlList
<CRect
>* output
)
8 if(output
==NULL
|| input
.GetCount()==0)
14 int seg_start
, seg_end
;
15 CAtlList
<CRect
>* rects
;
32 inline bool operator<(const BreakPoint
& breakpoint
) const
34 return (x
< breakpoint
.x
);
38 int input_count
= input
.GetCount();
39 std::vector
<int> vertical_breakpoints(2*input_count
);
40 std::vector
<BreakPoint
> herizon_breakpoints(input_count
+ 1);
42 POSITION pos
= input
.GetHeadPosition();
43 for(int i
=0; i
<input_count
; i
++)
45 const CRect
& rect
= input
.GetNext(pos
);
46 vertical_breakpoints
[2*i
]=rect
.top
;
47 vertical_breakpoints
[2*i
+1]=rect
.bottom
;
49 herizon_breakpoints
[i
].x
= rect
.left
;
50 herizon_breakpoints
[i
].rect
= &rect
;
52 CRect
sentinel_rect(INT_MAX
, 0, INT_MAX
, INT_MAX
);
53 herizon_breakpoints
[input_count
].x
= INT_MAX
;//sentinel
54 herizon_breakpoints
[input_count
].rect
= &sentinel_rect
;
56 std::sort(vertical_breakpoints
.begin(), vertical_breakpoints
.end());
57 std::sort(herizon_breakpoints
.begin(), herizon_breakpoints
.end());
59 std::vector
<Segment
> tempSegments(vertical_breakpoints
.size()-1);
60 int ptr
= 1, prev
= vertical_breakpoints
[0], count
= 0;
61 for(int i
= vertical_breakpoints
.size()-1; i
> 0; i
--, ptr
++)
63 if(vertical_breakpoints
[ptr
] != prev
)
65 Segment
& seg
= tempSegments
[count
];
67 seg
.bottom
= vertical_breakpoints
[ptr
];
68 seg
.seg_end
= seg
.seg_start
= INT_MIN
;//important! cannot use =0
69 seg
.rects
= new CAtlList
<CRect
>();
71 prev
= vertical_breakpoints
[ptr
];
76 for(int i
=0; i
<=input_count
; i
++)
78 const CRect
& rect
= *herizon_breakpoints
[i
].rect
;
80 int start
= 0, mid
, end
= count
;
85 if(tempSegments
[mid
].top
< rect
.top
)
94 for(; start
< count
&& tempSegments
[start
].bottom
<= rect
.bottom
; start
++)
96 if(tempSegments
[start
].seg_end
<rect
.left
)
98 CRect
out_rect( tempSegments
[start
].seg_start
, tempSegments
[start
].top
, tempSegments
[start
].seg_end
, tempSegments
[start
].bottom
);
99 tempSegments
[start
].rects
->AddTail( out_rect
);
100 tempSegments
[start
].seg_start
= rect
.left
;
101 tempSegments
[start
].seg_end
= rect
.right
;
103 else if( tempSegments
[start
].seg_end
<rect
.right
)
105 tempSegments
[start
].seg_end
=rect
.right
;
109 for (int i
=count
-1;i
>0;i
--)
111 CAtlList
<CRect
>& cur_line
= *tempSegments
[i
].rects
;
112 CRect cur_rect
= cur_line
.RemoveTail();
113 if(tempSegments
[i
].top
== tempSegments
[i
-1].bottom
)
115 CAtlList
<CRect
>& upper_line
= *tempSegments
[i
-1].rects
;
117 POSITION pos
= upper_line
.GetTailPosition();
120 CRect
& upper_rect
= upper_line
.GetPrev(pos
);
121 while( upper_rect
.right
<cur_rect
.right
|| upper_rect
.left
<cur_rect
.left
)
123 output
->AddHead(cur_rect
);
124 //if(!cur_line.IsEmpty())
125 cur_rect
= cur_line
.RemoveTail();
127 if(cur_line
.IsEmpty())
130 if(upper_rect
.right
==cur_rect
.right
&& upper_rect
.left
==cur_rect
.left
)
132 upper_rect
.bottom
= cur_rect
.bottom
;
133 //if(!cur_line.IsEmpty())
134 cur_rect
= cur_line
.RemoveTail();
136 //else if ( upper_rect.right>cur_rect.right || upper_rect.left>cur_rect.left )
139 while(!cur_line
.IsEmpty())
141 output
->AddHead(cur_rect
);
142 cur_rect
= cur_line
.RemoveTail();
147 CAtlList
<CRect
>& cur_line
= *tempSegments
[0].rects
;
148 CRect cur_rect
= cur_line
.RemoveTail();
149 while(!cur_line
.IsEmpty())
151 output
->AddHead(cur_rect
);
152 cur_rect
= cur_line
.RemoveTail();