/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"


#include <hintids.hxx>
#include <editeng/charscaleitem.hxx>
#include <txtatr.hxx>
#include <sfx2/printer.hxx>
#include <svx/svdobj.hxx>
#include <vcl/window.hxx>
#include <vcl/svapp.hxx>
#include <fmtanchr.hxx>
#include <fmtfsize.hxx>
#include <fmtornt.hxx>
#include <fmtflcnt.hxx>
#include <fmtcntnt.hxx>
#include <fmtftn.hxx>
#include <frmatr.hxx>
#include <frmfmt.hxx>
#include <fmtfld.hxx>
#include <doc.hxx>
#include <viewsh.hxx>	// ViewShell
#include <rootfrm.hxx>
#include <docary.hxx>
#include <ndtxt.hxx>
#include <dcontact.hxx>
#include <fldbas.hxx>      // SwField
#include <pam.hxx>         // SwPosition		(lcl_MinMaxNode)
#include <itratr.hxx>
#include <htmltbl.hxx>
#include <swtable.hxx>
#include <redlnitr.hxx>
#include <fmtsrnd.hxx>
#include <itrtxt.hxx>
#include <breakit.hxx>
#include <com/sun/star/i18n/WordType.hpp>
#include <com/sun/star/i18n/ScriptType.hdl>
#include <editeng/lrspitem.hxx>
#include <switerator.hxx>

using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star;

/*************************************************************************
 *						SwAttrIter::Chg()
 *************************************************************************/

void SwAttrIter::Chg( SwTxtAttr *pHt )
{
    ASSERT( pHt && pFnt, "No attribute of font available for change");
    if( pRedln && pRedln->IsOn() )
        pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True );
	else
        aAttrHandler.PushAndChg( *pHt, *pFnt );
	nChgCnt++;
}

/*************************************************************************
 *						SwAttrIter::Rst()
 *************************************************************************/

void SwAttrIter::Rst( SwTxtAttr *pHt )
{
    ASSERT( pHt && pFnt, "No attribute of font available for reset");
    // get top from stack after removing pHt
    if( pRedln && pRedln->IsOn() )
        pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False );
	else
        aAttrHandler.PopAndChg( *pHt, *pFnt );
	nChgCnt--;
}

/*************************************************************************
 *				virtual SwAttrIter::~SwAttrIter()
 *************************************************************************/

SwAttrIter::~SwAttrIter()
{
	delete pRedln;
	delete pFnt;
}

/*************************************************************************
 *						SwAttrIter::GetAttr()
 *
 * Liefert fuer eine Position das Attribut, wenn das Attribut genau auf
 * der Position nPos liegt und kein EndIndex besitzt.
 * GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen
 * sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten"
 * Attribute sind z.B. Felder (die expandierten Text bereit halten) und
 * zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen
 * solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs
 * an der Startposition ein Sonderzeichen in den String einfuegt.
 * Der Formatierer stoesst auf das Sonderzeichen und holt sich per
 * GetAttr() das entartete Attribut.
 *************************************************************************/

SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPosition ) const
{
    return (m_pTxtNode) ? m_pTxtNode->GetTxtAttrForCharAt(nPosition) : 0;
}

/*************************************************************************
 *						  SwAttrIter::SeekAndChg()
 *************************************************************************/

sal_Bool SwAttrIter::SeekAndChgAttrIter( const xub_StrLen nNewPos, OutputDevice* pOut )
{
	sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
	if ( pLastOut != pOut )
	{
		pLastOut = pOut;
		pFnt->SetFntChg( sal_True );
		bChg = sal_True;
	}
	if( bChg )
	{
		// wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
		// des gewuenschten Fonts ...
		if ( !nChgCnt && !nPropFont )
			pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
				aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
        pFnt->ChgPhysFnt( pShell, *pOut );
	}
	return bChg;
}

sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
{
	Seek( nNewPos );
	if ( !nChgCnt && !nPropFont )
		pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
			aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
	return pFnt->IsSymbol( pShell );
}

/*************************************************************************
 *						  SwAttrIter::SeekStartAndChg()
 *************************************************************************/

sal_Bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const sal_Bool bParaFont )
{
    if ( pRedln && pRedln->ExtOn() )
        pRedln->LeaveExtend( *pFnt, 0 );

    // reset font to its original state
    aAttrHandler.Reset();
    aAttrHandler.ResetFont( *pFnt );

    nStartIndex = nEndIndex = nPos = nChgCnt = 0;
	if( nPropFont )
		pFnt->SetProportion( nPropFont );
    if( pRedln )
	{
		pRedln->Clear( pFnt );
		if( !bParaFont )
			nChgCnt = nChgCnt + pRedln->Seek( *pFnt, 0, STRING_LEN );
		else
			pRedln->Reset();
	}

	if ( pHints && !bParaFont )
	{
		SwTxtAttr *pTxtAttr;
		// Solange wir noch nicht am Ende des StartArrays angekommen sind &&
		// das TextAttribut an Position 0 beginnt ...
		while ( ( nStartIndex < pHints->GetStartCount() ) &&
				!(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
		{
			// oeffne die TextAttribute
			Chg( pTxtAttr );
			nStartIndex++;
		}
	}

	sal_Bool bChg = pFnt->IsFntChg();
	if ( pLastOut != pOut )
	{
		pLastOut = pOut;
		pFnt->SetFntChg( sal_True );
		bChg = sal_True;
	}
	if( bChg )
	{
		// wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
		// des gewuenschten Fonts ...
		if ( !nChgCnt && !nPropFont )
			pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
				aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
        pFnt->ChgPhysFnt( pShell, *pOut );
	}
	return bChg;
}

/*************************************************************************
 *						 SwAttrIter::SeekFwd()
 *************************************************************************/

// AMA: Neuer AttrIter Nov 94

void SwAttrIter::SeekFwd( const xub_StrLen nNewPos )
{
	SwTxtAttr *pTxtAttr;

	if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden...
	{
		// Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden.

		// Solange wir noch nicht am Ende des EndArrays angekommen sind &&
		// das TextAttribut vor oder an der neuen Position endet ...
		while ( ( nEndIndex < pHints->GetEndCount() ) &&
				(*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
		{
			// schliesse die TextAttribute, deren StartPos vor
			// oder an der alten nPos lag, die z.Z. geoeffnet sind.
			if (*pTxtAttr->GetStart() <= nPos)	Rst( pTxtAttr );
			nEndIndex++;
		}
	}
	else // ueberlies die nicht geoeffneten Enden
	{
		while ( ( nEndIndex < pHints->GetEndCount() ) &&
				(*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
		{
			nEndIndex++;
		}
	}
	// Solange wir noch nicht am Ende des StartArrays angekommen sind &&
	// das TextAttribut vor oder an der neuen Position beginnt ...
	while ( ( nStartIndex < pHints->GetStartCount() ) &&
		   (*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos))
	{
		// oeffne die TextAttribute, deren Ende hinter der neuen Position liegt
		if ( *pTxtAttr->GetAnyEnd() > nNewPos )  Chg( pTxtAttr );
		nStartIndex++;
	}

}

/*************************************************************************
 *						 SwAttrIter::Seek()
 *************************************************************************/

sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
{
    if ( pRedln && pRedln->ExtOn() )
        pRedln->LeaveExtend( *pFnt, nNewPos );

	if( pHints )
	{
		if( !nNewPos || nNewPos < nPos )
		{
            if( pRedln )
				pRedln->Clear( NULL );

            // reset font to its original state
            aAttrHandler.Reset();
            aAttrHandler.ResetFont( *pFnt );

            if( nPropFont )
				pFnt->SetProportion( nPropFont );
			nStartIndex = nEndIndex = nPos = 0;
			nChgCnt = 0;

            // Achtung!
            // resetting the font here makes it necessary to apply any
            // changes for extended input directly to the font
            if ( pRedln && pRedln->ExtOn() )
            {
                pRedln->UpdateExtFont( *pFnt );
                ++nChgCnt;
            }
		}
		SeekFwd( nNewPos );
	}

    pFnt->SetActual( SwScriptInfo::WhichFont( nNewPos, 0, pScriptInfo ) );

    if( pRedln )
		nChgCnt = nChgCnt + pRedln->Seek( *pFnt, nNewPos, nPos );
	nPos = nNewPos;

	if( nPropFont )
		pFnt->SetProportion( nPropFont );

	return pFnt->IsFntChg();
}

/*************************************************************************
 *						SwAttrIter::GetNextAttr()
 *************************************************************************/

xub_StrLen SwAttrIter::GetNextAttr( ) const
{
	xub_StrLen nNext = STRING_LEN;
	if( pHints )
	{
		if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts?
		   nNext = (*pHints->GetStart(nStartIndex)->GetStart());
		if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden?
		{
			xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd());
			if ( nNextEnd<nNext ) nNext = nNextEnd; // Wer ist naeher?
		}
	}
	if (m_pTxtNode!=NULL) {
	    //TODO maybe use hints like FieldHints for this instead of looking at the text...
	    int l=(nNext<m_pTxtNode->Len()?nNext:m_pTxtNode->Len());
	    sal_uInt16 p=nPos;
	    const sal_Unicode *txt=m_pTxtNode->GetTxt().GetBuffer();
	    while(p<l && txt[p]!=CH_TXT_ATR_FIELDSTART && txt[p]!=CH_TXT_ATR_FIELDEND && txt[p]!=CH_TXT_ATR_FORMELEMENT) p++;
	    if ((p<l && p>nPos) || nNext<=p)
		nNext=p;
	    else
		nNext=p+1;
	}	
    if( pRedln )
		return pRedln->GetNextRedln( nNext );
	return nNext;
}

#if OSL_DEBUG_LEVEL > 1
/*************************************************************************
 *						SwAttrIter::Dump()
 *************************************************************************/

void SwAttrIter::Dump( SvStream &/*rOS*/ ) const
{
// Noch nicht an den neuen Attributiterator angepasst ...
}

#endif

class SwMinMaxArgs
{
public:
    OutputDevice* pOut;
    ViewShell* pSh;
	sal_uLong &rMin;
	sal_uLong &rMax;
	sal_uLong &rAbsMin;
	long nRowWidth;
	long nWordWidth;
	long nWordAdd;
    xub_StrLen nNoLineBreak;
    SwMinMaxArgs( OutputDevice* pOutI, ViewShell* pShI, sal_uLong& rMinI, sal_uLong &rMaxI, sal_uLong &rAbsI )
		: pOut( pOutI ), pSh( pShI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
        { nRowWidth = nWordWidth = nWordAdd = 0; nNoLineBreak = STRING_LEN; }
	void Minimum( long nNew ) { if( (long)rMin < nNew ) rMin = nNew; }
	void NewWord() { nWordAdd = nWordWidth = 0; }
};

sal_Bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const XubString &rTxt,
	xub_StrLen nIdx, xub_StrLen nEnd )
{
	sal_Bool bRet = sal_False;
	while( nIdx < nEnd )
	{
		xub_StrLen nStop = nIdx;
        sal_Bool bClear;
        LanguageType eLang = pFnt->GetLanguage();
        if( pBreakIt->GetBreakIter().is() )
        {
            bClear = CH_BLANK == rTxt.GetChar( nStop );
            Boundary aBndry( pBreakIt->GetBreakIter()->getWordBoundary( rTxt, nIdx,
                             pBreakIt->GetLocale( eLang ),
                             WordType::DICTIONARY_WORD, sal_True ) );
            nStop = (xub_StrLen)aBndry.endPos;
            if( nIdx <= aBndry.startPos && nIdx && nIdx-1 != rArg.nNoLineBreak )
                rArg.NewWord();
            if( nStop == nIdx )
                ++nStop;
            if( nStop > nEnd )
                nStop = nEnd;
        }
        else
        {
            while( nStop < nEnd && CH_BLANK != rTxt.GetChar( nStop ) )
                ++nStop;
            bClear = nStop == nIdx;
            if ( bClear )
            {
                rArg.NewWord();
                while( nStop < nEnd && CH_BLANK == rTxt.GetChar( nStop ) )
                    ++nStop;
            }
        }

        SwDrawTextInfo aDrawInf( rArg.pSh, *rArg.pOut, 0, rTxt, nIdx, nStop - nIdx );
        long nAktWidth = pFnt->_GetTxtSize( aDrawInf ).Width();
		rArg.nRowWidth += nAktWidth;
		if( bClear )
			rArg.NewWord();
		else
		{
			rArg.nWordWidth += nAktWidth;
			if( (long)rArg.rAbsMin < rArg.nWordWidth )
				rArg.rAbsMin = rArg.nWordWidth;
			rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
			bRet = sal_True;
		}
		nIdx = nStop;
    }
	return bRet;
}

sal_Bool SwTxtNode::IsSymbol( const xub_StrLen nBegin ) const//swmodtest 080307
{
	SwScriptInfo aScriptInfo;
    SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
    aIter.Seek( nBegin );
    return aIter.GetFnt()->IsSymbol( 
		const_cast<ViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()) );//swmod 080311
}

class SwMinMaxNodeArgs
{
public:
	sal_uLong nMaxWidth;    // Summe aller Rahmenbreite
	long nMinWidth;		// Breitester Rahmen
	long nLeftRest;     // noch nicht von Rahmen ueberdeckter Platz im l. Rand
	long nRightRest;    // noch nicht von Rahmen ueberdeckter Platz im r. Rand
	long nLeftDiff;		// Min/Max-Differenz des Rahmens im linken Rand
	long nRightDiff;    // Min/Max-Differenz des Rahmens im rechten Rand
	sal_uLong nIndx;		// Indexnummer des Nodes
	void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
};

sal_Bool lcl_MinMaxNode( const SwFrmFmtPtr& rpNd, void* pArgs )
{
	const SwFmtAnchor& rFmtA = ((SwFrmFmt*)rpNd)->GetAnchor();

	bool bCalculate = false;
    if ((FLY_AT_PARA == rFmtA.GetAnchorId()) ||
        (FLY_AT_CHAR == rFmtA.GetAnchorId()))
	{
		bCalculate = true;
	}

	if (bCalculate)
	{
		const SwMinMaxNodeArgs *pIn = (const SwMinMaxNodeArgs*)pArgs;
		const SwPosition *pPos = rFmtA.GetCntntAnchor();
		ASSERT(pPos && pIn, "Unexpected NULL arguments");
		if (!pPos || !pIn || pIn->nIndx != pPos->nNode.GetIndex())
			bCalculate = false;
	}

	if (bCalculate)
	{
		long nMin, nMax;
		SwHTMLTableLayout *pLayout = 0;
		MSHORT nWhich = ((SwFrmFmt*)rpNd)->Which();
		if( RES_DRAWFRMFMT != nWhich )
		{
			// Enthaelt der Rahmen zu Beginn oder am Ende eine Tabelle?
            const SwNodes& rNodes = static_cast<SwFrmFmt*>(rpNd)->GetDoc()->GetNodes();
            const SwFmtCntnt& rFlyCntnt = ((SwFrmFmt*)rpNd)->GetCntnt();
			sal_uLong nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
            SwTableNode* pTblNd = rNodes[nStt+1]->GetTableNode();
			if( !pTblNd )
			{
                SwNode *pNd = rNodes[nStt];
                pNd = rNodes[pNd->EndOfSectionIndex()-1];
				if( pNd->IsEndNode() )
					pTblNd = pNd->StartOfSectionNode()->GetTableNode();
			}

			if( pTblNd )
				pLayout = pTblNd->GetTable().GetHTMLTableLayout();
		}

		const SwFmtHoriOrient& rOrient = ((SwFrmFmt*)rpNd)->GetHoriOrient();
        sal_Int16 eHoriOri = rOrient.GetHoriOrient();

		long nDiff;
		if( pLayout )
		{
			nMin = pLayout->GetMin();
			nMax = pLayout->GetMax();
			nDiff = nMax - nMin;
		}
		else
		{
			if( RES_DRAWFRMFMT == nWhich )
			{
				const SdrObject* pSObj = rpNd->FindSdrObject();
				if( pSObj )
					nMin = pSObj->GetCurrentBoundRect().GetWidth();
				else
				nMin = 0;

			}
			else
			{
				const SwFmtFrmSize &rSz = ( (SwFrmFmt*)rpNd )->GetFrmSize();
				nMin = rSz.GetWidth();
			}
			nMax = nMin;
			nDiff = 0;
		}

		const SvxLRSpaceItem &rLR = ( (SwFrmFmt*)rpNd )->GetLRSpace();
		nMin += rLR.GetLeft();
		nMin += rLR.GetRight();
		nMax += rLR.GetLeft();
		nMax += rLR.GetRight();

		if( SURROUND_THROUGHT == ((SwFrmFmt*)rpNd)->GetSurround().GetSurround() )
		{
			( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
			return sal_True;
		}

		// Rahmen, die recht bzw. links ausgerichtet sind, gehen nur
		// teilweise in die Max-Berechnung ein, da der Rand schon berueck-
		// sichtigt wird. Nur wenn die Rahmen in den Textkoerper ragen,
		// wird dieser Teil hinzuaddiert.
		switch( eHoriOri )
		{
            case text::HoriOrientation::RIGHT:
			{
				if( nDiff )
				{
					((SwMinMaxNodeArgs*)pArgs)->nRightRest -=
						((SwMinMaxNodeArgs*)pArgs)->nRightDiff;
					((SwMinMaxNodeArgs*)pArgs)->nRightDiff = nDiff;
				}
                if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() )
				{
					if( ((SwMinMaxNodeArgs*)pArgs)->nRightRest > 0 )
						((SwMinMaxNodeArgs*)pArgs)->nRightRest = 0;
				}
				((SwMinMaxNodeArgs*)pArgs)->nRightRest -= nMin;
				break;
			}
            case text::HoriOrientation::LEFT:
			{
				if( nDiff )
				{
					((SwMinMaxNodeArgs*)pArgs)->nLeftRest -=
						((SwMinMaxNodeArgs*)pArgs)->nLeftDiff;
					((SwMinMaxNodeArgs*)pArgs)->nLeftDiff = nDiff;
				}
                if( text::RelOrientation::FRAME != rOrient.GetRelationOrient() &&
					((SwMinMaxNodeArgs*)pArgs)->nLeftRest < 0 )
					((SwMinMaxNodeArgs*)pArgs)->nLeftRest = 0;
				((SwMinMaxNodeArgs*)pArgs)->nLeftRest -= nMin;
				break;
			}
			default:
			{
				( (SwMinMaxNodeArgs*)pArgs )->nMaxWidth += nMax;
				( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
			}
		}
	}
	return sal_True;
}

#define FLYINCNT_MIN_WIDTH 284

// changing this method very likely requires changing of
// "GetScalingOfSelectedText"
void SwTxtNode::GetMinMaxSize( sal_uLong nIndex, sal_uLong& rMin, sal_uLong &rMax,
							   sal_uLong& rAbsMin, OutputDevice* pOut ) const
{
    ViewShell* pSh = 0;
	GetDoc()->GetEditShell( &pSh );
	if( !pOut )
	{
        if( pSh )
			pOut = pSh->GetWin();
		if( !pOut )
			pOut = GetpApp()->GetDefaultDevice();
	}

	MapMode aOldMap( pOut->GetMapMode() );
	pOut->SetMapMode( MapMode( MAP_TWIP ) );

	rMin = 0;
	rMax = 0;
	rAbsMin = 0;

	const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
	long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( sal_True );
	short nFLOffs;
	// Bei Numerierung ist ein neg. Erstzeileneinzug vermutlich
	// bereits gefuellt...
	if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
		nLROffset = nFLOffs;

	SwMinMaxNodeArgs aNodeArgs;
	aNodeArgs.nMinWidth = 0;
	aNodeArgs.nMaxWidth = 0;
	aNodeArgs.nLeftRest = nLROffset;
	aNodeArgs.nRightRest = rSpace.GetRight();
	aNodeArgs.nLeftDiff = 0;
	aNodeArgs.nRightDiff = 0;
	if( nIndex )
	{
		SwSpzFrmFmts* pTmp = (SwSpzFrmFmts*)GetDoc()->GetSpzFrmFmts();
		if( pTmp )
		{
			aNodeArgs.nIndx = nIndex;
			pTmp->ForEach( &lcl_MinMaxNode, &aNodeArgs );
		}
	}
	if( aNodeArgs.nLeftRest < 0 )
		aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
	aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
	if( aNodeArgs.nLeftRest < 0 )
		aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;

	if( aNodeArgs.nRightRest < 0 )
		aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
	aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
	if( aNodeArgs.nRightRest < 0 )
		aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;

	SwScriptInfo aScriptInfo;
    SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
	xub_StrLen nIdx = 0;
	aIter.SeekAndChgAttrIter( nIdx, pOut );
    xub_StrLen nLen = m_Text.Len();
	long nAktWidth = 0;
	MSHORT nAdd = 0;
    SwMinMaxArgs aArg( pOut, pSh, rMin, rMax, rAbsMin );
	while( nIdx < nLen )
	{
		xub_StrLen nNextChg = aIter.GetNextAttr();
		xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
		if( nNextChg > nStop )
			nNextChg = nStop;
		SwTxtAttr *pHint = NULL;
		xub_Unicode cChar = CH_BLANK;
		nStop = nIdx;
		while( nStop < nLen && nStop < nNextChg &&
               CH_TAB != ( cChar = m_Text.GetChar( nStop ) ) &&
               CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
               CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
               !pHint )
		{
			if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
				|| ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
				++nStop;
		}
        if ( lcl_MinMaxString( aArg, aIter.GetFnt(), m_Text, nIdx, nStop ) )
        {
			nAdd = 20;
        }
		nIdx = nStop;
		aIter.SeekAndChgAttrIter( nIdx, pOut );
		switch( cChar )
		{
			case CH_BREAK  :
			{
				if( (long)rMax < aArg.nRowWidth )
					rMax = aArg.nRowWidth;
				aArg.nRowWidth = 0;
				aArg.NewWord();
				aIter.SeekAndChgAttrIter( ++nIdx, pOut );
			}
			break;
			case CH_TAB    :
			{
				aArg.NewWord();
				aIter.SeekAndChgAttrIter( ++nIdx, pOut );
			}
			break;
            case CHAR_SOFTHYPHEN:
                ++nIdx;
            break;
            case CHAR_HARDBLANK:
            case CHAR_HARDHYPHEN:
            {
                XubString sTmp( cChar );
                SwDrawTextInfo aDrawInf( const_cast<ViewShell *>(getIDocumentLayoutAccess()->GetCurrentViewShell()), 
					*pOut, 0, sTmp, 0, 1, 0, sal_False );//swmod 080311
                nAktWidth = aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
                aArg.nWordWidth += nAktWidth;
                aArg.nRowWidth += nAktWidth;
                if( (long)rAbsMin < aArg.nWordWidth )
                    rAbsMin = aArg.nWordWidth;
                aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
                aArg.nNoLineBreak = nIdx++;
            }
            break;
			case CH_TXTATR_BREAKWORD:
			case CH_TXTATR_INWORD:
			{
				if( !pHint )
					break;
				long nOldWidth = aArg.nWordWidth;
				long nOldAdd = aArg.nWordAdd;
				aArg.NewWord();

				switch( pHint->Which() )
				{
					case RES_TXTATR_FLYCNT :
					{
						SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
						const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
						if( RES_DRAWFRMFMT == pFrmFmt->Which() )
						{
							const SdrObject* pSObj = pFrmFmt->FindSdrObject();
							if( pSObj )
								nAktWidth = pSObj->GetCurrentBoundRect().GetWidth();
							else
								nAktWidth = 0;
						}
						else
						{
							const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
							if( RES_FLYFRMFMT == pFrmFmt->Which()
								&& rTmpSize.GetWidthPercent() )
							{
/*-----------------24.01.97 14:09----------------------------------------------
 * Hier ein HACK fuer folgende Situation: In dem Absatz befindet sich
 * ein Textrahmen mit relativer Groesse. Dann nehmen wir mal als minimale
 * Breite 0,5 cm und als maximale KSHRT_MAX.
 * Sauberer und vielleicht spaeter notwendig waere es, ueber den Inhalt
 * des Textrahmens zu iterieren und GetMinMaxSize rekursiv zu rufen.
 * --------------------------------------------------------------------------*/
								nAktWidth = FLYINCNT_MIN_WIDTH; // 0,5 cm
								if( (long)rMax < KSHRT_MAX )
									rMax = KSHRT_MAX;
							}
							else
								nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
						}
						nAktWidth += rLR.GetLeft();
						nAktWidth += rLR.GetRight();
						aArg.nWordAdd = nOldWidth + nOldAdd;
						aArg.nWordWidth = nAktWidth;
						aArg.nRowWidth += nAktWidth;
						if( (long)rAbsMin < aArg.nWordWidth )
							rAbsMin = aArg.nWordWidth;
						aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
						break;
					}
					case RES_TXTATR_FTN :
					{
						const XubString aTxt = pHint->GetFtn().GetNumStr();
						if( lcl_MinMaxString( aArg, aIter.GetFnt(),	aTxt, 0,
							aTxt.Len() ) )
							nAdd = 20;
						break;
					}

                    case RES_TXTATR_FIELD :
                    case RES_TXTATR_ANNOTATION :
                        {
                            SwField *pFld = (SwField*)pHint->GetFmtFld().GetField();
                            const String aTxt = pFld->ExpandField(true);
                            if( lcl_MinMaxString( aArg, aIter.GetFnt(),	aTxt, 0,
                                aTxt.Len() ) )
                                nAdd = 20;
                            break;
                        }

                    default: aArg.nWordWidth = nOldWidth;
                        aArg.nWordAdd = nOldAdd;

				}
				aIter.SeekAndChgAttrIter( ++nIdx, pOut );
			}
			break;
		}
	}
	if( (long)rMax < aArg.nRowWidth )
		rMax = aArg.nRowWidth;

	nLROffset += rSpace.GetRight();

	rAbsMin += nLROffset;
	rAbsMin += nAdd;
	rMin += nLROffset;
	rMin += nAdd;
	if( (long)rMin < aNodeArgs.nMinWidth )
		rMin = aNodeArgs.nMinWidth;
	if( (long)rAbsMin < aNodeArgs.nMinWidth )
		rAbsMin = aNodeArgs.nMinWidth;
	rMax += aNodeArgs.nMaxWidth;
	rMax += nLROffset;
	rMax += nAdd;
	if( rMax < rMin ) // z.B. Rahmen mit Durchlauf gehen zunaechst nur
		rMax = rMin;  // in das Minimum ein
	pOut->SetMapMode( aOldMap );
}

/*************************************************************************
 *						SwTxtNode::GetScalingOfSelectedText()
 *
 * Calculates the width of the text part specified by nStt and nEnd,
 * the height of the line containing nStt is divided by this width,
 * indicating the scaling factor, if the text part is rotated.
 * Having CH_BREAKs in the text part, this method returns the scaling
 * factor for the longest of the text parts separated by the CH_BREAKs.
 *
 * changing this method very likely requires changing of "GetMinMaxSize"
 *************************************************************************/

sal_uInt16 SwTxtNode::GetScalingOfSelectedText(	xub_StrLen nStt, xub_StrLen nEnd )
	const
{
    ViewShell* pSh = NULL;
    OutputDevice* pOut = NULL;
	GetDoc()->GetEditShell( &pSh );

    if ( pSh )
        pOut = &pSh->GetRefDev();
    else
    {
        //Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
        if ( getIDocumentSettingAccess()->get(IDocumentSettingAccess::HTML_MODE) )
            pOut = GetpApp()->GetDefaultDevice();
        else
            pOut = getIDocumentDeviceAccess()->getReferenceDevice( true );
    }

    ASSERT( pOut, "GetScalingOfSelectedText without outdev" )

    MapMode aOldMap( pOut->GetMapMode() );
	pOut->SetMapMode( MapMode( MAP_TWIP ) );

    if ( nStt == nEnd )
    {
        if ( !pBreakIt->GetBreakIter().is() )
            return 100;

        SwScriptInfo aScriptInfo;
        SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
        aIter.SeekAndChgAttrIter( nStt, pOut );

        Boundary aBound =
            pBreakIt->GetBreakIter()->getWordBoundary( GetTxt(), nStt,
            pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
            WordType::DICTIONARY_WORD, sal_True );

        if ( nStt == aBound.startPos )
        {
            // cursor is at left or right border of word
            pOut->SetMapMode( aOldMap );
            return 100;
        }

        nStt = (xub_StrLen)aBound.startPos;
        nEnd = (xub_StrLen)aBound.endPos;

        if ( nStt == nEnd )
        {
            pOut->SetMapMode( aOldMap );
            return 100;
        }
    }

    SwScriptInfo aScriptInfo;
	SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );

    // We do not want scaling attributes to be considered during this
    // calculation. For this, we push a temporary scaling attribute with
    // scaling value 100 and priority flag on top of the scaling stack
    SwAttrHandler& rAH = aIter.GetAttrHandler();
    SvxCharScaleWidthItem aItem(100, RES_CHRATR_SCALEW);
    SwTxtAttrEnd aAttr( aItem, nStt, nEnd );
    aAttr.SetPriorityAttr( sal_True );
    rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );

    xub_StrLen nIdx = nStt;

	sal_uLong nWidth = 0;
	sal_uLong nProWidth = 0;

	while( nIdx < nEnd )
	{
		aIter.SeekAndChgAttrIter( nIdx, pOut );

		// scan for end of portion
		xub_StrLen nNextChg = aIter.GetNextAttr();
		xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
		if( nNextChg > nStop )
			nNextChg = nStop;

		nStop = nIdx;
		xub_Unicode cChar = CH_BLANK;
        SwTxtAttr* pHint = NULL;

        // stop at special characters in [ nIdx, nNextChg ]
        while( nStop < nEnd && nStop < nNextChg )
        {
            cChar = m_Text.GetChar( nStop );
            if (
                CH_TAB == cChar ||
                CH_BREAK == cChar ||
                CHAR_HARDBLANK == cChar ||
                CHAR_HARDHYPHEN == cChar ||
                CHAR_SOFTHYPHEN == cChar ||
                (
                  (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar) &&
                  (0 == (pHint = aIter.GetAttr(nStop)))
                )
               )
            {
                break;
            }
            else
                ++nStop;
        }

		// calculate text widths up to cChar
        if ( nStop > nIdx )
        {
            SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nIdx, nStop - nIdx );
            nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
        }

		nIdx = nStop;
		aIter.SeekAndChgAttrIter( nIdx, pOut );

		if ( cChar == CH_BREAK )
		{
			nWidth = Max( nWidth, nProWidth );
			nProWidth = 0;
			nIdx++;
		}
		else if ( cChar == CH_TAB )
		{
			// tab receives width of one space
            XubString sTmp( CH_BLANK );
            SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
            nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
			nIdx++;
		}
        else if ( cChar == CHAR_SOFTHYPHEN )
            ++nIdx;
        else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
        {
            XubString sTmp( cChar );
            SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
            nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
            nIdx++;
        }
        else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || CH_TXTATR_INWORD ) )
        {
            switch( pHint->Which() )
            {
            case RES_TXTATR_FTN :
                {
                    const XubString aTxt = pHint->GetFtn().GetNumStr();
                    SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );

                    nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
                    break;
                }

            case RES_TXTATR_FIELD :
            case RES_TXTATR_ANNOTATION :
                {
                    SwField *pFld = (SwField*)pHint->GetFmtFld().GetField();
                    String const aTxt = pFld->ExpandField(true);
                    SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );

                    nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
                    break;
                }

            default:
                {
                    // any suggestions for a default action?
                }
            } // end of switch
            nIdx++;
        } // end of while
    }

	nWidth = Max( nWidth, nProWidth );

	// search for a text frame this node belongs to
	SwIterator<SwTxtFrm,SwTxtNode> aFrmIter( *this );
    SwTxtFrm* pFrm = 0;
    for( SwTxtFrm* pTmpFrm = aFrmIter.First(); pTmpFrm; pTmpFrm = aFrmIter.Next() )
	{
			if ( pTmpFrm->GetOfst() <= nStt &&
				( !pTmpFrm->GetFollow() ||
				   pTmpFrm->GetFollow()->GetOfst() > nStt )	)
			{
				pFrm = pTmpFrm;
				break;
			}
		}

	// search for the line containing nStt
    if ( pFrm && pFrm->HasPara() )
	{
		SwTxtInfo aInf( pFrm );
        SwTxtIter aLine( pFrm, &aInf );
		aLine.CharToLine( nStt );
        pOut->SetMapMode( aOldMap );
        return (sal_uInt16)( nWidth ?
			( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
	}
	// no frame or no paragraph, we take the height of the character
	// at nStt as line height

    aIter.SeekAndChgAttrIter( nStt, pOut );
    pOut->SetMapMode( aOldMap );

    SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nStt, 1 );
    return (sal_uInt16)
           ( nWidth ? ((100 * aIter.GetFnt()->_GetTxtSize( aDrawInf ).Height()) / nWidth ) : 0 );
}

sal_uInt16 SwTxtNode::GetWidthOfLeadingTabs() const
{
    sal_uInt16 nRet = 0;

    xub_StrLen nIdx = 0;
    sal_Unicode cCh;

    while ( nIdx < GetTxt().Len() &&
             ( '\t' == ( cCh = GetTxt().GetChar( nIdx ) ) ||
                ' ' == cCh ) )
        ++nIdx;

    if ( nIdx > 0 )
    {
        SwPosition aPos( *this );
        aPos.nContent += nIdx;

        // Find the non-follow text frame:
	    SwIterator<SwTxtFrm,SwTxtNode> aIter( *this );
        for( SwTxtFrm* pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
        {
            // Only consider master frames:
            if ( !pFrm->IsFollow() )
            {
                SWRECTFN( pFrm )
                SwRect aRect;
                pFrm->GetCharRect( aRect, aPos );
                nRet = (sal_uInt16)
                       ( pFrm->IsRightToLeft() ?
                            (pFrm->*fnRect->fnGetPrtRight)() - (aRect.*fnRect->fnGetRight)() :
                            (aRect.*fnRect->fnGetLeft)() - (pFrm->*fnRect->fnGetPrtLeft)() );
                break;
            }
        }
    }

    return nRet;
}
