LCOV - code coverage report
Current view: top level - sw/source/core/text - itrcrsr.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 464 969 47.9 %
Date: 2015-06-13 12:38:46 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 SwTextCursor::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( SwTextSizeInfo& 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.InFieldGrp() && !static_cast<const SwFieldPortion&>(rPor).GetExp().isEmpty() )
      64             :     {
      65           0 :         const sal_Int32 nCharOfst = rCMS.pSpecialPos->nCharOfst;
      66           0 :         sal_Int32 nFieldIdx = 0;
      67           0 :         sal_Int32 nFieldLen = 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->InFieldGrp() )
      75             :             {
      76           0 :                 sString = static_cast<const SwFieldPortion*>(pPor)->GetExp();
      77           0 :                 pString = &sString;
      78           0 :                 nFieldLen = pString->getLength();
      79             :             }
      80             :             else
      81             :             {
      82           0 :                 pString = 0;
      83           0 :                 nFieldLen = 0;
      84             :             }
      85             : 
      86           0 :             if ( ! pPor->GetPortion() || nFieldIdx + nFieldLen > nCharOfst )
      87           0 :                 break;
      88             : 
      89           0 :             nFieldIdx = nFieldIdx + nFieldLen;
      90           0 :             rOrig.Pos().X() += pPor->Width();
      91           0 :             pPor = pPor->GetPortion();
      92             : 
      93             :         } while ( true );
      94             : 
      95             :         OSL_ENSURE( nCharOfst >= nFieldIdx, "Request of position inside field failed" );
      96           0 :         sal_Int32 nLen = nCharOfst - nFieldIdx + 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 :             const_cast<SwLinePortion*>(pPor)->SetLen( nLen - 1 );
     105           0 :             const SwTwips nX1 = pPor->GetLen() ?
     106           0 :                                 pPor->GetTextSize( rInf ).Width() :
     107           0 :                                 0;
     108             : 
     109           0 :             SwTwips nX2 = 0;
     110           0 :             if ( rCMS.bRealWidth )
     111             :             {
     112           0 :                 const_cast<SwLinePortion*>(pPor)->SetLen( nLen );
     113           0 :                 nX2 = pPor->GetTextSize( rInf ).Width();
     114             :             }
     115             : 
     116           0 :             const_cast<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      184321 :     bool AreListLevelIndentsApplicableAndLabelAlignmentActive( const SwTextNode& rTextNode )
     135             :     {
     136      184321 :         bool bRet( false );
     137             : 
     138      184321 :         if ( rTextNode.GetNumRule() && rTextNode.AreListLevelIndentsApplicable() )
     139             :         {
     140        9981 :             int nListLevel = rTextNode.GetActualListLevel();
     141             : 
     142        9981 :             if (nListLevel < 0)
     143           0 :                 nListLevel = 0;
     144             : 
     145        9981 :             if (nListLevel >= MAXLEVEL)
     146           0 :                 nListLevel = MAXLEVEL - 1;
     147             : 
     148             :             const SwNumFormat& rNumFormat =
     149        9981 :                     rTextNode.GetNumRule()->Get( static_cast<sal_uInt16>(nListLevel) );
     150        9981 :             if ( rNumFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
     151             :             {
     152        8742 :                 bRet = true;
     153             :             }
     154             :         }
     155             : 
     156      184321 :         return bRet;
     157             :     }
     158             : } // end of anonymous namespace
     159             : 
     160      184321 : void SwTextMargin::CtorInitTextMargin( SwTextFrm *pNewFrm, SwTextSizeInfo *pNewInf )
     161             : {
     162      184321 :     CtorInitTextIter( pNewFrm, pNewInf );
     163             : 
     164      184321 :     pInf = pNewInf;
     165      184321 :     GetInfo().SetFont( GetFnt() );
     166      184321 :     const SwTextNode *pNode = pFrm->GetTextNode();
     167             : 
     168      184321 :     const SvxLRSpaceItem &rSpace = pFrm->GetTextNode()->GetSwAttrSet().GetLRSpace();
     169             :     // #i95907#
     170             :     // #i111284#
     171             :     const bool bListLevelIndentsApplicableAndLabelAlignmentActive(
     172      184321 :         AreListLevelIndentsApplicableAndLabelAlignmentActive( *(pFrm->GetTextNode()) ) );
     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      184321 :     const int nLMWithNum = pNode->GetLeftMarginWithNum( true );
     186      184321 :     if ( pFrm->IsRightToLeft() )
     187             :     {
     188             :         // this calculation is identical this the calculation for L2R layout - see below
     189         592 :         nLeft = pFrm->Frm().Left() +
     190         592 :                 pFrm->Prt().Left() +
     191         296 :                 nLMWithNum -
     192         888 :                 pNode->GetLeftMarginWithNum() -
     193             :                 // #i95907#
     194             :                 // #i111284#
     195             :                 // rSpace.GetLeft() + rSpace.GetTextLeft();
     196             :                 ( bListLevelIndentsApplicableAndLabelAlignmentActive
     197             :                   ? 0
     198         592 :                   : ( rSpace.GetLeft() - rSpace.GetTextLeft() ) );
     199             :     }
     200             :     else
     201             :     {
     202             :         // #i95907#
     203             :         // #i111284#
     204      359308 :         if ( bListLevelIndentsApplicableAndLabelAlignmentActive ||
     205      175283 :              !pNode->getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
     206             :         {
     207             :             // this calculation is identical this the calculation for R2L layout - see above
     208      366556 :             nLeft = pFrm->Frm().Left() +
     209      366556 :                     pFrm->Prt().Left() +
     210      183278 :                     nLMWithNum -
     211      541092 :                     pNode->GetLeftMarginWithNum() -
     212             :                     // #i95907#
     213             :                     // #i111284#
     214             :                     ( bListLevelIndentsApplicableAndLabelAlignmentActive
     215             :                       ? 0
     216      357814 :                       : ( rSpace.GetLeft() - rSpace.GetTextLeft() ) );
     217             :         }
     218             :         else
     219             :         {
     220        1494 :             nLeft = pFrm->Frm().Left() +
     221         747 :                     std::max( long( rSpace.GetTextLeft() + nLMWithNum ),
     222        2241 :                          pFrm->Prt().Left() );
     223             :         }
     224             :     }
     225             : 
     226      184321 :     nRight = pFrm->Frm().Left() + pFrm->Prt().Left() + pFrm->Prt().Width();
     227             : 
     228      184601 :     if( nLeft >= nRight &&
     229             :          // #i53066# Omit adjustment of nLeft for numbered
     230             :          // paras inside cells inside new documents:
     231         271 :         ( pNode->getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) ||
     232         196 :           !pFrm->IsInTab() ||
     233             :           !nLMWithNum ) )
     234             :     {
     235         140 :         nLeft = pFrm->Prt().Left() + pFrm->Frm().Left();
     236         140 :         if( nLeft >= nRight )   // e.g. with large paragraph indentations in slim table columns
     237          49 :             nRight = nLeft + 1; // einen goennen wir uns immer
     238             :     }
     239             : 
     240      184321 :     if( pFrm->IsFollow() && pFrm->GetOfst() )
     241       15718 :         nFirst = nLeft;
     242             :     else
     243             :     {
     244      168603 :         short nFLOfst = 0;
     245      168603 :         long nFirstLineOfs = 0;
     246      322588 :         if( !pNode->GetFirstLineOfsWithNum( nFLOfst ) &&
     247      153985 :             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      168603 :             nFirstLineOfs = nFLOfst;
     298             : 
     299             :         // #i95907#
     300             :         // #i111284#
     301      505513 :         if ( pFrm->IsRightToLeft() ||
     302      328223 :              bListLevelIndentsApplicableAndLabelAlignmentActive ||
     303      159620 :              !pNode->getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
     304             :         {
     305      167966 :             nFirst = nLeft + nFirstLineOfs;
     306             :         }
     307             :         else
     308             :         {
     309        1274 :               nFirst = pFrm->Frm().Left() +
     310         637 :                      std::max( rSpace.GetTextLeft() + nLMWithNum+ nFirstLineOfs,
     311        1911 :                           pFrm->Prt().Left() );
     312             :         }
     313             : 
     314             :         // Note: <SwTextFrm::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      168603 :         nFirst += pFrm->GetAdditionalFirstLineOffset();
     319             : 
     320      168603 :         if( nFirst >= nRight )
     321          64 :             nFirst = nRight - 1;
     322             :     }
     323      184321 :     const SvxAdjustItem& rAdjust = pFrm->GetTextNode()->GetSwAttrSet().GetAdjust();
     324      184321 :     nAdjust = static_cast<sal_uInt16>(rAdjust.GetAdjust());
     325             : 
     326             :     // left is left and right is right
     327      184321 :     if ( pFrm->IsRightToLeft() )
     328             :     {
     329         296 :         if ( SVX_ADJUST_LEFT == nAdjust )
     330         137 :             nAdjust = SVX_ADJUST_RIGHT;
     331         159 :         else if ( SVX_ADJUST_RIGHT == nAdjust )
     332         102 :             nAdjust = SVX_ADJUST_LEFT;
     333             :     }
     334             : 
     335      184321 :     bOneBlock = rAdjust.GetOneWord() == SVX_ADJUST_BLOCK;
     336      184321 :     bLastBlock = rAdjust.GetLastBlock() == SVX_ADJUST_BLOCK;
     337      184321 :     bLastCenter = rAdjust.GetLastBlock() == SVX_ADJUST_CENTER;
     338             : 
     339             :     // #i91133#
     340      184321 :     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      184321 :     DropInit();
     351      184321 : }
     352             : 
     353      184327 : void SwTextMargin::DropInit()
     354             : {
     355      184327 :     nDropLeft = nDropLines = nDropHeight = nDropDescent = 0;
     356      184327 :     const SwParaPortion *pPara = GetInfo().GetParaPortion();
     357      184327 :     if( pPara )
     358             :     {
     359      184327 :         const SwDropPortion *pPorDrop = pPara->FindDropPortion();
     360      184327 :         if ( pPorDrop )
     361             :         {
     362          78 :             nDropLeft = pPorDrop->GetDropLeft();
     363          78 :             nDropLines = pPorDrop->GetLines();
     364          78 :             nDropHeight = pPorDrop->GetDropHeight();
     365          78 :             nDropDescent = pPorDrop->GetDropDescent();
     366             :         }
     367             :     }
     368      184327 : }
     369             : 
     370             : // The function is interpreting / observing / evaluating / keeping / respecting the first line indention and the specified width.
     371      145097 : SwTwips SwTextMargin::GetLineStart() const
     372             : {
     373      145097 :     SwTwips nRet = GetLeftMargin();
     374      167480 :     if( GetAdjust() != SVX_ADJUST_LEFT &&
     375       22383 :         !pCurr->GetFirstPortion()->IsMarginPortion() )
     376             :     {
     377             :         // If the first portion is a Margin, then the
     378             :         // adjustment is expressed by the portions.
     379       17979 :         if( GetAdjust() == SVX_ADJUST_RIGHT )
     380        1308 :             nRet = Right() - CurrWidth();
     381       16671 :         else if( GetAdjust() == SVX_ADJUST_CENTER )
     382        5454 :             nRet += (GetLineWidth() - CurrWidth()) / 2;
     383             :     }
     384      145097 :     return nRet;
     385             : }
     386             : 
     387      138248 : void SwTextCursor::CtorInitTextCursor( SwTextFrm *pNewFrm, SwTextSizeInfo *pNewInf )
     388             : {
     389      138248 :     CtorInitTextMargin( pNewFrm, pNewInf );
     390             :     // 6096: Attention, the iterators are derived!
     391             :     // GetInfo().SetOut( GetInfo().GetWin() );
     392      138248 : }
     393             : 
     394             : // 1170: Ancient bug: Shift-End forgets the last character ...
     395           0 : bool SwTextCursor::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().GetText().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->InTextGrp() || ( 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 SwTextCursor::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       69216 : void SwTextCursor::_GetCharRect( SwRect* pOrig, const sal_Int32 nOfst,
     470             :     SwCrsrMoveState* pCMS )
     471             : {
     472       69216 :     const OUString aText = GetInfo().GetText();
     473      138267 :     SwTextSizeInfo aInf( GetInfo(), &aText, nStart );
     474       69216 :     if( GetPropFont() )
     475          17 :         aInf.GetFont()->SetProportion( GetPropFont() );
     476             :     sal_uInt16 nTmpAscent, nTmpHeight;  // Line height
     477       69216 :     CalcAscentAndHeight( nTmpAscent, nTmpHeight );
     478       69216 :     const Size  aCharSize( 1, nTmpHeight );
     479       69216 :     const Point aCharPos;
     480       69216 :     pOrig->Pos( aCharPos );
     481       69216 :     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       69216 :     const bool bInsideFirstField = pCMS && pCMS->pSpecialPos &&
     487           0 :                                     ( pCMS->pSpecialPos->nLineOfst ||
     488           0 :                                       SwSPExtendRange::BEFORE ==
     489       69216 :                                       pCMS->pSpecialPos->nExtendRange );
     490             : 
     491       69216 :     bool bWidth = pCMS && pCMS->bRealWidth;
     492       69216 :     if( !pCurr->GetLen() && !pCurr->Width() )
     493             :     {
     494        7255 :         if ( pCMS && pCMS->bRealHeight )
     495             :         {
     496        7231 :             pCMS->aRealHeight.X() = 0;
     497        7231 :             pCMS->aRealHeight.Y() = nTmpHeight;
     498             :         }
     499             :     }
     500             :     else
     501             :     {
     502       61961 :         sal_uInt16 nPorHeight = nTmpHeight;
     503       61961 :         sal_uInt16 nPorAscent = nTmpAscent;
     504       61961 :         SwTwips nX = 0;
     505       61961 :         SwTwips nTmpFirst = 0;
     506       61961 :         SwLinePortion *pPor = pCurr->GetFirstPortion();
     507       61961 :         SwBidiPortion* pLastBidiPor = 0;
     508       61961 :         SwTwips nLastBidiPorWidth = 0;
     509       61961 :         std::deque<sal_uInt16>* pKanaComp = pCurr->GetpKanaComp();
     510       61961 :         sal_uInt16 nSpaceIdx = 0;
     511       61961 :         size_t nKanaIdx = 0;
     512       61961 :         long nSpaceAdd = pCurr->IsSpaceAdd() ? pCurr->GetLLSpaceAdd( 0 ) : 0;
     513             : 
     514       61961 :         bool bNoText = 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, FootnoteNum, FeldReste
     519             :         // 8477: but also the only Textportion of an empty line with
     520             :         // Right/Center-Adjustment! So not just pPor->GetExpandPortion() ...
     521      135882 :         while( pPor && !pPor->GetLen() && ! bInsideFirstField )
     522             :         {
     523       11960 :             nX += pPor->Width();
     524       11960 :             if ( pPor->InSpaceGrp() && nSpaceAdd )
     525           0 :                 nX += pPor->CalcSpacing( nSpaceAdd, aInf );
     526       11960 :             if( bNoText )
     527        6374 :                 nTmpFirst = nX;
     528             :             // 8670: EndPortions count once as TextPortions.
     529             :             // if( pPor->InTextGrp() || pPor->IsBreakPortion() )
     530       11960 :             if( pPor->InTextGrp() || pPor->IsBreakPortion() || pPor->InTabGrp() )
     531             :             {
     532        7413 :                 bNoText = false;
     533        7413 :                 nTmpFirst = nX;
     534             :             }
     535       11960 :             if( pPor->IsMultiPortion() && static_cast<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       11960 :             if( pPor->InFixMargGrp() )
     549             :             {
     550        7089 :                 if( pPor->IsMarginPortion() )
     551        3792 :                     bNoText = false;
     552             :                 else
     553             :                 {
     554             :                     // fix margin portion => next SpaceAdd, KanaComp value
     555        3297 :                     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        3297 :                     if( pKanaComp && ( nKanaIdx + 1 ) < pKanaComp->size() )
     564           0 :                         ++nKanaIdx;
     565             :                 }
     566             :             }
     567       11960 :             pPor = pPor->GetPortion();
     568             :         }
     569             : 
     570       61961 :         if( !pPor )
     571             :         {
     572             :             // There's just Spezialportions.
     573        1326 :             nX = nTmpFirst;
     574             :         }
     575             :         else
     576             :         {
     577      181397 :             if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
     578       61055 :                 (!pPor->InFieldGrp() || pPor->GetAscent() ) )
     579             :             {
     580       60381 :                 nPorHeight = pPor->Height();
     581       60381 :                 nPorAscent = pPor->GetAscent();
     582             :             }
     583      182285 :             while( pPor && !pPor->IsBreakPortion() && ( aInf.GetIdx() < nOfst ||
     584           0 :                    ( bWidth && ( pPor->IsKernPortion() || pPor->IsMultiPortion() ) ) ) )
     585             :             {
     586       92231 :                 if( !pPor->IsMarginPortion() && !pPor->IsPostItsPortion() &&
     587       31544 :                     (!pPor->InFieldGrp() || pPor->GetAscent() ) )
     588             :                 {
     589       30239 :                     nPorHeight = pPor->Height();
     590       30239 :                     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       32331 :                 const sal_Int32 nExtra = pPor->IsMultiPortion() &&
     599         578 :                                     ! static_cast<SwMultiPortion*>(pPor)->IsBidi() &&
     600       32331 :                                     ! bWidth ? 0 : 1;
     601       31753 :                 if ( aInf.GetIdx() + pPor->GetLen() < nOfst + nExtra )
     602             :                 {
     603       29262 :                     if ( pPor->InSpaceGrp() && nSpaceAdd )
     604           0 :                         nX += pPor->PrtWidth() +
     605           0 :                               pPor->CalcSpacing( nSpaceAdd, aInf );
     606             :                     else
     607             :                     {
     608       29262 :                         if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
     609             :                         {
     610             :                             // update to current SpaceAdd, KanaComp values
     611           6 :                             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           6 :                             if ( pKanaComp &&
     620           0 :                                 ( nKanaIdx + 1 ) < pKanaComp->size()
     621             :                                 )
     622           0 :                                 ++nKanaIdx;
     623             :                         }
     624       29262 :                         if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
     625           0 :                                 !pPor->GetPortion()->IsMarginPortion() ) )
     626       29262 :                             nX += pPor->PrtWidth();
     627             :                     }
     628       29262 :                     if( pPor->IsMultiPortion() )
     629             :                     {
     630         413 :                         if ( static_cast<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         413 :                         if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() &&
     649           0 :                              aInf.GetIdx() + pPor->GetLen() == nOfst )
     650             :                         {
     651           0 :                              pLastBidiPor = static_cast<SwBidiPortion*>(pPor);
     652           0 :                              nLastBidiPorWidth = pLastBidiPor->Width() +
     653           0 :                                                  pLastBidiPor->CalcSpacing( nSpaceAdd, aInf );;
     654             :                         }
     655             :                     }
     656             : 
     657       29262 :                     aInf.SetIdx( aInf.GetIdx() + pPor->GetLen() );
     658       29262 :                     pPor = pPor->GetPortion();
     659             :                 }
     660             :                 else
     661             :                 {
     662        2491 :                     if( pPor->IsMultiPortion() )
     663             :                     {
     664         165 :                         nTmpAscent = AdjustBaseLine( *pCurr, pPor );
     665         165 :                         GetInfo().SetMulti( true );
     666         165 :                         pOrig->Pos().Y() += nTmpAscent - nPorAscent;
     667             : 
     668         165 :                         if( pCMS && pCMS->b2Lines )
     669             :                         {
     670          77 :                             const bool bRecursion = pCMS->p2Lines;
     671          77 :                             if ( !bRecursion )
     672             :                             {
     673          77 :                                 pCMS->p2Lines = new Sw2LinesPos;
     674          77 :                                 pCMS->p2Lines->aLine = SwRect(aCharPos, aCharSize);
     675             :                             }
     676             : 
     677          77 :                             if( static_cast<SwMultiPortion*>(pPor)->HasRotation() )
     678             :                             {
     679           0 :                                 if( static_cast<SwMultiPortion*>(pPor)->IsRevers() )
     680           0 :                                     pCMS->p2Lines->nMultiType = MultiPortionType::ROT_270;
     681             :                                 else
     682           0 :                                     pCMS->p2Lines->nMultiType = MultiPortionType::ROT_90;
     683             :                             }
     684          77 :                             else if( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
     685          17 :                                 pCMS->p2Lines->nMultiType = MultiPortionType::TWOLINE;
     686          60 :                             else if( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
     687           0 :                                 pCMS->p2Lines->nMultiType = MultiPortionType::BIDI;
     688             :                             else
     689          60 :                                 pCMS->p2Lines->nMultiType = MultiPortionType::RUBY;
     690             : 
     691          77 :                             SwTwips nTmpWidth = pPor->Width();
     692          77 :                             if( nSpaceAdd )
     693           0 :                                 nTmpWidth += pPor->CalcSpacing(nSpaceAdd, aInf);
     694             : 
     695          77 :                             SwRect aRect( Point(aCharPos.X() + nX, pOrig->Top() ),
     696         154 :                                           Size( nTmpWidth, pPor->Height() ) );
     697             : 
     698          77 :                             if ( ! bRecursion )
     699          77 :                                 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         165 :                         sal_Int32 nOldStart = nStart;
     708         165 :                         SwTwips nOldY = nY;
     709         165 :                         sal_uInt8 nOldProp = GetPropFont();
     710         165 :                         nStart = aInf.GetIdx();
     711         165 :                         SwLineLayout* pOldCurr = pCurr;
     712         165 :                         pCurr = &static_cast<SwMultiPortion*>(pPor)->GetRoot();
     713         165 :                         if( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
     714          17 :                             SetPropFont( 50 );
     715             : 
     716             :                         SwTextGridItem const*const pGrid(
     717         165 :                                 GetGridItem(GetTextFrm()->FindPageFrm()));
     718         165 :                         const bool bHasGrid = pGrid && GetInfo().SnapToGrid();
     719             :                         const sal_uInt16 nRubyHeight = bHasGrid ?
     720         165 :                                                    pGrid->GetRubyHeight() : 0;
     721             : 
     722         445 :                         if( nStart + pCurr->GetLen() <= nOfst && GetNext() &&
     723         313 :                             ( ! static_cast<SwMultiPortion*>(pPor)->IsRuby() ||
     724         148 :                                 static_cast<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         115 :                             if ( bHasGrid &&
     730         115 :                                 static_cast<SwMultiPortion*>(pPor)->IsRuby() &&
     731           0 :                                 static_cast<SwMultiPortion*>(pPor)->OnTop() )
     732           0 :                                 nOffset = nRubyHeight;
     733             :                             else
     734         115 :                                 nOffset = GetLineHeight();
     735             : 
     736         115 :                             pOrig->Pos().Y() += nOffset;
     737         115 :                             Next();
     738             :                         }
     739             : 
     740             :                         const bool bSpaceChg = static_cast<SwMultiPortion*>(pPor)->
     741         165 :                                                 ChgSpaceAdd( pCurr, nSpaceAdd );
     742         165 :                         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         165 :                         const sal_uInt16 nOldRubyHeight = pCurr->Height();
     749         165 :                         const sal_uInt16 nOldRubyRealHeight = pCurr->GetRealHeight();
     750             :                         const bool bChgHeight =
     751         165 :                                 static_cast<SwMultiPortion*>(pPor)->IsRuby() && bHasGrid;
     752             : 
     753         165 :                         if ( bChgHeight )
     754             :                         {
     755           0 :                             pCurr->Height( pOldCurr->Height() - nRubyHeight );
     756           0 :                             pCurr->SetRealHeight( pOldCurr->GetRealHeight() -
     757           0 :                                                   nRubyHeight );
     758             :                         }
     759             : 
     760         165 :                         SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
     761         165 :                         if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
     762             :                         {
     763             :                             aLayoutModeModifier.Modify(
     764           0 :                                 static_cast<SwBidiPortion*>(pPor)->GetLevel() % 2 );
     765             :                         }
     766             : 
     767         165 :                         _GetCharRect( pOrig, nOfst, pCMS );
     768             : 
     769         165 :                         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         165 :                         if ( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
     779             :                         {
     780             :                             // the recursion may have damaged our font size
     781          17 :                             SetPropFont( nOldProp );
     782          17 :                             if ( !nOldProp )
     783          17 :                                 nOldProp = 100;
     784          17 :                             GetInfo().GetFont()->SetProportion( 100 );
     785             : 
     786          17 :                             if ( pCurr == &static_cast<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         148 :                         else if( static_cast<SwMultiPortion*>(pPor)->IsRuby() ||
     800           0 :                                  static_cast<SwMultiPortion*>(pPor)->IsBidi() )
     801         148 :                             GetInfo().SetMulti( false );
     802             : 
     803             :                         // calculate cursor values
     804         165 :                         if( static_cast<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( static_cast<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( static_cast<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         165 :                             pOrig->Pos().Y() += aOldPos.Y();
     850         165 :                             if ( static_cast<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         165 :                                 pOrig->Pos().X() += nX;
     860             : 
     861         165 :                             if( static_cast<SwMultiPortion*>(pPor)->HasBrackets() )
     862          14 :                                 pOrig->Pos().X() +=
     863          28 :                                     static_cast<SwDoubleLinePortion*>(pPor)->PreWidth();
     864             :                         }
     865             : 
     866         165 :                         if( bSpaceChg )
     867           0 :                             SwDoubleLinePortion::ResetSpaceAdd( pCurr );
     868             : 
     869         165 :                         pCurr = pOldCurr;
     870         165 :                         nStart = nOldStart;
     871         165 :                         nY = nOldY;
     872         165 :                         bPrev = false;
     873             : 
     874       69381 :                         return;
     875             :                     }
     876        2326 :                     if ( pPor->PrtWidth() )
     877             :                     {
     878        2324 :                         sal_Int32 nOldLen = pPor->GetLen();
     879        2324 :                         pPor->SetLen( nOfst - aInf.GetIdx() );
     880        2324 :                         aInf.SetLen( pPor->GetLen() );
     881        2324 :                         if( nX || !pPor->InNumberGrp() )
     882             :                         {
     883        2324 :                             SeekAndChg( aInf );
     884        2324 :                             const bool bOldOnWin = aInf.OnWin();
     885        2324 :                             aInf.SetOnWin( false ); // keine BULLETs!
     886        2324 :                             SwTwips nTmp = nX;
     887        2324 :                             aInf.SetKanaComp( pKanaComp );
     888        2324 :                             aInf.SetKanaIdx( nKanaIdx );
     889        2324 :                             nX += pPor->GetTextSize( aInf ).Width();
     890        2324 :                             aInf.SetOnWin( bOldOnWin );
     891        2324 :                             if ( pPor->InSpaceGrp() && nSpaceAdd )
     892           0 :                                 nX += pPor->CalcSpacing( nSpaceAdd, aInf );
     893        2324 :                             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->GetTextSize( 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        2324 :                         pPor->SetLen( nOldLen );
     906             : 
     907             :                         // Shift the cursor with the right border width
     908             :                         // Note: nX remains positive because GetTextSize() also include the width of the right border
     909        2324 :                         if( aInf.GetIdx() < nOfst && nOfst < aInf.GetIdx() + pPor->GetLen() )
     910             :                         {
     911             :                             // Find the current drop portion part and use its right border
     912        2324 :                             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        2324 :                             else if( GetInfo().GetFont()->GetRightBorder() && !pPor->GetJoinBorderWithNext())
     928             :                             {
     929           0 :                                 nX -= GetInfo().GetFont()->GetRightBorderSpace();
     930             :                             }
     931             :                          }
     932             :                     }
     933        2326 :                     bWidth = false;
     934        2326 :                     break;
     935             :                 }
     936             :             }
     937             :         }
     938             : 
     939       61796 :         if( pPor )
     940             :         {
     941             :             OSL_ENSURE( !pPor->InNumberGrp() || bInsideFirstField, "Number surprise" );
     942       39022 :             bool bEmptyField = false;
     943       39022 :             if( pPor->InFieldGrp() && pPor->GetLen() )
     944             :             {
     945         291 :                 SwFieldPortion *pTmp = static_cast<SwFieldPortion*>(pPor);
     946         582 :                 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->InFieldGrp() )
     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 = static_cast<SwFieldPortion*>(pNext);
     959           0 :                     nPorHeight = pTmp->Height();
     960           0 :                     nPorAscent = pTmp->GetAscent();
     961           0 :                     nX += nAddX;
     962           0 :                     bEmptyField = true;
     963             :                 }
     964             :             }
     965             :             // 8513: Fields in justified text, skipped
     966       78074 :             while( pPor && !pPor->GetLen() && ! bInsideFirstField &&
     967          42 :                    ( pPor->IsFlyPortion() || pPor->IsKernPortion() ||
     968          42 :                      pPor->IsBlankPortion() || pPor->InTabGrp() ||
     969          28 :                      ( !bEmptyField && pPor->InFieldGrp() ) ) )
     970             :             {
     971           8 :                 if ( pPor->InSpaceGrp() && nSpaceAdd )
     972           0 :                     nX += pPor->PrtWidth() +
     973           0 :                           pPor->CalcSpacing( nSpaceAdd, aInf );
     974             :                 else
     975             :                 {
     976           8 :                     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           8 :                     if ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
     990           0 :                             !pPor->GetPortion()->IsMarginPortion() ) )
     991           8 :                         nX += pPor->PrtWidth();
     992             :                 }
     993           8 :                 if( pPor->IsMultiPortion() &&
     994           0 :                     static_cast<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           8 :                 if( !pPor->IsFlyPortion() )
    1008             :                 {
    1009           8 :                     nPorHeight = pPor->Height();
    1010           8 :                     nPorAscent = pPor->GetAscent();
    1011             :                 }
    1012           8 :                 pPor = pPor->GetPortion();
    1013             :             }
    1014             : 
    1015      114740 :             if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
    1016       39022 :                 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       39022 :             if( pPor && pCMS )
    1034             :             {
    1035       36512 :                 if( pCMS->bFieldInfo && pPor->InFieldGrp() && pPor->Width() )
    1036           0 :                     pOrig->Width( pPor->Width() );
    1037       36512 :                 if( pPor->IsDropPortion() )
    1038             :                 {
    1039          64 :                     nPorAscent = static_cast<SwDropPortion*>(pPor)->GetDropHeight();
    1040             :                     // The drop height is only calculated, if we have more than
    1041             :                     // one line. Otherwise it is 0.
    1042          64 :                     if ( ! nPorAscent)
    1043          64 :                         nPorAscent = pPor->Height();
    1044          64 :                     nPorHeight = nPorAscent;
    1045         128 :                     pOrig->Height( nPorHeight +
    1046         128 :                         static_cast<SwDropPortion*>(pPor)->GetDropDescent() );
    1047          64 :                     if( nTmpHeight < pOrig->Height() )
    1048             :                     {
    1049           0 :                         nTmpAscent = nPorAscent;
    1050           0 :                         nTmpHeight = sal_uInt16( pOrig->Height() );
    1051             :                     }
    1052             :                 }
    1053       36512 :                 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->GetTextSize( 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       36512 :                 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       61965 :         if ( pCMS &&
    1101       59276 :                 ( pLastBidiPor ||
    1102       36512 :                 ( pPor &&
    1103       36844 :                   pPor->IsMultiPortion() &&
    1104         332 :                   static_cast<SwMultiPortion*>(pPor)->IsBidi() ) ) )
    1105             :         {
    1106             :             // we determine if the cursor has to blink before or behind
    1107             :             // the bidi portion
    1108         169 :             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 :                             static_cast<SwMultiPortion*>(pLastBidiPor)->GetRoot();
    1124             : 
    1125           0 :                     const SwLinePortion *pLast = rLineLayout.FindLastPortion();
    1126           0 :                     if ( pLast->IsMultiPortion() )
    1127             :                     {
    1128             :                         OSL_ENSURE( static_cast<const 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         169 :                 const sal_uInt8 nPortionLevel = static_cast<SwBidiPortion*>(pPor)->GetLevel();
    1138             : 
    1139         169 :                 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       61796 :         pOrig->Pos().X() += nX;
    1150             : 
    1151       61796 :         if ( pCMS && pCMS->bRealHeight )
    1152             :         {
    1153       57177 :             nTmpAscent = AdjustBaseLine( *pCurr, 0, nPorHeight, nPorAscent );
    1154       57177 :             if ( nTmpAscent > nPorAscent )
    1155        1546 :                 pCMS->aRealHeight.X() = nTmpAscent - nPorAscent;
    1156             :             else
    1157       55631 :                 pCMS->aRealHeight.X() = 0;
    1158             :             OSL_ENSURE( nPorHeight, "GetCharRect: Missing Portion-Height" );
    1159       57177 :             if ( nTmpHeight > nPorHeight )
    1160        2019 :                 pCMS->aRealHeight.Y() = nPorHeight;
    1161             :             else
    1162       55158 :                 pCMS->aRealHeight.Y() = nTmpHeight;
    1163             :         }
    1164       69051 :     }
    1165             : }
    1166             : 
    1167       69051 : bool SwTextCursor::GetCharRect( SwRect* pOrig, const sal_Int32 nOfst,
    1168             :                                SwCrsrMoveState* pCMS, const long nMax )
    1169             : {
    1170       69051 :     CharCrsrToLine(nOfst);
    1171             : 
    1172             :     // Indicates that a position inside a special portion (field, number portion)
    1173             :     // is requested.
    1174       69051 :     const bool bSpecialPos = pCMS && pCMS->pSpecialPos;
    1175       69051 :     sal_Int32 nFindOfst = nOfst;
    1176             : 
    1177       69051 :     if ( bSpecialPos )
    1178             :     {
    1179           0 :         const SwSPExtendRange nExtendRange = pCMS->pSpecialPos->nExtendRange;
    1180             : 
    1181             :         OSL_ENSURE( ! pCMS->pSpecialPos->nLineOfst || SwSPExtendRange::BEFORE != nExtendRange,
    1182             :                 "LineOffset AND Number Portion?" );
    1183             : 
    1184             :         // portions which are behind the string
    1185           0 :         if ( SwSPExtendRange::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       69051 :     GetAdjusted();
    1195             : 
    1196       69051 :     const Point aCharPos( GetTopLeft() );
    1197       69051 :     bool bRet = true;
    1198             : 
    1199       69051 :     _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       69051 :     const SwTwips nTmpRight = Right() - 12;
    1204             : 
    1205       69051 :     pOrig->Pos().X() += aCharPos.X();
    1206       69051 :     pOrig->Pos().Y() += aCharPos.Y();
    1207             : 
    1208       69051 :     if( pCMS && pCMS->b2Lines && pCMS->p2Lines )
    1209             :     {
    1210          77 :         pCMS->p2Lines->aLine.Pos().X() += aCharPos.X();
    1211          77 :         pCMS->p2Lines->aLine.Pos().Y() += aCharPos.Y();
    1212          77 :         pCMS->p2Lines->aPortion.Pos().X() += aCharPos.X();
    1213          77 :         pCMS->p2Lines->aPortion.Pos().Y() += aCharPos.Y();
    1214             :     }
    1215             : 
    1216       69051 :     const bool bTabOverMargin = GetTextFrm()->GetTextNode()->getIDocumentSettingAccess()->get(DocumentSettingId::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       69051 :     if( pOrig->Left() > nTmpRight && !bTabOverMargin)
    1219           6 :         pOrig->Pos().X() = nTmpRight;
    1220             : 
    1221       69051 :     if( nMax )
    1222             :     {
    1223       67358 :         if( pOrig->Top() + pOrig->Height() > nMax )
    1224             :         {
    1225         371 :             if( pOrig->Top() > nMax )
    1226           0 :                 pOrig->Top( nMax );
    1227         371 :             pOrig->Height( nMax - pOrig->Top() );
    1228             :         }
    1229       67358 :         if ( pCMS && pCMS->bRealHeight && pCMS->aRealHeight.Y() >= 0 )
    1230             :         {
    1231       64408 :             long nTmp = pCMS->aRealHeight.X() + pOrig->Top();
    1232       64408 :             if( nTmp >= nMax )
    1233             :             {
    1234           0 :                 pCMS->aRealHeight.X() = nMax - pOrig->Top();
    1235           0 :                 pCMS->aRealHeight.Y() = 0;
    1236             :             }
    1237       64408 :             else if( nTmp + pCMS->aRealHeight.Y() > nMax )
    1238         710 :                 pCMS->aRealHeight.Y() = nMax - nTmp;
    1239             :         }
    1240             :     }
    1241       69051 :     long nOut = pOrig->Right() - GetTextFrm()->Frm().Right();
    1242       69051 :     if( nOut > 0 )
    1243             :     {
    1244         262 :         if( GetTextFrm()->Frm().Width() < GetTextFrm()->Prt().Left()
    1245         131 :                                    + GetTextFrm()->Prt().Width() )
    1246           0 :             nOut += GetTextFrm()->Frm().Width() - GetTextFrm()->Prt().Left()
    1247           0 :                     - GetTextFrm()->Prt().Width();
    1248         131 :         if( nOut > 0 )
    1249         131 :             pOrig->Pos().X() -= nOut + 10;
    1250             :     }
    1251             : 
    1252       69051 :     return bRet;
    1253             : }
    1254             : 
    1255             : // Return: Offset in String
    1256         135 : sal_Int32 SwTextCursor::GetCrsrOfst( SwPosition *pPos, const Point &rPoint,
    1257             :                                     bool nChgNode, SwCrsrMoveState* pCMS ) const
    1258             : {
    1259             :     // If necessary, as catch up, do the adjustment
    1260         135 :     GetAdjusted();
    1261             : 
    1262         135 :     const OUString &rText = GetInfo().GetText();
    1263         135 :     sal_Int32 nOffset = 0;
    1264             : 
    1265             :     // x is the horizontal offset within the line.
    1266         135 :     SwTwips x = rPoint.X();
    1267         135 :     const SwTwips nLeftMargin  = GetLineStart();
    1268         135 :     SwTwips nRightMargin = GetLineEnd();
    1269         135 :     if( nRightMargin == nLeftMargin )
    1270           7 :         nRightMargin += 30;
    1271             : 
    1272         135 :     const bool bLeftOver = x < nLeftMargin;
    1273         135 :     if( bLeftOver )
    1274          14 :         x = nLeftMargin;
    1275         135 :     const bool bRightOver = x > nRightMargin;
    1276         135 :     if( bRightOver )
    1277          87 :         x = nRightMargin;
    1278             : 
    1279         135 :     const bool bRightAllowed = pCMS && ( pCMS->eState == MV_NONE );
    1280             : 
    1281             :     // Until here everything in document coordinates.
    1282         135 :     x -= nLeftMargin;
    1283             : 
    1284         135 :     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         135 :     SwLinePortion *pPor = pCurr->GetFirstPortion();
    1289         135 :     sal_Int32 nCurrStart  = nStart;
    1290         135 :     bool bHolePortion = false;
    1291         135 :     bool bLastHyph = false;
    1292             : 
    1293         135 :     std::deque<sal_uInt16> *pKanaComp = pCurr->GetpKanaComp();
    1294         135 :     sal_Int32 nOldIdx = GetInfo().GetIdx();
    1295         135 :     sal_uInt16 nSpaceIdx = 0;
    1296         135 :     size_t nKanaIdx = 0;
    1297         135 :     long nSpaceAdd = pCurr->IsSpaceAdd() ? pCurr->GetLLSpaceAdd( 0 ) : 0;
    1298         135 :     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         135 :     sal_uInt16 nWidth = pPor->Width();
    1304         135 :     if ( pCurr->IsSpaceAdd() || pKanaComp )
    1305             :     {
    1306           0 :         if ( pPor->InSpaceGrp() && nSpaceAdd )
    1307             :         {
    1308           0 :             const_cast<SwTextSizeInfo&>(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() && static_cast<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         135 :     if ( pPor->IsPostItsPortion() )
    1335           0 :         nWidth30 = 30 + pPor->GetViewWidth( GetInfo() ) / 2;
    1336             :     else
    1337           7 :         nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFieldGrp() ?
    1338             :                      30 :
    1339         270 :                      nWidth;
    1340             : 
    1341         275 :     while( pPor->GetPortion() && nWidth30 < nX && !pPor->IsBreakPortion() )
    1342             :     {
    1343           5 :         nX = nX - nWidth;
    1344           5 :         nCurrStart = nCurrStart + pPor->GetLen();
    1345           5 :         bHolePortion = pPor->IsHolePortion();
    1346           5 :         pPor = pPor->GetPortion();
    1347           5 :         nWidth = pPor->Width();
    1348           5 :         if ( pCurr->IsSpaceAdd() || pKanaComp )
    1349             :         {
    1350           0 :             if ( pPor->InSpaceGrp() && nSpaceAdd )
    1351             :             {
    1352           0 :                 const_cast<SwTextSizeInfo&>(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() && static_cast<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           5 :         if ( pPor->IsPostItsPortion() )
    1379           0 :             nWidth30 = 30 +  pPor->GetViewWidth( GetInfo() ) / 2;
    1380             :         else
    1381           2 :             nWidth30 = ! nWidth && pPor->GetLen() && pPor->InToxRefOrFieldGrp() ?
    1382             :                          30 :
    1383          10 :                          nWidth;
    1384           5 :         if( !pPor->IsFlyPortion() && !pPor->IsMarginPortion() )
    1385           5 :             bLastHyph = pPor->InHyphGrp();
    1386             :     }
    1387             : 
    1388         135 :     const bool bLastPortion = (0 == pPor->GetPortion());
    1389             : 
    1390         135 :     if( nX==nWidth )
    1391             :     {
    1392          83 :         SwLinePortion *pNextPor = pPor->GetPortion();
    1393         166 :         while( pNextPor && pNextPor->InFieldGrp() && !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         135 :     const_cast<SwTextSizeInfo&>(GetInfo()).SetIdx( nOldIdx );
    1404             : 
    1405         135 :     sal_Int32 nLength = pPor->GetLen();
    1406             : 
    1407         135 :     const bool bFieldInfo = pCMS && pCMS->bFieldInfo;
    1408             : 
    1409         141 :     if( bFieldInfo && ( nWidth30 < nX || bRightOver || bLeftOver ||
    1410           0 :         ( pPor->InNumberGrp() && !pPor->IsFootnoteNumPortion() ) ||
    1411           0 :         ( pPor->IsMarginPortion() && nWidth > nX + 30 ) ) )
    1412           6 :         static_cast<SwCrsrMoveState*>(pCMS)->bPosCorr = true;
    1413             : 
    1414             :     // #i27615#
    1415         135 :     if (pCMS)
    1416             :     {
    1417         133 :         if( pCMS->bInFrontOfLabel)
    1418             :         {
    1419           0 :             if (! (2 * nX < nWidth && pPor->InNumberGrp() &&
    1420           0 :                    !pPor->IsFootnoteNumPortion()))
    1421           0 :                 pCMS->bInFrontOfLabel = false;
    1422             :         }
    1423             :     }
    1424             : 
    1425             :     // 7684: We are exactly ended up at their 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         135 :     if( !nLength )
    1429             :     {
    1430           5 :         if( pCMS )
    1431             :         {
    1432           5 :             if( pPor->IsFlyPortion() && bFieldInfo )
    1433           0 :                 static_cast<SwCrsrMoveState*>(pCMS)->bPosCorr = true;
    1434             : 
    1435           5 :             if (!bRightOver && nX)
    1436             :             {
    1437           0 :                 if( pPor->IsFootnoteNumPortion())
    1438           0 :                     static_cast<SwCrsrMoveState*>(pCMS)->bFootnoteNoInfo = true;
    1439           0 :                 else if (pPor->InNumberGrp() ) // #i23726#
    1440             :                 {
    1441           0 :                     static_cast<SwCrsrMoveState*>(pCMS)->nInNumPostionOffset = nX;
    1442           0 :                     static_cast<SwCrsrMoveState*>(pCMS)->bInNumPortion = true;
    1443             :                 }
    1444             :             }
    1445             :         }
    1446           5 :         if( !nCurrStart )
    1447           5 :             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->InFieldGrp() && static_cast<SwFieldPortion*>(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         130 :     if ( 1 == nLength )
    1473             :     {
    1474         109 :         if ( nWidth )
    1475             :         {
    1476             :             // Else we may not enter the character-supplying frame...
    1477         107 :             if( !( nChgNode && pPos && pPor->IsFlyCntPortion() ) )
    1478             :             {
    1479           6 :                 if ( pPor->InFieldGrp() ||
    1480           3 :                      ( pPor->IsMultiPortion() &&
    1481           0 :                        static_cast<SwMultiPortion*>(pPor)->IsBidi()  ) )
    1482             :                 {
    1483           0 :                     sal_uInt16 nHeight = 0;
    1484           0 :                     if( !bFieldInfo )
    1485             :                     {
    1486           0 :                         nHeight = pPor->Height();
    1487           0 :                         if ( !nHeight || nHeight > nWidth )
    1488           0 :                             nHeight = nWidth;
    1489             :                     }
    1490             : 
    1491           0 :                     if( nWidth - nHeight/2 <= nX &&
    1492           0 :                         ( ! pPor->InFieldGrp() ||
    1493           0 :                           !static_cast<SwFieldPortion*>(pPor)->HasFollow() ) )
    1494           0 :                         ++nCurrStart;
    1495             :                 }
    1496           6 :                 else if ( ( !pPor->IsFlyPortion() || ( pPor->GetPortion() &&
    1497           0 :                     !pPor->GetPortion()->IsMarginPortion() &&
    1498           0 :                     !pPor->GetPortion()->IsHolePortion() ) )
    1499           5 :                          && ( nWidth/2 < nX ) &&
    1500           2 :                          ( !bFieldInfo ||
    1501           0 :                             ( pPor->GetPortion() &&
    1502           0 :                               pPor->GetPortion()->IsPostItsPortion() ) )
    1503           5 :                          && ( bRightAllowed || !bLastHyph ))
    1504           2 :                     ++nCurrStart;
    1505             : 
    1506             :                 // if we want to get the position inside the field, we should not return
    1507           3 :                 if ( !pCMS || !pCMS->pSpecialPos )
    1508           3 :                     return nCurrStart;
    1509             :             }
    1510             :         }
    1511             :         else
    1512             :         {
    1513           4 :             if ( pPor->IsPostItsPortion() || pPor->IsBreakPortion() ||
    1514           2 :                  pPor->InToxRefGrp() )
    1515           0 :                 return nCurrStart;
    1516           2 :             if ( pPor->InFieldGrp() )
    1517             :             {
    1518           0 :                 if( bRightOver && !static_cast<SwFieldPortion*>(pPor)->HasFollow() )
    1519           0 :                     ++nCurrStart;
    1520           0 :                 return nCurrStart;
    1521             :             }
    1522             :         }
    1523             :     }
    1524             : 
    1525             :     // Skip space at the end of the line
    1526         253 :     if( bLastPortion && (pCurr->GetNext() || pFrm->GetFollow() )
    1527         127 :         && rText[nCurrStart + nLength - 1] == ' ' )
    1528           0 :         --nLength;
    1529             : 
    1530         254 :     if( nWidth > nX ||
    1531         162 :       ( nWidth == nX && pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->IsDouble() ) )
    1532             :     {
    1533          45 :         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 ( ( static_cast<SwTextSizeInfo*>(pInf)->IsMulti() &&
    1541           0 :                    static_cast<SwTextSizeInfo*>(pInf)->IsFirstMulti() ) ||
    1542           0 :                  ( static_cast<SwMultiPortion*>(pPor)->IsRuby() &&
    1543           0 :                    static_cast<SwMultiPortion*>(pPor)->OnTop() ) )
    1544           0 :                 nTmpY += static_cast<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 (   static_cast<SwMultiPortion*>(pPor)->IsRuby() &&
    1550           0 :                  ! static_cast<SwMultiPortion*>(pPor)->OnTop() )
    1551           0 :                 nTmpY = 0;
    1552             : 
    1553             :             SwTextCursorSave aSave( const_cast<SwTextCursor*>(static_cast<const SwTextCursor*>(this)), static_cast<SwMultiPortion*>(pPor),
    1554           0 :                  nTmpY, nX, nCurrStart, nSpaceAdd );
    1555             : 
    1556           0 :             SwLayoutModeModifier aLayoutModeModifier( *GetInfo().GetOut() );
    1557           0 :             if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
    1558             :             {
    1559           0 :                 const sal_uInt8 nBidiLevel = static_cast<SwBidiPortion*>(pPor)->GetLevel();
    1560           0 :                 aLayoutModeModifier.Modify( nBidiLevel % 2 );
    1561             :             }
    1562             : 
    1563           0 :             if( static_cast<SwMultiPortion*>(pPor)->HasRotation() )
    1564             :             {
    1565           0 :                 nTmpY -= nY;
    1566           0 :                 if( !static_cast<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( static_cast<SwMultiPortion*>(pPor)->HasBrackets() )
    1574             :             {
    1575           0 :                 const sal_uInt16 nPreWidth = static_cast<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          45 :         if( pPor->InTextGrp() )
    1586             :         {
    1587             :             sal_uInt8 nOldProp;
    1588          16 :             if( GetPropFont() )
    1589             :             {
    1590           0 :                 const_cast<SwFont*>(GetFnt())->SetProportion( GetPropFont() );
    1591           0 :                 nOldProp = GetFnt()->GetPropr();
    1592             :             }
    1593             :             else
    1594          16 :                 nOldProp = 0;
    1595             :             {
    1596          16 :                 SwTextSizeInfo aSizeInf( GetInfo(), &rText, nCurrStart );
    1597          16 :                 const_cast<SwTextCursor*>(this)->SeekAndChg( aSizeInf );
    1598          32 :                 SwTextSlot aDiffText( &aSizeInf, static_cast<SwTextPortion*>(pPor), false, false );
    1599          16 :                 SwFontSave aSave( aSizeInf, pPor->IsDropPortion() ?
    1600          32 :                         static_cast<SwDropPortion*>(pPor)->GetFnt() : NULL );
    1601             : 
    1602          16 :                 SwParaPortion* pPara = const_cast<SwParaPortion*>(GetInfo().GetParaPortion());
    1603             :                 OSL_ENSURE( pPara, "No paragraph!" );
    1604             : 
    1605          16 :                 SwDrawTextInfo aDrawInf( aSizeInf.GetVsh(),
    1606          16 :                                          *aSizeInf.GetOut(),
    1607          16 :                                          &pPara->GetScriptInfo(),
    1608          16 :                                          aSizeInf.GetText(),
    1609             :                                          aSizeInf.GetIdx(),
    1610          48 :                                          pPor->GetLen() );
    1611             : 
    1612             :                 // Drop portion works like a multi portion, just its parts are not portions
    1613          16 :                 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          16 :                 else if( GetInfo().GetFont()->GetLeftBorder() && !pPor->GetJoinBorderWithPrev() )
    1638             :                 {
    1639           0 :                     nX = std::max(0, nX - GetInfo().GetFont()->GetLeftBorderSpace());
    1640             :                 }
    1641             : 
    1642          16 :                 aDrawInf.SetOfst( nX );
    1643             : 
    1644          16 :                 if ( nSpaceAdd )
    1645             :                 {
    1646           0 :                     sal_Int32 nCharCnt = 0;
    1647             :                     // #i41860# Thai justified alignemt needs some
    1648             :                     // additional information:
    1649           0 :                     aDrawInf.SetNumberOfBlanks( pPor->InTextGrp() ?
    1650             :                                                 static_cast<const SwTextPortion*>(pPor)->GetSpaceCnt( aSizeInf, nCharCnt ) :
    1651           0 :                                                 0 );
    1652             :                 }
    1653             : 
    1654          16 :                 if ( pPor->InFieldGrp() && pCMS && pCMS->pSpecialPos )
    1655           0 :                     aDrawInf.SetLen( COMPLETE_STRING );
    1656             : 
    1657          16 :                 aDrawInf.SetSpace( nSpaceAdd );
    1658          16 :                 aDrawInf.SetFont( aSizeInf.GetFont() );
    1659          16 :                 aDrawInf.SetFrm( pFrm );
    1660          16 :                 aDrawInf.SetSnapToGrid( aSizeInf.SnapToGrid() );
    1661          16 :                 aDrawInf.SetPosMatchesBounds( pCMS && pCMS->bPosMatchesBounds );
    1662             : 
    1663          32 :                 if ( SW_CJK == aSizeInf.GetFont()->GetActual() &&
    1664          16 :                      pPara->GetScriptInfo().CountCompChg() &&
    1665           0 :                     ! pPor->InFieldGrp() )
    1666           0 :                     aDrawInf.SetKanaComp( nKanaComp );
    1667             : 
    1668          16 :                 nLength = aSizeInf.GetFont()->_GetCrsrOfst( aDrawInf );
    1669             : 
    1670             :                 // get position inside field portion?
    1671          16 :                 if ( pPor->InFieldGrp() && pCMS && pCMS->pSpecialPos )
    1672             :                 {
    1673           0 :                     pCMS->pSpecialPos->nCharOfst = nLength;
    1674           0 :                     nLength = 0;
    1675             :                 }
    1676             : 
    1677             :                 // set cursor bidi level
    1678          16 :                 if ( pCMS )
    1679             :                     static_cast<SwCrsrMoveState*>(pCMS)->nCursorBidiLevel =
    1680          15 :                         aDrawInf.GetCursorBidiLevel();
    1681             : 
    1682          16 :                 if( bFieldInfo && nLength == pPor->GetLen() &&
    1683           0 :                     ( ! pPor->GetPortion() ||
    1684           0 :                       ! pPor->GetPortion()->IsPostItsPortion() ) )
    1685          16 :                     --nLength;
    1686             :             }
    1687          16 :             if( nOldProp )
    1688           0 :                 const_cast<SwFont*>(GetFnt())->SetProportion( nOldProp );
    1689             :         }
    1690             :         else
    1691             :         {
    1692          58 :             if( nChgNode && pPos && pPor->IsFlyCntPortion()
    1693          58 :                 && !static_cast<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 = static_cast<SwFlyCntPortion*>(pPor)->GetFlyFrm();
    1699           0 :                 SwFrm* pLower = pTmp->GetLower();
    1700             :                 bool bChgNode = pLower
    1701           0 :                     && (pLower->IsTextFrm() || 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 = static_cast<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 :                     static_cast<SwTextSizeInfo*>(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          29 :                 nLength = pPor->GetCrsrOfst( nX );
    1727             :         }
    1728             :     }
    1729         127 :     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         238 :     if( nOffset && pPor->GetLen() == nLength && pPor->GetPortion() &&
    1735         127 :         !pPor->GetPortion()->GetLen() && pPor->GetPortion()->InHyphGrp() )
    1736           0 :         --nOffset;
    1737             : 
    1738         127 :     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 SwTextFrm::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 :         SwContentNode &rNode = const_cast<SwContentNode&>( *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 :             SwTextInfo aInf( const_cast<SwTextFrm*>(this) );
    1784           0 :             SwTextIter aLine( const_cast<SwTextFrm*>(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         177 : }
    1883             : 
    1884             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11