OpenClonk
C4RectList Class Reference

#include <C4Rect.h>

Inheritance diagram for C4RectList:
[legend]
Collaboration diagram for C4RectList:
[legend]

Public Member Functions

void AddRect (const C4Rect &rNewRect)
 
void RemoveIndexedRect (int32_t idx)
 
void Clear ()
 
size_t GetCount () const
 
C4RectGet (size_t idx)
 
void ClipByRect (const C4Rect &rClip)
 

Detailed Description

Definition at line 98 of file C4Rect.h.

Member Function Documentation

◆ AddRect()

void C4RectList::AddRect ( const C4Rect rNewRect)
inline

Definition at line 101 of file C4Rect.h.

102  { push_back(rNewRect); }

Referenced by ClipByRect(), and C4ViewportList::RecalculateViewports().

Here is the caller graph for this function:

◆ Clear()

void C4RectList::Clear ( )
inline

Definition at line 105 of file C4Rect.h.

105 { clear(); }

Referenced by C4ViewportList::RecalculateViewports().

Here is the caller graph for this function:

◆ ClipByRect()

void C4RectList::ClipByRect ( const C4Rect rClip)

Definition at line 173 of file C4Rect.cpp.

174 {
175  // split up all rectangles
176  for (size_t i = 0; i < GetCount(); ++i)
177  {
178  C4Rect *pTarget = &Get(i);
179  // any overlap?
180  if (rClip.x+rClip.Wdt <= pTarget->x) continue;
181  if (rClip.y+rClip.Hgt <= pTarget->y) continue;
182  if (rClip.x >= pTarget->x+pTarget->Wdt) continue;
183  if (rClip.y >= pTarget->y+pTarget->Hgt) continue;
184  // okay; split up rectangle
185  // first split will just reduce the target rectangle size
186  // if more splits are done, additional rectangles need to be added
187  int32_t iSplitCount = 0, iOver; C4Rect rcThis(*pTarget);
188  // clipped by right side
189  if ((iOver=rcThis.x+rcThis.Wdt-rClip.x-rClip.Wdt)>0)
190  {
191  pTarget->x += pTarget->Wdt - iOver; pTarget->Wdt = iOver; rcThis.Wdt -= iOver;
192  ++iSplitCount;
193  }
194  // clipped by obttom side
195  if ((iOver=rcThis.y+rcThis.Hgt-rClip.y-rClip.Hgt)>0)
196  {
197  if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
198  pTarget->y += pTarget->Hgt - iOver; pTarget->Hgt = iOver; rcThis.Hgt -= iOver;
199  ++iSplitCount;
200  }
201  // clipped by left side
202  if ((iOver=rClip.x-rcThis.x)>0)
203  {
204  if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
205  pTarget->Wdt = iOver; rcThis.Wdt -= iOver; rcThis.x = rClip.x;
206  ++iSplitCount;
207  }
208  // clipped by top side
209  if ((iOver=rClip.y-rcThis.y)>0)
210  {
211  if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
212  else ++iSplitCount;
213  pTarget->Hgt = iOver; /* rcThis.Hgt -= iOver; rcThis.y = rClip.y; not needed, since rcThis is no longer used */
214  }
215  // nothing split? This means this rectnagle is completely contained
216  if (!iSplitCount)
217  {
218  // make it vanish
219  RemoveIndexedRect(i); --i;
220  }
221  }
222  // concat rectangles if possible
223  bool fDone = false;
224  while (!fDone)
225  {
226  fDone=true;
227  for (size_t i = 0, cnt=GetCount(); i < cnt && fDone; ++i)
228  {
229  C4Rect &rc1 = Get(i);
230  for (size_t j = i+1; j < cnt; ++j)
231  {
232  C4Rect &rc2 = Get(j);
233  if (rc1.y == rc2.y && rc1.Hgt == rc2.Hgt)
234  {
235  if (rc1.x + rc1.Wdt == rc2.x)
236  {
237  rc1.Wdt += rc2.Wdt; RemoveIndexedRect(j); fDone=false; break;
238  }
239  else if (rc2.x + rc2.Wdt == rc1.x)
240  {
241  rc2.Wdt += rc1.Wdt; RemoveIndexedRect(i); fDone=false; break;
242  }
243  }
244  else if (rc1.x == rc2.x && rc1.Wdt == rc2.Wdt)
245  {
246  if (rc1.y + rc1.Hgt == rc2.y)
247  {
248  rc1.Hgt += rc2.Hgt; RemoveIndexedRect(j); fDone=false; break;
249  }
250  else if (rc2.y + rc2.Hgt == rc1.y)
251  {
252  rc2.Hgt += rc1.Hgt; RemoveIndexedRect(i); fDone=false; break;
253  }
254  }
255  }
256  }
257  }
258 }
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
void AddRect(const C4Rect &rNewRect)
Definition: C4Rect.h:101
void RemoveIndexedRect(int32_t idx)
Definition: C4Rect.h:103
size_t GetCount() const
Definition: C4Rect.h:106
C4Rect & Get(size_t idx)
Definition: C4Rect.h:107

References AddRect(), Get(), GetCount(), C4Rect::Hgt, RemoveIndexedRect(), C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by C4ViewportList::RecalculateViewports().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Get()

C4Rect& C4RectList::Get ( size_t  idx)
inline

Definition at line 107 of file C4Rect.h.

107 { return (*this)[idx]; } // access w/o range check

Referenced by ClipByRect(), C4ViewportList::DrawFullscreenBackground(), and RemoveIndexedRect().

Here is the caller graph for this function:

◆ GetCount()

size_t C4RectList::GetCount ( ) const
inline

Definition at line 106 of file C4Rect.h.

106 { return size(); }

Referenced by ClipByRect(), C4ViewportList::DrawFullscreenBackground(), and RemoveIndexedRect().

Here is the caller graph for this function:

◆ RemoveIndexedRect()

void C4RectList::RemoveIndexedRect ( int32_t  idx)
inline

Definition at line 103 of file C4Rect.h.

104  { if (idx<int32_t(GetCount()-1)) Get(idx)=Get(GetCount()-1); pop_back(); }

References Get(), and GetCount().

Referenced by ClipByRect().

Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following files: