LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/gdi - regionband.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 349 488 71.5 %
Date: 2013-07-09 Functions: 24 33 72.7 %
Legend: Lines: hit not hit

          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: */

Generated by: LCOV version 1.10