/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sw_rdhnt.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006/11/08 12:33:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/


#pragma hdrstop

#define ITEMID_BOXINFO      SID_ATTR_BORDER_INNER

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif

#ifndef _SVX_PAPERINF_HXX //autogen
#include <bf_svx/paperinf.hxx>
#endif
#ifndef _SFXMACITEM_HXX //autogen
#include <svtools/macitem.hxx>
#endif
#ifndef _SVX_WRLMITEM_HXX //autogen
#include <bf_svx/wrlmitem.hxx>
#endif
#ifndef _SVX_BRSHITEM_HXX //autogen
#include <bf_svx/brshitem.hxx>
#endif
#ifndef _SVX_PROTITEM_HXX //autogen
#include <bf_svx/protitem.hxx>
#endif
#ifndef _SVX_OPAQITEM_HXX //autogen
#include <bf_svx/opaqitem.hxx>
#endif
#ifndef _SVX_PRNTITEM_HXX //autogen
#include <bf_svx/prntitem.hxx>
#endif
#ifndef _SVX_ULSPITEM_HXX //autogen
#include <bf_svx/ulspitem.hxx>
#endif
#ifndef _SVX_LRSPITEM_HXX //autogen
#include <bf_svx/lrspitem.hxx>
#endif
#ifndef _SVX_PBINITEM_HXX //autogen
#include <bf_svx/pbinitem.hxx>
#endif
#ifndef _SVX_BRKITEM_HXX //autogen
#include <bf_svx/brkitem.hxx>
#endif
#ifndef _SVX_SHADITEM_HXX //autogen
#include <bf_svx/shaditem.hxx>
#endif
#ifndef _SVX_BOXITEM_HXX //autogen
#include <bf_svx/boxitem.hxx>
#endif
#ifndef _SVX_UDLNITEM_HXX //autogen
#include <bf_svx/udlnitem.hxx>
#endif
#ifndef _SVX_HYZNITEM_HXX //autogen
#include <bf_svx/hyznitem.hxx>
#endif
#ifndef _SVX_TSTPITEM_HXX //autogen
#include <bf_svx/tstpitem.hxx>
#endif
#ifndef _SVX_ORPHITEM_HXX //autogen
#include <bf_svx/orphitem.hxx>
#endif
#ifndef _SVX_WIDWITEM_HXX //autogen
#include <bf_svx/widwitem.hxx>
#endif
#ifndef _SVX_SPLTITEM_HXX //autogen
#include <bf_svx/spltitem.hxx>
#endif
#ifndef _SVX_ADJITEM_HXX //autogen
#include <bf_svx/adjitem.hxx>
#endif
#ifndef _SVX_LSPCITEM_HXX //autogen
#include <bf_svx/lspcitem.hxx>
#endif
#ifndef _SVX_NHYPITEM_HXX //autogen
#include <bf_svx/nhypitem.hxx>
#endif
#ifndef _SVX_PRSZITEM_HXX //autogen
#include <bf_svx/prszitem.hxx>
#endif
#ifndef _SVX_FHGTITEM_HXX //autogen
#include <bf_svx/fhgtitem.hxx>
#endif
#ifndef _SVX_ESCPITEM_HXX //autogen
#include <bf_svx/escpitem.hxx>
#endif
#ifndef _SVX_LANGITEM_HXX //autogen
#include <bf_svx/langitem.hxx>
#endif
#ifndef _SVX_CMAPITEM_HXX //autogen
#include <bf_svx/cmapitem.hxx>
#endif
#ifndef _SVX_CRSDITEM_HXX //autogen
#include <bf_svx/crsditem.hxx>
#endif
#ifndef _SVX_KERNITEM_HXX //autogen
#include <bf_svx/kernitem.hxx>
#endif
#ifndef _SVX_CNTRITEM_HXX //autogen
#include <bf_svx/cntritem.hxx>
#endif
#ifndef _SVX_SHDDITEM_HXX //autogen
#include <bf_svx/shdditem.hxx>
#endif
#ifndef _SVX_CSCOITEM_HXX //autogen
#include <bf_svx/cscoitem.hxx>
#endif
#ifndef _SVX_WGHTITEM_HXX //autogen
#include <bf_svx/wghtitem.hxx>
#endif
#ifndef _SVX_POSTITEM_HXX //autogen
#include <bf_svx/postitem.hxx>
#endif
#ifndef _SVX_FONTITEM_HXX //autogen
#include <bf_svx/fontitem.hxx>
#endif


#ifndef _HORIORNT_HXX
#include <horiornt.hxx>
#endif

#ifndef _DOC_HXX
#include <doc.hxx>
#endif
#ifndef _SWTYPES_HXX
#include <swtypes.hxx>      //fuer MIN_BORDER_DIST
#endif

#ifndef _ERRHDL_HXX
#include <errhdl.hxx>
#endif

#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _PARATR_HXX
#include <paratr.hxx>
#endif
#ifndef _FLDBAS_HXX
#include <fldbas.hxx>
#endif
#ifndef _FMTHBSH_HXX //autogen
#include <fmthbsh.hxx>
#endif
#ifndef _FMTRFMRK_HXX //autogen
#include <fmtrfmrk.hxx>
#endif
#ifndef _FMTFLD_HXX //autogen
#include <fmtfld.hxx>
#endif
#ifndef _FMTFLCNT_HXX //autogen
#include <fmtflcnt.hxx>
#endif
#ifndef _FCHRFMT_HXX //autogen
#include <fchrfmt.hxx>
#endif
#ifndef _FMTFTN_HXX //autogen
#include <fmtftn.hxx>
#endif
#ifndef _FMTPDSC_HXX //autogen
#include <fmtpdsc.hxx>
#endif
#ifndef _FMTCLDS_HXX //autogen
#include <fmtclds.hxx>
#endif
#ifndef _FMTFSIZE_HXX //autogen
#include <fmtfsize.hxx>
#endif
#ifndef _FMTFORDR_HXX //autogen
#include <fmtfordr.hxx>
#endif
#ifndef _FMTHDFT_HXX //autogen
#include <fmthdft.hxx>
#endif
#ifndef _FMTCNTNT_HXX //autogen
#include <fmtcntnt.hxx>
#endif
#ifndef _FMTANCHR_HXX //autogen
#include <fmtanchr.hxx>
#endif
#ifndef _FMTORNT_HXX //autogen
#include <fmtornt.hxx>
#endif
#ifndef _FMTSRND_HXX //autogen
#include <fmtsrnd.hxx>
#endif
#ifndef _RDSWG_HXX
#include <rdswg.hxx>
#endif
#ifndef _PAGEDESC_HXX
#include <pagedesc.hxx>
#endif
#ifndef _GRFATR_HXX
#include <grfatr.hxx>
#endif
#ifndef _OLDHNTID_HXX
#include <oldhntid.hxx>
#endif
#ifndef _SWGIDS_HXX
#include <swgids.hxx>
#endif
#ifndef _TOX_HXX
#include <tox.hxx>
#endif
namespace binfilter {



//////////////////////////////// CHRATR.HXX ////////////////////////////////

static USHORT InSWG_SwFont
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    long nNext = rPar.r.getskip();
    BYTE eFamily, eFontPitch, eFontCharSet;
    rPar.r >> eFamily
           >> eFontPitch
           >> eFontCharSet;
    String aName  = rPar.GetText( FALSE );
    String aStyle;
    if( rPar.r.tell() < nNext )
        aStyle = rPar.GetText( FALSE );

    // irgendwann wandelte sich der StarBats vom ANSI- zum SYMBOL-Font
    if( SWG_VER_COMPAT >= rPar.aHdr.nVersion &&
        RTL_TEXTENCODING_SYMBOL !=
                eFontCharSet && aName.EqualsAscii( "StarBats" ) )
        eFontCharSet = RTL_TEXTENCODING_SYMBOL;
    SvxFontItem aAttr
        ( (FontFamily) eFamily, aName, aStyle,
          (FontPitch) eFontPitch,
          (rtl_TextEncoding) eFontCharSet );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SvxPostureItem
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nPosture;
    rPar.r >> nPosture;
    // backxxx war nie drin und wird nie drin sein!
    if( nPosture == 2 || nPosture == 4 ) return 0;
    if( nPosture > 1 ) nPosture = 2;
    SvxPostureItem aAttr( (const FontItalic) nPosture );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SvxWeightItem
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nWeight;
    rPar.r >> nWeight;
    nWeight = ( nWeight <= 4 ) ? WEIGHT_NORMAL : WEIGHT_BOLD;
    SvxWeightItem aAttr( (const FontWeight) nWeight );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwShadowed
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nState;
    rPar.r >> nState;
    SvxShadowedItem aAttr( nState );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwContour
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nState;
    rPar.r >> nState;
    SvxContourItem aAttr( nState );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwKerning
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nState;    // ignored
    long frKernZ, frKernN;
    rPar.r >> nState >> frKernZ >> frKernN;
    // Alt = Punkte, neu = Twips
    short nKern = nState ? (short) (frKernZ * 20 / frKernN ) : 0;
    SvxKerningItem aAttr( nKern );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwCrossedOut
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE chCross, bCrossOutSpaces, nState;
    rPar.r >> chCross >> bCrossOutSpaces >> nState;
    SvxCrossedOutItem aAttr( (FontStrikeout) nState );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    if( bCrossOutSpaces ) {
        SvxWordLineModeItem aMode( FALSE );
        if( pSet ) pSet->Put( aMode );
        else pNd->Insert( aMode, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    }
    return aAttr.Which();
}

static USHORT InSWG_SvxCaseMapItem
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nCaseMap;
    rPar.r >> nCaseMap;
    SvxCaseMapItem aAttr( (const SvxCaseMap) nCaseMap );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwUnderline
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE nState, bUnderlineSpaces;
    rPar.r >> nState >> bUnderlineSpaces;
    SvxUnderlineItem aAttr( (FontUnderline) nState );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    if( bUnderlineSpaces ) {
        SvxWordLineModeItem aMode( FALSE );
        if( pSet ) pSet->Put( aMode );
        else pNd->Insert( aMode, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    }
    return aAttr.Which();
}

static USHORT InSWG_SwLanguage
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    USHORT nLanguage;
    rPar.r >> nLanguage;
    if( !nLanguage )
        nLanguage = LANGUAGE_SYSTEM;
    else if( nLanguage == 0x400 )
        nLanguage = LANGUAGE_DONTKNOW;
//  else
//      rPar.TestLanguage( nLanguage );
    SvxLanguageItem aAttr( (LanguageType) nLanguage );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwEscapement
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE eEscape;
    long frEscapementZ, frEscapementN, frProportionZ, frProportionN;
    rPar.r >> eEscape >> frEscapementZ >> frEscapementN
           >> frProportionZ >> frProportionN;
    short nEsc = (short) ( frEscapementZ * 100 / frEscapementN );
    short nProp = (short) ( frProportionZ * 100 / frProportionN );
    switch( eEscape) {
        case SVX_ESCAPEMENT_OFF:
            nEsc = 0; nProp = 100; break;
        case SVX_ESCAPEMENT_SUBSCRIPT:
            nEsc = -nEsc; break;
    }
    SvxEscapementItem aAttr( nEsc, (BYTE) nProp );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwSize
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    long nSize;
    rPar.r >> nSize;
    SvxFontHeightItem aAttr( (USHORT) nSize );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwPropSize
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    long frPropSizeZ, frPropSizeN;
    rPar.r >> frPropSizeZ >> frPropSizeN;
    USHORT nFrac = (USHORT) ( frPropSizeZ * 100 / frPropSizeN );
    SvxPropSizeItem aAttr( nFrac, ITEMID_PROPSIZE );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwColor
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    USHORT red, green, blue;
    rPar.r >> red >> green >> blue;
    if( rPar.r.size() )
    {
        // Es ist noch etwas da, also ist es ein CharSetColor-Attribut
        BYTE cSet;
        rPar.r >> cSet;
        Color aColor( red, green, blue );
        SvxCharSetColorItem aAttr( aColor, (rtl_TextEncoding) cSet );
        if( pSet ) pSet->Put( aAttr );
        else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
        return aAttr.Which();
    }
    else
    {
        SvxColorItem aAttr( Color( red, green, blue ) );
        if( pSet ) pSet->Put( aAttr );
        else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
        return aAttr.Which();
    }
}

static USHORT InSWG_SwNoHyphenHere
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    BYTE bOn;
    rPar.r >> bOn;
    SvxNoHyphenItem aAttr;
    aAttr.SetValue( (BOOL) bOn );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwSoftHyphen
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    if( !pSet )
        pNd->Insert( CHAR_SOFTHYPHEN, SwIndex( pNd, nBgn ));
    return 0;
}

static USHORT InSWG_SwHardBlank
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    if( !pSet )
        pNd->Insert( CHAR_HARDBLANK, SwIndex( pNd, nBgn ));
    return 0;
}

static USHORT InSWG_SwRefMark
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    USHORT nMark;   // wird ignoriert
    rPar.r >> nMark;
    String aName = rPar.GetText( FALSE );
    if( pSet ) return 0;
    SwFmtRefMark aFmtAttr( aName );
    pNd->Insert( aFmtAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aFmtAttr.Which();
}

static USHORT InSWG_SwField
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    if( !rPar.r.size() ) return 0;
    SwField* pFld = rPar.InField();
    if( !pFld ) return 0;
    SwFmtFld aAttr( *pFld );
    delete pFld;
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwFlyCnt
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    if( pSet )
        return 0;
    if( rPar.r.peek() != SWG_FLYFMT )
        return 0;

    USHORT eSave_StartNodeType = rPar.eStartNodeType;
    rPar.eStartNodeType = SwFlyStartNode;

    rPar.r.next();
    SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*) rPar.InFormat( NULL );
    SwFmtFlyCnt aAttr( pFmt );
    rPar.eStartNodeType = eSave_StartNodeType;

    if( pSet )
        pSet->Put( aAttr );
    else
        pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwTOXMark
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    if( pSet ) return 0;
    // Flags:
    // 0x01 - hat eigenen Verz.-Namen
    // 0x02 - hat alternate Text
    // 0x04 - hat Primaeren Key
    // 0x08 - hat Sekundaeren Key
    BYTE nType, bFlags;
    const SwTOXType* pType = NULL;
    rPar.r >> nType >> bFlags;
    TOXTypes eType = (TOXTypes) nType;
    if( bFlags & 0x01 )
    {
        String aName( rPar.GetText( FALSE ) );
        USHORT n = rPar.pDoc->GetTOXTypeCount( eType );
        // Entsprechenden TOXtype suchen
        for( USHORT i = 0; i < n; i++ )
        {
            pType = rPar.pDoc->GetTOXType( eType, i );
            if( pType && pType->GetTypeName() == aName )
                break;
            pType = NULL;
        }
        // neu registrieren, falls noch nicht vorhanden
        if( !pType )
        {
            rPar.pDoc->InsertTOXType( SwTOXType( eType, aName ) );
            pType = rPar.pDoc->GetTOXType( eType, n );
        }
    }
    else
        pType = rPar.pDoc->GetTOXType( eType, 0 );
    if( pType )
    {
        SwTOXMark aMark( pType );
        if( bFlags & 0x02 )
            aMark.SetAlternativeText( rPar.GetText( FALSE ) );
        switch( nType )
        {
            case TOX_INDEX:
                if( bFlags & 0x04 )
                    aMark.SetPrimaryKey( rPar.GetText( FALSE ) );

                if( bFlags & 0x08 )
                    aMark.SetSecondaryKey( rPar.GetText( FALSE ) );

                break;
            case TOX_USER:
            case TOX_CONTENT: {
                USHORT nLevel;
                rPar.r >> nLevel;
                aMark.SetLevel( nLevel );
                } break;
            default:
                rPar.Error(); return 0;
        }
        // TOXMark mit Alternativtext aber ohne 0xff. Sowas konnte man
        // ueber die UI zwar erstellen, weil's aber ein Bug ist werden
        // die jetzt ignoriert.
        if( !aMark.IsAlternativeText() ||
            (rPar.GetReadTxt() && rPar.GetReadTxt()->Len() >= nBgn &&
                '\xff' == rPar.GetReadTxt()->GetChar(nBgn) ))
        {
            // Bug 31560: several txo marks w/o end at the same position
            if( aMark.IsAlternativeText() &&
                pNd->GetTxtAttr( nBgn, aMark.Which() ) )
            {
                ASSERT( !aMark.IsAlternativeText(),
                        "several TOXMark without end at same position" );
                return 0;
            }

            pNd->Insert( aMark, nBgn, nEnd, SETATTR_NOTXTATRCHR );
        }
        return aMark.Which();
    }
    rPar.Error(); return 0;
}

static USHORT InSWG_SwCharFmt
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    USHORT nIdx;
    rPar.r >> nIdx;
    if( (nIdx == IDX_NO_VALUE) ||
        ((nIdx&IDX_TYPEMASK) == IDX_COLLECTION) ) // bug fix #24427#
        return 0;
    SwCharFmt* pChFmt = (SwCharFmt*) rPar.FindFmt( nIdx, SWG_CHARFMT );
    SwFmtCharFmt aAttr( pChFmt );
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

static USHORT InSWG_SwFtn
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode* pNd, xub_StrLen nBgn, xub_StrLen nEnd )
{
    if( pSet ) return 0;
    String aNumber = rPar.GetText( FALSE );
    USHORT nNumber;
    rPar.r >> nNumber;
    SwFmtFtn aAttr;
    aAttr.SetNumStr( aNumber );
    aAttr.SetNumber( nNumber );
    // Der Footnote-Hint ist somewhat special. Er erhaelt
    // eine Section, wenn er in den TextNode eingefuegt wird (Brech!)
    // Daher muss der Text getrennt geparst werden (in FillTxtNode())
    if( pSet ) pSet->Put( aAttr );
    else pNd->Insert( aAttr, nBgn, nEnd, SETATTR_NOTXTATRCHR );
    return aAttr.Which();
}

///////////////////////////// PARATR.HXX ///////////////////////////////////

static USHORT InSWG_SwLineSpacing
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long frPropLineSpaceZ, frPropLineSpaceN;
    sal_Char nLineSpaceRule, nInterLineSpaceRule;
    short nInterLineSpace, nLineHeight;
    rPar.r >> frPropLineSpaceZ >> frPropLineSpaceN
           >> nLineSpaceRule   >> nInterLineSpaceRule
           >> nInterLineSpace  >> nLineHeight;
    short nFrac = (short) ( frPropLineSpaceZ * 100 / frPropLineSpaceN );
    SvxLineSpacingItem aAttr( nLineHeight );
    aAttr.SetInterLineSpace( nInterLineSpace );
    aAttr.SetPropLineSpace( (BYTE)nFrac );
    aAttr.GetLineSpaceRule() = (SvxLineSpace) nLineSpaceRule;
    aAttr.GetInterLineSpaceRule() = (SvxInterLineSpace) nInterLineSpaceRule;
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwAdjust
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    sal_Char eAdjustment;
    rPar.r >> eAdjustment;
    SvxAdjustItem aAttr( (SvxAdjust) eAdjustment );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwSplit
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    sal_Char bSplit;
    rPar.r >> bSplit;
    SvxFmtSplitItem aAttr( (BOOL) bSplit );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwWidows
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long nTwips;
    short nLines;
    rPar.r >> nLines >> nTwips;
    SvxWidowsItem aAttr( (BYTE) nLines );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwOrphans
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long nTwips;
    short nLines;
    rPar.r >> nLines >> nTwips;
    SvxOrphansItem aAttr( (BYTE) nLines );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwTabStop
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    short nTabs;
    rPar.r >> nTabs;
    SvxTabStopItem aAttr( 0, 0 );
    for( int i = 0; i < nTabs; i++ )
    {
        long nPos;
        BYTE eAdjust, cDecimal, cFill;
        rPar.r >> nPos >> eAdjust >> cDecimal >> cFill;
        if( !i || SVX_TAB_ADJUST_DEFAULT != eAdjust )
            aAttr.Insert( SvxTabStop
                ( (SwTwips) nPos, (SvxTabAdjust) eAdjust, cDecimal, cFill ) );
    }
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwHyphenZone
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bHyphen, bHyphenPageEnd;
    USHORT nMinLead, nMinTrail, nMaxHyphens;
    rPar.r >> bHyphen >> bHyphenPageEnd >> nMinLead >> nMinTrail >> nMaxHyphens;
    SvxHyphenZoneItem aAttr;
    aAttr.SetHyphen( BOOL( bHyphen != 0 ) );
    aAttr.SetPageEnd( BOOL( bHyphenPageEnd != 0 ) );
    aAttr.GetMinLead() = (BYTE) nMinLead;
    aAttr.GetMinTrail() = (BYTE) nMinTrail;
    aAttr.GetMaxHyphens() = (BYTE) nMaxHyphens;
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwDropCaps
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    USHORT nLines, nChars, nDistance, nX, nY, nFmt;
    rPar.r >> nLines >> nChars >> nDistance >> nX >> nY >> nFmt;
    SwFmtDrop aAttr;
    aAttr.GetLines() = (BYTE) nLines;
    aAttr.GetChars() = (BYTE) nChars;
    aAttr.GetDistance() = nDistance;
    aAttr.GetWholeWord() = FALSE;
    if( nFmt != IDX_NO_VALUE )
    {
        SwCharFmt* pSet = (SwCharFmt*) rPar.FindFmt( nFmt, SWG_CHARFMT );
        aAttr.SetCharFmt( pSet );
    }
    pSet->Put( aAttr );
    return aAttr.Which();
}

/////////////////////////////// FRMATR.HXX ///////////////////////////////

static USHORT InSWG_SwBox
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    short nDistance;
    rPar.r >> nDistance;
    SvxBoxItem aAttr;
    aAttr.SetDistance( nDistance );

    BOOL bDone = FALSE;
    while( !bDone )
    {
        BYTE ch = rPar.r.next();
        switch( ch )
        {
            case SWG_TOP:
            case SWG_LEFT:
            case SWG_RIGHT:
            case SWG_BOTTOM:break;
            default: bDone = TRUE;
        }
        if( !bDone )
        {
            USHORT red, green, blue;
            short nOutline, nInline, nDistance;
            rPar.r >> red >> green >> blue;
            rPar.r >> nOutline >> nInline >> nDistance;
            Color aClr( red, green, blue );
            SvxBorderLine aBorder( &aClr, nOutline, nInline, nDistance );
            switch( ch )
            {
                case SWG_TOP:    aAttr.SetLine( &aBorder, BOX_LINE_TOP ); break;
                case SWG_LEFT:   aAttr.SetLine( &aBorder, BOX_LINE_LEFT ); break;
                case SWG_RIGHT:  aAttr.SetLine( &aBorder, BOX_LINE_RIGHT ); break;
                case SWG_BOTTOM: aAttr.SetLine( &aBorder, BOX_LINE_BOTTOM ); break;
            }
        }
    }
    if ( rPar.aHdr.nVersion < SWG_VER_NEWALIGN )
    {
        //Wenn mindestens eine Line gesetzt wurde, so wird jetzt ein minimaler
        //Abstand eingetragen.
        if ( (aAttr.GetTop()    || aAttr.GetLeft() ||
              aAttr.GetBottom() || aAttr.GetRight()   ) &&
              nDistance < MIN_BORDER_DIST)
        {
            aAttr.SetDistance( MIN_BORDER_DIST );
        }
    }
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtShadow
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE cLoc;
    USHORT nWidth;
    rPar.r >> cLoc >> nWidth;
    Color aCol( rPar.InBrush() );
    SvxShadowItem aAttr( RES_SHADOW, &aCol, nWidth, (SvxShadowLocation) cLoc );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtPageDesc
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    // Dieser Hint kann bereits eingelesen werden, ehe die
    // Seitenbeschreibungen drin sind. Also, bitte erst mal speichern!
    // Das benoetigte Set muss leider "per Hand" nachgetragen werden
    // (siehe rdfmts.cxx)

    // Komischerweise gibt es immer noch leere PageDesc-Hints:
    if( !rPar.r.size() )
    {
        SwFmtPageDesc aAttr( NULL );
        pSet->Put( aAttr );
    }
    else
    {
        String aName( rPar.GetText( FALSE ) );
        USHORT nOff = 0;
        rPar.r >> nOff;
        if( aName.Len() )
            rPar.AddPageDescLink( aName, nOff );
        //JP 29.05.00: set always the hint into the AttrSet, because in
        //             InsertMode the NodeAttrSet for PageDescLink only created
        //             if there Attributes exists.
        SwFmtPageDesc aAttr( NULL );
        pSet->Put( aAttr );
    }
    return 0;
}

static USHORT InSWG_SwFmtMacro
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    if( rPar.r.peek() != SWG_MACROTBL )
        return 0;
    rPar.r.next();
    SvxMacroItem aAttr;
    short nMacro;
    rPar.r >> nMacro;
    for( short i = 0; i < nMacro; i++ )
    {
        USHORT nEvent;
        rPar.r >> nEvent;
        String aLib = rPar.GetText();
        String aMac = rPar.GetText();
        aAttr.SetMacro( nEvent, SvxMacro( aMac, aLib, STARBASIC ) );
    }
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtCol
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    // Die Longs muessen runtergerechnet werden
    sal_Char nLineAdj, bOrtho;
    short nGutterWidth;
    long  nHeightNum, nHeightDenom, nWishWidth;
    rPar.r.long4();
    rPar.r >> nLineAdj
           >> bOrtho
           >> nGutterWidth
           >> nWishWidth
           >> nHeightNum
           >> nHeightDenom;
    USHORT nMax = ( nWishWidth == LONG_MAX )
                ? USHRT_MAX
                : (USHORT) nWishWidth;
    ASSERT( nWishWidth == LONG_MAX || nWishWidth <= 65535L, "WishWidth zu gross" );
    long nFactor = nWishWidth / nMax;
    SwFmtCol aAttr;
    USHORT nLineWidth;
    Color aLineColor;
    rPar.InPen(nLineWidth, aLineColor);
    USHORT nCol;
    rPar.r >> nCol;
    if( nCol )
    {
        for( USHORT i = 0; i < nCol; i++ )
        {
            long nWishWidth;
            USHORT nLeft, nUpper, nRight, nLower;
            rPar.r >> nWishWidth >> nLeft >> nUpper >> nRight >> nLower;
            SwColumn* pCol = new SwColumn;
            pCol->SetWishWidth( (USHORT) ( nWishWidth / nFactor ) );
            pCol->SetLeft( nLeft );
            pCol->SetUpper( nUpper );
            pCol->SetRight( nRight );
            pCol->SetLower( nLower );
            aAttr.GetColumns().Insert( pCol, i );
        }
    }
    aAttr.SetLineColor( aLineColor );
    aAttr.SetLineWidth( nLineWidth );
    aAttr.SetWishWidth( (USHORT) nWishWidth );
    aAttr.SetLineHeight( (BYTE) ( nHeightNum * 100 / nHeightDenom ) );
    aAttr.SetLineAdj( (SwColLineAdj) nLineAdj );
    // temporaerer Bug Fix
    if( nCol )
        // Wert direkt mit dem Silberhammer einschlagen.
        aAttr._SetOrtho( (BOOL) bOrtho );
    rPar.r.long3();
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtFrmSize
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE nSizeType;
    long nWidth, nHeight;
    rPar.r >> nSizeType;
    rPar.r.long4();
    rPar.r >> nWidth >> nHeight;
    rPar.r.long3();
    if( rPar.IsTableBoxFrmFmt() )
    {
        // FrmSize-Attribut in TableBoxes: umdrehen!
        long n = nWidth;
        nWidth = nHeight;
        nHeight = n;
    }
    else if( nSizeType == ATT_FIX_SIZE
          && nWidth == LONG_MAX
          && nHeight == LONG_MAX )
    {
        // Uninitialisertes FrmSize-Attribut: setze auf DIN A4
        Size aSzA4 = SvxPaperInfo::GetPaperSize( SVX_PAPER_A4 );
        nWidth = aSzA4.Width();
        nHeight = aSzA4.Height();
    }

    SwFmtFrmSize aAttr( (SwFrmSize) nSizeType, nWidth, nHeight );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtFillOrder
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE nFillOrder;
    rPar.r >> nFillOrder;
    SwFmtFillOrder aAttr( (SwFillOrder) nFillOrder );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwPageBreak
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE nBreak, nIsAuto;
    rPar.r >> nBreak >> nIsAuto;
    if( nBreak != (SvxBreak) SVX_BREAK_NONE )
        nBreak += (SvxBreak) SVX_BREAK_COLUMN_BOTH;
    SvxFmtBreakItem aAttr( (SvxBreak) nBreak );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwColBreak
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE nBreak, nIsAuto;
    rPar.r >> nBreak >> nIsAuto;
    SvxFmtBreakItem aAttr( (SvxBreak) nBreak );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtPaperBin
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    short nTray;
    rPar.r >> nTray;
    SvxPaperBinItem aAttr( RES_PAPER_BIN,  (BYTE) nTray );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwLRSpace
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long left, right, firstline;
    rPar.r >> left >> right >> firstline;
    SvxLRSpaceItem aAttr;
    aAttr.SetTxtLeft( (USHORT) left );
    aAttr.SetRight( (USHORT) right );
    aAttr.SetTxtFirstLineOfst( USHORT(firstline) );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwULSpace
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long upper, lower;
    rPar.r >> upper >> lower;
    SvxULSpaceItem aAttr;
    aAttr.SetUpper( (USHORT) upper );
    aAttr.SetLower( (USHORT) lower );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtHeader
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bActive;
    SwFrmFmt* pFmt = NULL;
    rPar.r >> bActive;
    if( rPar.r.peek() == SWG_FREEFMT )
    {
        USHORT eSave_StartNodeType = rPar.eStartNodeType;
        rPar.eStartNodeType = SwHeaderStartNode;

        rPar.r.next();
        pFmt = (SwFrmFmt*) rPar.InFormat( NULL );
        rPar.RegisterFmt( *pFmt );
        SwFmtHeader aAttr( pFmt );
        aAttr.SetActive( BOOL( bActive ) );
        pSet->Put( aAttr );
        rPar.eStartNodeType = eSave_StartNodeType;

        return aAttr.Which();
    }
    else
    {
        SwFmtHeader aAttr( BOOL( bActive != 0 ) );
        pSet->Put( aAttr );
        return aAttr.Which();
    }
}

static USHORT InSWG_SwFmtFooter
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bActive;
    SwFrmFmt* pFmt = NULL;
    rPar.r >> bActive;
    if( rPar.r.peek() == SWG_FREEFMT )
    {
        USHORT eSave_StartNodeType = rPar.eStartNodeType;
        rPar.eStartNodeType = SwFooterStartNode;

        rPar.r.next();
        pFmt = (SwFrmFmt*) rPar.InFormat( NULL );
        rPar.RegisterFmt( *pFmt );
        SwFmtFooter aAttr( pFmt );
        aAttr.SetActive( BOOL( bActive != 0 ) );
        pSet->Put( aAttr );
        rPar.eStartNodeType = eSave_StartNodeType;

        return aAttr.Which();
    }
    else
    {
        SwFmtFooter aAttr( BOOL( bActive != 0 ) );
        pSet->Put( aAttr );
        return aAttr.Which();
    }
}

static USHORT InSWG_SwFmtCntnt
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    SwFmtCntnt aAttr( rPar.InSection() );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtPrint
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bActive;
    rPar.r >> bActive;
    SvxPrintItem aAttr( RES_PRINT, BOOL (bActive != 0 ) );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtOpaque
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bActive;
    rPar.r >> bActive;
    SvxOpaqueItem aAttr( RES_OPAQUE, BOOL( bActive != 0 ) );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtProtect
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bProtFrame, bProtCntnt;
    rPar.r >> bProtFrame >> bProtCntnt;
    SvxProtectItem aAttr;
    aAttr.SetPosProtect( BOOL( bProtFrame != 0 ) );
    aAttr.SetSizeProtect( BOOL( bProtFrame != 0 ) );
    aAttr.SetCntntProtect( BOOL( bProtCntnt != 0 ) );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtSurround
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE nType, bGold;
    rPar.r >> nType >> bGold;
    SwFmtSurround aAttr( (SwSurround) nType );
    if( bGold )
        aAttr.SetSurround( SURROUND_IDEAL );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtVertOrient
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long nPos;
    BYTE nOrient, nRelation;
    rPar.r >> nPos >> nOrient >> nRelation;
    if( VERT_NONE == (SwVertOrient)nOrient )
        nRelation = FRAME;
    SwFmtVertOrient aAttr( (SwTwips) nPos, (SwVertOrient) nOrient,
                           (SwRelationOrient) nRelation );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtHoriOrient
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long nPos;
    BYTE nOrient, nRelation;
    BYTE nAnchor;
    short nColumn;
    rPar.r >> nPos >> nOrient >> nRelation;
    rPar.r >> nAnchor >> nColumn;
    if( HORI_NONE == (SwHoriOrient)nOrient )
        nRelation = FRAME;
    SwFmtHoriOrient aAttr
        ( (SwTwips) nPos, (SwHoriOrient) nOrient, (SwRelationOrient) nRelation );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtAnchor
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE cType;
    USHORT nPage, nCol, nCntnt;
    rPar.r >> cType >> nPage >> nCol >> nCntnt;
    // auf globale Variable zuweisen:
    rPar.nCntntCol = (xub_StrLen)nCntnt;

    //RndId -> AnchorId mappen weil derzeit noch altes Attributformat
    //gelesen und geschrieben wird.
    switch ( cType )
    {
        case  1: cType = FLY_PAGE;      break;
        case 14: cType = FLY_AT_CNTNT;  break;
        case 15: cType = FLY_IN_CNTNT;  break;
        default: ASSERT( FALSE, "ungueltige AnchorId." );
    }

    SwFmtAnchor aAttr( (RndStdIds) cType, nPage + rPar.nPage1 );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwFmtBackground
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE bActive;
    rPar.r >> bActive;
    Color aCol = rPar.InBrush();
    SvxBrushItem aAttr( aCol, RES_BACKGROUND );
    pSet->Put( aAttr );
    return aAttr.Which();
}

/////////////////////////////// GRFATR.HXX /////////////////////////////////

static USHORT InSWG_SwMirrorGrf
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    BYTE nState;
    rPar.r >> nState;
    SwMirrorGrf aAttr( nState );
    pSet->Put( aAttr );
    return aAttr.Which();
}

static USHORT InSWG_SwCropGrf
( SwSwgReader& rPar, SfxItemSet* pSet, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    long top, left, right, bottom;
    rPar.r >> top >> left >> right >> bottom;
    SwCropGrf aCrop( -left, -right, -top, -bottom );
    pSet->Put( aCrop );
    return aCrop.Which();
}

//////////////////////////////////////////////////////////////////////////////

xub_StrLen InSWG_Nothing( SwSwgReader&, SfxItemSet*, SwTxtNode*, xub_StrLen, xub_StrLen )
{
    return 0;
}

typedef USHORT ( *SwHintFn )( SwSwgReader&, SfxItemSet*, SwTxtNode*, xub_StrLen, xub_StrLen );

SwHintFn __READONLY_DATA aChrInAttrs[] =
{
/* OLDRES_CHRATR_CASEMAP    */          InSWG_SvxCaseMapItem,
/* OLDRES_CHRATR_CHARWIDTH */           InSWG_Nothing,
/* OLDRES_CHRATR_COLOR */               InSWG_SwColor,
/* OLDRES_CHRATR_CONTOUR    */          InSWG_SwContour,
/* OLDRES_CHRATR_CROSSEDOUT */          InSWG_SwCrossedOut,
/* OLDRES_CHRATR_ESCAPEMENT */          InSWG_SwEscapement,
/* OLDRES_CHRATR_FONT   */              InSWG_SwFont,
/* OLDRES_CHRATR_FONTSIZE   */          InSWG_SwSize,
/* OLDRES_CHRATR_INVERTED   */          InSWG_Nothing,
/* OLDRES_CHRATR_KERNING    */          InSWG_SwKerning,
/* OLDRES_CHRATR_LANGUAGE   */          InSWG_SwLanguage,
/* OLDRES_CHRATR_MIRRORED   */          InSWG_Nothing,
/* OLDRES_CHRATR_POSTURE    */          InSWG_SvxPostureItem,
/* OLDRES_CHRATR_PROPORTIONALFONTSIZE*/ InSWG_SwPropSize,
/* OLDRES_CHRATR_SHADOWED   */          InSWG_SwShadowed,
/* OLDRES_CHRATR_UNDERLINE */           InSWG_SwUnderline,
/* OLDRES_CHRATR_WEIGHT */              InSWG_SvxWeightItem,
/* OLDRES_CHRATR_WRITINGDIRECTION   */  InSWG_Nothing,
/* OLDRES_CHRATR_FIELD          */      InSWG_SwField,
/* OLDRES_CHRATR_NOLINEBREAK        */  InSWG_Nothing,
/* OLDRES_CHRATR_NOHYPHEN           */  InSWG_SwNoHyphenHere,
/* OLDRES_CHRATR_SOFTHYPH           */  InSWG_SwSoftHyphen,
/* OLDRES_CHRATR_FTN                */  InSWG_SwFtn,
/* OLDRES_CHRATR_HARDBLANK          */  InSWG_SwHardBlank,
};

SwHintFn __READONLY_DATA aFontInAttrs[] =
{
/* OLDRES_TXTATR_CHARWIDTH */           InSWG_Nothing,
/* OLDRES_TXTATR_COLOR */               InSWG_SwColor,
/* OLDRES_TXTATR_CONTOUR    */          InSWG_SwContour,
/* OLDRES_TXTATR_CROSSEDOUT */          InSWG_SwCrossedOut,
/* OLDRES_TXTATR_FONT   */              InSWG_SwFont,
/* OLDRES_TXTATR_FONTSIZE   */          InSWG_SwSize,
/* OLDRES_TXTATR_INVERTED   */          InSWG_Nothing,
/* OLDRES_TXTATR_LANGUAGE   */          InSWG_SwLanguage,
/* OLDRES_TXTATR_MIRRORED   */          InSWG_Nothing,
/* OLDRES_TXTATR_POSTURE    */          InSWG_SvxPostureItem,
/* OLDRES_TXTATR_PROPORTIONALFONTSIZE*/ InSWG_SwPropSize,
/* OLDRES_TXTATR_SHADOWED   */          InSWG_SwShadowed,
/* OLDRES_TXTATR_UNDERLINE */           InSWG_SwUnderline,
/* OLDRES_TXTATR_WEIGHT */              InSWG_SvxWeightItem,
/* OLDRES_TXTATR_CHARFMT    */          InSWG_SwCharFmt,
};

SwHintFn __READONLY_DATA aEtcInAttrs[] =
{
/* OLDRES_TXTATR_WRITINGDIRECTION   */  InSWG_Nothing,
/* OLDRES_TXTATR_KERNING    */          InSWG_SwKerning,
/* OLDRES_TXTATR_NOLINEBREAK    */      InSWG_Nothing,
/* OLDRES_TXTATR_NOHYPHEN   */          InSWG_SwNoHyphenHere,
/* OLDRES_TXTATR_INSERTED   */          InSWG_Nothing,
/* OLDRES_TXTATR_DELETED    */          InSWG_Nothing,
/* OLDRES_TXTATR_ESCAPEMENT */          InSWG_SwEscapement,
/* OLDRES_TXTATR_CASEMAP    */          InSWG_SvxCaseMapItem,
/* OLDRES_TXTATR_FIELD */               InSWG_SwField,
/* OLDRES_TXTATR_FLYCNT */              InSWG_SwFlyCnt,
/* OLDRES_TXTATR_TOXMARK */             InSWG_SwTOXMark,
/* OLDRES_TXTATR_SOFTHYPH           */  InSWG_SwSoftHyphen,
/* OLDRES_TXTATR_FTN                */  InSWG_SwFtn,
/* OLDRES_TXTATR_HARDBLANK          */  InSWG_SwHardBlank,
/* OLDRES_TXTATR_REFMARK            */  InSWG_SwRefMark,
};


static SwHintFn __READONLY_DATA aParInAttrs[] =
{
/* OLDRES_PARATR_LINESPACING    */      InSWG_SwLineSpacing,
/* OLDRES_PARATR_FIRSTLINEOFFSET    */  InSWG_Nothing,      // nicht mehr da
/* OLDRES_PARATR_ADJUST */              InSWG_SwAdjust,
/* OLDRES_PARATR_SPLIT      */          InSWG_SwSplit,
/* OLDRES_PARATR_WIDOWS */              InSWG_SwWidows,
/* OLDRES_PARATR_ORPHANS    */          InSWG_SwOrphans,
/* OLDRES_PARATR_TABSTOP    */          InSWG_SwTabStop,
/* OLDRES_PARATR_HYPHENZONE */          InSWG_SwHyphenZone,
/* OLDRES_PARATR_DROP       */          InSWG_SwDropCaps,
};

static SwHintFn __READONLY_DATA aAddInAttrs[] =
{
/* OLDRES_ADD_POSTIT    */              InSWG_Nothing,
/* OLDRES_ADD_INSERTS   */              InSWG_Nothing,
/* OLDRES_ADD_AUTOTEXT */               InSWG_Nothing,
/* OLDRES_ADD_OTHERCONTENT */           InSWG_Nothing,
};

static SwHintFn __READONLY_DATA aFrmInAttrs[] =
{
/* OLDRES_FILL_ORDER    */              InSWG_SwFmtFillOrder,
/* OLDRES_FRM_SIZE */                   InSWG_SwFmtFrmSize,
/* OLDRES_PAGE_BREAK */                 InSWG_SwPageBreak,
/* OLDRES_SEL_PAGE */                   InSWG_Nothing,
/* OLDRES_PAPER_TRAY    */              InSWG_SwFmtPaperBin,
/* OLDRES_FRM_RNDREQUEST */             InSWG_Nothing,
/* OLDRES_FRM_RNDSUPPLY */              InSWG_Nothing,
/* OLDRES_LR_SPACE */                   InSWG_SwLRSpace,
/* OLDRES_UL_SPACE */                   InSWG_SwULSpace,
/* OLDRES_CNTNT */                      InSWG_SwFmtCntnt,
/* OLDRES_HEADER */                     InSWG_SwFmtHeader,
/* OLDRES_FOOTER */                     InSWG_SwFmtFooter,
/* OLDRES_FLY_PRINT */                  InSWG_SwFmtPrint,
/* OLDRES_FLY_OPAQUE */                 InSWG_SwFmtOpaque,
/* OLDRES_FLY_PROTECT */                InSWG_SwFmtProtect,
/* OLDRES_FLY_MAINCNTNT */              InSWG_SwFmtSurround,
/* OLDRES_FLY_VERT_ORIENT */            InSWG_SwFmtVertOrient,
/* OLDRES_FLY_HORI_ORIENT */            InSWG_SwFmtHoriOrient,
/* OLDRES_FLY_GENERIC */                InSWG_Nothing,
/* OLDRES_FLY_ANCHOR */                 InSWG_SwFmtAnchor,
/* OLDRES_BACKGROUND */                 InSWG_SwFmtBackground,
/* OLDRES_BOX   */                      InSWG_SwBox,
/* OLDRES_SHADOW */                     InSWG_SwFmtShadow,
/* OLDRES_PAGEDESC */                   InSWG_SwFmtPageDesc,
/* OLDRES_FRMMACRO */                   InSWG_SwFmtMacro,
/* OLDRES_COL_BREAK */                  InSWG_SwColBreak,
/* OLDRES_COL */                        InSWG_SwFmtCol
};

static SwHintFn __READONLY_DATA aGrfInAttrs[] =
{
/* OLDRES_GRFATR_GRFSIZE    */          InSWG_Nothing,
/* OLDRES_GRFATR_MIRRORGRF */           InSWG_SwMirrorGrf,
/* OLDRES_GRFATR_GRFOFFSET */           InSWG_Nothing,
/* OLDRES_GRFATR_ALIGNGRF   */          InSWG_Nothing,
/* OLDRES_GRFATR_CROPGRF    */          InSWG_SwCropGrf
};

#if defined GCC || defined HPUX
struct HintFns
#else
static struct HintFns
#endif
{
    const SwHintFn* pHintTab;
    short     nHintId1;
}
#if defined GCC || defined HPUX
;
static __READONLY_DATA HintFns aHintFns[] =
#else
__READONLY_DATA aHintFns[] =
#endif
{
    { aChrInAttrs,  OLDRES_CHRATR_BEGIN },
    { aFontInAttrs, OLDFONT_TXTATR_BEGIN},
    { aEtcInAttrs,  OLDETC_TXTATR_BEGIN },
    { aParInAttrs,  OLDRES_PARATR_BEGIN },
    { aAddInAttrs,  OLDRES_ADD_BEGIN    },
    { aFrmInAttrs,  OLDRES_FRMATR_BEGIN },
    { aGrfInAttrs,  OLDRES_GRFATR_BEGIN }

};

static USHORT __READONLY_DATA nAttrSizes[] =
{
    OLDRES_CHRATR_END + 1 - OLDRES_CHRATR_BEGIN,
    OLDFONT_TXTATR_END - OLDFONT_TXTATR_BEGIN,
    OLDETC_TXTATR_END - OLDETC_TXTATR_BEGIN,
    OLDRES_PARATR_END - OLDRES_PARATR_BEGIN,
    OLDRES_ADD_END - OLDRES_ADD_BEGIN,
    OLDRES_FRMATR_END - OLDRES_FRMATR_BEGIN,
    OLDRES_GRFATR_END - OLDRES_GRFATR_BEGIN
};

// Einlesen eines Format-Hints in ein Format
// Der Returnwert ist das Which-ID des eingelesenen Hints oder 0

USHORT SwSwgReader::InHint( SfxItemSet& rSet )
{
    USHORT nId = r.cur();
    long nextrec = r.getskip();
    SwHintFn pFn = NULL;

    for( short i = 6; i >= 0; i-- )
    {
        USHORT id1 = aHdr.cAttrTab[ i ];
        if( nId >= id1 )
        {
            nId -= id1;
            // Ausserhalb des Bereiches?
            if( nId >= aHdr.cAttrSiz[ i ] ) {
                Error(); return 0;
            }
            // Interpretierbar?
            if( nId < nAttrSizes[ i ] )
                pFn = aHintFns[ i ].pHintTab[ nId ];
            break;
        }
    }
    USHORT nWhich = 0;
    if( pFn )
        nWhich =  (*pFn) ( *this, &rSet, NULL, 0, 0 );
    // Vorsicht! Der Fussnoten-Hint ist erst zum Teil geparst!!
    if( nWhich != RES_TXTATR_FTN )
        r.skip( nextrec );
    return nWhich;
}

// Einen Text-Hint einlesen und anfuegen. Der Which-ID oder
// 0 wird returned.

USHORT SwSwgReader::InHint( SwTxtNode& rNd, xub_StrLen nBeg, xub_StrLen nEnd )
{
    USHORT nId = r.cur();
    long nextrec = r.getskip();
    SwHintFn pFn = NULL;

    for( short i = 6; i >= 0; i-- )
    {
        USHORT id1 = aHdr.cAttrTab[ i ];
        if( nId >= id1 )
        {
            nId -= id1;
            // Ausserhalb des Bereiches?
            if( nId >= aHdr.cAttrSiz[ i ] ) {
                Error(); return 0;
            }
            // Interpretierbar?
            if( nId < nAttrSizes[ i ] )
                pFn = aHintFns[ i ].pHintTab[ nId ];
            break;
        }
    }
    USHORT nWhich = 0;
    if( pFn )
        nWhich = (*pFn) ( *this, NULL, &rNd, nBeg, nEnd );
    // Vorsicht! Der Fussnoten-Hint ist erst zum Teil geparst!!
    if( nWhich != RES_TXTATR_FTN )
        r.skip( nextrec );
    return nWhich;
}


}
