LCOV - code coverage report
Current view: top level - libreoffice/editeng/source/misc - txtrange.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 345 0.0 %
Date: 2012-12-27 Functions: 0 27 0.0 %
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             : 
      21             : #include <editeng/txtrange.hxx>
      22             : #include <math.h>
      23             : #include <tools/poly.hxx>
      24             : #include <tools/debug.hxx>
      25             : #include <basegfx/polygon/b2dpolygon.hxx>
      26             : #include <basegfx/polygon/b2dpolygontools.hxx>
      27             : 
      28             : #include <vector>
      29             : 
      30           0 : TextRanger::TextRanger( const basegfx::B2DPolyPolygon& rPolyPolygon,
      31             :                         const basegfx::B2DPolyPolygon* pLinePolyPolygon,
      32             :                         sal_uInt16 nCacheSz, sal_uInt16 nLft, sal_uInt16 nRght,
      33             :                         sal_Bool bSimpl, sal_Bool bInnr, sal_Bool bVert ) :
      34             :     pBound( NULL ),
      35             :     nCacheSize( nCacheSz ),
      36             :     nRight( nRght ),
      37             :     nLeft( nLft ),
      38             :     nUpper( 0 ),
      39             :     nLower( 0 ),
      40             :     nPointCount( 0 ),
      41             :     bSimple( bSimpl ),
      42             :     bInner( bInnr ),
      43           0 :     bVertical( bVert )
      44             : {
      45             : #ifdef DBG_UTIL
      46             :     bFlag3 = bFlag4 = bFlag5 = bFlag6 = bFlag7 = sal_False;
      47             : #endif
      48           0 :     sal_uInt32 nCount(rPolyPolygon.count());
      49           0 :     mpPolyPolygon = new PolyPolygon( (sal_uInt16)nCount );
      50             : 
      51           0 :     for(sal_uInt32 i(0L); i < nCount; i++)
      52             :     {
      53           0 :         const basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(i).getDefaultAdaptiveSubdivision());
      54           0 :         nPointCount += aCandidate.count();
      55           0 :         mpPolyPolygon->Insert( Polygon(aCandidate), (sal_uInt16)i );
      56           0 :     }
      57             : 
      58           0 :     if( pLinePolyPolygon )
      59             :     {
      60           0 :         nCount = pLinePolyPolygon->count();
      61           0 :         mpLinePolyPolygon = new PolyPolygon();
      62             : 
      63           0 :         for(sal_uInt32 i(0L); i < nCount; i++)
      64             :         {
      65           0 :             const basegfx::B2DPolygon aCandidate(pLinePolyPolygon->getB2DPolygon(i).getDefaultAdaptiveSubdivision());
      66           0 :             nPointCount += aCandidate.count();
      67           0 :             mpLinePolyPolygon->Insert( Polygon(aCandidate), (sal_uInt16)i );
      68           0 :         }
      69             :     }
      70             :     else
      71           0 :         mpLinePolyPolygon = NULL;
      72           0 : }
      73             : 
      74             : 
      75           0 : TextRanger::~TextRanger()
      76             : {
      77           0 :     mRangeCache.clear();
      78           0 :     delete mpPolyPolygon;
      79           0 :     delete mpLinePolyPolygon;
      80           0 : }
      81             : 
      82             : /* TextRanger::SetVertical(..)
      83             :    If there's is a change in the writing direction,
      84             :    the cache has to be cleared.
      85             : */
      86           0 : void TextRanger::SetVertical( sal_Bool bNew )
      87             : {
      88           0 :     if( IsVertical() != bNew )
      89             :     {
      90           0 :         bVertical = bNew;
      91           0 :         mRangeCache.clear();
      92             :     }
      93           0 : }
      94             : 
      95             : //! SvxBoundArgs is used to perform temporary calculations on a range array.
      96             : //! Temporary instances are created in TextRanger::GetTextRanges()
      97           0 : class SvxBoundArgs
      98             : {
      99             :     std::vector<bool> aBoolArr;
     100             :     LongDqPtr pLongArr;
     101             :     TextRanger *pTextRanger;
     102             :     long nMin;
     103             :     long nMax;
     104             :     long nTop;
     105             :     long nBottom;
     106             :     long nUpDiff;
     107             :     long nLowDiff;
     108             :     long nUpper;
     109             :     long nLower;
     110             :     long nStart;
     111             :     long nEnd;
     112             :     sal_uInt16 nCut;
     113             :     sal_uInt16 nLast;
     114             :     sal_uInt16 nNext;
     115             :     sal_uInt8 nAct;
     116             :     sal_uInt8 nFirst;
     117             :     sal_Bool bClosed : 1;
     118             :     sal_Bool bInner : 1;
     119             :     sal_Bool bMultiple : 1;
     120             :     sal_Bool bConcat : 1;
     121             :     sal_Bool bRotate : 1;
     122             :     void NoteRange( bool bToggle );
     123             :     long Cut( long nY, const Point& rPt1, const Point& rPt2 );
     124             :     void Add();
     125             :     void _NoteFarPoint( long nPx, long nPyDiff, long nDiff );
     126           0 :     void NoteFarPoint( long nPx, long nPyDiff, long nDiff )
     127           0 :         { if( nDiff ) _NoteFarPoint( nPx, nPyDiff, nDiff ); }
     128             :     long CalcMax( const Point& rPt1, const Point& rPt2, long nRange, long nFar );
     129             :     void CheckCut( const Point& rLst, const Point& rNxt );
     130           0 :     inline long A( const Point& rP ) const { return bRotate ? rP.Y() : rP.X(); }
     131           0 :     inline long B( const Point& rP ) const { return bRotate ? rP.X() : rP.Y(); }
     132             : public:
     133             :     SvxBoundArgs( TextRanger* pRanger, LongDqPtr pLong, const Range& rRange );
     134           0 :     void NotePoint( const long nA ) { NoteMargin( nA - nStart, nA + nEnd ); }
     135           0 :     void NoteMargin( const long nL, const long nR )
     136           0 :         { if( nMin > nL ) nMin = nL; if( nMax < nR ) nMax = nR; }
     137             :     sal_uInt16 Area( const Point& rPt );
     138             :     void NoteUpLow( long nA, const sal_uInt8 nArea );
     139             :     void Calc( const PolyPolygon& rPoly );
     140             :     void Concat( const PolyPolygon* pPoly );
     141             :     // inlines
     142           0 :     void NoteLast() { if( bMultiple ) NoteRange( nAct == nFirst ); }
     143           0 :     void SetClosed( const sal_Bool bNew ){ bClosed = bNew; }
     144           0 :     sal_Bool IsClosed() const { return bClosed; }
     145           0 :     void SetConcat( const sal_Bool bNew ){ bConcat = bNew; }
     146           0 :     sal_Bool IsConcat() const { return bConcat; }
     147             :     sal_uInt8 GetAct() const { return nAct; }
     148             : };
     149             : 
     150           0 : SvxBoundArgs::SvxBoundArgs( TextRanger* pRanger, LongDqPtr pLong,
     151             :     const Range& rRange )
     152             :     : pLongArr( pLong ), pTextRanger( pRanger ),
     153           0 :     nTop( rRange.Min() ), nBottom( rRange.Max() ),
     154           0 :     bInner( pRanger->IsInner() ), bMultiple( bInner || !pRanger->IsSimple() ),
     155           0 :     bConcat( sal_False ), bRotate( pRanger->IsVertical() )
     156             : {
     157           0 :     if( bRotate )
     158             :     {
     159           0 :         nStart = pRanger->GetUpper();
     160           0 :         nEnd = pRanger->GetLower();
     161           0 :         nLowDiff = pRanger->GetLeft();
     162           0 :         nUpDiff = pRanger->GetRight();
     163             :     }
     164             :     else
     165             :     {
     166           0 :         nStart = pRanger->GetLeft();
     167           0 :         nEnd = pRanger->GetRight();
     168           0 :         nLowDiff = pRanger->GetUpper();
     169           0 :         nUpDiff = pRanger->GetLower();
     170             :     }
     171           0 :     nUpper = nTop - nUpDiff;
     172           0 :     nLower = nBottom + nLowDiff;
     173           0 :     pLongArr->clear();
     174           0 : }
     175             : 
     176           0 : long SvxBoundArgs::CalcMax( const Point& rPt1, const Point& rPt2,
     177             :     long nRange, long nFarRange )
     178             : {
     179           0 :     double nDa = Cut( nRange, rPt1, rPt2 ) - Cut( nFarRange, rPt1, rPt2 );
     180             :     double nB;
     181           0 :     if( nDa < 0 )
     182             :     {
     183           0 :         nDa = -nDa;
     184           0 :         nB = nEnd;
     185             :     }
     186             :     else
     187           0 :         nB = nStart;
     188           0 :     nB *= nB;
     189           0 :     nB += nDa * nDa;
     190           0 :     nB = nRange + nDa * ( nFarRange - nRange ) / sqrt( nB );
     191             : 
     192             :     sal_Bool bNote;
     193           0 :     if( nB < B(rPt2) )
     194           0 :         bNote = nB > B(rPt1);
     195             :     else
     196           0 :         bNote = nB < B(rPt1);
     197           0 :     if( bNote )
     198           0 :         return( long( nB ) );
     199           0 :     return 0;
     200             : }
     201             : 
     202           0 : void SvxBoundArgs::CheckCut( const Point& rLst, const Point& rNxt )
     203             : {
     204           0 :     if( nCut & 1 )
     205           0 :         NotePoint( Cut( nBottom, rLst, rNxt ) );
     206           0 :     if( nCut & 2 )
     207           0 :         NotePoint( Cut( nTop, rLst, rNxt ) );
     208           0 :     if( rLst.X() != rNxt.X() && rLst.Y() != rNxt.Y() )
     209             :     {
     210             :         long nYps;
     211           0 :         if( nLowDiff && ( ( nCut & 1 ) || nLast == 1 || nNext == 1 ) )
     212             :         {
     213           0 :             nYps = CalcMax( rLst, rNxt, nBottom, nLower );
     214           0 :             if( nYps )
     215           0 :                 _NoteFarPoint( Cut( nYps, rLst, rNxt ), nLower-nYps, nLowDiff );
     216             :         }
     217           0 :         if( nUpDiff && ( ( nCut & 2 ) || nLast == 2 || nNext == 2 ) )
     218             :         {
     219           0 :             nYps = CalcMax( rLst, rNxt, nTop, nUpper );
     220           0 :             if( nYps )
     221           0 :                 _NoteFarPoint( Cut( nYps, rLst, rNxt ), nYps-nUpper, nUpDiff );
     222             :         }
     223             :     }
     224           0 : }
     225             : 
     226           0 : void SvxBoundArgs::_NoteFarPoint( long nPa, long nPbDiff, long nDiff )
     227             : {
     228             :     long nTmpA;
     229           0 :     double nQuot = 2 * nDiff - nPbDiff;
     230           0 :     nQuot *= nPbDiff;
     231           0 :     nQuot = sqrt( nQuot );
     232           0 :     nQuot /= nDiff;
     233           0 :     nTmpA = nPa - long( nStart * nQuot );
     234           0 :     nPbDiff = nPa + long( nEnd * nQuot );
     235           0 :     NoteMargin( nTmpA, nPbDiff );
     236           0 : }
     237             : 
     238           0 : void SvxBoundArgs::NoteRange( bool bToggle )
     239             : {
     240             :     DBG_ASSERT( nMax >= nMin || bInner, "NoteRange: Min > Max?");
     241           0 :     if( nMax < nMin )
     242           0 :         return;
     243           0 :     if( !bClosed )
     244           0 :         bToggle = sal_False;
     245           0 :     sal_uInt16 nIdx = 0;
     246           0 :     sal_uInt16 nCount = pLongArr->size();
     247             :     DBG_ASSERT( nCount == 2 * aBoolArr.size(), "NoteRange: Incompatible Sizes" );
     248           0 :     while( nIdx < nCount && (*pLongArr)[ nIdx ] < nMin )
     249           0 :         ++nIdx;
     250           0 :     sal_Bool bOdd = (nIdx % 2) ? sal_True : sal_False;
     251             :     // No overlap with existing intervals?
     252           0 :     if( nIdx == nCount || ( !bOdd && nMax < (*pLongArr)[ nIdx ] ) )
     253             :     {   // Then a new one is inserted ...
     254           0 :         pLongArr->insert( pLongArr->begin() + nIdx, nMin );
     255           0 :         pLongArr->insert( pLongArr->begin() + nIdx + 1, nMax );
     256           0 :         aBoolArr.insert( aBoolArr.begin() + (nIdx/2), bToggle );
     257             :     }
     258             :     else
     259             :     {   // expand an existing interval ...
     260           0 :         sal_uInt16 nMaxIdx = nIdx;
     261             :         // If we end up on a left interval boundary, it must be reduced to nMin.
     262           0 :         if( bOdd )
     263           0 :             --nIdx;
     264             :         else
     265           0 :             (*pLongArr)[ nIdx ] = nMin;
     266           0 :         while( nMaxIdx < nCount && (*pLongArr)[ nMaxIdx ] < nMax )
     267           0 :             ++nMaxIdx;
     268             :         DBG_ASSERT( nMaxIdx > nIdx || nMin == nMax, "NoteRange: Funny Situation." );
     269           0 :         if( nMaxIdx )
     270           0 :             --nMaxIdx;
     271           0 :         if( nMaxIdx < nIdx )
     272           0 :             nMaxIdx = nIdx;
     273             :         // If we end up on a right interval boundary, it must be raised to nMax.
     274           0 :         if( nMaxIdx % 2 )
     275           0 :             (*pLongArr)[ nMaxIdx-- ] = nMax;
     276             :         // Possible merge of intervals.
     277           0 :         sal_uInt16 nDiff = nMaxIdx - nIdx;
     278           0 :         nMaxIdx = nIdx / 2; // From here on is nMaxIdx the Index in BoolArray.
     279           0 :         if( nDiff )
     280             :         {
     281           0 :             pLongArr->erase( pLongArr->begin() + nIdx + 1, pLongArr->begin() + nIdx + 1 + nDiff );
     282           0 :             nDiff /= 2;
     283           0 :             sal_uInt16 nStop = nMaxIdx + nDiff;
     284           0 :             for( sal_uInt16 i = nMaxIdx; i < nStop; ++i )
     285           0 :                 bToggle ^= aBoolArr[ i ];
     286           0 :             aBoolArr.erase( aBoolArr.begin() + nMaxIdx, aBoolArr.begin() + (nMaxIdx + nDiff) );
     287             :         }
     288             :         DBG_ASSERT( nMaxIdx < aBoolArr.size(), "NoteRange: Too much deleted" );
     289           0 :         aBoolArr[ nMaxIdx ] = aBoolArr[ nMaxIdx ] ^ bToggle;
     290             :     }
     291             : }
     292             : 
     293           0 : void SvxBoundArgs::Calc( const PolyPolygon& rPoly )
     294             : {
     295             :     sal_uInt16 nCount;
     296           0 :     nAct = 0;
     297           0 :     for( sal_uInt16 i = 0; i < rPoly.Count(); ++i )
     298             :     {
     299           0 :         const Polygon& rPol = rPoly[ i ];
     300           0 :         nCount = rPol.GetSize();
     301           0 :         if( nCount )
     302             :         {
     303           0 :             const Point& rNull = rPol[ 0 ];
     304           0 :             SetClosed( IsConcat() || ( rNull == rPol[ nCount - 1 ] ) );
     305           0 :             nLast = Area( rNull );
     306           0 :             if( nLast & 12 )
     307             :             {
     308           0 :                 nFirst = 3;
     309           0 :                 if( bMultiple )
     310           0 :                     nAct = 0;
     311             :             }
     312             :             else
     313             :             {
     314             :                 // The first point of the polygon is within the line.
     315           0 :                 if( nLast )
     316             :                 {
     317           0 :                     if( bMultiple || !nAct )
     318             :                     {
     319           0 :                         nMin = USHRT_MAX;
     320           0 :                         nMax = 0;
     321             :                     }
     322           0 :                     if( nLast & 1 )
     323           0 :                         NoteFarPoint( A(rNull), nLower - B(rNull), nLowDiff );
     324             :                     else
     325           0 :                         NoteFarPoint( A(rNull), B(rNull) - nUpper, nUpDiff );
     326             :                 }
     327             :                 else
     328             :                 {
     329           0 :                     if( bMultiple || !nAct )
     330             :                     {
     331           0 :                         nMin = A(rNull);
     332           0 :                         nMax = nMin + nEnd;
     333           0 :                         nMin -= nStart;
     334             :                     }
     335             :                     else
     336           0 :                         NotePoint( A(rNull) );
     337             :                 }
     338           0 :                 nFirst = 0; // leaving the line in which direction?
     339           0 :                 nAct = 3;   // we are within the line at the moment.
     340             :             }
     341           0 :             if( nCount > 1 )
     342             :             {
     343           0 :                 sal_uInt16 nIdx = 1;
     344           0 :                 while( sal_True )
     345             :                 {
     346           0 :                     const Point& rLast = rPol[ nIdx - 1 ];
     347           0 :                     if( nIdx == nCount )
     348           0 :                         nIdx = 0;
     349           0 :                     const Point& rNext = rPol[ nIdx ];
     350           0 :                     nNext = Area( rNext );
     351           0 :                     nCut = nNext ^ nLast;
     352           0 :                     sal_uInt16 nOldAct = nAct;
     353           0 :                     if( nAct )
     354           0 :                         CheckCut( rLast, rNext );
     355           0 :                     if( nCut & 4 )
     356             :                     {
     357           0 :                         NoteUpLow( Cut( nLower, rLast, rNext ), 2 );
     358           0 :                         if( nAct && nAct != nOldAct )
     359             :                         {
     360           0 :                             nOldAct = nAct;
     361           0 :                             CheckCut( rLast, rNext );
     362             :                         }
     363             :                     }
     364           0 :                     if( nCut & 8 )
     365             :                     {
     366           0 :                         NoteUpLow( Cut( nUpper, rLast, rNext ), 1 );
     367           0 :                         if( nAct && nAct != nOldAct )
     368           0 :                             CheckCut( rLast, rNext );
     369             :                     }
     370           0 :                     if( !nIdx )
     371             :                     {
     372           0 :                         if( !( nNext & 12 ) )
     373           0 :                             NoteLast();
     374           0 :                         break;
     375             :                     }
     376           0 :                     if( !( nNext & 12 ) )
     377             :                     {
     378           0 :                         if( !nNext )
     379           0 :                             NotePoint( A(rNext) );
     380           0 :                         else if( nNext & 1 )
     381           0 :                             NoteFarPoint( A(rNext), nLower-B(rNext), nLowDiff );
     382             :                         else
     383           0 :                             NoteFarPoint( A(rNext), B(rNext)-nUpper, nUpDiff );
     384             :                     }
     385           0 :                     nLast = nNext;
     386           0 :                     if( ++nIdx == nCount && !IsClosed() )
     387             :                     {
     388           0 :                         if( !( nNext & 12 ) )
     389           0 :                             NoteLast();
     390           0 :                         break;
     391             :                     }
     392             :                 }
     393             :             }
     394           0 :             if( bMultiple && IsConcat() )
     395             :             {
     396           0 :                 Add();
     397           0 :                 nAct = 0;
     398             :             }
     399             :         }
     400             :     }
     401           0 :     if( !bMultiple )
     402             :     {
     403             :         DBG_ASSERT( pLongArr->empty(), "I said: Simple!" );
     404           0 :         if( nAct )
     405             :         {
     406           0 :             if( bInner )
     407             :             {
     408           0 :                 long nTmpMin = nMin + 2 * nStart;
     409           0 :                 long nTmpMax = nMax - 2 * nEnd;
     410           0 :                 if( nTmpMin <= nTmpMax )
     411             :                 {
     412           0 :                     pLongArr->push_front(nTmpMax);
     413           0 :                     pLongArr->push_front(nTmpMin);
     414             :                 }
     415             :             }
     416             :             else
     417             :             {
     418           0 :                 pLongArr->push_front(nMax);
     419           0 :                 pLongArr->push_front(nMin);
     420             :             }
     421             :         }
     422             :     }
     423           0 :     else if( !IsConcat() )
     424           0 :         Add();
     425           0 : }
     426             : 
     427           0 : void SvxBoundArgs::Add()
     428             : {
     429           0 :     size_t nCount = aBoolArr.size();
     430           0 :     if( nCount && ( !bInner || !pTextRanger->IsSimple() ) )
     431             :     {
     432           0 :         sal_Bool bDelete = aBoolArr.front();
     433           0 :         if( bInner )
     434           0 :             bDelete = !bDelete;
     435           0 :         sal_uInt16 nLongIdx = 1;
     436           0 :         for( size_t nBoolIdx = 1; nBoolIdx < nCount; ++nBoolIdx )
     437             :         {
     438           0 :             if( bDelete )
     439             :             {
     440           0 :                 sal_uInt16 next = 2;
     441           0 :                 while( nBoolIdx < nCount && !aBoolArr[ nBoolIdx++ ] &&
     442           0 :                        (!bInner || nBoolIdx < nCount ) )
     443           0 :                     next += 2;
     444           0 :                 pLongArr->erase( pLongArr->begin() + nLongIdx, pLongArr->begin() + nLongIdx + next );
     445           0 :                 next /= 2;
     446           0 :                 nBoolIdx = nBoolIdx - next;
     447           0 :                 nCount = nCount - next;
     448           0 :                 aBoolArr.erase( aBoolArr.begin() + nBoolIdx, aBoolArr.begin() + (nBoolIdx + next) );
     449           0 :                 if( nBoolIdx )
     450           0 :                     aBoolArr[ nBoolIdx - 1 ] = sal_False;
     451             : #if OSL_DEBUG_LEVEL > 1
     452             :                 else
     453             :                     ++next;
     454             : #endif
     455             :             }
     456           0 :             bDelete = nBoolIdx < nCount && aBoolArr[ nBoolIdx ];
     457           0 :             nLongIdx += 2;
     458             :             DBG_ASSERT( nLongIdx == 2*nBoolIdx+1, "BoundArgs: Array-Idx Confusion" );
     459             :             DBG_ASSERT( aBoolArr.size()*2 == pLongArr->size(),
     460             :                         "BoundArgs: Array-Count: Confusion" );
     461             :         }
     462             :     }
     463           0 :     if( 0 != ( nCount = pLongArr->size() ) )
     464             :     {
     465           0 :         if( bInner )
     466             :         {
     467           0 :             pLongArr->pop_front();
     468           0 :             pLongArr->pop_back();
     469             : 
     470             :             // Here the line is held inside a large rectangle for "simple"
     471             :             // contour wrap. Currently (April 1999) the EditEngine evaluates
     472             :             // only the first rectangle. If it one day is able to output a line
     473             :             // in several parts, it may be advisable to delete the following lines.
     474           0 :             if( pTextRanger->IsSimple() && pLongArr->size() > 2 )
     475           0 :                 pLongArr->erase( pLongArr->begin() + 1, pLongArr->end() - 1 );
     476             : 
     477             :         }
     478             :     }
     479           0 : }
     480             : 
     481           0 : void SvxBoundArgs::Concat( const PolyPolygon* pPoly )
     482             : {
     483           0 :     SetConcat( sal_True );
     484             :     DBG_ASSERT( pPoly, "Nothing to do?" );
     485           0 :     LongDqPtr pOld = pLongArr;
     486           0 :     pLongArr = new std::deque<long>();
     487           0 :     aBoolArr.clear();
     488           0 :     bInner = sal_False;
     489           0 :     Calc( *pPoly ); // Note that this updates pLongArr, which is why we swapped it out earlier.
     490           0 :     sal_uInt16 nCount = pLongArr->size();
     491           0 :     sal_uInt16 nIdx = 0;
     492           0 :     sal_uInt16 i = 0;
     493           0 :     sal_Bool bSubtract = pTextRanger->IsInner();
     494           0 :     while( i < nCount )
     495             :     {
     496           0 :         sal_uLong nOldCount = pOld->size();
     497           0 :         if( nIdx == nOldCount )
     498             :         {   // Reached the end of the old Array...
     499           0 :             if( !bSubtract )
     500           0 :                 pOld->insert( pOld->begin() + nIdx, pLongArr->begin() + i, pLongArr->end() );
     501           0 :             break;
     502             :         }
     503           0 :         long nLeft = (*pLongArr)[ i++ ];
     504           0 :         long nRight = (*pLongArr)[ i++ ];
     505           0 :         sal_uInt16 nLeftPos = nIdx + 1;
     506           0 :         while( nLeftPos < nOldCount && nLeft > (*pOld)[ nLeftPos ] )
     507           0 :             nLeftPos += 2;
     508           0 :         if( nLeftPos >= nOldCount )
     509             :         {   // The current interval belongs to the end of the old array ...
     510           0 :             if( !bSubtract )
     511           0 :                 pOld->insert( pOld->begin() + nOldCount, pLongArr->begin() + i - 2, pLongArr->end() );
     512           0 :             break;
     513             :         }
     514           0 :         sal_uInt16 nRightPos = nLeftPos - 1;
     515           0 :         while( nRightPos < nOldCount && nRight >= (*pOld)[ nRightPos ] )
     516           0 :             nRightPos += 2;
     517           0 :         if( nRightPos < nLeftPos )
     518             :         {   // The current interval belongs between two old intervals
     519           0 :             if( !bSubtract )
     520           0 :                 pOld->insert( pOld->begin() + nRightPos, pLongArr->begin() + i - 2, pLongArr->begin() + i );
     521           0 :             nIdx = nRightPos + 2;
     522             :         }
     523           0 :         else if( bSubtract ) // Subtract, if necessary separate
     524             :         {
     525             :             long nOld;
     526           0 :             if( nLeft > ( nOld = (*pOld)[ nLeftPos - 1 ] ) )
     527             :             {   // Now we split the left part...
     528           0 :                 if( nLeft - 1 > nOld )
     529             :                 {
     530           0 :                     pOld->insert( pOld->begin() + nLeftPos - 1, nOld );
     531           0 :                     pOld->insert( pOld->begin() + nLeftPos, nLeft - 1 );
     532           0 :                     nLeftPos += 2;
     533           0 :                     nRightPos += 2;
     534             :                 }
     535             :             }
     536           0 :             if( nRightPos - nLeftPos > 1 )
     537           0 :                 pOld->erase( pOld->begin() + nLeftPos, pOld->begin() + nRightPos - 1 );
     538           0 :             if( ++nRight >= ( nOld = (*pOld)[ nLeftPos ] ) )
     539           0 :                 pOld->erase( pOld->begin() + nLeftPos - 1, pOld->begin() + nLeftPos + 1 );
     540             :             else
     541           0 :                 (*pOld)[ nLeftPos - 1 ] = nRight;
     542             :         }
     543             :         else // Merge
     544             :         {
     545           0 :             if( nLeft < (*pOld)[ nLeftPos - 1 ] )
     546           0 :                 (*pOld)[ nLeftPos - 1 ] = nLeft;
     547           0 :             if( nRight > (*pOld)[ nRightPos - 1 ] )
     548           0 :                 (*pOld)[ nRightPos - 1 ] = nRight;
     549           0 :             if( nRightPos - nLeftPos > 1 )
     550           0 :                 pOld->erase( pOld->begin() + nLeftPos, pOld->begin() + nRightPos - 1 );
     551             : 
     552             :         }
     553           0 :         nIdx = nLeftPos - 1;
     554             :     }
     555           0 :     delete pLongArr;
     556           0 : }
     557             : 
     558             : /*************************************************************************
     559             :  * SvxBoundArgs::Area returns the area in which the point is located.
     560             :  * 0 = within the line
     561             :  * 1 = below, but within the upper edge
     562             :  * 2 = above, but within the lower edge
     563             :  * 5 = below the upper edge
     564             :  *10 = above the lower edge
     565             :  *************************************************************************/
     566             : 
     567           0 : sal_uInt16 SvxBoundArgs::Area( const Point& rPt )
     568             : {
     569           0 :     long nB = B( rPt );
     570           0 :     if( nB >= nBottom )
     571             :     {
     572           0 :         if( nB >= nLower )
     573           0 :             return 5;
     574           0 :         return 1;
     575             :     }
     576           0 :     if( nB <= nTop )
     577             :     {
     578           0 :         if( nB <= nUpper )
     579           0 :             return 10;
     580           0 :         return 2;
     581             :     }
     582           0 :     return 0;
     583             : }
     584             : 
     585             : /*************************************************************************
     586             :  * lcl_Cut calculates the X-Coordinate of the distance (Pt1-Pt2) at the
     587             :  * Y-Coordinate nY.
     588             :  * It is assumed that the one of the points are located above and the other
     589             :  * one below the Y-Coordinate.
     590             :  *************************************************************************/
     591             : 
     592           0 : long SvxBoundArgs::Cut( long nB, const Point& rPt1, const Point& rPt2 )
     593             : {
     594           0 :     if( pTextRanger->IsVertical() )
     595             :     {
     596           0 :         double nQuot = nB - rPt1.X();
     597           0 :         nQuot /= ( rPt2.X() - rPt1.X() );
     598           0 :         nQuot *= ( rPt2.Y() - rPt1.Y() );
     599           0 :         return long( rPt1.Y() + nQuot );
     600             :     }
     601           0 :     double nQuot = nB - rPt1.Y();
     602           0 :     nQuot /= ( rPt2.Y() - rPt1.Y() );
     603           0 :     nQuot *= ( rPt2.X() - rPt1.X() );
     604           0 :     return long( rPt1.X() + nQuot );
     605             : }
     606             : 
     607           0 : void SvxBoundArgs::NoteUpLow( long nA, const sal_uInt8 nArea )
     608             : {
     609           0 :     if( nAct )
     610             :     {
     611           0 :         NoteMargin( nA, nA );
     612           0 :         if( bMultiple )
     613             :         {
     614           0 :             NoteRange( nArea != nAct );
     615           0 :             nAct = 0;
     616             :         }
     617           0 :         if( !nFirst )
     618           0 :             nFirst = nArea;
     619             :     }
     620             :     else
     621             :     {
     622           0 :         nAct = nArea;
     623           0 :         nMin = nA;
     624           0 :         nMax = nA;
     625             :     }
     626           0 : }
     627             : 
     628           0 : LongDqPtr TextRanger::GetTextRanges( const Range& rRange )
     629             : {
     630             :     DBG_ASSERT( rRange.Min() || rRange.Max(), "Zero-Range not allowed, Bye Bye" );
     631             :     //Can we find the result we need in the cache?
     632           0 :     for (std::deque<RangeCache>::iterator it = mRangeCache.begin(); it != mRangeCache.end(); ++it)
     633             :     {
     634           0 :         if (it->range == rRange)
     635           0 :             return &(it->results);
     636             :     }
     637             :     //Calculate a new result
     638           0 :     RangeCache rngCache(rRange);
     639           0 :     SvxBoundArgs aArg( this, &(rngCache.results), rRange );
     640           0 :     aArg.Calc( *mpPolyPolygon );
     641           0 :     if( mpLinePolyPolygon )
     642           0 :         aArg.Concat( mpLinePolyPolygon );
     643             :     //Add new result to the cache
     644           0 :     mRangeCache.push_back(rngCache);
     645           0 :     if (mRangeCache.size() > nCacheSize)
     646           0 :         mRangeCache.pop_front();
     647           0 :     return &(mRangeCache.back().results);
     648             : }
     649             : 
     650           0 : const Rectangle& TextRanger::_GetBoundRect()
     651             : {
     652             :     DBG_ASSERT( 0 == pBound, "Don't call twice." );
     653           0 :     pBound = new Rectangle( mpPolyPolygon->GetBoundRect() );
     654           0 :     return *pBound;
     655             : }
     656             : 
     657             : 
     658             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10