LCOV - code coverage report
Current view: top level - sw/source/core/text - itrtxt.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 185 210 88.1 %
Date: 2015-06-13 12:38:46 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      184833 : void SwTextIter::CtorInitTextIter( SwTextFrm *pNewFrm, SwTextInfo *pNewInf )
      37             : {
      38      184833 :     SwTextNode *pNode = pNewFrm->GetTextNode();
      39             : 
      40             :     OSL_ENSURE( pNewFrm->GetPara(), "No paragraph" );
      41             : 
      42      184833 :     CtorInitAttrIter( *pNode, pNewFrm->GetPara()->GetScriptInfo(), pNewFrm );
      43             : 
      44      184833 :     pFrm = pNewFrm;
      45      184833 :     pInf = pNewInf;
      46      184833 :     aLineInf.CtorInitLineInfo( pNode->GetSwAttrSet(), *pNode );
      47      184833 :     nFrameStart = pFrm->Frm().Pos().Y() + pFrm->Prt().Pos().Y();
      48      184833 :     SwTextIter::Init();
      49             : 
      50             :     // Order is important: only execute FillRegister if GetValue!=0
      51      184833 :     bRegisterOn = pNode->GetSwAttrSet().GetRegister().GetValue()
      52      184833 :         && pFrm->FillRegister( nRegStart, nRegDiff );
      53      184833 : }
      54             : 
      55      186247 : void SwTextIter::Init()
      56             : {
      57      186247 :     pCurr = pInf->GetParaPortion();
      58      186247 :     nStart = pInf->GetTextStart();
      59      186247 :     nY = nFrameStart;
      60      186247 :     bPrev = true;
      61      186247 :     pPrev = 0;
      62      186247 :     nLineNr = 1;
      63      186247 : }
      64             : 
      65       92627 : void SwTextIter::CalcAscentAndHeight( sal_uInt16 &rAscent, sal_uInt16 &rHeight ) const
      66             : {
      67       92627 :     rHeight = GetLineHeight();
      68       92627 :     rAscent = pCurr->GetAscent() + rHeight - pCurr->Height();
      69       92627 : }
      70             : 
      71          82 : SwLineLayout *SwTextIter::_GetPrev()
      72             : {
      73          82 :     pPrev = 0;
      74          82 :     bPrev = true;
      75          82 :     SwLineLayout *pLay = pInf->GetParaPortion();
      76          82 :     if( pCurr == pLay )
      77          10 :         return 0;
      78        1836 :     while( pLay->GetNext() != pCurr )
      79        1692 :         pLay = pLay->GetNext();
      80          72 :     return pPrev = pLay;
      81             : }
      82             : 
      83       48244 : const SwLineLayout *SwTextIter::GetPrev()
      84             : {
      85       48244 :     if(! bPrev)
      86           0 :         _GetPrev();
      87       48244 :     return pPrev;
      88             : }
      89             : 
      90        4578 : const SwLineLayout *SwTextIter::Prev()
      91             : {
      92        4578 :     if( !bPrev )
      93          82 :         _GetPrev();
      94        4578 :     if( pPrev )
      95             :     {
      96        1898 :         bPrev = false;
      97        1898 :         pCurr = pPrev;
      98        1898 :         nStart = nStart - pCurr->GetLen();
      99        1898 :         nY = nY - GetLineHeight();
     100        1898 :         if( !pCurr->IsDummy() && !(--nLineNr) )
     101           4 :             ++nLineNr;
     102        1898 :         return pCurr;
     103             :     }
     104             :     else
     105        2680 :         return 0;
     106             : }
     107             : 
     108      664488 : const SwLineLayout *SwTextIter::Next()
     109             : {
     110      664488 :     if(pCurr->GetNext())
     111             :     {
     112      462057 :         pPrev = pCurr;
     113      462057 :         bPrev = true;
     114      462057 :         nStart = nStart + pCurr->GetLen();
     115      462057 :         nY += GetLineHeight();
     116      462057 :         if( pCurr->GetLen() || ( nLineNr>1 && !pCurr->IsDummy() ) )
     117      460735 :             ++nLineNr;
     118      462057 :         return pCurr = pCurr->GetNext();
     119             :     }
     120             :     else
     121      202431 :         return 0;
     122             : }
     123             : 
     124          16 : const SwLineLayout *SwTextIter::NextLine()
     125             : {
     126          16 :     const SwLineLayout *pNext = Next();
     127          32 :     while( pNext && pNext->IsDummy() && pNext->GetNext() )
     128             :     {
     129           0 :         pNext = Next();
     130             :     }
     131          16 :     return pNext;
     132             : }
     133             : 
     134       58855 : const SwLineLayout *SwTextIter::GetNextLine() const
     135             : {
     136       58855 :     const SwLineLayout *pNext = pCurr->GetNext();
     137      117746 :     while( pNext && pNext->IsDummy() && pNext->GetNext() )
     138             :     {
     139          36 :         pNext = pNext->GetNext();
     140             :     }
     141       58855 :     return pNext;
     142             : }
     143             : 
     144          11 : const SwLineLayout *SwTextIter::GetPrevLine()
     145             : {
     146          11 :     const SwLineLayout *pRoot = pInf->GetParaPortion();
     147          11 :     if( pRoot == pCurr )
     148          10 :         return 0;
     149           1 :     const SwLineLayout *pLay = pRoot;
     150             : 
     151           3 :     while( pLay->GetNext() != pCurr )
     152           1 :         pLay = pLay->GetNext();
     153             : 
     154           1 :     if( pLay->IsDummy() )
     155             :     {
     156           1 :         const SwLineLayout *pTmp = pRoot;
     157           1 :         pLay = pRoot->IsDummy() ? 0 : pRoot;
     158           3 :         while( pTmp->GetNext() != pCurr )
     159             :         {
     160           1 :             if( !pTmp->IsDummy() )
     161           0 :                 pLay = pTmp;
     162           1 :             pTmp = pTmp->GetNext();
     163             :         }
     164             :     }
     165             : 
     166             :     // Wenn sich nichts getan hat, dann gibt es nur noch Dummys
     167           1 :     return pLay;
     168             : }
     169             : 
     170        1436 : const SwLineLayout *SwTextIter::PrevLine()
     171             : {
     172        1436 :     const SwLineLayout *pMyPrev = Prev();
     173        1436 :     if( !pMyPrev )
     174         312 :         return 0;
     175             : 
     176        1124 :     const SwLineLayout *pLast = pMyPrev;
     177        2259 :     while( pMyPrev && pMyPrev->IsDummy() )
     178             :     {
     179          11 :         pLast = pMyPrev;
     180          11 :         pMyPrev = Prev();
     181             :     }
     182        1124 :     return pMyPrev ? pMyPrev : pLast;
     183             : }
     184             : 
     185       97067 : void SwTextIter::Bottom()
     186             : {
     187       97067 :     while( Next() )
     188             :     {
     189             :         // nothing
     190             :     }
     191       97067 : }
     192             : 
     193      116917 : void SwTextIter::CharToLine(const sal_Int32 nChar)
     194             : {
     195      116917 :     while( nStart + pCurr->GetLen() <= nChar && Next() )
     196             :         ;
     197      116917 :     while( nStart > nChar && Prev() )
     198             :         ;
     199      116917 : }
     200             : 
     201             : // 1170: beruecksichtigt Mehrdeutigkeiten:
     202       70172 : const SwLineLayout *SwTextCursor::CharCrsrToLine( const sal_Int32 nPosition )
     203             : {
     204       70172 :     CharToLine( nPosition );
     205       70172 :     if( nPosition != nStart )
     206       25275 :         bRightMargin = false;
     207       70172 :     bool bPrevious = bRightMargin && pCurr->GetLen() && GetPrev() &&
     208       70172 :         GetPrev()->GetLen();
     209       70172 :     if( bPrevious && nPosition && CH_BREAK == GetInfo().GetChar( nPosition-1 ) )
     210           0 :         bPrevious = false;
     211       70172 :     return bPrevious ? PrevLine() : pCurr;
     212             : }
     213             : 
     214       58207 : sal_uInt16 SwTextCursor::AdjustBaseLine( const SwLineLayout& rLine,
     215             :                                     const SwLinePortion* pPor,
     216             :                                     sal_uInt16 nPorHeight, sal_uInt16 nPorAscent,
     217             :                                     const bool bAutoToCentered ) const
     218             : {
     219       58207 :     if ( pPor )
     220             :     {
     221        1030 :         nPorHeight = pPor->Height();
     222        1030 :         nPorAscent = pPor->GetAscent();
     223             :     }
     224             : 
     225       58207 :     sal_uInt16 nOfst = rLine.GetRealHeight() - rLine.Height();
     226             : 
     227       58207 :     SwTextGridItem const*const pGrid(GetGridItem(pFrm->FindPageFrm()));
     228             : 
     229       58207 :     if ( pGrid && GetInfo().SnapToGrid() )
     230             :     {
     231        1099 :         const sal_uInt16 nRubyHeight = pGrid->GetRubyHeight();
     232        1099 :         const bool bRubyTop = ! pGrid->GetRubyTextBelow();
     233             : 
     234        1099 :         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        1099 :             nOfst = nOfst + nPorAscent;
     243             : 
     244        1099 :             if ( ! pPor || ! pPor->IsMultiPortion() ||
     245           0 :                  ! static_cast<const 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        1099 :                 const sal_uInt16 nLineNet =  rLine.Height() - nRubyHeight;
     252             :                 //const sal_uInt16 nLineNet = ( nPorHeight > nGridWidth ) ?
     253             :                  //                           rLine.Height() - nRubyHeight :
     254             :                  //                           nGridWidth;
     255        1099 :                 nOfst += ( nLineNet - nPorHeight ) / 2;
     256        1099 :                 if ( bRubyTop )
     257        1099 :                     nOfst += nRubyHeight;
     258             :             }
     259             :         }
     260             :     }
     261             :     else
     262             :     {
     263       57108 :         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       57004 :                 if ( bAutoToCentered || GetInfo().GetTextFrm()->IsVertical() )
     276             :                 {
     277           0 :                     if( GetInfo().GetTextFrm()->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       57108 :                 nOfst = nOfst + rLine.GetAscent();
     286       57108 :                 break;
     287             :         }
     288             :     }
     289             : 
     290       58207 :     return nOfst;
     291             : }
     292             : 
     293       12789 : const SwLineLayout *SwTextIter::TwipsToLine( const SwTwips y)
     294             : {
     295       12789 :     while( nY + GetLineHeight() <= y && Next() )
     296             :         ;
     297       12789 :     while( nY > y && Prev() )
     298             :         ;
     299       12789 :     return pCurr;
     300             : }
     301             : 
     302             : // Local helper function to check, if pCurr needs a field rest portion:
     303         257 : static bool lcl_NeedsFieldRest( const SwLineLayout* pCurr )
     304             : {
     305         257 :     const SwLinePortion *pPor = pCurr->GetPortion();
     306         257 :     bool bRet = false;
     307         515 :     while( pPor && !bRet )
     308             :     {
     309         138 :         bRet = pPor->InFieldGrp() && static_cast<const SwFieldPortion*>(pPor)->HasFollow();
     310         138 :         if( !pPor->GetPortion() || !pPor->GetPortion()->InFieldGrp() )
     311         137 :             break;
     312           1 :         pPor = pPor->GetPortion();
     313             :     }
     314         257 :     return bRet;
     315             : }
     316             : 
     317       51798 : void SwTextIter::TruncLines( bool bNoteFollow )
     318             : {
     319       51798 :     SwLineLayout *pDel = pCurr->GetNext();
     320       51798 :     const sal_Int32 nEnd = nStart + pCurr->GetLen();
     321             : 
     322       51798 :     if( pDel )
     323             :     {
     324        1171 :         pCurr->SetNext( 0 );
     325        1171 :         if( GetHints() && bNoteFollow )
     326             :         {
     327         771 :             GetInfo().GetParaPortion()->SetFollowField( pDel->IsRest() ||
     328         771 :                                                         lcl_NeedsFieldRest( pCurr ) );
     329             : 
     330             :             // bug 88534: wrong positioning of flys
     331         257 :             SwTextFrm* pFollow = GetTextFrm()->GetFollow();
     332         496 :             if ( pFollow && ! pFollow->IsLocked() &&
     333         239 :                  nEnd == pFollow->GetOfst() )
     334             :             {
     335         191 :                 sal_Int32 nRangeEnd = nEnd;
     336         191 :                 SwLineLayout* pLine = pDel;
     337             : 
     338             :                 // determine range to be searched for flys anchored as characters
     339         573 :                 while ( pLine )
     340             :                 {
     341         191 :                     nRangeEnd = nRangeEnd + pLine->GetLen();
     342         191 :                     pLine = pLine->GetNext();
     343             :                 }
     344             : 
     345         191 :                 SwpHints* pTmpHints = GetTextFrm()->GetTextNode()->GetpSwpHints();
     346             : 
     347             :                 // examine hints in range nEnd - (nEnd + nRangeChar)
     348         710 :                 for( size_t i = 0; i < pTmpHints->Count(); ++i )
     349             :                 {
     350         519 :                     const SwTextAttr* pHt = pTmpHints->GetTextHint( i );
     351         519 :                     if( RES_TXTATR_FLYCNT == pHt->Which() )
     352             :                     {
     353             :                         // check, if hint is in our range
     354          28 :                         const sal_uInt16 nTmpPos = pHt->GetStart();
     355          28 :                         if ( nEnd <= nTmpPos && nTmpPos < nRangeEnd )
     356             :                             pFollow->_InvalidateRange(
     357          11 :                                 SwCharRange( nTmpPos, nTmpPos ), 0 );
     358             :                     }
     359             :                 }
     360             :             }
     361             :         }
     362        1171 :         delete pDel;
     363             :     }
     364      115389 :     if( pCurr->IsDummy() &&
     365       63447 :         !pCurr->GetLen() &&
     366       11649 :          nStart < GetTextFrm()->GetText().getLength() )
     367           9 :         pCurr->SetRealHeight( 1 );
     368       51798 :     if( GetHints() )
     369       25892 :         pFrm->RemoveFootnote( nEnd );
     370       51798 : }
     371             : 
     372           1 : void SwTextIter::CntHyphens( sal_uInt8 &nEndCnt, sal_uInt8 &nMidCnt) const
     373             : {
     374           1 :     nEndCnt = 0;
     375           1 :     nMidCnt = 0;
     376           1 :     if ( bPrev && pPrev && !pPrev->IsEndHyph() && !pPrev->IsMidHyph() )
     377           0 :          return;
     378           1 :     SwLineLayout *pLay = pInf->GetParaPortion();
     379           1 :     if( pCurr == pLay )
     380           1 :         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       84215 : SwHookOut::SwHookOut( SwTextSizeInfo& rInfo ) :
     398             :      pInf( &rInfo ),
     399             :      pOut( rInfo.GetOut() ),
     400       84215 :      bOnWin( rInfo.OnWin() )
     401             : {
     402             :     OSL_ENSURE( rInfo.GetRefDev(), "No reference device for text formatting" );
     403             : 
     404             :     // set new values
     405       84215 :     rInfo.SetOut( rInfo.GetRefDev() );
     406       84215 :     rInfo.SetOnWin( false );
     407       84215 : }
     408             : 
     409      168430 : SwHookOut::~SwHookOut()
     410             : {
     411       84215 :     pInf->SetOut( pOut );
     412       84215 :     pInf->SetOnWin( bOnWin );
     413       84392 : }
     414             : 
     415             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11