LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/text - itratr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 246 530 46.4 %
Date: 2013-07-09 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 <viewsh.hxx>   // ViewShell
      38             : #include <rootfrm.hxx>
      39             : #include <docary.hxx>
      40             : #include <ndtxt.hxx>
      41             : #include <dcontact.hxx>
      42             : #include <fldbas.hxx>      // SwField
      43             : #include <pam.hxx>         // SwPosition        (lcl_MinMaxNode)
      44             : #include <itratr.hxx>
      45             : #include <htmltbl.hxx>
      46             : #include <swtable.hxx>
      47             : #include <redlnitr.hxx>
      48             : #include <fmtsrnd.hxx>
      49             : #include <itrtxt.hxx>
      50             : #include <breakit.hxx>
      51             : #include <com/sun/star/i18n/WordType.hpp>
      52             : #include <com/sun/star/i18n/ScriptType.hpp>
      53             : #include <editeng/lrspitem.hxx>
      54             : #include <switerator.hxx>
      55             : #include <boost/foreach.hpp>
      56             : 
      57             : using namespace ::com::sun::star::i18n;
      58             : using namespace ::com::sun::star;
      59             : 
      60             : /*************************************************************************
      61             :  *                      SwAttrIter::Chg()
      62             :  *************************************************************************/
      63             : 
      64        4262 : void SwAttrIter::Chg( SwTxtAttr *pHt )
      65             : {
      66             :     OSL_ENSURE( pHt && pFnt, "No attribute of font available for change");
      67        4262 :     if( pRedln && pRedln->IsOn() )
      68          10 :         pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True );
      69             :     else
      70        4252 :         aAttrHandler.PushAndChg( *pHt, *pFnt );
      71        4262 :     nChgCnt++;
      72        4262 : }
      73             : 
      74             : /*************************************************************************
      75             :  *                      SwAttrIter::Rst()
      76             :  *************************************************************************/
      77             : 
      78        1589 : void SwAttrIter::Rst( SwTxtAttr *pHt )
      79             : {
      80             :     OSL_ENSURE( pHt && pFnt, "No attribute of font available for reset");
      81             :     // get top from stack after removing pHt
      82        1589 :     if( pRedln && pRedln->IsOn() )
      83          17 :         pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False );
      84             :     else
      85        1572 :         aAttrHandler.PopAndChg( *pHt, *pFnt );
      86        1589 :     nChgCnt--;
      87        1589 : }
      88             : 
      89             : /*************************************************************************
      90             :  *              virtual SwAttrIter::~SwAttrIter()
      91             :  *************************************************************************/
      92             : 
      93       97400 : SwAttrIter::~SwAttrIter()
      94             : {
      95       48700 :     delete pRedln;
      96       48700 :     delete pFnt;
      97       48700 : }
      98             : 
      99             : /*************************************************************************
     100             :  *                      SwAttrIter::GetAttr()
     101             :  *
     102             :  * Liefert fuer eine Position das Attribut, wenn das Attribut genau auf
     103             :  * der Position nPos liegt und kein EndIndex besitzt.
     104             :  * GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen
     105             :  * sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten"
     106             :  * Attribute sind z.B. Felder (die expandierten Text bereit halten) und
     107             :  * zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen
     108             :  * solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs
     109             :  * an der Startposition ein Sonderzeichen in den String einfuegt.
     110             :  * Der Formatierer stoesst auf das Sonderzeichen und holt sich per
     111             :  * GetAttr() das entartete Attribut.
     112             :  *************************************************************************/
     113             : 
     114        1195 : SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPosition ) const
     115             : {
     116        1195 :     return (m_pTxtNode) ? m_pTxtNode->GetTxtAttrForCharAt(nPosition) : 0;
     117             : }
     118             : 
     119             : /*************************************************************************
     120             :  *                        SwAttrIter::SeekAndChg()
     121             :  *************************************************************************/
     122             : 
     123       87263 : sal_Bool SwAttrIter::SeekAndChgAttrIter( const xub_StrLen nNewPos, OutputDevice* pOut )
     124             : {
     125       87263 :     sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
     126       87263 :     if ( pLastOut != pOut )
     127             :     {
     128       10956 :         pLastOut = pOut;
     129       10956 :         pFnt->SetFntChg( sal_True );
     130       10956 :         bChg = sal_True;
     131             :     }
     132       87263 :     if( bChg )
     133             :     {
     134             :         // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
     135             :         // des gewuenschten Fonts ...
     136       85907 :         if ( !nChgCnt && !nPropFont )
     137       80122 :             pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
     138      160244 :                 aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
     139       85907 :         pFnt->ChgPhysFnt( pShell, *pOut );
     140             :     }
     141       87263 :     return bChg;
     142             : }
     143             : 
     144           0 : sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
     145             : {
     146           0 :     Seek( nNewPos );
     147           0 :     if ( !nChgCnt && !nPropFont )
     148           0 :         pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
     149           0 :             aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
     150           0 :     return pFnt->IsSymbol( pShell );
     151             : }
     152             : 
     153             : /*************************************************************************
     154             :  *                        SwAttrIter::SeekStartAndChg()
     155             :  *************************************************************************/
     156             : 
     157        1241 : sal_Bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont )
     158             : {
     159        1241 :     if ( pRedln && pRedln->ExtOn() )
     160           0 :         pRedln->LeaveExtend( *pFnt, 0 );
     161             : 
     162             :     // reset font to its original state
     163        1241 :     aAttrHandler.Reset();
     164        1241 :     aAttrHandler.ResetFont( *pFnt );
     165             : 
     166        1241 :     nStartIndex = nEndIndex = nPos = nChgCnt = 0;
     167        1241 :     if( nPropFont )
     168           0 :         pFnt->SetProportion( nPropFont );
     169        1241 :     if( pRedln )
     170             :     {
     171           0 :         pRedln->Clear( pFnt );
     172           0 :         if( !bParaFont )
     173           0 :             nChgCnt = nChgCnt + pRedln->Seek( *pFnt, 0, STRING_LEN );
     174             :         else
     175           0 :             pRedln->Reset();
     176             :     }
     177             : 
     178        1241 :     if ( pHints && !bParaFont )
     179             :     {
     180             :         SwTxtAttr *pTxtAttr;
     181             :         // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
     182             :         // das TextAttribut an Position 0 beginnt ...
     183        1755 :         while ( ( nStartIndex < pHints->GetStartCount() ) &&
     184         702 :                 !(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
     185             :         {
     186             :             // oeffne die TextAttribute
     187         351 :             Chg( pTxtAttr );
     188         351 :             nStartIndex++;
     189             :         }
     190             :     }
     191             : 
     192        1241 :     sal_Bool bChg = pFnt->IsFntChg();
     193        1241 :     if ( pLastOut != pOut )
     194             :     {
     195        1223 :         pLastOut = pOut;
     196        1223 :         pFnt->SetFntChg( sal_True );
     197        1223 :         bChg = sal_True;
     198             :     }
     199        1241 :     if( bChg )
     200             :     {
     201             :         // wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
     202             :         // des gewuenschten Fonts ...
     203        1241 :         if ( !nChgCnt && !nPropFont )
     204         890 :             pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
     205        1780 :                 aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
     206        1241 :         pFnt->ChgPhysFnt( pShell, *pOut );
     207             :     }
     208        1241 :     return bChg;
     209             : }
     210             : 
     211             : /*************************************************************************
     212             :  *                       SwAttrIter::SeekFwd()
     213             :  *************************************************************************/
     214             : 
     215             : // AMA: Neuer AttrIter Nov 94
     216             : 
     217        8079 : void SwAttrIter::SeekFwd( const xub_StrLen nNewPos )
     218             : {
     219             :     SwTxtAttr *pTxtAttr;
     220             : 
     221        8079 :     if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden...
     222             :     {
     223             :         // Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden.
     224             : 
     225             :         // Solange wir noch nicht am Ende des EndArrays angekommen sind &&
     226             :         // das TextAttribut vor oder an der neuen Position endet ...
     227       16565 :         while ( ( nEndIndex < pHints->GetEndCount() ) &&
     228        8674 :                 (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
     229             :         {
     230             :             // schliesse die TextAttribute, deren StartPos vor
     231             :             // oder an der alten nPos lag, die z.Z. geoeffnet sind.
     232        1939 :             if (*pTxtAttr->GetStart() <= nPos)  Rst( pTxtAttr );
     233        1939 :             nEndIndex++;
     234             :         }
     235             :     }
     236             :     else // ueberlies die nicht geoeffneten Enden
     237             :     {
     238       22808 :         while ( ( nEndIndex < pHints->GetEndCount() ) &&
     239       11226 :                 (*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
     240             :         {
     241        1376 :             nEndIndex++;
     242             :         }
     243             :     }
     244             :     // Solange wir noch nicht am Ende des StartArrays angekommen sind &&
     245             :     // das TextAttribut vor oder an der neuen Position beginnt ...
     246       42753 :     while ( ( nStartIndex < pHints->GetStartCount() ) &&
     247       20958 :            (*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos))
     248             :     {
     249             :         // oeffne die TextAttribute, deren Ende hinter der neuen Position liegt
     250        5637 :         if ( *pTxtAttr->GetAnyEnd() > nNewPos )  Chg( pTxtAttr );
     251        5637 :         nStartIndex++;
     252             :     }
     253             : 
     254        8079 : }
     255             : 
     256             : /*************************************************************************
     257             :  *                       SwAttrIter::Seek()
     258             :  *************************************************************************/
     259             : 
     260      105247 : sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
     261             : {
     262      105247 :     if ( pRedln && pRedln->ExtOn() )
     263           0 :         pRedln->LeaveExtend( *pFnt, nNewPos );
     264             : 
     265      105247 :     if( pHints )
     266             :     {
     267        8079 :         if( !nNewPos || nNewPos < nPos )
     268             :         {
     269        4488 :             if( pRedln )
     270          25 :                 pRedln->Clear( NULL );
     271             : 
     272             :             // reset font to its original state
     273        4488 :             aAttrHandler.Reset();
     274        4488 :             aAttrHandler.ResetFont( *pFnt );
     275             : 
     276        4488 :             if( nPropFont )
     277         152 :                 pFnt->SetProportion( nPropFont );
     278        4488 :             nStartIndex = nEndIndex = nPos = 0;
     279        4488 :             nChgCnt = 0;
     280             : 
     281             :             // Achtung!
     282             :             // resetting the font here makes it necessary to apply any
     283             :             // changes for extended input directly to the font
     284        4488 :             if ( pRedln && pRedln->ExtOn() )
     285             :             {
     286           0 :                 pRedln->UpdateExtFont( *pFnt );
     287           0 :                 ++nChgCnt;
     288             :             }
     289             :         }
     290        8079 :         SeekFwd( nNewPos );
     291             :     }
     292             : 
     293      105247 :     pFnt->SetActual( SwScriptInfo::WhichFont( nNewPos, 0, pScriptInfo ) );
     294             : 
     295      105247 :     if( pRedln )
     296          72 :         nChgCnt = nChgCnt + pRedln->Seek( *pFnt, nNewPos, nPos );
     297      105247 :     nPos = nNewPos;
     298             : 
     299      105247 :     if( nPropFont )
     300         164 :         pFnt->SetProportion( nPropFont );
     301             : 
     302      105247 :     return pFnt->IsFntChg();
     303             : }
     304             : 
     305             : /*************************************************************************
     306             :  *                      SwAttrIter::GetNextAttr()
     307             :  *************************************************************************/
     308             : 
     309       23347 : xub_StrLen SwAttrIter::GetNextAttr( ) const
     310             : {
     311       23347 :     xub_StrLen nNext = STRING_LEN;
     312       23347 :     if( pHints )
     313             :     {
     314             :         // are there attribute starts left?
     315        2342 :         for (sal_uInt16 i = nStartIndex; i < pHints->GetStartCount(); ++i)
     316             :         {
     317        1482 :             SwTxtAttr *const pAttr(pHints->GetStart(i));
     318        1482 :             if (!pAttr->IsFormatIgnoreStart())
     319             :             {
     320        1479 :                 nNext = *pAttr->GetStart();
     321        1479 :                 break;
     322             :             }
     323             :         }
     324             :         // are there attribute ends left?
     325        2344 :         for (sal_uInt16 i = nEndIndex; i < pHints->GetEndCount(); ++i)
     326             :         {
     327        2103 :             SwTxtAttr *const pAttr(pHints->GetEnd(i));
     328        2103 :             if (!pAttr->IsFormatIgnoreEnd())
     329             :             {
     330        2098 :                 xub_StrLen const nNextEnd = *pAttr->GetAnyEnd();
     331        2098 :                 nNext = std::min(nNext, nNextEnd); // pick nearest one
     332        2098 :                 break;
     333             :             }
     334             :         }
     335             :     }
     336       23347 :     if (m_pTxtNode!=NULL) {
     337             :         //TODO maybe use hints like FieldHints for this instead of looking at the text...
     338       23347 :         int l=(nNext<m_pTxtNode->Len()?nNext:m_pTxtNode->Len());
     339       23347 :         sal_uInt16 p=nPos;
     340    72164935 :         while (p<l && m_pTxtNode->GetTxt()[p] != CH_TXT_ATR_FIELDSTART
     341    24031640 :                    && m_pTxtNode->GetTxt()[p] != CH_TXT_ATR_FIELDEND
     342    48086585 :                    && m_pTxtNode->GetTxt()[p] != CH_TXT_ATR_FORMELEMENT)
     343             :         {
     344    24031616 :             ++p;
     345             :         }
     346       23347 :         if ((p<l && p>nPos) || nNext<=p)
     347        2075 :         nNext=p;
     348             :         else
     349       21272 :         nNext=p+1;
     350             :     }
     351       23347 :     if( pRedln )
     352          21 :         return pRedln->GetNextRedln( nNext );
     353       23326 :     return nNext;
     354             : }
     355             : 
     356             : class SwMinMaxArgs
     357             : {
     358             : public:
     359             :     OutputDevice* pOut;
     360             :     ViewShell* pSh;
     361             :     sal_uLong &rMin;
     362             :     sal_uLong &rMax;
     363             :     sal_uLong &rAbsMin;
     364             :     long nRowWidth;
     365             :     long nWordWidth;
     366             :     long nWordAdd;
     367             :     xub_StrLen nNoLineBreak;
     368           6 :     SwMinMaxArgs( OutputDevice* pOutI, ViewShell* pShI, sal_uLong& rMinI, sal_uLong &rMaxI, sal_uLong &rAbsI )
     369           6 :         : pOut( pOutI ), pSh( pShI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
     370           6 :         { nRowWidth = nWordWidth = nWordAdd = 0; nNoLineBreak = STRING_LEN; }
     371           3 :     void Minimum( long nNew ) const { if( (long)rMin < nNew ) rMin = nNew; }
     372           6 :     void NewWord() { nWordAdd = nWordWidth = 0; }
     373             : };
     374             : 
     375          15 : static sal_Bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const XubString &rTxt,
     376             :     xub_StrLen nIdx, xub_StrLen nEnd )
     377             : {
     378          15 :     sal_Bool bRet = sal_False;
     379          33 :     while( nIdx < nEnd )
     380             :     {
     381           3 :         xub_StrLen nStop = nIdx;
     382             :         sal_Bool bClear;
     383           3 :         LanguageType eLang = pFnt->GetLanguage();
     384           3 :         if( g_pBreakIt->GetBreakIter().is() )
     385             :         {
     386           3 :             bClear = CH_BLANK == rTxt.GetChar( nStop );
     387           6 :             Boundary aBndry( g_pBreakIt->GetBreakIter()->getWordBoundary( rTxt, nIdx,
     388           3 :                              g_pBreakIt->GetLocale( eLang ),
     389           6 :                              WordType::DICTIONARY_WORD, sal_True ) );
     390           3 :             nStop = (xub_StrLen)aBndry.endPos;
     391           3 :             if( nIdx <= aBndry.startPos && nIdx && nIdx-1 != rArg.nNoLineBreak )
     392           0 :                 rArg.NewWord();
     393           3 :             if( nStop == nIdx )
     394           0 :                 ++nStop;
     395           3 :             if( nStop > nEnd )
     396           0 :                 nStop = nEnd;
     397             :         }
     398             :         else
     399             :         {
     400           0 :             while( nStop < nEnd && CH_BLANK != rTxt.GetChar( nStop ) )
     401           0 :                 ++nStop;
     402           0 :             bClear = nStop == nIdx;
     403           0 :             if ( bClear )
     404             :             {
     405           0 :                 rArg.NewWord();
     406           0 :                 while( nStop < nEnd && CH_BLANK == rTxt.GetChar( nStop ) )
     407           0 :                     ++nStop;
     408             :             }
     409             :         }
     410             : 
     411           3 :         SwDrawTextInfo aDrawInf( rArg.pSh, *rArg.pOut, 0, rTxt, nIdx, nStop - nIdx );
     412           3 :         long nAktWidth = pFnt->_GetTxtSize( aDrawInf ).Width();
     413           3 :         rArg.nRowWidth += nAktWidth;
     414           3 :         if( bClear )
     415           0 :             rArg.NewWord();
     416             :         else
     417             :         {
     418           3 :             rArg.nWordWidth += nAktWidth;
     419           3 :             if( (long)rArg.rAbsMin < rArg.nWordWidth )
     420           3 :                 rArg.rAbsMin = rArg.nWordWidth;
     421           3 :             rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
     422           3 :             bRet = sal_True;
     423             :         }
     424           3 :         nIdx = nStop;
     425           3 :     }
     426          15 :     return bRet;
     427             : }
     428             : 
     429           0 : sal_Bool SwTxtNode::IsSymbol( const xub_StrLen nBegin ) const//swmodtest 080307
     430             : {
     431           0 :     SwScriptInfo aScriptInfo;
     432           0 :     SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     433           0 :     aIter.Seek( nBegin );
     434             :     return aIter.GetFnt()->IsSymbol(
     435           0 :         const_cast<ViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()) );//swmod 080311
     436             : }
     437             : 
     438             : class SwMinMaxNodeArgs
     439             : {
     440             : public:
     441             :     sal_uLong nMaxWidth;    // Summe aller Rahmenbreite
     442             :     long nMinWidth;     // Breitester Rahmen
     443             :     long nLeftRest;     // noch nicht von Rahmen ueberdeckter Platz im l. Rand
     444             :     long nRightRest;    // noch nicht von Rahmen ueberdeckter Platz im r. Rand
     445             :     long nLeftDiff;     // Min/Max-Differenz des Rahmens im linken Rand
     446             :     long nRightDiff;    // Min/Max-Differenz des Rahmens im rechten Rand
     447             :     sal_uLong nIndx;        // Indexnummer des Nodes
     448           0 :     void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
     449             : };
     450             : 
     451           6 : static void lcl_MinMaxNode( SwFrmFmt* pNd, SwMinMaxNodeArgs* pIn )
     452             : {
     453           6 :     const SwFmtAnchor& rFmtA = pNd->GetAnchor();
     454             : 
     455           6 :     bool bCalculate = false;
     456           6 :     if ((FLY_AT_PARA == rFmtA.GetAnchorId()) ||
     457           0 :         (FLY_AT_CHAR == rFmtA.GetAnchorId()))
     458             :     {
     459           6 :         bCalculate = true;
     460             :     }
     461             : 
     462           6 :     if (bCalculate)
     463             :     {
     464           6 :         const SwPosition *pPos = rFmtA.GetCntntAnchor();
     465             :         OSL_ENSURE(pPos && pIn, "Unexpected NULL arguments");
     466           6 :         if (!pPos || !pIn || pIn->nIndx != pPos->nNode.GetIndex())
     467           6 :             bCalculate = false;
     468             :     }
     469             : 
     470           6 :     if (bCalculate)
     471             :     {
     472             :         long nMin, nMax;
     473           0 :         SwHTMLTableLayout *pLayout = 0;
     474           0 :         MSHORT nWhich = pNd->Which();
     475           0 :         if( RES_DRAWFRMFMT != nWhich )
     476             :         {
     477             :             // Enthaelt der Rahmen zu Beginn oder am Ende eine Tabelle?
     478           0 :             const SwNodes& rNodes = pNd->GetDoc()->GetNodes();
     479           0 :             const SwFmtCntnt& rFlyCntnt = pNd->GetCntnt();
     480           0 :             sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
     481           0 :             SwTableNode* pTblNd = rNodes[nStt+1]->GetTableNode();
     482           0 :             if( !pTblNd )
     483             :             {
     484           0 :                 SwNode *pNd2 = rNodes[nStt];
     485           0 :                 pNd2 = rNodes[pNd2->EndOfSectionIndex()-1];
     486           0 :                 if( pNd2->IsEndNode() )
     487           0 :                     pTblNd = pNd2->StartOfSectionNode()->GetTableNode();
     488             :             }
     489             : 
     490           0 :             if( pTblNd )
     491           0 :                 pLayout = pTblNd->GetTable().GetHTMLTableLayout();
     492             :         }
     493             : 
     494           0 :         const SwFmtHoriOrient& rOrient = pNd->GetHoriOrient();
     495           0 :         sal_Int16 eHoriOri = rOrient.GetHoriOrient();
     496             : 
     497             :         long nDiff;
     498           0 :         if( pLayout )
     499             :         {
     500           0 :             nMin = pLayout->GetMin();
     501           0 :             nMax = pLayout->GetMax();
     502           0 :             nDiff = nMax - nMin;
     503             :         }
     504             :         else
     505             :         {
     506           0 :             if( RES_DRAWFRMFMT == nWhich )
     507             :             {
     508           0 :                 const SdrObject* pSObj = pNd->FindSdrObject();
     509           0 :                 if( pSObj )
     510           0 :                     nMin = pSObj->GetCurrentBoundRect().GetWidth();
     511             :                 else
     512           0 :                 nMin = 0;
     513             : 
     514             :             }
     515             :             else
     516             :             {
     517           0 :                 const SwFmtFrmSize &rSz = pNd->GetFrmSize();
     518           0 :                 nMin = rSz.GetWidth();
     519             :             }
     520           0 :             nMax = nMin;
     521           0 :             nDiff = 0;
     522             :         }
     523             : 
     524           0 :         const SvxLRSpaceItem &rLR = pNd->GetLRSpace();
     525           0 :         nMin += rLR.GetLeft();
     526           0 :         nMin += rLR.GetRight();
     527           0 :         nMax += rLR.GetLeft();
     528           0 :         nMax += rLR.GetRight();
     529             : 
     530           0 :         if( SURROUND_THROUGHT == pNd->GetSurround().GetSurround() )
     531             :         {
     532           0 :             pIn->Minimum( nMin );
     533           6 :             return;
     534             :         }
     535             : 
     536             :         // Rahmen, die recht bzw. links ausgerichtet sind, gehen nur
     537             :         // teilweise in die Max-Berechnung ein, da der Rand schon berueck-
     538             :         // sichtigt wird. Nur wenn die Rahmen in den Textkoerper ragen,
     539             :         // wird dieser Teil hinzuaddiert.
     540           0 :         switch( eHoriOri )
     541             :         {
     542             :             case text::HoriOrientation::RIGHT:
     543             :             {
     544           0 :                 if( nDiff )
     545             :                 {
     546           0 :                     pIn->nRightRest -= pIn->nRightDiff;
     547           0 :                     pIn->nRightDiff = nDiff;
     548             :                 }
     549           0 :                 if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() )
     550             :                 {
     551           0 :                     if( pIn->nRightRest > 0 )
     552           0 :                         pIn->nRightRest = 0;
     553             :                 }
     554           0 :                 pIn->nRightRest -= nMin;
     555           0 :                 break;
     556             :             }
     557             :             case text::HoriOrientation::LEFT:
     558             :             {
     559           0 :                 if( nDiff )
     560             :                 {
     561           0 :                     pIn->nLeftRest -= pIn->nLeftDiff;
     562           0 :                     pIn->nLeftDiff = nDiff;
     563             :                 }
     564           0 :                 if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() &&
     565           0 :                     pIn->nLeftRest < 0 )
     566           0 :                     pIn->nLeftRest = 0;
     567           0 :                 pIn->nLeftRest -= nMin;
     568           0 :                 break;
     569             :             }
     570             :             default:
     571             :             {
     572           0 :                 pIn->nMaxWidth += nMax;
     573           0 :                 pIn->Minimum( nMin );
     574             :             }
     575             :         }
     576             :     }
     577             : }
     578             : 
     579             : #define FLYINCNT_MIN_WIDTH 284
     580             : 
     581             : // changing this method very likely requires changing of
     582             : // "GetScalingOfSelectedText"
     583           6 : void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMax,
     584             :                                sal_uLong& rAbsMin, OutputDevice* pOut ) const
     585             : {
     586           6 :     ViewShell* pSh = 0;
     587           6 :     GetDoc()->GetEditShell( &pSh );
     588           6 :     if( !pOut )
     589             :     {
     590           6 :         if( pSh )
     591           0 :             pOut = pSh->GetWin();
     592           6 :         if( !pOut )
     593           6 :             pOut = GetpApp()->GetDefaultDevice();
     594             :     }
     595             : 
     596           6 :     MapMode aOldMap( pOut->GetMapMode() );
     597           6 :     pOut->SetMapMode( MapMode( MAP_TWIP ) );
     598             : 
     599           6 :     rMin = 0;
     600           6 :     rMax = 0;
     601           6 :     rAbsMin = 0;
     602             : 
     603           6 :     const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
     604           6 :     long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( sal_True );
     605             :     short nFLOffs;
     606             :     // Bei Numerierung ist ein neg. Erstzeileneinzug vermutlich
     607             :     // bereits gefuellt...
     608           6 :     if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
     609           6 :         nLROffset = nFLOffs;
     610             : 
     611             :     SwMinMaxNodeArgs aNodeArgs;
     612           6 :     aNodeArgs.nMinWidth = 0;
     613           6 :     aNodeArgs.nMaxWidth = 0;
     614           6 :     aNodeArgs.nLeftRest = nLROffset;
     615           6 :     aNodeArgs.nRightRest = rSpace.GetRight();
     616           6 :     aNodeArgs.nLeftDiff = 0;
     617           6 :     aNodeArgs.nRightDiff = 0;
     618           6 :     if( nIndex )
     619             :     {
     620           6 :         SwFrmFmts* pTmp = (SwFrmFmts*)GetDoc()->GetSpzFrmFmts();
     621           6 :         if( pTmp )
     622             :         {
     623           6 :             aNodeArgs.nIndx = nIndex;
     624          12 :             BOOST_FOREACH( SwFrmFmt *pFmt, *pTmp )
     625           6 :                 lcl_MinMaxNode( pFmt, &aNodeArgs );
     626             :         }
     627             :     }
     628           6 :     if( aNodeArgs.nLeftRest < 0 )
     629           0 :         aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
     630           6 :     aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
     631           6 :     if( aNodeArgs.nLeftRest < 0 )
     632           0 :         aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;
     633             : 
     634           6 :     if( aNodeArgs.nRightRest < 0 )
     635           0 :         aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
     636           6 :     aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
     637           6 :     if( aNodeArgs.nRightRest < 0 )
     638           0 :         aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;
     639             : 
     640          12 :     SwScriptInfo aScriptInfo;
     641          12 :     SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     642           6 :     xub_StrLen nIdx = 0;
     643           6 :     aIter.SeekAndChgAttrIter( nIdx, pOut );
     644           6 :     xub_StrLen nLen = m_Text.getLength();
     645           6 :     long nAktWidth = 0;
     646           6 :     MSHORT nAdd = 0;
     647           6 :     SwMinMaxArgs aArg( pOut, pSh, rMin, rMax, rAbsMin );
     648          21 :     while( nIdx < nLen )
     649             :     {
     650           9 :         xub_StrLen nNextChg = aIter.GetNextAttr();
     651           9 :         xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
     652           9 :         if( nNextChg > nStop )
     653           0 :             nNextChg = nStop;
     654           9 :         SwTxtAttr *pHint = NULL;
     655           9 :         sal_Unicode cChar = CH_BLANK;
     656           9 :         nStop = nIdx;
     657          69 :         while( nStop < nLen && nStop < nNextChg &&
     658          36 :                CH_TAB != ( cChar = m_Text[nStop] ) &&
     659          18 :                CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
     660          39 :                CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
     661             :                !pHint )
     662             :         {
     663          18 :             if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
     664          18 :                 || ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
     665           6 :                 ++nStop;
     666             :         }
     667           9 :         if ( lcl_MinMaxString( aArg, aIter.GetFnt(), m_Text, nIdx, nStop ) )
     668             :         {
     669           3 :             nAdd = 20;
     670             :         }
     671           9 :         nIdx = nStop;
     672           9 :         aIter.SeekAndChgAttrIter( nIdx, pOut );
     673           9 :         switch( cChar )
     674             :         {
     675             :             case CH_BREAK  :
     676             :             {
     677           0 :                 if( (long)rMax < aArg.nRowWidth )
     678           0 :                     rMax = aArg.nRowWidth;
     679           0 :                 aArg.nRowWidth = 0;
     680           0 :                 aArg.NewWord();
     681           0 :                 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
     682             :             }
     683           0 :             break;
     684             :             case CH_TAB    :
     685             :             {
     686           0 :                 aArg.NewWord();
     687           0 :                 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
     688             :             }
     689           0 :             break;
     690             :             case CHAR_SOFTHYPHEN:
     691           0 :                 ++nIdx;
     692           0 :             break;
     693             :             case CHAR_HARDBLANK:
     694             :             case CHAR_HARDHYPHEN:
     695             :             {
     696           0 :                 OUString sTmp( cChar );
     697           0 :                 SwDrawTextInfo aDrawInf( const_cast<ViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()),
     698           0 :                     *pOut, 0, sTmp, 0, 1, 0, sal_False );//swmod 080311
     699           0 :                 nAktWidth = aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     700           0 :                 aArg.nWordWidth += nAktWidth;
     701           0 :                 aArg.nRowWidth += nAktWidth;
     702           0 :                 if( (long)rAbsMin < aArg.nWordWidth )
     703           0 :                     rAbsMin = aArg.nWordWidth;
     704           0 :                 aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
     705           0 :                 aArg.nNoLineBreak = nIdx++;
     706             :             }
     707           0 :             break;
     708             :             case CH_TXTATR_BREAKWORD:
     709             :             case CH_TXTATR_INWORD:
     710             :             {
     711           6 :                 if( !pHint )
     712           0 :                     break;
     713           6 :                 long nOldWidth = aArg.nWordWidth;
     714           6 :                 long nOldAdd = aArg.nWordAdd;
     715           6 :                 aArg.NewWord();
     716             : 
     717           6 :                 switch( pHint->Which() )
     718             :                 {
     719             :                     case RES_TXTATR_FLYCNT :
     720             :                     {
     721           0 :                         SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
     722           0 :                         const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
     723           0 :                         if( RES_DRAWFRMFMT == pFrmFmt->Which() )
     724             :                         {
     725           0 :                             const SdrObject* pSObj = pFrmFmt->FindSdrObject();
     726           0 :                             if( pSObj )
     727           0 :                                 nAktWidth = pSObj->GetCurrentBoundRect().GetWidth();
     728             :                             else
     729           0 :                                 nAktWidth = 0;
     730             :                         }
     731             :                         else
     732             :                         {
     733           0 :                             const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
     734           0 :                             if( RES_FLYFRMFMT == pFrmFmt->Which()
     735           0 :                                 && rTmpSize.GetWidthPercent() )
     736             :                             {
     737             : /*-----------------------------------------------------------------------------
     738             :  * Hier ein HACK fuer folgende Situation: In dem Absatz befindet sich
     739             :  * ein Textrahmen mit relativer Groesse. Dann nehmen wir mal als minimale
     740             :  * Breite 0,5 cm und als maximale KSHRT_MAX.
     741             :  * Sauberer und vielleicht spaeter notwendig waere es, ueber den Inhalt
     742             :  * des Textrahmens zu iterieren und GetMinMaxSize rekursiv zu rufen.
     743             :  * --------------------------------------------------------------------------*/
     744           0 :                                 nAktWidth = FLYINCNT_MIN_WIDTH; // 0,5 cm
     745           0 :                                 if( (long)rMax < KSHRT_MAX )
     746           0 :                                     rMax = KSHRT_MAX;
     747             :                             }
     748             :                             else
     749           0 :                                 nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
     750             :                         }
     751           0 :                         nAktWidth += rLR.GetLeft();
     752           0 :                         nAktWidth += rLR.GetRight();
     753           0 :                         aArg.nWordAdd = nOldWidth + nOldAdd;
     754           0 :                         aArg.nWordWidth = nAktWidth;
     755           0 :                         aArg.nRowWidth += nAktWidth;
     756           0 :                         if( (long)rAbsMin < aArg.nWordWidth )
     757           0 :                             rAbsMin = aArg.nWordWidth;
     758           0 :                         aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
     759           0 :                         break;
     760             :                     }
     761             :                     case RES_TXTATR_FTN :
     762             :                     {
     763           0 :                         const XubString aTxt = pHint->GetFtn().GetNumStr();
     764           0 :                         if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
     765           0 :                             aTxt.Len() ) )
     766           0 :                             nAdd = 20;
     767           0 :                         break;
     768             :                     }
     769             :                     case RES_TXTATR_FIELD :
     770             :                     {
     771           6 :                         SwField *pFld = (SwField*)pHint->GetFld().GetFld();
     772           6 :                         const String aTxt = pFld->ExpandField(true);
     773           6 :                         if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
     774           6 :                             aTxt.Len() ) )
     775           0 :                             nAdd = 20;
     776           6 :                         break;
     777             :                     }
     778           0 :                     default: aArg.nWordWidth = nOldWidth;
     779           0 :                              aArg.nWordAdd = nOldAdd;
     780             : 
     781             :                 }
     782           6 :                 aIter.SeekAndChgAttrIter( ++nIdx, pOut );
     783             :             }
     784           6 :             break;
     785             :         }
     786             :     }
     787           6 :     if( (long)rMax < aArg.nRowWidth )
     788           3 :         rMax = aArg.nRowWidth;
     789             : 
     790           6 :     nLROffset += rSpace.GetRight();
     791             : 
     792           6 :     rAbsMin += nLROffset;
     793           6 :     rAbsMin += nAdd;
     794           6 :     rMin += nLROffset;
     795           6 :     rMin += nAdd;
     796           6 :     if( (long)rMin < aNodeArgs.nMinWidth )
     797           0 :         rMin = aNodeArgs.nMinWidth;
     798           6 :     if( (long)rAbsMin < aNodeArgs.nMinWidth )
     799           0 :         rAbsMin = aNodeArgs.nMinWidth;
     800           6 :     rMax += aNodeArgs.nMaxWidth;
     801           6 :     rMax += nLROffset;
     802           6 :     rMax += nAdd;
     803           6 :     if( rMax < rMin ) // z.B. Rahmen mit Durchlauf gehen zunaechst nur
     804           0 :         rMax = rMin;  // in das Minimum ein
     805          12 :     pOut->SetMapMode( aOldMap );
     806           6 : }
     807             : 
     808             : /*************************************************************************
     809             :  *                      SwTxtNode::GetScalingOfSelectedText()
     810             :  *
     811             :  * Calculates the width of the text part specified by nStt and nEnd,
     812             :  * the height of the line containing nStt is devided by this width,
     813             :  * indicating the scaling factor, if the text part is rotated.
     814             :  * Having CH_BREAKs in the text part, this method returns the scaling
     815             :  * factor for the longest of the text parts separated by the CH_BREAKs.
     816             :  *
     817             :  * changing this method very likely requires changing of "GetMinMaxSize"
     818             :  *************************************************************************/
     819             : 
     820           0 : sal_uInt16 SwTxtNode::GetScalingOfSelectedText( xub_StrLen nStt, xub_StrLen nEnd )
     821             :     const
     822             : {
     823           0 :     ViewShell* pSh = NULL;
     824           0 :     OutputDevice* pOut = NULL;
     825           0 :     GetDoc()->GetEditShell( &pSh );
     826             : 
     827           0 :     if ( pSh )
     828           0 :         pOut = &pSh->GetRefDev();
     829             :     else
     830             :     {
     831             :         //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
     832           0 :         if ( getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) )
     833           0 :             pOut = GetpApp()->GetDefaultDevice();
     834             :         else
     835           0 :             pOut = getIDocumentDeviceAccess()->getReferenceDevice( true );
     836             :     }
     837             : 
     838             :     OSL_ENSURE( pOut, "GetScalingOfSelectedText without outdev" );
     839             : 
     840           0 :     MapMode aOldMap( pOut->GetMapMode() );
     841           0 :     pOut->SetMapMode( MapMode( MAP_TWIP ) );
     842             : 
     843           0 :     if ( nStt == nEnd )
     844             :     {
     845           0 :         if ( !g_pBreakIt->GetBreakIter().is() )
     846           0 :             return 100;
     847             : 
     848           0 :         SwScriptInfo aScriptInfo;
     849           0 :         SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     850           0 :         aIter.SeekAndChgAttrIter( nStt, pOut );
     851             : 
     852             :         Boundary aBound =
     853           0 :             g_pBreakIt->GetBreakIter()->getWordBoundary( GetTxt(), nStt,
     854           0 :             g_pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
     855           0 :             WordType::DICTIONARY_WORD, sal_True );
     856             : 
     857           0 :         if ( nStt == aBound.startPos )
     858             :         {
     859             :             // cursor is at left or right border of word
     860           0 :             pOut->SetMapMode( aOldMap );
     861           0 :             return 100;
     862             :         }
     863             : 
     864           0 :         nStt = (xub_StrLen)aBound.startPos;
     865           0 :         nEnd = (xub_StrLen)aBound.endPos;
     866             : 
     867           0 :         if ( nStt == nEnd )
     868             :         {
     869           0 :             pOut->SetMapMode( aOldMap );
     870           0 :             return 100;
     871           0 :         }
     872             :     }
     873             : 
     874           0 :     SwScriptInfo aScriptInfo;
     875           0 :     SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
     876             : 
     877             :     // We do not want scaling attributes to be considered during this
     878             :     // calculation. For this, we push a temporary scaling attribute with
     879             :     // scaling value 100 and priority flag on top of the scaling stack
     880           0 :     SwAttrHandler& rAH = aIter.GetAttrHandler();
     881           0 :     SvxCharScaleWidthItem aItem(100, RES_CHRATR_SCALEW);
     882           0 :     SwTxtAttrEnd aAttr( aItem, nStt, nEnd );
     883           0 :     aAttr.SetPriorityAttr( sal_True );
     884           0 :     rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
     885             : 
     886           0 :     xub_StrLen nIdx = nStt;
     887             : 
     888           0 :     sal_uLong nWidth = 0;
     889           0 :     sal_uLong nProWidth = 0;
     890             : 
     891           0 :     while( nIdx < nEnd )
     892             :     {
     893           0 :         aIter.SeekAndChgAttrIter( nIdx, pOut );
     894             : 
     895             :         // scan for end of portion
     896           0 :         xub_StrLen nNextChg = aIter.GetNextAttr();
     897           0 :         xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
     898           0 :         if( nNextChg > nStop )
     899           0 :             nNextChg = nStop;
     900             : 
     901           0 :         nStop = nIdx;
     902           0 :         sal_Unicode cChar = CH_BLANK;
     903           0 :         SwTxtAttr* pHint = NULL;
     904             : 
     905             :         // stop at special characters in [ nIdx, nNextChg ]
     906           0 :         while( nStop < nEnd && nStop < nNextChg )
     907             :         {
     908           0 :             cChar = m_Text[nStop];
     909           0 :             if (
     910           0 :                 CH_TAB == cChar ||
     911           0 :                 CH_BREAK == cChar ||
     912           0 :                 CHAR_HARDBLANK == cChar ||
     913           0 :                 CHAR_HARDHYPHEN == cChar ||
     914           0 :                 CHAR_SOFTHYPHEN == cChar ||
     915             :                 (
     916           0 :                   (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar) &&
     917           0 :                   (0 == (pHint = aIter.GetAttr(nStop)))
     918             :                 )
     919             :                )
     920             :             {
     921           0 :                 break;
     922             :             }
     923             :             else
     924           0 :                 ++nStop;
     925             :         }
     926             : 
     927             :         // calculate text widths up to cChar
     928           0 :         if ( nStop > nIdx )
     929             :         {
     930           0 :             SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nIdx, nStop - nIdx );
     931           0 :             nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     932             :         }
     933             : 
     934           0 :         nIdx = nStop;
     935           0 :         aIter.SeekAndChgAttrIter( nIdx, pOut );
     936             : 
     937           0 :         if ( cChar == CH_BREAK )
     938             :         {
     939           0 :             nWidth = std::max( nWidth, nProWidth );
     940           0 :             nProWidth = 0;
     941           0 :             nIdx++;
     942             :         }
     943           0 :         else if ( cChar == CH_TAB )
     944             :         {
     945             :             // tab receives width of one space
     946           0 :             OUString sTmp( CH_BLANK );
     947           0 :             SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
     948           0 :             nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     949           0 :             nIdx++;
     950             :         }
     951           0 :         else if ( cChar == CHAR_SOFTHYPHEN )
     952           0 :             ++nIdx;
     953           0 :         else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
     954             :         {
     955           0 :             OUString sTmp( cChar );
     956           0 :             SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
     957           0 :             nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     958           0 :             nIdx++;
     959             :         }
     960           0 :         else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || CH_TXTATR_INWORD ) )
     961             :         {
     962           0 :             switch( pHint->Which() )
     963             :             {
     964             :                 case RES_TXTATR_FTN :
     965             :                 {
     966           0 :                     const XubString aTxt = pHint->GetFtn().GetNumStr();
     967           0 :                     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );
     968             : 
     969           0 :                     nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     970           0 :                     break;
     971             :                 }
     972             :                 case RES_TXTATR_FIELD :
     973             :                 {
     974           0 :                     SwField *pFld = (SwField*)pHint->GetFld().GetFld();
     975           0 :                     String const aTxt = pFld->ExpandField(true);
     976           0 :                     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );
     977             : 
     978           0 :                     nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
     979           0 :                     break;
     980             :                 }
     981             :                 default:
     982             :                 {
     983             :                 // any suggestions for a default action?
     984             :                 }
     985             :             } // end of switch
     986           0 :             nIdx++;
     987             :         } // end of while
     988             :     }
     989             : 
     990           0 :     nWidth = std::max( nWidth, nProWidth );
     991             : 
     992             :     // search for a text frame this node belongs to
     993           0 :     SwIterator<SwTxtFrm,SwTxtNode> aFrmIter( *this );
     994           0 :     SwTxtFrm* pFrm = 0;
     995           0 :     for( SwTxtFrm* pTmpFrm = aFrmIter.First(); pTmpFrm; pTmpFrm = aFrmIter.Next() )
     996             :     {
     997           0 :             if ( pTmpFrm->GetOfst() <= nStt &&
     998           0 :                 ( !pTmpFrm->GetFollow() ||
     999           0 :                    pTmpFrm->GetFollow()->GetOfst() > nStt ) )
    1000             :             {
    1001           0 :                 pFrm = pTmpFrm;
    1002           0 :                 break;
    1003             :             }
    1004             :         }
    1005             : 
    1006             :     // search for the line containing nStt
    1007           0 :     if ( pFrm && pFrm->HasPara() )
    1008             :     {
    1009           0 :         SwTxtInfo aInf( pFrm );
    1010           0 :         SwTxtIter aLine( pFrm, &aInf );
    1011           0 :         aLine.CharToLine( nStt );
    1012           0 :         pOut->SetMapMode( aOldMap );
    1013             :         return (sal_uInt16)( nWidth ?
    1014           0 :             ( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
    1015             :     }
    1016             :     // no frame or no paragraph, we take the height of the character
    1017             :     // at nStt as line height
    1018             : 
    1019           0 :     aIter.SeekAndChgAttrIter( nStt, pOut );
    1020           0 :     pOut->SetMapMode( aOldMap );
    1021             : 
    1022           0 :     SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nStt, 1 );
    1023             :     return (sal_uInt16)
    1024           0 :            ( nWidth ? ((100 * aIter.GetFnt()->_GetTxtSize( aDrawInf ).Height()) / nWidth ) : 0 );
    1025             : }
    1026             : 
    1027           0 : sal_uInt16 SwTxtNode::GetWidthOfLeadingTabs() const
    1028             : {
    1029           0 :     sal_uInt16 nRet = 0;
    1030             : 
    1031           0 :     xub_StrLen nIdx = 0;
    1032             :     sal_Unicode cCh;
    1033             : 
    1034           0 :     while ( nIdx < GetTxt().getLength() &&
    1035           0 :              ( '\t' == ( cCh = GetTxt()[nIdx] ) ||
    1036             :                 ' ' == cCh ) )
    1037           0 :         ++nIdx;
    1038             : 
    1039           0 :     if ( nIdx > 0 )
    1040             :     {
    1041           0 :         SwPosition aPos( *this );
    1042           0 :         aPos.nContent += nIdx;
    1043             : 
    1044             :         // Find the non-follow text frame:
    1045           0 :         SwIterator<SwTxtFrm,SwTxtNode> aIter( *this );
    1046           0 :         for( SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
    1047             :         {
    1048             :             // Only consider master frames:
    1049           0 :             if ( !pFrm->IsFollow() )
    1050             :             {
    1051           0 :                 SWRECTFN( pFrm )
    1052           0 :                 SwRect aRect;
    1053           0 :                 pFrm->GetCharRect( aRect, aPos );
    1054             :                 nRet = (sal_uInt16)
    1055           0 :                        ( pFrm->IsRightToLeft() ?
    1056           0 :                             (pFrm->*fnRect->fnGetPrtRight)() - (aRect.*fnRect->fnGetRight)() :
    1057           0 :                             (aRect.*fnRect->fnGetLeft)() - (pFrm->*fnRect->fnGetPrtLeft)() );
    1058           0 :                 break;
    1059             :             }
    1060           0 :         }
    1061             :     }
    1062             : 
    1063           0 :     return nRet;
    1064          99 : }
    1065             : 
    1066             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10