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

Generated by: LCOV version 1.11