/**************************************************************
 * 
 * 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"
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */

/*
 * This file contains methods for the WW8 output
 * (nodes, attributes, formats und chars).
 */

#include <hintids.hxx>

#include <vcl/svapp.hxx>
#include <vcl/salbtype.hxx>
#include <svl/zformat.hxx>
#include <svl/itemiter.hxx>
#include <svl/whiter.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/tstpitem.hxx>
#include <editeng/adjitem.hxx>
#include <editeng/spltitem.hxx>
#include <editeng/widwitem.hxx>
#include <editeng/lspcitem.hxx>
#include <editeng/keepitem.hxx>
#include <editeng/shaditem.hxx>
#include <editeng/brshitem.hxx>
#include <editeng/postitem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/kernitem.hxx>
#include <editeng/crsditem.hxx>
#include <editeng/cmapitem.hxx>
#include <editeng/wrlmitem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/escpitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/hyznitem.hxx>
#include <editeng/brkitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/cntritem.hxx>
#include <editeng/shdditem.hxx>
#include <editeng/akrnitem.hxx>
#include <editeng/pbinitem.hxx>
#include <editeng/emphitem.hxx>
#include <editeng/twolinesitem.hxx>
#include <editeng/charscaleitem.hxx>
#include <editeng/charrotateitem.hxx>
#include <editeng/charreliefitem.hxx>
#include <editeng/paravertalignitem.hxx>
#include <editeng/pgrditem.hxx>
#include <editeng/frmdiritem.hxx>
#include <editeng/blnkitem.hxx>
#include <editeng/charhiddenitem.hxx>
#include <editeng/paperinf.hxx>
#include <fmtfld.hxx>
#include <fchrfmt.hxx>
#include <fmtfsize.hxx>
#include <fmtpdsc.hxx>
#include <fmtornt.hxx>
#include <fmtanchr.hxx>
#include <fmtclds.hxx>
#include <fmtsrnd.hxx>
#include <fmtftn.hxx>
#include <fmtflcnt.hxx>
#include <frmatr.hxx>
#include <swtable.hxx>
#include <fmtinfmt.hxx>
#include <txtfld.hxx>
#include <txtftn.hxx>
#include <poolfmt.hxx>
#include <doc.hxx>          // Doc for footnotes
#include <pam.hxx>
#include <paratr.hxx>
#include <fldbas.hxx>       // for SwField
#include <docufld.hxx>      // for SwField
#include <expfld.hxx>
#include <pagedesc.hxx>     // for SwPageDesc
#include <flddat.hxx>       // for Date fields
#include <ndtxt.hxx>        // for Numrules
#include <swrect.hxx>
#include <reffld.hxx>
#include <ftninfo.hxx>
#include <charfmt.hxx>
#include <section.hxx>
#include <lineinfo.hxx>
#include <fmtline.hxx>
#include <tox.hxx>
#include <fmtftntx.hxx>
#include <breakit.hxx>
#include <com/sun/star/i18n/ScriptType.hdl>
#include <unotools/localedatawrapper.hxx>
#include <tgrditem.hxx>
#include <flddropdown.hxx>
#include <chpfld.hxx>
#include <fmthdft.hxx>

#include <writerfilter/doctok/sprmids.hxx>

#include <fmtcntnt.hxx>
#include "writerhelper.hxx"
#include "writerwordglue.hxx"
#include "wrtww8.hxx"
#include "ww8par.hxx"
#include "ww8attributeoutput.hxx"
#include "fields.hxx"
#include <vcl/outdev.hxx>
#include <i18npool/mslangid.hxx>

using namespace ::com::sun::star;
using namespace nsFieldFlags;
using namespace nsSwDocInfoSubType;

/*
 * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
 * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
 * definiert und mit der akt. verglichen. Bei unterschieden wird der
 * Compiler schon meckern.
 *
 * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
 * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
*/

#if !defined(MSC) && !defined(UNX) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)

#define ATTRFNTAB_SIZE 130
#if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
#   error "Attribut-Tabelle ist ungueltigt. Wurden neue Hint-ID's zugefuegt ??"
#endif

#define NODETAB_SIZE 3
#if NODETAB_SIZE != RES_NODE_END - RES_NODE_BEGIN
#   error "Node-Tabelle ist ungueltigt. Wurden neue Hint-ID's zugefuegt ??"
#endif

#endif

using namespace sw::util;
using namespace sw::types;

bool WW8Export::CollapseScriptsforWordOk( sal_uInt16 nScript, sal_uInt16 nWhich )
{
    bool bRet = true;
    if ( nScript == i18n::ScriptType::ASIAN )
    {
        //for asian in ww8, there is only one fontsize
        //and one fontstyle (posture/weight) for ww6
        //there is the additional problem that there
        //is only one font setting for all three scripts
        switch ( nWhich )
        {
            case RES_CHRATR_FONTSIZE:
            case RES_CHRATR_POSTURE:
            case RES_CHRATR_WEIGHT:
                bRet = false;
                break;
            case RES_CHRATR_LANGUAGE:
            case RES_CHRATR_CTL_FONT:
            case RES_CHRATR_CTL_FONTSIZE:
            case RES_CHRATR_CTL_LANGUAGE:
            case RES_CHRATR_CTL_POSTURE:
            case RES_CHRATR_CTL_WEIGHT:
                if (bWrtWW8 == 0)
                    bRet = false;
            default:
                break;
        }
    }
    else if ( nScript == i18n::ScriptType::COMPLEX )
    {
        //Complex is ok in ww8, but for ww6 there is only
        //one font, one fontsize, one fontsize (weight/posture)
        //and only one language
        if ( bWrtWW8 == 0 )
        {
            switch ( nWhich )
            {
                case RES_CHRATR_CJK_FONT:
                case RES_CHRATR_CJK_FONTSIZE:
                case RES_CHRATR_CJK_POSTURE:
                case RES_CHRATR_CJK_WEIGHT:
                case RES_CHRATR_CJK_LANGUAGE:
                case RES_CHRATR_FONT:
                case RES_CHRATR_FONTSIZE:
                case RES_CHRATR_POSTURE:
                case RES_CHRATR_WEIGHT:
                case RES_CHRATR_LANGUAGE:
                    bRet = false;
                    break;
                default:
                    break;
            }
        }
    }
    else
    {
        //for western in ww8, there is only one fontsize
        //and one fontstyle (posture/weight) for ww6
        //there is the additional problem that there
        //is only one font setting for all three scripts
        switch ( nWhich )
        {
            case RES_CHRATR_CJK_FONTSIZE:
            case RES_CHRATR_CJK_POSTURE:
            case RES_CHRATR_CJK_WEIGHT:
                bRet = false;
                break;
            case RES_CHRATR_CJK_LANGUAGE:
            case RES_CHRATR_CTL_FONT:
            case RES_CHRATR_CTL_FONTSIZE:
            case RES_CHRATR_CTL_LANGUAGE:
            case RES_CHRATR_CTL_POSTURE:
            case RES_CHRATR_CTL_WEIGHT:
                if ( bWrtWW8 == 0 )
                    bRet = false;
            default:
                break;
        }
    }
    return bRet;
}

//------------------------------------------------------------
//  Hilfsroutinen fuer Styles
//------------------------------------------------------------

void MSWordExportBase::ExportPoolItemsToCHP( sw::PoolItems &rItems, sal_uInt16 nScript )
{
    sw::cPoolItemIter aEnd = rItems.end();
    for ( sw::cPoolItemIter aI = rItems.begin(); aI != aEnd; ++aI )
    {
        const SfxPoolItem *pItem = aI->second;
        sal_uInt16 nWhich = pItem->Which();
        if ( ( isCHRATR( nWhich ) || isTXTATR( nWhich ) ) && CollapseScriptsforWordOk( nScript, nWhich ) )
        {
			 //In the id definition, RES_TXTATR_INETFMT must precede RES_TXTATR_CHARFMT, so that link style can overwrite char style.
			 //and in #i24291# it describes "All we want to do is ensure for now is that if a charfmt exist in the character 
			 //properties that it rises to the top and is exported first."
		     //In bug 119649, it is in such situation, so we need to ignore the link style when doing ms word filter exports and
			 //add the second judgement for #i24291# definition. 
			 if ( nWhich == RES_TXTATR_INETFMT && ( rItems.begin()->second->Which() == RES_TXTATR_CHARFMT ) )
				 continue;
            AttrOutput().OutputItem( *pItem );
        }
    }
}

/*
 * Format wie folgt ausgeben:
 *      - gebe die Attribute aus; ohne Parents!
 */

void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFmt, bool bChpFmt, sal_uInt16 nScript,
                                      bool bExportParentItemSet )
{
    if( bExportParentItemSet || rSet.Count() )
    {
        const SfxPoolItem* pItem;
        pISet = &rSet;                  // fuer Doppel-Attribute

        // If frame dir is set, but not adjust, then force adjust as well
        if ( bPapFmt && SFX_ITEM_SET == rSet.GetItemState( RES_FRAMEDIR, bExportParentItemSet ) )
        {
            // No explicit adjust set ?
            if ( SFX_ITEM_SET != rSet.GetItemState( RES_PARATR_ADJUST, bExportParentItemSet ) )
            {
                if ( 0 != ( pItem = rSet.GetItem( RES_PARATR_ADJUST, bExportParentItemSet ) ) )
                {
                    // then set the adjust used by the parent format
                    AttrOutput().OutputItem( *pItem );
                }
            }
        }

        if ( bPapFmt && SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, bExportParentItemSet, &pItem ) )
        {
            AttrOutput().OutputItem( *pItem );

            // switch off the numerbering?
            if ( !( (SwNumRuleItem*)pItem )->GetValue().Len() &&
                 SFX_ITEM_SET != rSet.GetItemState( RES_LR_SPACE, false) &&
                 SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, true, &pItem ) )
            {
                // the set the LR-Space of the parentformat!
                AttrOutput().OutputItem( *pItem );
            }
        }

        sw::PoolItems aItems;
        GetPoolItems( rSet, aItems, bExportParentItemSet );
        if ( bChpFmt )
            ExportPoolItemsToCHP(aItems, nScript);

        if ( bPapFmt )
        {
            sw::cPoolItemIter aEnd = aItems.end();
            for ( sw::cPoolItemIter aI = aItems.begin(); aI != aEnd; ++aI )
            {
                pItem = aI->second;
                sal_uInt16 nWhich = pItem->Which();
                if ( nWhich >= RES_PARATR_BEGIN && nWhich < RES_FRMATR_END && nWhich != RES_PARATR_NUMRULE)
                    AttrOutput().OutputItem( *pItem );
            }
        }
        pISet = 0;                      // fuer Doppel-Attribute
    }
}
#include "switerator.hxx"
void MSWordExportBase::GatherChapterFields()
{
    //If the header/footer contains a chapter field
	SwFieldType* pType = pDoc->GetSysFldType( RES_CHAPTERFLD );
    SwIterator<SwFmtFld,SwFieldType> aFmtFlds( *pType );
    for ( SwFmtFld* pFld = aFmtFlds.First(); pFld; pFld = aFmtFlds.Next() )
    {
        if (const SwTxtFld *pTxtFld = pFld->GetTxtFld())
        {
            const SwTxtNode &rTxtNode = pTxtFld->GetTxtNode();
            maChapterFieldLocs.push_back(rTxtNode.GetIndex());
        }
    }
}

bool MSWordExportBase::CntntContainsChapterField(const SwFmtCntnt &rCntnt) const
{
    bool bRet = false;
    if ( const SwNodeIndex* pSttIdx = rCntnt.GetCntntIdx() )
    {
        SwNodeIndex aIdx( *pSttIdx, 1 );
        SwNodeIndex aEnd( *pSttIdx->GetNode().EndOfSectionNode() );
        sal_uLong nStart = aIdx.GetIndex();
        sal_uLong nEnd = aEnd.GetIndex();
        //If the header/footer contains a chapter field
        mycCFIter aIEnd = maChapterFieldLocs.end();
        for ( mycCFIter aI = maChapterFieldLocs.begin(); aI != aIEnd; ++aI )
        {
            if ( ( nStart <= *aI ) && ( *aI <= nEnd ) )
            {
                bRet = true;
                break;
            }
        }
    }
    return bRet;
}

bool MSWordExportBase::FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const
{
    if ( maChapterFieldLocs.empty() )
        return false;

    const SwFrmFmt *pFmt = 0;

    pFmt = rFmt.GetHeader().GetHeaderFmt();
    if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) )
        return true;

    pFmt = rFmt.GetFooter().GetFooterFmt();
    if ( pFmt && CntntContainsChapterField( pFmt->GetCntnt() ) )
        return true;

    return false;
}

bool MSWordExportBase::SetAktPageDescFromNode(const SwNode &rNd)
{
    bool bNewPageDesc = false;
    const SwPageDesc* pCurrent = SwPageDesc::GetPageDescOfNode(rNd);
    ASSERT(pCurrent && pAktPageDesc, "Not possible surely");
    if (pAktPageDesc && pCurrent)
    {
        if (pCurrent != pAktPageDesc)
        {
            if (pAktPageDesc->GetFollow() != pCurrent)
                bNewPageDesc = true;
            else
            {
                const SwFrmFmt& rTitleFmt = pAktPageDesc->GetMaster();
                const SwFrmFmt& rFollowFmt = pCurrent->GetMaster();

                bNewPageDesc = !IsPlausableSingleWordSection(rTitleFmt,
                    rFollowFmt);
            }
            pAktPageDesc = pCurrent;
        }
        else
        {
            const SwFrmFmt &rFmt = pCurrent->GetMaster();
            bNewPageDesc = FmtHdFtContainsChapterField(rFmt);
        }
    }
    return bNewPageDesc;
}

// Da WW nur Break-After ( Pagebreak und Sectionbreaks ) kennt, im SW aber
// Bagebreaks "vor" und "nach" und Pagedescs nur "vor" existieren, werden
// die Breaks 2* durchgeklimpert, naemlich vor und hinter jeder Zeile.
// Je nach BreakTyp werden sie vor oder nach der Zeile gesetzt.
// Es duerfen nur Funktionen gerufen werden, die nicht in den
// Ausgabebereich pO schreiben, da dieser nur einmal fuer CHP und PAP existiert
// und damit im falschen landen wuerden.
void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode& rNd )
{
    if ( bStyDef || bOutKF || bInWriteEscher || bOutPageDescs )
        return;

    bBreakBefore = true;

    bool bNewPageDesc = false;
    const SfxPoolItem* pItem=0;
    const SwFmtPageDesc *pPgDesc=0;

    //Output a sectionbreak if theres a new pagedesciptor.  otherwise output a
    //pagebreak if there is a pagebreak here, unless the new page (follow
    //style) is different to the current one, in which case plump for a
    //section.
    bool bBreakSet = false;

    const SwPageDesc * pPageDesc = rNd.FindPageDesc(sal_False);

    if ((!Sections().HeaderFooterWritten()) && (pAktPageDesc != pPageDesc))
    {
        bBreakSet = true;
        bNewPageDesc = true;
        pAktPageDesc = pPageDesc;
    }

    if ( pSet && pSet->Count() )
    {
        if ( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem ) && 
             dynamic_cast<const SwFmtPageDesc*>(pItem)->GetRegisteredIn() != NULL)
        {
            bBreakSet = true;
            bNewPageDesc = true;
            pPgDesc = (const SwFmtPageDesc*)pItem;
            pAktPageDesc = pPgDesc->GetPageDesc();
        }
        else if ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, false, &pItem ) )
        {
            // --> FME 2007-05-30 #146867# Word does not like hard break attributes in some table cells
            bool bRemoveHardBreakInsideTable = false;
            if ( bOutTable )
            {
                const SwTableNode* pTableNode = rNd.FindTableNode();
                if ( pTableNode )
                {
                    const SwTableBox* pBox = rNd.GetTblBox();
                    const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0;
                    // but only for non-complex tables
                    if ( pLine && !pLine->GetUpper() )
                    {
                        // check if box is not first in that line:
                        if ( 0 < pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() )
                        {
                            bRemoveHardBreakInsideTable = true;
                        }
                    }
                }
            }
            // <--

            bBreakSet = true;

            if ( !bRemoveHardBreakInsideTable )
            {
                ASSERT(pAktPageDesc, "should not be possible");
                /*
                 If because of this pagebreak the page desc following the page
                 break is the follow style of the current page desc then output a
                 section break using that style instead.  At least in those cases
                 we end up with the same style in word and writer, nothing can be
                 done when it happens when we get a new pagedesc because we
                 overflow from the first page style.
                */
                if ( pAktPageDesc )
                {
                    // --> OD 2007-05-30 #i76301#
                    // assure that there is a page break before set at the node.
                    const SvxFmtBreakItem* pBreak = dynamic_cast<const SvxFmtBreakItem*>(pItem);
                    if ( pBreak &&
                         pBreak->GetBreak() == SVX_BREAK_PAGE_BEFORE )
                    {
                        bNewPageDesc = SetAktPageDescFromNode( rNd );
                    }
                    // <--
                }
                if ( !bNewPageDesc )
                    AttrOutput().OutputItem( *pItem );
            }
        }
    }

    /*
    #i9301#
    No explicit page break, lets see if the style had one and we've moved to a
    new page style because of it, if we have to then we take the opportunity to
    set the equivalent word section here. We *could* do it for every paragraph
    that moves onto a new page because of layout, but that would be insane.
    */
    bool bHackInBreak = false;
    if ( !bBreakSet )
    {
        if ( const SwCntntNode *pNd = rNd.GetCntntNode() )
        {
            const SvxFmtBreakItem &rBreak =
                ItemGet<SvxFmtBreakItem>( *pNd, RES_BREAK );
            if ( rBreak.GetBreak() == SVX_BREAK_PAGE_BEFORE )
                bHackInBreak = true;
            else
            {   // Even a pagedesc item is set, the break item can be set 'NONE',
                // but a pagedesc item is an implicit page break before...
                const SwFmtPageDesc &rPageDesc =
                    ItemGet<SwFmtPageDesc>( *pNd, RES_PAGEDESC );
                if ( rPageDesc.KnowsPageDesc() )
                    bHackInBreak = true;
            }
        }
    }

    if ( bHackInBreak )
    {
        ASSERT( pAktPageDesc, "should not be possible" );
        if ( pAktPageDesc )
            bNewPageDesc = SetAktPageDescFromNode( rNd );
    }

    if ( bNewPageDesc && pAktPageDesc )
    {
        PrepareNewPageDesc( pSet, rNd, pPgDesc, pAktPageDesc );
    }
    bBreakBefore = false;
}

// --> OD 2007-05-29 #i76300#
bool MSWordExportBase::OutputFollowPageDesc( const SfxItemSet* pSet, const SwTxtNode* pNd )
{
    bool bRet = false;

    if ( pNd &&
         pAktPageDesc &&
         pAktPageDesc != pAktPageDesc->GetFollow() )
    {
        PrepareNewPageDesc( pSet, *pNd, 0, pAktPageDesc->GetFollow() );
        bRet = true;
    }

    return bRet;
}

const SwSectionFmt* MSWordExportBase::GetSectionFormat( const SwNode& rNd ) const
{
    const SwSectionFmt* pFmt = NULL;
    const SwSectionNode* pSect = rNd.FindSectionNode();
    if ( pSect &&
         CONTENT_SECTION == pSect->GetSection().GetType() )
    {
        pFmt = pSect->GetSection().GetFmt();
    }

    return pFmt;
}

sal_uLong MSWordExportBase::GetSectionLineNo( const SfxItemSet* pSet, const SwNode& rNd ) const
{
    const SwFmtLineNumber* pNItem = 0;
    if ( pSet )
    {
        pNItem = &( ItemGet<SwFmtLineNumber>( *pSet, RES_LINENUMBER ) );
    }
    else if ( const SwCntntNode *pNd = rNd.GetCntntNode() )
    {
        pNItem = &( ItemGet<SwFmtLineNumber>( *pNd, RES_LINENUMBER ) );
    }

    return pNItem? pNItem->GetStartValue() : 0;
}

void WW8Export::PrepareNewPageDesc( const SfxItemSet*pSet,
                                      const SwNode& rNd,
                                      const SwFmtPageDesc* pNewPgDescFmt,
                                      const SwPageDesc* pNewPgDesc )
{
    // Die PageDescs werden beim Auftreten von PageDesc-Attributen nur in
    // WW8Writer::pSepx mit der entsprechenden Position eingetragen.  Das
    // Aufbauen und die Ausgabe der am PageDesc haengenden Attribute und
    // Kopf/Fusszeilen passiert nach dem Haupttext und seinen Attributen.

    sal_uLong nFcPos = ReplaceCr( msword::PageBreak ); // Page/Section-Break

    // tatsaechlich wird hier NOCH NICHTS ausgegeben, sondern
    // nur die Merk-Arrays aCps, aSects entsprechend ergaenzt
    if ( !nFcPos )
        return;

    const SwSectionFmt* pFmt = GetSectionFormat( rNd );
    const sal_uLong nLnNm = GetSectionLineNo( pSet, rNd );

    ASSERT( pNewPgDescFmt || pNewPgDesc, "Neither page desc format nor page desc provided." );

    if ( pNewPgDescFmt )
    {
        pSepx->AppendSep( Fc2Cp( nFcPos ), *pNewPgDescFmt, rNd, pFmt, nLnNm );
    }
    else if ( pNewPgDesc )
    {
        pSepx->AppendSep( Fc2Cp( nFcPos ), pNewPgDesc, rNd, pFmt, nLnNm );
    }
}

void MSWordExportBase::CorrectTabStopInSet( SfxItemSet& rSet, sal_uInt16 nAbsLeft )
{
    const SvxTabStopItem *pItem =
        sw::util::HasItem<SvxTabStopItem>( rSet, RES_PARATR_TABSTOP );

    if ( pItem )
    {
        // dann muss das fuer die Ausgabe korrigiert werden
        SvxTabStopItem aTStop(*pItem);
        for ( sal_uInt16 nCnt = 0; nCnt < aTStop.Count(); ++nCnt )
        {
            SvxTabStop& rTab = (SvxTabStop&)aTStop[ nCnt ];
            if ( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() &&
                rTab.GetTabPos() >= nAbsLeft )
            {
                rTab.GetTabPos() -= nAbsLeft;
            }
            else
            {
                aTStop.Remove( nCnt );
                --nCnt;
            }
        }
        rSet.Put( aTStop );
    }
}

sal_uInt8 WW8Export::GetNumId( sal_uInt16 eNumType )
{
    sal_uInt8 nRet = 0;
    switch( eNumType )
    {
    case SVX_NUM_CHARS_UPPER_LETTER:
    case SVX_NUM_CHARS_UPPER_LETTER_N:  nRet = 3;       break;
    case SVX_NUM_CHARS_LOWER_LETTER:
    case SVX_NUM_CHARS_LOWER_LETTER_N:  nRet = 4;       break;
    case SVX_NUM_ROMAN_UPPER:           nRet = 1;       break;
    case SVX_NUM_ROMAN_LOWER:           nRet = 2;       break;

    case SVX_NUM_BITMAP:
    case SVX_NUM_CHAR_SPECIAL:          nRet = 23;      break;

    // nix, macht WW undokumentiert auch so
    case SVX_NUM_NUMBER_NONE:           nRet = 0xff;    break;
    }
    return nRet;
}

void WW8AttributeOutput::OutlineNumbering( sal_uInt8 nLvl, const SwNumFmt &rNFmt, const SwFmt &rFmt )
{
    if ( nLvl >= WW8ListManager::nMaxLevel )
        nLvl = WW8ListManager::nMaxLevel-1;

    if ( m_rWW8Export.bWrtWW8 )
    {
        // write sprmPOutLvl sprmPIlvl and sprmPIlfo
        SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_POutLvl );
        m_rWW8Export.pO->Insert( nLvl, m_rWW8Export.pO->Count() );
        SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl );
        m_rWW8Export.pO->Insert( nLvl, m_rWW8Export.pO->Count() );
        SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo );
        SwWW8Writer::InsUInt16( *m_rWW8Export.pO,
                1 + m_rWW8Export.GetId( *m_rWW8Export.pDoc->GetOutlineNumRule() ) );
    }
    else
    {
        m_rWW8Export.Out_SwNumLvl( nLvl );
        // --> OD 2008-06-03 #i86652#
//        if (rNFmt.GetAbsLSpace())
        if ( rNFmt.GetPositionAndSpaceMode() ==
                                   SvxNumberFormat::LABEL_WIDTH_AND_POSITION  &&
             rNFmt.GetAbsLSpace() )
        // <--
        {
            SwNumFmt aNumFmt( rNFmt );
            const SvxLRSpaceItem& rLR =
                ItemGet<SvxLRSpaceItem>( rFmt, RES_LR_SPACE );

            aNumFmt.SetAbsLSpace( writer_cast<short>(
                    aNumFmt.GetAbsLSpace() + rLR.GetLeft() ) );
            m_rWW8Export.Out_NumRuleAnld(
                    *m_rWW8Export.pDoc->GetOutlineNumRule(),
                    aNumFmt, nLvl );
        }
        else
            m_rWW8Export.Out_NumRuleAnld(
                    *m_rWW8Export.pDoc->GetOutlineNumRule(),
                    rNFmt, nLvl );
    }
}

// --> OD 2007-06-04 #i77805#
bool WW8Export::DisallowInheritingOutlineNumbering(const SwFmt &rFmt)
{
    bool bRet( false );

    //If there is no numbering on this fmt, but its parent was outline
    //numbered, then in writer this is no inheritied, but in word it would
    //be, so we must export "no numbering" and "body level" to make word
    //behave like writer (see #i25755)
    if (SFX_ITEM_SET != rFmt.GetItemState(RES_PARATR_NUMRULE, false))
    {
        if (const SwFmt *pParent = rFmt.DerivedFrom())
        {
			if (((const SwTxtFmtColl*)pParent)->IsAssignedToListLevelOfOutlineStyle())
			{
				if (bWrtWW8)
                {
                    SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_POutLvl);
                    pO->Insert(sal_uInt8(9), pO->Count());
                    SwWW8Writer::InsUInt16(*pO, NS_sprm::LN_PIlfo);
                    SwWW8Writer::InsUInt16(*pO, 0);

                    bRet = true;
                }
                /*whats the winword 6 way to do this ?*/
            }
        }
    }

    return bRet;
}
// <--

void MSWordExportBase::OutputFormat( const SwFmt& rFmt, bool bPapFmt, bool bChpFmt, bool bFlyFmt )
{
    bool bCallOutSet = true;
    const SwModify* pOldMod = pOutFmtNode;
    pOutFmtNode = &rFmt;

    switch( rFmt.Which() )
    {
    case RES_CONDTXTFMTCOLL:
    case RES_TXTFMTCOLL:
        if( bPapFmt )
        {
			if (((const SwTxtFmtColl&)rFmt).IsAssignedToListLevelOfOutlineStyle())
			{
				int nLvl = ((const SwTxtFmtColl&)rFmt).GetAssignedOutlineStyleLevel();

                //if outline numbered
                // if Write StyleDefinition then write the OutlineRule
                const SwNumFmt& rNFmt = pDoc->GetOutlineNumRule()->Get( static_cast<sal_uInt16>( nLvl ) );
                if ( bStyDef )
                    AttrOutput().OutlineNumbering( static_cast< sal_uInt8 >( nLvl ), rNFmt, rFmt );

                // --> OD 2008-06-03 #i86652#
//                if (rNFmt.GetAbsLSpace())
                if ( rNFmt.GetPositionAndSpaceMode() ==
                                           SvxNumberFormat::LABEL_WIDTH_AND_POSITION  &&
                     rNFmt.GetAbsLSpace() )
                // <--
                {
                    SfxItemSet aSet( rFmt.GetAttrSet() );
                    SvxLRSpaceItem aLR(
                        ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));

                    aLR.SetTxtLeft( aLR.GetTxtLeft() + rNFmt.GetAbsLSpace() );
                    aLR.SetTxtFirstLineOfst( GetWordFirstLineOffset(rNFmt));

                    aSet.Put( aLR );
                    CorrectTabStopInSet( aSet, rNFmt.GetAbsLSpace() );
                    OutputItemSet( aSet, bPapFmt, bChpFmt,
                        i18n::ScriptType::LATIN, mbExportModeRTF);
                    bCallOutSet = false;
                }
            }
            else
            {
                //otherwise we might have to remove outline numbering from
                //what gets exported if the parent style was outline numbered
                // --> OD 2007-06-04 #i77805#
                // If inherited outline numbering is suppress, the left/right
                // margins has to be exported explicitly.
                if ( bStyDef && DisallowInheritingOutlineNumbering(rFmt) )
                {
                    SfxItemSet aSet( rFmt.GetAttrSet() );
                    SvxLRSpaceItem aLR(
                        ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
                    aSet.Put( aLR );
                    OutputItemSet( aSet, bPapFmt, bChpFmt,
                        com::sun::star::i18n::ScriptType::LATIN, mbExportModeRTF);
                    bCallOutSet = false;
                }
                // <--
            }
        }
        break;

    case RES_CHRFMT:
        break;
    case RES_FLYFRMFMT:
        if (bFlyFmt)
        {
            ASSERT(mpParentFrame, "No parent frame, all broken");

            if (mpParentFrame)
            {
                const SwFrmFmt &rFrmFmt = mpParentFrame->GetFrmFmt();

                SfxItemSet aSet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
                    RES_FRMATR_END-1);
                aSet.Set(rFrmFmt.GetAttrSet());

                // Fly als Zeichen werden bei uns zu Absatz-gebundenen
                // jetzt den Abstand vom Absatz-Rand setzen
                if (pFlyOffset)
                {
                    aSet.Put(SwFmtHoriOrient(pFlyOffset->X()));
                    aSet.Put(SwFmtVertOrient(pFlyOffset->Y()));
                    SwFmtAnchor aAnchor(rFrmFmt.GetAnchor());
                    aAnchor.SetType(eNewAnchorType);
                    aSet.Put(aAnchor);
                }

                if (SFX_ITEM_SET != aSet.GetItemState(RES_SURROUND))
                    aSet.Put(SwFmtSurround(SURROUND_NONE));

                bOutFlyFrmAttrs = true;
                //script doesn't matter if not exporting chp
                OutputItemSet(aSet, true, false,
                    i18n::ScriptType::LATIN, mbExportModeRTF);
                bOutFlyFrmAttrs = false;

                bCallOutSet = false;
            }
        }
        break;
    case RES_FRMFMT:
        break;
    default:
        ASSERT( !this, "Which format is exported here?" );
        break;
    }

    if( bCallOutSet )
        OutputItemSet( rFmt.GetAttrSet(), bPapFmt, bChpFmt,
            i18n::ScriptType::LATIN, mbExportModeRTF);
    pOutFmtNode = pOldMod;
}

bool MSWordExportBase::HasRefToObject( sal_uInt16 nTyp, const String* pName, sal_uInt16 nSeqNo )
{
    const SwTxtNode* pNd;

	SwFieldType* pType = pDoc->GetSysFldType( RES_GETREFFLD );
    SwIterator<SwFmtFld, SwFieldType> aFmtFlds( *pType );
    for ( SwFmtFld* pFmtFld = aFmtFlds.First(); pFmtFld; pFmtFld = aFmtFlds.Next() )
    {
        if ( pFmtFld->GetTxtFld() && nTyp == pFmtFld->GetField()->GetSubType() &&
             0 != ( pNd = pFmtFld->GetTxtFld()->GetpTxtNode() ) &&
             pNd->GetNodes().IsDocNodes() )
        {
            const SwGetRefField& rRFld = *static_cast< SwGetRefField* >( pFmtFld->GetField() );
            switch ( nTyp )
            {
                case REF_BOOKMARK:
                case REF_SETREFATTR:
                    if ( pName && *pName == rRFld.GetSetRefName() )
                        return true;
                    break;
                case REF_FOOTNOTE:
                case REF_ENDNOTE:
                    if ( nSeqNo == rRFld.GetSeqNo() )
                        return true;
                    break;
                case REF_SEQUENCEFLD:
                    break;      // ???
                case REF_OUTLINE:
                    break;      // ???
            }
        }
    }

    return false;
}

String MSWordExportBase::GetBookmarkName( sal_uInt16 nTyp, const String* pName, sal_uInt16 nSeqNo )
{
    String sRet;
    switch ( nTyp )
    {
        case REF_SETREFATTR:
            if ( pName )
            {
                sRet.APPEND_CONST_ASC( "Ref_" );
                sRet += *pName;
            }
            break;
        case REF_SEQUENCEFLD:
            break;      // ???
        case REF_BOOKMARK:
            if ( pName )
                sRet = *pName;
            break;
        case REF_OUTLINE:
            break;      // ???
        case REF_FOOTNOTE:
            sRet.APPEND_CONST_ASC( "_RefF" );
            sRet += String::CreateFromInt32( nSeqNo );
            break;
        case REF_ENDNOTE:
            sRet.APPEND_CONST_ASC( "_RefE" );
            sRet += String::CreateFromInt32( nSeqNo );
            break;
    }
    // --> OD 2005-06-08 #i43956# - encode bookmark accordingly
    return BookmarkToWord( sRet );
    // <--
}

//-----------------------------------------------------------------------
/*  */
/* File CHRATR.HXX: */
void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
{
    if ( m_rWW8Export.bWrtWW8 && bIsRTL )
    {
        if( m_rWW8Export.pDoc->GetDocumentType() != SwDoc::DOCTYPE_MSWORD )
        {
        	m_rWW8Export.InsUInt16( NS_sprm::LN_CFBiDi );
        	m_rWW8Export.pO->Insert( (sal_uInt8)1, m_rWW8Export.pO->Count() );
        }
    }

    // #i46087# patch from james_clark; complex texts needs the undocumented SPRM CComplexScript with param 0x81.
    if ( m_rWW8Export.bWrtWW8 && nScript == i18n::ScriptType::COMPLEX && !bIsRTL )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_CComplexScript );
        m_rWW8Export.pO->Insert( (sal_uInt8)0x81, m_rWW8Export.pO->Count() );
        m_rWW8Export.pDop->bUseThaiLineBreakingRules = true;
    }
}

void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
{
    m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() - (mbOnTOXEnding?2:0), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
    mbOnTOXEnding = false;
    m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete

    if ( pTextNodeInfoInner.get() != NULL )
    {         
        if ( pTextNodeInfoInner->isEndOfLine() )
        {
            TableRowEnd( pTextNodeInfoInner->getDepth() );
            
            SVBT16 nSty;
            ShortToSVBT16( 0, nSty );
            m_rWW8Export.pO->Insert( (sal_uInt8*)&nSty, 2, m_rWW8Export.pO->Count() );     // Style #
            TableInfoRow( pTextNodeInfoInner );
            m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(),
                    m_rWW8Export.pO->GetData() );
            m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
	    //For Bug 119650, should break the properties of CHP PLC after a paragraph end.
	    m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(),
		    m_rWW8Export.pO->GetData() );
        }
    }
}

void WW8AttributeOutput::StartRunProperties()
{
    WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc();
    m_nFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0;
}


void WW8AttributeOutput::StartRun( const SwRedlineData* pRedlineData )
{
    if (pRedlineData)
    {
        const String &rComment = pRedlineData->GetComment();
        //Only possible to export to main text
        if (rComment.Len() && (m_rWW8Export.nTxtTyp == TXT_MAINTEXT))
        {
            if (m_rWW8Export.pAtn->IsNewRedlineComment(pRedlineData))
            {
                m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), pRedlineData );
                m_rWW8Export.WritePostItBegin( m_rWW8Export.pO );
            }
        }
    }
}

void WW8AttributeOutput::OnTOXEnding()
{
	mbOnTOXEnding = true;
}

void WW8AttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
{
    Redline( pRedlineData );

    WW8_WrPlcFld* pCurrentFields = m_rWW8Export.CurrentFieldPlc();
    sal_uInt16 nNewFieldResults = pCurrentFields ? pCurrentFields->ResultCount() : 0;

    bool bExportedFieldResult = ( m_nFieldResults != nNewFieldResults );

    // If we have exported a field result, then we will have been forced to
    // split up the text into a 0x13, 0x14, <result> 0x15 sequence with the
    // properties forced out at the end of the result, so the 0x15 itself
    // should remain clean of all other attributes to avoid #iXXXXX#
    if ( !bExportedFieldResult )
    {
        m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(),
                m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
    }
    m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
}

void WW8AttributeOutput::RunText( const String& rText, rtl_TextEncoding eCharSet )
{
    RawText( rText, m_rWW8Export.bWrtWW8, eCharSet );
}

void WW8AttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )
{
    m_rWW8Export.OutSwString( rText, 0, rText.Len(), bForceUnicode, eCharSet );
}

void WW8AttributeOutput::OutputFKP()
{
    if ( m_rWW8Export.pO->Count() )
    {
        m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(),
                m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
        m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
    }
}

void WW8AttributeOutput::ParagraphStyle( sal_uInt16 nStyle )
{
    ASSERT( !m_rWW8Export.pO->Count(), " pO ist am ZeilenEnde nicht leer" );

    SVBT16 nSty;
    ShortToSVBT16( nStyle, nSty );
    m_rWW8Export.pO->Insert( (sal_uInt8*)&nSty, 2, m_rWW8Export.pO->Count() );     // Style #
}

void WW8AttributeOutput::OutputWW8Attribute( sal_uInt8 nId, bool bVal )
{
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( 8 == nId ? NS_sprm::LN_CFDStrike : NS_sprm::LN_CFBold + nId );
    else if (8 == nId )
        return; // no such attribute in WW6
    else
        m_rWW8Export.pO->Insert( 85 + nId, m_rWW8Export.pO->Count() );

    m_rWW8Export.pO->Insert( bVal ? 1 : 0, m_rWW8Export.pO->Count() );
}

void WW8AttributeOutput::OutputWW8AttributeCTL( sal_uInt8 nId, bool bVal )
{
    ASSERT( nId <= 1, "out of range" );
    if ( !m_rWW8Export.bWrtWW8 || nId > 1 )
        return;

    m_rWW8Export.InsUInt16( NS_sprm::LN_CFBoldBi + nId );
    m_rWW8Export.pO->Insert( bVal ? 1 : 0, m_rWW8Export.pO->Count() );
}

void WW8AttributeOutput::CharFont( const SvxFontItem& rFont )
{
    sal_uInt16 nFontID = m_rWW8Export.GetId( rFont );

    if ( m_rWW8Export.bWrtWW8 )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc0 );
        m_rWW8Export.InsUInt16( nFontID );
        m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc2 );
    }
    else
        m_rWW8Export.pO->Insert( 93, m_rWW8Export.pO->Count() );

    m_rWW8Export.InsUInt16( nFontID );
}

void WW8AttributeOutput::CharFontCTL( const SvxFontItem& rFont )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_CFtcBi );
        m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rFont ) );
    }
}

void WW8AttributeOutput::CharFontCJK( const SvxFontItem& rFont )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_CRgFtc1 );
        m_rWW8Export.InsUInt16( m_rWW8Export.GetId( rFont ) );
    }
}

void WW8AttributeOutput::CharWeightCTL( const SvxWeightItem& rWeight )
{
    //Can only export in 8+, in 7- export as normal variant and expect that
    //upperlevel code has blocked exporting clobbering attributes
    if (m_rWW8Export.bWrtWW8)
    {
        OutputWW8AttributeCTL( 0, WEIGHT_BOLD == rWeight.GetWeight());
    }
    else
    {
        OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight());
    }
}

void WW8AttributeOutput::CharPostureCTL( const SvxPostureItem& rPosture )
{
    // Can only export in 8+, in 7- export as normal variant and expect that
    // upperlevel code has blocked exporting clobbering attributes
    if (m_rWW8Export.bWrtWW8)
    {
        OutputWW8AttributeCTL( 1, ITALIC_NONE != rPosture.GetPosture() );
    }
    else
    {
        OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() );
    }
}

void WW8AttributeOutput::CharPosture( const SvxPostureItem& rPosture )
{
    OutputWW8Attribute( 1, ITALIC_NONE != rPosture.GetPosture() );
}

void WW8AttributeOutput::CharWeight( const SvxWeightItem& rWeight )
{
    OutputWW8Attribute( 0, WEIGHT_BOLD == rWeight.GetWeight() );
}

// Shadowed und Contour are not in WW-UI. JP: ??
void WW8AttributeOutput::CharContour( const SvxContourItem& rContour )
{
    OutputWW8Attribute( 3, rContour.GetValue() ? true : false);
}

void WW8AttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
{
    OutputWW8Attribute( 4, rShadow.GetValue() ? true : false);
}

void WW8AttributeOutput::CharKerning( const SvxKerningItem& rKerning )
{
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_CDxaSpace );
    else
        m_rWW8Export.pO->Insert( 96, m_rWW8Export.pO->Count() );

    m_rWW8Export.InsUInt16( rKerning.GetValue() );
}

void WW8AttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern )
{
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsKern );
    else
        m_rWW8Export.pO->Insert( 107, m_rWW8Export.pO->Count() );
    
    m_rWW8Export.InsUInt16( rAutoKern.GetValue() ? 1 : 0 );
}

void WW8AttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_CSfxText );
        // At the moment the only animated text effect we support is blinking
        m_rWW8Export.InsUInt16( rBlink.GetValue() ? 2 : 0 );
    }
}

void WW8AttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossed )
{
    FontStrikeout eSt = rCrossed.GetStrikeout();
    if ( STRIKEOUT_DOUBLE == eSt )
    {
        OutputWW8Attribute( 8, true );
        return;
    }
    if ( STRIKEOUT_NONE != eSt )
    {
        OutputWW8Attribute( 2, true );
        return;
    }

    // otherwise both off
    OutputWW8Attribute( 8, false );
    OutputWW8Attribute( 2, false );
}

void WW8AttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
{
    sal_uInt16 eSt = rCaseMap.GetValue();
    switch ( eSt )
    {
        case SVX_CASEMAP_KAPITAELCHEN:
            OutputWW8Attribute( 5, true );
            return;
        case SVX_CASEMAP_VERSALIEN:
            OutputWW8Attribute( 6, true );
            return;
        case SVX_CASEMAP_TITEL:
            // no such feature in word
            break;
        default:
            // otherwise both off
            OutputWW8Attribute( 5, false );
            OutputWW8Attribute( 6, false );
            return;
    }
}

void WW8AttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
{
    OutputWW8Attribute( 7, rHidden.GetValue() );
}

void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
{
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_CKul );
    else
        m_rWW8Export.pO->Insert( 94, m_rWW8Export.pO->Count() );

    const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_CHRATR_WORDLINEMODE );
    bool bWord = false;
    if (pItem)
        bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;

    // WW95 - parameters:   0 = none,   1 = single, 2 = by Word,
    //                      3 = double, 4 = dotted, 5 = hidden
    // WW97 - additional parameters:
    //                      6 = thick,   7 = dash,       8 = dot(not used)
    //                      9 = dotdash 10 = dotdotdash, 11 = wave
    sal_uInt8 b = 0;
    switch ( rUnderline.GetLineStyle() )
    {
        case UNDERLINE_SINGLE:
            b = ( bWord ) ? 2 : 1;
            break;
        case UNDERLINE_BOLD:
            b = m_rWW8Export.bWrtWW8 ?  6 : 1;
            break;
        case UNDERLINE_DOUBLE:
            b = 3;
            break;
        case UNDERLINE_DOTTED:
            b = 4;
            break;
        case UNDERLINE_DASH:
            b = m_rWW8Export.bWrtWW8 ?  7 : 4;
            break;
        case UNDERLINE_DASHDOT:
            b = m_rWW8Export.bWrtWW8 ?  9 : 4;
            break;
        case UNDERLINE_DASHDOTDOT:
            b = m_rWW8Export.bWrtWW8 ? 10 : 4;
            break;
        case UNDERLINE_WAVE:
            b = m_rWW8Export.bWrtWW8 ? 11 : 3;
            break;
        // ------------  new in WW2000  -------------------------------------
        case UNDERLINE_BOLDDOTTED:
            b = m_rWW8Export.bWrtWW8 ? 20 : 4;
            break;
        case UNDERLINE_BOLDDASH:
            b = m_rWW8Export.bWrtWW8 ? 23 : 4;
            break;
        case UNDERLINE_LONGDASH:
            b = m_rWW8Export.bWrtWW8 ? 39 : 4;
            break;
        case UNDERLINE_BOLDLONGDASH:
            b = m_rWW8Export.bWrtWW8 ? 55 : 4;
            break;
        case UNDERLINE_BOLDDASHDOT:
            b = m_rWW8Export.bWrtWW8 ? 25 : 4;
            break;
        case UNDERLINE_BOLDDASHDOTDOT:
            b = m_rWW8Export.bWrtWW8 ? 26 : 4;
            break;
        case UNDERLINE_BOLDWAVE:
            b = m_rWW8Export.bWrtWW8 ? 27 : 3;
            break;
        case UNDERLINE_DOUBLEWAVE:
            b = m_rWW8Export.bWrtWW8 ? 43 : 3;
            break;
        case UNDERLINE_NONE:
            b = 0;
            break;
        default:
            ASSERT( rUnderline.GetLineStyle() == UNDERLINE_NONE, "Unhandled underline type" );
            break;
    }

    m_rWW8Export.pO->Insert( b, m_rWW8Export.pO->Count() );
	Color aColor = rUnderline.GetColor();
	if( aColor != COL_TRANSPARENT )
	{
		if( m_rWW8Export.bWrtWW8 )
		{
			m_rWW8Export.InsUInt16( 0x6877 );
			
			m_rWW8Export.InsUInt32( wwUtility::RGBToBGR( aColor.GetColor() ) );
		}
	}
}

void WW8AttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
{
    sal_uInt16 nId = 0;
    if ( m_rWW8Export.bWrtWW8 )
    {
        switch ( rLanguage.Which() )
        {
            case RES_CHRATR_LANGUAGE:
                nId = NS_sprm::LN_CRgLid0;
                break;
            case RES_CHRATR_CJK_LANGUAGE:
                nId = NS_sprm::LN_CRgLid1;
                break;
            case RES_CHRATR_CTL_LANGUAGE:
                nId = NS_sprm::LN_CLidBi;
                break;
        }
    }
    else
        nId = 97;

    if ( nId )
    {
        if ( m_rWW8Export.bWrtWW8 ) // use sprmCRgLid0 rather than sprmCLid
            m_rWW8Export.InsUInt16( nId );
        else
            m_rWW8Export.pO->Insert( (sal_uInt8)nId, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );

        // unknown as to exactly why, but this seems to shadow the other
        // paramater in word 2000 and without it spellchecking doesn't work
        if ( nId == NS_sprm::LN_CRgLid0 )
        {
            m_rWW8Export.InsUInt16( 0x4873 );
            m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
        }
        else if ( nId == NS_sprm::LN_CLidBi )
        {
            m_rWW8Export.InsUInt16( 0x4874 );
            m_rWW8Export.InsUInt16( rLanguage.GetLanguage() );
        }

    }
}

void WW8AttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
{
    sal_uInt8 b = 0xFF;
    short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
    if ( !nEsc )
    {
        b = 0;
        nEsc = 0;
        nProp = 100;
    }
    else if ( DFLT_ESC_PROP == nProp )
    {
        if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
            b = 2;
        else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
            b = 1;
    }

    if ( 0xFF != b )
    {
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_CIss );
        else
            m_rWW8Export.pO->Insert( 104, m_rWW8Export.pO->Count() );

        m_rWW8Export.pO->Insert( b, m_rWW8Export.pO->Count() );
    }

    if ( 0 == b || 0xFF == b )
    {
        long nHeight = ((SvxFontHeightItem&)m_rWW8Export.GetItem(
                                    RES_CHRATR_FONTSIZE )).GetHeight();
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos );
        else
            m_rWW8Export.pO->Insert( 101, m_rWW8Export.pO->Count() );

        m_rWW8Export.InsUInt16( (short)(( nHeight * nEsc + 500 ) / 1000 ));

        if( 100 != nProp || !b )
        {
            if( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_CHps );
            else
                m_rWW8Export.pO->Insert( 99, m_rWW8Export.pO->Count() );

            m_rWW8Export.InsUInt16(
                msword_cast<sal_uInt16>((nHeight * nProp + 500 ) / 1000));
        }
    }
}

void WW8AttributeOutput::CharFontSize( const SvxFontHeightItem& rHeight )
{
    sal_uInt16 nId = 0;
    if ( m_rWW8Export.bWrtWW8 )
    {
        switch ( rHeight.Which() )
        {
            case RES_CHRATR_FONTSIZE:
            case RES_CHRATR_CJK_FONTSIZE:
                nId = NS_sprm::LN_CHps;
                break;
            case RES_CHRATR_CTL_FONTSIZE:
                nId = NS_sprm::LN_CHpsBi;
                break;
        }
    }
    else
        nId = 99;

    if ( nId )
    {
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( nId );
        else
            m_rWW8Export.pO->Insert( (sal_uInt8)nId, m_rWW8Export.pO->Count() );

        m_rWW8Export.InsUInt16( (sal_uInt16)(( rHeight.GetHeight() + 5 ) / 10 ) );
    }
}

void WW8AttributeOutput::CharScaleWidth( const SvxCharScaleWidthItem& rScaleWidth )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_CCharScale );
        m_rWW8Export.InsUInt16( rScaleWidth.GetValue() );
    }
}

void WW8AttributeOutput::CharRelief( const SvxCharReliefItem& rRelief )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        sal_uInt16 nId;
        switch ( rRelief.GetValue() )
        {
            case RELIEF_EMBOSSED:   nId = NS_sprm::LN_CFEmboss;     break;
            case RELIEF_ENGRAVED:   nId = NS_sprm::LN_CFImprint;    break;
            default:                nId = 0;                        break;
        }

        if( nId )
        {
            m_rWW8Export.InsUInt16( nId );
            m_rWW8Export.pO->Insert( (sal_uInt8)0x81, m_rWW8Export.pO->Count() );
        }
        else
        {
            // switch both flags off
            m_rWW8Export.InsUInt16( NS_sprm::LN_CFEmboss );
            m_rWW8Export.pO->Insert( (sal_uInt8)0x0, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( NS_sprm::LN_CFImprint );
            m_rWW8Export.pO->Insert( (sal_uInt8)0x0, m_rWW8Export.pO->Count() );
        }
    }
}

void WW8AttributeOutput::CharBidiRTL( const SfxPoolItem& rHt )
{
	const SfxInt16Item& rAttr = (const SfxInt16Item&)rHt;
	if( rAttr.GetValue() == 1 )
	{
		m_rWW8Export.InsUInt16(0x85a);
		m_rWW8Export.pO->Insert((sal_uInt8)1, m_rWW8Export.pO->Count());			
	}
}

void WW8AttributeOutput::CharIdctHint( const SfxPoolItem& rHt )
{
	const SfxInt16Item& rAttr = (const SfxInt16Item&)rHt;
	m_rWW8Export.InsUInt16(0x286F);
	m_rWW8Export.pO->Insert((sal_uInt8)(rAttr.GetValue()), m_rWW8Export.pO->Count());			
}

void WW8AttributeOutput::CharRotate( const SvxCharRotateItem& rRotate )
{
    // #i28331# - check that a Value is set
    if ( !rRotate.GetValue() )
        return;

    if ( m_rWW8Export.bWrtWW8 && !m_rWW8Export.IsInTable() )
    {
        // #i36867 In word the text in a table is rotated via the TC or NS_sprm::LN_TTextFlow
        // This means you can only rotate all or none of the text adding NS_sprm::LN_CEastAsianLayout
        // here corrupts the table, hence !m_rWW8Export.bIsInTable

        m_rWW8Export.InsUInt16( NS_sprm::LN_CEastAsianLayout );
        m_rWW8Export.pO->Insert( (sal_uInt8)0x06, m_rWW8Export.pO->Count() ); //len 6
        m_rWW8Export.pO->Insert( (sal_uInt8)0x01, m_rWW8Export.pO->Count() );

        m_rWW8Export.InsUInt16( rRotate.IsFitToLine() ? 1 : 0 );
        static const sal_uInt8 aZeroArr[ 3 ] = { 0, 0, 0 };
        m_rWW8Export.pO->Insert( aZeroArr, 3, m_rWW8Export.pO->Count() );
    }
}

void WW8AttributeOutput::CharEmphasisMark( const SvxEmphasisMarkItem& rEmphasisMark )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        sal_uInt8 nVal;
        switch ( rEmphasisMark.GetValue() )
        {
            case EMPHASISMARK_NONE:             nVal = 0;   break;
            case EMPHASISMARK_SIDE_DOTS:        nVal = 2;   break;
            case EMPHASISMARK_CIRCLE_ABOVE:     nVal = 3;   break;
            case EMPHASISMARK_DOTS_BELOW:       nVal = 4;   break;
            // case 1:
            default:                            nVal = 1;   break;
        }

        m_rWW8Export.InsUInt16( NS_sprm::LN_CKcd );
        m_rWW8Export.pO->Insert( nVal, m_rWW8Export.pO->Count() );
    }
}

// TransCol uebersetzt SW-Farben in WW. Heraus kommt die bei WW fuer
// Text- und Hintergrundfarbe benutzte Codierung.
// Gibt es keine direkte Entsprechung, dann wird versucht, eine moeglichst
// aehnliche WW-Farbe zu finden.
// return: 5-Bit-Wert ( 0..16 )
sal_uInt8 WW8Export::TransCol( const Color& rCol )
{
    sal_uInt8 nCol = 0;      // ->Auto
    switch( rCol.GetColor() )
    {
    case COL_BLACK:         nCol = 1;   break;
    case COL_BLUE:          nCol = 9;   break;
    case COL_GREEN:         nCol = 11;  break;
    case COL_CYAN:          nCol = 10;  break;
    case COL_RED:           nCol = 13;  break;
    case COL_MAGENTA:       nCol = 12;  break;
    case COL_BROWN:         nCol = 14;  break;
    case COL_GRAY:          nCol = 15;  break;
    case COL_LIGHTGRAY:     nCol = 16;  break;
    case COL_LIGHTBLUE:     nCol = 2;   break;
    case COL_LIGHTGREEN:    nCol = 4;   break;
    case COL_LIGHTCYAN:     nCol = 3;   break;
    case COL_LIGHTRED:      nCol = 6;   break;
    case COL_LIGHTMAGENTA:  nCol = 5;   break;
    case COL_YELLOW:        nCol = 7;   break;
    case COL_WHITE:         nCol = 8;   break;
    case COL_AUTO:          nCol = 0;   break;

    default:
        if( !pBmpPal )
        {
            pBmpPal = new BitmapPalette( 16 );
            static const ColorData aColArr[ 16 ] = {
                COL_BLACK,      COL_LIGHTBLUE,  COL_LIGHTCYAN,  COL_LIGHTGREEN,
                COL_LIGHTMAGENTA,COL_LIGHTRED,  COL_YELLOW,     COL_WHITE,
                COL_BLUE,       COL_CYAN,       COL_GREEN,      COL_MAGENTA,
                COL_RED,        COL_BROWN,      COL_GRAY,       COL_LIGHTGRAY
            };

            for( sal_uInt16 i = 0; i < 16; ++i )
                pBmpPal->operator[]( i ) = Color( aColArr[ i ] );
        }
        nCol = static_cast< sal_uInt8 >(pBmpPal->GetBestIndex( rCol ) + 1);
        break;
    }
    return nCol;
}

// TransBrush uebersetzt SW-Brushes in WW. Heraus kommt WW8_SHD.
// Nicht-Standardfarben des SW werden noch nicht in die
// Misch-Werte ( 0 .. 95% ) vom WW uebersetzt.
// Return: Echte Brush ( nicht transparent )
// auch bei Transparent wird z.B. fuer Tabellen eine transparente Brush
// geliefert
bool WW8Export::TransBrush(const Color& rCol, WW8_SHD& rShd)
{
    if( rCol.GetTransparency() )
        rShd = WW8_SHD();               // alles Nullen : transparent
    else
    {
        rShd.SetFore( 0);
        rShd.SetBack( TransCol( rCol ) );
        rShd.SetStyle( bWrtWW8, 0 );
    }
    return !rCol.GetTransparency();
}

sal_uInt32 SuitableBGColor(sal_uInt32 nIn)
{
    if (nIn == COL_AUTO)
        return 0xFF000000;
    return wwUtility::RGBToBGR(nIn);
}

void WW8AttributeOutput::CharColor( const SvxColorItem& rColor )
{
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_CIco );
    else
        m_rWW8Export.pO->Insert( 98, m_rWW8Export.pO->Count() );

    sal_uInt8 nColor = m_rWW8Export.TransCol( rColor.GetValue() );
    m_rWW8Export.pO->Insert( nColor, m_rWW8Export.pO->Count() );

    if ( m_rWW8Export.bWrtWW8 && nColor )
    {
        m_rWW8Export.InsUInt16( 0x6870 );
        m_rWW8Export.InsUInt32( wwUtility::RGBToBGR( rColor.GetValue().GetColor() ) );
    }
}

void WW8AttributeOutput::CharBackground( const SvxBrushItem& rBrush )
{
    if( m_rWW8Export.bWrtWW8 )   // nur WW8 kann ZeichenHintergrund
    {
        WW8_SHD aSHD;

        m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD );
        // sprmCShd
        m_rWW8Export.InsUInt16( NS_sprm::LN_CShd );
        m_rWW8Export.InsUInt16( aSHD.GetValue() );

        //Quite a few unknowns, some might be transparency or something
        //of that nature...
        m_rWW8Export.InsUInt16( 0xCA71 );
        m_rWW8Export.pO->Insert( 10, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt32( 0xFF000000 );
        m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) );
        m_rWW8Export.InsUInt16( 0x0000);
    }
}

void WW8AttributeOutput::TextINetFormat( const SwFmtINetFmt& rINet )
{
    if ( rINet.GetValue().Len() )
    {
        const sal_uInt16 nId = rINet.GetINetFmtId();
        const String& rStr = rINet.GetINetFmt();
        if ( rStr.Len() == 0 )
        {
            ASSERT( false, "WW8AttributeOutput::TextINetFormat(..) - missing unvisited character format at hyperlink attribute" );
        }

        const SwCharFmt* pFmt = IsPoolUserFmt( nId )
                        ? m_rWW8Export.pDoc->FindCharFmtByName( rStr )
                        : m_rWW8Export.pDoc->GetCharFmtFromPool( nId );

        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
        else
            m_rWW8Export.pO->Insert( 80, m_rWW8Export.pO->Count() );

        m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pFmt ) );
    }
}

// --> OD 2005-06-08 #i43956# - add optional parameter <pLinkStr>
// It's needed to write the hyperlink data for a certain cross-reference
// - it contains the name of the link target, which is a bookmark.
// --> OD 2008-08-14 #158418# - add optional parameter <bIncludeEmptyPicLocation>
// It is needed to write an empty picture location for page number field separators
static void InsertSpecialChar( WW8Export& rWrt, sal_uInt8 c,
                               String* pLinkStr = 0L,
                               bool bIncludeEmptyPicLocation = false )
{
    WW8Bytes aItems;
    rWrt.GetCurrentItems(aItems);

    if (c == 0x13)
        rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell());
    else
        rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell(), aItems.Count(),
            aItems.GetData());

    rWrt.WriteChar(c);

    // --> OD 2008-08-14 #158418#
    // store empty sprmCPicLocation for field separator
    if ( bIncludeEmptyPicLocation &&
         ( c == 0x13 || c == 0x14 || c == 0x15 ) )
    {
        SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation );
        SwWW8Writer::InsUInt32( aItems, 0x00000000 );
    }
    // <--

    // --> OD 2005-06-08 #i43956# - write hyperlink data and attributes
    if ( rWrt.bWrtWW8 && c == 0x01 && pLinkStr )
    {
        // write hyperlink data to data stream
        SvStream& rStrm = *rWrt.pDataStrm;
        // position of hyperlink data
        const sal_uInt32 nLinkPosInDataStrm = rStrm.Tell();
        // write empty header
        const sal_uInt16 nEmptyHdrLen = 0x44;
        sal_uInt8 aEmptyHeader[ nEmptyHdrLen ] = { 0 };
        aEmptyHeader[ 4 ] = 0x44;
        rStrm.Write( aEmptyHeader, nEmptyHdrLen );
        // writer fixed header
        const sal_uInt16 nFixHdrLen = 0x19;
        sal_uInt8 aFixHeader[ nFixHdrLen ] =
        {
            0x08, 0xD0, 0xC9, 0xEA, 0x79, 0xF9, 0xBA, 0xCE,
            0x11, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9,
            0x0B, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
            0x00,
        };
        rStrm.Write( aFixHeader, nFixHdrLen );
        // write reference string including length+1
        sal_uInt32 nStrLen( pLinkStr->Len() + 1 );
        SwWW8Writer::WriteLong( rStrm, nStrLen );
        SwWW8Writer::WriteString16( rStrm, *(pLinkStr), false );
        // write additional two NULL Bytes
        SwWW8Writer::WriteLong( rStrm, 0 );
        // write length of hyperlink data
        const sal_uInt32 nCurrPos = rStrm.Tell();
        rStrm.Seek( nLinkPosInDataStrm );
        SVBT32 nLen;
        UInt32ToSVBT32( nCurrPos - nLinkPosInDataStrm, nLen );
        rStrm.Write( nLen, 4 );
        rStrm.Seek( nCurrPos );

        // write attributes of hyperlink character 0x01
        SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish );
        aItems.Insert( (sal_uInt8)0x81, aItems.Count() );
        SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CPicLocation );
        SwWW8Writer::InsUInt32( aItems, nLinkPosInDataStrm );
        SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFData );
        aItems.Insert( (sal_uInt8)0x01, aItems.Count() );
    }

    //Technically we should probably Remove all attribs
    //here for the 0x13, 0x14, 0x15, but our import
    //is slightly lacking
    //aItems.Remove(0, aItems.Count());
    // fSpec-Attribute true
    if( rWrt.bWrtWW8 )
    {
        SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFSpec );
        aItems.Insert( 1, aItems.Count() );
    }
    else
    {
        aItems.Insert( 117, aItems.Count() ); //sprmCFSpec
        aItems.Insert( 1, aItems.Count() );
    }

    rWrt.pChpPlc->AppendFkpEntry(rWrt.Strm().Tell(), aItems.Count(),
        aItems.GetData());
}

String lcl_GetExpandedField(const SwField &rFld)
{
    String sRet(rFld.ExpandField(true));

    //replace LF 0x0A with VT 0x0B
    sRet.SearchAndReplaceAll(0x0A, 0x0B);

    return sRet;
}

WW8_WrPlcFld* WW8Export::CurrentFieldPlc() const
{
    WW8_WrPlcFld* pFldP = NULL;
    switch (nTxtTyp)
    {
        case TXT_MAINTEXT:
            pFldP = pFldMain;
            break;
        case TXT_HDFT:
            pFldP = pFldHdFt;
            break;
        case TXT_FTN:
            pFldP = pFldFtn;
            break;
        case TXT_EDN:
            pFldP = pFldEdn;
            break;
        case TXT_ATN:
            pFldP = pFldAtn;
            break;
        case TXT_TXTBOX:
            pFldP = pFldTxtBxs;
            break;
        case TXT_HFTXTBOX:
            pFldP = pFldHFTxtBxs;
            break;
        default:
            ASSERT( !this, "was ist das fuer ein SubDoc-Type?" );
    }
    return pFldP;
}

void WW8Export::OutputField( const SwField* pFld, ww::eField eFldType,
    const String& rFldCmd, sal_uInt8 nMode )
{
    bool bUnicode = IsUnicode();
    WW8_WrPlcFld* pFldP = CurrentFieldPlc();

    const bool bIncludeEmptyPicLocation = ( eFldType == ww::ePAGE );
    if (WRITEFIELD_START & nMode)
    {
        sal_uInt8 aFld13[2] = { 0x13, 0x00 };  // will change
        //#i3958#, Needed to make this field work correctly in Word 2000
        if (eFldType == ww::eSHAPE)
            aFld13[0] |= 0x80;
        aFld13[1] = static_cast< sal_uInt8 >(eFldType);  // Typ nachtragen
        pFldP->Append( Fc2Cp( Strm().Tell() ), aFld13 );
        InsertSpecialChar( *this, 0x13, 0, bIncludeEmptyPicLocation );
    }
    if (WRITEFIELD_CMD_START & nMode)
    {
        if (bUnicode)
            SwWW8Writer::WriteString16(Strm(), rFldCmd, false);
        else
        {
            SwWW8Writer::WriteString8(Strm(), rFldCmd, false,
                RTL_TEXTENCODING_MS_1252);
        }
        // write hyperlink character including attributes and
        // corresponding binary data for certain reference fields.
        bool bHandleBookmark = false;

        if (pFld)
        {
            if (pFld->GetTyp()->Which() == RES_GETREFFLD &&
                ( eFldType == ww::ePAGEREF || eFldType == ww::eREF ||
                  eFldType == ww::eNOTEREF || eFldType == ww::eFOOTREF ))
                bHandleBookmark = true;
        }

        if ( bHandleBookmark )
        {
            // retrieve reference destionation - the name of the bookmark
            String aLinkStr;
            const sal_uInt16 nSubType = pFld->GetSubType();
            const SwGetRefField& rRFld = *(static_cast<const SwGetRefField*>(pFld));
            if ( nSubType == REF_SETREFATTR ||
                 nSubType == REF_BOOKMARK )
            {
                aLinkStr = GetBookmarkName( nSubType, &rRFld.GetSetRefName(), 0 );
            }
            else if ( nSubType == REF_FOOTNOTE ||
                      nSubType == REF_ENDNOTE )
            {
                aLinkStr = GetBookmarkName( nSubType, 0, rRFld.GetSeqNo() );
            }
            else if ( nSubType == REF_SEQUENCEFLD )
            {
                aLinkStr = pFld->GetPar2();
            }
            // insert hyperlink character including attributes and data.
            InsertSpecialChar( *this, 0x01, &aLinkStr );
        }
    }
    if (WRITEFIELD_CMD_END & nMode)
    {
        static const sal_uInt8 aFld14[2] = { 0x14, 0xff };
        pFldP->Append( Fc2Cp( Strm().Tell() ), aFld14 );
        pFldP->ResultAdded();
        InsertSpecialChar( *this, 0x14, 0, bIncludeEmptyPicLocation );
    }
    if (WRITEFIELD_END & nMode)
    {
        String sOut;
        if( pFld )
            sOut = lcl_GetExpandedField(*pFld);
        else
            sOut = rFldCmd;
        if( sOut.Len() )
        {
            if( bUnicode )
                SwWW8Writer::WriteString16(Strm(), sOut, false);
            else
            {
                SwWW8Writer::WriteString8(Strm(), sOut, false,
                    RTL_TEXTENCODING_MS_1252);
            }

            if (pFld)
            {
                if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
                    eFldType == ww::eFORMTEXT)
                {
                    sal_uInt8 aArr[12];
                    sal_uInt8 *pArr = aArr;

                    if ( bWrtWW8 )
                    {
                        Set_UInt16( pArr, NS_sprm::LN_CPicLocation );
                        Set_UInt32( pArr, 0x0 );

                        Set_UInt16( pArr, NS_sprm::LN_CFSpec );
                        Set_UInt8( pArr, 1 );

                        Set_UInt16( pArr, NS_sprm::LN_CFNoProof );
                        Set_UInt8( pArr, 1 );
                    }
                    else
                    {
                        Set_UInt8(pArr, 0x68); //sprmCPicLocation
                        Set_UInt32(pArr, 0x0);

                        Set_UInt8( pArr, 117 ); //sprmCFSpec
                        Set_UInt8( pArr, 1 );
                    }
                    pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
                }
            }
        }
    }
    if (WRITEFIELD_CLOSE & nMode)
    {
        sal_uInt8 aFld15[2] = { 0x15, 0x80 };

        if (pFld)
        {
            if (pFld->GetTyp()->Which() == RES_INPUTFLD &&
                eFldType == ww::eFORMTEXT)
            {
                sal_uInt16 nSubType = pFld->GetSubType();

                if (nSubType == REF_SEQUENCEFLD)
                    aFld15[0] |= (0x4 << 5);
            }
        }

        pFldP->Append( Fc2Cp( Strm().Tell() ), aFld15 );
        InsertSpecialChar( *this, 0x15, 0, bIncludeEmptyPicLocation );
    }
}

void WW8Export::StartCommentOutput(const String& rName)
{
    String sStr(FieldString(ww::eQUOTE));
    sStr.APPEND_CONST_ASC("[");
    sStr += rName;
    sStr.APPEND_CONST_ASC("] ");
    OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_START | WRITEFIELD_CMD_START);
}

void WW8Export::EndCommentOutput(const String& rName)
{
    String sStr(CREATE_CONST_ASC(" ["));
    sStr += rName;
    sStr.APPEND_CONST_ASC("] ");
    OutputField(0, ww::eQUOTE, sStr, WRITEFIELD_CMD_END | WRITEFIELD_END |
        WRITEFIELD_CLOSE);
}

sal_uInt16 MSWordExportBase::GetId( const SwTOXType& rTOXType )
{
    void* p = (void*)&rTOXType;
    sal_uInt16 nRet = aTOXArr.GetPos( p );
    if( USHRT_MAX == nRet )
        aTOXArr.Insert( p, nRet = aTOXArr.Count() );
    return nRet;
}

// return values:  1 - no PageNum,
//                 2 - TabStop before PageNum,
//                 3 - Text before PageNum - rTxt hold the text
//                 4 - no Text and no TabStop before PageNum
int lcl_CheckForm( const SwForm& rForm, sal_uInt8 nLvl, String& rText )
{
    int nRet = 4;
    rText.Erase();

    // #i21237#
    SwFormTokens aPattern = rForm.GetPattern(nLvl);
    SwFormTokens::iterator aIt = aPattern.begin();
    bool bPgNumFnd = false;
    FormTokenType eTType;

    // #i61362#
    if (! aPattern.empty())
    {
        // #i21237#
        while( ++aIt != aPattern.end() && !bPgNumFnd )
        {
            eTType = aIt->eTokenType;

            switch( eTType )
            {
            case TOKEN_PAGE_NUMS:
                bPgNumFnd = true;
                break;

            case TOKEN_TAB_STOP:
                nRet = 2;
                break;
            case TOKEN_TEXT:
                nRet = 3;
                rText = aIt->sText.Copy( 0, 5 ); // #i21237#
                break;

            case TOKEN_LINK_START:
            case TOKEN_LINK_END:
                break;

            default:
                nRet = 4;
                break;
            }
        }

        if( !bPgNumFnd )
            nRet = 1;
    }

    return nRet;
}

bool lcl_IsHyperlinked(const SwForm& rForm, sal_uInt16 nTOXLvl)
{
    bool bRes = false;
    for (sal_uInt16 nI = 1; nI < nTOXLvl; ++nI)
    {
        // #i21237#
        SwFormTokens aPattern = rForm.GetPattern(nI);

        if ( !aPattern.empty() )
        {
            SwFormTokens::iterator aIt = aPattern.begin();

            FormTokenType eTType;

            // #i21237#
            while ( ++aIt != aPattern.end() )
            {
                eTType = aIt->eTokenType;
                switch (eTType)
                {
                case TOKEN_LINK_START:
                case TOKEN_LINK_END:
                    bRes = true;
                break;
                default:
                    ;
                }
            }
        }
    }
    return bRes;
}

void AttributeOutputBase::StartTOX( const SwSection& rSect )
{
    if ( const SwTOXBase* pTOX = rSect.GetTOXBase() )
    {
        static const sal_Char sEntryEnd[] = "\" ";

        ww::eField eCode = ww::eTOC;
        String sStr = pTOX->GetMSTOCExpression();
        if ( !sStr.Len() )
        {
            switch (pTOX->GetType())
            {
            case TOX_INDEX:
                eCode = ww::eINDEX;
                sStr = FieldString(eCode);

                if (pTOX->GetTOXForm().IsCommaSeparated())
                    sStr.APPEND_CONST_ASC("\\r ");

                if (nsSwTOIOptions::TOI_ALPHA_DELIMITTER & pTOX->GetOptions())
                    sStr.APPEND_CONST_ASC("\\h \"A\" ");

                {
                    String aFillTxt;
                    for (sal_uInt8 n = 1; n <= 3; ++n)
                    {
                        String aTxt;
                        int nRet = ::lcl_CheckForm(pTOX->GetTOXForm(), n, aTxt);

                        if( 3 == nRet )
                            aFillTxt = aTxt;
                        else if ((4 == nRet) || (2 == nRet)) //#109414#
                            aFillTxt = '\t';
                        else
                            aFillTxt.Erase();
                    }
                    sStr.APPEND_CONST_ASC("\\e \"");
                    sStr += aFillTxt;
                    sStr.AppendAscii(sEntryEnd);
                }
                break;

                //      case TOX_AUTHORITIES:   eCode = eTOA; sStr = ???; break;

            case TOX_ILLUSTRATIONS:
            case TOX_OBJECTS:
            case TOX_TABLES:
                if (!pTOX->IsFromObjectNames())
                {
                    sStr = FieldString(eCode);

                    sStr.APPEND_CONST_ASC("\\c \"");
                    sStr += pTOX->GetSequenceName();
                    sStr.AppendAscii(sEntryEnd);

                    String aTxt;
                    int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(), 1, aTxt );
                    if (1 == nRet)
                        sStr.APPEND_CONST_ASC("\\n ");
                    else if( 3 == nRet || 4 == nRet )
                    {
                        sStr.APPEND_CONST_ASC("\\p \"");
                        sStr += aTxt;
                        sStr.AppendAscii(sEntryEnd);
                    }
                }
                break;

                //      case TOX_USER:
                //      case TOX_CONTENT:
            default:
                {
                    sStr = FieldString(eCode);

                    String sTOption;
                    sal_uInt16 n, nTOXLvl = pTOX->GetLevel();
                    if( !nTOXLvl )
                        ++nTOXLvl;

                    if( nsSwTOXElement::TOX_MARK & pTOX->GetCreateType() )
                    {
                        sStr.APPEND_CONST_ASC( "\\f " );

                        if( TOX_USER == pTOX->GetType() )
                        {
                            sStr += '\"';
                            sStr += (sal_Char)( 'A' + GetExport( ).GetId( *pTOX->GetTOXType() ) );
                            sStr.AppendAscii( sEntryEnd );
                        }

                        if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
                        {
                            const int nMinLvl = nTOXLvl;
                            if ( nMinLvl > 0 )
                            {
                                int nTmpLvl = nMinLvl;
                                if (nTmpLvl > WW8ListManager::nMaxLevel)
                                    nTmpLvl = WW8ListManager::nMaxLevel;

                                sStr.APPEND_CONST_ASC( "\\o \"1-" );
                                sStr += String::CreateFromInt32( nTmpLvl );
                                sStr.AppendAscii(sEntryEnd);

                            }
                        }


                        if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
                        {
                            // Take the TOC value of the max level to evaluate to as
                            // the starting point for the \o flag, but reduce it to the 
                            // value of the highest outline level filled by a *standard*
                            // Heading 1 - 9 style because \o "Builds a table of
                            // contents from paragraphs formatted with built-in heading
                            // styles". And afterward fill in any outline styles left
                            // uncovered by that range to the \t flag
                            //
                            // i.e. for
                            // Heading 1
                            // Heading 2
                            // custom-style
                            // Heading 4
                            // output
                            // \o 1-2 \tcustom-style,3,Heading 3,4

                            // Search over all the outline styles used and figure out
                            // what is the minimum outline level (if any) filled by a
                            // non-standard style for that level, i.e. ignore headline
                            // styles 1-9 and find the lowest valid outline level
                            sal_uInt8 nPosOfLowestNonStandardLvl = MAXLEVEL;
                            const SwTxtFmtColls& rColls = *GetExport().pDoc->GetTxtFmtColls();
                            for( n = rColls.Count(); n; )
                            {
                                const SwTxtFmtColl* pColl = rColls[ --n ];
                                sal_uInt16 nPoolId = pColl->GetPoolFmtId();
                                if (
                                    //Is a Non-Standard Outline Style
                                    (RES_POOLCOLL_HEADLINE1 > nPoolId || RES_POOLCOLL_HEADLINE9 < nPoolId) &&
                                    //Has a valid outline level
                                    (pColl->IsAssignedToListLevelOfOutlineStyle()) &&
                                    // Is less than the lowest known non-standard level
                                    (pColl->GetAssignedOutlineStyleLevel() < nPosOfLowestNonStandardLvl)
                                    )
                                {
                                    nPosOfLowestNonStandardLvl = ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
                                }
                            }

                            sal_uInt8 nMaxMSAutoEvaluate = nPosOfLowestNonStandardLvl < nTOXLvl ? nPosOfLowestNonStandardLvl : (sal_uInt8)nTOXLvl;

                            //output \o 1-X where X is the highest normal outline style to be included in the toc
                            if ( nMaxMSAutoEvaluate )
                            {
                                if (nMaxMSAutoEvaluate > WW8ListManager::nMaxLevel)
                                    nMaxMSAutoEvaluate = WW8ListManager::nMaxLevel;

                                sStr.APPEND_CONST_ASC( "\\o \"1-" );
                                sStr += String::CreateFromInt32( nMaxMSAutoEvaluate );
                                sStr.AppendAscii(sEntryEnd);
                            }

                            //collect up any other styles in the writer TOC which will
                            //not already appear in the MS TOC and place then into the
                            //\t option
                            if( nMaxMSAutoEvaluate < nTOXLvl )
                            {
                                // collect this templates into the \t otion
                                for( n = rColls.Count(); n;)
                                {
                                    const SwTxtFmtColl* pColl = rColls[ --n ];
                                    if (!pColl->IsAssignedToListLevelOfOutlineStyle())
                                        continue;
                                    sal_uInt8 nTestLvl =  ::sal::static_int_cast<sal_uInt8>(pColl->GetAssignedOutlineStyleLevel());
                                    if (nTestLvl < nTOXLvl && nTestLvl >= nMaxMSAutoEvaluate)
                                    {
                                        if( sTOption.Len() )
                                            sTOption += ',';
                                        (( sTOption += pColl->GetName() ) += ',' )
                                            += String::CreateFromInt32( nTestLvl + 1 );
                                    }
                                }
                            }
                        }

                        if( nsSwTOXElement::TOX_TEMPLATE & pTOX->GetCreateType() )
                            // --> OD 2009-02-27 #i99641#
                            // Consider additional styles regardless of TOX-outlinelevel
                            for( n = 0; n < MAXLEVEL; ++n )
                                // <--
                            {
                                const String& rStyles = pTOX->GetStyleNames( n );
                                if( rStyles.Len() )
                                {
                                    xub_StrLen nPos = 0;
                                    String sLvl( ',' );
                                    sLvl += String::CreateFromInt32( n + 1 );
                                    do {
                                        String sStyle( rStyles.GetToken( 0,
                                            TOX_STYLE_DELIMITER, nPos ));
                                        if( sStyle.Len() )
                                        {
                                            SwTxtFmtColl* pColl = GetExport().pDoc->FindTxtFmtCollByName(sStyle);
                                            if (!pColl->IsAssignedToListLevelOfOutlineStyle() || pColl->GetAssignedOutlineStyleLevel() < nTOXLvl)
                                            {
                                                if( sTOption.Len() )
                                                    sTOption += ',';
                                                ( sTOption += sStyle ) += sLvl;
                                            }
                                        }
                                    } while( STRING_NOTFOUND != nPos );
                                }
                            }

                            {
                                String aFillTxt;
                                sal_uInt8 nNoPgStt = MAXLEVEL, nNoPgEnd = MAXLEVEL;
                                bool bFirstFillTxt = true, bOnlyText = true;
                                for( n = 0; n < nTOXLvl; ++n )
                                {
                                    String aTxt;
                                    int nRet = ::lcl_CheckForm( pTOX->GetTOXForm(),
                                        static_cast< sal_uInt8 >(n+1), aTxt );
                                    if( 1 == nRet )
                                    {
                                        bOnlyText = false;
                                        if( MAXLEVEL == nNoPgStt )
                                            nNoPgStt = static_cast< sal_uInt8 >(n+1);
                                    }
                                    else
                                    {
                                        if( MAXLEVEL != nNoPgStt &&
                                            MAXLEVEL == nNoPgEnd )
                                            nNoPgEnd = sal_uInt8(n);

                                        bOnlyText = bOnlyText && 3 == nRet;
                                        if( 3 == nRet || 4 == nRet )
                                        {
                                            if( bFirstFillTxt )
                                                aFillTxt = aTxt;
                                            else if( aFillTxt != aTxt )
                                                aFillTxt.Erase();
                                            bFirstFillTxt = false;
                                        }
                                    }
                                }
                                if( MAXLEVEL != nNoPgStt )
                                {
                                    if (WW8ListManager::nMaxLevel < nNoPgEnd)
                                        nNoPgEnd = WW8ListManager::nMaxLevel;
                                    sStr.APPEND_CONST_ASC( "\\n " );
                                    sStr += String::CreateFromInt32( nNoPgStt );
                                    sStr += '-';
                                    sStr += String::CreateFromInt32( nNoPgEnd  );
                                    sStr += ' ';
                                }
                                if( bOnlyText )
                                {
                                    sStr.APPEND_CONST_ASC( "\\p \"" );
                                    sStr += aFillTxt;
                                    sStr.AppendAscii(sEntryEnd);
                                }
                            }

                            if( sTOption.Len() )
                            {
                                sStr.APPEND_CONST_ASC( "\\t \"" );
                                sStr += sTOption;
                                sStr.AppendAscii(sEntryEnd);
                            }

                            if (lcl_IsHyperlinked(pTOX->GetTOXForm(), nTOXLvl))
                                sStr.APPEND_CONST_ASC("\\h");
                    }
                    break;
                }
            }
        }

        if ( sStr.Len() )
        {
            GetExport( ).bInWriteTOX = true;
            GetExport( ).OutputField( 0, eCode, sStr, 
                                      WRITEFIELD_START | WRITEFIELD_CMD_START | WRITEFIELD_CMD_END );
        }
    }

    GetExport( ).bStartTOX = false;
}

void AttributeOutputBase::EndTOX( const SwSection& rSect,bool bCareEnd )
{
    const SwTOXBase* pTOX = rSect.GetTOXBase();
    if ( pTOX )
    {
        ww::eField eCode = TOX_INDEX == pTOX->GetType() ? ww::eINDEX : ww::eTOC;
        GetExport( ).OutputField( 0, eCode, aEmptyStr, WRITEFIELD_CLOSE );
    }
    GetExport( ).bInWriteTOX = false;
    if (bCareEnd)
        OnTOXEnding();
}

bool MSWordExportBase::GetNumberFmt(const SwField& rFld, String& rStr)
{
    // Returns a date or time format string by using the US NfKeywordTable
    bool bHasFmt = false;
    SvNumberFormatter* pNFmtr = pDoc->GetNumberFormatter();
    sal_uInt32 nFmtIdx = rFld.GetFormat();
    const SvNumberformat* pNumFmt = pNFmtr->GetEntry( nFmtIdx );
    if( pNumFmt )
    {
        sal_uInt16 nLng = rFld.GetLanguage();
        LocaleDataWrapper aLocDat(pNFmtr->GetServiceManager(),
                                  MsLangId::convertLanguageToLocale(nLng));

        String sFmt(pNumFmt->GetMappedFormatstring(GetNfKeywordTable(),
            aLocDat));

        if (sFmt.Len())
        {
            sw::ms::SwapQuotesInField(sFmt);

            rStr.APPEND_CONST_ASC( "\\@\"" );
            rStr += sFmt;
            rStr.APPEND_CONST_ASC( "\" " );
            bHasFmt = true;
        }
    }
    return bHasFmt;
}

void AttributeOutputBase::GetNumberPara( String& rStr, const SwField& rFld )
{
    switch(rFld.GetFormat())
    {
        case SVX_NUM_CHARS_UPPER_LETTER:
        case SVX_NUM_CHARS_UPPER_LETTER_N:
            rStr.APPEND_CONST_ASC( "\\*ALPHABETIC ");
            break;
        case SVX_NUM_CHARS_LOWER_LETTER:
        case SVX_NUM_CHARS_LOWER_LETTER_N:
            rStr.APPEND_CONST_ASC("\\*alphabetic ");
            break;
        case SVX_NUM_ROMAN_UPPER:
            rStr.APPEND_CONST_ASC("\\*ROMAN ");
            break;
        case SVX_NUM_ROMAN_LOWER:
            rStr.APPEND_CONST_ASC("\\*roman ");
            break;
        default:
            ASSERT(rFld.GetFormat() == SVX_NUM_ARABIC,
                "Unknown numbering type exported as default\n");
        case SVX_NUM_ARABIC:
            rStr.APPEND_CONST_ASC("\\*Arabic ");
            break;
        case SVX_NUM_PAGEDESC:
            //Nothing, use word's default
            break;
    }
}

void WW8Export::WritePostItBegin( WW8Bytes* pOut )
{
    sal_uInt8 aArr[ 3 ];
    sal_uInt8* pArr = aArr;

    // sprmCFSpec true
    if( bWrtWW8 )
        Set_UInt16( pArr, NS_sprm::LN_CFSpec );
    else
        Set_UInt8( pArr, 117 ); //sprmCFSpec
    Set_UInt8( pArr, 1 );

    pChpPlc->AppendFkpEntry( Strm().Tell() );
    WriteChar( 0x05 );              // Annotation reference

    if( pOut )
        pOut->Insert( aArr, static_cast< sal_uInt16 >(pArr - aArr), pOut->Count() );
    else
        pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
}

String FieldString(ww::eField eIndex)
{
    String sRet(CREATE_CONST_ASC("  "));
    if (const char *pField = ww::GetEnglishFieldName(eIndex))
        sRet.InsertAscii(pField, 1);
    return sRet;
}

void WW8AttributeOutput::HiddenField( const SwField& rFld )
{
    String sExpand(rFld.GetPar2());

    //replace LF 0x0A with VT 0x0B
    sExpand.SearchAndReplaceAll(0x0A, 0x0B);
    m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell());
    if (m_rWW8Export.IsUnicode())
    {
        SwWW8Writer::WriteString16(m_rWW8Export.Strm(), sExpand, false);
        static sal_uInt8 aArr[] =
        {
            0x3C, 0x08, 0x1
        };
        m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr);
    }
    else
    {
        SwWW8Writer::WriteString8(m_rWW8Export.Strm(), sExpand, false,
            RTL_TEXTENCODING_MS_1252);
        static sal_uInt8 aArr[] =
        {
            92, 0x1
        };
        m_rWW8Export.pChpPlc->AppendFkpEntry(m_rWW8Export.Strm().Tell(), sizeof(aArr), aArr);
    }
}

void WW8AttributeOutput::SetField( const SwField& rFld, ww::eField eType, const String& rCmd )
{
    const SwSetExpField* pSet=(const SwSetExpField*)(&rFld);
    const String &rVar = pSet->GetPar2();

    sal_uLong nFrom = m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell());

    GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_START |
        WRITEFIELD_CMD_START | WRITEFIELD_CMD_END);

    /*
    Is there a bookmark at the start position of this field, if so
    move it to the 0x14 of the result of the field.  This is what word
    does. MoveFieldMarks moves any bookmarks at this position to
    the beginning of the field result, and marks the bookmark as a
    fieldbookmark which is to be ended before the field end mark
    instead of after it like a normal bookmark.
    */
    m_rWW8Export.MoveFieldMarks(nFrom,m_rWW8Export.Fc2Cp(m_rWW8Export.Strm().Tell()));

    if (rVar.Len())
    {
        if (m_rWW8Export.IsUnicode())
            SwWW8Writer::WriteString16(m_rWW8Export.Strm(), rVar, false);
        else
        {
            SwWW8Writer::WriteString8(m_rWW8Export.Strm(), rVar, false,
                RTL_TEXTENCODING_MS_1252);
        }
    }
    GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_CLOSE);
}

void WW8AttributeOutput::PostitField( const SwField* pFld ) 
{
    const SwPostItField *pPFld = (const SwPostItField*)pFld;
    m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), pPFld );
    m_rWW8Export.WritePostItBegin( m_rWW8Export.pO );
}

bool WW8AttributeOutput::DropdownField( const SwField* pFld )
{
    bool bExpand = true;
    if ( m_rWW8Export.bWrtWW8 )
    {
        const SwDropDownField& rFld2 = *(SwDropDownField*)pFld;
        uno::Sequence<rtl::OUString> aItems =
            rFld2.GetItemSequence();
        GetExport().DoComboBox(rFld2.GetName(),
                           rFld2.GetHelp(),
                           rFld2.GetToolTip(),
                           rFld2.GetSelectedItem(), aItems);
        bExpand = false;
    }
    return bExpand;
}

void WW8AttributeOutput::RefField( const SwField &rFld, const String &rRef)
{
    String sStr( FieldString( ww::eREF ) );
    sStr.APPEND_CONST_ASC( "\"" );
    sStr += rRef;
    sStr.APPEND_CONST_ASC( "\" " );
    m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_START |
        WRITEFIELD_CMD_START | WRITEFIELD_CMD_END );
    String sVar = lcl_GetExpandedField( rFld );
    if ( sVar.Len() )
    {
        if ( m_rWW8Export.IsUnicode() )
            SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sVar, false );
        else
        {
            SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sVar, false,
                RTL_TEXTENCODING_MS_1252 );
        }
    }
    m_rWW8Export.OutputField( &rFld, ww::eREF, sStr, WRITEFIELD_CLOSE );
}

void WW8AttributeOutput::WriteExpand( const SwField* pFld )
{
    String sExpand( lcl_GetExpandedField( *pFld ) );
    if ( m_rWW8Export.IsUnicode() )
        SwWW8Writer::WriteString16( m_rWW8Export.Strm(), sExpand, false );
    else
    {
        SwWW8Writer::WriteString8( m_rWW8Export.Strm(), sExpand, false,
            RTL_TEXTENCODING_MS_1252 );
    }
}

void AttributeOutputBase::TextField( const SwFmtFld& rField )
{
    const SwField* pFld = rField.GetField();
    String sStr;        // fuer optionale Parameter
    bool bWriteExpand = false;
    const sal_uInt16 nSubType = pFld->GetSubType();

    switch (pFld->GetTyp()->Which())
    {
    case RES_GETEXPFLD:
        if (nSubType == nsSwGetSetExpType::GSE_STRING)
        {
            const SwGetExpField *pGet=(const SwGetExpField*)(pFld);
            RefField( *pGet, pGet->GetFormula() );
        }
        else
            bWriteExpand = true;
        break;
    case RES_SETEXPFLD:
        if (nsSwGetSetExpType::GSE_SEQ == nSubType)
        {
            sStr = FieldString(ww::eSEQ);
            sStr.APPEND_CONST_ASC("\"");
            sStr += pFld->GetTyp()->GetName();
            sStr.APPEND_CONST_ASC( "\" " );

            GetNumberPara( sStr, *pFld );
            GetExport().OutputField(pFld, ww::eSEQ, sStr);
        }
        else if (nSubType & nsSwGetSetExpType::GSE_STRING)
        {
            bool bShowAsWell = false;
            ww::eField eFieldNo;
            const SwSetExpField *pSet=(const SwSetExpField*)(pFld);
            const String &rVar = pSet->GetPar2();
            if (pSet->GetInputFlag())
            {
                sStr = FieldString(ww::eASK);
                sStr.APPEND_CONST_ASC("\"");
                sStr += pSet->GetPar1();
                sStr.APPEND_CONST_ASC( "\" " );
                sStr += pSet->GetPromptText();
                sStr.APPEND_CONST_ASC( " \\d " );
                sStr += rVar;
                eFieldNo = ww::eASK;
            }
            else
            {
                sStr = FieldString(ww::eSET);
                sStr += pSet->GetPar1();
                sStr.APPEND_CONST_ASC(" \"");
                sStr += rVar;
                sStr.APPEND_CONST_ASC("\" ");
                eFieldNo = ww::eSET;
                bShowAsWell = (nSubType & nsSwExtendedSubType::SUB_INVISIBLE) ? false : true;
            }

            SetField( *pFld, eFieldNo, sStr );

            if (bShowAsWell)
                RefField( *pSet, pSet->GetPar1() );
        }
        else
            bWriteExpand = true;
        break;
    case RES_PAGENUMBERFLD:
        sStr = FieldString(ww::ePAGE);
        GetNumberPara(sStr, *pFld);
        GetExport().OutputField(pFld, ww::ePAGE, sStr);
        break;
    case RES_FILENAMEFLD:
        sStr = FieldString(ww::eFILENAME);
        if (pFld->GetFormat() == FF_PATHNAME)
            sStr.APPEND_CONST_ASC("\\p ");
        GetExport().OutputField(pFld, ww::eFILENAME, sStr);
        break;
    case RES_DBNAMEFLD:
        {
            sStr = FieldString(ww::eDATABASE);
            SwDBData aData = GetExport().pDoc->GetDBData();
            sStr += String(aData.sDataSource);
            sStr += DB_DELIM;
            sStr += String(aData.sCommand);
            GetExport().OutputField(pFld, ww::eDATABASE, sStr);
        }
        break;
    case RES_AUTHORFLD:
        {
            ww::eField eFld =
                (AF_SHORTCUT & nSubType ? ww::eUSERINITIALS : ww::eUSERNAME);
            GetExport().OutputField(pFld, eFld, FieldString(eFld));
        }
        break;
    case RES_TEMPLNAMEFLD:
        GetExport().OutputField(pFld, ww::eTEMPLATE, FieldString(ww::eTEMPLATE));
        break;
    case RES_DOCINFOFLD:    // Last printed, last edited,...
        if( DI_SUB_FIXED & nSubType )
            bWriteExpand = true;
        else
        {
            ww::eField eFld(ww::eNONE);
            switch (0xff & nSubType)
            {
                case DI_TITEL:
                    eFld = ww::eTITLE;
                    break;
                case DI_THEMA:
                    eFld = ww::eSUBJECT;
                    break;
                case DI_KEYS:
                    eFld = ww::eKEYWORDS;
                    break;
                case DI_COMMENT:
                    eFld = ww::eCOMMENTS;
                    break;
                case DI_DOCNO:
                    eFld = ww::eREVNUM;
                    break;
                case DI_CREATE:
                    if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK))
                        eFld = ww::eAUTHOR;
                    else if (GetExport().GetNumberFmt(*pFld, sStr))
                        eFld = ww::eCREATEDATE;
                    break;

                case DI_CHANGE:
                    if (DI_SUB_AUTHOR == (nSubType & DI_SUB_MASK))
                        eFld = ww::eLASTSAVEDBY;
                    else if (GetExport().GetNumberFmt(*pFld, sStr))
                        eFld = ww::eSAVEDATE;
                    break;

                case DI_PRINT:
                    if (DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK) &&
                        GetExport().GetNumberFmt(*pFld, sStr))
                        eFld = ww::ePRINTDATE;
                    break;
                case DI_EDIT:
                    if( DI_SUB_AUTHOR != (nSubType & DI_SUB_MASK ) &&
                        GetExport().GetNumberFmt( *pFld, sStr ))
                        eFld = ww::eSAVEDATE;
                    break;
                case DI_CUSTOM:
                    eFld = ww::eDOCPROPERTY;
                    {
                        static String sQuotes('\"');
                        const SwDocInfoField * pDocInfoField =
                        dynamic_cast<const SwDocInfoField *> (pFld);

                        if (pDocInfoField != NULL)
                        {
                            String sFieldname = pDocInfoField->GetFieldName();
                            xub_StrLen nIndex = sFieldname.Search(':');

                            if (nIndex != sFieldname.Len())
                                sFieldname = sFieldname.Copy(nIndex + 1);

                            sStr.Insert(sQuotes);
                            sStr.Insert(sFieldname);
                            sStr.Insert(sQuotes);
                        }
                    }
                    break;
                default:
                    break;
            }

            if (eFld != ww::eNONE)
            {
                sStr.Insert(FieldString(eFld), 0);
                GetExport().OutputField(pFld, eFld, sStr);
            }
            else
                bWriteExpand = true;
        }
        break;
    case RES_DATETIMEFLD:
        if (FIXEDFLD & nSubType || !GetExport().GetNumberFmt(*pFld, sStr))
            bWriteExpand = true;
        else
        {
            ww::eField eFld = (DATEFLD & nSubType) ? ww::eDATE : ww::eTIME;
            sStr.Insert(FieldString(eFld), 0);
            GetExport().OutputField(pFld, eFld, sStr);
        }
        break;
    case RES_DOCSTATFLD:
        {
            ww::eField eFld = ww::eNONE;

            switch (nSubType)
            {
                case DS_PAGE:
                    eFld = ww::eNUMPAGE;
                    break;
                case DS_WORD:
                    eFld = ww::eNUMWORDS;
                    break;
                case DS_CHAR:
                    eFld = ww::eNUMCHARS;
                    break;
            }

            if (eFld != ww::eNONE)
            {
                sStr = FieldString(eFld);
                GetNumberPara(sStr, *pFld);
                GetExport().OutputField(pFld, eFld, sStr);
            }
            else
                bWriteExpand = true;
        }
        break;
    case RES_EXTUSERFLD:
        {
            ww::eField eFld = ww::eNONE;
            switch (0xFF & nSubType)
            {
                case EU_FIRSTNAME:
                case EU_NAME:
                    eFld = ww::eUSERNAME;
                    break;
                case EU_SHORTCUT:
                    eFld = ww::eUSERINITIALS;
                    break;
                case EU_STREET:
                case EU_COUNTRY:
                case EU_ZIP:
                case EU_CITY:
                    eFld = ww::eUSERADDRESS;
                    break;
            }

            if (eFld != ww::eNONE)
            {
                sStr = FieldString(eFld);
                GetExport().OutputField(pFld, eFld, sStr);
            }
            else
                bWriteExpand = true;
        }
        break;
    case RES_POSTITFLD:
        //Sadly only possible for word in main document text
        if (GetExport().nTxtTyp == TXT_MAINTEXT)
        {
            PostitField( pFld );
        }
        break;
    case RES_INPUTFLD:
        {
            const SwInputField * pInputField = dynamic_cast<const SwInputField *>(pFld);

            if (pInputField->isFormField())
                GetExport().DoFormText(pInputField);
            else
            {
                sStr = FieldString(ww::eFILLIN);

                sStr.APPEND_CONST_ASC("\"");
                sStr += pFld->GetPar2();
                sStr += '\"';

                GetExport().OutputField(pFld, ww::eFILLIN, sStr);
            }
        }
        break;
    case RES_GETREFFLD:
        {
            ww::eField eFld = ww::eNONE;
            const SwGetRefField& rRFld = *(SwGetRefField*)pFld;
            switch (nSubType)
            {
                case REF_SETREFATTR:
                case REF_BOOKMARK:
                    switch (pFld->GetFormat())
                    {
                        case REF_PAGE_PGDESC:
                        case REF_PAGE:
                            eFld = ww::ePAGEREF;
                            break;
                        default:
                            eFld = ww::eREF;
                            break;
                    }
                    sStr = FieldString(eFld);
                    sStr += GetExport().GetBookmarkName(nSubType,
                        &rRFld.GetSetRefName(), 0);
                    break;
                case REF_FOOTNOTE:
                case REF_ENDNOTE:
                    switch (pFld->GetFormat())
                    {
                        case REF_PAGE_PGDESC:
                        case REF_PAGE:
                            eFld = ww::ePAGEREF;
                            break;
                        case REF_UPDOWN:
                            eFld = ww::eREF;
                            break;
                        default:
                            eFld =
                                REF_ENDNOTE == nSubType ? ww::eNOTEREF : ww::eFOOTREF;
                            break;
                    }
                    sStr = FieldString(eFld);
                    sStr += GetExport().GetBookmarkName(nSubType, 0,
                        rRFld.GetSeqNo());
                    break;
            }

            if (eFld != ww::eNONE)
            {
                switch (pFld->GetFormat())
                {
                    case REF_UPDOWN:
                        sStr.APPEND_CONST_ASC(" \\p");
                        break;
                    case REF_CHAPTER:
                        sStr.APPEND_CONST_ASC(" \\n");
                        break;
                    default:
                        break;
                }
                sStr.APPEND_CONST_ASC(" \\h ");       // insert hyperlink
                GetExport().OutputField(pFld, eFld, sStr);
            }
            else
                bWriteExpand = true;
        }
        break;
    case RES_COMBINED_CHARS:
        {
        /*
        We need a font size to fill in the defaults, if these are overridden
        (as they generally are) by character properties then those properties
        win.

        The fontsize that is used in MS for determing the defaults is always
        the CJK fontsize even if the text is not in that language, in OOo the
        largest fontsize used in the field is the one we should take, but
        whatever we do, word will actually render using the fontsize set for
        CJK text. Nevertheless we attempt to guess whether the script is in
        asian or western text based up on the first character and use the
        font size of that script as our default.
        */
        sal_uInt16 nScript;
        if( pBreakIt->GetBreakIter().is() )
            nScript = pBreakIt->GetBreakIter()->getScriptType( pFld->GetPar1(), 0);
        else
            nScript = i18n::ScriptType::ASIAN;

        long nHeight = ((SvxFontHeightItem&)(GetExport().GetItem(
            GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript)))).GetHeight();;

        nHeight = (nHeight + 10) / 20; //Font Size in points;

        /*
        Divide the combined char string into its up and down part. Get the
        font size and fill in the defaults as up == half the font size and
        down == a fifth the font size
        */
        xub_StrLen nAbove = (pFld->GetPar1().Len()+1)/2;
        sStr = FieldString(ww::eEQ);
        sStr.APPEND_CONST_ASC("\\o (\\s\\up ");
        sStr += String::CreateFromInt32(nHeight/2);

        sStr.Append('(');
        sStr += String(pFld->GetPar1(),0,nAbove);
        sStr.APPEND_CONST_ASC("), \\s\\do ");
        sStr += String::CreateFromInt32(nHeight/5);

        sStr.Append('(');
        sStr += String(pFld->GetPar1(),nAbove,pFld->GetPar1().Len()-nAbove);
        sStr.APPEND_CONST_ASC("))");
        GetExport().OutputField(pFld, ww::eEQ, sStr);
        }
        break;
    case RES_DROPDOWN:
        bWriteExpand = DropdownField( pFld );
        break;
    case RES_CHAPTERFLD:
        bWriteExpand = true;
        if (GetExport().bOutKF && rField.GetTxtFld())
        {
            const SwTxtNode *pTxtNd = GetExport().GetHdFtPageRoot();
            if (!pTxtNd)
            {
                if (const SwNode *pNd = GetExport().pCurPam->GetNode())
                    pTxtNd = pNd->GetTxtNode();
            }

            if (pTxtNd)
            {
                SwChapterField aCopy(*(const SwChapterField*)pFld);
                aCopy.ChangeExpansion(*pTxtNd, false);
                WriteExpand( &aCopy );
                bWriteExpand = false;
            }
        }
        break;
        case RES_HIDDENTXTFLD:
        {
            String sExpand(pFld->GetPar2());
            if (sExpand.Len())
            {
                HiddenField( *pFld );
            }
        }
        break;
        case RES_MACROFLD:
            sStr.ASSIGN_CONST_ASC(" MACROBUTTON");
            sStr += pFld->GetPar1();
            sStr.SearchAndReplaceAscii("StarOffice.Standard.Modul1.", String(' '));
            sStr += String(' ');
            sStr += lcl_GetExpandedField(*pFld);
            GetExport().OutputField( pFld, ww::eMACROBUTTON, sStr );
            break; 
    default:
        bWriteExpand = true;
        break;
    }

    if (bWriteExpand)
        WriteExpand( pFld );
}

void AttributeOutputBase::TextFlyContent( const SwFmtFlyCnt& rFlyContent )
{
    if ( GetExport().pOutFmtNode && dynamic_cast< const SwCntntNode* >(GetExport().pOutFmtNode) )
    {
        SwTxtNode* pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode;

        Point aLayPos;
        aLayPos = pTxtNd->FindLayoutRect( false, &aLayPos ).Pos();

        SwPosition aPos( *pTxtNd );
        sw::Frame aFrm( *rFlyContent.GetFrmFmt(), aPos );

        OutputFlyFrame_Impl( aFrm, aLayPos );
    }
}

// TOXMarks fehlen noch

// Detaillierte Einstellungen zur Trennung erlaubt WW nur dokumentenweise.
// Man koennte folgende Mimik einbauen: Die Werte des Style "Standard" werden,
// falls vorhanden, in die Document Properties ( DOP ) gesetzt.
// ---
// ACK.  Dieser Vorschlag passt exakt zu unserer Implementierung des Import,
// daher setze ich das gleich mal um. (KHZ, 07/15/2000)
void WW8AttributeOutput::ParaHyphenZone( const SvxHyphenZoneItem& rHyphenZone )
{
    // sprmPFNoAutoHyph
    if( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoAutoHyph );
    else
        m_rWW8Export.pO->Insert( 44, m_rWW8Export.pO->Count() );

    m_rWW8Export.pO->Insert( rHyphenZone.IsHyphen() ? 0 : 1, m_rWW8Export.pO->Count() );
}

void WW8AttributeOutput::ParaScriptSpace( const SfxBoolItem& rScriptSpace )
{
    sal_uInt16 nId = 0;
    if ( m_rWW8Export.bWrtWW8 )
        switch ( rScriptSpace.Which() )
        {
            case RES_PARATR_SCRIPTSPACE:            nId = NS_sprm::LN_PFAutoSpaceDE;   break;
            case RES_PARATR_HANGINGPUNCTUATION:     nId = NS_sprm::LN_PFOverflowPunct;   break;
            case RES_PARATR_FORBIDDEN_RULES:        nId = NS_sprm::LN_PFKinsoku;   break;
        }

    if ( nId )
    {
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( nId );
        else
            m_rWW8Export.pO->Insert( (sal_uInt8)nId, m_rWW8Export.pO->Count() );

        m_rWW8Export.pO->Insert( rScriptSpace.GetValue() ? 1 : 0,
                            m_rWW8Export.pO->Count() );
    }
}

void WW8AttributeOutput::ParaSnapToGrid( const SvxParaGridItem& rGrid )
{
    // sprmPFUsePgsuSettings
    // 97+ only
    if ( !m_rWW8Export.bWrtWW8 )
        return;

    m_rWW8Export.InsUInt16( NS_sprm::LN_PFUsePgsuSettings );
    m_rWW8Export.pO->Insert( rGrid.GetValue(), m_rWW8Export.pO->Count() );
}

void WW8AttributeOutput::ParaVerticalAlign( const SvxParaVertAlignItem& rAlign )
{
    // sprmPWAlignFont
    // 97+ only
    if( !m_rWW8Export.bWrtWW8 )
        return;

    m_rWW8Export.InsUInt16( NS_sprm::LN_PWAlignFont );

    sal_Int16 nVal = rAlign.GetValue();
    switch ( nVal )
    {
        case SvxParaVertAlignItem::BASELINE:
            nVal = 2;
            break;
        case SvxParaVertAlignItem::TOP:
            nVal = 0;
            break;
        case SvxParaVertAlignItem::CENTER:
            nVal = 1;
            break;
        case SvxParaVertAlignItem::BOTTOM:
            nVal = 3;
            break;
        case SvxParaVertAlignItem::AUTOMATIC:
            nVal = 4;
            break;
        default:
            nVal = 4;
            ASSERT( false, "Unknown vert alignment" );
            break;
    }
    m_rWW8Export.InsUInt16( nVal );
}


// NoHyphen: ich habe keine Entsprechung in der SW-UI und WW-UI gefunden


// RefMark, NoLineBreakHere  fehlen noch

void WW8Export::WriteFtnBegin( const SwFmtFtn& rFtn, WW8Bytes* pOutArr )
{
    WW8Bytes aAttrArr;
    bool bAutoNum = !rFtn.GetNumStr().Len();    // Auto-Nummer
    if( bAutoNum )
    {
        if( bWrtWW8 )
        {
            static const sal_uInt8 aSpec[] =
            {
                0x03, 0x6a, 0, 0, 0, 0, // sprmCObjLocation
                0x55, 0x08, 1           // sprmCFSpec
            };

            aAttrArr.Insert(aSpec, sizeof(aSpec), aAttrArr.Count());
        }
        else
        {
            static sal_uInt8 const aSpec[] =
            {
                117, 1,                         // sprmCFSpec
                68, 4, 0, 0, 0, 0               // sprmCObjLocation
            };

            aAttrArr.Insert(aSpec, sizeof(aSpec), aAttrArr.Count());
        }
    }

    // sprmCIstd
    const SwEndNoteInfo* pInfo;
    if( rFtn.IsEndNote() )
        pInfo = &pDoc->GetEndNoteInfo();
    else
        pInfo = &pDoc->GetFtnInfo();
    const SwCharFmt* pCFmt = pOutArr
                                ? pInfo->GetAnchorCharFmt( *pDoc )
                                : pInfo->GetCharFmt( *pDoc );
    if( bWrtWW8 )
        SwWW8Writer::InsUInt16( aAttrArr, NS_sprm::LN_CIstd );
    else
        aAttrArr.Insert( 80, aAttrArr.Count() );
    SwWW8Writer::InsUInt16( aAttrArr, GetId( *pCFmt ) );

                                                // fSpec-Attribut true
                            // Fuer Auto-Nummer muss ein Spezial-Zeichen
                            // in den Text und darum ein fSpec-Attribut
    pChpPlc->AppendFkpEntry( Strm().Tell() );
    if( bAutoNum )
        WriteChar( 0x02 );              // Auto-Nummer-Zeichen
    else
        // User-Nummerierung
        OutSwString( rFtn.GetNumStr(), 0, rFtn.GetNumStr().Len(),
                        IsUnicode(), RTL_TEXTENCODING_MS_1252 );

    if( pOutArr )
    {
        // insert at start of array, so the "hard" attribute overrule the
        // attributes of the character template
        pOutArr->Insert( &aAttrArr, 0 );
    }
    else
    {
        WW8Bytes aOutArr;

        // insert at start of array, so the "hard" attribute overrule the
        // attributes of the character template
        aOutArr.Insert( &aAttrArr, 0 );

        // write for the ftn number in the content, the font of the anchor
        const SwTxtFtn* pTxtFtn = rFtn.GetTxtFtn();
        if( pTxtFtn )
        {
            WW8Bytes* pOld = pO;
            pO = &aOutArr;
            SfxItemSet aSet( pDoc->GetAttrPool(), RES_CHRATR_FONT,
                                                  RES_CHRATR_FONT );

            pCFmt = pInfo->GetCharFmt( *pDoc );
            aSet.Set( pCFmt->GetAttrSet() );

            pTxtFtn->GetTxtNode().GetAttr( aSet, *pTxtFtn->GetStart(),
                                            (*pTxtFtn->GetStart()) + 1 );
            m_pAttrOutput->OutputItem( aSet.Get( RES_CHRATR_FONT ) );
            pO = pOld;
        }
        pChpPlc->AppendFkpEntry( Strm().Tell(), aOutArr.Count(),
                                                aOutArr.GetData() );
    }
}

static bool lcl_IsAtTxtEnd(const SwFmtFtn& rFtn)
{
    bool bRet = true;
    if( rFtn.GetTxtFtn() )
    {
        sal_uInt16 nWh = static_cast< sal_uInt16 >(rFtn.IsEndNote() ? RES_END_AT_TXTEND
                                      : RES_FTN_AT_TXTEND);
        const SwSectionNode* pSectNd = rFtn.GetTxtFtn()->GetTxtNode().
                                                        FindSectionNode();
        while( pSectNd && FTNEND_ATPGORDOCEND ==
                ((const SwFmtFtnAtTxtEnd&)pSectNd->GetSection().GetFmt()->
                GetFmtAttr( nWh, true)).GetValue() )
            pSectNd = pSectNd->StartOfSectionNode()->FindSectionNode();

        if (!pSectNd)
            bRet = false;   // the is ftn/end collected at Page- or Doc-End
    }
    return bRet;
}


void AttributeOutputBase::TextFootnote( const SwFmtFtn& rFtn )
{
    sal_uInt16 nTyp;
    if ( rFtn.IsEndNote() )
    {
        nTyp = REF_ENDNOTE;
        if ( GetExport().bEndAtTxtEnd )
            GetExport().bEndAtTxtEnd = lcl_IsAtTxtEnd( rFtn );
    }
    else
    {
        nTyp = REF_FOOTNOTE;
        if ( GetExport().bFtnAtTxtEnd )
            GetExport().bFtnAtTxtEnd = lcl_IsAtTxtEnd( rFtn );
    }

    // if any reference to this footnote/endnote then insert an internal
    // Bookmark.
    String sBkmkNm;
    if ( GetExport().HasRefToObject( nTyp, 0, rFtn.GetTxtFtn()->GetSeqRefNo() ))
    {
        sBkmkNm = GetExport().GetBookmarkName( nTyp, 0,
                                    rFtn.GetTxtFtn()->GetSeqRefNo() );
        GetExport().AppendBookmark( sBkmkNm );
    }

    TextFootnote_Impl( rFtn );

    if ( sBkmkNm.Len() )
        GetExport().AppendBookmark( sBkmkNm ); // FIXME: Why is it added twice?  Shouldn't this one go to WW8AttributeOuput::TextFootnote_Impl()?
}

void WW8AttributeOutput::TextFootnote_Impl( const SwFmtFtn& rFtn )
{
    WW8_WrPlcFtnEdn* pFtnEnd;
    if ( rFtn.IsEndNote() )
        pFtnEnd = m_rWW8Export.pEdn;
    else
        pFtnEnd = m_rWW8Export.pFtn;

    pFtnEnd->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), rFtn );
    m_rWW8Export.WriteFtnBegin( rFtn, m_rWW8Export.pO );
}

void WW8AttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
{
    if( rCharFmt.GetCharFmt() )
    {
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
        else
            m_rWW8Export.pO->Insert( 80, m_rWW8Export.pO->Count() );

        m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *rCharFmt.GetCharFmt() ) );
    }
}

/*
 See ww8par6.cxx Read_DoubleLine for some more info
 */
void WW8AttributeOutput::CharTwoLines( const SvxTwoLinesItem& rTwoLines )
{
    // #i28331# - check that bOn is set
    if ( rTwoLines.GetValue() )
    {
        //97+ only
        if( !m_rWW8Export.bWrtWW8 )
            return;

        m_rWW8Export.InsUInt16( NS_sprm::LN_CEastAsianLayout );
        m_rWW8Export.pO->Insert( (sal_uInt8)0x06, m_rWW8Export.pO->Count() ); //len 6
        m_rWW8Export.pO->Insert( (sal_uInt8)0x02, m_rWW8Export.pO->Count() );

        sal_Unicode cStart = rTwoLines.GetStartBracket();
        sal_Unicode cEnd = rTwoLines.GetEndBracket();

        /*
        As per usual we have problems. We can have separate left and right brackets
        in OOo, it doesn't appear that you can in word. Also in word there appear
        to only be a limited number of possibilities, we can use pretty much
        anything.

        So if we have none, we export none, if either bracket is set to a known
        word type we export both as that type (with the bracket winning out in
        the case of a conflict simply being the order of test here.

        Upshot being a documented created in word will be reexported with no
        ill effects.
        */

        sal_uInt16 nType;
        if (!cStart && !cEnd)
            nType = 0;
        else if ((cStart == '{') || (cEnd == '}'))
            nType = 4;
        else if ((cStart == '<') || (cEnd == '>'))
            nType = 3;
        else if ((cStart == '[') || (cEnd == ']'))
            nType = 2;
        else
            nType = 1;
        m_rWW8Export.InsUInt16( nType );
        static const sal_uInt8 aZeroArr[ 3 ] = { 0, 0, 0 };
        m_rWW8Export.pO->Insert( aZeroArr, 3, m_rWW8Export.pO->Count() );
    }
}

void AttributeOutputBase::ParaNumRule( const SwNumRuleItem& rNumRule )
{
    const SwTxtNode* pTxtNd = 0;
    sal_uInt16 nNumId;
    sal_uInt8 nLvl = 0;
    if ( rNumRule.GetValue().Len() )
    {
        const SwNumRule* pRule = GetExport().pDoc->FindNumRulePtr(
                                        rNumRule.GetValue() );
        if ( pRule && USHRT_MAX != ( nNumId = GetExport().GetId( *pRule ) ) )
        {
            ++nNumId;
            if ( GetExport().pOutFmtNode )
            {
                if ( dynamic_cast< const SwCntntNode* >(GetExport().pOutFmtNode) )
                {
                    pTxtNd = (SwTxtNode*)GetExport().pOutFmtNode;

                    if( pTxtNd->IsCountedInList())
                    {
                        nLvl = static_cast< sal_uInt8 >(pTxtNd->GetActualListLevel());

                        if ( pTxtNd->IsListRestart() )
                        {
                            sal_uInt16 nStartWith = static_cast< sal_uInt16 >( pTxtNd->GetActualListStartValue() );
                            nNumId = GetExport().DuplicateNumRule( pRule, nLvl, nStartWith );
                            if ( USHRT_MAX != nNumId )
                                ++nNumId;
                        }
                    }
                    else
                    {
                        // #i44815# adjust numbering for numbered paragraphs
                        // without number (NO_NUMLEVEL). These paragaphs
                        // will receive a list id 0, which WW interprets as
                        // 'no number'.
                        nNumId = 0;
                    }
                }
                else if ( dynamic_cast< const SwTxtFmtColl* >(GetExport().pOutFmtNode) )
                {
                    const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode;
                    if ( pC && pC->IsAssignedToListLevelOfOutlineStyle() )
                        nLvl = static_cast< sal_uInt8 >( pC->GetAssignedOutlineStyleLevel() ); //<-end,zhaojianwei
                }
            }
        }
        else
            nNumId = USHRT_MAX;
    }
    else
        nNumId = 0;

    if ( USHRT_MAX != nNumId )
    {
        if ( nLvl >= WW8ListManager::nMaxLevel )
            nLvl = WW8ListManager::nMaxLevel - 1;

        ParaNumRule_Impl( pTxtNd, nLvl, nNumId );
    }
}

void WW8AttributeOutput::ParaNumRule_Impl( const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId )
{
    if ( m_rWW8Export.bWrtWW8 )
    {
        // write sprmPIlvl and sprmPIlfo
        SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlvl );
		m_rWW8Export.pO->Insert( ::sal::static_int_cast<sal_uInt8>(nLvl), m_rWW8Export.pO->Count() );
        SwWW8Writer::InsUInt16( *m_rWW8Export.pO, NS_sprm::LN_PIlfo );
		SwWW8Writer::InsUInt16( *m_rWW8Export.pO, ::sal::static_int_cast<sal_uInt16>(nNumId) );
    }
    else if ( pTxtNd && m_rWW8Export.Out_SwNum( pTxtNd ) )                // NumRules
        m_rWW8Export.pSepx->SetNum( pTxtNd );
}

/* File FRMATR.HXX */

void WW8AttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
{
    if( m_rWW8Export.bOutFlyFrmAttrs )                   // Flys
    {
        if( m_rWW8Export.bOutGrf )
            return;                // Fly um Grafik -> Auto-Groesse

//???? was ist bei Prozentangaben ???
        if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE)
        {
            //"sprmPDxaWidth"
            if( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaWidth );
            else
                m_rWW8Export.pO->Insert( 28, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( (sal_uInt16)rSize.GetWidth() );
        }

        if ( rSize.GetHeight() )
        {
            // sprmPWHeightAbs
            if( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_PWHeightAbs );
            else
                m_rWW8Export.pO->Insert( 45, m_rWW8Export.pO->Count() );

            sal_uInt16 nH = 0;
            switch ( rSize.GetHeightSizeType() )
            {
                case ATT_VAR_SIZE: break;
                case ATT_FIX_SIZE: nH = (sal_uInt16)rSize.GetHeight() & 0x7fff; break;
                default:           nH = (sal_uInt16)rSize.GetHeight() | 0x8000; break;
            }
            m_rWW8Export.InsUInt16( nH );
        }
    }
    else if( m_rWW8Export.bOutPageDescs )            // PageDesc : Breite + Hoehe
    {
        if( m_rWW8Export.pAktPageDesc->GetLandscape() )
        {
            /*sprmSBOrientation*/
            if( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_SBOrientation );
            else
                m_rWW8Export.pO->Insert( 162, m_rWW8Export.pO->Count() );
            m_rWW8Export.pO->Insert( 2, m_rWW8Export.pO->Count() );
        }

        /*sprmSXaPage*/
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_SXaPage );
        else
            m_rWW8Export.pO->Insert( 164, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16(
            msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetWidth())));

        /*sprmSYaPage*/
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_SYaPage );
        else
            m_rWW8Export.pO->Insert( 165, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16(
            msword_cast<sal_uInt16>(SvxPaperInfo::GetSloppyPaperDimension(rSize.GetHeight())));
    }
}

// FillOrder fehlt noch

// ReplaceCr() wird fuer Pagebreaks und Pagedescs gebraucht. Es wird ein
// bereits geschriebenes CR durch ein Break-Zeichen ersetzt. Replace muss
// direkt nach Schreiben des CR gerufen werden.
// Rueckgabe: FilePos des ersetzten CRs + 1 oder 0 fuer nicht ersetzt

sal_uLong WW8Export::ReplaceCr( sal_uInt8 nChar )
{
    // Bug #49917#
    ASSERT( nChar, "gegen 0 ersetzt bringt WW97/95 zum Absturz" );

    bool bReplaced = false;
    SvStream& rStrm = Strm();
    sal_uLong nRetPos = 0, nPos = rStrm.Tell();
    sal_uInt8 nBCode=0;
    sal_uInt16 nUCode=0;
    //If there is at least two characters already output
    if (nPos - (IsUnicode() ? 2 : 1) >= sal_uLong(pFib->fcMin))
    {
        rStrm.SeekRel(IsUnicode() ? -2 : -1);
        if (IsUnicode())
            rStrm >> nUCode;
        else
        {
            rStrm >> nBCode;
            nUCode = nBCode;
        }
        //If the last char was a cr
        if (nUCode == 0x0d)             // CR ?
        {
            if ((nChar == 0x0c) &&
                (nPos - (IsUnicode() ? 4 : 2) >= sal_uLong(pFib->fcMin)))
            {
                rStrm.SeekRel( IsUnicode() ? -4 : -2 );
                if (IsUnicode())
                    rStrm >> nUCode;
                else
                {
                    rStrm >> nUCode;
                    nUCode = nBCode;
                }
            }
            else
            {
                rStrm.SeekRel( IsUnicode() ? -2 : -1 );
                nUCode = 0x0;
            }
            //And the para is not of len 0, then replace this cr with the mark
			//#120140# If there is a cr before a column break, need replace the cr. So remove the "nChar==0x0e" check.
            if( nUCode == 0x0d )
                bReplaced = false;
            else
            {
                bReplaced = true;
                WriteChar(nChar);
                nRetPos = nPos;
            }
        }
        else if ((nUCode == 0x0c) && (nChar == 0x0e))
        {
            //#108854# a column break after a section has
            //no effect in writer
            bReplaced = true;
        }
        rStrm.Seek( nPos );
    }
    else
        bReplaced = true;

    if (!bReplaced)
    {
        // then write as normal char
        WriteChar(nChar);
        pPiece->SetParaBreak();
        pPapPlc->AppendFkpEntry(rStrm.Tell());
        pChpPlc->AppendFkpEntry(rStrm.Tell());
        nRetPos = rStrm.Tell();
    }
#ifndef DBG_UTIL
    else
    {
        ASSERT( nRetPos || nPos == (sal_uLong)pFib->fcMin,
                "WW8_ReplaceCr an falscher FilePos gerufen" );
    }
#endif
    return nRetPos;
}

void WW8AttributeOutput::TableRowEnd(sal_uInt32 nDepth)
{
    if ( nDepth == 1 )
        m_rWW8Export.WriteChar( (sal_uInt8)0x07 );
    else if ( nDepth > 1 )
        m_rWW8Export.WriteChar( (sal_uInt8)0x0d );

    //Technically in a word document this is a different value for a row ends
    //that are not row ends directly after a cell with a graphic. But it
    //doesn't seem to make a difference
    //pMagicTable->Append(Fc2Cp(Strm().Tell()),0x1B6);
}

void AttributeOutputBase::FormatPageDescription( const SwFmtPageDesc& rPageDesc )
{
    if ( GetExport().bStyDef && GetExport().pOutFmtNode && dynamic_cast< const SwTxtFmtColl* >(GetExport().pOutFmtNode) )
    {
        const SwTxtFmtColl* pC = (SwTxtFmtColl*)GetExport().pOutFmtNode;
        if ( (SFX_ITEM_SET != pC->GetItemState( RES_BREAK, false ) ) && rPageDesc.KnowsPageDesc() )
            FormatBreak( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) );
    }
}

void WW8AttributeOutput::PageBreakBefore( bool bBreak )
{
    // sprmPPageBreakBefore/sprmPFPageBreakBefore
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFPageBreakBefore );
    else
        m_rWW8Export.pO->Insert( 9, m_rWW8Export.pO->Count() );

    m_rWW8Export.pO->Insert( bBreak ? 1 : 0, m_rWW8Export.pO->Count() );
}

// Breaks schreiben nichts in das Ausgabe-Feld rWrt.pO,
// sondern nur in den Text-Stream ( Bedingung dafuer, dass sie von Out_Break...
// gerufen werden duerfen )
void AttributeOutputBase::FormatBreak( const SvxFmtBreakItem& rBreak )
{
    if ( GetExport().bStyDef )
    {
        switch ( rBreak.GetBreak() )
        {
            // JP 21.06.99: column breaks never change to pagebreaks
            // case SVX_BREAK_COLUMN_BEFORE:
            // case SVX_BREAK_COLUMN_BOTH:
            case SVX_BREAK_NONE:
            case SVX_BREAK_PAGE_BEFORE:
            case SVX_BREAK_PAGE_BOTH:
                PageBreakBefore( rBreak.GetValue() );
                break;
            default:
                break;
        }
    }
    else if ( !GetExport().mpParentFrame )
    {
        sal_uInt8 nC = 0;
        bool bBefore = false;
        // --> OD 2007-05-29 #i76300#
        // Note: Can only be <true>, if <bBefore> equals <false>.
        bool bCheckForFollowPageDesc = false;
        // <--

        switch ( rBreak.GetBreak() )
        {
            case SVX_BREAK_NONE:                                // Ausgeschaltet
                if ( !GetExport().bBreakBefore )
                    PageBreakBefore( false );
                return;

            case SVX_BREAK_COLUMN_BEFORE:                       // ColumnBreak
                bBefore = true;
                // no break;
            case SVX_BREAK_COLUMN_AFTER:
            case SVX_BREAK_COLUMN_BOTH:
                if ( GetExport().Sections().CurrentNumberOfColumns( *GetExport().pDoc ) > 1 )
                {
                    nC = msword::ColumnBreak;
                }
                break;

            case SVX_BREAK_PAGE_BEFORE:                         // PageBreak
                // From now on(fix for #i77900#) we prefer to save a page break as
                // paragraph attribute, this has to be done after the export of the
                // paragraph ( => !GetExport().bBreakBefore )
                if ( !GetExport().bBreakBefore )
                    PageBreakBefore( true );
                break;

            case SVX_BREAK_PAGE_AFTER:
            case SVX_BREAK_PAGE_BOTH:
                nC = msword::PageBreak;
                // --> OD 2007-05-29 #i76300#
                // check for follow page description, if current writing attributes
                // of a paragraph.
                if ( dynamic_cast< const SwTxtNode* >( GetExport().pOutFmtNode ) &&
                     GetExport().GetCurItemSet() )
                {
                    bCheckForFollowPageDesc = true;
                }
                // <--
                break;

            default:
                break;
        }

        if ( ( bBefore == GetExport().bBreakBefore ) && nC )  // #49917#
        {
            // --> OD 2007-05-29 #i76300#
            bool bFollowPageDescWritten = false;
            if ( bCheckForFollowPageDesc && !bBefore )
            {
                bFollowPageDescWritten =
                    GetExport().OutputFollowPageDesc( GetExport().GetCurItemSet(),
                            dynamic_cast<const SwTxtNode*>( GetExport().pOutFmtNode ) );
            }
            if ( !bFollowPageDescWritten )
            {
                SectionBreak( nC );
            }
            // <--
        }
    }
}

void WW8AttributeOutput::SectionBreak( sal_uInt8 nC, const WW8_SepInfo* /*pSectionInfo*/ )
{
    m_rWW8Export.ReplaceCr( nC );
}

void WW8AttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
{
    if ( m_rWW8Export.bOutPageDescs && m_rWW8Export.bWrtWW8 )
    {
        sal_uInt16 nGridType = 0;
        switch ( rGrid.GetGridType() )
        {
            default:
                ASSERT(false, "Unknown grid type");
            case GRID_NONE:
                nGridType = 0;
                break;
            case GRID_LINES_ONLY:
                nGridType = 2;
                break;
            case GRID_LINES_CHARS:
                if ( rGrid.IsSnapToChars() )
                    nGridType = 3;
                else
                    nGridType = 1; 
                break;
        }
        m_rWW8Export.InsUInt16( NS_sprm::LN_SClm );
        m_rWW8Export.InsUInt16( nGridType );

        sal_uInt16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
        m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaLinePitch );
        m_rWW8Export.InsUInt16( nHeight );

        MSWordStyles * pStyles = m_rWW8Export.pStyles;
        SwFmt * pSwFmt = pStyles->GetSwFmt();

        sal_uInt32 nPageCharSize = 0;

        if (pSwFmt != NULL)
        {
            nPageCharSize = ItemGet<SvxFontHeightItem>
            (*pSwFmt, RES_CHRATR_CJK_FONTSIZE).GetHeight();
        }

        sal_Int32 nCharWidth = rGrid.GetBaseWidth() - nPageCharSize;
        sal_Int32 nFraction = 0;
        nFraction = nCharWidth % 20;
        if ( nCharWidth < 0 )
            nFraction = 20 + nFraction;
        nFraction = ( nFraction * 0xFFF ) / 20;
        nFraction = ( nFraction & 0x00000FFF );

        sal_Int32 nMain = 0;
        nMain = nCharWidth / 20;
        if ( nCharWidth < 0 )
            nMain -= 1;
        nMain = nMain * 0x1000;
        nMain = ( nMain & 0xFFFFF000 );

        sal_uInt32 nCharSpace = nFraction + nMain;
        m_rWW8Export.InsUInt16( NS_sprm::LN_SDxtCharSpace );
        m_rWW8Export.InsUInt32( nCharSpace );
    }
}

void WW8AttributeOutput::FormatPaperBin( const SvxPaperBinItem& rPaperBin )
{
    if ( m_rWW8Export.bOutPageDescs )
    {
        sal_uInt16 nVal;
        switch ( rPaperBin.GetValue() )
        {
            case 0: nVal = 15;  break;      // Automatically select
            case 1: nVal = 1;   break;      // Upper paper tray
            case 2: nVal = 4;   break;      // Manual paper feed
            default: nVal = 0;  break;
        }

        if ( nVal )
        {
            if( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( m_rWW8Export.bOutFirstPage? NS_sprm::LN_SDmBinFirst: NS_sprm::LN_SDmBinOther );
            else
                m_rWW8Export.pO->Insert( m_rWW8Export.bOutFirstPage? 140: 141, m_rWW8Export.pO->Count() );

            m_rWW8Export.InsUInt16( nVal );
        }
    }
}

void WW8AttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLR )
{
    // Flys fehlen noch ( siehe RTF )

    if ( m_rWW8Export.bOutFlyFrmAttrs )                   // Flys
    {
        // sprmPDxaFromText10
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText10 );
        else
            m_rWW8Export.pO->Insert( 49, m_rWW8Export.pO->Count() );
        // Mittelwert nehmen, da WW nur 1 Wert kennt
        m_rWW8Export.InsUInt16( (sal_uInt16) ( ( rLR.GetLeft() + rLR.GetRight() ) / 2 ) );
    }
    else if ( m_rWW8Export.bOutPageDescs )                // PageDescs
    {
        sal_uInt16 nLDist, nRDist;
        const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_BOX );
        if ( pItem )
        {
            nRDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_LEFT );
            nLDist = ((SvxBoxItem*)pItem)->CalcLineSpace( BOX_LINE_RIGHT );
        }
        else
            nLDist = nRDist = 0;
        nLDist = nLDist + (sal_uInt16)rLR.GetLeft();
        nRDist = nRDist + (sal_uInt16)rLR.GetRight();

        // sprmSDxaLeft
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaLeft );
        else
            m_rWW8Export.pO->Insert( 166, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( nLDist );

        // sprmSDxaRight
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaRight );
        else
            m_rWW8Export.pO->Insert( 167, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( nRDist );
    }
    else
    {                                          // normale Absaetze
        // sprmPDxaLeft
        if( m_rWW8Export.bWrtWW8 )
        {
            m_rWW8Export.InsUInt16( 0x845E );        //asian version ?
            m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetTxtLeft() );
        }
        else
        {
            m_rWW8Export.pO->Insert( 17, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetTxtLeft() );
        }

        // sprmPDxaRight
        if( m_rWW8Export.bWrtWW8 )
        {
            m_rWW8Export.InsUInt16( 0x845D );        //asian version ?
            m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetRight() );
        }
        else
        {
            m_rWW8Export.pO->Insert( 16, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( (sal_uInt16)rLR.GetRight() );
        }

        // sprmPDxaLeft1
        if( m_rWW8Export.bWrtWW8 )
        {
            m_rWW8Export.InsUInt16( 0x8460 );        //asian version ?
            m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() );
        }
        else
        {
            m_rWW8Export.pO->Insert( 19, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( rLR.GetTxtFirstLineOfst() );
        }
    }
}

void WW8AttributeOutput::FormatULSpace( const SvxULSpaceItem& rUL )
{
    // Flys fehlen noch ( siehe RTF )

    if ( m_rWW8Export.bOutFlyFrmAttrs )                   // Flys
    {
        // sprmPDyaFromText
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaFromText );
        else
            m_rWW8Export.pO->Insert( 48, m_rWW8Export.pO->Count() );
        // Mittelwert nehmen, da WW nur 1 Wert kennt
        m_rWW8Export.InsUInt16( (sal_uInt16) ( ( rUL.GetUpper() + rUL.GetLower() ) / 2 ) );
    }
    else if ( m_rWW8Export.bOutPageDescs )            // Page-UL
    {
        ASSERT( m_rWW8Export.GetCurItemSet(), "Impossible" );
        if ( !m_rWW8Export.GetCurItemSet() )
            return;

        HdFtDistanceGlue aDistances( *m_rWW8Export.GetCurItemSet() );

        if ( aDistances.HasHeader() )
        {
            //sprmSDyaHdrTop
            if ( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrTop );
            else
                m_rWW8Export.pO->Insert( 156, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( aDistances.dyaHdrTop );
        }

        // sprmSDyaTop
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaTop );
        else
            m_rWW8Export.pO->Insert( 168, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( aDistances.dyaTop );

        if ( aDistances.HasFooter() )
        {
            //sprmSDyaHdrBottom
            if ( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaHdrBottom );
            else
                m_rWW8Export.pO->Insert( 157, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt16( aDistances.dyaHdrBottom );
        }

        //sprmSDyaBottom
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_SDyaBottom );
        else
            m_rWW8Export.pO->Insert( 169, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( aDistances.dyaBottom );
    }
    else
    {
        // sprmPDyaBefore
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaBefore );
        else
            m_rWW8Export.pO->Insert( 21, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( rUL.GetUpper() );
        // sprmPDyaAfter
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAfter );
        else
            m_rWW8Export.pO->Insert( 22, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( rUL.GetLower() );
    }
}

// Print, Opaque, Protect fehlen noch

void WW8AttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
{
    if ( m_rWW8Export.bOutFlyFrmAttrs )
    {
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PWr );
        else
            m_rWW8Export.pO->Insert( 37, m_rWW8Export.pO->Count() );

        m_rWW8Export.pO->Insert(
                ( SURROUND_NONE != rSurround.GetSurround() ) ? 2 : 1,
                m_rWW8Export.pO->Count() );
    }
}

void WW8AttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
{
//!!!! Ankertyp und entsprechende Umrechnung fehlt noch

    if ( m_rWW8Export.bOutFlyFrmAttrs )
    {
        short nPos;
        switch( rFlyVert.GetVertOrient() )
        {
            case text::VertOrientation::NONE:
                nPos = (short)rFlyVert.GetPos();
                break;
            case text::VertOrientation::CENTER:
            case text::VertOrientation::LINE_CENTER:
                nPos = -8;
                break;
            case text::VertOrientation::BOTTOM:
            case text::VertOrientation::LINE_BOTTOM:
                nPos = -12;
                break;
            case text::VertOrientation::TOP:
            case text::VertOrientation::LINE_TOP:
            default:
                nPos = -4;
                break;
        }

        // sprmPDyaAbs
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaAbs );
        else
            m_rWW8Export.pO->Insert( 27, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( nPos );
    }
}


void WW8AttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
{
    if ( !m_rWW8Export.mpParentFrame )
    {
        ASSERT( m_rWW8Export.mpParentFrame, "HoriOrient without mpParentFrame !!" );
        return;
    }

//!!!! Ankertyp und entsprechende Umrechnung fehlt noch
    if ( m_rWW8Export.bOutFlyFrmAttrs )
    {
        short nPos;
        switch( rFlyHori.GetHoriOrient() )
        {
            case text::HoriOrientation::NONE:
                nPos = (short)rFlyHori.GetPos();
                if( !nPos )
                    nPos = 1;   // WW: 0 ist reserviert
                break;
            case text::HoriOrientation::LEFT:
                nPos = rFlyHori.IsPosToggle() ? -12 : 0;
                break;
            case text::HoriOrientation::RIGHT:
                nPos = rFlyHori.IsPosToggle() ? -16 : -8;
                break;
            case text::HoriOrientation::CENTER:
            case text::HoriOrientation::FULL:                         // FULL nur fuer Tabellen
            default:
                nPos = -4;
                break;
        }

        // sprmPDxaAbs
        if( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaAbs );
        else
            m_rWW8Export.pO->Insert( 26, m_rWW8Export.pO->Count() );
        m_rWW8Export.InsUInt16( nPos );
    }
}

void WW8AttributeOutput::FormatAnchor( const SwFmtAnchor& rAnchor )
{
    ASSERT( m_rWW8Export.mpParentFrame, "Anchor without mpParentFrame !!" );

    if ( m_rWW8Export.bOutFlyFrmAttrs )
    {
        sal_uInt8 nP = 0;
        switch ( rAnchor.GetAnchorId() )
        {
            case FLY_AT_PAGE:
                // Vert: Page | Horz: Page
                nP |= (1 << 4) | (2 << 6);
                break;
            // Im Fall eine Flys als Zeichen: Absatz-gebunden setzen!!!
            case FLY_AT_FLY:
            case FLY_AT_CHAR:
            case FLY_AT_PARA:
            case FLY_AS_CHAR:
                // Vert: Page | Horz: Page
                nP |= (2 << 4) | (0 << 6);
                break;
            default:
                break;
        }

        // sprmPPc
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PPc );
        else
            m_rWW8Export.pO->Insert( 29, m_rWW8Export.pO->Count() );
        m_rWW8Export.pO->Insert( nP, m_rWW8Export.pO->Count() );
    }
}

void WW8AttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
{
    // WW cannot have background in a section
    if ( !m_rWW8Export.bOutPageDescs )
    {
        WW8_SHD aSHD;

        m_rWW8Export.TransBrush( rBrush.GetColor(), aSHD );
        // sprmPShd
        if ( m_rWW8Export.bWrtWW8 )
            m_rWW8Export.InsUInt16( NS_sprm::LN_PShd );
        else
            m_rWW8Export.pO->Insert(47, m_rWW8Export.pO->Count());
        m_rWW8Export.InsUInt16( aSHD.GetValue() );

        // Quite a few unknowns, some might be transparency or something
        // of that nature...
        if ( m_rWW8Export.bWrtWW8 )
        {
            m_rWW8Export.InsUInt16( 0xC64D );
            m_rWW8Export.pO->Insert( 10, m_rWW8Export.pO->Count() );
            m_rWW8Export.InsUInt32( 0xFF000000 );
            m_rWW8Export.InsUInt32( SuitableBGColor( rBrush.GetColor().GetColor() ) );
            m_rWW8Export.InsUInt16( 0x0000 );
        }
    }
}

WW8_BRC WW8Export::TranslateBorderLine(const SvxBorderLine& rLine,
    sal_uInt16 nDist, bool bShadow)
{
    // M.M. This function writes out border lines to the word format similar to
    // what SwRTFWriter::OutRTFBorder does in the RTF filter Eventually it
    // would be nice if all this functionality was in the one place
    WW8_BRC aBrc;
    sal_uInt16 nWidth = rLine.GetInWidth() + rLine.GetOutWidth();
    sal_uInt8 brcType = 0, nColCode = 0;

    if( nWidth )                                // Linie ?
    {
        // BRC.brcType
        bool bDouble = 0 != rLine.GetInWidth() && 0 != rLine.GetOutWidth();
        bool bThick = !bDouble && !bWrtWW8 && nWidth > 75;
        if( bDouble )
            brcType = 3;
        else if( bThick )
            brcType = 2;
        else
            brcType = 1;

        // BRC.dxpLineWidth
        if( bThick )
            nWidth /= 2;

        if( bWrtWW8 )
        {
            // Angabe in 8tel Punkten, also durch 2.5, da 1 Punkt = 20 Twips
            nWidth = (( nWidth * 8 ) + 10 ) / 20;
            if( 0xff < nWidth )
                nWidth = 0xff;
        }
        else
        {
            // Angabe in 0.75 pt
            nWidth = ( nWidth + 7 ) / 15;
            if( nWidth > 5 )
                nWidth = 5;
        }

        if( 0 == nWidth )                       // ganz duenne Linie
            nWidth = 1;                         //       nicht weglassen

        // BRC.ico
        nColCode = TransCol( rLine.GetColor() );
    }

    // BRC.dxpSpace
    sal_uInt16 nLDist = nDist;
    nLDist /= 20;               // Masseinheit : pt
    if( nLDist > 0x1f )
        nLDist = 0x1f;

    if( bWrtWW8 )
    {
        aBrc.aBits1[0] = sal_uInt8(nWidth);
        aBrc.aBits1[1] = brcType;
        aBrc.aBits2[0] = nColCode;
        aBrc.aBits2[1] = sal_uInt8(nLDist);

        // fShadow, keine weiteren Einstellungen im WW moeglich
        if( bShadow )
            aBrc.aBits2[1] |= 0x20;
    }
    else
    {
        sal_uInt16 aBits = nWidth + ( brcType << 3 );
        aBits |= (nColCode & 0x1f) << 6;
        aBits |= nLDist << 11;
        // fShadow, keine weiteren Einstellungen im WW moeglich
        if( bShadow )
            aBits |= 0x20;
        ShortToSVBT16( aBits, aBrc.aBits1);
    }

    return aBrc;
}

// MakeBorderLine() bekommt einen WW8Bytes* uebergeben, um die Funktion
// auch fuer die Tabellen-Umrandungen zu benutzen.
// Wenn nSprmNo == 0, dann wird der Opcode nicht ausgegeben.
// bShadow darf bei Tabellenzellen *nicht* gesetzt sein !
void WW8Export::Out_BorderLine(WW8Bytes& rO, const SvxBorderLine* pLine,
    sal_uInt16 nDist, sal_uInt16 nSprmNo, bool bShadow)
{
    ASSERT( ( nSprmNo == 0 ) ||
            ( nSprmNo >= 38 && nSprmNo <= 41 ) ||
            ( nSprmNo >= NS_sprm::LN_PBrcTop && nSprmNo <= NS_sprm::LN_PBrcRight ) ||
            ( nSprmNo >= NS_sprm::LN_SBrcTop && nSprmNo <= NS_sprm::LN_SBrcRight ),
            "Sprm for border out is of range" );

    WW8_BRC aBrc;

    if (pLine)
        aBrc = TranslateBorderLine( *pLine, nDist, bShadow );

    if( bWrtWW8 )
    {
        // WW97-SprmIds
        if ( nSprmNo != 0 )
            SwWW8Writer::InsUInt16( rO, nSprmNo );

        rO.Insert( aBrc.aBits1, 2, rO.Count() );
        rO.Insert( aBrc.aBits2, 2, rO.Count() );
    }
    else
    {
        // WW95-SprmIds
        if ( nSprmNo != 0 )
            rO.Insert( (sal_uInt8)( nSprmNo ), rO.Count() );
        rO.Insert( aBrc.aBits1, 2, rO.Count() );
    }
}

// FormatBox1() ist fuer alle Boxen ausser in Tabellen.
// es wird pO des WW8Writers genommen
void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow)
{
    if ( bOutPageDescs && !bWrtWW8 )
        return; // no page ouline in WW6

    static const sal_uInt16 aBorders[] =
    {
        BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    };
    static const sal_uInt16 aPBrc[] =
    {
        NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight
    };
    static const sal_uInt16 aSBrc[] =
    {
        NS_sprm::LN_SBrcTop, NS_sprm::LN_SBrcLeft, NS_sprm::LN_SBrcBottom, NS_sprm::LN_SBrcRight
    };
    static const sal_uInt16 aWW6PBrc[] =
    {
        38, 39, 40, 41
    };

    const sal_uInt16* pBrd = aBorders;
    for( sal_uInt16 i = 0; i < 4; ++i, ++pBrd )
    {
        const SvxBorderLine* pLn = rBox.GetLine( *pBrd );

        sal_uInt16 nSprmNo = 0;
        if ( !bWrtWW8 )
            nSprmNo = aWW6PBrc[i];
        else if ( bOutPageDescs )
            nSprmNo = aSBrc[i];
        else
            nSprmNo = aPBrc[i];

        Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nSprmNo, bShadow );
    }
}

// FormatBox2() ist fuer TC-Strukturen in Tabellen. Der Sprm-Opcode
// wird nicht geschrieben, da es in der TC-Structur ohne Opcode gepackt ist.
// dxpSpace wird immer 0, da WW das in Tabellen so verlangt
// ( Tabellenumrandungen fransen sonst aus )
// Ein WW8Bytes-Ptr wird als Ausgabe-Parameter uebergeben

void WW8Export::Out_SwFmtTableBox( WW8Bytes& rO, const SvxBoxItem * pBox )
{
    // moeglich und vielleicht besser waere 0xffff
    static const sal_uInt16 aBorders[] =
    {
        BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    };
    static const SvxBorderLine aBorderLine;

    const sal_uInt16* pBrd = aBorders;
    for( int i = 0; i < 4; ++i, ++pBrd )
    {
        const SvxBorderLine* pLn;
        if (pBox != NULL)
            pLn = pBox->GetLine( *pBrd );
        else
            pLn = & aBorderLine;

        Out_BorderLine(rO, pLn, 0, 0, false);
    }
}

void WW8AttributeOutput::FormatBox( const SvxBoxItem& rBox )
{
    // Fly um Grafik-> keine Umrandung hier, da
    // der GrafikHeader bereits die Umrandung hat
    if ( !m_rWW8Export.bOutGrf )
    {
        bool bShadow = false;
        const SfxPoolItem* pItem = m_rWW8Export.HasItem( RES_SHADOW );
        if ( pItem )
        {
            const SvxShadowItem* p = (const SvxShadowItem*)pItem;
            bShadow = ( p->GetLocation() != SVX_SHADOW_NONE )
                      && ( p->GetWidth() != 0 );
        }

        m_rWW8Export.Out_SwFmtBox( rBox, bShadow );
    }
}

SwTwips WW8Export::CurrentPageWidth(SwTwips &rLeft, SwTwips &rRight) const
{
    const SwFrmFmt* pFmt = pAktPageDesc ? &pAktPageDesc->GetMaster()
        : &const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetMaster();

    const SvxLRSpaceItem& rLR = pFmt->GetLRSpace();
    SwTwips nPageSize = pFmt->GetFrmSize().GetWidth();
    rLeft = rLR.GetLeft();
    rRight = rLR.GetRight();
    return nPageSize;
}

void WW8AttributeOutput::FormatColumns_Impl( sal_uInt16 nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize )
{
    // CColumns
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_SCcolumns );
    else
        m_rWW8Export.pO->Insert( 144, m_rWW8Export.pO->Count(  ) );
    m_rWW8Export.InsUInt16( nCols - 1 );

    // DxaColumns
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColumns );
    else
        m_rWW8Export.pO->Insert( 145, m_rWW8Export.pO->Count(  ) );
    m_rWW8Export.InsUInt16( rCol.GetGutterWidth( true ) );

    // LBetween
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_SLBetween );
    else
        m_rWW8Export.pO->Insert( 158, m_rWW8Export.pO->Count(  ) );
    m_rWW8Export.pO->Insert( COLADJ_NONE == rCol.GetLineAdj(  )? 0 : 1,
                             m_rWW8Export.pO->Count(  ) );

    const SwColumns & rColumns = rCol.GetColumns(  );

    // FEvenlySpaced
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_SFEvenlySpaced );
    else
        m_rWW8Export.pO->Insert( 138, m_rWW8Export.pO->Count(  ) );
    m_rWW8Export.pO->Insert( bEven ? 1 : 0, m_rWW8Export.pO->Count(  ) );
    
#if 0 
    // FIXME what's the use of this code
    if ( bEven )
    {
        sal_uInt16 nSpace = rColumns[0]->GetRight() + rColumns[1]->GetLeft();
        for ( n = 2; n < nCols; n++ )
        {
            short nDiff = nSpace - ( rColumns[n - 1]->GetRight()
                                         + rColumns[n]->GetLeft() );
            if (nDiff > 10 || nDiff < -10)
            {
                // Toleranz: 10 tw
                bEven = false;
                break;
            }
        }
    }
#endif

    if ( !bEven )
    {
        for ( sal_uInt16 n = 0; n < nCols; ++n )
        {
            //sprmSDxaColWidth
            if ( m_rWW8Export.bWrtWW8 )
                m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColWidth );
            else
                m_rWW8Export.pO->Insert( 136, m_rWW8Export.pO->Count(  ) );
            m_rWW8Export.pO->Insert( ( sal_uInt8 ) n, m_rWW8Export.pO->Count(  ) );
            m_rWW8Export.InsUInt16( rCol.
                                    CalcPrtColWidth( n,
                                                     ( sal_uInt16 ) nPageSize ) );

            if ( n + 1 != nCols )
            {
                //sprmSDxaColSpacing
                if ( m_rWW8Export.bWrtWW8 )
                    m_rWW8Export.InsUInt16( NS_sprm::LN_SDxaColSpacing );
                else
                    m_rWW8Export.pO->Insert( 137,
                                             m_rWW8Export.pO->Count(  ) );
                m_rWW8Export.pO->Insert( ( sal_uInt8 ) n,
                                         m_rWW8Export.pO->Count(  ) );
                m_rWW8Export.InsUInt16( rColumns[n]->GetRight(  ) +
                                        rColumns[n + 1]->GetLeft(  ) );
            }
        }
    }
}

void AttributeOutputBase::FormatColumns( const SwFmtCol& rCol )
{
    const SwColumns& rColumns = rCol.GetColumns();

    sal_uInt16 nCols = rColumns.Count();
    if ( 1 < nCols && !GetExport( ).bOutFlyFrmAttrs )
    {
        // dann besorge mal die Seitenbreite ohne Raender !!

		const SwFrmFmt* pFmt = GetExport( ).pAktPageDesc ? &GetExport( ).pAktPageDesc->GetMaster() : &const_cast<const SwDoc *>(GetExport( ).pDoc)->GetPageDesc(0).GetMaster();
		const SvxFrameDirectionItem &frameDirection = pFmt->GetFrmDir();
		SwTwips nPageSize;
		if ( frameDirection.GetValue() == FRMDIR_VERT_TOP_RIGHT || frameDirection.GetValue() == FRMDIR_VERT_TOP_LEFT )
		{
			const SvxULSpaceItem &rUL = pFmt->GetULSpace();
			nPageSize = pFmt->GetFrmSize().GetHeight();
			nPageSize -= rUL.GetUpper() + rUL.GetLower();

			const SwFmtHeader *header = dynamic_cast<const SwFmtHeader *>(pFmt->GetAttrSet().GetItem(RES_HEADER));
			if ( header )
			{
				const SwFrmFmt *headerFmt = header->GetHeaderFmt();
				if (headerFmt)
				{
					nPageSize -= headerFmt->GetFrmSize().GetHeight();
				}
			}
			const SwFmtFooter *footer = dynamic_cast<const SwFmtFooter *>(pFmt->GetAttrSet().GetItem(RES_FOOTER));
			if ( footer )
			{
				const SwFrmFmt *footerFmt = footer->GetFooterFmt();
				if ( footerFmt )
				{
					nPageSize -= footerFmt->GetFrmSize().GetHeight();
				}
			}
		}
		else
		{
			const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
			nPageSize = pFmt->GetFrmSize().GetWidth();
			nPageSize -= rLR.GetLeft() + rLR.GetRight();
			//i120133: The Section width should consider page indent value.
			nPageSize -= rCol.GetAdjustValue();
			
		}

        // Nachsehen, ob alle Spalten gleich sind
        bool bEven = true;
        sal_uInt16 n;
        sal_uInt16 nColWidth = rCol.CalcPrtColWidth( 0, (sal_uInt16)nPageSize );
        for ( n = 1; n < nCols; n++ )
        {
            short nDiff = nColWidth -
                rCol.CalcPrtColWidth( n, (sal_uInt16)nPageSize );

            if ( nDiff > 10 || nDiff < -10 )      // Toleranz: 10 tw
            {
                bEven = false;
                break;
            }
        }
        
        FormatColumns_Impl( nCols, rCol, bEven, nPageSize );
    }
}

// "Paragraphs together"
void WW8AttributeOutput::FormatKeep( const SvxFmtKeepItem& rKeep )
{
    // sprmFKeepFollow
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeepFollow );
    else
        m_rWW8Export.pO->Insert( 8, m_rWW8Export.pO->Count() );

    m_rWW8Export.pO->Insert( rKeep.GetValue() ? 1 : 0, m_rWW8Export.pO->Count() );
}

// exclude a paragraph from Line Numbering
void WW8AttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
{
    // sprmPFNoLineNumb
    if( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFNoLineNumb );
    else
        m_rWW8Export.pO->Insert( 14, m_rWW8Export.pO->Count() );

    m_rWW8Export.pO->Insert( rNumbering.IsCount() ? 0 : 1, m_rWW8Export.pO->Count() );
}


/* File PARATR.HXX  */

void WW8AttributeOutput::ParaLineSpacing_Impl( short nSpace, short nMulti )
{
    // sprmPDyaLine
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine );
    else
        m_rWW8Export.pO->Insert( 20, m_rWW8Export.pO->Count() );

    m_rWW8Export.InsUInt16( nSpace );
    m_rWW8Export.InsUInt16( nMulti );
}

void AttributeOutputBase::ParaLineSpacing( const SvxLineSpacingItem& rSpacing )
{
    short nSpace = 240, nMulti = 0;

    switch ( rSpacing.GetLineSpaceRule() )
    {
        default:
            break;
        case SVX_LINE_SPACE_AUTO:
        case SVX_LINE_SPACE_FIX:
        case SVX_LINE_SPACE_MIN:
        {
            switch ( rSpacing.GetInterLineSpaceRule() )
            {
                case SVX_INTER_LINE_SPACE_FIX:      // unser Durchschuss
                {
                    // gibt es aber nicht in WW - also wie kommt man an
                    // die MaxLineHeight heran?
                    nSpace = (short)rSpacing.GetInterLineSpace();
                    sal_uInt16 nScript =
                        i18n::ScriptType::LATIN;
                    const SwAttrSet *pSet = 0;
                    if ( GetExport().pOutFmtNode && dynamic_cast< const SwFmt* >(GetExport().pOutFmtNode) )
                    {
                        const SwFmt *pFmt = (const SwFmt*)( GetExport().pOutFmtNode );
                        pSet = &pFmt->GetAttrSet();
                    }
                    else if ( GetExport().pOutFmtNode && dynamic_cast< const SwTxtNode* >(GetExport().pOutFmtNode) )
                    {
                        const SwTxtNode* pNd = (const SwTxtNode*)GetExport().pOutFmtNode;
                        pSet = &pNd->GetSwAttrSet();
                        if ( pBreakIt->GetBreakIter().is() )
                        {
                            nScript = pBreakIt->GetBreakIter()->
                                getScriptType(pNd->GetTxt(), 0);
                        }
                    }
                    ASSERT( pSet, "No attrset for lineheight :-(" );
                    if ( pSet )
                    {
                        nSpace = nSpace + (short)( AttrSetToLineHeight( *GetExport().pDoc,
                            *pSet, *Application::GetDefaultDevice(), nScript ) );
                    }
                }
                break;
            case SVX_INTER_LINE_SPACE_PROP:
                nSpace = (short)( ( 240L * rSpacing.GetPropLineSpace() ) / 100L );
                nMulti = 1;
                break;
            default:                    // z.B. Minimum oder FIX?
                if ( SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() )
                    nSpace = -(short)rSpacing.GetLineHeight();
                else
                    nSpace = (short)rSpacing.GetLineHeight();
                break;
            }
        }
        break;
    }

    ParaLineSpacing_Impl( nSpace, nMulti );
}

void WW8AttributeOutput::ParaAdjust( const SvxAdjustItem& rAdjust )
{
    // sprmPJc
    sal_uInt8 nAdj = 255;
    sal_uInt8 nAdjBiDi = 255;
    switch ( rAdjust.GetAdjust() )
    {
        case SVX_ADJUST_LEFT:
            nAdj = 0;
            nAdjBiDi = 2;
            break;
        case SVX_ADJUST_RIGHT:
            nAdj = 2;
            nAdjBiDi = 0;
            break;
        case SVX_ADJUST_BLOCKLINE:
        case SVX_ADJUST_BLOCK:
            nAdj = nAdjBiDi = 3;
            break;
        case SVX_ADJUST_CENTER:
            nAdj = nAdjBiDi = 1;
            break;
        default:
            return;    // not a supported Attribut
    }

    if ( 255 != nAdj )        // supported Attribut?
    {
        if ( m_rWW8Export.bWrtWW8 )
        {
            m_rWW8Export.InsUInt16( NS_sprm::LN_PJc );
            m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() );

            /*
            Sadly for left to right paragraphs both these values are the same,
            for right to left paragraphs the bidi one is the reverse of the
            normal one.
            */
            m_rWW8Export.InsUInt16( NS_sprm::LN_PJcExtra ); //bidi version ?
            bool bBiDiSwap = false;
            if ( m_rWW8Export.pOutFmtNode )
            {
                short nDirection = FRMDIR_HORI_LEFT_TOP;
                if ( dynamic_cast< const SwTxtNode* >(m_rWW8Export.pOutFmtNode) )
                {
                    SwPosition aPos(*(const SwCntntNode*)m_rWW8Export.pOutFmtNode);
                    nDirection = m_rWW8Export.pDoc->GetTextDirection(aPos);
                }
                else if ( dynamic_cast< const SwTxtFmtColl* >(m_rWW8Export.pOutFmtNode) )
                {
                    const SwTxtFmtColl* pC =
                        (const SwTxtFmtColl*)m_rWW8Export.pOutFmtNode;
                    const SvxFrameDirectionItem &rItem =
                        ItemGet<SvxFrameDirectionItem>(*pC, RES_FRAMEDIR);
                    nDirection = rItem.GetValue();
                }
                if ( ( nDirection == FRMDIR_HORI_RIGHT_TOP ) ||
                     ( nDirection == FRMDIR_ENVIRONMENT && Application::GetSettings().GetLayoutRTL() ) )
                {
                    bBiDiSwap = true;
                }
            }

            if ( bBiDiSwap )
                m_rWW8Export.pO->Insert( nAdjBiDi, m_rWW8Export.pO->Count() );
            else
                m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() );
        }
        else
        {
            m_rWW8Export.pO->Insert( 5, m_rWW8Export.pO->Count() );
            m_rWW8Export.pO->Insert( nAdj, m_rWW8Export.pO->Count() );
        }
    }
}

void WW8AttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDirection )
{
    if ( !m_rWW8Export.bWrtWW8 )   //8+ only
        return;

    sal_uInt16 nTextFlow=0;
    bool bBiDi = false;
    short nDir = rDirection.GetValue();

    if ( nDir == FRMDIR_ENVIRONMENT )
    {
        if ( m_rWW8Export.bOutPageDescs )
            nDir = m_rWW8Export.GetCurrentPageDirection();
        else if ( m_rWW8Export.pOutFmtNode )
        {
            if ( m_rWW8Export.bOutFlyFrmAttrs )  //frame
            {
                nDir = m_rWW8Export.TrueFrameDirection(
                    *(const SwFrmFmt*)m_rWW8Export.pOutFmtNode );
            }
            else if ( dynamic_cast< const SwCntntNode* >(m_rWW8Export.pOutFmtNode) )   //pagagraph
            {
                const SwCntntNode* pNd =
                    (const SwCntntNode*)m_rWW8Export.pOutFmtNode;
                SwPosition aPos( *pNd );
                nDir = m_rWW8Export.pDoc->GetTextDirection( aPos );
            }
            else if ( dynamic_cast< const SwTxtFmtColl* >(m_rWW8Export.pOutFmtNode) )
                nDir = FRMDIR_HORI_LEFT_TOP;    //what else can we do :-(
        }

        if ( nDir == FRMDIR_ENVIRONMENT )
            nDir = FRMDIR_HORI_LEFT_TOP;    //Set something
    }

    switch ( nDir )
    {
        default:
            //Can't get an unknown type here
            ASSERT(false, "Unknown frame direction");
        case FRMDIR_HORI_LEFT_TOP:
            nTextFlow = 0;
            break;
        case FRMDIR_HORI_RIGHT_TOP:
            nTextFlow = 0;
            bBiDi = true;
            break;
        case FRMDIR_VERT_TOP_LEFT:  //word doesn't have this
        case FRMDIR_VERT_TOP_RIGHT:
            nTextFlow = 1;
            break;
    }

    if ( m_rWW8Export.bOutPageDescs )
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_STextFlow );
        m_rWW8Export.InsUInt16( nTextFlow );
        m_rWW8Export.InsUInt16( NS_sprm::LN_SFBiDi );
        m_rWW8Export.pO->Insert( bBiDi, m_rWW8Export.pO->Count() );
    }
    else if ( !m_rWW8Export.bOutFlyFrmAttrs )  //paragraph/style
    {
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFBiDi );
        m_rWW8Export.pO->Insert( bBiDi, m_rWW8Export.pO->Count() );
    }
}

// "Separate paragraphs"
void WW8AttributeOutput::ParaSplit( const SvxFmtSplitItem& rSplit )
{
    // sprmPFKeep
    if ( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFKeep );
    else
        m_rWW8Export.pO->Insert( 7, m_rWW8Export.pO->Count() );
    m_rWW8Export.pO->Insert( rSplit.GetValue() ? 0 : 1, m_rWW8Export.pO->Count() );
}

//  Es wird nur das Item "SvxWidowItem" und nicht die Orphans uebersetzt,
//  da es fuer beides im WW nur ein Attribut "Absatzkontrolle" gibt und
//  im SW wahrscheinlich vom Anwender immer Beide oder keiner gesetzt werden.
void WW8AttributeOutput::ParaWidows( const SvxWidowsItem& rWidows )
{
// sprmPFWidowControl
    if( m_rWW8Export.bWrtWW8 )
        m_rWW8Export.InsUInt16( NS_sprm::LN_PFWidowControl );
    else
        m_rWW8Export.pO->Insert( 51, m_rWW8Export.pO->Count() );
    m_rWW8Export.pO->Insert( rWidows.GetValue() ? 1 : 0, m_rWW8Export.pO->Count() );
}


class SwWW8WrTabu
{
    sal_uInt8* pDel;                 // DelArray
    sal_uInt8* pAddPos;              // AddPos-Array
    sal_uInt8* pAddTyp;              // AddTyp-Array
    sal_uInt16 nAdd;            // so viele Tabs kommen hinzu
    sal_uInt16 nDel;            // so viele Tabs fallen weg
public:
    SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax);
    ~SwWW8WrTabu();

    void Add(const SvxTabStop &rTS, long nAdjustment);
    void Del(const SvxTabStop &rTS, long nAdjustment);
    void PutAll(WW8Export& rWW8Wrt);
};

SwWW8WrTabu::SwWW8WrTabu(sal_uInt16 nDelMax, sal_uInt16 nAddMax)
    : nAdd(0), nDel(0)
{
    pDel = nDelMax ? new sal_uInt8[nDelMax * 2] : 0;
    pAddPos = new sal_uInt8[nAddMax * 2];
    pAddTyp = new sal_uInt8[nAddMax];
}

SwWW8WrTabu::~SwWW8WrTabu()
{
    delete[] pAddTyp;
    delete[] pAddPos;
    delete[] pDel;
}

// Add( const SvxTabStop & rTS ) fuegt einen Tab in die WW-Struktur ein
void SwWW8WrTabu::Add(const SvxTabStop & rTS, long nAdjustment)
{
    // Tab-Position eintragen
    ShortToSVBT16(msword_cast<sal_Int16>(rTS.GetTabPos() + nAdjustment),
        pAddPos + (nAdd * 2));

    // Tab-Typ eintragen
    sal_uInt8 nPara = 0;
    switch (rTS.GetAdjustment())
    {
        case SVX_TAB_ADJUST_RIGHT:
            nPara = 2;
            break;
        case SVX_TAB_ADJUST_CENTER:
            nPara = 1;
            break;
        case SVX_TAB_ADJUST_DECIMAL:
            /*
            Theres nothing we can do btw the the decimal seperator has been
            customized, but if you think different remember that different
            locales have different seperators, i.e. german is a , while english
            is a .
            */
            nPara = 3;
            break;
        default:
            break;
    }

    switch( rTS.GetFill() )
    {
        case '.':   // dotted leader
            nPara |= 1 << 3;
            break;
        case '_':   // Single line leader
            nPara |= 3 << 3;
            break;
        case '-':   // hyphenated leader
            nPara |= 2 << 3;
            break;
        case '=':   // heavy line leader
            nPara |= 4 << 3;
            break;
    }

    ByteToSVBT8(nPara, pAddTyp + nAdd);
    ++nAdd;
}

// Del( const SvxTabStop & rTS ) fuegt einen zu loeschenden Tab
// in die WW-Struktur ein
void SwWW8WrTabu::Del(const SvxTabStop &rTS, long nAdjustment)
{
    // Tab-Position eintragen
    ShortToSVBT16(msword_cast<sal_Int16>(rTS.GetTabPos() + nAdjustment),
        pDel + (nDel * 2));
    ++nDel;
}

//  PutAll( WW8Export& rWW8Wrt ) schreibt das Attribut nach rWrt.pO
void SwWW8WrTabu::PutAll(WW8Export& rWrt)
{
    if (!nAdd && !nDel) //It its a no-op
        return;
    ASSERT(nAdd <= 255, "more than 255 added tabstops ?");
    ASSERT(nDel <= 255, "more than 244 removed tabstops ?");
    if (nAdd > 255)
        nAdd = 255;
    if (nDel > 255)
        nDel = 255;

    sal_uInt16 nSiz = 2 * nDel + 3 * nAdd + 2;
    if (nSiz > 255)
        nSiz = 255;

    if (rWrt.bWrtWW8)
        rWrt.InsUInt16(NS_sprm::LN_PChgTabsPapx);
    else
        rWrt.pO->Insert(15, rWrt.pO->Count());
    // cch eintragen
    rWrt.pO->Insert(msword_cast<sal_uInt8>(nSiz), rWrt.pO->Count());
    // DelArr schreiben
    rWrt.pO->Insert(msword_cast<sal_uInt8>(nDel), rWrt.pO->Count());
    rWrt.OutSprmBytes(pDel, nDel * 2);
    // InsArr schreiben
    rWrt.pO->Insert(msword_cast<sal_uInt8>(nAdd), rWrt.pO->Count());
    rWrt.OutSprmBytes(pAddPos, 2 * nAdd);         // AddPosArray
    rWrt.OutSprmBytes(pAddTyp, nAdd);             // AddTypArray
}


static void ParaTabStopAdd( WW8Export& rWrt, 
                            const SvxTabStopItem& rTStops,
                            const long nLParaMgn )
{
    SwWW8WrTabu aTab( 0, rTStops.Count());

    for( sal_uInt16 n = 0; n < rTStops.Count(); n++ )
    {
        const SvxTabStop& rTS = rTStops[n];
        // Def-Tabs ignorieren
        if (SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment())
            aTab.Add(rTS, nLParaMgn);
    }
    aTab.PutAll( rWrt );
}

bool lcl_IsEqual(long nOneLeft, const SvxTabStop &rOne,
    long nTwoLeft, const SvxTabStop &rTwo)
{
    return(
            nOneLeft == nTwoLeft &&
            rOne.GetAdjustment() == rTwo.GetAdjustment() &&
            rOne.GetDecimal() == rTwo.GetDecimal() &&
            rOne.GetFill() == rTwo.GetFill()
          );
}

static void ParaTabStopDelAdd( WW8Export& rWrt, 
                               const SvxTabStopItem& rTStyle,
                               const long nLStypeMgn, 
                               const SvxTabStopItem& rTNew, 
                               const long nLParaMgn )
{
    SwWW8WrTabu aTab(rTStyle.Count(), rTNew.Count());

    sal_uInt16 nO = 0;      // rTStyle Index
    sal_uInt16 nN = 0;      // rTNew Index

    do {
        const SvxTabStop* pTO;
        long nOP;
        if( nO < rTStyle.Count() )                  // alt noch nicht am Ende ?
        {
            pTO = &rTStyle[ nO ];
            nOP = pTO->GetTabPos() + nLStypeMgn;
            if( SVX_TAB_ADJUST_DEFAULT == pTO->GetAdjustment() )
            {
                nO++;                                // Default-Tab ignorieren
                continue;
            }
        }
        else
        {
            pTO = 0;
            nOP = LONG_MAX;
        }

        const SvxTabStop* pTN;
        long nNP;
        if( nN < rTNew.Count() )                    // neu noch nicht am Ende
        {
            pTN = &rTNew[ nN ];
            nNP = pTN->GetTabPos() + nLParaMgn;
            if( SVX_TAB_ADJUST_DEFAULT == pTN->GetAdjustment() )
            {
                nN++;                               // Default-Tab ignorieren
                continue;
            }
        }
        else
        {
            pTN = 0;
            nNP = LONG_MAX;
        }

        if( nOP == LONG_MAX && nNP == LONG_MAX )
            break;                                  // alles fertig

        if( nOP < nNP )                             // naechster Tab ist alt
        {
            aTab.Del(*pTO, nLStypeMgn);             // muss geloescht werden
            nO++;
        }
        else if( nNP < nOP )                        // naechster Tab ist neu
        {
            aTab.Add(*pTN, nLParaMgn);              // muss eigefuegt werden
            nN++;
        }
        else if (lcl_IsEqual(nOP, *pTO, nNP, *pTN)) // Tabs sind gleich:
        {
            nO++;                                   // nichts zu tun
            nN++;
        }
        else                                        // Tabs selbe Pos, diff Typ
        {
            aTab.Del(*pTO, nLStypeMgn);             // alten loeschen
            aTab.Add(*pTN, nLParaMgn);              // neuen einfuegen
            nO++;
            nN++;
        }
    } while( 1 );

    aTab.PutAll( rWrt );
}

void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
{
    const bool bTabsRelativeToIndex = m_rWW8Export.pCurPam->GetDoc()->get( IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT );

    long nCurrentLeft = 0;
    if ( bTabsRelativeToIndex )
    {
        const SfxPoolItem* pLR = m_rWW8Export.HasItem( RES_LR_SPACE );
        
        if ( pLR != NULL )
            nCurrentLeft = static_cast<const SvxLRSpaceItem*>(pLR)->GetTxtLeft();
    }

    // --> FLR 2009-03-17 #i100264#
    if ( m_rWW8Export.bStyDef &&
         m_rWW8Export.pCurrentStyle != NULL &&
         m_rWW8Export.pCurrentStyle->DerivedFrom() != NULL ) 
    {
        SvxTabStopItem aParentTabs( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
        const SwFmt *pParentStyle = m_rWW8Export.pCurrentStyle->DerivedFrom();
        {
            const SvxTabStopItem* pParentTabs = HasItem<SvxTabStopItem>( pParentStyle->GetAttrSet(), RES_PARATR_TABSTOP );
            if ( pParentTabs )
            {
                aParentTabs.Insert( pParentTabs );
            }
        }

        // #120938# - consider left indentation of style and its parent style
        long nParentLeft = 0;
        if ( bTabsRelativeToIndex )
        {
            const SvxLRSpaceItem &rStyleLR = ItemGet<SvxLRSpaceItem>( pParentStyle->GetAttrSet(), RES_LR_SPACE );
            nParentLeft = rStyleLR.GetTxtLeft();
        }

        ParaTabStopDelAdd( m_rWW8Export, aParentTabs, nParentLeft, rTabStops, nCurrentLeft );
        return;
    }
    // <--

    const SvxTabStopItem* pStyleTabs = 0;
    if ( !m_rWW8Export.bStyDef && m_rWW8Export.pStyAttr )
    {
        pStyleTabs = HasItem<SvxTabStopItem>( *m_rWW8Export.pStyAttr, RES_PARATR_TABSTOP );
    }

    if ( !pStyleTabs )
    {
        ParaTabStopAdd(m_rWW8Export, rTabStops, nCurrentLeft);
    }
    else
    {
        long nStyleLeft = 0;
        if ( bTabsRelativeToIndex )
        {
            const SvxLRSpaceItem &rStyleLR = ItemGet<SvxLRSpaceItem>(*m_rWW8Export.pStyAttr, RES_LR_SPACE);
            nStyleLeft = rStyleLR.GetTxtLeft();
        }

        ParaTabStopDelAdd( m_rWW8Export, 
                           *pStyleTabs, nStyleLeft, 
                           rTabStops, nCurrentLeft);
    }
}

//-----------------------------------------------------------------------

void AttributeOutputBase::OutputItem( const SfxPoolItem& rHt )
{
    // FIXME maybe use 'item_cast', like 'item_cast<SvxCharHiddenItem>( rHt )'?
    switch ( rHt.Which() )
    {
        case RES_CHRATR_CASEMAP:
            CharCaseMap( static_cast< const SvxCaseMapItem& >( rHt ) );
            break;
        case RES_CHRATR_COLOR:
            CharColor( static_cast< const SvxColorItem& >( rHt ) );
            break;
        case RES_CHRATR_CONTOUR:
            CharContour( static_cast< const SvxContourItem& >( rHt ) );
            break;
        case RES_CHRATR_CROSSEDOUT:
            CharCrossedOut( static_cast< const SvxCrossedOutItem& >( rHt ) );
            break;
        case RES_CHRATR_ESCAPEMENT:
            CharEscapement( static_cast< const SvxEscapementItem& >( rHt ) );
            break;
        case RES_CHRATR_FONT:
            CharFont( static_cast< const SvxFontItem& >( rHt ) );
            break;
        case RES_CHRATR_FONTSIZE:
            CharFontSize( static_cast< const SvxFontHeightItem& >( rHt ) );
            break;
        case RES_CHRATR_KERNING:
            CharKerning( static_cast< const SvxKerningItem& >( rHt ) );
            break;
        case RES_CHRATR_LANGUAGE:
            CharLanguage( static_cast< const SvxLanguageItem& >( rHt ) );
            break;
        case RES_CHRATR_POSTURE:
            CharPosture( static_cast< const SvxPostureItem& >( rHt ) );
            break;
        case RES_CHRATR_SHADOWED:
            CharShadow( static_cast< const SvxShadowedItem& >( rHt ) );
            break;
        case RES_CHRATR_UNDERLINE:
            CharUnderline( static_cast< const SvxUnderlineItem& >( rHt ) );
            break;
        case RES_CHRATR_WEIGHT:
            CharWeight( static_cast< const SvxWeightItem& >( rHt ) );
            break;
        case RES_CHRATR_AUTOKERN:
            CharAutoKern( static_cast< const SvxAutoKernItem& >( rHt ) );
            break;
        case RES_CHRATR_BLINK:
            CharAnimatedText( static_cast< const SvxBlinkItem& >( rHt ) );
            break;
        case RES_CHRATR_BACKGROUND:
            CharBackground( static_cast< const SvxBrushItem& >( rHt ) );
            break;

        case RES_CHRATR_CJK_FONT:
            CharFontCJK( static_cast< const SvxFontItem& >( rHt ) );
            break;
        case RES_CHRATR_CJK_FONTSIZE:
            CharFontSizeCJK( static_cast< const SvxFontHeightItem& >( rHt ) );
            break;
        case RES_CHRATR_CJK_LANGUAGE:
            CharLanguageCJK( static_cast< const SvxLanguageItem& >( rHt ) );
            break;
        case RES_CHRATR_CJK_POSTURE:
            CharPostureCJK( static_cast< const SvxPostureItem& >( rHt ) );
            break;
        case RES_CHRATR_CJK_WEIGHT:
            CharWeightCJK( static_cast< const SvxWeightItem& >( rHt ) );
            break;

        case RES_CHRATR_CTL_FONT:
            CharFontCTL( static_cast< const SvxFontItem& >( rHt ) );
            break;
        case RES_CHRATR_CTL_FONTSIZE:
            CharFontSizeCTL( static_cast< const SvxFontHeightItem& >( rHt ) );
            break;
        case RES_CHRATR_CTL_LANGUAGE:
            CharLanguageCTL( static_cast< const SvxLanguageItem& >( rHt ) );
            break;
        case RES_CHRATR_CTL_POSTURE:
            CharPostureCTL( static_cast< const SvxPostureItem& >( rHt ) );
            break;
        case RES_CHRATR_CTL_WEIGHT:
            CharWeightCTL( static_cast< const SvxWeightItem& >( rHt ) );
            break;

        case RES_CHRATR_ROTATE:
            CharRotate( static_cast< const SvxCharRotateItem& >( rHt ) );
            break;
        case RES_CHRATR_EMPHASIS_MARK:
            CharEmphasisMark( static_cast< const SvxEmphasisMarkItem& >( rHt ) );
            break;
        case RES_CHRATR_TWO_LINES:
            CharTwoLines( static_cast< const SvxTwoLinesItem& >( rHt ) );
            break;
        case RES_CHRATR_SCALEW:
            CharScaleWidth( static_cast< const SvxCharScaleWidthItem& >( rHt ) );
            break;
        case RES_CHRATR_RELIEF:
            CharRelief( static_cast< const SvxCharReliefItem& >( rHt ) );
            break;
        case RES_CHRATR_HIDDEN:
            CharHidden( static_cast< const SvxCharHiddenItem& >( rHt ) );
            break;
        case RES_CHRATR_BIDIRTL:
			CharBidiRTL( static_cast< const SfxPoolItem& >( rHt ) );
			break;
        case RES_CHRATR_IDCTHINT:
			CharIdctHint( static_cast< const SfxPoolItem& >( rHt ) );
			break;
        case RES_TXTATR_INETFMT:
            TextINetFormat( static_cast< const SwFmtINetFmt& >( rHt ) );
            break;
        case RES_TXTATR_CHARFMT:
            TextCharFormat( static_cast< const SwFmtCharFmt& >( rHt ) );
            break;

        case RES_TXTATR_FIELD:
        case RES_TXTATR_ANNOTATION:
        case RES_TXTATR_INPUTFIELD:
            TextField( static_cast< const SwFmtFld& >( rHt ) );
            break;

        case RES_TXTATR_FLYCNT:
            TextFlyContent( static_cast< const SwFmtFlyCnt& >( rHt ) );
            break;
        case RES_TXTATR_FTN:
            TextFootnote( static_cast< const SwFmtFtn& >( rHt ) );
            break;

        case RES_PARATR_LINESPACING:
            ParaLineSpacing( static_cast< const SvxLineSpacingItem& >( rHt ) );
            break;
        case RES_PARATR_ADJUST:
            ParaAdjust( static_cast< const SvxAdjustItem& >( rHt ) );
            break;
        case RES_PARATR_SPLIT:
            ParaSplit( static_cast< const SvxFmtSplitItem& >( rHt ) );
            break;
        case RES_PARATR_WIDOWS:
            ParaWidows( static_cast< const SvxWidowsItem& >( rHt ) );
            break;
        case RES_PARATR_TABSTOP:
            ParaTabStop( static_cast< const SvxTabStopItem& >( rHt ) );
            break;
        case RES_PARATR_HYPHENZONE:
            ParaHyphenZone( static_cast< const SvxHyphenZoneItem& >( rHt ) );
            break;
        case RES_PARATR_NUMRULE:
            ParaNumRule( static_cast< const SwNumRuleItem& >( rHt ) );
            break;
        case RES_PARATR_SCRIPTSPACE:
            ParaScriptSpace( static_cast< const SfxBoolItem& >( rHt ) );
            break;
        case RES_PARATR_HANGINGPUNCTUATION:
            ParaHangingPunctuation( static_cast< const SfxBoolItem& >( rHt ) );
            break;
        case RES_PARATR_FORBIDDEN_RULES:
            ParaForbiddenRules( static_cast< const SfxBoolItem& >( rHt ) );
            break;
        case RES_PARATR_VERTALIGN:
            ParaVerticalAlign( static_cast< const SvxParaVertAlignItem& >( rHt ) );
            break;
        case RES_PARATR_SNAPTOGRID:
            ParaSnapToGrid( static_cast< const SvxParaGridItem& >( rHt ) );
            break;

        case RES_FRM_SIZE:
            FormatFrameSize( static_cast< const SwFmtFrmSize& >( rHt ) );
            break;
        case RES_PAPER_BIN:
            FormatPaperBin( static_cast< const SvxPaperBinItem& >( rHt ) );
            break;
        case RES_LR_SPACE:
            FormatLRSpace( static_cast< const SvxLRSpaceItem& >( rHt ) );
            break;
        case RES_UL_SPACE:
            FormatULSpace( static_cast< const SvxULSpaceItem& >( rHt ) );
            break;
        case RES_PAGEDESC:
            FormatPageDescription( static_cast< const SwFmtPageDesc& >( rHt ) );
            break;
        case RES_BREAK:
            FormatBreak( static_cast< const SvxFmtBreakItem& >( rHt ) );
            break;
        case RES_SURROUND:
            FormatSurround( static_cast< const SwFmtSurround& >( rHt ) );
            break;
        case RES_VERT_ORIENT:
            FormatVertOrientation( static_cast< const SwFmtVertOrient& >( rHt ) );
            break;
        case RES_HORI_ORIENT:
            FormatHorizOrientation( static_cast< const SwFmtHoriOrient& >( rHt ) );
            break;
        case RES_ANCHOR:
            FormatAnchor( static_cast< const SwFmtAnchor& >( rHt ) );
            break;
        case RES_BACKGROUND:
            FormatBackground( static_cast< const SvxBrushItem& >( rHt ) );
            break;
        case RES_BOX:
            FormatBox( static_cast< const SvxBoxItem& >( rHt ) );
            break;
        case RES_COL:
            FormatColumns( static_cast< const SwFmtCol& >( rHt ) );
            break;
        case RES_KEEP:
            FormatKeep( static_cast< const SvxFmtKeepItem& >( rHt ) );
            break;
        case RES_TEXTGRID:
            FormatTextGrid( static_cast< const SwTextGridItem& >( rHt ) );
            break;
        case RES_LINENUMBER:
            FormatLineNumbering( static_cast< const SwFmtLineNumber& >( rHt ) );
            break;
        case RES_FRAMEDIR:
            FormatFrameDirection( static_cast< const SvxFrameDirectionItem& >( rHt ) );
            break;

        default:
            OSL_TRACE("Unhandled SfxPoolItem with id %d.\n", rHt.Which() );
            break;
    }
}

void AttributeOutputBase::OutputStyleItemSet( const SfxItemSet& rSet, sal_Bool bDeep, sal_Bool bTestForDefault )
{
    // based on OutputItemSet() from wrt_fn.cxx

    const SfxItemPool& rPool = *rSet.GetPool();
    const SfxItemSet* pSet = &rSet;
    if ( !pSet->Count() )
    {
        if ( !bDeep )
            return;

        while ( 0 != ( pSet = pSet->GetParent() ) && !pSet->Count() )
            ;

        if ( !pSet )
            return;
    }

    const SfxPoolItem* pItem;
    if ( !bDeep || !pSet->GetParent() )
    {
        ASSERT( rSet.Count(), "Wurde doch schon behandelt oder?" );
        SfxItemIter aIter( *pSet );
        pItem = aIter.GetCurItem();
        do {
            OutputItem( *pItem );
        } while ( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
    }
    else
    {
        SfxWhichIter aIter( *pSet );
        sal_uInt16 nWhich = aIter.FirstWhich();
        while ( nWhich )
        {
            if ( SFX_ITEM_SET == pSet->GetItemState( nWhich, bDeep, &pItem ) &&
                 ( !bTestForDefault ||
                   *pItem != rPool.GetDefaultItem( nWhich ) ||
                   ( pSet->GetParent() && *pItem != pSet->GetParent()->Get( nWhich ) ) ) )
            {
                OutputItem( *pItem );
            }
            nWhich = aIter.NextWhich();
        }
    }
}

/* vi:set tabstop=4 shiftwidth=4 expandtab: */
