LCOV - code coverage report
Current view: top level - sw/source/core/text - itrtxt.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 184 211 87.2 %
Date: 2014-11-03 Functions: 23 23 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "ndtxt.hxx"
      21             : #include "flyfrm.hxx"
      22             : #include "paratr.hxx"
      23             : #include <vcl/outdev.hxx>
      24             : #include <editeng/paravertalignitem.hxx>
      25             : 
      26             : #include "pormulti.hxx"
      27             : #include <pagefrm.hxx>
      28             : #include <pagedesc.hxx>
      29             : #include <tgrditem.hxx>
      30             : #include <porfld.hxx>
      31             : 
      32             : #include "itrtxt.hxx"
      33             : #include "txtfrm.hxx"
      34             : #include "porfly.hxx"
      35             : 
      36      318182 : void SwTxtIter::CtorInitTxtIter( SwTxtFrm *pNewFrm, SwTxtInfo *pNewInf )
      37             : {
      38      318182 :     SwTxtNode *pNode = pNewFrm->GetTxtNode();
      39             : 
      40             :     OSL_ENSURE( pNewFrm->GetPara(), "No paragraph" );
      41             : 
      42      318182 :     CtorInitAttrIter( *pNode, pNewFrm->GetPara()->GetScriptInfo(), pNewFrm );
      43             : 
      44      318182 :     pFrm = pNewFrm;
      45      318182 :     pInf = pNewInf;
      46      318182 :     aLineInf.CtorInitLineInfo( pNode->GetSwAttrSet(), *pNode );
      47      318182 :     nFrameStart = pFrm->Frm().Pos().Y() + pFrm->Prt().Pos().Y();
      48      318182 :     SwTxtIter::Init();
      49             : 
      50             :     // Order is important: only execute FillRegister if GetValue!=0
      51      318182 :     bRegisterOn = pNode->GetSwAttrSet().GetRegister().GetValue()
      52      318182 :         && pFrm->FillRegister( nRegStart, nRegDiff );
      53      318182 : }
      54             : 
      55      320924 : void SwTxtIter::Init()
      56             : {
      57      320924 :     pCurr = pInf->GetParaPortion();
      58      320924 :     nStart = pInf->GetTxtStart();
      59      320924 :     nY = nFrameStart;
      60      320924 :     bPrev = true;
      61      320924 :     pPrev = 0;
      62      320924 :     nLineNr = 1;
      63      320924 : }
      64             : 
      65      167389 : void SwTxtIter::CalcAscentAndHeight( sal_uInt16 &rAscent, sal_uInt16 &rHeight ) const
      66             : {
      67      167389 :     rHeight = GetLineHeight();
      68      167389 :     rAscent = pCurr->GetAscent() + rHeight - pCurr->Height();
      69      167389 : }
      70             : 
      71         108 : SwLineLayout *SwTxtIter::_GetPrev()
      72             : {
      73         108 :     pPrev = 0;
      74         108 :     bPrev = true;
      75         108 :     SwLineLayout *pLay = pInf->GetParaPortion();
      76         108 :     if( pCurr == pLay )
      77           8 :         return 0;
      78        2678 :     while( pLay->GetNext() != pCurr )
      79        2478 :         pLay = pLay->GetNext();
      80         100 :     return pPrev = pLay;
      81             : }
      82             : 
      83       86805 : const SwLineLayout *SwTxtIter::GetPrev()
      84             : {
      85       86805 :     if(! bPrev)
      86           0 :         _GetPrev();
      87       86805 :     return pPrev;
      88             : }
      89             : 
      90        7796 : const SwLineLayout *SwTxtIter::Prev()
      91             : {
      92        7796 :     if( !bPrev )
      93         108 :         _GetPrev();
      94        7796 :     if( pPrev )
      95             :     {
      96        3084 :         bPrev = false;
      97        3084 :         pCurr = pPrev;
      98        3084 :         nStart = nStart - pCurr->GetLen();
      99        3084 :         nY = nY - GetLineHeight();
     100        3084 :         if( !pCurr->IsDummy() && !(--nLineNr) )
     101           0 :             ++nLineNr;
     102        3084 :         return pCurr;
     103             :     }
     104             :     else
     105        4712 :         return 0;
     106             : }
     107             : 
     108     1298558 : const SwLineLayout *SwTxtIter::Next()
     109             : {
     110     1298558 :     if(pCurr->GetNext())
     111             :     {
     112      935124 :         pPrev = pCurr;
     113      935124 :         bPrev = true;
     114      935124 :         nStart = nStart + pCurr->GetLen();
     115      935124 :         nY += GetLineHeight();
     116      935124 :         if( pCurr->GetLen() || ( nLineNr>1 && !pCurr->IsDummy() ) )
     117      933709 :             ++nLineNr;
     118      935124 :         return pCurr = pCurr->GetNext();
     119             :     }
     120             :     else
     121      363434 :         return 0;
     122             : }
     123             : 
     124          28 : const SwLineLayout *SwTxtIter::NextLine()
     125             : {
     126          28 :     const SwLineLayout *pNext = Next();
     127          56 :     while( pNext && pNext->IsDummy() && pNext->GetNext() )
     128             :     {
     129           0 :         pNext = Next();
     130             :     }
     131          28 :     return pNext;
     132             : }
     133             : 
     134      111368 : const SwLineLayout *SwTxtIter::GetNextLine() const
     135             : {
     136      111368 :     const SwLineLayout *pNext = pCurr->GetNext();
     137      222808 :     while( pNext && pNext->IsDummy() && pNext->GetNext() )
     138             :     {
     139          72 :         pNext = pNext->GetNext();
     140             :     }
     141      111368 :     return (SwLineLayout*)pNext;
     142             : }
     143             : 
     144           2 : const SwLineLayout *SwTxtIter::GetPrevLine()
     145             : {
     146           2 :     const SwLineLayout *pRoot = pInf->GetParaPortion();
     147           2 :     if( pRoot == pCurr )
     148           0 :         return 0;
     149           2 :     const SwLineLayout *pLay = pRoot;
     150             : 
     151           6 :     while( pLay->GetNext() != pCurr )
     152           2 :         pLay = pLay->GetNext();
     153             : 
     154           2 :     if( pLay->IsDummy() )
     155             :     {
     156           2 :         const SwLineLayout *pTmp = pRoot;
     157           2 :         pLay = pRoot->IsDummy() ? 0 : pRoot;
     158           6 :         while( pTmp->GetNext() != pCurr )
     159             :         {
     160           2 :             if( !pTmp->IsDummy() )
     161           0 :                 pLay = pTmp;
     162           2 :             pTmp = pTmp->GetNext();
     163             :         }
     164             :     }
     165             : 
     166             :     // Wenn sich nichts getan hat, dann gibt es nur noch Dummys
     167           2 :     return (SwLineLayout*)pLay;
     168             : }
     169             : 
     170        2539 : const SwLineLayout *SwTxtIter::PrevLine()
     171             : {
     172        2539 :     const SwLineLayout *pMyPrev = Prev();
     173        2539 :     if( !pMyPrev )
     174         824 :         return 0;
     175             : 
     176        1715 :     const SwLineLayout *pLast = pMyPrev;
     177        3438 :     while( pMyPrev && pMyPrev->IsDummy() )
     178             :     {
     179           8 :         pLast = pMyPrev;
     180           8 :         pMyPrev = Prev();
     181             :     }
     182        1715 :     return (SwLineLayout*)(pMyPrev ? pMyPrev : pLast);
     183             : }
     184             : 
     185      171625 : void SwTxtIter::Bottom()
     186             : {
     187      171625 :     while( Next() )
     188             :     {
     189             :         // nothing
     190             :     }
     191      171625 : }
     192             : 
     193      203716 : void SwTxtIter::CharToLine(const sal_Int32 nChar)
     194             : {
     195      203716 :     while( nStart + pCurr->GetLen() <= nChar && Next() )
     196             :         ;
     197      203716 :     while( nStart > nChar && Prev() )
     198             :         ;
     199      203716 : }
     200             : 
     201             : // 1170: beruecksichtigt Mehrdeutigkeiten:
     202      120679 : const SwLineLayout *SwTxtCursor::CharCrsrToLine( const sal_Int32 nPosition )
     203             : {
     204      120679 :     CharToLine( nPosition );
     205      120679 :     if( nPosition != nStart )
     206       48643 :         bRightMargin = false;
     207      120679 :     bool bPrevious = bRightMargin && pCurr->GetLen() && GetPrev() &&
     208      120679 :         GetPrev()->GetLen();
     209      120679 :     if( bPrevious && nPosition && CH_BREAK == GetInfo().GetChar( nPosition-1 ) )
     210           0 :         bPrevious = false;
     211      120679 :     return bPrevious ? PrevLine() : pCurr;
     212             : }
     213             : 
     214      100766 : sal_uInt16 SwTxtCursor::AdjustBaseLine( const SwLineLayout& rLine,
     215             :                                     const SwLinePortion* pPor,
     216             :                                     sal_uInt16 nPorHeight, sal_uInt16 nPorAscent,
     217             :                                     const bool bAutoToCentered ) const
     218             : {
     219      100766 :     if ( pPor )
     220             :     {
     221        1820 :         nPorHeight = pPor->Height();
     222        1820 :         nPorAscent = pPor->GetAscent();
     223             :     }
     224             : 
     225      100766 :     sal_uInt16 nOfst = rLine.GetRealHeight() - rLine.Height();
     226             : 
     227      100766 :     SwTextGridItem const*const pGrid(GetGridItem(pFrm->FindPageFrm()));
     228             : 
     229      100766 :     if ( pGrid && GetInfo().SnapToGrid() )
     230             :     {
     231         606 :         const sal_uInt16 nRubyHeight = pGrid->GetRubyHeight();
     232         606 :         const bool bRubyTop = ! pGrid->GetRubyTextBelow();
     233             : 
     234         606 :         if ( GetInfo().IsMulti() )
     235             :             // we are inside the GetCharRect recursion for multi portions
     236             :             // we center the portion in its surrounding line
     237           0 :             nOfst = ( pCurr->Height() - nPorHeight ) / 2 + nPorAscent;
     238             :         else
     239             :         {
     240             :             // We have to take care for ruby portions.
     241             :             // The ruby portion is NOT centered
     242         606 :             nOfst = nOfst + nPorAscent;
     243             : 
     244         606 :             if ( ! pPor || ! pPor->IsMultiPortion() ||
     245           0 :                  ! ((SwMultiPortion*)pPor)->IsRuby() )
     246             :             {
     247             :                 // Portions which are bigger than on grid distance are
     248             :                 // centered inside the whole line.
     249             : 
     250             :                 //for text refactor
     251         606 :                 const sal_uInt16 nLineNet =  rLine.Height() - nRubyHeight;
     252             :                 //const sal_uInt16 nLineNet = ( nPorHeight > nGridWidth ) ?
     253             :                  //                           rLine.Height() - nRubyHeight :
     254             :                  //                           nGridWidth;
     255         606 :                 nOfst += ( nLineNet - nPorHeight ) / 2;
     256         606 :                 if ( bRubyTop )
     257         606 :                     nOfst += nRubyHeight;
     258             :             }
     259             :         }
     260             :     }
     261             :     else
     262             :     {
     263      100160 :         switch ( GetLineInfo().GetVertAlign() ) {
     264             :             case SvxParaVertAlignItem::TOP :
     265           0 :                 nOfst = nOfst + nPorAscent;
     266           0 :                 break;
     267             :             case SvxParaVertAlignItem::CENTER :
     268             :                 OSL_ENSURE( rLine.Height() >= nPorHeight, "Portion height > Line height");
     269           0 :                 nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent;
     270           0 :                 break;
     271             :             case SvxParaVertAlignItem::BOTTOM :
     272           0 :                 nOfst += rLine.Height() - nPorHeight + nPorAscent;
     273           0 :                 break;
     274             :             case SvxParaVertAlignItem::AUTOMATIC :
     275       99952 :                 if ( bAutoToCentered || GetInfo().GetTxtFrm()->IsVertical() )
     276             :                 {
     277           0 :                     if( GetInfo().GetTxtFrm()->IsVertLR() )
     278           0 :                             nOfst += rLine.Height() - ( rLine.Height() - nPorHeight ) / 2 - nPorAscent;
     279             :                     else
     280           0 :                             nOfst += ( rLine.Height() - nPorHeight ) / 2 + nPorAscent;
     281           0 :                     break;
     282             :                 }
     283             :             case SvxParaVertAlignItem::BASELINE :
     284             :                 // base line
     285      100160 :                 nOfst = nOfst + rLine.GetAscent();
     286      100160 :                 break;
     287             :         }
     288             :     }
     289             : 
     290      100766 :     return nOfst;
     291             : }
     292             : 
     293       20188 : const SwLineLayout *SwTxtIter::TwipsToLine( const SwTwips y)
     294             : {
     295       20188 :     while( nY + GetLineHeight() <= y && Next() )
     296             :         ;
     297       20188 :     while( nY > y && Prev() )
     298             :         ;
     299       20188 :     return pCurr;
     300             : }
     301             : 
     302             : // Local helper function to check, if pCurr needs a field rest portion:
     303         606 : static bool lcl_NeedsFieldRest( const SwLineLayout* pCurr )
     304             : {
     305         606 :     const SwLinePortion *pPor = pCurr->GetPortion();
     306         606 :     bool bRet = false;
     307        1214 :     while( pPor && !bRet )
     308             :     {
     309         246 :         bRet = pPor->InFldGrp() && ((SwFldPortion*)pPor)->HasFollow();
     310         246 :         if( !pPor->GetPortion() || !pPor->GetPortion()->InFldGrp() )
     311         244 :             break;
     312           2 :         pPor = pPor->GetPortion();
     313             :     }
     314         606 :     return bRet;
     315             : }
     316             : 
     317       92515 : void SwTxtIter::TruncLines( bool bNoteFollow )
     318             : {
     319       92515 :     SwLineLayout *pDel = pCurr->GetNext();
     320       92515 :     const sal_Int32 nEnd = nStart + pCurr->GetLen();
     321             : 
     322       92515 :     if( pDel )
     323             :     {
     324        1663 :         pCurr->SetNext( 0 );
     325        1663 :         if( GetHints() && bNoteFollow )
     326             :         {
     327        1818 :             GetInfo().GetParaPortion()->SetFollowField( pDel->IsRest() ||
     328        1818 :                                                         lcl_NeedsFieldRest( pCurr ) );
     329             : 
     330             :             // bug 88534: wrong positioning of flys
     331         606 :             SwTxtFrm* pFollow = GetTxtFrm()->GetFollow();
     332        1184 :             if ( pFollow && ! pFollow->IsLocked() &&
     333         578 :                  nEnd == pFollow->GetOfst() )
     334             :             {
     335         508 :                 sal_Int32 nRangeEnd = nEnd;
     336         508 :                 SwLineLayout* pLine = pDel;
     337             : 
     338             :                 // determine range to be searched for flys anchored as characters
     339        1524 :                 while ( pLine )
     340             :                 {
     341         508 :                     nRangeEnd = nRangeEnd + pLine->GetLen();
     342         508 :                     pLine = pLine->GetNext();
     343             :                 }
     344             : 
     345         508 :                 SwpHints* pTmpHints = GetTxtFrm()->GetTxtNode()->GetpSwpHints();
     346             : 
     347             :                 // examine hints in range nEnd - (nEnd + nRangeChar)
     348        1802 :                 for( size_t i = 0; i < pTmpHints->Count(); ++i )
     349             :                 {
     350        1294 :                     const SwTxtAttr* pHt = pTmpHints->GetTextHint( i );
     351        1294 :                     if( RES_TXTATR_FLYCNT == pHt->Which() )
     352             :                     {
     353             :                         // check, if hint is in our range
     354          52 :                         const sal_uInt16 nTmpPos = pHt->GetStart();
     355          52 :                         if ( nEnd <= nTmpPos && nTmpPos < nRangeEnd )
     356             :                             pFollow->_InvalidateRange(
     357          18 :                                 SwCharRange( nTmpPos, nTmpPos ), 0 );
     358             :                     }
     359             :                 }
     360             :             }
     361             :         }
     362        1663 :         delete pDel;
     363             :     }
     364      207335 :     if( pCurr->IsDummy() &&
     365      114560 :         !pCurr->GetLen() &&
     366       22045 :          nStart < GetTxtFrm()->GetTxt().getLength() )
     367          14 :         pCurr->SetRealHeight( 1 );
     368       92515 :     if( GetHints() )
     369       48954 :         pFrm->RemoveFtn( nEnd );
     370       92515 : }
     371             : 
     372           2 : void SwTxtIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
     373             : {
     374           2 :     nEndCnt = 0;
     375           2 :     nMidCnt = 0;
     376           2 :     if ( bPrev && pPrev && !pPrev->IsEndHyph() && !pPrev->IsMidHyph() )
     377           0 :          return;
     378           2 :     SwLineLayout *pLay = pInf->GetParaPortion();
     379           2 :     if( pCurr == pLay )
     380           2 :         return;
     381           0 :     while( pLay != pCurr )
     382             :     {
     383           0 :         if ( pLay->IsEndHyph() )
     384           0 :             nEndCnt++;
     385             :         else
     386           0 :             nEndCnt = 0;
     387           0 :         if ( pLay->IsMidHyph() )
     388           0 :             nMidCnt++;
     389             :         else
     390           0 :             nMidCnt = 0;
     391           0 :         pLay = pLay->GetNext();
     392             :     }
     393             : }
     394             : 
     395             : // Change current output device to formatting device, this has to be done before
     396             : // formatting.
     397      142152 : SwHookOut::SwHookOut( SwTxtSizeInfo& rInfo ) :
     398             :      pInf( &rInfo ),
     399      142152 :      pOut( rInfo.GetOut() ),
     400      284304 :      bOnWin( rInfo.OnWin() )
     401             : {
     402             :     OSL_ENSURE( rInfo.GetRefDev(), "No reference device for text formatting" );
     403             : 
     404             :     // set new values
     405      142152 :     rInfo.SetOut( rInfo.GetRefDev() );
     406      142152 :     rInfo.SetOnWin( false );
     407      142152 : }
     408             : 
     409      142152 : SwHookOut::~SwHookOut()
     410             : {
     411      142152 :     pInf->SetOut( pOut );
     412      142152 :     pInf->SetOnWin( bOnWin );
     413      142422 : }
     414             : 
     415             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10