LCOV - code coverage report
Current view: top level - sw/source/core/text - itratr.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 254 530 47.9 %
Date: 2014-11-03 Functions: 17 23 73.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 <editeng/charscaleitem.hxx>
      22             : #include <txtatr.hxx>
      23             : #include <sfx2/printer.hxx>
      24             : #include <svx/svdobj.hxx>
      25             : #include <vcl/window.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <fmtanchr.hxx>
      28             : #include <fmtfsize.hxx>
      29             : #include <fmtornt.hxx>
      30             : #include <fmtflcnt.hxx>
      31             : #include <fmtcntnt.hxx>
      32             : #include <fmtftn.hxx>
      33             : #include <frmatr.hxx>
      34             : #include <frmfmt.hxx>
      35             : #include <fmtfld.hxx>
      36             : #include <doc.hxx>
      37             : #include <IDocumentSettingAccess.hxx>
      38             : #include <IDocumentDeviceAccess.hxx>
      39             : #include <IDocumentLayoutAccess.hxx>
      40             : #include <viewsh.hxx>
      41             : #include <rootfrm.hxx>
      42             : #include <docary.hxx>
      43             : #include <ndtxt.hxx>
      44             : #include <dcontact.hxx>
      45             : #include <fldbas.hxx>
      46             : #include <pam.hxx>
      47             : #include <itratr.hxx>
      48             : #include <htmltbl.hxx>
      49             : #include <swtable.hxx>
      50             : #include <redlnitr.hxx>
      51             : #include <fmtsrnd.hxx>
      52             : #include <itrtxt.hxx>
      53             : #include <breakit.hxx>
      54             : #include <com/sun/star/i18n/WordType.hpp>
      55             : #include <com/sun/star/i18n/ScriptType.hpp>
      56             : #include <editeng/lrspitem.hxx>
      57             : #include <switerator.hxx>
      58             : #include <boost/foreach.hpp>
      59             : 
      60             : using namespace ::com::sun::star::i18n;
      61             : using namespace ::com::sun::star;
      62             : 
      63      104710 : void SwAttrIter::Chg( SwTxtAttr *pHt )
      64             : {
      65             :     assert(pHt && pFnt && "No attribute of font available for change");
      66      104710 :     if( pRedln && pRedln->IsOn() )
      67         526 :         pRedln->ChangeTxtAttr( pFnt, *pHt, true );
      68             :     else
      69      104184 :         aAttrHandler.PushAndChg( *pHt, *pFnt );
      70      104710 :     nChgCnt++;
      71      104710 : }
      72             : 
      73       27154 : void SwAttrIter::Rst( SwTxtAttr *pHt )
      74             : {
      75             :     assert(pHt && pFnt && "No attribute of font available for reset");
      76             :     // get top from stack after removing pHt
      77       27154 :     if( pRedln && pRedln->IsOn() )
      78         580 :         pRedln->ChangeTxtAttr( pFnt, *pHt, false );
      79             :     else
      80       26574 :         aAttrHandler.PopAndChg( *pHt, *pFnt );
      81       27154 :     nChgCnt--;
      82       27154 : }
      83             : 
      84      637960 : SwAttrIter::~SwAttrIter()
      85             : {
      86      318980 :     delete pRedln;
      87      318980 :     delete pFnt;
      88      318980 : }
      89             : 
      90             : /**
      91             :  * Returns the attribute for a position
      92             :  *
      93             :  * Only if the attribute is exactly at the position @param nPos and
      94             :  * does not have an EndIndex
      95             :  *
      96             :  * We need this function for attributes which should alter formatting without
      97             :  * changing the content of the string.
      98             :  * Such "degenerated" attributes are e.g.: fields which retain expanded text and
      99             :  * line-bound Frames.
     100             :  * In order to avoid ambiguities between different such attributes, we insert a
     101             :  * special character at the start of the string, when creating such an attribute.
     102             :  * The Formatter later on encounters such a special character and retrieves the
     103             :  * degenerate attribute via GetAttr().
     104             :  */
     105       10600 : SwTxtAttr *SwAttrIter::GetAttr( const sal_Int32 nPosition ) const
     106             : {
     107       10600 :     return (m_pTxtNode) ? m_pTxtNode->GetTxtAttrForCharAt(nPosition) : 0;
     108             : }
     109             : 
     110      501240 : bool SwAttrIter::SeekAndChgAttrIter( const sal_Int32 nNewPos, OutputDevice* pOut )
     111             : {
     112      501240 :     bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
     113      501240 :     if ( pLastOut != pOut )
     114             :     {
     115       82099 :         pLastOut = pOut;
     116       82099 :         pFnt->SetFntChg( true );
     117       82099 :         bChg = true;
     118             :     }
     119      501240 :     if( bChg )
     120             :     {
     121             :         // if the change counter is zero, we know the MagicNo of the wanted font
     122      498510 :         if ( !nChgCnt && !nPropFont )
     123      275270 :             pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
     124      550540 :                 aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
     125      498510 :         pFnt->ChgPhysFnt( pShell, *pOut );
     126             :     }
     127             : 
     128      501240 :     return bChg;
     129             : }
     130             : 
     131           0 : bool SwAttrIter::IsSymbol( const sal_Int32 nNewPos )
     132             : {
     133           0 :     Seek( nNewPos );
     134           0 :     if ( !nChgCnt && !nPropFont )
     135           0 :         pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
     136           0 :             aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
     137           0 :     return pFnt->IsSymbol( pShell );
     138             : }
     139             : 
     140       24749 : bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const bool bParaFont )
     141             : {
     142       24749 :     if ( pRedln && pRedln->ExtOn() )
     143           0 :         pRedln->LeaveExtend( *pFnt, 0 );
     144             : 
     145             :     // reset font to its original state
     146       24749 :     aAttrHandler.Reset();
     147       24749 :     aAttrHandler.ResetFont( *pFnt );
     148             : 
     149       24749 :     nStartIndex = 0;
     150       24749 :     nEndIndex = 0;
     151       24749 :     nPos = 0;
     152       24749 :     nChgCnt = 0;
     153       24749 :     if( nPropFont )
     154           0 :         pFnt->SetProportion( nPropFont );
     155       24749 :     if( pRedln )
     156             :     {
     157         108 :         pRedln->Clear( pFnt );
     158         108 :         if( !bParaFont )
     159         108 :             nChgCnt = nChgCnt + pRedln->Seek( *pFnt, 0, USHRT_MAX );
     160             :         else
     161           0 :             pRedln->Reset();
     162             :     }
     163             : 
     164       24749 :     if ( pHints && !bParaFont )
     165             :     {
     166             :         SwTxtAttr *pTxtAttr;
     167             :         // While we've not reached the end of the StartArray && the TextAttribute starts at position 0...
     168       13208 :         while ( ( nStartIndex < pHints->GetStartCount() ) &&
     169        5280 :                 !((pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
     170             :         {
     171             :             // open the TextAttributes
     172        2640 :             Chg( pTxtAttr );
     173        2640 :             nStartIndex++;
     174             :         }
     175             :     }
     176             : 
     177       24749 :     bool bChg = pFnt->IsFntChg();
     178       24749 :     if ( pLastOut != pOut )
     179             :     {
     180       24579 :         pLastOut = pOut;
     181       24579 :         pFnt->SetFntChg( true );
     182       24579 :         bChg = true;
     183             :     }
     184       24749 :     if( bChg )
     185             :     {
     186             :         // if the application counter is zero, we know the MagicNo of the wanted font
     187       24749 :         if ( !nChgCnt && !nPropFont )
     188       22013 :             pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
     189       44026 :                 aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
     190       24749 :         pFnt->ChgPhysFnt( pShell, *pOut );
     191             :     }
     192       24749 :     return bChg;
     193             : }
     194             : 
     195             : // AMA: New AttrIter Nov 94
     196      200121 : void SwAttrIter::SeekFwd( const sal_Int32 nNewPos )
     197             : {
     198             :     SwTxtAttr *pTxtAttr;
     199             : 
     200      200121 :     if ( nStartIndex ) // If attributes have been opened at all ...
     201             :     {
     202             :         // Close attributes that are currently open, but stop at nNewPos+1
     203             : 
     204             :         // As long as we've not yet reached the end of EndArray and the
     205             :         // TextAttribute ends before or at the new position ...
     206      487484 :         while ( ( nEndIndex < pHints->GetEndCount() ) &&
     207      253494 :                 (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
     208             :         {
     209             :             // Close the TextAttributes, whoes StartPos were before or at
     210             :             // the old nPos and are currently open
     211       30704 :             if (pTxtAttr->GetStart() <= nPos)  Rst( pTxtAttr );
     212       30704 :             nEndIndex++;
     213             :         }
     214             :     }
     215             :     else // skip the not opended ends
     216             :     {
     217      313692 :         while ( (nEndIndex < pHints->GetEndCount()) &&
     218      104350 :                 (*pHints->GetEnd(nEndIndex)->GetAnyEnd() <= nNewPos) )
     219             :         {
     220       12386 :             nEndIndex++;
     221             :         }
     222             :     }
     223             : 
     224             :     // As long as we've not yet reached the end of EndArray and the
     225             :     // TextAttribute ends before or at the new position ...
     226     1076228 :     while ( ( nStartIndex < pHints->GetStartCount() ) &&
     227      557980 :             ((pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos) )
     228             :     {
     229             : 
     230             :         // open the TextAttributes, whose ends lie behind the new position
     231      118006 :         if ( *pTxtAttr->GetAnyEnd() > nNewPos )  Chg( pTxtAttr );
     232      118006 :         nStartIndex++;
     233             :     }
     234             : 
     235      200121 : }
     236             : 
     237      483023 : bool SwAttrIter::Seek( const sal_Int32 nNewPos )
     238             : {
     239      483023 :     if ( pRedln && pRedln->ExtOn() )
     240           0 :         pRedln->LeaveExtend( *pFnt, nNewPos );
     241             : 
     242      483023 :     if( pHints )
     243             :     {
     244      200121 :         if( !nNewPos || nNewPos < nPos )
     245             :         {
     246       91404 :             if( pRedln )
     247        1289 :                 pRedln->Clear( NULL );
     248             : 
     249             :             // reset font to its original state
     250       91404 :             aAttrHandler.Reset();
     251       91404 :             aAttrHandler.ResetFont( *pFnt );
     252             : 
     253       91404 :             if( nPropFont )
     254         296 :                 pFnt->SetProportion( nPropFont );
     255       91404 :             nStartIndex = 0;
     256       91404 :             nEndIndex = 0;
     257       91404 :             nPos = 0;
     258       91404 :             nChgCnt = 0;
     259             : 
     260             :             // Attention!
     261             :             // resetting the font here makes it necessary to apply any
     262             :             // changes for extended input directly to the font
     263       91404 :             if ( pRedln && pRedln->ExtOn() )
     264             :             {
     265           0 :                 pRedln->UpdateExtFont( *pFnt );
     266           0 :                 ++nChgCnt;
     267             :             }
     268             :         }
     269      200121 :         SeekFwd( nNewPos );
     270             :     }
     271             : 
     272      483023 :     pFnt->SetActual( SwScriptInfo::WhichFont( nNewPos, 0, pScriptInfo ) );
     273             : 
     274      483023 :     if( pRedln )
     275        5933 :         nChgCnt = nChgCnt + pRedln->Seek( *pFnt, nNewPos, nPos );
     276      483023 :     nPos = nNewPos;
     277             : 
     278      483023 :     if( nPropFont )
     279         316 :         pFnt->SetProportion( nPropFont );
     280             : 
     281      483023 :     return pFnt->IsFntChg();
     282             : }
     283             : 
     284      146453 : sal_Int32 SwAttrIter::GetNextAttr( ) const
     285             : {
     286      146453 :     sal_Int32 nNext = COMPLETE_STRING;
     287      146453 :     if( pHints )
     288             :     {
     289             :         // are there attribute starts left?
     290       91752 :         for (size_t i = nStartIndex; i < pHints->GetStartCount(); ++i)
     291             :         {
     292       76123 :             SwTxtAttr *const pAttr(pHints->GetStart(i));
     293       76123 :             if (!pAttr->IsFormatIgnoreStart())
     294             :             {
     295       76066 :                 nNext = pAttr->GetStart();
     296       76066 :                 break;
     297             :             }
     298             :         }
     299             :         // are there attribute ends left?
     300       92269 :         for (size_t i = nEndIndex; i < pHints->GetEndCount(); ++i)
     301             :         {
     302       88576 :             SwTxtAttr *const pAttr(pHints->GetEnd(i));
     303       88576 :             if (!pAttr->IsFormatIgnoreEnd())
     304             :             {
     305       88002 :                 sal_Int32 const nNextEnd = *pAttr->GetAnyEnd();
     306       88002 :                 nNext = std::min(nNext, nNextEnd); // pick nearest one
     307       88002 :                 break;
     308             :             }
     309             :         }
     310             :     }
     311      146453 :     if (m_pTxtNode!=NULL) {
     312             :         // TODO: maybe use hints like FieldHints for this instead of looking at the text...
     313      146453 :         const sal_Int32 l = nNext<m_pTxtNode->Len() ? nNext : m_pTxtNode->Len();
     314      146453 :         sal_Int32 p=nPos;
     315      146453 :         const sal_Unicode* aStr = m_pTxtNode->GetTxt().getStr();
     316    54650607 :         while (p<l)
     317             :         {
     318    54358263 :             sal_Unicode aChar = aStr[p];
     319    54358263 :             if (aChar < CH_TXT_ATR_FORMELEMENT
     320    54358125 :                 || aChar > CH_TXT_ATR_FIELDEND)
     321             :             {
     322    54357701 :                 ++p;
     323             :             }
     324             :             else
     325             :             {
     326             :                 break;
     327             :             }
     328             :         }
     329      146453 :         if ((p<l && p>nPos) || nNext<=p)
     330       87876 :         nNext=p;
     331             :         else
     332       58577 :         nNext=p+1;
     333             :     }
     334      146453 :     if( pRedln )
     335        1307 :         return pRedln->GetNextRedln( nNext );
     336      145146 :     return nNext;
     337             : }
     338             : 
     339             : class SwMinMaxArgs
     340             : {
     341             : public:
     342             :     OutputDevice* pOut;
     343             :     SwViewShell const * pSh;
     344             :     sal_uLong &rMin;
     345             :     sal_uLong &rMax;
     346             :     sal_uLong &rAbsMin;
     347             :     long nRowWidth;
     348             :     long nWordWidth;
     349             :     long nWordAdd;
     350             :     sal_Int32 nNoLineBreak;
     351         528 :     SwMinMaxArgs( OutputDevice* pOutI, SwViewShell const * pShI, sal_uLong& rMinI, sal_uLong &rMaxI, sal_uLong &rAbsI )
     352         528 :         : pOut( pOutI ), pSh( pShI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
     353         528 :         { nRowWidth = nWordWidth = nWordAdd = 0; nNoLineBreak = COMPLETE_STRING; }
     354          16 :     void Minimum( long nNew ) const { if( (long)rMin < nNew ) rMin = nNew; }
     355          14 :     void NewWord() { nWordAdd = nWordWidth = 0; }
     356             : };
     357             : 
     358          34 : static bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const OUString &rTxt,
     359             :     sal_Int32 nIdx, sal_Int32 nEnd )
     360             : {
     361          34 :     bool bRet = false;
     362          84 :     while( nIdx < nEnd )
     363             :     {
     364          16 :         sal_Int32 nStop = nIdx;
     365          16 :         bool bClear = false;
     366          16 :         LanguageType eLang = pFnt->GetLanguage();
     367          16 :         if( g_pBreakIt->GetBreakIter().is() )
     368             :         {
     369          16 :             bClear = CH_BLANK == rTxt[ nStop ];
     370          32 :             Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary( rTxt, nIdx,
     371          16 :                              g_pBreakIt->GetLocale( eLang ),
     372          32 :                              WordType::DICTIONARY_WORD, true ) );
     373          16 :             nStop = aBndry.endPos;
     374          16 :             if( nIdx <= aBndry.startPos && nIdx && nIdx-1 != rArg.nNoLineBreak )
     375           2 :                 rArg.NewWord();
     376          16 :             if( nStop == nIdx )
     377           0 :                 ++nStop;
     378          16 :             if( nStop > nEnd )
     379           0 :                 nStop = nEnd;
     380             :         }
     381             :         else
     382             :         {
     383           0 :             while( nStop < nEnd && CH_BLANK != rTxt[ nStop ] )
     384           0 :                 ++nStop;
     385           0 :             bClear = nStop == nIdx;
     386           0 :             if ( bClear )
     387             :             {
     388           0 :                 rArg.NewWord();
     389           0 :                 while( nStop < nEnd && CH_BLANK == rTxt[ nStop ] )
     390           0 :                     ++nStop;
     391             :             }
     392             :         }
     393             : 
     394          16 :         SwDrawTextInfo aDrawInf( rArg.pSh, *rArg.pOut, 0, rTxt, nIdx, nStop - nIdx );
     395          16 :         long nAktWidth = pFnt->_GetTxtSize( aDrawInf ).Width();
     396          16 :         rArg.nRowWidth += nAktWidth;
     397          16 :         if( bClear )
     398           0 :             rArg.NewWord();
     399             :         else
     400             :         {
     401          16 :             rArg.nWordWidth += nAktWidth;
     402          16 :             if( (long)rArg.rAbsMin < rArg.nWordWidth )
     403          16 :                 rArg.rAbsMin = rArg.nWordWidth;
     404          16 :             rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
     405          16 :             bRet = true;
     406             :         }
     407          16 :         nIdx = nStop;
     408          16 :     }
     409          34 :     return bRet;
     410             : }
     411             : 
     412           0 : bool SwTxtNode::IsSymbol( const sal_Int32 nBegin ) const
     413             : {
     414           0 :     SwScriptInfo aScriptInfo;
     415           0 :     SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     416           0 :     aIter.Seek( nBegin );
     417             :     return aIter.GetFnt()->IsSymbol(
     418           0 :         const_cast<SwViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()) );
     419             : }
     420             : 
     421             : class SwMinMaxNodeArgs
     422             : {
     423             : public:
     424             :     sal_uLong nMaxWidth;    // sum of all frame widths
     425             :     long nMinWidth;         // biggest frame
     426             :     long nLeftRest;         // space not already covered by frames in the left margin
     427             :     long nRightRest;        // space not already covered by frames in the right margin
     428             :     long nLeftDiff;         // Min/Max-difference of the frame in the left margin
     429             :     long nRightDiff;        // Min/Max-difference of the frame in the right margin
     430             :     sal_uLong nIndx;        // index of the node
     431           0 :     void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
     432             : };
     433             : 
     434           6 : static void lcl_MinMaxNode( SwFrmFmt* pNd, SwMinMaxNodeArgs* pIn )
     435             : {
     436           6 :     const SwFmtAnchor& rFmtA = pNd->GetAnchor();
     437             : 
     438           6 :     if ((FLY_AT_PARA == rFmtA.GetAnchorId()) ||
     439           0 :         (FLY_AT_CHAR == rFmtA.GetAnchorId()))
     440             :     {
     441           6 :         const SwPosition *pPos = rFmtA.GetCntntAnchor();
     442             :         OSL_ENSURE(pPos && pIn, "Unexpected NULL arguments");
     443           6 :         if (!pPos || !pIn || pIn->nIndx != pPos->nNode.GetIndex())
     444           6 :             return;
     445             :     }
     446             : 
     447             :     long nMin, nMax;
     448           0 :     SwHTMLTableLayout *pLayout = 0;
     449           0 :     const bool bIsDrawFrmFmt = pNd->Which()==RES_DRAWFRMFMT;
     450           0 :     if( !bIsDrawFrmFmt )
     451             :     {
     452             :         // Does the frame contain a table at the start or the end?
     453           0 :         const SwNodes& rNodes = pNd->GetDoc()->GetNodes();
     454           0 :         const SwFmtCntnt& rFlyCntnt = pNd->GetCntnt();
     455           0 :         sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
     456           0 :         SwTableNode* pTblNd = rNodes[nStt+1]->GetTableNode();
     457           0 :         if( !pTblNd )
     458             :         {
     459           0 :             SwNode *pNd2 = rNodes[nStt];
     460           0 :             pNd2 = rNodes[pNd2->EndOfSectionIndex()-1];
     461           0 :             if( pNd2->IsEndNode() )
     462           0 :                 pTblNd = pNd2->StartOfSectionNode()->GetTableNode();
     463             :         }
     464             : 
     465           0 :         if( pTblNd )
     466           0 :             pLayout = pTblNd->GetTable().GetHTMLTableLayout();
     467             :     }
     468             : 
     469           0 :     const SwFmtHoriOrient& rOrient = pNd->GetHoriOrient();
     470           0 :     sal_Int16 eHoriOri = rOrient.GetHoriOrient();
     471             : 
     472             :     long nDiff;
     473           0 :     if( pLayout )
     474             :     {
     475           0 :         nMin = pLayout->GetMin();
     476           0 :         nMax = pLayout->GetMax();
     477           0 :         nDiff = nMax - nMin;
     478             :     }
     479             :     else
     480             :     {
     481           0 :         if( bIsDrawFrmFmt )
     482             :         {
     483           0 :             const SdrObject* pSObj = pNd->FindSdrObject();
     484           0 :             if( pSObj )
     485           0 :                 nMin = pSObj->GetCurrentBoundRect().GetWidth();
     486             :             else
     487           0 :                 nMin = 0;
     488             : 
     489             :         }
     490             :         else
     491             :         {
     492           0 :             const SwFmtFrmSize &rSz = pNd->GetFrmSize();
     493           0 :             nMin = rSz.GetWidth();
     494             :         }
     495           0 :         nMax = nMin;
     496           0 :         nDiff = 0;
     497             :     }
     498             : 
     499           0 :     const SvxLRSpaceItem &rLR = pNd->GetLRSpace();
     500           0 :     nMin += rLR.GetLeft();
     501           0 :     nMin += rLR.GetRight();
     502           0 :     nMax += rLR.GetLeft();
     503           0 :     nMax += rLR.GetRight();
     504             : 
     505           0 :     if( SURROUND_THROUGHT == pNd->GetSurround().GetSurround() )
     506             :     {
     507           0 :         pIn->Minimum( nMin );
     508           0 :         return;
     509             :     }
     510             : 
     511             :     // Frames, which are left- or right-aligned are only party considered
     512             :     // when calculating the maximum, since the border is already being considered.
     513             :     // Only if the frame extends into the text body, this part is being added
     514           0 :     switch( eHoriOri )
     515             :     {
     516             :         case text::HoriOrientation::RIGHT:
     517             :         {
     518           0 :             if( nDiff )
     519             :             {
     520           0 :                 pIn->nRightRest -= pIn->nRightDiff;
     521           0 :                 pIn->nRightDiff = nDiff;
     522             :             }
     523           0 :             if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() )
     524             :             {
     525           0 :                 if( pIn->nRightRest > 0 )
     526           0 :                     pIn->nRightRest = 0;
     527             :             }
     528           0 :             pIn->nRightRest -= nMin;
     529           0 :             break;
     530             :         }
     531             :         case text::HoriOrientation::LEFT:
     532             :         {
     533           0 :             if( nDiff )
     534             :             {
     535           0 :                 pIn->nLeftRest -= pIn->nLeftDiff;
     536           0 :                 pIn->nLeftDiff = nDiff;
     537             :             }
     538           0 :             if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() &&
     539           0 :                 pIn->nLeftRest < 0 )
     540           0 :                 pIn->nLeftRest = 0;
     541           0 :             pIn->nLeftRest -= nMin;
     542           0 :             break;
     543             :         }
     544             :         default:
     545             :         {
     546           0 :             pIn->nMaxWidth += nMax;
     547           0 :             pIn->Minimum( nMin );
     548             :         }
     549             :     }
     550             : }
     551             : 
     552             : #define FLYINCNT_MIN_WIDTH 284
     553             : 
     554             : /**
     555             :  * Changing this method very likely requires changing of GetScalingOfSelectedText
     556             :  */
     557         528 : void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMax,
     558             :                                sal_uLong& rAbsMin, OutputDevice* pOut ) const
     559             : {
     560         528 :     SwViewShell const * pSh = GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
     561         528 :     if( !pOut )
     562             :     {
     563         528 :         if( pSh )
     564           0 :             pOut = pSh->GetWin();
     565         528 :         if( !pOut )
     566         528 :             pOut = Application::GetDefaultDevice();
     567             :     }
     568             : 
     569         528 :     MapMode aOldMap( pOut->GetMapMode() );
     570         528 :     pOut->SetMapMode( MapMode( MAP_TWIP ) );
     571             : 
     572         528 :     rMin = 0;
     573         528 :     rMax = 0;
     574         528 :     rAbsMin = 0;
     575             : 
     576         528 :     const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
     577         528 :     long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( true );
     578             :     short nFLOffs;
     579             :     // For enumerations a negative first line indentation is probably filled already
     580         528 :     if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
     581         528 :         nLROffset = nFLOffs;
     582             : 
     583             :     SwMinMaxNodeArgs aNodeArgs;
     584         528 :     aNodeArgs.nMinWidth = 0;
     585         528 :     aNodeArgs.nMaxWidth = 0;
     586         528 :     aNodeArgs.nLeftRest = nLROffset;
     587         528 :     aNodeArgs.nRightRest = rSpace.GetRight();
     588         528 :     aNodeArgs.nLeftDiff = 0;
     589         528 :     aNodeArgs.nRightDiff = 0;
     590         528 :     if( nIndex )
     591             :     {
     592         528 :         SwFrmFmts* pTmp = (SwFrmFmts*)GetDoc()->GetSpzFrmFmts();
     593         528 :         if( pTmp )
     594             :         {
     595         528 :             aNodeArgs.nIndx = nIndex;
     596         534 :             BOOST_FOREACH( SwFrmFmt *pFmt, *pTmp )
     597           6 :                 lcl_MinMaxNode( pFmt, &aNodeArgs );
     598             :         }
     599             :     }
     600         528 :     if( aNodeArgs.nLeftRest < 0 )
     601           0 :         aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
     602         528 :     aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
     603         528 :     if( aNodeArgs.nLeftRest < 0 )
     604           0 :         aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;
     605             : 
     606         528 :     if( aNodeArgs.nRightRest < 0 )
     607           0 :         aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
     608         528 :     aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
     609         528 :     if( aNodeArgs.nRightRest < 0 )
     610           0 :         aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;
     611             : 
     612        1056 :     SwScriptInfo aScriptInfo;
     613        1056 :     SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     614         528 :     sal_Int32 nIdx = 0;
     615         528 :     aIter.SeekAndChgAttrIter( nIdx, pOut );
     616         528 :     sal_Int32 nLen = m_Text.getLength();
     617         528 :     long nAktWidth = 0;
     618         528 :     long nAdd = 0;
     619         528 :     SwMinMaxArgs aArg( pOut, pSh, rMin, rMax, rAbsMin );
     620        1078 :     while( nIdx < nLen )
     621             :     {
     622          22 :         sal_Int32 nNextChg = aIter.GetNextAttr();
     623          22 :         sal_Int32 nStop = aScriptInfo.NextScriptChg( nIdx );
     624          22 :         if( nNextChg > nStop )
     625          12 :             nNextChg = nStop;
     626          22 :         SwTxtAttr *pHint = NULL;
     627          22 :         sal_Unicode cChar = CH_BLANK;
     628          22 :         nStop = nIdx;
     629         248 :         while( nStop < nLen && nStop < nNextChg &&
     630         144 :                CH_TAB != ( cChar = m_Text[nStop] ) &&
     631          72 :                CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
     632         154 :                CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
     633             :                !pHint )
     634             :         {
     635         108 :             if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
     636          72 :                 || ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
     637          48 :                 ++nStop;
     638             :         }
     639          22 :         if ( lcl_MinMaxString( aArg, aIter.GetFnt(), m_Text, nIdx, nStop ) )
     640             :         {
     641          10 :             nAdd = 20;
     642             :         }
     643          22 :         nIdx = nStop;
     644          22 :         aIter.SeekAndChgAttrIter( nIdx, pOut );
     645          22 :         switch( cChar )
     646             :         {
     647             :             case CH_BREAK  :
     648             :             {
     649           0 :                 if( (long)rMax < aArg.nRowWidth )
     650           0 :                     rMax = aArg.nRowWidth;
     651           0 :                 aArg.nRowWidth = 0;
     652           0 :                 aArg.NewWord();
     653           0 :                 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
     654             :             }
     655           0 :             break;
     656             :             case CH_TAB    :
     657             :             {
     658           0 :                 aArg.NewWord();
     659           0 :                 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
     660             :             }
     661           0 :             break;
     662             :             case CHAR_SOFTHYPHEN:
     663           0 :                 ++nIdx;
     664           0 :             break;
     665             :             case CHAR_HARDBLANK:
     666             :             case CHAR_HARDHYPHEN:
     667             :             {
     668           0 :                 OUString sTmp( cChar );
     669           0 :                 SwDrawTextInfo aDrawInf( const_cast<SwViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()),
     670           0 :                     *pOut, 0, sTmp, 0, 1, 0, false );
     671           0 :                 nAktWidth = aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     672           0 :                 aArg.nWordWidth += nAktWidth;
     673           0 :                 aArg.nRowWidth += nAktWidth;
     674           0 :                 if( (long)rAbsMin < aArg.nWordWidth )
     675           0 :                     rAbsMin = aArg.nWordWidth;
     676           0 :                 aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
     677           0 :                 aArg.nNoLineBreak = nIdx++;
     678             :             }
     679           0 :             break;
     680             :             case CH_TXTATR_BREAKWORD:
     681             :             case CH_TXTATR_INWORD:
     682             :             {
     683          12 :                 if( !pHint )
     684           0 :                     break;
     685          12 :                 long nOldWidth = aArg.nWordWidth;
     686          12 :                 long nOldAdd = aArg.nWordAdd;
     687          12 :                 aArg.NewWord();
     688             : 
     689          12 :                 switch( pHint->Which() )
     690             :                 {
     691             :                     case RES_TXTATR_FLYCNT :
     692             :                     {
     693           0 :                         SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
     694           0 :                         const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
     695           0 :                         if( RES_DRAWFRMFMT == pFrmFmt->Which() )
     696             :                         {
     697           0 :                             const SdrObject* pSObj = pFrmFmt->FindSdrObject();
     698           0 :                             if( pSObj )
     699           0 :                                 nAktWidth = pSObj->GetCurrentBoundRect().GetWidth();
     700             :                             else
     701           0 :                                 nAktWidth = 0;
     702             :                         }
     703             :                         else
     704             :                         {
     705           0 :                             const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
     706           0 :                             if( RES_FLYFRMFMT == pFrmFmt->Which()
     707           0 :                                 && rTmpSize.GetWidthPercent() )
     708             :                             {
     709             :                                 // This is a hack for the wollowing situation: In the paragraph there's a
     710             :                                 // text frame with relative size. Then let's take 0.5 cm as minimum width
     711             :                                 // and USHRT_MAX as maximum width
     712             :                                 // It were cleaner and maybe necessary later on to iterate over the content
     713             :                                 // of the text frame and call GetMinMaxSize recursively
     714           0 :                                 nAktWidth = FLYINCNT_MIN_WIDTH; // 0.5 cm
     715           0 :                                 if( (long)rMax < USHRT_MAX )
     716           0 :                                     rMax = USHRT_MAX;
     717             :                             }
     718             :                             else
     719           0 :                                 nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
     720             :                         }
     721           0 :                         nAktWidth += rLR.GetLeft();
     722           0 :                         nAktWidth += rLR.GetRight();
     723           0 :                         aArg.nWordAdd = nOldWidth + nOldAdd;
     724           0 :                         aArg.nWordWidth = nAktWidth;
     725           0 :                         aArg.nRowWidth += nAktWidth;
     726           0 :                         if( (long)rAbsMin < aArg.nWordWidth )
     727           0 :                             rAbsMin = aArg.nWordWidth;
     728           0 :                         aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
     729           0 :                         break;
     730             :                     }
     731             :                     case RES_TXTATR_FTN :
     732             :                     {
     733           0 :                         const OUString aTxt = pHint->GetFtn().GetNumStr();
     734           0 :                         if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
     735           0 :                             aTxt.getLength() ) )
     736           0 :                             nAdd = 20;
     737           0 :                         break;
     738             :                     }
     739             : 
     740             :                     case RES_TXTATR_FIELD :
     741             :                     case RES_TXTATR_ANNOTATION :
     742             :                         {
     743          12 :                             SwField *pFld = (SwField*)pHint->GetFmtFld().GetField();
     744          12 :                             const OUString aTxt = pFld->ExpandField(true);
     745          12 :                             if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
     746          12 :                                 aTxt.getLength() ) )
     747           6 :                                 nAdd = 20;
     748          12 :                             break;
     749             :                         }
     750           0 :                     default: aArg.nWordWidth = nOldWidth;
     751           0 :                         aArg.nWordAdd = nOldAdd;
     752             : 
     753             :                 }
     754          12 :                 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
     755             :             }
     756          12 :             break;
     757             :         }
     758             :     }
     759         528 :     if( (long)rMax < aArg.nRowWidth )
     760          16 :         rMax = aArg.nRowWidth;
     761             : 
     762         528 :     nLROffset += rSpace.GetRight();
     763             : 
     764         528 :     rAbsMin += nLROffset;
     765         528 :     rAbsMin += nAdd;
     766         528 :     rMin += nLROffset;
     767         528 :     rMin += nAdd;
     768         528 :     if( (long)rMin < aNodeArgs.nMinWidth )
     769           0 :         rMin = aNodeArgs.nMinWidth;
     770         528 :     if( (long)rAbsMin < aNodeArgs.nMinWidth )
     771           0 :         rAbsMin = aNodeArgs.nMinWidth;
     772         528 :     rMax += aNodeArgs.nMaxWidth;
     773         528 :     rMax += nLROffset;
     774         528 :     rMax += nAdd;
     775         528 :     if( rMax < rMin ) // e.g. Frames with flow through only contribute to the minimum
     776           0 :         rMax = rMin;
     777        1056 :     pOut->SetMapMode( aOldMap );
     778         528 : }
     779             : 
     780             : /**
     781             :  * Calculates the width of the text part specified by nStt and nEnd,
     782             :  * the height of the line containing nStt is devided by this width,
     783             :  * indicating the scaling factor, if the text part is rotated.
     784             :  * Having CH_BREAKs in the text part, this method returns the scaling
     785             :  * factor for the longest of the text parts separated by the CH_BREAK
     786             :  *
     787             :  * Changing this method very likely requires changing of "GetMinMaxSize"
     788             :  */
     789           0 : sal_uInt16 SwTxtNode::GetScalingOfSelectedText( sal_Int32 nStt, sal_Int32 nEnd )
     790             :     const
     791             : {
     792           0 :     SwViewShell const * pSh = GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell();
     793           0 :     OutputDevice* pOut = NULL;
     794             : 
     795           0 :     if ( pSh )
     796           0 :         pOut = &pSh->GetRefDev();
     797             :     else
     798             :     {
     799             :         // Access via StarONE, there's no need for an existing or active shell
     800           0 :         if ( getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) )
     801           0 :             pOut = Application::GetDefaultDevice();
     802             :         else
     803           0 :             pOut = getIDocumentDeviceAccess()->getReferenceDevice( true );
     804             :     }
     805             : 
     806             :     OSL_ENSURE( pOut, "GetScalingOfSelectedText without outdev" );
     807             : 
     808           0 :     MapMode aOldMap( pOut->GetMapMode() );
     809           0 :     pOut->SetMapMode( MapMode( MAP_TWIP ) );
     810             : 
     811           0 :     if ( nStt == nEnd )
     812             :     {
     813           0 :         if ( !g_pBreakIt->GetBreakIter().is() )
     814           0 :             return 100;
     815             : 
     816           0 :         SwScriptInfo aScriptInfo;
     817           0 :         SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     818           0 :         aIter.SeekAndChgAttrIter( nStt, pOut );
     819             : 
     820             :         Boundary aBound =
     821           0 :             g_pBreakIt->GetBreakIter()->getWordBoundary( GetTxt(), nStt,
     822           0 :             g_pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
     823           0 :             WordType::DICTIONARY_WORD, true );
     824             : 
     825           0 :         if ( nStt == aBound.startPos )
     826             :         {
     827             :             // cursor is at left or right border of word
     828           0 :             pOut->SetMapMode( aOldMap );
     829           0 :             return 100;
     830             :         }
     831             : 
     832           0 :         nStt = aBound.startPos;
     833           0 :         nEnd = aBound.endPos;
     834             : 
     835           0 :         if ( nStt == nEnd )
     836             :         {
     837           0 :             pOut->SetMapMode( aOldMap );
     838           0 :             return 100;
     839           0 :         }
     840             :     }
     841             : 
     842           0 :     SwScriptInfo aScriptInfo;
     843           0 :     SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     844             : 
     845             :     // We do not want scaling attributes to be considered during this
     846             :     // calculation. For this, we push a temporary scaling attribute with
     847             :     // scaling value 100 and priority flag on top of the scaling stack
     848           0 :     SwAttrHandler& rAH = aIter.GetAttrHandler();
     849           0 :     SvxCharScaleWidthItem aItem(100, RES_CHRATR_SCALEW);
     850           0 :     SwTxtAttrEnd aAttr( aItem, nStt, nEnd );
     851           0 :     aAttr.SetPriorityAttr( true );
     852           0 :     rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
     853             : 
     854           0 :     sal_Int32 nIdx = nStt;
     855             : 
     856           0 :     sal_uLong nWidth = 0;
     857           0 :     sal_uLong nProWidth = 0;
     858             : 
     859           0 :     while( nIdx < nEnd )
     860             :     {
     861           0 :         aIter.SeekAndChgAttrIter( nIdx, pOut );
     862             : 
     863             :         // scan for end of portion
     864           0 :         const sal_Int32 nNextChg = std::max(aIter.GetNextAttr(), aScriptInfo.NextScriptChg( nIdx ));
     865             : 
     866           0 :         sal_Int32 nStop = nIdx;
     867           0 :         sal_Unicode cChar = CH_BLANK;
     868           0 :         SwTxtAttr* pHint = NULL;
     869             : 
     870             :         // stop at special characters in [ nIdx, nNextChg ]
     871           0 :         while( nStop < nEnd && nStop < nNextChg )
     872             :         {
     873           0 :             cChar = m_Text[nStop];
     874           0 :             if (
     875           0 :                 CH_TAB == cChar ||
     876           0 :                 CH_BREAK == cChar ||
     877           0 :                 CHAR_HARDBLANK == cChar ||
     878           0 :                 CHAR_HARDHYPHEN == cChar ||
     879           0 :                 CHAR_SOFTHYPHEN == cChar ||
     880             :                 (
     881           0 :                   (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar) &&
     882             :                   (0 == (pHint = aIter.GetAttr(nStop)))
     883             :                 )
     884             :                )
     885             :             {
     886           0 :                 break;
     887             :             }
     888             :             else
     889           0 :                 ++nStop;
     890             :         }
     891             : 
     892             :         // calculate text widths up to cChar
     893           0 :         if ( nStop > nIdx )
     894             :         {
     895           0 :             SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nIdx, nStop - nIdx );
     896           0 :             nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     897             :         }
     898             : 
     899           0 :         nIdx = nStop;
     900           0 :         aIter.SeekAndChgAttrIter( nIdx, pOut );
     901             : 
     902           0 :         if ( cChar == CH_BREAK )
     903             :         {
     904           0 :             nWidth = std::max( nWidth, nProWidth );
     905           0 :             nProWidth = 0;
     906           0 :             nIdx++;
     907             :         }
     908           0 :         else if ( cChar == CH_TAB )
     909             :         {
     910             :             // tab receives width of one space
     911           0 :             OUString sTmp( CH_BLANK );
     912           0 :             SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
     913           0 :             nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     914           0 :             nIdx++;
     915             :         }
     916           0 :         else if ( cChar == CHAR_SOFTHYPHEN )
     917           0 :             ++nIdx;
     918           0 :         else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
     919             :         {
     920           0 :             OUString sTmp( cChar );
     921           0 :             SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
     922           0 :             nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     923           0 :             nIdx++;
     924             :         }
     925           0 :         else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || cChar == CH_TXTATR_INWORD ) )
     926             :         {
     927           0 :             switch( pHint->Which() )
     928             :             {
     929             :             case RES_TXTATR_FTN :
     930             :                 {
     931           0 :                     const OUString aTxt = pHint->GetFtn().GetNumStr();
     932           0 :                     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.getLength() );
     933             : 
     934           0 :                     nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     935           0 :                     break;
     936             :                 }
     937             : 
     938             :             case RES_TXTATR_FIELD :
     939             :             case RES_TXTATR_ANNOTATION :
     940             :                 {
     941           0 :                     SwField *pFld = (SwField*)pHint->GetFmtFld().GetField();
     942           0 :                     OUString const aTxt = pFld->ExpandField(true);
     943           0 :                     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.getLength() );
     944             : 
     945           0 :                     nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     946           0 :                     break;
     947             :                 }
     948             : 
     949             :             default:
     950             :                 {
     951             :                     // any suggestions for a default action?
     952             :                 }
     953             :             } // end of switch
     954           0 :             nIdx++;
     955             :         } // end of while
     956             :     }
     957             : 
     958           0 :     nWidth = std::max( nWidth, nProWidth );
     959             : 
     960             :     // search for a text frame this node belongs to
     961           0 :     SwIterator<SwTxtFrm,SwTxtNode> aFrmIter( *this );
     962           0 :     SwTxtFrm* pFrm = 0;
     963           0 :     for( SwTxtFrm* pTmpFrm = aFrmIter.First(); pTmpFrm; pTmpFrm = aFrmIter.Next() )
     964             :     {
     965           0 :             if ( pTmpFrm->GetOfst() <= nStt &&
     966           0 :                 ( !pTmpFrm->GetFollow() ||
     967           0 :                    pTmpFrm->GetFollow()->GetOfst() > nStt ) )
     968             :             {
     969           0 :                 pFrm = pTmpFrm;
     970           0 :                 break;
     971             :             }
     972             :         }
     973             : 
     974             :     // search for the line containing nStt
     975           0 :     if ( pFrm && pFrm->HasPara() )
     976             :     {
     977           0 :         SwTxtInfo aInf( pFrm );
     978           0 :         SwTxtIter aLine( pFrm, &aInf );
     979           0 :         aLine.CharToLine( nStt );
     980           0 :         pOut->SetMapMode( aOldMap );
     981             :         return (sal_uInt16)( nWidth ?
     982           0 :             ( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
     983             :     }
     984             :     // no frame or no paragraph, we take the height of the character
     985             :     // at nStt as line height
     986             : 
     987           0 :     aIter.SeekAndChgAttrIter( nStt, pOut );
     988           0 :     pOut->SetMapMode( aOldMap );
     989             : 
     990           0 :     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nStt, 1 );
     991             :     return (sal_uInt16)
     992           0 :            ( nWidth ? ((100 * aIter.GetFnt()->_GetTxtSize( aDrawInf ).Height()) / nWidth ) : 0 );
     993             : }
     994             : 
     995           0 : SwTwips SwTxtNode::GetWidthOfLeadingTabs() const
     996             : {
     997           0 :     SwTwips nRet = 0;
     998             : 
     999           0 :     sal_Int32 nIdx = 0;
    1000             : 
    1001           0 :     while ( nIdx < GetTxt().getLength() )
    1002             :     {
    1003           0 :         const sal_Unicode cCh = GetTxt()[nIdx];
    1004           0 :         if ( cCh!='\t' && cCh!=' ' )
    1005             :         {
    1006           0 :             break;
    1007             :         }
    1008           0 :         ++nIdx;
    1009             :     }
    1010             : 
    1011           0 :     if ( nIdx > 0 )
    1012             :     {
    1013           0 :         SwPosition aPos( *this );
    1014           0 :         aPos.nContent += nIdx;
    1015             : 
    1016             :         // Find the non-follow text frame:
    1017           0 :         SwIterator<SwTxtFrm,SwTxtNode> aIter( *this );
    1018           0 :         for( SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
    1019             :         {
    1020             :             // Only consider master frames:
    1021           0 :             if ( !pFrm->IsFollow() )
    1022             :             {
    1023           0 :                 SWRECTFN( pFrm )
    1024           0 :                 SwRect aRect;
    1025           0 :                 pFrm->GetCharRect( aRect, aPos );
    1026           0 :                 nRet = pFrm->IsRightToLeft() ?
    1027           0 :                             (pFrm->*fnRect->fnGetPrtRight)() - (aRect.*fnRect->fnGetRight)() :
    1028           0 :                             (aRect.*fnRect->fnGetLeft)() - (pFrm->*fnRect->fnGetPrtLeft)();
    1029           0 :                 break;
    1030             :             }
    1031           0 :         }
    1032             :     }
    1033             : 
    1034           0 :     return nRet;
    1035         270 : }
    1036             : 
    1037             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10