CWS-TOOLING: integrate CWS hb11
diff --git a/sw/inc/pam.hxx b/sw/inc/pam.hxx
index 49b7dd9..09f2931 100644
--- a/sw/inc/pam.hxx
+++ b/sw/inc/pam.hxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: pam.hxx,v $
 * $Revision: 1.19 $
 * $Revision: 1.19.172.1 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -251,6 +251,8 @@ public:
    BOOL ContainsPosition(const SwPosition & rPos)
    { return *Start() <= rPos && rPos <= *End(); }

    static BOOL Overlap(const SwPaM & a, const SwPaM & b);

    DECL_FIXEDMEMPOOL_NEWDEL(SwPaM);

    String GetTxt() const;
diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx
index 332dab7..acf124b 100644
--- a/sw/source/core/crsr/pam.cxx
+++ b/sw/source/core/crsr/pam.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: pam.cxx,v $
 * $Revision: 1.23 $
 * $Revision: 1.23.12.1 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -1149,3 +1149,8 @@ String SwPaM::GetTxt() const

    return aResult;
}

BOOL SwPaM::Overlap(const SwPaM & a, const SwPaM & b)
{
    return !(*b.End() <= *a.Start() || *a.End() <= *b.End());
}
diff --git a/sw/source/core/doc/dbgoutsw.cxx b/sw/source/core/doc/dbgoutsw.cxx
index c5a8cf1..b768a79 100644
--- a/sw/source/core/doc/dbgoutsw.cxx
+++ b/sw/source/core/doc/dbgoutsw.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: dbgoutsw.cxx,v $
 * $Revision: 1.27 $
 * $Revision: 1.27.18.2 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -540,51 +540,54 @@ String lcl_dbg_out(const SwNode & rNode)
{
    String aTmpStr;

    aTmpStr += String("[ Idx: ", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String("<node ", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String("index =\"", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String::CreateFromInt32(rNode.GetIndex());
    aTmpStr += String("\"", RTL_TEXTENCODING_ASCII_US);

#ifndef PRODUCT
    aTmpStr += String("(", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String(" serial=\"", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String::CreateFromInt32(rNode.GetSerial());
    aTmpStr += String(")", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String("\"", RTL_TEXTENCODING_ASCII_US);
#endif

    aTmpStr += String(" ", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String(" pointer=\"", RTL_TEXTENCODING_ASCII_US);

    char aBuffer[128];
    sprintf(aBuffer, "%p", &rNode);
    aTmpStr += String(aBuffer, RTL_TEXTENCODING_ASCII_US);

    aTmpStr += String("\">", RTL_TEXTENCODING_ASCII_US);

    const SwTxtNode * pTxtNode = rNode.GetTxtNode();

    if (rNode.IsStartNode())
        aTmpStr += String(" Start", RTL_TEXTENCODING_ASCII_US);
    else if (rNode.IsEndNode())
        aTmpStr += String(" End", RTL_TEXTENCODING_ASCII_US);
    else if (rNode.IsTxtNode())
    if (rNode.IsTxtNode())
    {
        const SfxItemSet * pAttrSet = pTxtNode->GetpSwAttrSet();

        aTmpStr += String(" Txt ", RTL_TEXTENCODING_ASCII_US);
        aTmpStr += String("<txt>", RTL_TEXTENCODING_ASCII_US);
        aTmpStr += pTxtNode->GetTxt().Copy(0, 10);
        aTmpStr += String("</txt>", RTL_TEXTENCODING_ASCII_US);

        if (rNode.IsTableNode())
            aTmpStr += String(" Tbl", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<tbl/>", RTL_TEXTENCODING_ASCII_US);

        aTmpStr += String(" olvl:", RTL_TEXTENCODING_ASCII_US);
        aTmpStr += String("<outlinelevel>", RTL_TEXTENCODING_ASCII_US);
        aTmpStr += String::CreateFromInt32(pTxtNode->GetOutlineLevel());
        aTmpStr += String("</outlinelevel>", RTL_TEXTENCODING_ASCII_US);

        const SwNumRule * pNumRule = pTxtNode->GetNumRule();

        if (pNumRule != NULL)
        {
            aTmpStr += String(" Num: ", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<number>", RTL_TEXTENCODING_ASCII_US);
            if ( pTxtNode->GetNum() )
            {
                aTmpStr += lcl_dbg_out(*(pTxtNode->GetNum()));
            }
            aTmpStr += String("</number>", RTL_TEXTENCODING_ASCII_US);

            aTmpStr += String(" Rule: ", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<rule>", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += pNumRule->GetName();

            const SfxPoolItem * pItem = NULL;
@@ -600,26 +603,28 @@ String lcl_dbg_out(const SwNode & rNode)
            }

            const SwNumFmt * pNumFmt = NULL;
            aTmpStr += String("</rule>", RTL_TEXTENCODING_ASCII_US);

            if (pTxtNode->GetActualListLevel() > 0)
                pNumFmt = pNumRule->GetNumFmt( static_cast< USHORT >(pTxtNode->GetActualListLevel()) );

            if (pNumFmt)
            {
                aTmpStr += String(" NumFmt: ", RTL_TEXTENCODING_ASCII_US);
                aTmpStr += String("<numformat>", RTL_TEXTENCODING_ASCII_US);
                aTmpStr +=
                    lcl_dbg_out_NumType(pNumFmt->GetNumberingType());
                aTmpStr += String("</numformat>", RTL_TEXTENCODING_ASCII_US);
            }
        }

        if (pTxtNode->IsCountedInList())
            aTmpStr += String(" counted", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<counted/>", RTL_TEXTENCODING_ASCII_US);

        SwFmtColl * pColl = pTxtNode->GetFmtColl();

        if (pColl)
        {
            aTmpStr += String(" Coll: ", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<coll>", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += pColl->GetName();

            aTmpStr += String("(", RTL_TEXTENCODING_ASCII_US);
@@ -637,27 +642,35 @@ String lcl_dbg_out(const SwNode & rNode)
                aTmpStr += sNumruleName;
            }
            aTmpStr += String(")", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("</coll>", RTL_TEXTENCODING_ASCII_US);
        }

        SwFmtColl * pCColl = pTxtNode->GetCondFmtColl();

        if (pCColl)
        {
            aTmpStr += String(" CCOll: ", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<ccoll>", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += pCColl->GetName();
            aTmpStr += String("</ccoll>", RTL_TEXTENCODING_ASCII_US);
        }

        aTmpStr += String(", Frms: ", RTL_TEXTENCODING_ASCII_US);
        aTmpStr += String("<frms>", RTL_TEXTENCODING_ASCII_US);
        aTmpStr += lcl_AnchoredFrames(rNode);
        aTmpStr += String("</frms>", RTL_TEXTENCODING_ASCII_US);

        if (bDbgOutPrintAttrSet)
        {
            aTmpStr += String(" Attrs: ", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += String("<attrs>", RTL_TEXTENCODING_ASCII_US);
            aTmpStr += lcl_dbg_out(pTxtNode->GetSwAttrSet());
            aTmpStr += String("</attrs>", RTL_TEXTENCODING_ASCII_US);
        }
    }
    else if (rNode.IsStartNode())
        aTmpStr += String("<start/>", RTL_TEXTENCODING_ASCII_US);
    else if (rNode.IsEndNode())
        aTmpStr += String("<end/>", RTL_TEXTENCODING_ASCII_US);

    aTmpStr += String(" ]", RTL_TEXTENCODING_ASCII_US);
    aTmpStr += String("</node>", RTL_TEXTENCODING_ASCII_US);

    return aTmpStr;
}
@@ -705,15 +718,23 @@ BOOL lcl_dbg_add_node(const SwNodePtr & pNode, void * pArgs)

String lcl_dbg_out(SwNodes & rNodes)
{
    String aStr("[\n", RTL_TEXTENCODING_ASCII_US);
    String aStr("<nodes>", RTL_TEXTENCODING_ASCII_US);

    for (ULONG i = 0; i < rNodes.Count(); i++)
    {
        aStr += lcl_dbg_out(*rNodes[i]);
        SwNode * pNode = rNodes[i];

        if (pNode->IsEndNode())
            aStr += String("</nodes>\n", RTL_TEXTENCODING_ASCII_US);

        aStr += lcl_dbg_out(*pNode);
        aStr += String("\n", RTL_TEXTENCODING_ASCII_US);

        if (pNode->IsStartNode())
            aStr += String("<nodes>", RTL_TEXTENCODING_ASCII_US);
    }

    aStr += String("]\n", RTL_TEXTENCODING_ASCII_US);
    aStr += String("</nodes>\n", RTL_TEXTENCODING_ASCII_US);

    return aStr;
}
diff --git a/sw/source/filter/ww8/makefile.mk b/sw/source/filter/ww8/makefile.mk
index f502d40..7f59944 100644
--- a/sw/source/filter/ww8/makefile.mk
+++ b/sw/source/filter/ww8/makefile.mk
@@ -8,7 +8,7 @@
#
# $RCSfile: makefile.mk,v $
#
# $Revision: 1.23 $
# $Revision: 1.22.172.2 $
#
# This file is part of OpenOffice.org.
#
@@ -67,6 +67,7 @@ EXCEPTIONSFILES = \
        $(SLO)$/writerhelper.obj \
        $(SLO)$/writerwordglue.obj \
        $(SLO)$/ww8scan.obj \
        $(SLO)$/WW8TableInfo.obj \
        $(SLO)$/WW8FFData.obj


@@ -93,6 +94,7 @@ SLOFILES =	\
        $(SLO)$/ww8scan.obj \
        $(SLO)$/writerhelper.obj \
        $(SLO)$/writerwordglue.obj \
        $(SLO)$/WW8TableInfo.obj \
        $(SLO)$/WW8FFData.obj


diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index 1529d1c..b73935b 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: wrtw8esh.cxx,v $
 * $Revision: 1.105 $
 * $Revision: 1.105.10.1 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -223,23 +223,23 @@ void SwWW8Writer::DoComboBox(const rtl::OUString &rName,
    OutField(0, ww::eFORMDROPDOWN, FieldString(ww::eFORMDROPDOWN),
             WRITEFIELD_CLOSE);

    ::sw::WW8FFData * pFFData = new ::sw::WW8FFData();
    ::sw::WW8FFData aFFData;

    pFFData->setType(2);
    pFFData->setName(rName);
    pFFData->setHelp(rHelp);
    pFFData->setStatus(rToolTip);
    aFFData.setType(2);
    aFFData.setName(rName);
    aFFData.setHelp(rHelp);
    aFFData.setStatus(rToolTip);

    sal_uInt32 nListItems = rListItems.getLength();

    for (sal_uInt32 i = 0; i < nListItems; i++)
    {
        if (i < 0x20 && rSelected == rListItems[i])
            pFFData->setResult(::sal::static_int_cast<sal_uInt8>(i));
        pFFData->addListboxEntry(rListItems[i]);
            aFFData.setResult(::sal::static_int_cast<sal_uInt8>(i));
        aFFData.addListboxEntry(rListItems[i]);
    }

    pFFData->Write(pDataStrm);
    aFFData.Write(pDataStrm);

}

@@ -268,10 +268,10 @@ void SwWW8Writer::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet)
    pChpPlc->AppendFkpEntry(Strm().Tell(),
                sizeof( aArr1 ), aArr1 );

    ::sw::WW8FFData * pFFData = new ::sw::WW8FFData();
    ::sw::WW8FFData aFFData;

    pFFData->setType(1);
    pFFData->setCheckboxHeight(0x14);
    aFFData.setType(1);
    aFFData.setCheckboxHeight(0x14);

    sal_Int16 nTemp = 0;
    xPropSet->getPropertyValue(C2U("DefaultState")) >>= nTemp;
@@ -285,10 +285,10 @@ void SwWW8Writer::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet)
        switch (nIsChecked)
        {
            case false:
                pFFData->setResult(0);
                aFFData.setResult(0);
                break;
            case true:
                pFFData->setResult(1);
                aFFData.setResult(1);
                break;
            default:
                ASSERT(!this, "how did that happen");
@@ -300,23 +300,23 @@ void SwWW8Writer::DoCheckBox(uno::Reference<beans::XPropertySet> xPropSet)
    if (xPropSetInfo->hasPropertyByName(sName))
    {
        xPropSet->getPropertyValue(sName) >>= aStr;
        pFFData->setName(aStr);
        aFFData.setName(aStr);
    }

    static ::rtl::OUString sHelpText(C2U("HelpText"));
    if (xPropSetInfo->hasPropertyByName(sHelpText))
    {
        xPropSet->getPropertyValue(sHelpText) >>= aStr;
        pFFData->setHelp(aStr);
        aFFData.setHelp(aStr);
    }
    static ::rtl::OUString sHelpF1Text(C2U("HelpF1Text"));
    if (xPropSetInfo->hasPropertyByName(sHelpF1Text))
    {
        xPropSet->getPropertyValue(sHelpF1Text) >>= aStr;
        pFFData->setStatus(aStr);
        aFFData.setStatus(aStr);
    }

    pFFData->Write(pDataStrm);
    aFFData.Write(pDataStrm);

    OutField(0, ww::eFORMCHECKBOX, aEmptyStr, WRITEFIELD_CLOSE);
}
@@ -343,13 +343,13 @@ void SwWW8Writer::DoFormText(const SwInputField * pFld)
    pChpPlc->AppendFkpEntry(Strm().Tell(),
                sizeof( aArr1 ), aArr1 );

    ::sw::WW8FFData * pFFData = new ::sw::WW8FFData();
    ::sw::WW8FFData aFFData;

    pFFData->setType(0);
    pFFData->setName(pFld->GetPar2());
    pFFData->setHelp(pFld->GetHelp());
    pFFData->setStatus(pFld->GetToolTip());
    pFFData->Write(pDataStrm);
    aFFData.setType(0);
    aFFData.setName(pFld->GetPar2());
    aFFData.setHelp(pFld->GetHelp());
    aFFData.setStatus(pFld->GetToolTip());
    aFFData.Write(pDataStrm);

    OutField(0, ww::eFORMTEXT, aEmptyStr, WRITEFIELD_CMD_END);

diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 494c702..7024c96 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: wrtw8nds.cxx,v $
 * $Revision: 1.110 $
 * $Revision: 1.109.40.8 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -38,6 +38,7 @@
#include <utility>
#include <algorithm>
#include <functional>
#include <iostream>
#include <hintids.hxx>
#include <tools/urlobj.hxx>
#include <svx/boxitem.hxx>
@@ -941,7 +942,21 @@ void WW8_AttrIter::StartURL(const String &rUrl, const String &rTarget)
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        };

        sURL = aURL.PathToFileName();
        // save the links to files as relative
        sURL = URIHelper::simpleNormalizedMakeRelative( rWrt.GetBaseURL(), sURL );
        if ( sURL.EqualsAscii( "/", 0, 1 ) )
            sURL = aURL.PathToFileName();

        // special case for the absolute windows names
        // (convert '/c:/foo/bar.doc' into 'c:\foo\bar.doc')
        sal_Unicode aDrive = ( sURL.Len() > 1 )? sURL.GetChar( 1 ): 0;
        if ( sURL.EqualsAscii( "/", 0, 1 ) &&
             ( ( aDrive >= 'A' && aDrive <= 'Z' ) || ( aDrive >= 'a' && aDrive <= 'z' ) ) &&
             sURL.EqualsAscii( ":", 2, 1 ) )
        {
            sURL.Erase( 0, 1 );
            sURL.SearchAndReplaceAll( '/', '\\' );
        }

        rWrt.pDataStrm->Write( MAGIC_C, sizeof(MAGIC_C) );
        SwWW8Writer::WriteLong( *rWrt.pDataStrm, sURL.Len()+1 );
@@ -1437,6 +1452,10 @@ SwTxtFmtColl& lcl_getFormatCollection( Writer& rWrt, SwTxtNode* pTxtNode )

Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
{
#ifdef DEBUG
    ::std::clog << "<OutWW8_SwTxtNode>" << ::std::endl;
#endif

    SwWW8Writer& rWW8Wrt = (SwWW8Writer&)rWrt;
    SwTxtNode* pNd = &((SwTxtNode&)rNode);

@@ -1494,6 +1513,9 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )

    String aStr( pNd->GetTxt() );

    ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo =
    rWW8Wrt.mpTableInfo->getTableNodeInfo(pNd);

    xub_StrLen nAktPos = 0;
    xub_StrLen nEnd = aStr.Len();
    bool bUnicode = rWW8Wrt.bWrtWW8, bRedlineAtEnd = false;
@@ -1625,9 +1647,18 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
                }
            }

            rWW8Wrt.WriteCR();
            rWW8Wrt.WriteCR(pTextNodeInfo);

            rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(),
            if (pTextNodeInfo.get() != NULL)
            {
#ifdef DEBUG
                ::std::clog << pTextNodeInfo->toString() << ::std::endl;
#endif

                rWW8Wrt.OutWW8TableInfoCell(pTextNodeInfo);
            }

             rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(),
                pO->GetData() );
            pO->Remove( 0, pO->Count() );

@@ -1691,7 +1722,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
                        rWW8Wrt.pop_charpropstart();
                        rWW8Wrt.EndTOX(*pTOXSect);
                    }
                    rWW8Wrt.WriteCR();              // CR danach
                    rWW8Wrt.WriteCR(pTextNodeInfo);              // CR danach
                }
            }
        }
@@ -1734,7 +1765,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
                    rWW8Wrt.EndTOX( *pTOXSect );
                }

                rWW8Wrt.WriteCR();              // CR danach
                rWW8Wrt.WriteCR(pTextNodeInfo);              // CR danach

                if( bRedlineAtEnd )
                {
@@ -1761,14 +1792,13 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
    if (rWW8Wrt.mpParentFrame && !rWW8Wrt.bIsInTable)    // Fly-Attrs
        rWW8Wrt.Out_SwFmt(rWW8Wrt.mpParentFrame->GetFrmFmt(), false, false, true);

    if( rWW8Wrt.bOutTable )
    {                                               // Tab-Attr
        // sprmPFInTable
        if( rWW8Wrt.bWrtWW8 )
            SwWW8Writer::InsUInt16( *pO, 0x2416 );
        else
            pO->Insert( 24, pO->Count() );
        pO->Insert( 1, pO->Count() );
    if (pTextNodeInfo.get() != NULL)
    {
#ifdef DEBUG
        ::std::clog << pTextNodeInfo->toString() << ::std::endl;
#endif

        rWW8Wrt.OutWW8TableInfoCell(pTextNodeInfo);
    }

    if( !bFlyInTable )
@@ -2049,8 +2079,27 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
    }

    rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(),
        pO->GetData() );
                                    pO->GetData() );
    pO->Remove( 0, pO->Count() );                       // leeren

    if (pTextNodeInfo.get() != NULL)
    {
        if (pTextNodeInfo->isEndOfLine())
        {
            rWW8Wrt.WriteRowEnd(pTextNodeInfo->getDepth());

            pO->Insert( (BYTE*)&nSty, 2, pO->Count() );     // Style #
            rWW8Wrt.OutWW8TableInfoRow(pTextNodeInfo);
            rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(), pO->Count(),
                                            pO->GetData() );
            pO->Remove( 0, pO->Count() );                       // leeren
        }
    }

#ifdef DEBUG
    ::std::clog << "</OutWW8_SwTxtNode>" << ::std::endl;
#endif

    return rWrt;
}

@@ -2178,523 +2227,6 @@ bool RowContainsProblematicGraphic(const SwWriteTableCellPtr *pRow,
//       Tabellen
//---------------------------------------------------------------------------

Writer& OutWW8_SwTblNode( Writer& rWrt, SwTableNode & rNode )
{
    SwWW8Writer & rWW8Wrt = (SwWW8Writer&)rWrt;
    SwTable& rTbl = rNode.GetTable();
    const bool bNewTableModel = rTbl.IsNewModel();

    const SwFrmFmt *pFmt = rTbl.GetFrmFmt();
    ASSERT(pFmt,"Impossible");
    if (!pFmt)
        return rWrt;
    rWW8Wrt.Out_SfxBreakItems(&(pFmt->GetAttrSet()), rNode);

    /*
    ALWAYS relative when text::HoriOrientation::NONE (nPageSize + ( nPageSize / 10 )) < nTblSz,
    in that case the cell width's and table width's are not real. The table
    width is maxed and cells relative, so we need the frame (generally page)
    width that the table is in to work out the true widths.
    */
    const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
    int nWidthPercent = rSize.GetWidthPercent();
    bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE;
    if ( (pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::FULL) || bManualAligned )
        nWidthPercent = 100;
    bool bRelBoxSize = nWidthPercent != 0;
    unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
    if (nTblSz > USHRT_MAX/2 && !bRelBoxSize)
    {
        ASSERT(bRelBoxSize, "huge table width but not relative, suspicious");
        bRelBoxSize = true;
    }

    unsigned long nPageSize = nTblSz;
    if (bRelBoxSize)
    {
        Point aPt;
        SwRect aRect(pFmt->FindLayoutRect(false, &aPt));
        if (aRect.IsEmpty())
        {
            // dann besorge mal die Seitenbreite ohne Raender !!
            const SwFrmFmt* pParentFmt =
                rWW8Wrt.mpParentFrame ?
                &(rWW8Wrt.mpParentFrame->GetFrmFmt()) :
                const_cast<const SwDoc *>(rWrt.pDoc)->GetPageDesc(0).GetPageFmtOfNode(rNode, false);
            aRect = pParentFmt->FindLayoutRect(true);
            if (0 == (nPageSize = aRect.Width()))
            {
                const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace();
                nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft()
                    - rLR.GetRight();
            }
        }
        else
        {
            nPageSize = aRect.Width();
            if(bManualAligned)
            {
                // #i37571# For manually aligned tables
                const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
                nPageSize -= (rLR.GetLeft() + rLR.GetRight());
            }

        }

        ASSERT(nWidthPercent, "Impossible");
        if (nWidthPercent)
        {
            nPageSize *= nWidthPercent;
            nPageSize /= 100;
        }
    }

    WW8Bytes aAt( 128, 128 );   // Attribute fuer's Tabellen-Zeilenende
    SwTwips nTblOffset = 0;
    USHORT nStdAtLen = rWW8Wrt.StartTableFromFrmFmt(aAt, pFmt, nTblOffset);
    static const BYTE aNullBytes[] = { 0, 0, 0, 0 };

    SwWriteTable* pTableWrt;
    const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
    if( pLayout && pLayout->IsExportable() )
        pTableWrt = new SwWriteTable( pLayout );
    else
    {
        pTableWrt = new SwWriteTable( rTbl.GetTabLines(), nPageSize,
            (USHORT)nTblSz, false);
    }

    const SwFrmFmt *pDefaultFmt = 0;
    // WW6 / 8 can not have more then 31 / 63 cells
    const BYTE nMaxCols = rWW8Wrt.bWrtWW8 ? 63 : 31;
    // rCols are the array of all cols of the table
    const SwWriteTableCols& rCols = pTableWrt->GetCols();
    USHORT nColCnt = rCols.Count();
    SwWriteTableCellPtr* pBoxArr = new SwWriteTableCellPtr[ nColCnt ];
    USHORT* pRowSpans = new USHORT[ nColCnt ];
    memset( pBoxArr, 0, sizeof( pBoxArr[0] ) * nColCnt );
    memset( pRowSpans, 0, sizeof( pRowSpans[0] ) * nColCnt );
    const SwWriteTableRows& rRows = pTableWrt->GetRows();
    for( USHORT nLine = 0; nLine < rRows.Count(); ++nLine )
    {
        USHORT nBox, nRealBox;

        const SwWriteTableRow *pRow = rRows[ nLine ];
        const SwWriteTableCells& rCells = pRow->GetCells();

        bool bFixRowHeight = false;
        USHORT nRealColCnt = 0;
        USHORT nTotal = rCells.Count();
        ASSERT(nTotal <= rCols.Count(),
            "oh oh!,row has more cells than table is wide!");
        if (nTotal > rCols.Count())
            nTotal = rCols.Count();
        for( nColCnt = 0, nBox = 0; nBox < nTotal; ++nColCnt )
        {
            ASSERT( nColCnt < rCols.Count(), "Leaving table" );

            SwWriteTableCell* pCell = rCells[nBox];
            const bool bProcessCoveredCell = bNewTableModel && 0 == pCell->GetRowSpan();

            if( !pRowSpans[ nColCnt ] || bProcessCoveredCell )
            {
                // set new BoxPtr
                nBox++;
                pBoxArr[ nColCnt ] = pCell;
                if ( !bProcessCoveredCell )
                    pRowSpans[ nColCnt ] = pCell->GetRowSpan();
                for( USHORT nCellSpan = pCell->GetColSpan(), nCS = 1;
                        nCS < nCellSpan; ++nCS, ++nColCnt )
                {
                    ASSERT( nColCnt+1 < rCols.Count(), "More colspan than columns" );
                    if( nColCnt+1 < rCols.Count() ) // robust against wrong colspans
                    {
                        pBoxArr[ nColCnt+1 ] = pBoxArr[ nColCnt ];
                        pRowSpans[ nColCnt+1 ] = pRowSpans[ nColCnt ];
                    }
                }
                ++nRealColCnt;
            }
            else if( !nColCnt || pBoxArr[ nColCnt-1 ] != pBoxArr[ nColCnt ] )
                ++nRealColCnt;

            if( 1 != pRowSpans[ nColCnt ] && !bNewTableModel )
                bFixRowHeight = true;
        }

        for( ; nColCnt < rCols.Count() && pRowSpans[ nColCnt ]; ++nColCnt )
        {
            if( !nColCnt || pBoxArr[ nColCnt-1 ] != pBoxArr[ nColCnt ] )
                ++nRealColCnt;
            bFixRowHeight = true;
        }
        nColCnt = rCols.Count(); // A wrong cellspan-value could cause a nColCnt > rCols.Count()

        if (!bFixRowHeight)
        {
            bFixRowHeight = RowContainsProblematicGraphic(pBoxArr, nColCnt,
                rWW8Wrt);
        }

        //Winword column export limited to 31/63 cells
        sal_uInt8 nWWColMax = nRealColCnt > nMaxCols ?
            nMaxCols : msword_cast<sal_uInt8>(nRealColCnt);

        // Check if this is a repeated row - sprmTTableHeader
        if( rTbl.GetRowsToRepeat() > nLine)
        {
            if( rWW8Wrt.bWrtWW8 )
                SwWW8Writer::InsUInt16( aAt, 0x3404 );
            else
                aAt.Insert( 186, aAt.Count() );
            aAt.Insert( 1, aAt.Count() );
        }

        const SwTableLine* pLine = pBoxArr[0]->GetBox()->GetUpper();
        const SwFrmFmt *pLineFmt = pLine ? pLine->GetFrmFmt() : 0;

        // Zeilenhoehe ausgeben   sprmTDyaRowHeight
        long nHeight = 0;
        if( bFixRowHeight )
        {
            nHeight = -pRow->GetPos();      //neg. => abs. height!
            if( nLine )
                nHeight += rRows[ nLine - 1 ]->GetPos();
        }
        else
        {
            const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
            if( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
                nHeight = ATT_MIN_SIZE == rLSz.GetHeightSizeType()
                                                ? rLSz.GetHeight()
                                                : -rLSz.GetHeight();
        }
        if (nHeight)
        {
            if( rWW8Wrt.bWrtWW8 )
                SwWW8Writer::InsUInt16( aAt, 0x9407 );
            else
                aAt.Insert( 189, aAt.Count() );
            SwWW8Writer::InsUInt16( aAt, (USHORT)nHeight );
        }

        /*
        By default the row can be split in word, and now in writer we have a
        feature equivalent to this, Word stores 1 for fCantSplit if the row
        cannot be split, we set true if we can split it. An example is #i4569#
        */
        const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
        BYTE nCantSplit = (!rSplittable.GetValue()) ? 1 : 0;
        if (rWW8Wrt.bWrtWW8)
        {
            SwWW8Writer::InsUInt16(aAt, 0x3403);
            aAt.Insert(nCantSplit, aAt.Count());
            SwWW8Writer::InsUInt16(aAt, 0x3466); // also write fCantSplit90
        }
        else
        {
            aAt.Insert(185, aAt.Count());
        }
        aAt.Insert(nCantSplit, aAt.Count());


        if (rWW8Wrt.bWrtWW8)
        {
            if (rWW8Wrt.TrueFrameDirection(*pFmt) == FRMDIR_HORI_RIGHT_TOP)
            {
                SwWW8Writer::InsUInt16(aAt, 0x560B);
                SwWW8Writer::InsUInt16(aAt, 1);
            }
        }

        // Inhalt der Boxen ausgeben
        for( nBox = 0, nRealBox = 0; nBox < nColCnt; ++nBox )
        {
            if( nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ] )
                continue;

            if (pBoxArr[nBox] && pBoxArr[nBox]->GetRowSpan() == pRowSpans[nBox])
            {
                // new Box
                const SwStartNode* pSttNd = pBoxArr[nBox]->GetBox()->GetSttNd();
                WW8SaveData aSaveData( rWW8Wrt, pSttNd->GetIndex()+1,
                                        pSttNd->EndOfSectionIndex() );
                rWW8Wrt.bOutTable = true;
                rWW8Wrt.bIsInTable= true;
                rWW8Wrt.WriteText();
            }
            else
            {
                rWW8Wrt.bOutTable = true;
                rWW8Wrt.WriteStringAsPara( aEmptyStr );
                rWW8Wrt.bOutTable = false;
            }

            if( nWWColMax < nRealColCnt )
            {
                if( nRealBox+1 < nWWColMax || nRealBox+1 == nRealColCnt )
                    rWW8Wrt.WriteCellEnd(); // SpaltenEnde
            }
            else if( nRealBox < nWWColMax )
                    rWW8Wrt.WriteCellEnd(); // SpaltenEnde
            ++nRealBox;
        }

        // das wars mit der Line
        rWW8Wrt.WriteRowEnd();  // TabellenZeilen-Ende

        if( rWW8Wrt.bWrtWW8 )
        {
            // SprmTDefTable
            // 0+1 - OpCode, 2+3 - Laenge = Cells * (sizeof TC + uint16)
            // 4 - Cells (max 32!)
            SwWW8Writer::InsUInt16( aAt, 0xD608 );
            SwWW8Writer::InsUInt16( aAt, 2 + ( nWWColMax + 1 ) * 2 +
                                                ( nWWColMax * 20 ));
            aAt.Insert( nWWColMax, aAt.Count() );               //
        }
        else
        {
            // SprmTDefTable
            // 0 - OpCode, 1,2 - Laenge = Cells * (sizeof TC + uint16)
            // 3 - Cells (max 32!)
            aAt.Insert( 190, aAt.Count() );
            SwWW8Writer::InsUInt16( aAt, nWWColMax * 12 + 4 );  // Sprm-Laenge
            aAt.Insert( nWWColMax, aAt.Count() );               //
        }

        SwTwips nSz = 0, nCalc;
        SwWW8Writer::InsUInt16( aAt, (USHORT)nTblOffset );

        for (nBox = 0, nRealBox = 0; nRealBox < nWWColMax; ++nBox)
        {
            if( (nBox > 0 && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ])
                || pBoxArr[nBox] == NULL)
                continue;

            const SwFrmFmt* pBoxFmt = pBoxArr[ nBox ]->GetBox()->GetFrmFmt();
            const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize();
            nSz += rLSz.GetWidth();
            nCalc = nSz;
            if( bRelBoxSize )
            {
                nCalc *= nPageSize;
                nCalc /= nTblSz;
            }
            SwWW8Writer::InsUInt16( aAt, (USHORT)(nTblOffset + nCalc ));
            ++nRealBox;
        }

        for (nBox = 0, nRealBox = 0; nRealBox < nWWColMax; ++nBox)
        {
            if( nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ] )
                continue;
            // rgf, erstmal alles 0 - WW8: 4, sonst 2 Byte
            // write vertikal alignment
            const SwFrmFmt& rFmt = *pBoxArr[ nBox ]->GetBox()->GetFrmFmt();
            if( rWW8Wrt.bWrtWW8 )
            {
                USHORT nFlags = pBoxArr[ nBox ]->GetRowSpan();
                if( 1 < nFlags || ( bNewTableModel && 0 == nFlags ) )
                {
                    if( nFlags == pRowSpans[ nBox ] )
                        nFlags = 0x60;      // start a new vert. merge
                    else
                        nFlags = 0x20;      // continue a vert. merge
                }
                else
                    nFlags = 0;             // no vert. merge

                switch (rFmt.GetVertOrient().GetVertOrient())
                {
                    case text::VertOrientation::CENTER:
                        nFlags |= 0x080;
                        break;
                    case text::VertOrientation::BOTTOM:
                        nFlags |= 0x100;
                        break;
                    default:
                        break;
                }
                SwWW8Writer::InsUInt16( aAt, nFlags );
            }
            ++nRealBox;
            aAt.Insert( aNullBytes, 2, aAt.Count() );   // dummy
            rWW8Wrt.Out_SwFmtTableBox( aAt, rFmt.GetBox() ); // 8/16 Byte
        }

        //Cell widths and heights
        if (rWW8Wrt.bWrtWW8)
        {
            if (!pDefaultFmt && nWWColMax)
                pDefaultFmt = pBoxArr[ 0 ]->GetBox()->GetFrmFmt();

            static USHORT __READONLY_DATA aBorders[] =
            {
                BOX_LINE_TOP, BOX_LINE_LEFT,
                BOX_LINE_BOTTOM, BOX_LINE_RIGHT
            };
            const USHORT* pBrd = aBorders;

            //Export non default border spacing
            for( nBox = 0, nRealBox = 0; nRealBox < nWWColMax; ++nBox)
            {
                if( nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ] )
                    continue;
                const SwFrmFmt& rFmt = *pBoxArr[ nBox ]->GetBox()->GetFrmFmt();

                pBrd = aBorders;
                for( int i = 0; i < 4; ++i, ++pBrd)
                {
                    USHORT nDist = rFmt.GetBox().GetDistance(*pBrd);
                    if (pDefaultFmt->GetBox().GetDistance(*pBrd) != nDist)
                    {
                        SwWW8Writer::InsUInt16(aAt, 0xD632);
                        aAt.Insert( BYTE(6), aAt.Count() );
                        aAt.Insert( BYTE(nRealBox), aAt.Count() );
                        aAt.Insert( BYTE(3), aAt.Count() );
                        aAt.Insert( BYTE(1 << i), aAt.Count() );
                        aAt.Insert( BYTE(3), aAt.Count() );
                        SwWW8Writer::InsUInt16(aAt, nDist);
                    }
                }
                ++nRealBox;
            }

            //Export any vertical direction cells
            for (nBox = 0, nRealBox = 0; nRealBox < nWWColMax; ++nBox)
            {
                if( nBox && pBoxArr[nBox-1] == pBoxArr[nBox])
                    continue;
                const SwFrmFmt& rFmt = *pBoxArr[ nBox ]->GetBox()->GetFrmFmt();
                //a bit lazy, could calculate range of cells with equal
                //direction to optimize size of exported document
                if (FRMDIR_VERT_TOP_RIGHT == rWW8Wrt.TrueFrameDirection(rFmt))
                {
                    SwWW8Writer::InsUInt16(aAt, 0x7629);
                    aAt.Insert(BYTE(nBox), aAt.Count());        //start range
                    aAt.Insert(BYTE(nBox + 1), aAt.Count());    //end range
                    SwWW8Writer::InsUInt16(aAt, 5); //Equals vertical writing
                }
                ++nRealBox;
            }

            //Set Default, just taken from the first cell of the first
            //row
            pBrd = aBorders;
            for( int i = 0; i < 4; ++i, ++pBrd)
            {
                SwWW8Writer::InsUInt16(aAt, 0xD634);
                aAt.Insert( BYTE(6), aAt.Count() );
                aAt.Insert( BYTE(0), aAt.Count() );
                aAt.Insert( BYTE(1), aAt.Count() );
                aAt.Insert( BYTE(1 << i), aAt.Count() );
                aAt.Insert( BYTE(3), aAt.Count() );

                SwWW8Writer::InsUInt16(aAt,
                    pDefaultFmt->GetBox().GetDistance(*pBrd));
            }
        }

        // Background
        USHORT nBackg;
        if( pRow->GetBackground() )
            // over all boxes!
            nBackg = nWWColMax;
        else
        {
            nBackg = 0;
            for( nBox = 0, nRealBox = 0; nRealBox < nWWColMax; ++nBox )
            {
                if( nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ] )
                    continue;

                SwWriteTableCell* pCell = pBoxArr[ nBox ];
                if( pCell->GetBackground() ||
                    SFX_ITEM_ON == pCell->GetBox()->GetFrmFmt()->
                    GetItemState( RES_BACKGROUND, false) )
                    nBackg = nRealBox + 1;
                ++nRealBox;
            }
        }

        if( nBackg )
        {
            // TableShade, 0(+1) - OpCode, 1(2) - Count * sizeof( SHD ),
            // 2..(3..) - SHD
            if( rWW8Wrt.bWrtWW8 )
                SwWW8Writer::InsUInt16( aAt, 0xD609 );
            else
                aAt.Insert( (BYTE)191, aAt.Count() );
            aAt.Insert( (BYTE)(nBackg * 2), aAt.Count() );  // Len

            Color *pColors = new Color[nBackg];

            const SfxPoolItem* pI;
            for( nBox = 0, nRealBox = 0; nRealBox < nBackg; ++nBox )
            {
                if( nBox && pBoxArr[ nBox-1 ] == pBoxArr[ nBox ] )
                    continue;

                SwWriteTableCell* pCell = pBoxArr[ nBox ];
                if( SFX_ITEM_ON == pCell->GetBox()->GetFrmFmt()->
                    GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI )
                    || 0 != ( pI = pCell->GetBackground() )
                    || 0 != ( pI = pRow->GetBackground() ) )
                {
                    pColors[nRealBox] = ((const SvxBrushItem*)pI)->GetColor();
                }
                else
                    pColors[nRealBox] = COL_AUTO;
                ++nRealBox;
            }

            for(USHORT nI = 0; nI < nBackg; ++nI)
            {
                WW8_SHD aShd;
                rWW8Wrt.TransBrush(pColors[nI], aShd);
                SwWW8Writer::InsUInt16(aAt, aShd.GetValue());
            }

            if( rWW8Wrt.bWrtWW8 )
            {
                SwWW8Writer::InsUInt16( aAt, 0xD612 );
                aAt.Insert( (BYTE)(nBackg * 10), aAt.Count() ); // Len
                for(USHORT nI = 0; nI < nBackg; ++nI)
                {
                    SwWW8Writer::InsUInt32(aAt, 0xFF000000);
                    sal_uInt32 nBgColor = pColors[nI].GetColor();
                    if (nBgColor == COL_AUTO)
                        nBgColor = 0xFF000000;
                    else
                        nBgColor = wwUtility::RGBToBGR(nBgColor);
                    SwWW8Writer::InsUInt32(aAt, nBgColor);
                    SwWW8Writer::InsUInt16(aAt, 0x0000);
                }
            }

            delete[] pColors;
        }

        rWW8Wrt.pPapPlc->AppendFkpEntry( rWrt.Strm().Tell(),
                                   aAt.Count(), aAt.GetData() );
        if( aAt.Count() > nStdAtLen )
            aAt.Remove( nStdAtLen, aAt.Count() - nStdAtLen );

        for( nBox = 0; nBox < nColCnt; ++nBox )
            --pRowSpans[ nBox ];
    }

    delete pTableWrt;
    delete[] pBoxArr;
    delete[] pRowSpans;

    // Pam hinter die Tabelle verschieben
    rWW8Wrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();

    return rWrt;
}

bool SwWW8Writer::NoPageBreakSection(const SfxItemSet* pSet)
{
    bool bRet = false;
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 76838c6..96ec05a 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: wrtww8.cxx,v $
 * $Revision: 1.93 $
 * $Revision: 1.91.98.8 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -31,6 +31,9 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */

#include <iostream>

#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <unotools/ucbstreamhelper.hxx>
@@ -61,11 +64,16 @@
#include <svx/langitem.hxx>
#include <svx/msoleexp.hxx>
#include <svx/msocximex.hxx>
#include <svx/lrspitem.hxx>
#include <svx/boxitem.hxx>
#include <svx/brshitem.hxx>
#include <swtypes.hxx>
#include <swrect.hxx>
#include <txatbase.hxx>
#include <fmtcntnt.hxx>
#include <fmtpdsc.hxx>
#include <fmtrowsplt.hxx>
#include <frmatr.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <pam.hxx>
@@ -95,6 +103,7 @@
#include <statstr.hrc>          // ResId fuer Statusleiste
#endif
#include <fmtline.hxx>
#include <fmtfsize.hxx>
#include <comphelper/extract.hxx>
#include "writerhelper.hxx"
#include "writerwordglue.hxx"
@@ -106,6 +115,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>

#include "dbgoutsw.hxx"

using namespace sw::util;
using namespace sw::types;
@@ -676,8 +686,8 @@ bool WW8_WrMagicTable::Write(SwWW8Writer& rWrt)
        return false;
    ULONG nFcStart = rWrt.pTableStrm->Tell();
    WW8_WrPlc1::Write( *rWrt.pTableStrm );
    rWrt.pFib->fcMagicTable = nFcStart;
    rWrt.pFib->lcbMagicTable = rWrt.pTableStrm->Tell() - nFcStart;
    rWrt.pFib->fcPlcfTch = nFcStart;
    rWrt.pFib->lcbPlcfTch = rWrt.pTableStrm->Tell() - nFcStart;
    return true;
}

@@ -1655,6 +1665,10 @@ void SwWW8Writer::OutSwString(const String& rStr, xub_StrLen nStt,
    xub_StrLen nLen, bool bUnicode, rtl_TextEncoding eChrSet)

{
#ifdef DEBUG
    ::std::clog << "<OutSwString>" << ::std::endl;
#endif

    if( nLen )
    {
        if ( bUnicode != pPiece->IsUnicode() )
@@ -1663,21 +1677,41 @@ void SwWW8Writer::OutSwString(const String& rStr, xub_StrLen nStt,
        if( nStt || nLen != rStr.Len() )
        {
            String sOut( rStr.Copy( nStt, nLen ) );

#ifdef DEBUG
            ::std::clog << ::rtl::OUStringToOString(sOut, RTL_TEXTENCODING_ASCII_US).getStr() << ::std::endl;
#endif

            if (bUnicode)
                SwWW8Writer::WriteString16(Strm(), sOut, false);
            else
                SwWW8Writer::WriteString8(Strm(), sOut, false, eChrSet);
        }
        else if (bUnicode)
            SwWW8Writer::WriteString16(Strm(), rStr, false);
        else
            SwWW8Writer::WriteString8(Strm(), rStr, false, eChrSet);
        {
#ifdef DEBUG
            ::std::clog << ::rtl::OUStringToOString(rStr, RTL_TEXTENCODING_ASCII_US).getStr() << ::std::endl;
#endif

            if (bUnicode)
                SwWW8Writer::WriteString16(Strm(), rStr, false);
            else
                SwWW8Writer::WriteString8(Strm(), rStr, false, eChrSet);
        }
    }

#ifdef DEBUG
    ::std::clog << "</OutSwString>" << ::std::endl;
#endif
}

void SwWW8Writer::WriteCR()
void SwWW8Writer::WriteCR(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    WriteChar( '\015' );
    if (pTableTextNodeInfo.get() != NULL && pTableTextNodeInfo->getDepth() == 1 && pTableTextNodeInfo->isEndOfCell())
        WriteChar('\007');
    else
        WriteChar( '\015' );

    pPiece->SetParaBreak();
}

@@ -1759,9 +1793,498 @@ WW8SaveData::~WW8SaveData()
    rWrt.pFlyOffset = pOldFlyOffset;
}

void SwWW8Writer::OutWW8TableInfoCell
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    sal_uInt32 nDepth = pTableTextNodeInfo->getDepth();

    if (nDepth > 0)
    {
        /* Cell */
        InsUInt16(0x2416);
        pO->Insert((BYTE)0x1, pO->Count());
        InsUInt16(0x6649);
        InsUInt32(nDepth);

        if (nDepth > 1 && pTableTextNodeInfo->isEndOfCell())
        {
            InsUInt16(0x244b);
            pO->Insert((BYTE)0x1, pO->Count());
        }
    }
}

void SwWW8Writer::OutWW8TableInfoRow
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    sal_uInt32 nDepth = pTableTextNodeInfo->getDepth();

    if (nDepth > 0)
    {

        /* Row */
        if (pTableTextNodeInfo->isEndOfLine())
        {
            InsUInt16(0x2416);
            pO->Insert((BYTE)0x1, pO->Count());

            if (nDepth == 1)
            {
                InsUInt16(0x2417);
                pO->Insert((BYTE)0x1, pO->Count());
            }

            InsUInt16(0x6649);
            InsUInt32(nDepth);

            if (nDepth > 1)
            {
                InsUInt16(0x244b);
                pO->Insert((BYTE)0x1, pO->Count());
                InsUInt16(0x244c);
                pO->Insert((BYTE)0x1, pO->Count());
            }

            OutWW8TableDefinition(pTableTextNodeInfo);
            OutWW8TableHeight(pTableTextNodeInfo);
            OutWW8TableBackgrounds(pTableTextNodeInfo);
            OutWW8TableDefaultBorders(pTableTextNodeInfo);
            OutWW8TableCanSplit(pTableTextNodeInfo);
            OutWW8TableBidi(pTableTextNodeInfo);
            OutWW8TableVerticalCell(pTableTextNodeInfo);
        }
    }
}

static sal_uInt16 lcl_TCFlags(const SwTableBox * pBox)
{
    sal_uInt16 nFlags = 0;

    long nRowSpan = pBox->getRowSpan();

    if (nRowSpan != 0)
    {
        nFlags |= (1 << 5);

        if (nRowSpan > 0)
            nFlags |= (1 << 6);
    }

    const SwFrmFmt * pFmt = pBox->GetFrmFmt();
    switch (pFmt->GetVertOrient().GetVertOrient())
    {
        case text::VertOrientation::CENTER:
            nFlags |= (1 << 7);
            break;
        case text::VertOrientation::BOTTOM:
            nFlags |= (2 << 7);
            break;
        default:
            break;
    }

    return nFlags;
}

void SwWW8Writer::OutWW8TableVerticalCell
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTableBox * pTabBox = pTableTextNodeInfo->getTableBox();
    const SwTableLine * pTabLine = pTabBox->GetUpper();
    const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes();

    sal_uInt8 nBoxes = rTblBoxes.Count();
    for (sal_uInt8 n = 0; n < nBoxes; n++)
    {
        const SwTableBox * pTabBox1 = rTblBoxes[n];
        const SwFrmFmt * pFrmFmt = pTabBox1->GetFrmFmt();

        if (FRMDIR_VERT_TOP_RIGHT == TrueFrameDirection(*pFrmFmt))
        {
            InsUInt16(0x7629);
            pO->Insert(BYTE(n), pO->Count());        //start range
            pO->Insert(BYTE(n + 1), pO->Count());    //end range
            InsUInt16(5); //Equals vertical writing
        }
    }
}

void SwWW8Writer::OutWW8TableCanSplit
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTableBox * pTabBox = pTableTextNodeInfo->getTableBox();
    const SwTableLine * pTabLine = pTabBox->GetUpper();
    const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();

    /*
     By default the row can be split in word, and now in writer we have a
     feature equivalent to this, Word stores 1 for fCantSplit if the row
     cannot be split, we set true if we can split it. An example is #i4569#
     */

    const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
    BYTE nCantSplit = (!rSplittable.GetValue()) ? 1 : 0;
    if (bWrtWW8)
    {
        InsUInt16(0x3403);
        pO->Insert(nCantSplit, pO->Count());
        InsUInt16(0x3466); // also write fCantSplit90
    }
    else
    {
        pO->Insert(185, pO->Count());
    }
    pO->Insert(nCantSplit, pO->Count());
}

void SwWW8Writer::OutWW8TableBidi
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTable * pTable = pTableTextNodeInfo->getTable();
    const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();

    if (bWrtWW8)
    {
        if (TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP)
        {
            InsUInt16(0x560B);
            InsUInt16(1);
        }
    }
}

void SwWW8Writer::OutWW8TableHeight
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTableBox * pTabBox = pTableTextNodeInfo->getTableBox();
    const SwTableLine * pTabLine = pTabBox->GetUpper();
    const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();

#if 0
    const SwTable * pTable = pTableTextNodeInfo->getTable();
    bool bNewTableModel = pTable->IsNewModel();
    bool bFixRowHeight = false;
    const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
    if (! bNewModel)
    {
        sal_uInt32 nBoxes = rTabBoxes.Count();

        for (sal_uInt32 n = 0; n < nBoxes; n++)
        {
            SwTableBox * pBox1 = rTabBoxes[n];
            if (pBox1->getRowspan() != 1)
            {
                bFixRowHeight = true;
                break;
            }
        }
    }
#endif

    // Zeilenhoehe ausgeben   sprmTDyaRowHeight
    long nHeight = 0;
    const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
    if( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
    {
        if (ATT_MIN_SIZE == rLSz.GetHeightSizeType())
            nHeight = rLSz.GetHeight();
        else
            nHeight = -rLSz.GetHeight();
    }

    if (nHeight)
    {
        if( bWrtWW8 )
            InsUInt16( 0x9407 );
        else
            pO->Insert( 189, pO->Count() );
        InsUInt16( (USHORT)nHeight );
    }

}

void SwWW8Writer::OutWW8TableDefinition
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTableBox * pTabBox = pTableTextNodeInfo->getTableBox();
    const SwTableLine * pTabLine = pTabBox->GetUpper();
    const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();
    const SwNode * pTxtNd = pTableTextNodeInfo->getNode();
    const SwTable * pTable = pTableTextNodeInfo->getTable();

    if( pTable->GetRowsToRepeat() > pTableTextNodeInfo->getRow())
    {
        if( bWrtWW8 )
            InsUInt16( 0x3404 );
        else
            pO->Insert(186, pO->Count());
        pO->Insert( 1, pO->Count() );
    }

    // number of cell written
    sal_uInt32 nBoxes = rTabBoxes.Count();
    if (nBoxes > 32)
        nBoxes = 32;

    // sprm header
    InsUInt16(0xd608);
    sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20;
    InsUInt16(nSprmSize); // length

    // number of boxes
    pO->Insert(static_cast<BYTE>(nBoxes), pO->Count());


    /* cellxs */
    /*
     ALWAYS relative when text::HoriOrientation::NONE (nPageSize + ( nPageSize / 10 )) < nTblSz,
     in that case the cell width's and table width's are not real. The table
     width is maxed and cells relative, so we need the frame (generally page)
     width that the table is in to work out the true widths.
     */
    //const bool bNewTableModel = pTbl->IsNewModel();
    const SwFrmFmt *pFmt = pTable->GetFrmFmt();
    ASSERT(pFmt,"Impossible");
    if (!pFmt)
        return;

    const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
    const SwFmtVertOrient &rVert = pFmt->GetVertOrient();

    sal_uInt16 nTblOffset = 0;

    if (
        (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
         text::RelOrientation::FRAME == rHori.GetRelationOrient())
        &&
        (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
         text::RelOrientation::FRAME == rVert.GetRelationOrient())
        )
    {
        sal_Int16 eHOri = rHori.GetHoriOrient();
        switch (eHOri)
        {
            case text::HoriOrientation::CENTER:
            case text::HoriOrientation::RIGHT:
                if( bWrtWW8 )
                    InsUInt16(0x5400 );
                else
                    pO->Insert(182, pO->Count());
                InsUInt16(text::HoriOrientation::RIGHT == eHOri ? 2 : 1);
                break;
                default:

                nTblOffset = rHori.GetPos();
                const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace();
                nTblOffset += rLRSp.GetLeft();
                break;
        }
    }

    const SwFmtFrmSize &rSize = pFmt->GetFrmSize();
    int nWidthPercent = rSize.GetWidthPercent();
    bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE;
    if ( (pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::FULL) || bManualAligned )
        nWidthPercent = 100;
    bool bRelBoxSize = nWidthPercent != 0;
    unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth());
    if (nTblSz > USHRT_MAX/2 && !bRelBoxSize)
    {
        ASSERT(bRelBoxSize, "huge table width but not relative, suspicious");
        bRelBoxSize = true;
    }

    unsigned long nPageSize = nTblSz;
    if (bRelBoxSize)
    {
        Point aPt;
        SwRect aRect(pFmt->FindLayoutRect(false, &aPt));
        if (aRect.IsEmpty())
        {
            // dann besorge mal die Seitenbreite ohne Raender !!
            const SwFrmFmt* pParentFmt =
            mpParentFrame ?
            &(mpParentFrame->GetFrmFmt()) :
            const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false);
            aRect = pParentFmt->FindLayoutRect(true);
            if (0 == (nPageSize = aRect.Width()))
            {
                const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace();
                nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft()
                - rLR.GetRight();
            }
        }
        else
        {
            nPageSize = aRect.Width();
            if(bManualAligned)
            {
                // #i37571# For manually aligned tables
                const SvxLRSpaceItem &rLR = pFmt->GetLRSpace();
                nPageSize -= (rLR.GetLeft() + rLR.GetRight());
            }

        }

        ASSERT(nWidthPercent, "Impossible");
        if (nWidthPercent)
        {
            nPageSize *= nWidthPercent;
            nPageSize /= 100;
        }
    }

    SwTwips nSz = 0;
    sal_uInt32 n = 0;
    InsUInt16(nTblOffset);

    for (n = 0; n < nBoxes; n++)
    {
        const SwFrmFmt* pBoxFmt = rTabBoxes[ n ]->GetFrmFmt();
        const SwFmtFrmSize& rLSz = pBoxFmt->GetFrmSize();
        nSz += rLSz.GetWidth();
        SwTwips nCalc = nSz;
        if (bRelBoxSize)
            nCalc = (nCalc * nPageSize) / nTblSz;

        InsUInt16(static_cast<USHORT>(nCalc));
    }

    /* TCs */
    for (n = 0; n < nBoxes; n++)
    {
#ifdef DEBUG
        sal_uInt16 npOCount = pO->Count();
#endif

        SwTableBox * pTabBox1 = rTabBoxes[n];
        const SwFrmFmt & rBoxFmt = *(pTabBox1->GetFrmFmt());
        if( bWrtWW8 )
        {
            sal_uInt16 nFlags = lcl_TCFlags(pTabBox1);
            InsUInt16( nFlags );
        }

        static BYTE aNullBytes[] = { 0x0, 0x0 };

        pO->Insert( aNullBytes, 2, pO->Count() );   // dummy
        Out_SwFmtTableBox( *pO, rBoxFmt.GetBox() ); // 8/16 Byte

#ifdef DEBUG
        ::std::clog << "<tclength>" << pO->Count() - npOCount << "</tclength>"
        << ::std::endl;
#endif
    }
}

void SwWW8Writer::OutWW8TableDefaultBorders
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTableBox * pTabBox = pTableTextNodeInfo->getTableBox();
    const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();

    //Set Default, just taken from the first cell of the first
    //row
    static USHORT aBorders[] =
    {
        BOX_LINE_TOP, BOX_LINE_LEFT,
        BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    };

    for( int i = 0; i < 4; ++i)
    {
        SwWW8Writer::InsUInt16(*pO, 0xD634);
        pO->Insert( BYTE(6), pO->Count() );
        pO->Insert( BYTE(0), pO->Count() );
        pO->Insert( BYTE(1), pO->Count() );
        pO->Insert( BYTE(1 << i), pO->Count() );
        pO->Insert( BYTE(3), pO->Count() );

        SwWW8Writer::InsUInt16(*pO,
                               pFrmFmt->GetBox().GetDistance(aBorders[i]));
    }

}

void SwWW8Writer::OutWW8TableBackgrounds
(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo)
{
    const SwTableBox * pTabBox = pTableTextNodeInfo->getTableBox();
    const SwTableLine * pTabLine = pTabBox->GetUpper();
    const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes();

    sal_uInt8 nBoxes = rTabBoxes.Count();
    if( bWrtWW8 )
        InsUInt16( 0xD609 );
    else
        pO->Insert( (BYTE)191, pO->Count() );
    pO->Insert( (BYTE)(nBoxes * 2), pO->Count() );  // Len

    for (sal_uInt8 n = 0; n < nBoxes; n++)
    {
        const SwTableBox * pBox1 = rTabBoxes[n];
        const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
        const SfxPoolItem * pI = NULL;
        Color aColor;

        if (SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState(RES_BACKGROUND,
                                                              false, &pI))
        {
            aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
        }
        else
            aColor = COL_AUTO;

        WW8_SHD aShd;
        TransBrush(aColor, aShd);
        InsUInt16(aShd.GetValue());
    }

    if (bWrtWW8)
    {
        sal_uInt8 nBoxes0 = rTabBoxes.Count();
        if (nBoxes0 > 21)
            nBoxes0 = 21;

        InsUInt16(0xd612);
        pO->Insert(static_cast<BYTE>(nBoxes0 * 10), pO->Count());

        for (sal_uInt8 n = 0; n < nBoxes0; n++)
        {
            const SwTableBox * pBox1 = rTabBoxes[n];
            const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt();
            const SfxPoolItem * pI = NULL;
            Color aColor;

            if (SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState(RES_BACKGROUND,
                                                                  false, &pI))
            {
                aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
            }
            else
                aColor = COL_AUTO;

            WW8SHDLong aSHD;
            aSHD.setCvFore(0xFF000000);

            sal_uInt32 nBgColor = aColor.GetColor();
            if (nBgColor == COL_AUTO)
                aSHD.setCvBack(0xFF000000);
            else
                aSHD.setCvBack(wwUtility::RGBToBGR(nBgColor));

            aSHD.Write(*this);
        }
    }
}

void SwWW8Writer::WriteText()
{
#ifdef DEBUG
    ::std::clog << "<WriteText>" << ::std::endl;
    ::std::clog << dbg_out(pCurPam->GetDoc()->GetNodes()) << ::std::endl;
#endif

    while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode ||
            (pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode &&
            pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex()) )
@@ -1789,8 +2312,10 @@ void SwWW8Writer::WriteText()
            pCurPam->GetPoint()->nContent.Assign( pCNd, 0 );
            Out( aWW8NodeFnTab, *pCNd, *this );
        }
        else if( pNd->IsTableNode() && !bIsInTable )
            OutWW8_SwTblNode( *this, *(SwTableNode*)pNd );
        else if( pNd->IsTableNode() )
        {
            mpTableInfo->processSwTable(&(dynamic_cast<SwTableNode *>(pNd)->GetTable()));
        }
        else if( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp )
            OutWW8_SwSectionNode( *this, *pNd->GetSectionNode() );
        else if( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() &&
@@ -1827,18 +2352,33 @@ void SwWW8Writer::WriteText()
                                    pAktPageDesc, pParentFmt, nRstLnNum );
            }
        }
        else if( pNd == &pNd->GetNodes().GetEndOfContent() )
        else if (pNd->IsEndNode())
        {
            OutWW8_SwEndNode(pNd);
        }

        if( pNd == &pNd->GetNodes().GetEndOfContent() )
            break;

        ULONG nPos = pCurPam->GetPoint()->nNode++;  // Bewegen
        ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() );   // Wie weit ?
    }

#ifdef DEBUG
    ::std::clog << "</WriteText>" << ::std::endl;
#endif
}

void SwWW8Writer::WriteMainText()
{
#ifdef DEBUG
    ::std::clog << "<WriteMainText>" << ::std::endl;
#endif

    pFib->fcMin = Strm().Tell();

    pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex();

    WriteText();

    if( 0 == Strm().Tell() - pFib->fcMin )  // kein Text ?
@@ -1855,6 +2395,10 @@ void SwWW8Writer::WriteMainText()
    const SwTxtNode* pLastNd = pCurPam->GetMark()->nNode.GetNode().GetTxtNode();
    if( pLastNd )
        nLastFmtId = GetId( (SwTxtFmtColl&)pLastNd->GetAnyFmtColl() );

#ifdef DEBUG
    ::std::clog << "</WriteMainText>" << ::std::endl;
#endif
}

void SwWW8Writer::WriteFkpPlcUsw()
@@ -2481,7 +3025,8 @@ ULONG SwWW8Writer::WriteMedium( SfxMedium& )

SwWW8Writer::SwWW8Writer(const String& rFltName, const String& rBaseURL)
    : aMainStg(sMainStream), pISet(0), pUsedNumTbl(0), mpTopNodeOfHdFtPage(0),
    pBmpPal(0), pKeyMap(0), pOLEExp(0), pOCXExp(0), pOleMap(0), nUniqueList(0),
    pBmpPal(0), pKeyMap(0), pOLEExp(0), pOCXExp(0), pOleMap(0),
    mpTableInfo(new ww8::WW8TableInfo()), nUniqueList(0),
    mnHdFtIndex(0), pAktPageDesc(0), pPapPlc(0), pChpPlc(0), pChpIter(0), pO(0),
    bHasHdr(false), bHasFtr(false)
{
@@ -2602,6 +3147,13 @@ void SwWW8Writer::RestoreMacroCmds()
    pFib->lcbCmds = pTableStrm->Tell() - pFib->fcCmds;
}

void WW8SHDLong::Write(SwWW8Writer & rWriter)
{
    rWriter.InsUInt32(m_cvFore);
    rWriter.InsUInt32(m_cvBack);
    rWriter.InsUInt16(m_ipat);
}

void SwWW8Writer::WriteFormData(SwFieldBookmark &rFieldmark)
{
    ASSERT(bWrtWW8, "No 95 export yet");
@@ -2695,4 +3247,51 @@ void SwWW8Writer::WriteFormData(SwFieldBookmark &rFieldmark)

}

void SwWW8Writer::OutWW8_SwEndNode(SwNode * pNode)
{
    ww8::WW8TableNodeInfo::Pointer_t pNodeInfo =
    mpTableInfo->getTableNodeInfo(pNode);

    SVBT16 nStyle;
    ShortToSVBT16(nStyleBeforeFly, nStyle);

    if (pNodeInfo)
    {
        if (pNodeInfo.get() != NULL)
        {
#ifdef DEBUG
            ::std::clog << pNodeInfo->toString() << ::std::endl;
#endif

            pO->Remove( 0, pO->Count() );                       // leeren

            if (pNodeInfo->isEndOfCell())
            {
                WriteCR(pNodeInfo);

                pO->Insert( (BYTE*)&nStyle, 2, pO->Count() );     // Style #
                OutWW8TableInfoCell(pNodeInfo);
                pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(),
                                        pO->GetData() );

                pO->Remove( 0, pO->Count() );                       // leeren
            }

            if (pNodeInfo->isEndOfLine())
            {
                WriteRowEnd(pNodeInfo->getDepth());

                pO->Insert( (BYTE*)&nStyle, 2, pO->Count() );     // Style #
                OutWW8TableInfoRow(pNodeInfo);
                pPapPlc->AppendFkpEntry( Strm().Tell(), pO->Count(),
                                        pO->GetData() );

                pO->Remove( 0, pO->Count() );                       // leeren
            }
        }
    }
}



/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 3329552..4669bee 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: wrtww8.hxx,v $
 * $Revision: 1.78 $
 * $Revision: 1.76.172.5 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -127,6 +127,8 @@ class SvStorageRef;
struct WW8_PdAttrDesc;
class SvxBrushItem;

#include "WW8TableInfo.hxx"

#define GRF_MAGIC_1 0x12    // 3 magic Bytes fuer PicLocFc-Attribute
#define GRF_MAGIC_2 0x34
#define GRF_MAGIC_3 0x56
@@ -393,6 +395,7 @@ friend Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode );
    SvxMSExportOLEObjects* pOLEExp;
    SwMSConvertControls* pOCXExp;
    WW8OleMaps* pOleMap;
    ww8::WW8TableInfo::Pointer_t mpTableInfo;

    USHORT nCharFmtStart;
    USHORT nFmtCollStart;
@@ -440,6 +443,7 @@ friend Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode );
    void GatherChapterFields();
    bool FmtHdFtContainsChapterField(const SwFrmFmt &rFmt) const;
    bool CntntContainsChapterField(const SwFmtCntnt &rCntnt) const;
    void OutWW8_SwEndNode( SwNode * pNode );
public:

    /* implicit bookmark vector containing pairs of node indexes and bookmark names */
@@ -553,6 +557,15 @@ public:
    void AppendFlyInFlys(const sw::Frame& rFrmFmt, const Point& rNdTopLeft);
    void WriteOutliner(const OutlinerParaObject& rOutliner, BYTE nTyp);
    void WriteSdrTextObj(const SdrObject& rObj, BYTE nTyp);
    void OutWW8TableInfoCell(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableInfoRow(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableDefinition(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableDefaultBorders(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableBackgrounds(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableHeight(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableCanSplit(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableBidi(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);
    void OutWW8TableVerticalCell(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo);

    UINT32 GetSdrOrdNum( const SwFrmFmt& rFmt ) const;
    void CreateEscher();
@@ -579,10 +592,10 @@ public:
    void WriteAsStringTable(const ::std::vector<String>&, INT32& rfcSttbf,
        INT32& rlcbSttbf, USHORT nExtraLen = 0);
    void WriteText();
    void WriteCR();
    void WriteCR(ww8::WW8TableNodeInfo::Pointer_t pTableTextNodeInfo = ww8::WW8TableNodeInfo::Pointer_t());
    void WriteChar( sal_Unicode c );
    void WriteCellEnd();
    void WriteRowEnd();
    void WriteRowEnd(sal_uInt32 nDepth = 1);
    USHORT StartTableFromFrmFmt(WW8Bytes &rAt, const SwFrmFmt *pFmt,
        SwTwips &rPageSize);

@@ -1004,7 +1017,6 @@ public:
Writer& OutWW8_SwGrfNode( Writer& rWrt, SwCntntNode& rNode );
Writer& OutWW8_SwOleNode( Writer& rWrt, SwCntntNode& rNode );
Writer& OutWW8_SwSectionNode(Writer& rWrt, SwSectionNode& rSectionNode );
Writer& OutWW8_SwTblNode( Writer& rWrt, SwTableNode & rNode );

Writer& OutWW8_SwFmtHoriOrient( Writer& rWrt, const SfxPoolItem& rHt );
Writer& OutWW8_SwFmtVertOrient( Writer& rWrt, const SfxPoolItem& rHt );
@@ -1013,6 +1025,23 @@ sal_Int16 GetWordFirstLineOffset(const SwNumFmt &rFmt);
//A bit of a bag on the side for now
String FieldString(ww::eField eIndex);
String BookmarkToWord(const String &rBookmark);

class WW8SHDLong
{
    sal_uInt32 m_cvFore;
    sal_uInt32 m_cvBack;
    sal_uInt16 m_ipat;

public:
    WW8SHDLong() : m_cvFore(0), m_cvBack(0), m_ipat(0) {}
    virtual ~WW8SHDLong() {}

    void Write(SwWW8Writer & rWriter);
    void setCvFore(sal_uInt32 cvFore) { m_cvFore = cvFore; }
    void setCvBack(sal_uInt32 cvBack) { m_cvBack = cvBack; }
    void setIPat(sal_uInt16 ipat) { m_ipat = ipat; }
};

#endif  //  _WRTWW8_HXX

/* vi:set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index d4dd58f..3b724c9 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8atr.cxx,v $
 * $Revision: 1.113 $
 * $Revision: 1.113.40.3 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -3436,13 +3436,17 @@ void SwWW8Writer::WriteCellEnd()
        pMagicTable->Append(Fc2Cp(nOffset),0x122);
}

void SwWW8Writer::WriteRowEnd()
void SwWW8Writer::WriteRowEnd(sal_uInt32 nDepth)
{
    WriteChar( (BYTE)0x07 );
    if (nDepth == 1)
        WriteChar( (BYTE)0x07 );
    else if (nDepth > 1)
        WriteChar( (BYTE)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);
    //pMagicTable->Append(Fc2Cp(Strm().Tell()),0x1B6);
}

static Writer& OutWW8_SwFmtPageDesc(Writer& rWrt, const SfxPoolItem& rHt)
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index bcc341f..50be184 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8par.cxx,v $
 * $Revision: 1.199 $
 * $Revision: 1.199.12.6 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -141,6 +141,11 @@

#include <stdio.h>

#ifdef DEBUG
#include <iostream>
#include <dbgoutsw.hxx>
#endif

#define MM_250 1417             // WW-Default fuer Hor. Seitenraender: 2.5 cm
#define MM_200 1134             // WW-Default fuer u.Seitenrand: 2.0 cm

@@ -2228,6 +2233,9 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
    }
    if (bStartTab)
    {
        WW8PLCFxSave1 aSave;
        pPlcxMan->GetPap()->Save( aSave );

        if (bAnl)                           // Nummerierung ueber Zellengrenzen
            StopAllAnl();                   // fuehrt zu Absturz -> keine Anls
                                            // in Tabellen
@@ -2243,6 +2251,7 @@ bool SwWW8ImplReader::ProcessSpecial(bool &rbReSync, WW8_CP nStartCp)
        // nach StartTable ist ein ReSync noetig ( eigentlich nur, falls die
        // Tabelle ueber eine FKP-Grenze geht
        rbReSync = true;
        pPlcxMan->GetPap()->Restore( aSave );
    }
    return bTableRowEnd;
}
@@ -2512,6 +2521,10 @@ bool SwWW8ImplReader::AddTextToParagraph(const String& rAddString)
    const SwTxtNode* pNd = pPaM->GetCntntNode()->GetTxtNode();
    if (rAddString.Len())
    {
#ifdef DEBUG
        ::std::clog << "<addTextToParagraph>" << dbg_out(rAddString)
        << "</addTextToParagraph>" << ::std::endl;
#endif
        if ((pNd->GetTxt().Len() + rAddString.Len()) < STRING_MAXLEN -1)
        {
            rDoc.Insert (*pPaM, rAddString, true);
@@ -2535,7 +2548,10 @@ bool SwWW8ImplReader::AddTextToParagraph(const String& rAddString)
                rDoc.Insert (*pPaM, rAddString, true);
            }
        }

        bReadTable = false;
    }

    return true;
}

@@ -2757,7 +2773,15 @@ bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs)
                        bRet = false;
                    }
                }
                else if (bWasTabCellEnd)
                {
                    TabCellEnd();
                    bRet = false;
                }
            }

            bWasTabCellEnd = false;

            break;              // line end
        case 0x5:               // Annotation reference
        case 0x13:
@@ -3194,7 +3218,8 @@ SwWW8ImplReader::SwWW8ImplReader(BYTE nVersionPara, SvStorage* pStorage,
    mbNewDoc(bNewDoc),
    nDropCap(0),
    nIdctHint(0),
    bBidi(false)
    bBidi(false),
    bReadTable(false)
{
    pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    nWantedVersion = nVersionPara;
@@ -3225,7 +3250,7 @@ SwWW8ImplReader::SwWW8ImplReader(BYTE nVersionPara, SvStorage* pStorage,
    nInTable=0;
    bReadNoTbl = bPgSecBreak = bSpec = bObj = bTxbxFlySection
               = bHasBorder = bSymbol = bIgnoreText
               = bWasTabRowEnd = false;
               = bWasTabRowEnd = bWasTabCellEnd = false;
    bShdTxtCol = bCharShdTxtCol = bAnl = bHdFtFtnEdn = bFtnEdn
               = bIsHeader = bIsFooter = bIsUnicode = bCpxStyle = bStyNormal =
                 bWWBugNormal  = false;
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index c09bbe2..3a9aacf 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8par.hxx,v $
 * $Revision: 1.159 $
 * $Revision: 1.159.12.2 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -1050,6 +1050,7 @@ private:
    bool bIgnoreText;       // z.B. fuer FieldVanish
    int  nInTable;          // wird gerade eine Tabelle eingelesen
    bool bWasTabRowEnd;     // Tabelle : Row End Mark
    bool bWasTabCellEnd;    // table: Cell End Mark

    bool bShdTxtCol;        // Textfarbe indirekt gesetzt ( Hintergrund sw )
    bool bCharShdTxtCol;    // Textfarbe indirekt gesetzt ( Zeichenhintergrund sw )
@@ -1096,6 +1097,8 @@ private:

    int nIdctHint;
    bool bBidi;
    bool bReadTable;
    boost::shared_ptr<SwPaM> mpTableEndPaM;

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

@@ -1496,6 +1499,7 @@ public:     // eigentlich private, geht aber leider nur public


    void Read_TabRowEnd(        USHORT, const BYTE* pData, short nLen );
    void Read_TabCellEnd(        USHORT, const BYTE* pData, short nLen );
    static bool ParseTabPos(WW8_TablePos *aTabPos, WW8PLCFx_Cp_FKP* pPap);
    void Read_Shade(            USHORT, const BYTE* pData, short nLen );
    void Read_ANLevelNo(        USHORT, const BYTE* pData, short nLen );
diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx
index 409c0bb..42d6f6e 100644
--- a/sw/source/filter/ww8/ww8par2.cxx
+++ b/sw/source/filter/ww8/ww8par2.cxx
@@ -32,7 +32,6 @@
#include "precompiled_sw.hxx"
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */


#include <tools/solar.h>
#include <vcl/vclenum.hxx>
#include <vcl/font.hxx>
@@ -2528,6 +2527,7 @@ void WW8TabDesc::UseSwTable()
    aDup.Insert(*pIo->pPaM->GetPoint());

    pIo->bWasTabRowEnd = false;
    pIo->bWasTabCellEnd = false;
}

void WW8TabDesc::MergeCells()
@@ -2710,6 +2710,7 @@ void WW8TabDesc::FinishSwTable()
    aDup.Insert(*pIo->pPaM->GetPoint());

    pIo->bWasTabRowEnd = false;
    pIo->bWasTabCellEnd = false;

    pIo->maInsertedTables.InsertTable(*pTblNd, *pIo->pPaM);

@@ -3440,11 +3441,11 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
                "how could we be in a local apo and have no apo");
        }

        if ( !maTableStack.empty() && !InEqualApo(nNewInTable) )
        if ( eAnchor == FLY_AUTO_CNTNT && !maTableStack.empty() && !InEqualApo(nNewInTable) )
        {
            pTableDesc->pParentPos = new SwPosition(*pPaM->GetPoint());
            SfxItemSet aItemSet(rDoc.GetAttrPool(),
                RES_FRMATR_BEGIN, RES_FRMATR_END-1);
                                RES_FRMATR_BEGIN, RES_FRMATR_END-1);
            // --> OD 2005-01-26 #i33818# - anchor the Writer fly frame for
            // the nested table at-character.
            // --> OD 2005-03-21 #i45301#
@@ -3452,9 +3453,9 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
            aAnchor.SetAnchor( pTableDesc->pParentPos );
            aItemSet.Put( aAnchor );
            pTableDesc->pFlyFmt = rDoc.MakeFlySection( eAnchor,
                pTableDesc->pParentPos, &aItemSet);
                                                      pTableDesc->pParentPos, &aItemSet);
            ASSERT( pTableDesc->pFlyFmt->GetAnchor().GetAnchorId() == eAnchor,
                    "Not the anchor type requested!" );
                   "Not the anchor type requested!" );
            // <--
            MoveInsideFly(pTableDesc->pFlyFmt);
        }
@@ -3510,8 +3511,28 @@ bool SwWW8ImplReader::StartTable(WW8_CP nStartCp)
void SwWW8ImplReader::TabCellEnd()
{
    if (nInTable && pTableDesc)
    {
        pTableDesc->TableCellEnd();

        if (bReadTable &&  pWFlyPara == NULL && mpTableEndPaM.get() != NULL &&
            ! SwPaM::Overlap(*pPaM, *mpTableEndPaM))
        {
            if (mpTableEndPaM->GetPoint()->nNode.GetNode().IsTxtNode())
            {
                rDoc.DelFullPara(*mpTableEndPaM);
            }
        }
    }

    bFirstPara = true;    // We have come to the end of a cell so FirstPara flag
    bReadTable = false;
    mpTableEndPaM.reset();
}

void SwWW8ImplReader::Read_TabCellEnd( USHORT, const BYTE* pData, short nLen)
{
    if( ( nLen > 0 ) && ( *pData == 1 ) )
        bWasTabCellEnd = true;
}

void SwWW8ImplReader::Read_TabRowEnd( USHORT, const BYTE* pData, short nLen )   // Sprm25
@@ -3557,6 +3578,9 @@ void SwWW8ImplReader::StopTable()
        maTracer.EnterEnvironment(sw::log::eTable, rtl::OUString::valueOf(
            static_cast<sal_Int32>(maTableStack.size())));
    }

    bReadTable = true;
    mpTableEndPaM.reset(new SwPaM(*pPaM));
}

// GetTableLeft() wird fuer absatzgebundene Grafikobjekte in Tabellen
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 8ce5899..452650e 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8par5.cxx,v $
 * $Revision: 1.111 $
 * $Revision: 1.110.40.4 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -428,6 +428,7 @@ void SwWW8ImplReader::ConvertFFileName( String& rName, const String& rOrg )
{
    rName = rOrg;
    rName.SearchAndReplaceAllAscii( "\\\\", String( '\\' ));
    rName.SearchAndReplaceAllAscii( "%20", String( ' ' ));

    // ggfs. anhaengende Anfuehrungszeichen entfernen
    if( rName.Len() &&  '"' == rName.GetChar( rName.Len()-1 ))
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index ecff56d..61b5763d 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8par6.cxx,v $
 * $Revision: 1.188 $
 * $Revision: 1.188.8.1 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -6037,7 +6037,7 @@ const wwSprmDispatcher *GetWW8SprmDispatcher()
        {0x9410, 0},                                 //undocumented
        {0x703A, 0},                                 //undocumented
        {0x303B, 0},                                 //undocumented
        {0x244B, 0},                                 //undocumented, must be
        {0x244B, &SwWW8ImplReader::Read_TabCellEnd}, //undocumented, must be
                                                     //subtable "sprmPFInTable"
        {0x244C, &SwWW8ImplReader::Read_TabRowEnd},  //undocumented, must be
                                                     // subtable "sprmPFTtp"
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index fac1f62..604af8e 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8scan.cxx,v $
 * $Revision: 1.142 $
 * $Revision: 1.142.12.1 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -1778,10 +1778,10 @@ WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTblSt,
                    pWwFib->fcPlcfHdrtxbxBkd, pWwFib->lcbPlcfHdrtxbxBkd, 0);
            }
            // Sub table cp positions
            if (pWwFib->fcMagicTable && pWwFib->lcbMagicTable)
            if (pWwFib->fcPlcfTch && pWwFib->lcbPlcfTch)
            {
                pMagicTables = new WW8PLCFspecial( pTblSt,
                    pWwFib->fcMagicTable, pWwFib->lcbMagicTable, 4);
                    pWwFib->fcPlcfTch, pWwFib->lcbPlcfTch, 4);
            }
            // Sub document cp positions
            if (pWwFib->fcPlcfwkb && pWwFib->lcbPlcfwkb)
@@ -5534,8 +5534,8 @@ WW8Fib::WW8Fib(SvStream& rSt, BYTE nWantedVersion, UINT32 nOffset)
            if (cfclcb > 93)
            {
                rSt.Seek( 0x382 );          // MagicTables
                rSt >> fcMagicTable;
                rSt >> lcbMagicTable;
                rSt >> fcPlcfTch;
                rSt >> lcbPlcfTch;
            }

            if (cfclcb > 113)
@@ -5569,7 +5569,7 @@ WW8Fib::WW8Fib(BYTE nVer)
    {
        fcMin = 0x800;
        wIdent = 0xa5ec;
        nFib = 0xc2;
        nFib = 0x0101;
        nFibBack = 0xbf;
        nProduct = 0x204D;

@@ -5889,8 +5889,8 @@ bool WW8Fib::Write(SvStream& rStrm)
        Set_UInt32( pData, lcbSttbListNames );

        pData += 0x382 - 0x37A;
        Set_UInt32( pData, fcMagicTable );
        Set_UInt32( pData, lcbMagicTable );
        Set_UInt32( pData, fcPlcfTch );
        Set_UInt32( pData, lcbPlcfTch );

        pData += 0x3FA - 0x38A;
        Set_UInt16( pData, (UINT16)0x0002);
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index 56c6996..58a0c5c 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -7,7 +7,7 @@
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: ww8scan.hxx,v $
 * $Revision: 1.85 $
 * $Revision: 1.85.12.1 $
 *
 * This file is part of OpenOffice.org.
 *
@@ -1403,8 +1403,8 @@ public:
    WW8_FC fcSttbListNames;// 0x0372 PLCF for Listname Table
    INT32 lcbSttbListNames;// 0x0376

    WW8_FC fcMagicTable;
    INT32 lcbMagicTable;
    WW8_FC fcPlcfTch;
    INT32 lcbPlcfTch;

    // 0x38A - 41A == ignore
    WW8_FC fcAtrdExtra;