Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/stream.hxx>
21 : #include <tools/debug.hxx>
22 : #include <regionband.hxx>
23 :
24 : //////////////////////////////////////////////////////////////////////////////
25 :
26 : DBG_NAME( RegionBand )
27 : DBG_NAMEEX( Polygon )
28 : DBG_NAMEEX( PolyPolygon )
29 :
30 : //////////////////////////////////////////////////////////////////////////////
31 :
32 26 : RegionBand::RegionBand()
33 : : mpFirstBand(0),
34 26 : mpLastCheckedBand(0)
35 : {
36 : DBG_CTOR(RegionBand, ImplDbgTestRegionBand);
37 26 : }
38 :
39 874937 : RegionBand::RegionBand(const RegionBand& rRef)
40 : : mpFirstBand(0),
41 874937 : mpLastCheckedBand(0)
42 : {
43 874937 : *this = rRef;
44 : DBG_CTOR(RegionBand, ImplDbgTestRegionBand);
45 874937 : }
46 :
47 874937 : RegionBand& RegionBand::operator=(const RegionBand& rRef)
48 : {
49 874937 : ImplRegionBand* pPrevBand = 0;
50 874937 : ImplRegionBand* pBand = rRef.mpFirstBand;
51 :
52 2681037 : while(pBand)
53 : {
54 931163 : ImplRegionBand* pNewBand = new ImplRegionBand(*pBand);
55 :
56 : // first element? -> set as first into the list
57 931163 : if(pBand == rRef.mpFirstBand)
58 : {
59 874937 : mpFirstBand = pNewBand;
60 : }
61 : else
62 : {
63 56226 : pPrevBand->mpNextBand = pNewBand;
64 : }
65 :
66 931163 : pPrevBand = pNewBand;
67 931163 : pBand = pBand->mpNextBand;
68 : }
69 :
70 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
71 : DBG_CHKOBJ(&rRef, RegionBand, ImplDbgTestRegionBand);
72 :
73 874937 : return *this;
74 : }
75 :
76 412202 : RegionBand::RegionBand(const Rectangle& rRect)
77 : : mpFirstBand(0),
78 412202 : mpLastCheckedBand(0)
79 : {
80 412202 : const long nTop(std::min(rRect.Top(), rRect.Bottom()));
81 412202 : const long nBottom(std::max(rRect.Top(), rRect.Bottom()));
82 412202 : const long nLeft(std::min(rRect.Left(), rRect.Right()));
83 412202 : const long nRight(std::max(rRect.Left(), rRect.Right()));
84 :
85 : // add band with boundaries of the rectangle
86 412202 : mpFirstBand = new ImplRegionBand(nTop, nBottom);
87 :
88 : // Set left and right boundaries of the band
89 412202 : mpFirstBand->Union(nLeft, nRight);
90 :
91 : DBG_CTOR(RegionBand, ImplDbgTestRegionBand);
92 412202 : }
93 :
94 1287127 : void RegionBand::implReset()
95 : {
96 1287127 : ImplRegionBand* pBand = mpFirstBand;
97 :
98 3824999 : while(pBand)
99 : {
100 1250745 : ImplRegionBand* pTempBand = pBand->mpNextBand;
101 1250745 : delete pBand;
102 1250745 : pBand = pTempBand;
103 : }
104 :
105 1287127 : mpLastCheckedBand = 0;
106 :
107 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
108 1287127 : }
109 :
110 1287123 : RegionBand::~RegionBand()
111 : {
112 1287123 : implReset();
113 : DBG_DTOR(RegionBand, ImplDbgTestRegionBand);
114 1287123 : }
115 :
116 15970 : bool RegionBand::operator==( const RegionBand& rRegionBand ) const
117 : {
118 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
119 : DBG_CHKOBJ(&rRegionBand, RegionBand, ImplDbgTestRegionBand);
120 :
121 : // initialise pointers
122 15970 : ImplRegionBand* pOwnRectBand = mpFirstBand;
123 15970 : ImplRegionBandSep* pOwnRectBandSep = pOwnRectBand->mpFirstSep;
124 15970 : ImplRegionBand* pSecondRectBand = rRegionBand.mpFirstBand;
125 15970 : ImplRegionBandSep* pSecondRectBandSep = pSecondRectBand->mpFirstSep;
126 :
127 32344 : while ( pOwnRectBandSep && pSecondRectBandSep )
128 : {
129 : // get boundaries of current rectangle
130 15970 : long nOwnXLeft = pOwnRectBandSep->mnXLeft;
131 15970 : long nSecondXLeft = pSecondRectBandSep->mnXLeft;
132 :
133 15970 : if ( nOwnXLeft != nSecondXLeft )
134 : {
135 8574 : return false;
136 : }
137 :
138 7396 : long nOwnYTop = pOwnRectBand->mnYTop;
139 7396 : long nSecondYTop = pSecondRectBand->mnYTop;
140 :
141 7396 : if ( nOwnYTop != nSecondYTop )
142 : {
143 3384 : return false;
144 : }
145 :
146 4012 : long nOwnXRight = pOwnRectBandSep->mnXRight;
147 4012 : long nSecondXRight = pSecondRectBandSep->mnXRight;
148 :
149 4012 : if ( nOwnXRight != nSecondXRight )
150 : {
151 1906 : return false;
152 : }
153 :
154 2106 : long nOwnYBottom = pOwnRectBand->mnYBottom;
155 2106 : long nSecondYBottom = pSecondRectBand->mnYBottom;
156 :
157 2106 : if ( nOwnYBottom != nSecondYBottom )
158 : {
159 1702 : return false;
160 : }
161 :
162 : // get next separation from current band
163 404 : pOwnRectBandSep = pOwnRectBandSep->mpNextSep;
164 :
165 : // no separation found? -> go to next band!
166 404 : if ( !pOwnRectBandSep )
167 : {
168 : // get next band
169 404 : pOwnRectBand = pOwnRectBand->mpNextBand;
170 :
171 : // get first separation in current band
172 404 : if( pOwnRectBand )
173 : {
174 0 : pOwnRectBandSep = pOwnRectBand->mpFirstSep;
175 : }
176 : }
177 :
178 : // get next separation from current band
179 404 : pSecondRectBandSep = pSecondRectBandSep->mpNextSep;
180 :
181 : // no separation found? -> go to next band!
182 404 : if ( !pSecondRectBandSep )
183 : {
184 : // get next band
185 404 : pSecondRectBand = pSecondRectBand->mpNextBand;
186 :
187 : // get first separation in current band
188 404 : if( pSecondRectBand )
189 : {
190 0 : pSecondRectBandSep = pSecondRectBand->mpFirstSep;
191 : }
192 : }
193 :
194 404 : if ( pOwnRectBandSep && !pSecondRectBandSep )
195 : {
196 0 : return false;
197 : }
198 :
199 404 : if ( !pOwnRectBandSep && pSecondRectBandSep )
200 : {
201 0 : return false;
202 : }
203 : }
204 :
205 404 : return true;
206 : }
207 :
208 : enum StreamEntryType { STREAMENTRY_BANDHEADER, STREAMENTRY_SEPARATION, STREAMENTRY_END };
209 :
210 4 : void RegionBand::load(SvStream& rIStrm)
211 : {
212 : // clear this nstance's data
213 4 : implReset();
214 :
215 : // get all bands
216 4 : ImplRegionBand* pCurrBand = 0;
217 :
218 : // get header from first element
219 4 : sal_uInt16 nTmp16(0);
220 4 : rIStrm >> nTmp16;
221 :
222 16 : while(STREAMENTRY_END != (StreamEntryType)nTmp16)
223 : {
224 : // insert new band or new separation?
225 8 : if(STREAMENTRY_BANDHEADER == (StreamEntryType)nTmp16)
226 : {
227 4 : sal_Int32 nYTop(0);
228 4 : sal_Int32 nYBottom(0);
229 :
230 4 : rIStrm >> nYTop;
231 4 : rIStrm >> nYBottom;
232 :
233 : // create band
234 4 : ImplRegionBand* pNewBand = new ImplRegionBand( nYTop, nYBottom );
235 :
236 : // first element? -> set as first into the list
237 4 : if ( !pCurrBand )
238 : {
239 4 : mpFirstBand = pNewBand;
240 : }
241 : else
242 : {
243 0 : pCurrBand->mpNextBand = pNewBand;
244 : }
245 :
246 : // save pointer for next creation
247 4 : pCurrBand = pNewBand;
248 : }
249 : else
250 : {
251 4 : sal_Int32 nXLeft(0);
252 4 : sal_Int32 nXRight(0);
253 :
254 4 : rIStrm >> nXLeft;
255 4 : rIStrm >> nXRight;
256 :
257 : // add separation
258 4 : if ( pCurrBand )
259 : {
260 4 : pCurrBand->Union( nXLeft, nXRight );
261 : }
262 : }
263 :
264 8 : if( rIStrm.IsEof() )
265 : {
266 : OSL_ENSURE(false, "premature end of region stream" );
267 0 : implReset();
268 0 : return;
269 : }
270 :
271 : // get next header
272 8 : rIStrm >> nTmp16;
273 : }
274 :
275 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
276 : }
277 :
278 0 : void RegionBand::save(SvStream& rOStrm) const
279 : {
280 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
281 0 : ImplRegionBand* pBand = mpFirstBand;
282 :
283 0 : while(pBand)
284 : {
285 : // put boundaries
286 0 : rOStrm << (sal_uInt16)STREAMENTRY_BANDHEADER;
287 0 : rOStrm << static_cast<sal_Int32>(pBand->mnYTop);
288 0 : rOStrm << static_cast<sal_Int32>(pBand->mnYBottom);
289 :
290 : // put separations of current band
291 0 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
292 :
293 0 : while(pSep)
294 : {
295 : // put separation
296 0 : rOStrm << (sal_uInt16)STREAMENTRY_SEPARATION;
297 0 : rOStrm << static_cast<sal_Int32>(pSep->mnXLeft);
298 0 : rOStrm << static_cast<sal_Int32>(pSep->mnXRight);
299 :
300 : // next separation from current band
301 0 : pSep = pSep->mpNextSep;
302 : }
303 :
304 0 : pBand = pBand->mpNextBand;
305 : }
306 :
307 : // put endmarker
308 0 : rOStrm << (sal_uInt16)STREAMENTRY_END;
309 0 : }
310 :
311 0 : bool RegionBand::isSingleRectangle() const
312 : {
313 : // just one band?
314 0 : if(mpFirstBand && !mpFirstBand->mpNextBand)
315 : {
316 : // just one sep?
317 0 : if(mpFirstBand->mpFirstSep && !mpFirstBand->mpFirstSep->mpNextSep)
318 : {
319 0 : return true;
320 : }
321 : }
322 :
323 0 : return false;
324 : }
325 :
326 30 : void RegionBand::InsertBand(ImplRegionBand* pPreviousBand, ImplRegionBand* pBandToInsert)
327 : {
328 : OSL_ASSERT(pBandToInsert!=NULL);
329 :
330 30 : if(!pPreviousBand)
331 : {
332 : // Insert band before all others.
333 24 : if(mpFirstBand)
334 : {
335 2 : mpFirstBand->mpPrevBand = pBandToInsert;
336 : }
337 :
338 24 : pBandToInsert->mpNextBand = mpFirstBand;
339 24 : mpFirstBand = pBandToInsert;
340 : }
341 : else
342 : {
343 : // Insert band directly after pPreviousBand.
344 6 : pBandToInsert->mpNextBand = pPreviousBand->mpNextBand;
345 6 : pPreviousBand->mpNextBand = pBandToInsert;
346 6 : pBandToInsert->mpPrevBand = pPreviousBand;
347 : }
348 :
349 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
350 30 : }
351 :
352 22 : void RegionBand::processPoints()
353 : {
354 22 : ImplRegionBand* pRegionBand = mpFirstBand;
355 :
356 74 : while(pRegionBand)
357 : {
358 : // generate separations from the lines and process union
359 30 : pRegionBand->ProcessPoints();
360 30 : pRegionBand = pRegionBand->mpNextBand;
361 : }
362 :
363 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
364 22 : }
365 :
366 : /** This function is similar to the RegionBand::InsertBands() method.
367 : It creates a minimal set of missing bands so that the entire vertical
368 : interval from nTop to nBottom is covered by bands.
369 : */
370 60 : void RegionBand::ImplAddMissingBands(const long nTop, const long nBottom)
371 : {
372 : // Iterate over already existing bands and add missing bands atop the
373 : // first and between two bands.
374 60 : ImplRegionBand* pPreviousBand = NULL;
375 60 : ImplRegionBand* pBand = ImplGetFirstRegionBand();
376 60 : long nCurrentTop (nTop);
377 :
378 164 : while (pBand != NULL && nCurrentTop<nBottom)
379 : {
380 44 : if (nCurrentTop < pBand->mnYTop)
381 : {
382 : // Create new band above the current band.
383 : ImplRegionBand* pAboveBand = new ImplRegionBand(
384 : nCurrentTop,
385 2 : ::std::min(nBottom,pBand->mnYTop-1));
386 2 : InsertBand(pPreviousBand, pAboveBand);
387 : }
388 :
389 : // Adapt the top of the interval to prevent overlapping bands.
390 44 : nCurrentTop = ::std::max(nTop, pBand->mnYBottom+1);
391 :
392 : // Advance to next band.
393 44 : pPreviousBand = pBand;
394 44 : pBand = pBand->mpNextBand;
395 : }
396 :
397 : // We still have to cover two cases:
398 : // 1. The region does not yet contain any bands.
399 : // 2. The intervall nTop->nBottom extends past the bottom most band.
400 60 : if (nCurrentTop <= nBottom
401 28 : && (pBand==NULL || nBottom>pBand->mnYBottom))
402 : {
403 : // When there is no previous band then the new one will be the
404 : // first. Otherwise the new band is inserted behind the last band.
405 : InsertBand(
406 : pPreviousBand,
407 : new ImplRegionBand(
408 : nCurrentTop,
409 28 : nBottom));
410 : }
411 :
412 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
413 60 : }
414 :
415 0 : void RegionBand::CreateBandRange(long nYTop, long nYBottom)
416 : {
417 : // add top band
418 0 : mpFirstBand = new ImplRegionBand( nYTop-1, nYTop-1 );
419 :
420 : // begin first search from the first element
421 0 : mpLastCheckedBand = mpFirstBand;
422 0 : ImplRegionBand* pBand = mpFirstBand;
423 :
424 0 : for ( int i = nYTop; i <= nYBottom+1; i++ )
425 : {
426 : // create new band
427 0 : ImplRegionBand* pNewBand = new ImplRegionBand( i, i );
428 0 : pBand->mpNextBand = pNewBand;
429 :
430 0 : if ( pBand != mpFirstBand )
431 : {
432 0 : pNewBand->mpPrevBand = pBand;
433 : }
434 :
435 0 : pBand = pBand->mpNextBand;
436 : }
437 :
438 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
439 0 : }
440 :
441 0 : bool RegionBand::InsertLine(const Point& rStartPt, const Point& rEndPt, long nLineId)
442 : {
443 : long nX, nY;
444 :
445 : // lines consisting of a single point do not interest here
446 0 : if ( rStartPt == rEndPt )
447 : {
448 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
449 0 : return true;
450 : }
451 :
452 0 : LineType eLineType = (rStartPt.Y() > rEndPt.Y()) ? LINE_DESCENDING : LINE_ASCENDING;
453 0 : if ( rStartPt.X() == rEndPt.X() )
454 : {
455 : // vertical line
456 0 : const long nEndY = rEndPt.Y();
457 :
458 0 : nX = rStartPt.X();
459 0 : nY = rStartPt.Y();
460 :
461 0 : if( nEndY > nY )
462 : {
463 0 : for ( ; nY <= nEndY; nY++ )
464 : {
465 0 : Point aNewPoint( nX, nY );
466 : InsertPoint( aNewPoint, nLineId,
467 0 : (aNewPoint == rEndPt) || (aNewPoint == rStartPt),
468 0 : eLineType );
469 : }
470 : }
471 : else
472 : {
473 0 : for ( ; nY >= nEndY; nY-- )
474 : {
475 0 : Point aNewPoint( nX, nY );
476 : InsertPoint( aNewPoint, nLineId,
477 0 : (aNewPoint == rEndPt) || (aNewPoint == rStartPt),
478 0 : eLineType );
479 : }
480 : }
481 : }
482 0 : else if ( rStartPt.Y() != rEndPt.Y() )
483 : {
484 0 : const long nDX = labs( rEndPt.X() - rStartPt.X() );
485 0 : const long nDY = labs( rEndPt.Y() - rStartPt.Y() );
486 0 : const long nStartX = rStartPt.X();
487 0 : const long nStartY = rStartPt.Y();
488 0 : const long nEndX = rEndPt.X();
489 0 : const long nEndY = rEndPt.Y();
490 0 : const long nXInc = ( nStartX < nEndX ) ? 1L : -1L;
491 0 : const long nYInc = ( nStartY < nEndY ) ? 1L : -1L;
492 :
493 0 : if ( nDX >= nDY )
494 : {
495 0 : const long nDYX = ( nDY - nDX ) << 1;
496 0 : const long nDY2 = nDY << 1;
497 0 : long nD = nDY2 - nDX;
498 :
499 0 : for ( nX = nStartX, nY = nStartY; nX != nEndX; nX += nXInc )
500 : {
501 0 : InsertPoint( Point( nX, nY ), nLineId, nStartX == nX, eLineType );
502 :
503 0 : if ( nD < 0L )
504 0 : nD += nDY2;
505 : else
506 0 : nD += nDYX, nY += nYInc;
507 : }
508 : }
509 : else
510 : {
511 0 : const long nDYX = ( nDX - nDY ) << 1;
512 0 : const long nDY2 = nDX << 1;
513 0 : long nD = nDY2 - nDY;
514 :
515 0 : for ( nX = nStartX, nY = nStartY; nY != nEndY; nY += nYInc )
516 : {
517 0 : InsertPoint( Point( nX, nY ), nLineId, nStartY == nY, eLineType );
518 :
519 0 : if ( nD < 0L )
520 0 : nD += nDY2;
521 : else
522 0 : nD += nDYX, nX += nXInc;
523 : }
524 : }
525 :
526 : // last point
527 0 : InsertPoint( Point( nEndX, nEndY ), nLineId, true, eLineType );
528 : }
529 :
530 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
531 0 : return true;
532 : }
533 :
534 0 : bool RegionBand::InsertPoint(const Point &rPoint, long nLineID, bool bEndPoint, LineType eLineType)
535 : {
536 : DBG_ASSERT( mpFirstBand != NULL, "RegionBand::InsertPoint - no bands available!" );
537 :
538 0 : if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
539 : {
540 0 : mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
541 0 : return true;
542 : }
543 :
544 0 : if ( rPoint.Y() > mpLastCheckedBand->mnYTop )
545 : {
546 : // Search ascending
547 0 : while ( mpLastCheckedBand )
548 : {
549 : // Insert point if possible
550 0 : if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
551 : {
552 0 : mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
553 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
554 0 : return true;
555 : }
556 :
557 0 : mpLastCheckedBand = mpLastCheckedBand->mpNextBand;
558 : }
559 :
560 : OSL_ENSURE(false, "RegionBand::InsertPoint reached the end of the list!" );
561 : }
562 : else
563 : {
564 : // Search descending
565 0 : while ( mpLastCheckedBand )
566 : {
567 : // Insert point if possible
568 0 : if ( rPoint.Y() == mpLastCheckedBand->mnYTop )
569 : {
570 0 : mpLastCheckedBand->InsertPoint( rPoint.X(), nLineID, bEndPoint, eLineType );
571 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
572 0 : return true;
573 : }
574 :
575 0 : mpLastCheckedBand = mpLastCheckedBand->mpPrevBand;
576 : }
577 :
578 : OSL_ENSURE(false, "RegionBand::InsertPoint reached the beginning of the list!" );
579 : }
580 :
581 : OSL_ENSURE(false, "RegionBand::InsertPoint point not inserted!" );
582 :
583 : // reinitialize pointer (should never be reached!)
584 0 : mpLastCheckedBand = mpFirstBand;
585 :
586 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
587 0 : return false;
588 : }
589 :
590 609073 : bool RegionBand::OptimizeBandList()
591 : {
592 609073 : ImplRegionBand* pPrevBand = 0;
593 609073 : ImplRegionBand* pBand = mpFirstBand;
594 :
595 3306000 : while ( pBand )
596 : {
597 2087854 : const bool bBTEqual = pBand->mpNextBand && (pBand->mnYBottom == pBand->mpNextBand->mnYTop);
598 :
599 : // no separation? -> remove!
600 2087854 : if ( pBand->IsEmpty() || (bBTEqual && (pBand->mnYBottom == pBand->mnYTop)) )
601 : {
602 : // save pointer
603 922388 : ImplRegionBand* pOldBand = pBand;
604 :
605 : // previous element of the list
606 922388 : if ( pBand == mpFirstBand )
607 681928 : mpFirstBand = pBand->mpNextBand;
608 : else
609 240460 : pPrevBand->mpNextBand = pBand->mpNextBand;
610 :
611 922388 : pBand = pBand->mpNextBand;
612 922388 : delete pOldBand;
613 : }
614 : else
615 : {
616 : // fixup
617 1165466 : if ( bBTEqual )
618 1944 : pBand->mnYBottom = pBand->mpNextBand->mnYTop-1;
619 :
620 : // this and next band with equal separations? -> combine!
621 2036261 : if ( pBand->mpNextBand &&
622 2035646 : ((pBand->mnYBottom+1) == pBand->mpNextBand->mnYTop) &&
623 870180 : (*pBand == *pBand->mpNextBand) )
624 : {
625 : // expand current height
626 600487 : pBand->mnYBottom = pBand->mpNextBand->mnYBottom;
627 :
628 : // remove next band from list
629 600487 : ImplRegionBand* pDeletedBand = pBand->mpNextBand;
630 600487 : pBand->mpNextBand = pDeletedBand->mpNextBand;
631 600487 : delete pDeletedBand;
632 :
633 : // check band again!
634 : }
635 : else
636 : {
637 : // count rectangles within band
638 564979 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
639 1733716 : while ( pSep )
640 : {
641 603758 : pSep = pSep->mpNextSep;
642 : }
643 :
644 564979 : pPrevBand = pBand;
645 564979 : pBand = pBand->mpNextBand;
646 : }
647 : }
648 : }
649 :
650 : #ifdef DBG_UTIL
651 : pBand = mpFirstBand;
652 : while ( pBand )
653 : {
654 : DBG_ASSERT( pBand->mpFirstSep != NULL, "Exiting RegionBand::OptimizeBandList(): empty band in region!" );
655 :
656 : if ( pBand->mnYBottom < pBand->mnYTop )
657 : OSL_ENSURE(false, "RegionBand::OptimizeBandList(): YBottomBoundary < YTopBoundary" );
658 :
659 : if ( pBand->mpNextBand )
660 : {
661 : if ( pBand->mnYBottom >= pBand->mpNextBand->mnYTop )
662 : OSL_ENSURE(false, "RegionBand::OptimizeBandList(): overlapping bands in region!" );
663 : }
664 :
665 : pBand = pBand->mpNextBand;
666 : }
667 : #endif
668 :
669 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
670 609073 : return (0 != mpFirstBand);
671 : }
672 :
673 265895 : void RegionBand::Move(long nHorzMove, long nVertMove)
674 : {
675 265895 : ImplRegionBand* pBand = mpFirstBand;
676 :
677 805406 : while(pBand)
678 : {
679 : // process the vertical move
680 273616 : if(nVertMove)
681 : {
682 273538 : pBand->mnYTop = pBand->mnYTop + nVertMove;
683 273538 : pBand->mnYBottom = pBand->mnYBottom + nVertMove;
684 : }
685 :
686 : // process the horizontal move
687 273616 : if(nHorzMove)
688 : {
689 44189 : pBand->MoveX(nHorzMove);
690 : }
691 :
692 273616 : pBand = pBand->mpNextBand;
693 : }
694 :
695 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
696 265895 : }
697 :
698 0 : void RegionBand::Scale(double fScaleX, double fScaleY)
699 : {
700 0 : ImplRegionBand* pBand = mpFirstBand;
701 :
702 0 : while(pBand)
703 : {
704 : // process the vertical move
705 0 : if(0.0 != fScaleY)
706 : {
707 0 : pBand->mnYTop = basegfx::fround(pBand->mnYTop * fScaleY);
708 0 : pBand->mnYBottom = basegfx::fround(pBand->mnYBottom * fScaleY);
709 : }
710 :
711 : // process the horizontal move
712 0 : if(0.0 != fScaleX)
713 : {
714 0 : pBand->ScaleX(fScaleX);
715 : }
716 :
717 0 : pBand = pBand->mpNextBand;
718 : }
719 :
720 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
721 0 : }
722 :
723 617394 : void RegionBand::InsertBands(long nTop, long nBottom)
724 : {
725 : // region empty? -> set rectagle as first entry!
726 617394 : if ( !mpFirstBand )
727 : {
728 : // add band with boundaries of the rectangle
729 0 : mpFirstBand = new ImplRegionBand( nTop, nBottom );
730 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
731 617394 : return;
732 : }
733 :
734 : // find/insert bands for the boundaries of the rectangle
735 617394 : bool bTopBoundaryInserted = false;
736 617394 : bool bTop2BoundaryInserted = false;
737 617394 : bool bBottomBoundaryInserted = false;
738 :
739 : // special case: top boundary is above the first band
740 : ImplRegionBand* pNewBand;
741 :
742 617394 : if ( nTop < mpFirstBand->mnYTop )
743 : {
744 : // create new band above the first in the list
745 223744 : pNewBand = new ImplRegionBand( nTop, mpFirstBand->mnYTop );
746 :
747 223744 : if ( nBottom < mpFirstBand->mnYTop )
748 : {
749 12111 : pNewBand->mnYBottom = nBottom;
750 : }
751 :
752 : // insert band into the list
753 223744 : pNewBand->mpNextBand = mpFirstBand;
754 223744 : mpFirstBand = pNewBand;
755 :
756 223744 : bTopBoundaryInserted = true;
757 : }
758 :
759 : // insert band(s) into the list
760 617394 : ImplRegionBand* pBand = mpFirstBand;
761 :
762 2893491 : while ( pBand )
763 : {
764 : // Insert Bands if possible
765 2073980 : if ( !bTopBoundaryInserted )
766 : {
767 849153 : bTopBoundaryInserted = InsertSingleBand( pBand, nTop - 1 );
768 : }
769 :
770 2073980 : if ( !bTop2BoundaryInserted )
771 : {
772 999675 : bTop2BoundaryInserted = InsertSingleBand( pBand, nTop );
773 : }
774 :
775 2073980 : if ( !bBottomBoundaryInserted && (nTop != nBottom) )
776 : {
777 1871187 : bBottomBoundaryInserted = InsertSingleBand( pBand, nBottom );
778 : }
779 :
780 : // both boundaries inserted? -> nothing more to do
781 2073980 : if ( bTopBoundaryInserted && bTop2BoundaryInserted && bBottomBoundaryInserted )
782 : {
783 415277 : break;
784 : }
785 :
786 : // insert bands between two bands if neccessary
787 1658703 : if ( pBand->mpNextBand )
788 : {
789 1456586 : if ( (pBand->mnYBottom + 1) < pBand->mpNextBand->mnYTop )
790 : {
791 : // copy band with list and set new boundary
792 17151 : pNewBand = new ImplRegionBand( pBand->mnYBottom+1, pBand->mpNextBand->mnYTop-1 );
793 :
794 : // insert band into the list
795 17151 : pNewBand->mpNextBand = pBand->mpNextBand;
796 17151 : pBand->mpNextBand = pNewBand;
797 : }
798 : }
799 :
800 1658703 : pBand = pBand->mpNextBand;
801 : }
802 :
803 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
804 : }
805 :
806 3720015 : bool RegionBand::InsertSingleBand(ImplRegionBand* pBand, long nYBandPosition)
807 : {
808 : // boundary already included in band with height 1? -> nothing to do!
809 3720015 : if ( (pBand->mnYTop == pBand->mnYBottom) && (nYBandPosition == pBand->mnYTop) )
810 : {
811 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
812 9562 : return true;
813 : }
814 :
815 : // insert single height band on top?
816 : ImplRegionBand* pNewBand;
817 :
818 3710453 : if ( nYBandPosition == pBand->mnYTop )
819 : {
820 : // copy band with list and set new boundary
821 549830 : pNewBand = new ImplRegionBand( *pBand );
822 549830 : pNewBand->mnYTop = nYBandPosition+1;
823 :
824 : // insert band into the list
825 549830 : pNewBand->mpNextBand = pBand->mpNextBand;
826 549830 : pBand->mnYBottom = nYBandPosition;
827 549830 : pBand->mpNextBand = pNewBand;
828 :
829 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
830 549830 : return true;
831 : }
832 :
833 : // top of new rectangle within the current band? -> insert new band and copy data
834 3160623 : if ( (nYBandPosition > pBand->mnYTop) && (nYBandPosition < pBand->mnYBottom) )
835 : {
836 : // copy band with list and set new boundary
837 258233 : pNewBand = new ImplRegionBand( *pBand );
838 258233 : pNewBand->mnYTop = nYBandPosition;
839 :
840 : // insert band into the list
841 258233 : pNewBand->mpNextBand = pBand->mpNextBand;
842 258233 : pBand->mnYBottom = nYBandPosition;
843 258233 : pBand->mpNextBand = pNewBand;
844 :
845 : // copy band with list and set new boundary
846 258233 : pNewBand = new ImplRegionBand( *pBand );
847 258233 : pNewBand->mnYTop = nYBandPosition;
848 :
849 : // insert band into the list
850 258233 : pBand->mpNextBand->mnYTop = nYBandPosition+1;
851 :
852 258233 : pNewBand->mpNextBand = pBand->mpNextBand;
853 258233 : pBand->mnYBottom = nYBandPosition - 1;
854 258233 : pBand->mpNextBand = pNewBand;
855 :
856 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
857 258233 : return true;
858 : }
859 :
860 : // create new band behind the current in the list
861 2902390 : if ( !pBand->mpNextBand )
862 : {
863 1166092 : if ( nYBandPosition == pBand->mnYBottom )
864 : {
865 : // copy band with list and set new boundary
866 177907 : pNewBand = new ImplRegionBand( *pBand );
867 177907 : pNewBand->mnYTop = pBand->mnYBottom;
868 177907 : pNewBand->mnYBottom = nYBandPosition;
869 :
870 177907 : pBand->mnYBottom = nYBandPosition-1;
871 :
872 : // append band to the list
873 177907 : pBand->mpNextBand = pNewBand;
874 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
875 177907 : return true;
876 : }
877 :
878 988185 : if ( nYBandPosition > pBand->mnYBottom )
879 : {
880 : // create new band
881 423990 : pNewBand = new ImplRegionBand( pBand->mnYBottom + 1, nYBandPosition );
882 :
883 : // append band to the list
884 423990 : pBand->mpNextBand = pNewBand;
885 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
886 423990 : return true;
887 : }
888 : }
889 :
890 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
891 2300493 : return false;
892 : }
893 :
894 43094 : void RegionBand::Union(long nLeft, long nTop, long nRight, long nBottom)
895 : {
896 : DBG_ASSERT( nLeft <= nRight, "RegionBand::Union() - nLeft > nRight" );
897 : DBG_ASSERT( nTop <= nBottom, "RegionBand::Union() - nTop > nBottom" );
898 :
899 : // process union
900 43094 : ImplRegionBand* pBand = mpFirstBand;
901 248740 : while ( pBand )
902 : {
903 176800 : if ( pBand->mnYTop >= nTop )
904 : {
905 144729 : if ( pBand->mnYBottom <= nBottom )
906 130481 : pBand->Union( nLeft, nRight );
907 : else
908 : {
909 : #ifdef DBG_UTIL
910 : long nCurY = pBand->mnYBottom;
911 : pBand = pBand->mpNextBand;
912 : while ( pBand )
913 : {
914 : if ( (pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY) )
915 : {
916 : OSL_ENSURE(false, "RegionBand::Union() - Bands not sorted!" );
917 : }
918 : pBand = pBand->mpNextBand;
919 : }
920 : #endif
921 14248 : break;
922 : }
923 : }
924 :
925 162552 : pBand = pBand->mpNextBand;
926 : }
927 :
928 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
929 43094 : }
930 :
931 171132 : void RegionBand::Intersect(long nLeft, long nTop, long nRight, long nBottom)
932 : {
933 : // process intersections
934 171132 : ImplRegionBand* pPrevBand = 0;
935 171132 : ImplRegionBand* pBand = mpFirstBand;
936 :
937 1008331 : while(pBand)
938 : {
939 : // band within intersection boundary? -> process. otherwise remove
940 666067 : if((pBand->mnYTop >= nTop) && (pBand->mnYBottom <= nBottom))
941 : {
942 : // process intersection
943 527666 : pBand->Intersect(nLeft, nRight);
944 527666 : pPrevBand = pBand;
945 527666 : pBand = pBand->mpNextBand;
946 : }
947 : else
948 : {
949 138401 : ImplRegionBand* pOldBand = pBand;
950 :
951 138401 : if(pBand == mpFirstBand)
952 : {
953 136026 : mpFirstBand = pBand->mpNextBand;
954 : }
955 : else
956 : {
957 2375 : pPrevBand->mpNextBand = pBand->mpNextBand;
958 : }
959 :
960 138401 : pBand = pBand->mpNextBand;
961 138401 : delete pOldBand;
962 : }
963 : }
964 :
965 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
966 171132 : }
967 :
968 36218 : void RegionBand::Union(const RegionBand& rSource)
969 : {
970 : // apply all rectangles from rSource to this
971 36218 : ImplRegionBand* pBand = rSource.mpFirstBand;
972 :
973 110116 : while ( pBand )
974 : {
975 : // insert bands if the boundaries are not allready in the list
976 37680 : InsertBands(pBand->mnYTop, pBand->mnYBottom);
977 :
978 : // process all elements of the list
979 37680 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
980 :
981 113362 : while(pSep)
982 : {
983 38002 : Union(pSep->mnXLeft, pBand->mnYTop, pSep->mnXRight, pBand->mnYBottom);
984 38002 : pSep = pSep->mpNextSep;
985 : }
986 :
987 37680 : pBand = pBand->mpNextBand;
988 : }
989 :
990 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
991 36218 : }
992 :
993 841575 : void RegionBand::Exclude(long nLeft, long nTop, long nRight, long nBottom)
994 : {
995 : DBG_ASSERT( nLeft <= nRight, "RegionBand::Exclude() - nLeft > nRight" );
996 : DBG_ASSERT( nTop <= nBottom, "RegionBand::Exclude() - nTop > nBottom" );
997 :
998 : // process exclude
999 841575 : ImplRegionBand* pBand = mpFirstBand;
1000 :
1001 4981375 : while(pBand)
1002 : {
1003 3562179 : if(pBand->mnYTop >= nTop)
1004 : {
1005 3016598 : if(pBand->mnYBottom <= nBottom)
1006 : {
1007 2752644 : pBand->Exclude(nLeft, nRight);
1008 : }
1009 : else
1010 : {
1011 : #ifdef DBG_UTIL
1012 : long nCurY = pBand->mnYBottom;
1013 : pBand = pBand->mpNextBand;
1014 :
1015 : while(pBand)
1016 : {
1017 : if((pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY))
1018 : {
1019 : OSL_ENSURE(false, "RegionBand::Exclude() - Bands not sorted!" );
1020 : }
1021 :
1022 : pBand = pBand->mpNextBand;
1023 : }
1024 : #endif
1025 263954 : break;
1026 : }
1027 : }
1028 :
1029 3298225 : pBand = pBand->mpNextBand;
1030 : }
1031 :
1032 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1033 841575 : }
1034 :
1035 0 : void RegionBand::XOr(long nLeft, long nTop, long nRight, long nBottom)
1036 : {
1037 : DBG_ASSERT( nLeft <= nRight, "RegionBand::Exclude() - nLeft > nRight" );
1038 : DBG_ASSERT( nTop <= nBottom, "RegionBand::Exclude() - nTop > nBottom" );
1039 :
1040 : // process xor
1041 0 : ImplRegionBand* pBand = mpFirstBand;
1042 :
1043 0 : while(pBand)
1044 : {
1045 0 : if(pBand->mnYTop >= nTop)
1046 : {
1047 0 : if(pBand->mnYBottom <= nBottom)
1048 : {
1049 0 : pBand->XOr(nLeft, nRight);
1050 : }
1051 : else
1052 : {
1053 : #ifdef DBG_UTIL
1054 : long nCurY = pBand->mnYBottom;
1055 : pBand = pBand->mpNextBand;
1056 :
1057 : while(pBand)
1058 : {
1059 : if((pBand->mnYTop < nCurY) || (pBand->mnYBottom < nCurY))
1060 : {
1061 : OSL_ENSURE(false, "RegionBand::XOr() - Bands not sorted!" );
1062 : }
1063 :
1064 : pBand = pBand->mpNextBand;
1065 : }
1066 : #endif
1067 0 : break;
1068 : }
1069 : }
1070 :
1071 0 : pBand = pBand->mpNextBand;
1072 : }
1073 :
1074 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1075 0 : }
1076 :
1077 352303 : void RegionBand::Intersect(const RegionBand& rSource)
1078 : {
1079 : // mark all bands as untouched
1080 352303 : ImplRegionBand* pBand = mpFirstBand;
1081 :
1082 1063266 : while ( pBand )
1083 : {
1084 358660 : pBand->mbTouched = false;
1085 358660 : pBand = pBand->mpNextBand;
1086 : }
1087 :
1088 352303 : pBand = rSource.mpFirstBand;
1089 :
1090 1063790 : while ( pBand )
1091 : {
1092 : // insert bands if the boundaries are not allready in the list
1093 359184 : InsertBands( pBand->mnYTop, pBand->mnYBottom );
1094 :
1095 : // process all elements of the list
1096 359184 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
1097 :
1098 1156445 : while ( pSep )
1099 : {
1100 : // left boundary?
1101 438077 : if ( pSep == pBand->mpFirstSep )
1102 : {
1103 : // process intersection and do not remove untouched bands
1104 359184 : Exclude( LONG_MIN+1, pBand->mnYTop, pSep->mnXLeft-1, pBand->mnYBottom );
1105 : }
1106 :
1107 : // right boundary?
1108 438077 : if ( pSep->mpNextSep == NULL )
1109 : {
1110 : // process intersection and do not remove untouched bands
1111 359184 : Exclude( pSep->mnXRight+1, pBand->mnYTop, LONG_MAX-1, pBand->mnYBottom );
1112 : }
1113 : else
1114 : {
1115 : // process intersection and do not remove untouched bands
1116 78893 : Exclude( pSep->mnXRight+1, pBand->mnYTop, pSep->mpNextSep->mnXLeft-1, pBand->mnYBottom );
1117 : }
1118 :
1119 438077 : pSep = pSep->mpNextSep;
1120 : }
1121 :
1122 359184 : pBand = pBand->mpNextBand;
1123 : }
1124 :
1125 : // remove all untouched bands if bands allready left
1126 352303 : ImplRegionBand* pPrevBand = 0;
1127 352303 : pBand = mpFirstBand;
1128 :
1129 2238331 : while ( pBand )
1130 : {
1131 1533725 : if ( !pBand->mbTouched )
1132 : {
1133 : // save pointer
1134 340422 : ImplRegionBand* pOldBand = pBand;
1135 :
1136 : // previous element of the list
1137 340422 : if ( pBand == mpFirstBand )
1138 : {
1139 219702 : mpFirstBand = pBand->mpNextBand;
1140 : }
1141 : else
1142 : {
1143 120720 : pPrevBand->mpNextBand = pBand->mpNextBand;
1144 : }
1145 :
1146 340422 : pBand = pBand->mpNextBand;
1147 340422 : delete pOldBand;
1148 : }
1149 : else
1150 : {
1151 1193303 : pPrevBand = pBand;
1152 1193303 : pBand = pBand->mpNextBand;
1153 : }
1154 : }
1155 :
1156 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1157 352303 : }
1158 :
1159 929 : bool RegionBand::Exclude(const RegionBand& rSource)
1160 : {
1161 : // Alle Rechtecke aus der uebergebenen Region auf diese Region anwenden
1162 929 : ImplRegionBand* pBand = rSource.mpFirstBand;
1163 :
1164 2745 : while ( pBand )
1165 : {
1166 : // insert bands if the boundaries are not allready in the list
1167 938 : InsertBands( pBand->mnYTop, pBand->mnYBottom );
1168 :
1169 : // process all elements of the list
1170 938 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
1171 :
1172 2822 : while ( pSep )
1173 : {
1174 946 : Exclude( pSep->mnXLeft, pBand->mnYTop, pSep->mnXRight, pBand->mnYBottom );
1175 946 : pSep = pSep->mpNextSep;
1176 : }
1177 :
1178 : // to test less bands, already check in the loop
1179 938 : if ( !OptimizeBandList() )
1180 : {
1181 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1182 51 : return false;
1183 : }
1184 :
1185 887 : pBand = pBand->mpNextBand;
1186 : }
1187 :
1188 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1189 878 : return true;
1190 : }
1191 :
1192 173739 : Rectangle RegionBand::GetBoundRect() const
1193 : {
1194 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1195 :
1196 : // get the boundaries of the first band
1197 173739 : long nYTop(mpFirstBand->mnYTop);
1198 173739 : long nYBottom(mpFirstBand->mnYBottom);
1199 173739 : long nXLeft(mpFirstBand->GetXLeftBoundary());
1200 173739 : long nXRight(mpFirstBand->GetXRightBoundary());
1201 :
1202 : // look in the band list (don't test first band again!)
1203 173739 : ImplRegionBand* pBand = mpFirstBand->mpNextBand;
1204 :
1205 353915 : while ( pBand )
1206 : {
1207 6437 : nYBottom = pBand->mnYBottom;
1208 6437 : nXLeft = std::min( nXLeft, pBand->GetXLeftBoundary() );
1209 6437 : nXRight = std::max( nXRight, pBand->GetXRightBoundary() );
1210 :
1211 6437 : pBand = pBand->mpNextBand;
1212 : }
1213 :
1214 173739 : return Rectangle( nXLeft, nYTop, nXRight, nYBottom );
1215 : }
1216 :
1217 0 : void RegionBand::XOr(const RegionBand& rSource)
1218 : {
1219 0 : ImplRegionBand* pBand = rSource.mpFirstBand;
1220 :
1221 0 : while ( pBand )
1222 : {
1223 : // insert bands if the boundaries are not allready in the list
1224 0 : InsertBands( pBand->mnYTop, pBand->mnYBottom );
1225 :
1226 : // process all elements of the list
1227 0 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
1228 :
1229 0 : while ( pSep )
1230 : {
1231 0 : XOr( pSep->mnXLeft, pBand->mnYTop, pSep->mnXRight, pBand->mnYBottom );
1232 0 : pSep = pSep->mpNextSep;
1233 : }
1234 :
1235 0 : pBand = pBand->mpNextBand;
1236 : }
1237 0 : }
1238 :
1239 0 : bool RegionBand::IsInside(const Point& rPoint) const
1240 : {
1241 : DBG_CHKTHIS(RegionBand, ImplDbgTestRegionBand);
1242 :
1243 : // search band list
1244 0 : ImplRegionBand* pBand = mpFirstBand;
1245 :
1246 0 : while(pBand)
1247 : {
1248 : // is point within band?
1249 0 : if((pBand->mnYTop <= rPoint.Y()) && (pBand->mnYBottom >= rPoint.Y()))
1250 : {
1251 : // is point within separation of the band?
1252 0 : if(pBand->IsInside(rPoint.X()))
1253 : {
1254 0 : return true;
1255 : }
1256 : else
1257 : {
1258 0 : return false;
1259 : }
1260 : }
1261 :
1262 0 : pBand = pBand->mpNextBand;
1263 : }
1264 :
1265 0 : return false;
1266 : }
1267 :
1268 379457 : void RegionBand::GetRegionRectangles(RectangleVector& rTarget) const
1269 : {
1270 : // clear result vector
1271 379457 : rTarget.clear();
1272 379457 : ImplRegionBand* mpCurrRectBand = mpFirstBand;
1273 379457 : Rectangle aRectangle;
1274 :
1275 1159303 : while(mpCurrRectBand)
1276 : {
1277 400389 : ImplRegionBandSep* mpCurrRectBandSep = mpCurrRectBand->mpFirstSep;
1278 :
1279 400389 : aRectangle.Top() = mpCurrRectBand->mnYTop;
1280 400389 : aRectangle.Bottom() = mpCurrRectBand->mnYBottom;
1281 :
1282 1436792 : while(mpCurrRectBandSep)
1283 : {
1284 636014 : aRectangle.Left() = mpCurrRectBandSep->mnXLeft;
1285 636014 : aRectangle.Right() = mpCurrRectBandSep->mnXRight;
1286 636014 : rTarget.push_back(aRectangle);
1287 636014 : mpCurrRectBandSep = mpCurrRectBandSep->mpNextSep;
1288 : }
1289 :
1290 400389 : mpCurrRectBand = mpCurrRectBand->mpNextBand;
1291 : }
1292 379457 : }
1293 :
1294 704606 : sal_uInt32 RegionBand::getRectangleCount() const
1295 : {
1296 704606 : sal_uInt32 nCount = 0;
1297 704606 : const ImplRegionBand* pBand = mpFirstBand;
1298 :
1299 2127056 : while(pBand)
1300 : {
1301 717844 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
1302 :
1303 2282310 : while(pSep)
1304 : {
1305 846622 : nCount++;
1306 846622 : pSep = pSep->mpNextSep;
1307 : }
1308 :
1309 717844 : pBand = pBand->mpNextBand;
1310 : }
1311 :
1312 704606 : return 0;
1313 : }
1314 :
1315 : #ifdef DBG_UTIL
1316 : const char* ImplDbgTestRegionBand(const void* pObj)
1317 : {
1318 : const RegionBand* pRegionBand = reinterpret_cast< const RegionBand* >(pObj);
1319 :
1320 : if(pRegionBand)
1321 : {
1322 : const ImplRegionBand* pBand = pRegionBand->ImplGetFirstRegionBand();
1323 :
1324 : while(pBand)
1325 : {
1326 : if(pBand->mnYBottom < pBand->mnYTop)
1327 : {
1328 : return "YBottom < YTop";
1329 : }
1330 :
1331 : if(pBand->mpNextBand)
1332 : {
1333 : if(pBand->mnYBottom >= pBand->mpNextBand->mnYTop)
1334 : {
1335 : return "overlapping bands in region";
1336 : }
1337 : }
1338 :
1339 : if(pBand->mbTouched)
1340 : {
1341 : return "Band-mbTouched overwrite";
1342 : }
1343 :
1344 : ImplRegionBandSep* pSep = pBand->mpFirstSep;
1345 :
1346 : while(pSep)
1347 : {
1348 : if(pSep->mnXRight < pSep->mnXLeft)
1349 : {
1350 : return "XLeft < XRight";
1351 : }
1352 :
1353 : if(pSep->mpNextSep)
1354 : {
1355 : if(pSep->mnXRight >= pSep->mpNextSep->mnXLeft)
1356 : {
1357 : return "overlapping separations in region";
1358 : }
1359 : }
1360 :
1361 : if ( pSep->mbRemoved )
1362 : {
1363 : return "Sep-mbRemoved overwrite";
1364 : }
1365 :
1366 : pSep = pSep->mpNextSep;
1367 : }
1368 :
1369 : pBand = pBand->mpNextBand;
1370 : }
1371 : }
1372 :
1373 : return 0;
1374 : }
1375 : #endif
1376 :
1377 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|