LCOV - code coverage report
Current view: top level - sw/source/core/text - itrcrsr.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 471 969 48.6 %
Date: 2014-11-03 Functions: 10 13 76.9 %
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 "hintids.hxx"
      21             : #include "ndtxt.hxx"
      22             : #include "frmfmt.hxx"
      23             : #include "paratr.hxx"
      24             : #include "flyfrm.hxx"
      25             : #include "pam.hxx"
      26             : #include "swselectionlist.hxx"
      27             : #include <sortedobjs.hxx>
      28             : #include <editeng/protitem.hxx>
      29             : #include <editeng/adjustitem.hxx>
      30             : #include <editeng/lspcitem.hxx>
      31             : #include <editeng/lrspitem.hxx>
      32             : #include <editeng/borderline.hxx>
      33             : #include <frmatr.hxx>
      34             : #include <pagedesc.hxx>
      35             : #include <tgrditem.hxx>
      36             : #include <IDocumentSettingAccess.hxx>
      37             : #include <pagefrm.hxx>
      38             : 
      39             : #include "itrtxt.hxx"
      40             : #include "txtfrm.hxx"
      41             : #include "flyfrms.hxx"
      42             : #include "porglue.hxx"
      43             : #include "porfld.hxx"
      44             : #include "porfly.hxx"
      45             : #include "pordrop.hxx"
      46             : #include "crstate.hxx"
      47             : #include <pormulti.hxx>
      48             : #include <numrule.hxx>
      49             : 
      50             : // Not reentrant !!!
      51             : // is set in GetCharRect and is interpreted in UnitUp/Down.
      52             : bool SwTxtCursor::bRightMargin = false;
      53             : 
      54             : // After calculating the position of a character during GetCharRect
      55             : // this function allows to find the coordinates of a position (defined
      56             : // in pCMS->pSpecialPos) inside a special portion (e.g., a field)
      57           0 : static void lcl_GetCharRectInsideField( SwTxtSizeInfo& rInf, SwRect& rOrig,
      58             :                                  const SwCrsrMoveState& rCMS,
      59             :                                  const SwLinePortion& rPor )
      60             : {
      61             :     OSL_ENSURE( rCMS.pSpecialPos, "Information about special pos missing" );
      62             : 
      63           0 :     if ( rPor.InFldGrp() && !((SwFldPortion&)rPor).GetExp().isEmpty() )
      64             :     {
      65           0 :         const sal_Int32 nCharOfst = rCMS.pSpecialPos->nCharOfst;
      66           0 :         sal_Int32 nFldIdx = 0;
      67           0 :         sal_Int32 nFldLen = 0;
      68             : 
      69           0 :         OUString sString;
      70           0 :         const OUString* pString = 0;
      71           0 :         const SwLinePortion* pPor = &rPor;
      72             :         do
      73             :         {
      74           0 :             if ( pPor->InFldGrp() )
      75             :             {
      76           0 :                 sString = ((SwFldPortion*)pPor)->GetExp();
      77           0 :                 pString = &sString;
      78           0 :                 nFldLen = pString->getLength();
      79             :             }
      80             :             else
      81             :             {
      82           0 :                 pString = 0;
      83           0 :                 nFldLen = 0;
      84             :             }
      85             : 
      86           0 :             if ( ! pPor->GetPortion() || nFldIdx + nFldLen > nCharOfst )
      87           0 :                 break;
      88             : 
      89           0 :             nFldIdx = nFldIdx + nFldLen;
      90           0 :             rOrig.Pos().X() += pPor->Width();
      91           0 :             pPor = pPor->GetPortion();
      92             : 
      93             :         } while ( true );
      94             : 
      95             :         OSL_ENSURE( nCharOfst >= nFldIdx, "Request of position inside field failed" );
      96           0 :         sal_Int32 nLen = nCharOfst - nFldIdx + 1;
      97             : 
      98           0 :         if ( pString )
      99             :         {
     100             :             // get script for field portion
     101           0 :             rInf.GetFont()->SetActual( SwScriptInfo::WhichFont( 0, pString, 0 ) );
     102             : 
     103           0 :             sal_Int32 nOldLen = pPor->GetLen();
     104           0 :             ((SwLinePortion*)pPor)->SetLen( nLen - 1 );
     105           0 :             const SwTwips nX1 = pPor->GetLen() ?
     106           0 :                                 pPor->GetTxtSize( rInf ).Width() :
     107           0 :                                 0;
     108             : 
     109           0 :             SwTwips nX2 = 0;
     110           0 :             if ( rCMS.bRealWidth )
     111             :             {
     112           0 :                 ((SwLinePortion*)pPor)->SetLen( nLen );
     113           0 :                 nX2 = pPor->GetTxtSize( rInf ).Width();
     114             :             }
     115             : 
     116           0 :             ((SwLinePortion*)pPor)->SetLen( nOldLen );
     117             : 
     118           0 :             rOrig.Pos().X() += nX1;
     119             :             rOrig.Width( ( nX2 > nX1 ) ?
     120             :                          ( nX2 - nX1 ) :
     121           0 :                            1 );
     122           0 :         }
     123             :     }
     124             :     else
     125             :     {
     126             :         // special cases: no common fields, e.g., graphic number portion,
     127             :         // FlyInCntPortions, Notes
     128           0 :         rOrig.Width( rCMS.bRealWidth && rPor.Width() ? rPor.Width() : 1 );
     129             :     }
     130           0 : }
     131             : 
     132             : // #i111284#
     133             : namespace {
     134      317328 :     bool AreListLevelIndentsApplicableAndLabelAlignmentActive( const SwTxtNode& rTxtNode )
     135             :     {
     136      317328 :         bool bRet( false );
     137             : 
     138      317328 :         if ( rTxtNode.GetNumRule() && rTxtNode.AreListLevelIndentsApplicable() )
     139             :         {
     140       11568 :             int nListLevel = rTxtNode.GetActualListLevel();
     141             : 
     142       11568 :             if (nListLevel < 0)
     143           0 :                 nListLevel = 0;
     144             : 
     145       11568 :             if (nListLevel >= MAXLEVEL)
     146           0 :                 nListLevel = MAXLEVEL - 1;
     147             : 
     148             :             const SwNumFmt& rNumFmt =
     149       11568 :                     rTxtNode.GetNumRule()->Get( static_cast<sal_uInt16>(nListLevel) );
     150       11568 :             if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
     151             :             {
     152       10498 :                 bRet = true;
     153             :             }
     154             :         }
     155             : 
     156      317328 :         return bRet;
     157             :     }
     158             : } // end of anonymous namespace
     159             : 
     160      317328 : void SwTxtMargin::CtorInitTxtMargin( SwTxtFrm *pNewFrm, SwTxtSizeInfo *pNewInf )
     161             : {
     162      317328 :     CtorInitTxtIter( pNewFrm, pNewInf );
     163             : 
     164      317328 :     pInf = pNewInf;
     165      317328 :     GetInfo().SetFont( GetFnt() );
     166      317328 :     const SwTxtNode *pNode = pFrm->GetTxtNode();
     167             : 
     168      317328 :     const SvxLRSpaceItem &rSpace = pFrm->GetTxtNode()->GetSwAttrSet().GetLRSpace();
     169             :     // #i95907#
     170             :     // #i111284#
     171             :     const bool bListLevelIndentsApplicableAndLabelAlignmentActive(
     172      317328 :         AreListLevelIndentsApplicableAndLabelAlignmentActive( *(pFrm->GetTxtNode()) ) );
     173             : 
     174             :     // Carefully adjust the text formatting ranges.
     175             : 
     176             :     // This whole area desperately needs some rework. There are
     177             :     // quite a couple of values that need to be considered:
     178             :     // 1. paragraph indent
     179             :     // 2. paragraph first line indent
     180             :     // 3. numbering indent
     181             :     // 4. numbering spacing to text
     182             :     // 5. paragraph border
     183             :     // Note: These values have already been used during calculation
     184             :     // of the printing area of the paragraph.
     185      317328 :     const int nLMWithNum = pNode->GetLeftMarginWithNum( true );
     186      317328 :     if ( pFrm->IsRightToLeft() )
     187             :     {
     188             :         // this calculation is identical this the calculation for L2R layout - see below
     189         776 :         nLeft = pFrm->Frm().Left() +
     190         776 :                 pFrm->Prt().Left() +
     191         388 :                 nLMWithNum -
     192        1164 :                 pNode->GetLeftMarginWithNum() -
     193             :                 // #i95907#
     194             :                 // #i111284#
     195             :                 // rSpace.GetLeft() + rSpace.GetTxtLeft();
     196             :                 ( bListLevelIndentsApplicableAndLabelAlignmentActive
     197             :                   ? 0
     198         776 :                   : ( rSpace.GetLeft() - rSpace.GetTxtLeft() ) );
     199             :     }
     200             :     else
     201             :     {
     202             :         // #i95907#
     203             :         // #i111284#
     204      623382 :         if ( bListLevelIndentsApplicableAndLabelAlignmentActive ||
     205      306442 :              !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
     206             :         {
     207             :             // this calculation is identical this the calculation for R2L layout - see above
     208      633546 :             nLeft = pFrm->Frm().Left() +
     209      633546 :                     pFrm->Prt().Left() +
     210      316773 :                     nLMWithNum -
     211      939821 :                     pNode->GetLeftMarginWithNum() -
     212             :                     // #i95907#
     213             :                     // #i111284#
     214             :                     ( bListLevelIndentsApplicableAndLabelAlignmentActive
     215             :                       ? 0
     216      623048 :                       : ( rSpace.GetLeft() - rSpace.GetTxtLeft() ) );
     217             :         }
     218             :         else
     219             :         {
     220         334 :             nLeft = pFrm->Frm().Left() +
     221         167 :                     std::max( long( rSpace.GetTxtLeft() + nLMWithNum ),
     222         501 :                          pFrm->Prt().Left() );
     223             :         }
     224             :     }
     225             : 
     226      317328 :     nRight = pFrm->Frm().Left() + pFrm->Prt().Left() + pFrm->Prt().Width();
     227             : 
     228      318092 :     if( nLeft >= nRight &&
     229             :          // #i53066# Omit adjustment of nLeft for numbered
     230             :          // paras inside cells inside new documents:
     231         764 :         ( pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) ||
     232         632 :           !pFrm->IsInTab() ||
     233             :           !nLMWithNum ) )
     234             :     {
     235         382 :         nLeft = pFrm->Prt().Left() + pFrm->Frm().Left();
     236         382 :         if( nLeft >= nRight )   // e.g. with large paragraph indentations in slim table columns
     237         238 :             nRight = nLeft + 1; // einen goennen wir uns immer
     238             :     }
     239             : 
     240      317328 :     if( pFrm->IsFollow() && pFrm->GetOfst() )
     241       27071 :         nFirst = nLeft;
     242             :     else
     243             :     {
     244      290257 :         short nFLOfst = 0;
     245      290257 :         long nFirstLineOfs = 0;
     246      566254 :         if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) &&
     247      275997 :             rSpace.IsAutoFirst() )
     248             :         {
     249           0 :             nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height();
     250           0 :             const SvxLineSpacingItem *pSpace = aLineInf.GetLineSpacing();
     251           0 :             if( pSpace )
     252             :             {
     253           0 :                 switch( pSpace->GetLineSpaceRule() )
     254             :                 {
     255             :                     case SVX_LINE_SPACE_AUTO:
     256           0 :                     break;
     257             :                     case SVX_LINE_SPACE_MIN:
     258             :                     {
     259           0 :                         if( nFirstLineOfs < pSpace->GetLineHeight() )
     260           0 :                             nFirstLineOfs = pSpace->GetLineHeight();
     261           0 :                         break;
     262             :                     }
     263             :                     case SVX_LINE_SPACE_FIX:
     264           0 :                         nFirstLineOfs = pSpace->GetLineHeight();
     265           0 :                     break;
     266             :                     default: OSL_FAIL( ": unknown LineSpaceRule" );
     267             :                 }
     268           0 :                 switch( pSpace->GetInterLineSpaceRule() )
     269             :                 {
     270             :                     case SVX_INTER_LINE_SPACE_OFF:
     271           0 :                     break;
     272             :                     case SVX_INTER_LINE_SPACE_PROP:
     273             :                     {
     274           0 :                         long nTmp = pSpace->GetPropLineSpace();
     275             :                         // 50% is the minimumm, at 0% we switch to
     276             :                         // the default value 100% ...
     277           0 :                         if( nTmp < 50 )
     278           0 :                             nTmp = nTmp ? 50 : 100;
     279             : 
     280           0 :                         nTmp *= nFirstLineOfs;
     281           0 :                         nTmp /= 100;
     282           0 :                         if( !nTmp )
     283           0 :                             ++nTmp;
     284           0 :                         nFirstLineOfs = nTmp;
     285           0 :                         break;
     286             :                     }
     287             :                     case SVX_INTER_LINE_SPACE_FIX:
     288             :                     {
     289           0 :                         nFirstLineOfs += pSpace->GetInterLineSpace();
     290           0 :                         break;
     291             :                     }
     292             :                     default: OSL_FAIL( ": unknown InterLineSpaceRule" );
     293             :                 }
     294             :             }
     295             :         }
     296             :         else
     297      290257 :             nFirstLineOfs = nFLOfst;
     298             : 
     299             :         // #i95907#
     300             :         // #i111284#
     301      870383 :         if ( pFrm->IsRightToLeft() ||
     302      569646 :              bListLevelIndentsApplicableAndLabelAlignmentActive ||
     303      279389 :              !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
     304             :         {
     305      290090 :             nFirst = nLeft + nFirstLineOfs;
     306             :         }
     307             :         else
     308             :         {
     309         334 :               nFirst = pFrm->Frm().Left() +
     310         167 :                      std::max( rSpace.GetTxtLeft() + nLMWithNum+ nFirstLineOfs,
     311         501 :                           pFrm->Prt().Left() );
     312             :         }
     313             : 
     314             :         // Note: <SwTxtFrm::GetAdditionalFirstLineOffset()> returns a negative
     315             :         //       value for the new list label position and space mode LABEL_ALIGNMENT
     316             :         //       and label alignment CENTER and RIGHT in L2R layout respectively
     317             :         //       label alignment LEFT and CENTER in R2L layout
     318      290257 :         nFirst += pFrm->GetAdditionalFirstLineOffset();
     319             : 
     320      290257 :         if( nFirst >= nRight )
     321         110 :             nFirst = nRight - 1;
     322             :     }
     323      317328 :     const SvxAdjustItem& rAdjust = pFrm->GetTxtNode()->GetSwAttrSet().GetAdjust();
     324      317328 :     nAdjust = static_cast<sal_uInt16>(rAdjust.GetAdjust());
     325             : 
     326             :     // left is left and right is right
     327      317328 :     if ( pFrm->IsRightToLeft() )
     328             :     {
     329         388 :         if ( SVX_ADJUST_LEFT == nAdjust )
     330         164 :             nAdjust = SVX_ADJUST_RIGHT;
     331         224 :         else if ( SVX_ADJUST_RIGHT == nAdjust )
     332         110 :             nAdjust = SVX_ADJUST_LEFT;
     333             :     }
     334             : 
     335      317328 :     bOneBlock = rAdjust.GetOneWord() == SVX_ADJUST_BLOCK;
     336      317328 :     bLastBlock = rAdjust.GetLastBlock() == SVX_ADJUST_BLOCK;
     337      317328 :     bLastCenter = rAdjust.GetLastBlock() == SVX_ADJUST_CENTER;
     338             : 
     339             :     // #i91133#
     340      317328 :     mnTabLeft = pNode->GetLeftMarginForTabCalculation();
     341             : 
     342             : #if OSL_DEBUG_LEVEL > 1
     343             :     static bool bOne = false;
     344             :     static bool bLast = false;
     345             :     static bool bCenter = false;
     346             :     bOneBlock |= bOne;
     347             :     bLastBlock |= bLast;
     348             :     bLastCenter |= bCenter;
     349             : #endif
     350      317328 :     DropInit();
     351      317328 : }
     352             : 
     353      317340 : void SwTxtMargin::DropInit()
     354             : {
     355      317340 :     nDropLeft = nDropLines = nDropHeight = nDropDescent = 0;
     356      317340 :     const SwParaPortion *pPara = GetInfo().GetParaPortion();
     357      317340 :     if( pPara )
     358             :     {
     359      317340 :         const SwDropPortion *pPorDrop = pPara->FindDropPortion();
     360      317340 :         if ( pPorDrop )
     361             :         {
     362         156 :             nDropLeft = pPorDrop->GetDropLeft();
     363         156 :             nDropLines = pPorDrop->GetLines();
     364         156 :             nDropHeight = pPorDrop->GetDropHeight();
     365         156 :             nDropDescent = pPorDrop->GetDropDescent();
     366             :         }
     367             :     }
     368      317340 : }
     369             : 
     370             : // The function is interpreting / observing / evaluating / keeping / respecting the first line indention and the specified width.
     371      263993 : SwTwips SwTxtMargin::GetLineStart() const
     372             : {
     373      263993 :     SwTwips nRet = GetLeftMargin();
     374      306471 :     if( GetAdjust() != SVX_ADJUST_LEFT &&
     375       42478 :         !pCurr->GetFirstPortion()->IsMarginPortion() )
     376             :     {
     377             :         // If the first portion is a Margin, then the
     378             :         // adjustment is expressed by the portions.
     379       34628 :         if( GetAdjust() == SVX_ADJUST_RIGHT )
     380        2196 :             nRet = Right() - CurrWidth();
     381       32432 :         else if( GetAdjust() == SVX_ADJUST_CENTER )
     382       10966 :             nRet += (GetLineWidth() - CurrWidth()) / 2;
     383             :     }
     384      263993 :     return nRet;
     385             : }
     386             : 
     387      237348 : void SwTxtCursor::CtorInitTxtCursor( SwTxtFrm *pNewFrm, SwTxtSizeInfo *pNewInf )
     388             : {
     389      237348 :     CtorInitTxtMargin( pNewFrm, pNewInf );
     390             :     // 6096: Attention, the iterators are derived!
     391             :     // GetInfo().SetOut( GetInfo().GetWin() );
     392      237348 : }
     393             : 
     394             : // 1170: Ancient bug: Shift-End forgets the last character ...
     395           0 : bool SwTxtCursor::GetEndCharRect( SwRect* pOrig, const sal_Int32 nOfst,
     396             :                                   SwCrsrMoveState* pCMS, const long nMax )
     397             : {
     398             :     // 1170: Ambiguity of document positions
     399           0 :     bRightMargin = true;
     400           0 :     CharCrsrToLine(nOfst);
     401             : 
     402             :     // Somehow twisted: nOfst names the position behind the last
     403             :     // character of the last line == This is the position in front of the first character
     404             :     // of the line, in which we are situated:
     405           0 :     if( nOfst != GetStart() || !pCurr->GetLen() )
     406             :     {
     407             :         // 8810: Master line RightMargin, after that LeftMargin
     408           0 :         const bool bRet = GetCharRect( pOrig, nOfst, pCMS, nMax );
     409           0 :         bRightMargin = nOfst >= GetEnd() && nOfst < GetInfo().GetTxt().getLength();
     410           0 :         return bRet;
     411             :     }
     412             : 
     413           0 :     if( !GetPrev() || !GetPrev()->GetLen() || !PrevLine() )
     414           0 :         return GetCharRect( pOrig, nOfst, pCMS, nMax );
     415             : 
     416             :     // If necessary, as catch up, do the adjustment
     417           0 :     GetAdjusted();
     418             : 
     419           0 :     long nX = 0;
     420           0 :     long nLast = 0;
     421           0 :     SwLinePortion *pPor = pCurr->GetFirstPortion();
     422             : 
     423             :     sal_uInt16 nTmpHeight, nTmpAscent;
     424           0 :     CalcAscentAndHeight( nTmpAscent, nTmpHeight );
     425           0 :     sal_uInt16 nPorHeight = nTmpHeight;
     426           0 :     sal_uInt16 nPorAscent = nTmpAscent;
     427             : 
     428             :     // Search for the last Text/EndPortion of the line
     429           0 :     while( pPor )
     430             :     {
     431           0 :         nX = nX + pPor->Width();
     432           0 :         if( pPor->InTxtGrp() || ( pPor->GetLen() && !pPor->IsFlyPortion()
     433           0 :             && !pPor->IsHolePortion() ) || pPor->IsBreakPortion() )
     434             :         {
     435           0 :             nLast = nX;
     436           0 :             nPorHeight = pPor->Height();
     437           0 :             nPorAscent = pPor->GetAscent();
     438             :         }
     439           0 :         pPor = pPor->GetPortion();
     440             :     }
     441             : 
     442           0 :     const Size aCharSize( 1, nTmpHeight );
     443           0 :     pOrig->Pos( GetTopLeft() );
     444           0 :     pOrig->SSize( aCharSize );
     445           0 :     pOrig->Pos().X() += nLast;
     446           0 :     const SwTwips nTmpRight = Right() - 1;
     447           0 :     if( pOrig->Left() > nTmpRight )
     448           0 :         pOrig->Pos().X() = nTmpRight;
     449             : 
     450           0 :     if ( pCMS && pCMS->bRealHeight )
     451             :     {
     452           0 :         if ( nTmpAscent > nPorAscent )
     453           0 :             pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
     454             :         else
     455           0 :             pCMS->aRealHeight.X() = 0;
     456             :         OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
     457           0 :         pCMS->aRealHeight.Y() = nPorHeight;
     458             :     }
     459             : 
     460           0 :     return true;
     461             : }
     462             : 
     463             : // internal function, called by SwTxtCursor::GetCharRect() to calculate
     464             : // the relative character position in the current line.
     465             : // pOrig referes to x and y coordinates, width and height of the cursor
     466             : // pCMS is used for restricting the cursor, if there are different font
     467             : // heights in one line ( first value = offset to y of pOrig, second
     468             : // value = real height of (shortened) cursor
     469      119033 : void SwTxtCursor::_GetCharRect( SwRect* pOrig, const sal_Int32 nOfst,
     470             :     SwCrsrMoveState* pCMS )
     471             : {
     472      119033 :     const OUString aText = GetInfo().GetTxt();
     473      237674 :     SwTxtSizeInfo aInf( GetInfo(), &aText, nStart );
     474      119033 :     if( GetPropFont() )
     475          50 :         aInf.GetFont()->SetProportion( GetPropFont() );
     476             :     sal_uInt16 nTmpAscent, nTmpHeight;  // Line height
     477      119033 :     CalcAscentAndHeight( nTmpAscent, nTmpHeight );
     478      119033 :     const Size  aCharSize( 1, nTmpHeight );
     479      119033 :     const Point aCharPos;
     480      119033 :     pOrig->Pos( aCharPos );
     481      119033 :     pOrig->SSize( aCharSize );
     482             : 
     483             :     // If we are looking for a position inside a field which covers
     484             :     // more than one line we may not skip any "empty portions" at the
     485             :     // beginning of a line
     486      119033 :     const bool bInsideFirstField = pCMS && pCMS->pSpecialPos &&
     487           0 :                                        ( pCMS->pSpecialPos->nLineOfst ||
     488           0 :                                          SP_EXTEND_RANGE_BEFORE ==
     489      119033 :                                          pCMS->pSpecialPos->nExtendRange );
     490             : 
     491      119033 :     bool bWidth = pCMS && pCMS->bRealWidth;
     492      119033 :     if( !pCurr->GetLen() && !pCurr->Width() )
     493             :     {
     494       12506 :         if ( pCMS && pCMS->bRealHeight )
     495             :         {
     496       12470 :             pCMS->aRealHeight.X() = 0;
     497       12470 :             pCMS->aRealHeight.Y() = nTmpHeight;
     498             :         }
     499             :     }
     500             :     else
     501             :     {
     502      106527 :         sal_uInt16 nPorHeight = nTmpHeight;
     503      106527 :         sal_uInt16 nPorAscent = nTmpAscent;
     504      106527 :         SwTwips nX = 0;
     505      106527 :         SwTwips nTmpFirst = 0;
     506      106527 :         SwLinePortion *pPor = pCurr->GetFirstPortion();
     507      106527 :         SwBidiPortion* pLastBidiPor = 0;
     508      106527 :         SwTwips nLastBidiPorWidth = 0;
     509      106527 :         std::deque<sal_uInt16>* pKanaComp = pCurr->GetpKanaComp();
     510      106527 :         sal_uInt16 nSpaceIdx = 0;
     511      106527 :         size_t nKanaIdx = 0;
     512      106527 :         long nSpaceAdd = pCurr->IsSpaceAdd() ? pCurr->GetLLSpaceAdd( 0 ) : 0;
     513             : 
     514      106527 :         bool bNoTxt = true;
     515             : 
     516             :         // First all portions without Len at beginning of line are skipped.
     517             :         // Exceptions are the mean special portions from WhichFirstPortion:
     518             :         // Num, ErgoSum, FtnNum, FeldReste
     519             :         // 8477: but also the only Textportion of an empty line with
     520             :         // Right/Center-Adjustment! So not just pPor->GetExpandPortion() ...
     521      225766 :         while( pPor && !pPor->GetLen() && ! bInsideFirstField )
     522             :         {
     523       12712 :             nX += pPor->Width();
     524       12712 :             if ( pPor->InSpaceGrp() && nSpaceAdd )
     525           0 :                 nX += pPor->CalcSpacing( nSpaceAdd, aInf );
     526       12712 :             if( bNoTxt )
     527        8320 :                 nTmpFirst = nX;
     528             :             // 8670: EndPortions count once as TxtPortions.
     529             :             // if( pPor->InTxtGrp() || pPor->IsBreakPortion() )
     530       12712 :             if( pPor->InTxtGrp() || pPor->IsBreakPortion() || pPor->InTabGrp() )
     531             :             {
     532        4804 :                 bNoTxt = false;
     533        4804 :                 nTmpFirst = nX;
     534             :             }
     535       12712 :             if( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() )
     536             :             {
     537           0 :                 if ( pCurr->IsSpaceAdd() )
     538             :                 {
     539           0 :                     if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
     540           0 :                         nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
     541             :                     else
     542           0 :                         nSpaceAdd = 0;
     543             :                 }
     544             : 
     545           0 :                 if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
     546           0 :                     ++nKanaIdx;
     547             :             }
     548       12712 :             if( pPor->InFixMargGrp() )
     549             :             {
     550        9636 :                 if( pPor->IsMarginPortion() )
     551        6808 :                     bNoTxt = false;
     552             :                 else
     553             :                 {
     554             :                     // fix margin portion => next SpaceAdd, KanaComp value
     555        2828 :                     if ( pCurr->IsSpaceAdd() )
     556             :                     {
     557           0 :                         if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
     558           0 :                             nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
     559             :                         else
     560           0 :                             nSpaceAdd = 0;
     561             :                     }
     562             : 
     563        2828 :                     if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
     564           0 :                         ++nKanaIdx;
     565             :                 }
     566             :             }
     567       12712 :             pPor = pPor->GetPortion();
     568             :         }
     569             : 
     570      106527 :         if( !pPor )
     571             :         {
     572             :             // There's just Spezialportions.
     573        1794 :             nX = nTmpFirst;
     574             :         }
     575             :         else
     576             :         {
     577      313243 :             if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
     578      105283 :                 (!pPor->InFldGrp() || pPor->GetAscent() ) )
     579             :             {
     580      104255 :                 nPorHeight = pPor->Height();
     581      104255 :                 nPorAscent = pPor->GetAscent();
     582             :             }
     583      319965 :             while( pPor && !pPor->IsBreakPortion() && ( aInf.GetIdx() < nOfst ||
     584           0 :                    ( bWidth && ( pPor->IsKernPortion() || pPor->IsMultiPortion() ) ) ) )
     585             :             {
     586      169747 :                 if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
     587       58307 :                     (!pPor->InFldGrp() || pPor->GetAscent() ) )
     588             :                 {
     589       56173 :                     nPorHeight = pPor->Height();
     590       56173 :                     nPorAscent = pPor->GetAscent();
     591             :                 }
     592             : 
     593             :                 // If we are behind the portion, we add the portion width to
     594             :                 // nX. Special case: nOfst = aInf.GetIdx() + pPor->GetLen().
     595             :                 // For common portions (including BidiPortions) we want to add
     596             :                 // the portion width to nX. For MultiPortions, nExtra = 0,
     597             :                 // therefore we go to the 'else' branch and start a recursion.
     598       58585 :                 const sal_Int32 nExtra = pPor->IsMultiPortion() &&
     599        1184 :                                     ! ((SwMultiPortion*)pPor)->IsBidi() &&
     600       58585 :                                     ! bWidth ? 0 : 1;
     601       57401 :                 if ( aInf.GetIdx() + pPor->GetLen() < nOfst + nExtra )
     602             :                 {
     603       53098 :                     if ( pPor->InSpaceGrp() && nSpaceAdd )
     604           0 :                         nX += pPor->PrtWidth() +
     605           0 :                               pPor->CalcSpacing( nSpaceAdd, aInf );
     606             :                     else
     607             :                     {
     608       53098 :                         if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
     609             :                         {
     610             :                             // update to current SpaceAdd, KanaComp values
     611          12 :                             if ( pCurr->IsSpaceAdd() )
     612             :                             {
     613           0 :                                 if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
     614           0 :                                     nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
     615             :                                 else
     616           0 :                                     nSpaceAdd = 0;
     617             :                             }
     618             : 
     619          12 :                             if ( pKanaComp &&
     620           0 :                                 ( nKanaIdx + 1 ) < pKanaComp->size()
     621             :                                 )
     622           0 :                                 ++nKanaIdx;
     623             :                         }
     624       53098 :                         if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
     625           0 :                                 !pPor->GetPortion()->IsMarginPortion() ) )
     626       53098 :                             nX += pPor->PrtWidth();
     627             :                     }
     628       53098 :                     if( pPor->IsMultiPortion() )
     629             :                     {
     630         792 :                         if ( ((SwMultiPortion*)pPor)->HasTabulator() )
     631             :                         {
     632           0 :                             if ( pCurr->IsSpaceAdd() )
     633             :                             {
     634           0 :                                 if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
     635           0 :                                     nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
     636             :                                 else
     637           0 :                                     nSpaceAdd = 0;
     638             :                             }
     639             : 
     640           0 :                             if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
     641           0 :                                 ++nKanaIdx;
     642             :                         }
     643             : 
     644             :                         // if we are right behind a BidiPortion, we have to
     645             :                         // hold a pointer to the BidiPortion in order to
     646             :                         // find the correct cursor position, depending on the
     647             :                         // cursor level
     648         792 :                         if ( ((SwMultiPortion*)pPor)->IsBidi() &&
     649           0 :                              aInf.GetIdx() + pPor->GetLen() == nOfst )
     650             :                         {
     651           0 :                              pLastBidiPor = (SwBidiPortion*)pPor;
     652           0 :                              nLastBidiPorWidth = pLastBidiPor->Width() +
     653           0 :                                                  pLastBidiPor->CalcSpacing( nSpaceAdd, aInf );;
     654             :                         }
     655             :                     }
     656             : 
     657       53098 :                     aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() );
     658       53098 :                     pPor = pPor->GetPortion();
     659             :                 }
     660             :                 else
     661             :                 {
     662        4303 :                     if( pPor->IsMultiPortion() )
     663             :                     {
     664         392 :                         nTmpAscent = AdjustBaseLine( *pCurr, pPor );
     665         392 :                         GetInfo().SetMulti( true );
     666         392 :                         pOrig->Pos().Y() += nTmpAscent - nPorAscent;
     667             : 
     668         392 :                         if( pCMS && pCMS->b2Lines )
     669             :                         {
     670         136 :                             const bool bRecursion = pCMS->p2Lines;
     671         136 :                             if ( !bRecursion )
     672             :                             {
     673         136 :                                 pCMS->p2Lines = new Sw2LinesPos;
     674         136 :                                 pCMS->p2Lines->aLine = SwRect(aCharPos, aCharSize);
     675             :                             }
     676             : 
     677         136 :                             if( ((SwMultiPortion*)pPor)->HasRotation() )
     678             :                             {
     679           0 :                                 if( ((SwMultiPortion*)pPor)->IsRevers() )
     680           0 :                                     pCMS->p2Lines->nMultiType = MT_ROT_270;
     681             :                                 else
     682           0 :                                     pCMS->p2Lines->nMultiType = MT_ROT_90;
     683             :                             }
     684         136 :                             else if( ((SwMultiPortion*)pPor)->IsDouble() )
     685          30 :                                 pCMS->p2Lines->nMultiType = MT_TWOLINE;
     686         106 :                             else if( ((SwMultiPortion*)pPor)->IsBidi() )
     687           0 :                                 pCMS->p2Lines->nMultiType = MT_BIDI;
     688             :                             else
     689         106 :                                 pCMS->p2Lines->nMultiType = MT_RUBY;
     690             : 
     691         136 :                             SwTwips nTmpWidth = pPor->Width();
     692         136 :                             if( nSpaceAdd )
     693           0 :                                 nTmpWidth += pPor->CalcSpacing(nSpaceAdd, aInf);
     694             : 
     695         136 :                             SwRect aRect( Point(aCharPos.X() + nX, pOrig->Top() ),
     696         272 :                                           Size( nTmpWidth, pPor->Height() ) );
     697             : 
     698         136 :                             if ( ! bRecursion )
     699         136 :                                 pCMS->p2Lines->aPortion = aRect;
     700             :                             else
     701           0 :                                 pCMS->p2Lines->aPortion2 = aRect;
     702             :                         }
     703             : 
     704             :                         // In a multi-portion we use GetCharRect()-function
     705             :                         // recursively and must add the x-position
     706             :                         // of the multi-portion.
     707         392 :                         sal_Int32 nOldStart = nStart;
     708         392 :                         SwTwips nOldY = nY;
     709         392 :                         sal_uInt8 nOldProp = GetPropFont();
     710         392 :                         nStart = aInf.GetIdx();
     711         392 :                         SwLineLayout* pOldCurr = pCurr;
     712         392 :                         pCurr = &((SwMultiPortion*)pPor)->GetRoot();
     713         392 :                         if( ((SwMultiPortion*)pPor)->IsDouble() )
     714          50 :                             SetPropFont( 50 );
     715             : 
     716             :                         SwTextGridItem const*const pGrid(
     717         392 :                                 GetGridItem(GetTxtFrm()->FindPageFrm()));
     718         392 :                         const bool bHasGrid = pGrid && GetInfo().SnapToGrid();
     719             :                         const sal_uInt16 nRubyHeight = bHasGrid ?
     720         392 :                                                    pGrid->GetRubyHeight() : 0;
     721             : 
     722        1028 :                         if( nStart + pCurr->GetLen() <= nOfst && GetNext() &&
     723         734 :                             ( ! ((SwMultiPortion*)pPor)->IsRuby() ||
     724         342 :                                 ((SwMultiPortion*)pPor)->OnTop() ) )
     725             :                         {
     726             :                             sal_uInt16 nOffset;
     727             :                             // in grid mode we may only add the height of the
     728             :                             // ruby line if ruby line is on top
     729         244 :                             if ( bHasGrid &&
     730         244 :                                 ((SwMultiPortion*)pPor)->IsRuby() &&
     731           0 :                                 ((SwMultiPortion*)pPor)->OnTop() )
     732           0 :                                 nOffset = nRubyHeight;
     733             :                             else
     734         244 :                                 nOffset = GetLineHeight();
     735             : 
     736         244 :                             pOrig->Pos().Y() += nOffset;
     737         244 :                             Next();
     738             :                         }
     739             : 
     740             :                         const bool bSpaceChg = ((SwMultiPortion*)pPor)->
     741         392 :                                                 ChgSpaceAdd( pCurr, nSpaceAdd );
     742         392 :                         Point aOldPos = pOrig->Pos();
     743             : 
     744             :                         // Ok, for ruby portions in grid mode we have to
     745             :                         // temporarily set the inner line height to the
     746             :                         // outer line height because that value is needed
     747             :                         // for the adjustment inside the recursion
     748         392 :                         const sal_uInt16 nOldRubyHeight = pCurr->Height();
     749         392 :                         const sal_uInt16 nOldRubyRealHeight = pCurr->GetRealHeight();
     750             :                         const bool bChgHeight =
     751         392 :                                 ((SwMultiPortion*)pPor)->IsRuby() && bHasGrid;
     752             : 
     753         392 :                         if ( bChgHeight )
     754             :                         {
     755           0 :                             pCurr->Height( pOldCurr->Height() - nRubyHeight );
     756           0 :                             pCurr->SetRealHeight( pOldCurr->GetRealHeight() -
     757           0 :                                                   nRubyHeight );
     758             :                         }
     759             : 
     760         392 :                         SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
     761         392 :                         if ( ((SwMultiPortion*)pPor)->IsBidi() )
     762             :                         {
     763             :                             aLayoutModeModifier.Modify(
     764           0 :                                 ((SwBidiPortion*)pPor)->GetLevel() % 2 );
     765             :                         }
     766             : 
     767         392 :                         _GetCharRect( pOrig, nOfst, pCMS );
     768             : 
     769         392 :                         if ( bChgHeight )
     770             :                         {
     771           0 :                             pCurr->Height( nOldRubyHeight );
     772           0 :                             pCurr->SetRealHeight( nOldRubyRealHeight );
     773             :                         }
     774             : 
     775             :                         // if we are still in the first row of
     776             :                         // our 2 line multiportion, we use the FirstMulti flag
     777             :                         // to indicate this
     778         392 :                         if ( ((SwMultiPortion*)pPor)->IsDouble() )
     779             :                         {
     780             :                             // the recursion may have damaged our font size
     781          50 :                             SetPropFont( nOldProp );
     782          50 :                             if ( !nOldProp )
     783          50 :                                 nOldProp = 100;
     784          50 :                             GetInfo().GetFont()->SetProportion( 100 );
     785             : 
     786          50 :                             if ( pCurr == &((SwMultiPortion*)pPor)->GetRoot() )
     787             :                             {
     788           0 :                                 GetInfo().SetFirstMulti( true );
     789             : 
     790             :                                 // we want to treat a double line portion like a
     791             :                                 // single line portion, if there is no text in
     792             :                                 // the second line
     793           0 :                                 if ( !pCurr->GetNext() ||
     794           0 :                                      !pCurr->GetNext()->GetLen() )
     795           0 :                                     GetInfo().SetMulti( false );
     796             :                             }
     797             :                         }
     798             :                         // ruby portions are treated like single line portions
     799         342 :                         else if( ((SwMultiPortion*)pPor)->IsRuby() ||
     800           0 :                                  ((SwMultiPortion*)pPor)->IsBidi() )
     801         342 :                             GetInfo().SetMulti( false );
     802             : 
     803             :                         // calculate cursor values
     804         392 :                         if( ((SwMultiPortion*)pPor)->HasRotation() )
     805             :                         {
     806           0 :                             GetInfo().SetMulti( false );
     807           0 :                             long nTmp = pOrig->Width();
     808           0 :                             pOrig->Width( pOrig->Height() );
     809           0 :                             pOrig->Height( nTmp );
     810           0 :                             nTmp = pOrig->Left() - aOldPos.X();
     811             : 
     812             :                             // if we travel into our rotated portion from
     813             :                             // a line below, we have to take care, that the
     814             :                             // y coord in pOrig is less than line height:
     815           0 :                             if ( nTmp )
     816           0 :                                 nTmp--;
     817             : 
     818           0 :                             pOrig->Pos().X() = nX + aOldPos.X();
     819           0 :                             if( ((SwMultiPortion*)pPor)->IsRevers() )
     820           0 :                                 pOrig->Pos().Y() = aOldPos.Y() + nTmp;
     821             :                             else
     822           0 :                                 pOrig->Pos().Y() = aOldPos.Y()
     823           0 :                                     + pPor->Height() - nTmp - pOrig->Height();
     824           0 :                             if ( pCMS && pCMS->bRealHeight )
     825             :                             {
     826           0 :                                 pCMS->aRealHeight.Y() = -pCMS->aRealHeight.Y();
     827             :                                 // result for rotated multi portion is not
     828             :                                 // correct for reverse (270 degree) portions
     829           0 :                                 if( ((SwMultiPortion*)pPor)->IsRevers() )
     830             :                                 {
     831           0 :                                     if ( SvxParaVertAlignItem::AUTOMATIC ==
     832           0 :                                          GetLineInfo().GetVertAlign() )
     833             :                                         // if vertical alignment is set to auto,
     834             :                                         // we switch from base line alignment
     835             :                                         // to centered alignment
     836           0 :                                         pCMS->aRealHeight.X() =
     837           0 :                                             ( pOrig->Width() +
     838           0 :                                               pCMS->aRealHeight.Y() ) / 2;
     839             :                                     else
     840           0 :                                         pCMS->aRealHeight.X() =
     841           0 :                                             ( pOrig->Width() -
     842           0 :                                               pCMS->aRealHeight.X() +
     843           0 :                                               pCMS->aRealHeight.Y() );
     844             :                                 }
     845             :                             }
     846             :                         }
     847             :                         else
     848             :                         {
     849         392 :                             pOrig->Pos().Y() += aOldPos.Y();
     850         392 :                             if ( ((SwMultiPortion*)pPor)->IsBidi() )
     851             :                             {
     852           0 :                                 const SwTwips nPorWidth = pPor->Width() +
     853           0 :                                                          pPor->CalcSpacing( nSpaceAdd, aInf );
     854           0 :                                 const SwTwips nInsideOfst = pOrig->Pos().X();
     855           0 :                                 pOrig->Pos().X() = nX + nPorWidth -
     856           0 :                                                    nInsideOfst - pOrig->Width();
     857             :                             }
     858             :                             else
     859         392 :                                 pOrig->Pos().X() += nX;
     860             : 
     861         392 :                             if( ((SwMultiPortion*)pPor)->HasBrackets() )
     862          40 :                                 pOrig->Pos().X() +=
     863          80 :                                     ((SwDoubleLinePortion*)pPor)->PreWidth();
     864             :                         }
     865             : 
     866         392 :                         if( bSpaceChg )
     867           0 :                             SwDoubleLinePortion::ResetSpaceAdd( pCurr );
     868             : 
     869         392 :                         pCurr = pOldCurr;
     870         392 :                         nStart = nOldStart;
     871         392 :                         nY = nOldY;
     872         392 :                         bPrev = false;
     873             : 
     874      119425 :                         return;
     875             :                     }
     876        3911 :                     if ( pPor->PrtWidth() )
     877             :                     {
     878        3907 :                         sal_Int32 nOldLen = pPor->GetLen();
     879        3907 :                         pPor->SetLen( nOfst - aInf.GetIdx() );
     880        3907 :                         aInf.SetLen( pPor->GetLen() );
     881        3907 :                         if( nX || !pPor->InNumberGrp() )
     882             :                         {
     883        3907 :                             SeekAndChg( aInf );
     884        3907 :                             const bool bOldOnWin = aInf.OnWin();
     885        3907 :                             aInf.SetOnWin( false ); // keine BULLETs!
     886        3907 :                             SwTwips nTmp = nX;
     887        3907 :                             aInf.SetKanaComp( pKanaComp );
     888        3907 :                             aInf.SetKanaIdx( nKanaIdx );
     889        3907 :                             nX += pPor->GetTxtSize( aInf ).Width();
     890        3907 :                             aInf.SetOnWin( bOldOnWin );
     891        3907 :                             if ( pPor->InSpaceGrp() && nSpaceAdd )
     892           0 :                                 nX += pPor->CalcSpacing( nSpaceAdd, aInf );
     893        3907 :                             if( bWidth )
     894             :                             {
     895           0 :                                 pPor->SetLen( pPor->GetLen() + 1 );
     896           0 :                                 aInf.SetLen( pPor->GetLen() );
     897           0 :                                 aInf.SetOnWin( false ); // keine BULLETs!
     898           0 :                                 nTmp += pPor->GetTxtSize( aInf ).Width();
     899           0 :                                 aInf.SetOnWin( bOldOnWin );
     900           0 :                                 if ( pPor->InSpaceGrp() && nSpaceAdd )
     901           0 :                                     nTmp += pPor->CalcSpacing(nSpaceAdd, aInf);
     902           0 :                                 pOrig->Width( nTmp - nX );
     903             :                             }
     904             :                         }
     905        3907 :                         pPor->SetLen( nOldLen );
     906             : 
     907             :                         // Shift the cursor with the right border width
     908             :                         // Note: nX remains positive because GetTxtSize() also include the width of the right border
     909        3907 :                         if( aInf.GetIdx() < nOfst && nOfst < aInf.GetIdx() + pPor->GetLen() )
     910             :                         {
     911             :                             // Find the current drop portion part and use its right border
     912        3907 :                             if( pPor->IsDropPortion() && static_cast<SwDropPortion*>(pPor)->GetLines() > 1 )
     913             :                             {
     914           0 :                                 SwDropPortion* pDrop = static_cast<SwDropPortion*>(pPor);
     915           0 :                                 const SwDropPortionPart* pCurrPart = pDrop->GetPart();
     916           0 :                                 sal_Int16 nSumLength = 0;
     917           0 :                                 while( pCurrPart && (nSumLength += pCurrPart->GetLen()) < nOfst - aInf.GetIdx() )
     918             :                                 {
     919           0 :                                     pCurrPart = pCurrPart->GetFollow();
     920             :                                 }
     921           0 :                                 if( pCurrPart && nSumLength != nOfst - aInf.GetIdx() &&
     922           0 :                                     pCurrPart->GetFont().GetRightBorder() && !pCurrPart->GetJoinBorderWithNext() )
     923             :                                 {
     924           0 :                                     nX -= pCurrPart->GetFont().GetRightBorderSpace();
     925             :                                 }
     926             :                             }
     927        3907 :                             else if( GetInfo().GetFont()->GetRightBorder() && !pPor->GetJoinBorderWithNext())
     928             :                             {
     929           0 :                                 nX -= GetInfo().GetFont()->GetRightBorderSpace();
     930             :                             }
     931             :                          }
     932             :                     }
     933        3911 :                     bWidth = false;
     934        3911 :                     break;
     935             :                 }
     936             :             }
     937             :         }
     938             : 
     939      106135 :         if( pPor )
     940             :         {
     941             :             OSL_ENSURE( !pPor->InNumberGrp() || bInsideFirstField, "Number surprise" );
     942       61971 :             bool bEmptyFld = false;
     943       61971 :             if( pPor->InFldGrp() && pPor->GetLen() )
     944             :             {
     945         436 :                 SwFldPortion *pTmp = (SwFldPortion*)pPor;
     946         872 :                 while( pTmp->HasFollow() && pTmp->GetExp().isEmpty() )
     947             :                 {
     948           0 :                     sal_uInt16 nAddX = pTmp->Width();
     949           0 :                     SwLinePortion *pNext = pTmp->GetPortion();
     950           0 :                     while( pNext && !pNext->InFldGrp() )
     951             :                     {
     952             :                         OSL_ENSURE( !pNext->GetLen(), "Where's my field follow?" );
     953           0 :                         nAddX = nAddX + pNext->Width();
     954           0 :                         pNext = pNext->GetPortion();
     955             :                     }
     956           0 :                     if( !pNext )
     957           0 :                         break;
     958           0 :                     pTmp = (SwFldPortion*)pNext;
     959           0 :                     nPorHeight = pTmp->Height();
     960           0 :                     nPorAscent = pTmp->GetAscent();
     961           0 :                     nX += nAddX;
     962           0 :                     bEmptyFld = true;
     963             :                 }
     964             :             }
     965             :             // 8513: Fields in justified text, skipped
     966      123978 :             while( pPor && !pPor->GetLen() && ! bInsideFirstField &&
     967          36 :                    ( pPor->IsFlyPortion() || pPor->IsKernPortion() ||
     968          36 :                      pPor->IsBlankPortion() || pPor->InTabGrp() ||
     969          24 :                      ( !bEmptyFld && pPor->InFldGrp() ) ) )
     970             :             {
     971          12 :                 if ( pPor->InSpaceGrp() && nSpaceAdd )
     972           0 :                     nX += pPor->PrtWidth() +
     973           0 :                           pPor->CalcSpacing( nSpaceAdd, aInf );
     974             :                 else
     975             :                 {
     976          12 :                     if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
     977             :                     {
     978           0 :                         if ( pCurr->IsSpaceAdd() )
     979             :                         {
     980           0 :                             if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
     981           0 :                                 nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
     982             :                             else
     983           0 :                                 nSpaceAdd = 0;
     984             :                         }
     985             : 
     986           0 :                         if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
     987           0 :                             ++nKanaIdx;
     988             :                     }
     989          12 :                     if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
     990           0 :                             !pPor->GetPortion()->IsMarginPortion() ) )
     991          12 :                         nX += pPor->PrtWidth();
     992             :                 }
     993          12 :                 if( pPor->IsMultiPortion() &&
     994           0 :                     ((SwMultiPortion*)pPor)->HasTabulator() )
     995             :                 {
     996           0 :                     if ( pCurr->IsSpaceAdd() )
     997             :                     {
     998           0 :                         if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
     999           0 :                             nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
    1000             :                         else
    1001           0 :                             nSpaceAdd = 0;
    1002             :                     }
    1003             : 
    1004           0 :                     if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
    1005           0 :                         ++nKanaIdx;
    1006             :                 }
    1007          12 :                 if( !pPor->IsFlyPortion() )
    1008             :                 {
    1009          12 :                     nPorHeight = pPor->Height();
    1010          12 :                     nPorAscent = pPor->GetAscent();
    1011             :                 }
    1012          12 :                 pPor = pPor->GetPortion();
    1013             :             }
    1014             : 
    1015      182002 :             if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
    1016       61971 :                 pPor->GetPortion() && pPor->GetPortion()->InFixGrp() )
    1017             :             {
    1018             :                 // All special portions have to be skipped
    1019             :                 // Taking the German word "zusammen" as example: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right()
    1020             :                 // Without the adjustment we end up in front of '-', with the
    1021             :                 // adjustment in front of the 's'.
    1022           0 :                 while( pPor && !pPor->GetLen() )
    1023             :                 {
    1024           0 :                     nX += pPor->Width();
    1025           0 :                     if( !pPor->IsMarginPortion() )
    1026             :                     {
    1027           0 :                         nPorHeight = pPor->Height();
    1028           0 :                         nPorAscent = pPor->GetAscent();
    1029             :                     }
    1030           0 :                     pPor = pPor->GetPortion();
    1031             :                 }
    1032             :             }
    1033       61971 :             if( pPor && pCMS )
    1034             :             {
    1035       57634 :                 if( pCMS->bFieldInfo && pPor->InFldGrp() && pPor->Width() )
    1036           0 :                     pOrig->Width( pPor->Width() );
    1037       57634 :                 if( pPor->IsDropPortion() )
    1038             :                 {
    1039         128 :                     nPorAscent = ((SwDropPortion*)pPor)->GetDropHeight();
    1040             :                     // The drop height is only calculated, if we have more than
    1041             :                     // one line. Otherwise it is 0.
    1042         128 :                     if ( ! nPorAscent)
    1043         128 :                         nPorAscent = pPor->Height();
    1044         128 :                     nPorHeight = nPorAscent;
    1045         256 :                     pOrig->Height( nPorHeight +
    1046         256 :                         ((SwDropPortion*)pPor)->GetDropDescent() );
    1047         128 :                     if( nTmpHeight < pOrig->Height() )
    1048             :                     {
    1049           0 :                         nTmpAscent = nPorAscent;
    1050           0 :                         nTmpHeight = sal_uInt16( pOrig->Height() );
    1051             :                     }
    1052             :                 }
    1053       57634 :                 if( bWidth && pPor->PrtWidth() && pPor->GetLen() &&
    1054           0 :                     aInf.GetIdx() == nOfst )
    1055             :                 {
    1056           0 :                     if( !pPor->IsFlyPortion() && pPor->Height() &&
    1057           0 :                         pPor->GetAscent() )
    1058             :                     {
    1059           0 :                         nPorHeight = pPor->Height();
    1060           0 :                         nPorAscent = pPor->GetAscent();
    1061             :                     }
    1062             :                     SwTwips nTmp;
    1063           0 :                     if( 2 > pPor->GetLen() )
    1064             :                     {
    1065           0 :                         nTmp = pPor->Width();
    1066           0 :                         if ( pPor->InSpaceGrp() && nSpaceAdd )
    1067           0 :                             nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
    1068             :                     }
    1069             :                     else
    1070             :                     {
    1071           0 :                         const bool bOldOnWin = aInf.OnWin();
    1072           0 :                         sal_Int32 nOldLen = pPor->GetLen();
    1073           0 :                         pPor->SetLen( 1 );
    1074           0 :                         aInf.SetLen( pPor->GetLen() );
    1075           0 :                         SeekAndChg( aInf );
    1076           0 :                         aInf.SetOnWin( false ); // keine BULLETs!
    1077           0 :                         aInf.SetKanaComp( pKanaComp );
    1078           0 :                         aInf.SetKanaIdx( nKanaIdx );
    1079           0 :                         nTmp = pPor->GetTxtSize( aInf ).Width();
    1080           0 :                         aInf.SetOnWin( bOldOnWin );
    1081           0 :                         if ( pPor->InSpaceGrp() && nSpaceAdd )
    1082           0 :                             nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
    1083           0 :                         pPor->SetLen( nOldLen );
    1084             :                     }
    1085           0 :                     pOrig->Width( nTmp );
    1086             :                 }
    1087             : 
    1088             :                 // travel inside field portion?
    1089       57634 :                 if ( pCMS->pSpecialPos )
    1090             :                 {
    1091             :                     // apply attributes to font
    1092           0 :                     Seek( nOfst );
    1093           0 :                     lcl_GetCharRectInsideField( aInf, *pOrig, *pCMS, *pPor );
    1094             :                 }
    1095             :             }
    1096             :         }
    1097             : 
    1098             :         // special case: We are at the beginning of a BidiPortion or
    1099             :         // directly behind a BidiPortion
    1100      106333 :         if ( pCMS &&
    1101      101804 :                 ( pLastBidiPor ||
    1102       57634 :                 ( pPor &&
    1103       58134 :                   pPor->IsMultiPortion() &&
    1104         500 :                   ((SwMultiPortion*)pPor)->IsBidi() ) ) )
    1105             :         {
    1106             :             // we determine if the cursor has to blink before or behind
    1107             :             // the bidi portion
    1108         198 :             if ( pLastBidiPor )
    1109             :             {
    1110           0 :                 const sal_uInt8 nPortionLevel = pLastBidiPor->GetLevel();
    1111             : 
    1112           0 :                 if ( pCMS->nCursorBidiLevel >= nPortionLevel )
    1113             :                 {
    1114             :                     // we came from inside the bidi portion, we want to blink
    1115             :                     // behind the portion
    1116           0 :                     pOrig->Pos().X() -= nLastBidiPorWidth;
    1117             : 
    1118             :                     // Again, there is a special case: logically behind
    1119             :                     // the portion can actually mean that the cursor is inside
    1120             :                     // the portion. This can happen is the last portion
    1121             :                     // inside the bidi portion is a nested bidi portion
    1122             :                     SwLineLayout& rLineLayout =
    1123           0 :                             ((SwMultiPortion*)pLastBidiPor)->GetRoot();
    1124             : 
    1125           0 :                     const SwLinePortion *pLast = rLineLayout.FindLastPortion();
    1126           0 :                     if ( pLast->IsMultiPortion() )
    1127             :                     {
    1128             :                         OSL_ENSURE( ((SwMultiPortion*)pLast)->IsBidi(),
    1129             :                                  "Non-BidiPortion inside BidiPortion" );
    1130           0 :                         pOrig->Pos().X() += pLast->Width() +
    1131           0 :                                             pLast->CalcSpacing( nSpaceAdd, aInf );
    1132             :                     }
    1133             :                 }
    1134             :             }
    1135             :             else
    1136             :             {
    1137         198 :                 const sal_uInt8 nPortionLevel = ((SwBidiPortion*)pPor)->GetLevel();
    1138             : 
    1139         198 :                 if ( pCMS->nCursorBidiLevel >= nPortionLevel )
    1140             :                 {
    1141             :                     // we came from inside the bidi portion, we want to blink
    1142             :                     // behind the portion
    1143           0 :                     pOrig->Pos().X() += pPor->Width() +
    1144           0 :                                         pPor->CalcSpacing( nSpaceAdd, aInf );
    1145             :                 }
    1146             :             }
    1147             :         }
    1148             : 
    1149      106135 :         pOrig->Pos().X() += nX;
    1150             : 
    1151      106135 :         if ( pCMS && pCMS->bRealHeight )
    1152             :         {
    1153       98946 :             nTmpAscent = AdjustBaseLine( *pCurr, 0, nPorHeight, nPorAscent );
    1154       98946 :             if ( nTmpAscent > nPorAscent )
    1155        1846 :                 pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
    1156             :             else
    1157       97100 :                 pCMS->aRealHeight.X() = 0;
    1158             :             OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
    1159       98946 :             if ( nTmpHeight > nPorHeight )
    1160        2662 :                 pCMS->aRealHeight.Y() = nPorHeight;
    1161             :             else
    1162       96284 :                 pCMS->aRealHeight.Y() = nTmpHeight;
    1163             :         }
    1164      118641 :     }
    1165             : }
    1166             : 
    1167      118641 : bool SwTxtCursor::GetCharRect( SwRect* pOrig, const sal_Int32 nOfst,
    1168             :                                SwCrsrMoveState* pCMS, const long nMax )
    1169             : {
    1170      118641 :     CharCrsrToLine(nOfst);
    1171             : 
    1172             :     // Indicates that a position inside a special portion (field, number portion)
    1173             :     // is requested.
    1174      118641 :     const bool bSpecialPos = pCMS && pCMS->pSpecialPos;
    1175      118641 :     sal_Int32 nFindOfst = nOfst;
    1176             : 
    1177      118641 :     if ( bSpecialPos )
    1178             :     {
    1179           0 :         const sal_uInt8 nExtendRange = pCMS->pSpecialPos->nExtendRange;
    1180             : 
    1181             :         OSL_ENSURE( ! pCMS->pSpecialPos->nLineOfst || SP_EXTEND_RANGE_BEFORE != nExtendRange,
    1182             :                 "LineOffset AND Number Portion?" );
    1183             : 
    1184             :         // portions which are behind the string
    1185           0 :         if ( SP_EXTEND_RANGE_BEHIND == nExtendRange )
    1186           0 :             ++nFindOfst;
    1187             : 
    1188             :         // skip lines for fields which cover more than one line
    1189           0 :         for ( sal_uInt16 i = 0; i < pCMS->pSpecialPos->nLineOfst; i++ )
    1190           0 :             Next();
    1191             :     }
    1192             : 
    1193             :     // If necessary, as catch up, do the adjustment
    1194      118641 :     GetAdjusted();
    1195             : 
    1196      118641 :     const Point aCharPos( GetTopLeft() );
    1197      118641 :     bool bRet = true;
    1198             : 
    1199      118641 :     _GetCharRect( pOrig, nFindOfst, pCMS );
    1200             : 
    1201             :     // This actually would have to be "-1 LogicToPixel", but that seems too
    1202             :     // expensive, so it's a value (-12), that should hopefully be OK.
    1203      118641 :     const SwTwips nTmpRight = Right() - 12;
    1204             : 
    1205      118641 :     pOrig->Pos().X() += aCharPos.X();
    1206      118641 :     pOrig->Pos().Y() += aCharPos.Y();
    1207             : 
    1208      118641 :     if( pCMS && pCMS->b2Lines && pCMS->p2Lines )
    1209             :     {
    1210         136 :         pCMS->p2Lines->aLine.Pos().X() += aCharPos.X();
    1211         136 :         pCMS->p2Lines->aLine.Pos().Y() += aCharPos.Y();
    1212         136 :         pCMS->p2Lines->aPortion.Pos().X() += aCharPos.X();
    1213         136 :         pCMS->p2Lines->aPortion.Pos().Y() += aCharPos.Y();
    1214             :     }
    1215             : 
    1216      118641 :     const bool bTabOverMargin = GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_OVER_MARGIN);
    1217             :     // Make sure the cursor respects the right margin, unless in compat mode, where the tab size has priority over the margin size.
    1218      118641 :     if( pOrig->Left() > nTmpRight && !bTabOverMargin)
    1219          12 :         pOrig->Pos().X() = nTmpRight;
    1220             : 
    1221      118641 :     if( nMax )
    1222             :     {
    1223      115474 :         if( pOrig->Top() + pOrig->Height() > nMax )
    1224             :         {
    1225         790 :             if( pOrig->Top() > nMax )
    1226           0 :                 pOrig->Top( nMax );
    1227         790 :             pOrig->Height( nMax - pOrig->Top() );
    1228             :         }
    1229      115474 :         if ( pCMS && pCMS->bRealHeight && pCMS->aRealHeight.Y() >= 0 )
    1230             :         {
    1231      111416 :             long nTmp = pCMS->aRealHeight.X() + pOrig->Top();
    1232      111416 :             if( nTmp >= nMax )
    1233             :             {
    1234           0 :                 pCMS->aRealHeight.X() = nMax - pOrig->Top();
    1235           0 :                 pCMS->aRealHeight.Y() = 0;
    1236             :             }
    1237      111416 :             else if( nTmp + pCMS->aRealHeight.Y() > nMax )
    1238         848 :                 pCMS->aRealHeight.Y() = nMax - nTmp;
    1239             :         }
    1240             :     }
    1241      118641 :     long nOut = pOrig->Right() - GetTxtFrm()->Frm().Right();
    1242      118641 :     if( nOut > 0 )
    1243             :     {
    1244         540 :         if( GetTxtFrm()->Frm().Width() < GetTxtFrm()->Prt().Left()
    1245         270 :                                    + GetTxtFrm()->Prt().Width() )
    1246           0 :             nOut += GetTxtFrm()->Frm().Width() - GetTxtFrm()->Prt().Left()
    1247           0 :                     - GetTxtFrm()->Prt().Width();
    1248         270 :         if( nOut > 0 )
    1249         270 :             pOrig->Pos().X() -= nOut + 10;
    1250             :     }
    1251             : 
    1252      118641 :     return bRet;
    1253             : }
    1254             : 
    1255             : // Return: Offset in String
    1256         234 : sal_Int32 SwTxtCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
    1257             :                                     bool nChgNode, SwCrsrMoveState* pCMS ) const
    1258             : {
    1259             :     // If necessary, as catch up, do the adjustment
    1260         234 :     GetAdjusted();
    1261             : 
    1262         234 :     const OUString &rText = GetInfo().GetTxt();
    1263         234 :     sal_Int32 nOffset = 0;
    1264             : 
    1265             :     // x is the horizontal offset within the line.
    1266         234 :     SwTwips x = rPoint.X();
    1267         234 :     const SwTwips nLeftMargin  = GetLineStart();
    1268         234 :     SwTwips nRightMargin = GetLineEnd();
    1269         234 :     if( nRightMargin == nLeftMargin )
    1270           2 :         nRightMargin += 30;
    1271             : 
    1272         234 :     const bool bLeftOver = x < nLeftMargin;
    1273         234 :     if( bLeftOver )
    1274           4 :         x = nLeftMargin;
    1275         234 :     const bool bRightOver = x > nRightMargin;
    1276         234 :     if( bRightOver )
    1277         166 :         x = nRightMargin;
    1278             : 
    1279         234 :     const bool bRightAllowed = pCMS && ( pCMS->eState == MV_NONE );
    1280             : 
    1281             :     // Until here everything in document coordinates.
    1282         234 :     x -= nLeftMargin;
    1283             : 
    1284         234 :     sal_uInt16 nX = sal_uInt16( x );
    1285             : 
    1286             :     // If there are attribute changes in the line, search for the paragraph,
    1287             :     // in which nX is situated.
    1288         234 :     SwLinePortion *pPor = pCurr->GetFirstPortion();
    1289         234 :     sal_Int32 nCurrStart  = nStart;
    1290         234 :     bool bHolePortion = false;
    1291         234 :     bool bLastHyph = false;
    1292             : 
    1293         234 :     std::deque<sal_uInt16> *pKanaComp = pCurr->GetpKanaComp();
    1294         234 :     sal_Int32 nOldIdx = GetInfo().GetIdx();
    1295         234 :     sal_uInt16 nSpaceIdx = 0;
    1296         234 :     size_t nKanaIdx = 0;
    1297         234 :     long nSpaceAdd = pCurr->IsSpaceAdd() ? pCurr->GetLLSpaceAdd( 0 ) : 0;
    1298         234 :     short nKanaComp = pKanaComp ? (*pKanaComp)[0] : 0;
    1299             : 
    1300             :     // nWidth is the width of the line, or the width of
    1301             :     // the paragraph with the font change, in which nX is situated.
    1302             : 
    1303         234 :     sal_uInt16 nWidth = pPor->Width();
    1304         234 :     if ( pCurr->IsSpaceAdd() || pKanaComp )
    1305             :     {
    1306           0 :         if ( pPor->InSpaceGrp() && nSpaceAdd )
    1307             :         {
    1308           0 :             ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
    1309           0 :             nWidth = nWidth + sal_uInt16( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) );
    1310             :         }
    1311           0 :         if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
    1312           0 :             ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() )
    1313             :           )
    1314             :         {
    1315           0 :             if ( pCurr->IsSpaceAdd() )
    1316             :             {
    1317           0 :                 if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
    1318           0 :                     nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
    1319             :                 else
    1320           0 :                     nSpaceAdd = 0;
    1321             :             }
    1322             : 
    1323           0 :             if( pKanaComp )
    1324             :             {
    1325           0 :                 if ( nKanaIdx + 1 < pKanaComp->size() )
    1326           0 :                     nKanaComp = (*pKanaComp)[++nKanaIdx];
    1327             :                 else
    1328           0 :                     nKanaComp = 0;
    1329             :             }
    1330             :         }
    1331             :     }
    1332             : 
    1333             :     sal_uInt16 nWidth30;
    1334         234 :     if ( pPor->IsPostItsPortion() )
    1335           0 :         nWidth30 = 30 + pPor->GetViewWidth( GetInfo() ) / 2;
    1336             :     else
    1337           2 :         nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp() ?
    1338             :                      30 :
    1339         468 :                      nWidth;
    1340             : 
    1341         480 :     while( pPor->GetPortion() && nWidth30 < nX && !pPor->IsBreakPortion() )
    1342             :     {
    1343          12 :         nX = nX - nWidth;
    1344          12 :         nCurrStart = nCurrStart + pPor->GetLen();
    1345          12 :         bHolePortion = pPor->IsHolePortion();
    1346          12 :         pPor = pPor->GetPortion();
    1347          12 :         nWidth = pPor->Width();
    1348          12 :         if ( pCurr->IsSpaceAdd() || pKanaComp )
    1349             :         {
    1350           0 :             if ( pPor->InSpaceGrp() && nSpaceAdd )
    1351             :             {
    1352           0 :                 ((SwTxtSizeInfo&)GetInfo()).SetIdx( nCurrStart );
    1353           0 :                 nWidth = nWidth + sal_uInt16( pPor->CalcSpacing( nSpaceAdd, GetInfo() ) );
    1354             :             }
    1355             : 
    1356           0 :             if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
    1357           0 :                 ( pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->HasTabulator() )
    1358             :               )
    1359             :             {
    1360           0 :                 if ( pCurr->IsSpaceAdd() )
    1361             :                 {
    1362           0 :                     if ( ++nSpaceIdx < pCurr->GetLLSpaceAddCount() )
    1363           0 :                         nSpaceAdd = pCurr->GetLLSpaceAdd( nSpaceIdx );
    1364             :                     else
    1365           0 :                         nSpaceAdd = 0;
    1366             :                 }
    1367             : 
    1368           0 :                 if ( pKanaComp )
    1369             :                 {
    1370           0 :                     if( nKanaIdx + 1 < pKanaComp->size() )
    1371           0 :                         nKanaComp = (*pKanaComp)[++nKanaIdx];
    1372             :                     else
    1373           0 :                         nKanaComp = 0;
    1374             :                 }
    1375             :             }
    1376             :         }
    1377             : 
    1378          12 :         if ( pPor->IsPostItsPortion() )
    1379           0 :             nWidth30 = 30 +  pPor->GetViewWidth( GetInfo() ) / 2;
    1380             :         else
    1381           0 :             nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFldGrp() ?
    1382             :                          30 :
    1383          24 :                          nWidth;
    1384          12 :         if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
    1385          12 :             bLastHyph = pPor->InHyphGrp();
    1386             :     }
    1387             : 
    1388         234 :     const bool bLastPortion = (0 == pPor->GetPortion());
    1389             : 
    1390         234 :     if( nX==nWidth )
    1391             :     {
    1392         164 :         SwLinePortion *pNextPor = pPor->GetPortion();
    1393         328 :         while( pNextPor && pNextPor->InFldGrp() && !pNextPor->Width() )
    1394             :         {
    1395           0 :             nCurrStart = nCurrStart + pPor->GetLen();
    1396           0 :             pPor = pNextPor;
    1397           0 :             if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
    1398           0 :                 bLastHyph = pPor->InHyphGrp();
    1399           0 :             pNextPor = pPor->GetPortion();
    1400             :         }
    1401             :     }
    1402             : 
    1403         234 :     ((SwTxtSizeInfo&)GetInfo()).SetIdx( nOldIdx );
    1404             : 
    1405         234 :     sal_Int32 nLength = pPor->GetLen();
    1406             : 
    1407         234 :     const bool bFieldInfo = pCMS && pCMS->bFieldInfo;
    1408             : 
    1409         236 :     if( bFieldInfo && ( nWidth30 < nX || bRightOver || bLeftOver ||
    1410           0 :         ( pPor->InNumberGrp() && !pPor->IsFtnNumPortion() ) ||
    1411           0 :         ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) )
    1412           2 :         ((SwCrsrMoveState*)pCMS)->bPosCorr = true;
    1413             : 
    1414             :     // #i27615#
    1415         234 :     if (pCMS)
    1416             :     {
    1417         234 :         if( pCMS->bInFrontOfLabel)
    1418             :         {
    1419           0 :             if (! (2 * nX < nWidth && pPor->InNumberGrp() &&
    1420           0 :                    !pPor->IsFtnNumPortion()))
    1421           0 :                 pCMS->bInFrontOfLabel = false;
    1422             :         }
    1423             :     }
    1424             : 
    1425             :     // 7684: We are exactly ended up at ther HyphPortion. It is our task to
    1426             :     // provide, that we end up in the String.
    1427             :     // 7993: If length = 0, then we must exit...
    1428         234 :     if( !nLength )
    1429             :     {
    1430           4 :         if( pCMS )
    1431             :         {
    1432           4 :             if( pPor->IsFlyPortion() && bFieldInfo )
    1433           0 :                 ((SwCrsrMoveState*)pCMS)->bPosCorr = true;
    1434             : 
    1435           4 :             if (!bRightOver && nX)
    1436             :             {
    1437           2 :                 if( pPor->IsFtnNumPortion())
    1438           0 :                     ((SwCrsrMoveState*)pCMS)->bFtnNoInfo = true;
    1439           2 :                 else if (pPor->InNumberGrp() ) // #i23726#
    1440             :                 {
    1441           0 :                     ((SwCrsrMoveState*)pCMS)->nInNumPostionOffset = nX;
    1442           0 :                     ((SwCrsrMoveState*)pCMS)->bInNumPortion = true;
    1443             :                 }
    1444             :             }
    1445             :         }
    1446           4 :         if( !nCurrStart )
    1447           4 :             return 0;
    1448             : 
    1449             :         // 7849, 7816: pPor->GetHyphPortion is mandatory!
    1450           0 :         if( bHolePortion || ( !bRightAllowed && bLastHyph ) ||
    1451           0 :             ( pPor->IsMarginPortion() && !pPor->GetPortion() &&
    1452             :               // 46598: Consider the situation: We might end up behind the last character,
    1453             :               // in the last line of a centered paragraph
    1454           0 :               nCurrStart < rText.getLength() ) )
    1455           0 :             --nCurrStart;
    1456           0 :         else if( pPor->InFldGrp() && ((SwFldPortion*)pPor)->IsFollow()
    1457           0 :                  && nWidth > nX )
    1458             :         {
    1459           0 :             if( bFieldInfo )
    1460           0 :                 --nCurrStart;
    1461             :             else
    1462             :             {
    1463           0 :                 sal_uInt16 nHeight = pPor->Height();
    1464           0 :                 if ( !nHeight || nHeight > nWidth )
    1465           0 :                     nHeight = nWidth;
    1466           0 :                 if( nChgNode && nWidth - nHeight/2 > nX )
    1467           0 :                     --nCurrStart;
    1468             :             }
    1469             :         }
    1470           0 :         return nCurrStart;
    1471             :     }
    1472         230 :     if ( 1 == nLength )
    1473             :     {
    1474         224 :         if ( nWidth )
    1475             :         {
    1476             :             // Else we may not enter the character-supplying frame...
    1477         224 :             if( !( nChgNode && pPos && pPor->IsFlyCntPortion() ) )
    1478             :             {
    1479          16 :                 if ( pPor->InFldGrp() ||
    1480           4 :                      ( pPor->IsMultiPortion() &&
    1481           0 :                        ((SwMultiPortion*)pPor)->IsBidi()  ) )
    1482             :                 {
    1483           4 :                     sal_uInt16 nHeight = 0;
    1484           4 :                     if( !bFieldInfo )
    1485             :                     {
    1486           2 :                         nHeight = pPor->Height();
    1487           2 :                         if ( !nHeight || nHeight > nWidth )
    1488           2 :                             nHeight = nWidth;
    1489             :                     }
    1490             : 
    1491           4 :                     if( nWidth - nHeight/2 <= nX &&
    1492           0 :                         ( ! pPor->InFldGrp() ||
    1493           0 :                           !((SwFldPortion*)pPor)->HasFollow() ) )
    1494           0 :                         ++nCurrStart;
    1495             :                 }
    1496           8 :                 else if ( ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
    1497           0 :                     !pPor->GetPortion()->IsMarginPortion() &&
    1498           0 :                     !pPor->GetPortion()->IsHolePortion() ) )
    1499           8 :                          && ( nWidth/2 < nX ) &&
    1500           4 :                          ( !bFieldInfo ||
    1501           0 :                             ( pPor->GetPortion() &&
    1502           0 :                               pPor->GetPortion()->IsPostItsPortion() ) )
    1503           8 :                          && ( bRightAllowed || !bLastHyph ))
    1504           4 :                     ++nCurrStart;
    1505             : 
    1506             :                 // if we want to get the position inside the field, we should not return
    1507           8 :                 if ( !pCMS || !pCMS->pSpecialPos )
    1508           6 :                     return nCurrStart;
    1509             :             }
    1510             :         }
    1511             :         else
    1512             :         {
    1513           0 :             if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
    1514           0 :                  pPor->InToxRefGrp() )
    1515           0 :                 return nCurrStart;
    1516           0 :             if ( pPor->InFldGrp() )
    1517             :             {
    1518           0 :                 if( bRightOver && !((SwFldPortion*)pPor)->HasFollow() )
    1519           0 :                     ++nCurrStart;
    1520           0 :                 return nCurrStart;
    1521             :             }
    1522             :         }
    1523             :     }
    1524             : 
    1525             :     // Skip space at the end of the line
    1526         440 :     if( bLastPortion && (pCurr->GetNext() || pFrm->GetFollow() )
    1527         224 :         && rText[nCurrStart + nLength - 1] == ' ' )
    1528           0 :         --nLength;
    1529             : 
    1530         448 :     if( nWidth > nX ||
    1531         320 :       ( nWidth == nX && pPor->IsMultiPortion() && ((SwMultiPortion*)pPor)->IsDouble() ) )
    1532             :     {
    1533          64 :         if( pPor->IsMultiPortion() )
    1534             :         {
    1535             :             // In a multi-portion we use GetCrsrOfst()-function recursively
    1536           0 :             SwTwips nTmpY = rPoint.Y() - pCurr->GetAscent() + pPor->GetAscent();
    1537             :             // if we are in the first line of a double line portion, we have
    1538             :             // to add a value to nTmpY for not staying in this line
    1539             :             // we also want to skip the first line, if we are inside ruby
    1540           0 :             if ( ( ((SwTxtSizeInfo*)pInf)->IsMulti() &&
    1541           0 :                    ((SwTxtSizeInfo*)pInf)->IsFirstMulti() ) ||
    1542           0 :                  ( ((SwMultiPortion*)pPor)->IsRuby() &&
    1543           0 :                    ((SwMultiPortion*)pPor)->OnTop() ) )
    1544           0 :                 nTmpY += ((SwMultiPortion*)pPor)->Height();
    1545             : 
    1546             :             // Important for cursor traveling in ruby portions:
    1547             :             // We have to set nTmpY to 0 in order to stay in the first row
    1548             :             // if the phonetic line is the second row
    1549           0 :             if (   ((SwMultiPortion*)pPor)->IsRuby() &&
    1550           0 :                  ! ((SwMultiPortion*)pPor)->OnTop() )
    1551           0 :                 nTmpY = 0;
    1552             : 
    1553             :             SwTxtCursorSave aSave( (SwTxtCursor*)this, (SwMultiPortion*)pPor,
    1554           0 :                  nTmpY, nX, nCurrStart, nSpaceAdd );
    1555             : 
    1556           0 :             SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
    1557           0 :             if ( ((SwMultiPortion*)pPor)->IsBidi() )
    1558             :             {
    1559           0 :                 const sal_uInt8 nBidiLevel = ((SwBidiPortion*)pPor)->GetLevel();
    1560           0 :                 aLayoutModeModifier.Modify( nBidiLevel % 2 );
    1561             :             }
    1562             : 
    1563           0 :             if( ((SwMultiPortion*)pPor)->HasRotation() )
    1564             :             {
    1565           0 :                 nTmpY -= nY;
    1566           0 :                 if( !((SwMultiPortion*)pPor)->IsRevers() )
    1567           0 :                     nTmpY = pPor->Height() - nTmpY;
    1568           0 :                 if( nTmpY < 0 )
    1569           0 :                     nTmpY = 0;
    1570           0 :                 nX = (sal_uInt16)nTmpY;
    1571             :             }
    1572             : 
    1573           0 :             if( ((SwMultiPortion*)pPor)->HasBrackets() )
    1574             :             {
    1575           0 :                 const sal_uInt16 nPreWidth = ((SwDoubleLinePortion*)pPor)->PreWidth();
    1576           0 :                 if ( nX > nPreWidth )
    1577           0 :                     nX = nX - nPreWidth;
    1578             :                 else
    1579           0 :                     nX = 0;
    1580             :             }
    1581             : 
    1582           0 :             return GetCrsrOfst( pPos, Point( GetLineStart() + nX, rPoint.Y() ),
    1583           0 :                                 nChgNode, pCMS );
    1584             :         }
    1585          64 :         if( pPor->InTxtGrp() )
    1586             :         {
    1587             :             sal_uInt8 nOldProp;
    1588           6 :             if( GetPropFont() )
    1589             :             {
    1590           0 :                 ((SwFont*)GetFnt())->SetProportion( GetPropFont() );
    1591           0 :                 nOldProp = GetFnt()->GetPropr();
    1592             :             }
    1593             :             else
    1594           6 :                 nOldProp = 0;
    1595             :             {
    1596           6 :                 SwTxtSizeInfo aSizeInf( GetInfo(), &rText, nCurrStart );
    1597           6 :                 ((SwTxtCursor*)this)->SeekAndChg( aSizeInf );
    1598          12 :                 SwTxtSlot aDiffTxt( &aSizeInf, ((SwTxtPortion*)pPor), false, false );
    1599           6 :                 SwFontSave aSave( aSizeInf, pPor->IsDropPortion() ?
    1600          12 :                         ((SwDropPortion*)pPor)->GetFnt() : NULL );
    1601             : 
    1602           6 :                 SwParaPortion* pPara = (SwParaPortion*)GetInfo().GetParaPortion();
    1603             :                 OSL_ENSURE( pPara, "No paragraph!" );
    1604             : 
    1605           6 :                 SwDrawTextInfo aDrawInf( aSizeInf.GetVsh(),
    1606           6 :                                          *aSizeInf.GetOut(),
    1607           6 :                                          &pPara->GetScriptInfo(),
    1608           6 :                                          aSizeInf.GetTxt(),
    1609             :                                          aSizeInf.GetIdx(),
    1610          18 :                                          pPor->GetLen() );
    1611             : 
    1612             :                 // Drop portion works like a multi portion, just its parts are not portions
    1613           6 :                 if( pPor->IsDropPortion() && static_cast<SwDropPortion*>(pPor)->GetLines() > 1 )
    1614             :                 {
    1615           0 :                     SwDropPortion* pDrop = static_cast<SwDropPortion*>(pPor);
    1616           0 :                     const SwDropPortionPart* pCurrPart = pDrop->GetPart();
    1617           0 :                     sal_uInt16 nSumWidth = 0;
    1618           0 :                     sal_uInt16 nSumBorderWidth = 0;
    1619             :                     // Shift offset with the right and left border of previous parts and left border of actual one
    1620           0 :                     while( pCurrPart && nSumWidth <= nX - nCurrStart )
    1621             :                     {
    1622           0 :                         nSumWidth += pCurrPart->GetWidth();
    1623           0 :                         if( pCurrPart->GetFont().GetLeftBorder() && !pCurrPart->GetJoinBorderWithPrev() )
    1624             :                         {
    1625           0 :                             nSumBorderWidth += pCurrPart->GetFont().GetLeftBorderSpace();
    1626             :                         }
    1627           0 :                         if( nSumWidth <= nX - nCurrStart && pCurrPart->GetFont().GetRightBorder() &&
    1628           0 :                             !pCurrPart->GetJoinBorderWithNext() )
    1629             :                         {
    1630           0 :                             nSumBorderWidth += pCurrPart->GetFont().GetRightBorderSpace();
    1631             :                         }
    1632           0 :                         pCurrPart = pCurrPart->GetFollow();
    1633             :                     }
    1634           0 :                     nX = std::max(0, nX - nSumBorderWidth);
    1635             :                 }
    1636             :                 // Shift the offset with the left border width
    1637           6 :                 else if( GetInfo().GetFont()->GetLeftBorder() && !pPor->GetJoinBorderWithPrev() )
    1638             :                 {
    1639           0 :                     nX = std::max(0, nX - GetInfo().GetFont()->GetLeftBorderSpace());
    1640             :                 }
    1641             : 
    1642           6 :                 aDrawInf.SetOfst( nX );
    1643             : 
    1644           6 :                 if ( nSpaceAdd )
    1645             :                 {
    1646           0 :                     sal_Int32 nCharCnt = 0;
    1647             :                     // #i41860# Thai justified alignemt needs some
    1648             :                     // additional information:
    1649           0 :                     aDrawInf.SetNumberOfBlanks( pPor->InTxtGrp() ?
    1650             :                                                 static_cast<const SwTxtPortion*>(pPor)->GetSpaceCnt( aSizeInf, nCharCnt ) :
    1651           0 :                                                 0 );
    1652             :                 }
    1653             : 
    1654           6 :                 if ( pPor->InFldGrp() && pCMS && pCMS->pSpecialPos )
    1655           2 :                     aDrawInf.SetLen( COMPLETE_STRING );
    1656             : 
    1657           6 :                 aDrawInf.SetSpace( nSpaceAdd );
    1658           6 :                 aDrawInf.SetFont( aSizeInf.GetFont() );
    1659           6 :                 aDrawInf.SetFrm( pFrm );
    1660           6 :                 aDrawInf.SetSnapToGrid( aSizeInf.SnapToGrid() );
    1661           6 :                 aDrawInf.SetPosMatchesBounds( pCMS && pCMS->bPosMatchesBounds );
    1662             : 
    1663          12 :                 if ( SW_CJK == aSizeInf.GetFont()->GetActual() &&
    1664           6 :                      pPara->GetScriptInfo().CountCompChg() &&
    1665           0 :                     ! pPor->InFldGrp() )
    1666           0 :                     aDrawInf.SetKanaComp( nKanaComp );
    1667             : 
    1668           6 :                 nLength = aSizeInf.GetFont()->_GetCrsrOfst( aDrawInf );
    1669             : 
    1670             :                 // get position inside field portion?
    1671           6 :                 if ( pPor->InFldGrp() && pCMS && pCMS->pSpecialPos )
    1672             :                 {
    1673           2 :                     pCMS->pSpecialPos->nCharOfst = nLength;
    1674           2 :                     nLength = 0;
    1675             :                 }
    1676             : 
    1677             :                 // set cursor bidi level
    1678           6 :                 if ( pCMS )
    1679             :                     ((SwCrsrMoveState*)pCMS)->nCursorBidiLevel =
    1680           6 :                         aDrawInf.GetCursorBidiLevel();
    1681             : 
    1682           6 :                 if( bFieldInfo && nLength == pPor->GetLen() &&
    1683           0 :                     ( ! pPor->GetPortion() ||
    1684           0 :                       ! pPor->GetPortion()->IsPostItsPortion() ) )
    1685           6 :                     --nLength;
    1686             :             }
    1687           6 :             if( nOldProp )
    1688           0 :                 ((SwFont*)GetFnt())->SetProportion( nOldProp );
    1689             :         }
    1690             :         else
    1691             :         {
    1692         116 :             if( nChgNode && pPos && pPor->IsFlyCntPortion()
    1693         116 :                 && !( (SwFlyCntPortion*)pPor )->IsDraw() )
    1694             :             {
    1695             :                 // JP 24.11.94: if the Position is not in Fly, then
    1696             :                 //              we many not return with COMPLETE_STRING as value!
    1697             :                 //              (BugId: 9692 + Change in feshview)
    1698           0 :                 SwFlyInCntFrm *pTmp = ( (SwFlyCntPortion*)pPor )->GetFlyFrm();
    1699           0 :                 SwFrm* pLower = pTmp->GetLower();
    1700             :                 bool bChgNode = pLower
    1701           0 :                     && (pLower->IsTxtFrm() || pLower->IsLayoutFrm());
    1702           0 :                 Point aTmpPoint( rPoint );
    1703             : 
    1704           0 :                 if ( pFrm->IsRightToLeft() )
    1705           0 :                     pFrm->SwitchLTRtoRTL( aTmpPoint );
    1706             : 
    1707           0 :                 if ( pFrm->IsVertical() )
    1708           0 :                     pFrm->SwitchHorizontalToVertical( aTmpPoint );
    1709             : 
    1710           0 :                 if( bChgNode && pTmp->Frm().IsInside( aTmpPoint ) &&
    1711           0 :                     !( pTmp->IsProtected() ) )
    1712             :                 {
    1713             :                     nLength = ((SwFlyCntPortion*)pPor)->
    1714           0 :                               GetFlyCrsrOfst( nX, aTmpPoint, pPos, pCMS );
    1715             :                     // After a change of the frame, our font must be still
    1716             :                     // available for/in the OutputDevice.
    1717             :                     // For comparison: Paint and new SwFlyCntPortion !
    1718           0 :                     ((SwTxtSizeInfo*)pInf)->SelectFont();
    1719             : 
    1720             :                     // 6776: The pIter->GetCrsrOfst is returning here
    1721             :                     // from a nesting with COMPLETE_STRING.
    1722           0 :                     return COMPLETE_STRING;
    1723             :                 }
    1724             :             }
    1725             :             else
    1726          58 :                 nLength = pPor->GetCrsrOfst( nX );
    1727             :         }
    1728             :     }
    1729         224 :     nOffset = nCurrStart + nLength;
    1730             : 
    1731             :     // 7684: We end up in front of the HyphPortion. We must assure
    1732             :     // that we end up in the string.
    1733             :     // If we are at end of line in front of FlyFrms, we must proceed the same way.
    1734         440 :     if( nOffset && pPor->GetLen() == nLength && pPor->GetPortion() &&
    1735         224 :         !pPor->GetPortion()->GetLen() && pPor->GetPortion()->InHyphGrp() )
    1736           0 :         --nOffset;
    1737             : 
    1738         224 :     return nOffset;
    1739             : }
    1740             : 
    1741             : /** Looks for text portions which are inside the given rectangle
    1742             : 
    1743             :     For a rectangular text selection every text portions which is inside the given
    1744             :     rectangle has to be put into the SwSelectionList as SwPaM
    1745             :     From these SwPaM the SwCursors will be created.
    1746             : 
    1747             :     @param rSelList
    1748             :     The container for the overlapped text portions
    1749             : 
    1750             :     @param rRect
    1751             :     A rectangle in document coordinates, text inside this rectangle has to be
    1752             :     selected.
    1753             : 
    1754             :     @return [ true, false ]
    1755             :     true if any overlapping text portion has been found and put into list
    1756             :     false if no portion overlaps, the list has been unchanged
    1757             : */
    1758           0 : bool SwTxtFrm::FillSelection( SwSelectionList& rSelList, const SwRect& rRect ) const
    1759             : {
    1760           0 :     bool bRet = false;
    1761             :     // PaintArea() instead Frm() for negative indents
    1762           0 :     SwRect aTmpFrm( PaintArea() );
    1763           0 :     if( !rRect.IsOver( aTmpFrm ) )
    1764           0 :         return false;
    1765           0 :     if( rSelList.checkContext( this ) )
    1766             :     {
    1767           0 :         SwRect aRect( aTmpFrm );
    1768           0 :         aRect.Intersection( rRect );
    1769             :         // rNode without const to create SwPaMs
    1770           0 :         SwCntntNode &rNode = const_cast<SwCntntNode&>( *GetNode() );
    1771           0 :         SwNodeIndex aIdx( rNode );
    1772           0 :         SwPosition aPosL( aIdx, SwIndex( &rNode, 0 ) );
    1773           0 :         if( IsEmpty() )
    1774             :         {
    1775           0 :             SwPaM *pPam = new SwPaM( aPosL, aPosL );
    1776           0 :             rSelList.insertPaM( pPam );
    1777             :         }
    1778           0 :         else if( aRect.HasArea() )
    1779             :         {
    1780           0 :             sal_Int32 nOld = -1;
    1781           0 :             SwPosition aPosR( aPosL );
    1782           0 :             Point aPoint;
    1783           0 :             SwTxtInfo aInf( const_cast<SwTxtFrm*>(this) );
    1784           0 :             SwTxtIter aLine( const_cast<SwTxtFrm*>(this), &aInf );
    1785             :             // We have to care for top-to-bottom layout, where right becomes top etc.
    1786           0 :             SWRECTFN( this )
    1787           0 :             SwTwips nTop = (aRect.*fnRect->fnGetTop)();
    1788           0 :             SwTwips nBottom = (aRect.*fnRect->fnGetBottom)();
    1789           0 :             SwTwips nLeft = (aRect.*fnRect->fnGetLeft)();
    1790           0 :             SwTwips nRight = (aRect.*fnRect->fnGetRight)();
    1791           0 :             SwTwips nY = aLine.Y(); // Top position of the first line
    1792           0 :             SwTwips nLastY = nY;
    1793           0 :             while( nY < nTop && aLine.Next() ) // line above rectangle
    1794             :             {
    1795           0 :                 nLastY = nY;
    1796           0 :                 nY = aLine.Y();
    1797             :             }
    1798           0 :             bool bLastLine = false;
    1799           0 :             if( nY < nTop && !aLine.GetNext() )
    1800             :             {
    1801           0 :                 bLastLine = true;
    1802           0 :                 nY += aLine.GetLineHeight();
    1803             :             }
    1804           0 :             do // check the lines for overlapping
    1805             :             {
    1806           0 :                 if( nLastY < nTop ) // if the last line was above rectangle
    1807           0 :                     nLastY = nTop;
    1808           0 :                 if( nY > nBottom ) // if the current line leaves the rectangle
    1809           0 :                     nY = nBottom;
    1810           0 :                 if( nY >= nLastY ) // gotcha: overlapping
    1811             :                 {
    1812           0 :                     nLastY += nY;
    1813           0 :                     nLastY /= 2;
    1814           0 :                     if( bVert )
    1815             :                     {
    1816           0 :                         aPoint.X() = nLastY;
    1817           0 :                         aPoint.Y() = nLeft;
    1818             :                     }
    1819             :                     else
    1820             :                     {
    1821           0 :                         aPoint.X() = nLeft;
    1822           0 :                         aPoint.Y() = nLastY;
    1823             :                     }
    1824             :                     // Looking for the position of the left border of the rectangle
    1825             :                     // in this text line
    1826           0 :                     SwCrsrMoveState aState( MV_UPDOWN );
    1827           0 :                     if( GetCrsrOfst( &aPosL, aPoint, &aState ) )
    1828             :                     {
    1829           0 :                         if( bVert )
    1830             :                         {
    1831           0 :                             aPoint.X() = nLastY;
    1832           0 :                             aPoint.Y() = nRight;
    1833             :                         }
    1834             :                         else
    1835             :                         {
    1836           0 :                             aPoint.X() = nRight;
    1837           0 :                             aPoint.Y() = nLastY;
    1838             :                         }
    1839             :                         // If we get a right position and if the left position
    1840             :                         // is not the same like the left position of the line before
    1841             :                         // which cound happen e.g. for field portions or fly frames
    1842             :                         // a SwPaM will be inserted with these positions
    1843           0 :                         if( GetCrsrOfst( &aPosR, aPoint, &aState ) &&
    1844           0 :                             nOld != aPosL.nContent.GetIndex() )
    1845             :                         {
    1846           0 :                             SwPaM *pPam = new SwPaM( aPosL, aPosR );
    1847           0 :                             rSelList.insertPaM( pPam );
    1848           0 :                             nOld = aPosL.nContent.GetIndex();
    1849             :                         }
    1850             :                     }
    1851             :                 }
    1852           0 :                 if( aLine.Next() )
    1853             :                 {
    1854           0 :                     nLastY = nY;
    1855           0 :                     nY = aLine.Y();
    1856             :                 }
    1857           0 :                 else if( !bLastLine )
    1858             :                 {
    1859           0 :                     bLastLine = true;
    1860           0 :                     nLastY = nY;
    1861           0 :                     nY += aLine.GetLineHeight();
    1862             :                 }
    1863             :                 else
    1864           0 :                     break;
    1865           0 :             }while( nLastY < nBottom );
    1866           0 :         }
    1867             :     }
    1868           0 :     if( GetDrawObjs() )
    1869             :     {
    1870           0 :         const SwSortedObjs &rObjs = *GetDrawObjs();
    1871           0 :         for ( size_t i = 0; i < rObjs.size(); ++i )
    1872             :         {
    1873           0 :             const SwAnchoredObject* pAnchoredObj = rObjs[i];
    1874           0 :             if( !pAnchoredObj->ISA(SwFlyFrm) )
    1875           0 :                 continue;
    1876           0 :             const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj);
    1877           0 :             if( pFly->IsFlyInCntFrm() && pFly->FillSelection( rSelList, rRect ) )
    1878           0 :                 bRet = true;
    1879             :         }
    1880             :     }
    1881           0 :     return bRet;
    1882         270 : }
    1883             : 
    1884             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10