[ooo-build-commit] .: 5 commits - sw/source sw/util

Cédric Bosdonnat cbosdo at kemper.freedesktop.org
Fri Sep 17 04:17:19 PDT 2010


 sw/source/filter/rtf/makefile.mk             |    9 
 sw/source/filter/rtf/rtfnum.cxx              |    3 
 sw/source/filter/rtf/swparrtf.cxx            |    6 
 sw/source/filter/rtf/swparrtf.hxx            |    2 
 sw/source/filter/ww8/README-rtf.txt          |  226 +
 sw/source/filter/ww8/attributeoutputbase.hxx |   23 
 sw/source/filter/ww8/docxattributeoutput.cxx |  520 +++-
 sw/source/filter/ww8/docxattributeoutput.hxx |    8 
 sw/source/filter/ww8/docxexport.cxx          |  125 -
 sw/source/filter/ww8/docxexport.hxx          |   22 
 sw/source/filter/ww8/docxexportfilter.cxx    |   53 
 sw/source/filter/ww8/makefile.mk             |   15 
 sw/source/filter/ww8/rtfattributeoutput.cxx  | 3356 +++++++++++++++++++++++++++
 sw/source/filter/ww8/rtfattributeoutput.hxx  |  574 ++++
 sw/source/filter/ww8/rtfexport.cxx           | 1240 +++++++++
 sw/source/filter/ww8/rtfexport.hxx           |  211 +
 sw/source/filter/ww8/rtfexportfilter.cxx     |  136 +
 sw/source/filter/ww8/rtfexportfilter.hxx     |   84 
 sw/source/filter/ww8/rtfimportfilter.cxx     |  134 +
 sw/source/filter/ww8/rtfimportfilter.hxx     |   74 
 sw/source/filter/ww8/rtfsdrexport.cxx        |  577 ++++
 sw/source/filter/ww8/rtfsdrexport.hxx        |  111 
 sw/source/filter/ww8/writerwordglue.cxx      |    2 
 sw/source/filter/ww8/wrtw8esh.cxx            |   66 
 sw/source/filter/ww8/wrtw8nds.cxx            |  244 +
 sw/source/filter/ww8/wrtw8num.cxx            |    3 
 sw/source/filter/ww8/wrtw8sty.cxx            |   67 
 sw/source/filter/ww8/wrtww8.cxx              |    2 
 sw/source/filter/ww8/wrtww8.hxx              |  162 +
 sw/source/filter/ww8/ww8atr.cxx              |   71 
 sw/source/filter/ww8/ww8attributeoutput.hxx  |    5 
 sw/source/filter/ww8/ww8par5.cxx             |    9 
 sw/source/filter/ww8/ww8scan.cxx             |   15 
 sw/source/filter/ww8/ww8scan.hxx             |    4 
 sw/util/msword.map                           |    3 
 35 files changed, 7668 insertions(+), 494 deletions(-)

New commits:
commit 5af90594c6ac8e98c81bbd3f90ff92e794c7deee
Author: Cédric Bosdonnat <cedricbosdo at openoffice.org>
Date:   Fri Sep 17 12:57:18 2010 +0200

    sw-ww8-ruby-export-fix.diff: Fixed wrong ruby export in WW8
    
    i#79246

diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 37ac58e..66222b7 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -741,7 +741,14 @@ void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen /*nPos*/,
     aStr += String::CreateFromInt32(nHeight);
     aStr += '(';
     aStr += rRuby.GetText();
-    aStr.APPEND_CONST_ASC( ");" );
+    aStr.APPEND_CONST_ASC( ")" );
+
+    // The parameter separator depends on the FIB.lid
+    if ( m_rWW8Export.pFib->getNumDecimalSep() == '.' )
+        aStr.APPEND_CONST_ASC( "," );
+    else
+        aStr.APPEND_CONST_ASC( ";" );
+
     m_rWW8Export.OutputField( 0, ww::eEQ, aStr,
             WRITEFIELD_START | WRITEFIELD_CMD_START );
 }
diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx
index 8ca3f12..66db95e 100644
--- a/sw/source/filter/ww8/ww8scan.cxx
+++ b/sw/source/filter/ww8/ww8scan.cxx
@@ -47,8 +47,11 @@
 #include <swtypes.hxx>      // DELETEZ
 
 #endif                      // dump
+#include <comphelper/processfactory.hxx>
+#include <unotools/localedatawrapper.hxx>
 #include <tools/debug.hxx>
 #include <i18npool/lang.h>
+#include <editeng/unolingu.hxx>
 #include <vcl/svapp.hxx>    // Application  #i90932#
 
 #include <stdio.h>
@@ -58,6 +61,8 @@
     if (!(aCon)) \
         return aRet;
 
+using namespace ::com::sun::star::lang;
+
 //-begin
 namespace SL
 {
@@ -5649,6 +5654,16 @@ WW8Fib::WW8Fib(BYTE nVer)
             break;
     };
     // <-- #i90932# 
+
+    Locale aTempLocale;
+    SvxLanguageToLocale( aTempLocale, lid );
+    LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), aTempLocale );
+    nNumDecimalSep = aLocaleWrapper.getNumDecimalSep().GetChar( 0 );
+}
+
+sal_Unicode WW8Fib::getNumDecimalSep() const
+{
+    return nNumDecimalSep;
 }
 
 bool WW8Fib::WriteHeader(SvStream& rStrm)
diff --git a/sw/source/filter/ww8/ww8scan.hxx b/sw/source/filter/ww8/ww8scan.hxx
index f559543..7844860 100644
--- a/sw/source/filter/ww8/ww8scan.hxx
+++ b/sw/source/filter/ww8/ww8scan.hxx
@@ -988,6 +988,9 @@ public:
 */
 class WW8Fib
 {
+private:
+    sal_Unicode nNumDecimalSep;
+
 public:
     /**
         Program-Version asked for by us:
@@ -1445,6 +1448,7 @@ public:
     static rtl_TextEncoding GetFIBCharset(UINT16 chs);
     ww::WordVersion GetFIBVersion() const;
     WW8_CP GetBaseCp(ManTypes nType) const;
+    sal_Unicode getNumDecimalSep() const;
 };
 
 class WW8Style
commit 32e1302830f938ae4897a5a43d1b91c025fa3f45
Author: Cédric Bosdonnat <cedricbosdo at openoffice.org>
Date:   Fri Sep 17 12:54:17 2010 +0200

    sw-ww8-styles-import-fix.diff: wrong style import in french
    
    i#21939

diff --git a/sw/source/filter/ww8/writerwordglue.cxx b/sw/source/filter/ww8/writerwordglue.cxx
index 2d07aba..078e2a7 100644
--- a/sw/source/filter/ww8/writerwordglue.cxx
+++ b/sw/source/filter/ww8/writerwordglue.cxx
@@ -162,7 +162,7 @@ namespace myImplHelpers
             RES_NONE, RES_NONE, RES_NONE, RES_POOLCOLL_LISTS_BEGIN,
             RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
             RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
-            RES_NONE, RES_NONE, RES_POOLCOLL_DOC_TITEL, RES_NONE,
+            RES_NONE, RES_NONE, RES_POOLCOLL_HEADLINE_BASE, RES_NONE,
             RES_POOLCOLL_SIGNATURE, RES_NONE, RES_POOLCOLL_TEXT,
             RES_POOLCOLL_TEXT_MOVE, RES_NONE, RES_NONE, RES_NONE, RES_NONE,
             RES_NONE, RES_NONE, RES_POOLCOLL_DOC_SUBTITEL
commit 155332642bf8d533aec11631261e5c3f2eb5aa7e
Author: Cédric Bosdonnat <cedricbosdo at openoffice.org>
Date:   Fri Sep 17 12:52:07 2010 +0200

    sw-ww8-field-fix.diff: WW8 fields import fix
    
    i#61075, i#89667, i#111684

diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 4af6197..57dfd8a 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -985,9 +985,12 @@ long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes)
         pStrm->Seek( nOldPos );
 
         //#124725# field codes which contain '/' or '.' are not displayed in WinWord
-        if (!aStr.EqualsAscii(" ADDIN", 0, 6) &&
-            (aStr.Search('.') != STRING_NOTFOUND ||
-             aStr.Search('/') != STRING_NOTFOUND))
+        xub_StrLen nSpacePos = aStr.Search( ' ', 1 );
+        if ( STRING_NOTFOUND == nSpacePos )
+            nSpacePos = aStr.Len( );
+        xub_StrLen nSearchPos = STRING_NOTFOUND;
+        if ( ( ( nSearchPos = aStr.Search('.') ) != STRING_NOTFOUND && nSearchPos < nSpacePos ) ||
+             ( ( nSearchPos = aStr.Search('/') ) != STRING_NOTFOUND && nSearchPos < nSpacePos ) )
             return aF.nLen;
         else
             return aF.nLen - aF.nLRes - 1;  // so viele ueberlesen, das Resultfeld
commit e5693d5e14f8a53070b86ea1682201f5f2149b82
Author: Cédric Bosdonnat <cedricbosdo at openoffice.org>
Date:   Fri Sep 17 12:35:12 2010 +0200

    docx-fixes02.diff: Some other misc docx fixes
    
    n#581604

diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index e5f40b9..7ff2ada 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2000, 2010 Oracle and/or its affiliates.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -171,12 +171,12 @@ public:
 
     /// Output text (inside a run).
     virtual void RunText( const String& rText, rtl_TextEncoding eCharSet ) = 0;
-    
+
     /// Output text (without markup).
     virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet ) = 0;
 
     /// Output ruby start.
-    virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby ) = 0;
+    virtual void StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, const SwFmtRuby& rRuby ) = 0;
 
     /// Output ruby end.
     virtual void EndRuby() = 0;
@@ -247,7 +247,8 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const String& rName, bool bPapFmt,
-            USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId ) = 0;
+            USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId,
+            bool bAutoUpdate ) = 0;
 
     /// End of a style in the styles table.
     virtual void EndStyle() = 0;
@@ -306,7 +307,7 @@ public:
 
     /// Start of the abstract numbering definition instance.
     virtual void StartAbstractNumbering( USHORT /*nId*/ ) {}
-    
+
     /// End of the abstract numbering definition instance.
     virtual void EndAbstractNumbering() {}
 
@@ -323,7 +324,7 @@ public:
         sal_Int16 nFirstLineIndex,
         sal_Int16 nListTabPos,
         const String &rNumberingString ) = 0;
-    
+
 protected:
 
     void GetNumberPara( String& rStr, const SwField& rFld );
@@ -528,7 +529,7 @@ protected:
 
     /// Sfx item RES_COL
     void FormatColumns( const SwFmtCol& );
-    
+
     virtual void FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol, bool bEven, SwTwips nPageSize ) = 0;
 
     /// Sfx item RES_KEEP
@@ -545,10 +546,10 @@ protected:
 
     /// Write the expanded field
     virtual void WriteExpand( const SwField* pFld ) = 0;
-    
+
     virtual void RefField( const SwField& rFld, const String& rRef ) = 0;
     virtual void HiddenField( const SwField& rFld ) = 0;
-    virtual void SetField( const SwField& rFld, ww::eField eType, const String& rCmd ) = 0; 
+    virtual void SetField( const SwField& rFld, ww::eField eType, const String& rCmd ) = 0;
     virtual void PostitField( const SwField* pFld ) = 0;
     virtual bool DropdownField( const SwField* pFld ) = 0;
 
@@ -573,9 +574,9 @@ public:
     void OutputFlyFrame( const sw::Frame& rFmt );
 
     void GetTablePageSize
-    ( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, 
+    ( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner,
       sal_uInt32& rPageSize, bool& rRelBoxSize );
-    
+
 };
 
 #endif // _ATTRIBUTEOUTPUTBASE_HXX_
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 4637f0d..18f8712 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2000, 2010 Oracle and/or its affiliates.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -31,6 +31,13 @@
 #include "writerwordglue.hxx"
 #include "wrtww8.hxx"
 #include "ww8par.hxx"
+#include "fmtcntnt.hxx"
+#include "fmtsrnd.hxx"
+#include "fchrfmt.hxx"
+#include "tgrditem.hxx"
+#include "fmtruby.hxx"
+#include "charfmt.hxx"
+#include "breakit.hxx"
 
 #include <oox/core/tokens.hxx>
 #include <oox/export/drawingml.hxx>
@@ -193,7 +200,7 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
 
     // no section break in this paragraph yet; can be set in SectionBreak()
     m_pSectionInfo = NULL;
-    
+
     m_bParagraphOpened = true;
 }
 
@@ -207,6 +214,25 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
     FinishTableRowCell( pTextNodeInfoInner );
 
     m_bParagraphOpened = false;
+
+    // Write the anchored frame if any
+    if ( m_pParentFrame )
+    {
+        const SwFrmFmt& rFrmFmt = m_pParentFrame->GetFrmFmt( );
+        const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
+
+        ULONG nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
+        ULONG nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
+
+        m_rExport.SaveData( nStt, nEnd );
+
+        m_rExport.mpParentFrame = m_pParentFrame;
+        m_pParentFrame = NULL;
+
+        m_rExport.WriteText( );
+
+        m_rExport.RestoreData();
+    }
 }
 
 void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool bForceEmptyParagraph )
@@ -223,7 +249,7 @@ void DocxAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointe
         if ( pInner->isEndOfCell() )
         {
             if ( bForceEmptyParagraph )
-                m_pSerializer->singleElementNS( XML_w, XML_p, FSEND ); 
+                m_pSerializer->singleElementNS( XML_w, XML_p, FSEND );
 
             EndTableCell();
         }
@@ -286,6 +312,14 @@ void DocxAttributeOutput::InitCollectedParagraphProperties()
 
 void DocxAttributeOutput::WriteCollectedParagraphProperties()
 {
+    if ( m_pFlyAttrList )
+    {
+        XFastAttributeListRef xAttrList( m_pFlyAttrList );
+        m_pFlyAttrList = NULL;
+
+        m_pSerializer->singleElementNS( XML_w, XML_framePr, xAttrList );
+    }
+
     if ( m_pSpacingAttrList )
     {
         XFastAttributeListRef xAttrList( m_pSpacingAttrList );
@@ -300,7 +334,7 @@ void DocxAttributeOutput::EndParagraphProperties()
     WriteCollectedParagraphProperties();
 
     m_pSerializer->endElementNS( XML_w, XML_pPr );
-            
+
     if ( m_nColBreakStatus == COLBRK_WRITE )
     {
         m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
@@ -382,7 +416,7 @@ void DocxAttributeOutput::EndRun()
             }
         }
     }
-   
+
     DoWriteBookmarks( );
 
     m_pSerializer->startElementNS( XML_w, XML_r, FSEND );
@@ -423,12 +457,12 @@ void DocxAttributeOutput::DoWriteBookmarks()
         m_rOpenedMarksIds[rName] = nId;
         m_pSerializer->singleElementNS( XML_w, XML_bookmarkStart,
             FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr(  ),
-            FSNS( XML_w, XML_name ), rName.getStr(), 
+            FSNS( XML_w, XML_name ), rName.getStr(),
             FSEND );
     }
     m_rMarksStart.clear();
 
-    // export the end bookmarks 
+    // export the end bookmarks
     for ( std::vector< OString >::const_iterator it = m_rMarksEnd.begin(), end = m_rMarksEnd.end();
           it < end; ++it )
     {
@@ -440,7 +474,7 @@ void DocxAttributeOutput::DoWriteBookmarks()
         {
             USHORT nId = ( *pPos ).second;
             m_pSerializer->singleElementNS( XML_w, XML_bookmarkEnd,
-                FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr(  ), 
+                FSNS( XML_w, XML_id ), OString::valueOf( sal_Int32( nId ) ).getStr(  ),
                 FSEND );
             m_rOpenedMarksIds.erase( rName );
         }
@@ -475,7 +509,7 @@ void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRu
                            rFld2.GetSelectedItem(), aItems);
 
                 m_pSerializer->endElementNS( XML_w, XML_fldChar );
-        
+
                 if ( bWriteRun )
                     m_pSerializer->endElementNS( XML_w, XML_r );
 
@@ -490,7 +524,7 @@ void DocxAttributeOutput::StartField_Impl( FieldInfos& rInfos, sal_Bool bWriteRu
             if ( bWriteRun )
                 m_pSerializer->endElementNS( XML_w, XML_r );
 
-            // The hyperlinks fields can't be expanded: the value is 
+            // The hyperlinks fields can't be expanded: the value is
             // normally in the text run
             if ( !rInfos.pField )
                 CmdField_Impl( rInfos );
@@ -522,7 +556,7 @@ void DocxAttributeOutput::CmdField_Impl( FieldInfos& rInfos )
         if ( i < ( nNbToken - 1 ) )
             RunText( String::CreateFromAscii( "\t" ) );
     }
-    
+
     m_pSerializer->endElementNS( XML_w, XML_r );
 
 
@@ -587,7 +621,7 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
         USHORT nSubType = rInfos.pField->GetSubType( );
         bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == RES_SETEXPFLD;
         bool bShowRef = ( !bIsSetField || ( nSubType & nsSwExtendedSubType::SUB_INVISIBLE ) ) ? false : true;
-    
+
         if ( ( m_sFieldBkm.Len( ) > 0 ) && bShowRef )
         {
             // Write the field beginning
@@ -596,15 +630,15 @@ void DocxAttributeOutput::EndField_Impl( FieldInfos& rInfos )
                 FSNS( XML_w, XML_fldCharType ), "begin",
                 FSEND );
             m_pSerializer->endElementNS( XML_w, XML_r );
-    
+
             rInfos.sCmd = FieldString( ww::eREF );
             rInfos.sCmd.APPEND_CONST_ASC( "\"" );
             rInfos.sCmd += m_sFieldBkm;
             rInfos.sCmd.APPEND_CONST_ASC( "\" " );
-    
+
             // Clean the field bookmark data to avoid infinite loop
             m_sFieldBkm = String( );
-    
+
             // Write the end of the field
             EndField_Impl( rInfos );
         }
@@ -745,14 +779,75 @@ void DocxAttributeOutput::RawText( const String& /*rText*/, bool /*bForceUnicode
     OSL_TRACE("TODO DocxAttributeOutput::RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet )\n" );
 }
 
-void DocxAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ )
+void DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, const SwFmtRuby& rRuby )
 {
     OSL_TRACE("TODO DocxAttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )\n" );
+    m_pSerializer->startElementNS( XML_w, XML_ruby, FSEND );
+    m_pSerializer->startElementNS( XML_w, XML_rubyPr, FSEND );
+    // hps
+    // hpsBaseText
+    // hpsRaise
+    // lid
+    lang::Locale aLocale( SwBreakIt::Get()->GetLocale(
+                rNode.GetLang( nPos ) ) );
+    OUString sLang( aLocale.Language );
+    if ( aLocale.Country.getLength( ) > 0 )
+        sLang += OUString::createFromAscii( "-" ) + OUString( aLocale.Country );
+    m_pSerializer->singleElementNS( XML_w, XML_lid,
+            FSNS( XML_w, XML_val ),
+            OUStringToOString( sLang, RTL_TEXTENCODING_UTF8 ).getStr( ), FSEND );
+
+
+    OString sAlign ( "center" );
+    switch ( rRuby.GetAdjustment( ) )
+    {
+        case 0:
+            sAlign = OString( "left" );
+            break;
+        case 1:
+            // Defaults to center
+            break;
+        case 2:
+            sAlign = OString( "right" );
+            break;
+        case 3:
+            sAlign = OString( "distributeLetter" );
+            break;
+        case 4:
+            sAlign = OString( "distributeSpace" );
+            break;
+        default:
+            break;
+    }
+    m_pSerializer->singleElementNS( XML_w, XML_rubyAlign,
+            FSNS( XML_w, XML_val ), sAlign.getStr(), FSEND );
+    m_pSerializer->endElementNS( XML_w, XML_rubyPr );
+
+    m_pSerializer->startElementNS( XML_w, XML_rt, FSEND );
+    StartRun( NULL );
+    StartRunProperties( );
+    SwAttrIter aAttrIt( m_rExport, rNode );
+    aAttrIt.OutAttr( nPos, true );
+    USHORT nStyle = m_rExport.GetId( *rRuby.GetTxtRuby()->GetCharFmt() );
+    OString aStyleId( "style" );
+    aStyleId += OString::valueOf( sal_Int32( nStyle ) );
+    m_pSerializer->singleElementNS( XML_w, XML_rStyle,
+            FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
+    EndRunProperties( NULL );
+    RunText( rRuby.GetText( ) );
+    EndRun( );
+    m_pSerializer->endElementNS( XML_w, XML_rt );
+
+    m_pSerializer->startElementNS( XML_w, XML_rubyBase, FSEND );
+    StartRun( NULL );
 }
 
 void DocxAttributeOutput::EndRuby()
 {
     OSL_TRACE( "TODO DocxAttributeOutput::EndRuby()\n" );
+    EndRun( );
+    m_pSerializer->endElementNS( XML_w, XML_rubyBase );
+    m_pSerializer->endElementNS( XML_w, XML_ruby );
 }
 
 bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
@@ -764,7 +859,7 @@ bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget,
 
     bool bOutputField = sMark.Len();
 
-    if ( bOutputField ) 
+    if ( bOutputField )
     {
         if ( bBookMarkOnly )
             sURL = FieldString( ww::eHYPERLINK );
@@ -775,10 +870,10 @@ bool DocxAttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget,
             sURL.Insert( sFld, 0 );
             sURL += '\"';
         }
-    
+
         if ( sMark.Len() )
             ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"';
-    
+
         if ( rTarget.Len() )
             ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget;
     }
@@ -796,16 +891,16 @@ bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
 
     bool bBookmarkOnly = AnalyzeURL( rUrl, rTarget, &sUrl, &sMark );
 
-    if ( sMark.Len() && !bBookmarkOnly ) 
+    if ( sMark.Len() && !bBookmarkOnly )
     {
         m_rExport.OutputField( NULL, ww::eHYPERLINK, sUrl );
     }
     else
     {
         // Output a hyperlink XML element
-    
+
         m_pHyperlinkAttrList = m_pSerializer->createAttrList();
-        if ( !bBookmarkOnly ) 
+        if ( !bBookmarkOnly )
         {
             OUString osUrl( sUrl );
 
@@ -815,9 +910,9 @@ bool DocxAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
             m_pHyperlinkAttrList->add( FSNS( XML_r, XML_id), sId.getStr());
         }
         else
-            m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ), 
+            m_pHyperlinkAttrList->add( FSNS( XML_w, XML_anchor ),
                     OUStringToOString( OUString( sMark ), RTL_TEXTENCODING_UTF8 ).getStr( ) );
-    
+
         OUString sTarget( rTarget );
         if ( sTarget.getLength( ) > 0 )
         {
@@ -1071,7 +1166,7 @@ static void impl_pageBorders( FSHelperPtr pSerializer, const SvxBoxItem& rBox )
         BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
     };
 
-    static const USHORT aXmlElements[] = 
+    static const USHORT aXmlElements[] =
     {
         XML_top, XML_left, XML_bottom, XML_right
     };
@@ -1100,13 +1195,13 @@ void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Point
     long vSpan = pTblBox->getRowSpan( );
     if ( vSpan > 1 )
     {
-        m_pSerializer->singleElementNS( XML_w, XML_vMerge, 
+        m_pSerializer->singleElementNS( XML_w, XML_vMerge,
                 FSNS( XML_w, XML_val ), "restart",
                 FSEND );
     }
     else if ( vSpan < 0 )
     {
-        m_pSerializer->singleElementNS( XML_w, XML_vMerge, 
+        m_pSerializer->singleElementNS( XML_w, XML_vMerge,
                 FSNS( XML_w, XML_val ), "continue",
                 FSEND );
     }
@@ -1126,7 +1221,7 @@ void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Point
 
     // Cell prefered width
     SwTwips nWidth = GetGridCols( pTableTextNodeInfoInner )->at( pTableTextNodeInfoInner->getCell() );
-    m_pSerializer->singleElementNS( XML_w, XML_tcW, 
+    m_pSerializer->singleElementNS( XML_w, XML_tcW,
            FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nWidth ) ).getStr( ),
            FSNS( XML_w, XML_type ), "dxa",
            FSEND );
@@ -1139,7 +1234,7 @@ void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Point
         BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
     };
 
-    static const USHORT aXmlElements[] = 
+    static const USHORT aXmlElements[] =
     {
         XML_top, XML_left, XML_bottom, XML_right
     };
@@ -1167,16 +1262,16 @@ void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t
 
     // Create the SwWriteTable instance to use col spans (and maybe other infos)
     GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
-    
+
     const SwTable* pTable = pTableTextNodeInfoInner->getTable( );
     const SwFrmFmt *pFmt = pTable->GetFrmFmt( );
     SwTwips nTblSz = pFmt->GetFrmSize( ).GetWidth( );
-    
+
     const SwHTMLTableLayout *pLayout = pTable->GetHTMLTableLayout();
     if( pLayout && pLayout->IsExportable() )
         m_pTableWrt = new SwWriteTable( pLayout );
     else
-        m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (USHORT)nPageSize, 
+        m_pTableWrt = new SwWriteTable( pTable->GetTabLines(), (USHORT)nPageSize,
                 (USHORT)nTblSz, false);
 }
 
@@ -1209,11 +1304,11 @@ void DocxAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t p
 
     // Output the row properties
     m_pSerializer->startElementNS( XML_w, XML_trPr, FSEND );
-    
+
     // Header row: tblHeader
     const SwTable *pTable = pTableTextNodeInfoInner->getTable( );
     if ( pTable->GetRowsToRepeat( ) > pTableTextNodeInfoInner->getRow( ) )
-        m_pSerializer->singleElementNS( XML_w, XML_tblHeader, 
+        m_pSerializer->singleElementNS( XML_w, XML_tblHeader,
                FSNS( XML_w, XML_val ), "true",
                FSEND );
 
@@ -1264,13 +1359,13 @@ void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t
 
     sal_uInt32 nPageSize = 0;
     bool bRelBoxSize = false;
-    
+
     // Create the SwWriteTable instance to use col spans (and maybe other infos)
     GetTablePageSize( pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize );
-    
+
     // Output the table prefered width
     if ( nPageSize != 0 )
-        m_pSerializer->singleElementNS( XML_w, XML_tblW, 
+        m_pSerializer->singleElementNS( XML_w, XML_tblW,
                 FSNS( XML_w, XML_w ), OString::valueOf( sal_Int32( nPageSize ) ).getStr( ),
                 FSNS( XML_w, XML_type ), "dxa",
                 FSEND );
@@ -1313,11 +1408,11 @@ void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t
                 FSEND );
 
     m_pSerializer->endElementNS( XML_w, XML_tblPr );
-    
+
 
     // Write the table grid infos
     m_pSerializer->startElementNS( XML_w, XML_tblGrid, FSEND );
-    
+
     ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner );
     for ( ww8::GridCols::const_iterator it = pGridCols->begin(); it != pGridCols->end(); ++it )
         m_pSerializer->singleElementNS( XML_w, XML_gridCol,
@@ -1346,7 +1441,7 @@ void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_
 
     Color aColor;
     if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) )
-        aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); 
+        aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor();
     else
         aColor = COL_AUTO;
 
@@ -1359,7 +1454,7 @@ void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_
 void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
 {
     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
-    const SwTableLine * pTabLine = pTabBox->GetUpper();    
+    const SwTableLine * pTabLine = pTabBox->GetUpper();
     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
 
     const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
@@ -1386,7 +1481,7 @@ void DocxAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTa
 void DocxAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
 {
     const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
-    const SwTableLine * pTabLine = pTabBox->GetUpper();    
+    const SwTableLine * pTabLine = pTabBox->GetUpper();
     const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
 
     const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
@@ -1401,7 +1496,7 @@ void DocxAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTabl
 {
     const SwTable * pTable = pTableTextNodeInfoInner->getTable();
     const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
-    
+
     if ( m_rExport.TrueFrameDirection( *pFrmFmt ) == FRMDIR_HORI_RIGHT_TOP )
     {
         m_pSerializer->singleElementNS( XML_w, XML_bidiVisual,
@@ -1693,6 +1788,12 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po
                 }
             }
             break;
+        case sw::Frame::eTxtBox:
+            {
+                // The frame output is postponed at the end of the anchor paragraph
+                m_pParentFrame = &rFrame;
+            }
+            break;
         default:
 #if OSL_DEBUG_LEVEL > 0
             OSL_TRACE( "TODO DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& rNdTopLeft ) - frame type '%s'\n",
@@ -1707,7 +1808,7 @@ void DocxAttributeOutput::OutputFlyFrame_Impl( const sw::Frame &rFrame, const Po
 }
 
 void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
-        USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId )
+        USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId, bool bAutoUpdate )
 {
     OString aStyle( "style" );
 
@@ -1730,6 +1831,9 @@ void DocxAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
     m_pSerializer->singleElementNS( XML_w, XML_next,
             FSNS( XML_w, XML_val ), ( aStyle + OString::valueOf( sal_Int32( nNext ) ) ).getStr(),
             FSEND );
+
+    if ( bAutoUpdate )
+        m_pSerializer->singleElementNS( XML_w, XML_autoRedefine, FSEND );
 }
 
 void DocxAttributeOutput::EndStyle()
@@ -2247,11 +2351,43 @@ void DocxAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
     }
 }
 
-void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& /*rEscapement*/ )
+void DocxAttributeOutput::CharEscapement( const SvxEscapementItem& rEscapement )
 {
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::CharEscapement()\n" );
-#endif
+    OString sIss;
+    short nEsc = rEscapement.GetEsc(), nProp = rEscapement.GetProp();
+    if ( !nEsc )
+    {
+        sIss = OString( "baseline" );
+        nEsc = 0;
+        nProp = 100;
+    }
+    else if ( DFLT_ESC_PROP == nProp )
+    {
+        if ( DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc )
+            sIss = OString( "subscript" );
+        else if ( DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc )
+            sIss = OString( "superscript" );
+    }
+
+    if ( sIss.getLength( ) > 0 )
+        m_pSerializer->singleElementNS( XML_w, XML_vertAlign,
+           FSNS( XML_w, XML_val ), sIss.getStr(), FSEND );
+
+    if ( sIss.getLength() == 0 || sIss.match( OString( "baseline" ) ) )
+    {
+        long nHeight = ((SvxFontHeightItem&)m_rExport.GetItem(
+                                    RES_CHRATR_FONTSIZE )).GetHeight();
+        OString sPos = OString::valueOf( ( nHeight * nEsc + 500 ) / 1000 );
+        m_pSerializer->singleElementNS( XML_w, XML_position,
+                FSNS( XML_w, XML_val ), sPos.getStr( ), FSEND );
+
+        if( 100 != nProp || sIss.match( OString( "baseline" ) ) )
+        {
+            OString sSize = OString::valueOf( ( nHeight * nProp + 500 ) / 1000 );
+                m_pSerializer->singleElementNS( XML_w, XML_sz,
+                    FSNS( XML_w, XML_val ), sSize.getStr( ), FSEND );
+        }
+    }
 }
 
 void DocxAttributeOutput::CharFont( const SvxFontItem& rFont)
@@ -2283,7 +2419,7 @@ void DocxAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
 void DocxAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
 {
     OString aKerning = OString::valueOf( ( sal_Int32 ) rKerning.GetValue() );
-    m_pSerializer->singleElementNS( XML_w, XML_kern, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
+    m_pSerializer->singleElementNS( XML_w, XML_spacing, FSNS(XML_w, XML_val), aKerning.getStr(), FSEND );
 }
 
 void DocxAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
@@ -2536,11 +2672,12 @@ void DocxAttributeOutput::TextINetFormat( const SwFmtINetFmt& rLink )
     m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
 }
 
-void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& )
+void DocxAttributeOutput::TextCharFormat( const SwFmtCharFmt& rCharFmt )
 {
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::TextCharFormat()\n" );
-#endif
+    OString aStyleId( "style" );
+    aStyleId += OString::valueOf( sal_Int32( m_rExport.GetId( *rCharFmt.GetCharFmt() ) ) );
+
+    m_pSerializer->singleElementNS( XML_w, XML_rStyle, FSNS( XML_w, XML_val ), aStyleId.getStr(), FSEND );
 }
 
 void DocxAttributeOutput::RefField( const SwField&  rFld, const String& rRef )
@@ -2612,7 +2749,7 @@ void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType
     {
         USHORT nType = pFld->GetTyp( )->Which( );
         USHORT nSubType = pFld->GetSubType();
-    
+
         // TODO Any other field types here ?
         if ( ( nType == RES_SETEXPFLD ) && ( nSubType & nsSwGetSetExpType::GSE_STRING ) )
         {
@@ -2627,7 +2764,7 @@ void DocxAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField eType
     }
 }
 
-void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts, 
+void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
         std::vector< OUString >& rEnds )
 {
     for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it )
@@ -2636,7 +2773,7 @@ void DocxAttributeOutput::WriteBookmarks_Impl( std::vector< OUString >& rStarts,
         m_rMarksStart.push_back( rName );
     }
     rStarts.clear();
-    
+
     for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it )
     {
         OString rName = OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr( );
@@ -2863,13 +3000,13 @@ void DocxAttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStop )
 {
     const SfxPoolItem* pLR = m_rExport.HasItem( RES_LR_SPACE );
     long nCurrentLeft = pLR ? ((const SvxLRSpaceItem*)pLR)->GetTxtLeft() : 0;
-    
+
     m_pSerializer->startElementNS( XML_w, XML_tabs, FSEND );
 
     sal_uInt16 nCount = rTabStop.Count();
     for (sal_uInt16 i = 0; i < nCount; i++ )
         impl_WriteTabElement( m_pSerializer, rTabStop[i], nCurrentLeft );
-    
+
     m_pSerializer->endElementNS( XML_w, XML_tabs );
 }
 
@@ -2954,11 +3091,24 @@ void DocxAttributeOutput::FormatFrameSize( const SwFmtFrmSize& rSize )
 {
     if ( m_rExport.bOutFlyFrmAttrs )
     {
- #if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatFrameSize() - Fly frames\n" );
- #endif
+        if ( !m_pFlyAttrList )
+            m_pFlyAttrList = m_pSerializer->createAttrList( );
+
+        if ( rSize.GetWidth() && rSize.GetWidthSizeType() == ATT_FIX_SIZE )
+        {
+            m_pFlyAttrList->add( FSNS( XML_w, XML_w ), OString::valueOf( rSize.GetWidth( ) ) );
+        }
+
+        if ( rSize.GetHeight() )
+        {
+            OString sRule( "exact" );
+            if ( rSize.GetHeightSizeType() == ATT_MIN_SIZE )
+                sRule = OString( "atLeast" );
+            m_pFlyAttrList->add( FSNS( XML_w, XML_hRule ), sRule );
+            m_pFlyAttrList->add( FSNS( XML_w, XML_h ), OString::valueOf( rSize.GetHeight( ) ) );
+        }
     }
-    else if ( m_rExport.bOutPageDescs ) 
+    else if ( m_rExport.bOutPageDescs )
     {
         FastAttributeList *attrList = m_pSerializer->createAttrList( );
         if ( m_rExport.pAktPageDesc->GetLandscape( ) )
@@ -2986,11 +3136,14 @@ void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
 {
     if ( m_rExport.bOutFlyFrmAttrs )
     {
-#if OSL_DEBUG_LEVEL > 0
-        OSL_TRACE( "DocxAttributeOutput::FormatLRSpace() - Fly frames\n" );
-#endif
+        if ( !m_pFlyAttrList )
+            m_pFlyAttrList = m_pSerializer->createAttrList();
+
+        m_pFlyAttrList->add( FSNS( XML_w, XML_hSpace ),
+                OString::valueOf(
+                    sal_Int32( ( rLRSpace.GetLeft() + rLRSpace.GetRight() ) / 2 ) ) );
     }
-    else if ( m_rExport.bOutPageDescs ) 
+    else if ( m_rExport.bOutPageDescs )
     {
         if ( !m_pSpacingAttrList )
             m_pSpacingAttrList = m_pSerializer->createAttrList();
@@ -3029,12 +3182,18 @@ void DocxAttributeOutput::FormatLRSpace( const SvxLRSpaceItem& rLRSpace )
 
 void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
 {
-    if (!m_pSpacingAttrList)
+    if ( !m_pSpacingAttrList && !m_rExport.bOutFlyFrmAttrs )
         m_pSpacingAttrList = m_pSerializer->createAttrList();
 
     if ( m_rExport.bOutFlyFrmAttrs )
     {
-    } 
+        if ( !m_pFlyAttrList )
+            m_pFlyAttrList = m_pSerializer->createAttrList();
+
+        m_pFlyAttrList->add( FSNS( XML_w, XML_vSpace ),
+                OString::valueOf(
+                    sal_Int32( ( rULSpace.GetLower() + rULSpace.GetUpper() ) / 2 ) ) );
+    }
     else if (m_rExport.bOutPageDescs )
     {
         ASSERT( m_rExport.GetCurItemSet(), "Impossible" );
@@ -3046,61 +3205,179 @@ void DocxAttributeOutput::FormatULSpace( const SvxULSpaceItem& rULSpace )
         if ( aDistances.HasHeader() )
         {
             // Header top
-            m_pSpacingAttrList->add( FSNS( XML_w, XML_header ), 
+            m_pSpacingAttrList->add( FSNS( XML_w, XML_header ),
                     OString::valueOf( sal_Int32( aDistances.dyaHdrTop ) ) );
         }
 
         // Page top
-        m_pSpacingAttrList->add( FSNS( XML_w, XML_top ), 
+        m_pSpacingAttrList->add( FSNS( XML_w, XML_top ),
                 OString::valueOf( sal_Int32( aDistances.dyaTop ) ) );
 
         if ( aDistances.HasFooter() )
         {
             // Footer bottom
-            m_pSpacingAttrList->add( FSNS( XML_w, XML_footer ), 
+            m_pSpacingAttrList->add( FSNS( XML_w, XML_footer ),
                     OString::valueOf( sal_Int32( aDistances.dyaHdrBottom ) ) );
         }
 
         // Page Bottom
-        m_pSpacingAttrList->add( FSNS( XML_w, XML_bottom ), 
+        m_pSpacingAttrList->add( FSNS( XML_w, XML_bottom ),
                 OString::valueOf( sal_Int32( aDistances.dyaBottom ) ) );
-        
+
     }
     else
     {
-        m_pSpacingAttrList->add( FSNS( XML_w, XML_before ), 
+        m_pSpacingAttrList->add( FSNS( XML_w, XML_before ),
                 OString::valueOf( (sal_Int32)rULSpace.GetUpper() ) );
-        m_pSpacingAttrList->add( FSNS( XML_w, XML_after ), 
+        m_pSpacingAttrList->add( FSNS( XML_w, XML_after ),
                 OString::valueOf( (sal_Int32)rULSpace.GetLower() ) );
     }
 }
 
-void DocxAttributeOutput::FormatSurround( const SwFmtSurround& )
+void DocxAttributeOutput::FormatSurround( const SwFmtSurround& rSurround )
 {
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatSurround()\n" );
-#endif
+    if ( m_rExport.bOutFlyFrmAttrs )
+    {
+        if ( !m_pFlyAttrList )
+            m_pFlyAttrList = m_pSerializer->createAttrList();
+
+        OString sWrap( "auto" );
+        switch ( rSurround.GetSurround( ) )
+        {
+            case SURROUND_NONE:
+                sWrap = OString( "none" );
+                break;
+            case SURROUND_THROUGHT:
+                sWrap = OString( "through" );
+                break;
+            case SURROUND_IDEAL:
+            case SURROUND_PARALLEL:
+            case SURROUND_LEFT:
+            case SURROUND_RIGHT:
+            default:
+                sWrap = OString( "around" );
+        }
+
+        m_pFlyAttrList->add( FSNS( XML_w, XML_wrap ), sWrap );
+    }
 }
 
-void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& )
+void DocxAttributeOutput::FormatVertOrientation( const SwFmtVertOrient& rFlyVert )
 {
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatVertOrientation()\n" );
-#endif
+    if ( m_rExport.bOutFlyFrmAttrs )
+    {
+        if ( !m_pFlyAttrList )
+            m_pFlyAttrList = m_pSerializer->createAttrList();
+
+        OString sAlign;
+        switch( rFlyVert.GetVertOrient() )
+        {
+            case text::VertOrientation::NONE:
+                break;
+            case text::VertOrientation::CENTER:
+            case text::VertOrientation::LINE_CENTER:
+                sAlign = OString( "center" );
+                break;
+            case text::VertOrientation::BOTTOM:
+            case text::VertOrientation::LINE_BOTTOM:
+                sAlign = OString( "bottom" );
+                break;
+            case text::VertOrientation::TOP:
+            case text::VertOrientation::LINE_TOP:
+            default:
+                sAlign = OString( "top" );
+                break;
+        }
+
+        if ( sAlign.getLength() > 0 )
+            m_pFlyAttrList->add( FSNS( XML_w, XML_yAlign ), sAlign );
+        else
+            m_pFlyAttrList->add( FSNS( XML_w, XML_y ),
+                OString::valueOf( sal_Int32( rFlyVert.GetPos() ) ) );
+
+        OString sVAnchor( "page" );
+        switch ( rFlyVert.GetRelationOrient( ) )
+        {
+            case text::RelOrientation::CHAR:
+            case text::RelOrientation::PRINT_AREA:
+            case text::RelOrientation::TEXT_LINE:
+                sVAnchor = OString( "column" );
+                break;
+            case text::RelOrientation::FRAME:
+            case text::RelOrientation::PAGE_LEFT:
+            case text::RelOrientation::PAGE_RIGHT:
+            case text::RelOrientation::FRAME_LEFT:
+            case text::RelOrientation::FRAME_RIGHT:
+                sVAnchor = OString( "margin" );
+                break;
+            case text::RelOrientation::PAGE_FRAME:
+            case text::RelOrientation::PAGE_PRINT_AREA:
+            default:
+                break;
+        }
+
+        m_pFlyAttrList->add( FSNS( XML_w, XML_vAnchor ), sVAnchor );
+    }
 }
 
-void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& )
+void DocxAttributeOutput::FormatHorizOrientation( const SwFmtHoriOrient& rFlyHori )
 {
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatHorizOrientation()\n" );
-#endif
+    if ( m_rExport.bOutFlyFrmAttrs )
+    {
+        if ( !m_pFlyAttrList )
+            m_pFlyAttrList = m_pSerializer->createAttrList();
+
+        OString sAlign;
+        switch( rFlyHori.GetHoriOrient() )
+        {
+            case text::HoriOrientation::NONE:
+                break;
+            case text::HoriOrientation::LEFT:
+                sAlign = OString( rFlyHori.IsPosToggle( ) ? "inside" : "left" );
+                break;
+            case text::HoriOrientation::RIGHT:
+                sAlign = OString( rFlyHori.IsPosToggle( ) ? "outside" : "right" );
+                break;
+            case text::HoriOrientation::CENTER:
+            case text::HoriOrientation::FULL: // FULL only for tables
+            default:
+                sAlign = OString( "center" );
+                break;
+        }
+
+        if ( sAlign.getLength() > 0 )
+            m_pFlyAttrList->add( FSNS( XML_w, XML_xAlign ), sAlign );
+        else
+            m_pFlyAttrList->add( FSNS( XML_w, XML_x ),
+                OString::valueOf( sal_Int32( rFlyHori.GetPos() ) ) );
+
+        OString sHAnchor( "page" );
+        switch ( rFlyHori.GetRelationOrient( ) )
+        {
+            case text::RelOrientation::CHAR:
+            case text::RelOrientation::PRINT_AREA:
+                sHAnchor = OString( "text" );
+                break;
+            case text::RelOrientation::FRAME:
+            case text::RelOrientation::PAGE_LEFT:
+            case text::RelOrientation::PAGE_RIGHT:
+            case text::RelOrientation::FRAME_LEFT:
+            case text::RelOrientation::FRAME_RIGHT:
+                sHAnchor = OString( "margin" );
+                break;
+            case text::RelOrientation::PAGE_FRAME:
+            case text::RelOrientation::PAGE_PRINT_AREA:
+            default:
+                break;
+        }
+
+        m_pFlyAttrList->add( FSNS( XML_w, XML_hAnchor ), sHAnchor );
+    }
 }
 
 void DocxAttributeOutput::FormatAnchor( const SwFmtAnchor& )
 {
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatAnchor()\n" );
-#endif
+    // Fly frames: anchors here aren't matching the anchors in docx
 }
 
 void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
@@ -3112,10 +3389,6 @@ void DocxAttributeOutput::FormatBackground( const SvxBrushItem& rBrush )
                 FSNS( XML_w, XML_fill ), sColor.getStr( ),
                 FSEND );
     }
-
-#if OSL_DEBUG_LEVEL > 0
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatBackground()\n" );
-#endif
 }
 
 void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
@@ -3147,7 +3420,7 @@ void DocxAttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol& rCol
     // Get the columns attributes
     FastAttributeList *pColsAttrList = m_pSerializer->createAttrList();
 
-    pColsAttrList->add( FSNS( XML_w, XML_num ), 
+    pColsAttrList->add( FSNS( XML_w, XML_num ),
             OString::valueOf( sal_Int32( nCols ) ). getStr( ) );
 
     const char* pEquals = "false";
@@ -3198,9 +3471,52 @@ void DocxAttributeOutput::FormatKeep( const SvxFmtKeepItem& )
     m_pSerializer->singleElementNS( XML_w, XML_keepNext, FSEND );
 }
 
-void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& )
+void DocxAttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
 {
-    OSL_TRACE( "TODO DocxAttributeOutput::FormatTextGrid()\n" );
+    FastAttributeList *pGridAttrList = m_pSerializer->createAttrList();
+
+    OString sGridType;
+    switch ( rGrid.GetGridType( ) )
+    {
+        default:
+        case GRID_NONE:
+            sGridType = OString( "default" );
+            break;
+        case GRID_LINES_ONLY:
+            sGridType = OString( "lines" );
+            break;
+        case GRID_LINES_CHARS:
+            if ( rGrid.IsSnapToChars( ) )
+                sGridType = OString( "snapToChars" );
+            else
+                sGridType = OString( "linesAndChars" );
+            break;
+    }
+    pGridAttrList->add( FSNS( XML_w, XML_type ), sGridType.getStr( ) );
+
+    UINT16 nHeight = rGrid.GetBaseHeight() + rGrid.GetRubyHeight();
+    pGridAttrList->add( FSNS( XML_w, XML_linePitch ),
+            OString::valueOf( sal_Int32( nHeight ) ).getStr( ) );
+
+    MSWordStyles * pStyles = m_rExport.pStyles;
+    SwFmt * pSwFmt = pStyles->GetSwFmt();
+
+    sal_uInt32 nPageCharSize = 0;
+
+    if (pSwFmt != NULL)
+    {
+        nPageCharSize = ItemGet<SvxFontHeightItem>
+        (*pSwFmt, RES_CHRATR_FONTSIZE).GetHeight();
+    }
+
+    sal_uInt16 nPitch = rGrid.IsSquaredMode() ? rGrid.GetBaseHeight() :
+        rGrid.GetBaseWidth( );
+    INT32 nCharSpace = ( nPitch - nPageCharSize ) * 4096 / 20;
+
+    pGridAttrList->add( FSNS( XML_w, XML_charSpace ),
+            OString::valueOf( sal_Int32( nCharSpace ) ).getStr( ) );
+
+    m_pSerializer->singleElementNS( XML_w, XML_docGrid, pGridAttrList );
 }
 
 void DocxAttributeOutput::FormatLineNumbering( const SwFmtLineNumber& rNumbering )
@@ -3240,12 +3556,12 @@ void DocxAttributeOutput::FormatFrameDirection( const SvxFrameDirectionItem& rDi
                FSNS( XML_w, XML_val ), sTextFlow.getStr( ),
                FSEND );
         if ( bBiDi )
-            m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); 
+            m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
     }
     else if ( !m_rExport.bOutFlyFrmAttrs )
     {
         if ( bBiDi )
-            m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND ); 
+            m_pSerializer->singleElementNS( XML_w, XML_bidi, FSEND );
     }
 }
 
@@ -3258,6 +3574,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
       m_pCharLangAttrList( NULL ),
       m_pSpacingAttrList( NULL ),
       m_pHyperlinkAttrList( NULL ),
+      m_pFlyAttrList( NULL ),
       m_pFootnotesList( new ::docx::FootnotesList() ),
       m_pEndnotesList( new ::docx::FootnotesList() ),
       m_pSectionInfo( NULL ),
@@ -3270,7 +3587,8 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
       m_bTableCellOpen( false ),
       m_nTableDepth( 0 ),
       m_bParagraphOpened( false ),
-      m_nColBreakStatus( COLBRK_NONE )
+      m_nColBreakStatus( COLBRK_NONE ),
+      m_pParentFrame( NULL )
 {
 }
 
@@ -3281,11 +3599,13 @@ DocxAttributeOutput::~DocxAttributeOutput()
     delete m_pCharLangAttrList, m_pCharLangAttrList = NULL;
     delete m_pSpacingAttrList, m_pSpacingAttrList = NULL;
     delete m_pHyperlinkAttrList, m_pHyperlinkAttrList = NULL;
+    delete m_pFlyAttrList, m_pFlyAttrList = NULL;
 
     delete m_pFootnotesList, m_pFootnotesList = NULL;
     delete m_pEndnotesList, m_pEndnotesList = NULL;
 
     delete m_pTableWrt, m_pTableWrt = NULL;
+    m_pParentFrame = NULL;
 }
 
 MSWordExportBase& DocxAttributeOutput::GetExport()
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 2e94069..2625d6d 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -102,7 +102,7 @@ public:
     virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet );
 
     /// Output ruby start.
-    virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby );
+    virtual void StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, const SwFmtRuby& rRuby );
 
     /// Output ruby end.
     virtual void EndRuby();
@@ -175,7 +175,8 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const String& rName, bool bPapFmt,
-            USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId );
+            USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId,
+            bool bAutoUpdate );
 
     /// End of a style in the styles table.
     virtual void EndStyle();
@@ -541,6 +542,7 @@ private:
     ::sax_fastparser::FastAttributeList *m_pCharLangAttrList;
     ::sax_fastparser::FastAttributeList *m_pSpacingAttrList;
     ::sax_fastparser::FastAttributeList *m_pHyperlinkAttrList;
+    ::sax_fastparser::FastAttributeList *m_pFlyAttrList;
 
     ::docx::FootnotesList *m_pFootnotesList;
     ::docx::FootnotesList *m_pEndnotesList;
@@ -583,6 +585,8 @@ private:
     // beginning of the next paragraph
     DocxColBreakStatus m_nColBreakStatus;
 
+    const sw::Frame *m_pParentFrame;
+
 public:
     DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML );
 
diff --git a/sw/source/filter/ww8/makefile.mk b/sw/source/filter/ww8/makefile.mk
index f3638e2..1ca992f 100644
--- a/sw/source/filter/ww8/makefile.mk
+++ b/sw/source/filter/ww8/makefile.mk
@@ -58,6 +58,7 @@ EXCEPTIONSFILES = \
         $(SLO)$/wrtw8num.obj \
         $(SLO)$/wrtw8sty.obj \
         $(SLO)$/wrtww8.obj \
+        $(SLO)$/docxattributeoutput.obj \
         $(SLO)$/docxexportfilter.obj \
         $(SLO)$/ww8atr.obj \
         $(SLO)$/ww8par.obj \
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index c5ac3b1..ae0275f 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -435,7 +435,7 @@ void RtfAttributeOutput::RawText( const String& rText, bool /*bForceUnicode*/, r
     m_aRunText.append(m_rExport.OutString(rText, eCharSet));
 }
 
-void RtfAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, const SwFmtRuby& /*rRuby*/ )
+void RtfAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, xub_StrLen /*nPos*/, const SwFmtRuby& /*rRuby*/ )
 {
     OSL_TRACE("TODO: %s", OSL_THIS_FUNC);
 }
@@ -1000,7 +1000,7 @@ void RtfAttributeOutput::DefaultStyle( USHORT /*nStyle*/ )
 }
 
 void RtfAttributeOutput::StartStyle( const String& rName, bool bPapFmt,
-        USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId )
+        USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId, bool /*bAutoUpdate*/ )
 {
     OSL_TRACE("%s, rName = '%s'", OSL_THIS_FUNC,
             OUStringToOString( OUString( rName ), m_rExport.eCurrentEncoding ).getStr());
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 8a4d0e7..cdbc6c6 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -89,7 +89,7 @@ public:
     virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet );
 
     /// Output ruby start.
-    virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby );
+    virtual void StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, const SwFmtRuby& rRuby );
 
     /// Output ruby end.
     virtual void EndRuby();
@@ -151,7 +151,8 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const String& rName, bool bPapFmt,
-            USHORT nBase, USHORT nNext, USHORT nWwId, USHORT nId );
+            USHORT nBase, USHORT nNext, USHORT nWwIdi, USHORT nId,
+            bool bAutoUpdate );
 
     /// End of a style in the styles table.
     virtual void EndStyle();
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 5d8f5e2..37ac58e 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -168,76 +168,6 @@ MSWordAttrIter::~MSWordAttrIter()
     m_rExport.pChpIter = pOld;
 }
 
-// Die Klasse SwAttrIter ist eine Hilfe zum Aufbauen der Fkp.chpx.
-// Dabei werden nur Zeichen-Attribute beachtet; Absatz-Attribute brauchen
-// diese Behandlung nicht.
-// Die Absatz- und Textattribute des Writers kommen rein, und es wird
-// mit Where() die naechste Position geliefert, an der sich die Attribute
-// aendern. IsTxtAtr() sagt, ob sich an der mit Where() gelieferten Position
-// ein Attribut ohne Ende und mit \xff im Text befindet.
-// Mit OutAttr() werden die Attribute an der angegebenen SwPos
-// ausgegeben.
-
-class SwAttrIter : public MSWordAttrIter
-{
-private:
-    const SwTxtNode& rNd;
-
-    CharRuns maCharRuns;
-    cCharRunIter maCharRunIter;
-
-    rtl_TextEncoding meChrSet;
-    sal_uInt16 mnScript;
-    bool mbCharIsRTL;
-
-    const SwRedline* pCurRedline;
-    xub_StrLen nAktSwPos;
-    USHORT nCurRedlinePos;
-
-    bool mbParaIsRTL;
-
-    const SwFmtDrop &mrSwFmtDrop;
-
-    sw::Frames maFlyFrms;     // #i2916#
-    sw::FrameIter maFlyIter;
-
-    xub_StrLen SearchNext( xub_StrLen nStartPos );
-    void FieldVanish( const String& rTxt );
-
-    void OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool bStart);
-
-    void IterToCurrent();
-
-    //No copying
-    SwAttrIter(const SwAttrIter&);
-    SwAttrIter& operator=(const SwAttrIter&);
-public:
-    SwAttrIter( MSWordExportBase& rWr, const SwTxtNode& rNd );
-
-    bool IsTxtAttr( xub_StrLen nSwPos );
-    bool IsRedlineAtEnd( xub_StrLen nPos ) const;
-    bool IsDropCap( int nSwPos );
-    bool RequiresImplicitBookmark();
-
-    void NextPos() { nAktSwPos = SearchNext( nAktSwPos + 1 ); }
-
-    void OutAttr( xub_StrLen nSwPos );
-    virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const;
-    virtual const SfxPoolItem& GetItem( USHORT nWhich ) const;
-    int OutAttrWithRange(xub_StrLen nPos);
-    const SwRedlineData* GetRedline( xub_StrLen nPos );
-    void OutFlys(xub_StrLen nSwPos);
-
-    xub_StrLen WhereNext() const    { return nAktSwPos; }
-    sal_uInt16 GetScript() const { return mnScript; }
-    bool IsCharRTL() const { return mbCharIsRTL; }
-    bool IsParaRTL() const { return mbParaIsRTL; }
-    rtl_TextEncoding GetCharSet() const { return meChrSet; }
-    String GetSnippet(const String &rStr, xub_StrLen nAktPos,
-        xub_StrLen nLen) const;
-    const SwFmtDrop& GetSwFmtDrop() const { return mrSwFmtDrop; }
-};
-
 class sortswflys :
     public std::binary_function<const sw::Frame&, const sw::Frame&, bool>
 {
@@ -456,7 +386,14 @@ xub_StrLen SwAttrIter::SearchNext( xub_StrLen nStartPos )
     return nMinPos;
 }
 
-void SwAttrIter::OutAttr( xub_StrLen nSwPos )
+bool lcl_isFontsizeItem( const SfxPoolItem& rItem )
+{
+    return ( rItem.Which( ) == RES_CHRATR_FONTSIZE ||
+            rItem.Which( ) == RES_CHRATR_CJK_FONTSIZE ||
+            rItem.Which( ) == RES_CHRATR_CTL_FONTSIZE );
+}
+
+void SwAttrIter::OutAttr( xub_StrLen nSwPos, bool bRuby )
 {
     m_rExport.AttrOutput().RTLAndCJKState( IsCharRTL(), GetScript() );
 
@@ -544,7 +481,10 @@ void SwAttrIter::OutAttr( xub_StrLen nSwPos )
 
     sw::cPoolItemIter aEnd = aRangeItems.end();
     for ( sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI )
-        aExportItems[aI->first] = aI->second;
+    {
+        if ( !bRuby || !lcl_isFontsizeItem( *aI->second ) )
+            aExportItems[aI->first] = aI->second;
+    }
 
     if ( !aExportItems.empty() )
     {
@@ -697,7 +637,7 @@ const SfxPoolItem& SwAttrIter::GetItem(USHORT nWhich) const
     return pRet ? *pRet : rNd.SwCntntNode::GetAttr(nWhich);
 }
 
-void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )
+void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, xub_StrLen /*nPos*/, const SwFmtRuby& rRuby )
 {
     String aStr( FieldString( ww::eEQ ) );
     aStr.APPEND_CONST_ASC( "\\* jc" );
@@ -1217,7 +1157,7 @@ int SwAttrIter::OutAttrWithRange(xub_StrLen nPos)
                 case RES_TXTATR_CJK_RUBY:
                     if ( nPos == *pHt->GetStart() )
                     {
-                        m_rExport.AttrOutput().StartRuby( rNd, *static_cast< const SwFmtRuby* >( pItem ) );
+                        m_rExport.AttrOutput().StartRuby( rNd, nPos, *static_cast< const SwFmtRuby* >( pItem ) );
                         ++nRet;
                     }
                     if ( 0 != ( pEnd = pHt->GetEnd() ) && nPos == *pEnd )
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index 2a6a204..62d02c0 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2000, 2010 Oracle and/or its affiliates.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -268,7 +268,7 @@ void MSWordStyles::BuildStylesTable()
         pFmt = (SwFmt*)rArr[n];
         pFmtA[ BuildGetSlot( *pFmt ) ] = pFmt;
     }
-    
+
     const SvPtrarr& rArr2 = *m_rExport.pDoc->GetTxtFmtColls();   // dann TxtFmtColls
     // das Default-TextStyle ( 0 ) wird nicht mit ausgegeben !
     for( n = 1; n < rArr2.Count(); n++ )
@@ -300,7 +300,7 @@ void WW8AttributeOutput::EndStyle()
 }
 
 void WW8AttributeOutput::StartStyle( const String& rName, bool bPapFmt, USHORT nWwBase,
-    USHORT nWwNext, USHORT nWwId, USHORT /*nId*/ )
+    USHORT nWwNext, USHORT nWwId, USHORT /*nId*/, bool bAutoUpdate )
 {
     BYTE aWW8_STD[ sizeof( WW8_STD ) ];
     BYTE* pData = aWW8_STD;
@@ -322,12 +322,12 @@ void WW8AttributeOutput::StartStyle( const String& rName, bool bPapFmt, USHORT n
 
     if( m_rWW8Export.bWrtWW8 )
     {
+        nBit16 = bAutoUpdate ? 1 : 0;  // fAutoRedef : 1
+        Set_UInt16( pData, nBit16 );
         //-------- jetzt neu:
         // ab Ver8 gibts zwei Felder mehr:
-        //UINT16    fAutoRedef : 1;    /* auto redefine style when appropriate */
         //UINT16    fHidden : 1;       /* hidden from UI? */
         //UINT16    : 14;              /* unused bits */
-        pData += sizeof( UINT16 );
     }
 
 
@@ -522,12 +522,17 @@ void MSWordStyles::OutputStyle( SwFmt* pFmt, USHORT nPos )
     {
         bool bFmtColl;
         USHORT nBase, nWwNext;
-        
+
         GetStyleData( pFmt, bFmtColl, nBase, nWwNext );
 
-        m_rExport.AttrOutput().StartStyle( pFmt->GetName(), bFmtColl,
-                nBase, nWwNext, GetWWId( *pFmt ), nPos );
-        
+        String aName = pFmt->GetName();
+        if ( aName.EqualsAscii( "Default" ) )
+            aName = String::CreateFromAscii( "Normal" );
+
+        m_rExport.AttrOutput().StartStyle( aName, bFmtColl,
+                nBase, nWwNext, GetWWId( *pFmt ), nPos,
+                pFmt->IsAutoUpdateFmt() );
+
         if ( bFmtColl )
             WriteProperties( pFmt, true, nPos, nBase==0xfff );           // UPX.papx
 
@@ -1148,7 +1153,7 @@ void MSWordSections::SetFooterFlag( BYTE& rHeadFootFlags, const SwFmt& rFmt,
 }
 
 void WW8_WrPlcSepx::OutHeaderFooter( WW8Export& rWrt, bool bHeader,
-                     const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags, 
+                     const SwFmt& rFmt, ULONG& rCpPos, BYTE nHFFlags,
                      BYTE nFlag,  BYTE nBreakCode)
 {
     if ( nFlag & nHFFlags )
@@ -1477,10 +1482,10 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt
         pPd = &const_cast<const SwDoc *>( pDoc )->GetPageDesc( 0 );
 
     pAktPageDesc = pPd;
-    
+
     if ( !pPd )
         return;
-    
+
     bool bOldPg = bOutPageDescs;
     bOutPageDescs = true;
 
@@ -1834,7 +1839,7 @@ void MSWordExportBase::WriteHeaderFooterText( const SwFmt& rFmt, bool bHeader )
         ASSERT( rFt.GetFooterFmt(), "Footer text is not here" );
         pCntnt = &rFt.GetFooterFmt()->GetCntnt();
     }
-    
+
     const SwNodeIndex* pSttIdx = pCntnt->GetCntntIdx();
 
     if ( pSttIdx )
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 3a005a9..94d6505 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1411,6 +1411,75 @@ public:
     rtl_TextEncoding GetNodeCharSet() const     { return eNdChrSet; }
 };
 
+// Die Klasse SwAttrIter ist eine Hilfe zum Aufbauen der Fkp.chpx.
+// Dabei werden nur Zeichen-Attribute beachtet; Absatz-Attribute brauchen
+// diese Behandlung nicht.
+// Die Absatz- und Textattribute des Writers kommen rein, und es wird
+// mit Where() die naechste Position geliefert, an der sich die Attribute
+// aendern. IsTxtAtr() sagt, ob sich an der mit Where() gelieferten Position
+// ein Attribut ohne Ende und mit \xff im Text befindet.
+// Mit OutAttr() werden die Attribute an der angegebenen SwPos
+// ausgegeben.
+class SwAttrIter : public MSWordAttrIter
+{
+private:
+    const SwTxtNode& rNd;
+
+    sw::util::CharRuns maCharRuns;
+    sw::util::cCharRunIter maCharRunIter;
+
+    rtl_TextEncoding meChrSet;
+    sal_uInt16 mnScript;
+    bool mbCharIsRTL;
+
+    const SwRedline* pCurRedline;
+    xub_StrLen nAktSwPos;
+    USHORT nCurRedlinePos;
+
+    bool mbParaIsRTL;
+
+    const SwFmtDrop &mrSwFmtDrop;
+
+    sw::Frames maFlyFrms;     // #i2916#
+    sw::FrameIter maFlyIter;
+
+    xub_StrLen SearchNext( xub_StrLen nStartPos );
+    void FieldVanish( const String& rTxt );
+
+    void OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool bStart);
+
+    void IterToCurrent();
+
+    //No copying
+    SwAttrIter(const SwAttrIter&);
+    SwAttrIter& operator=(const SwAttrIter&);
+public:
+    SwAttrIter( MSWordExportBase& rWr, const SwTxtNode& rNd );
+
+    bool IsTxtAttr( xub_StrLen nSwPos );
+    bool IsRedlineAtEnd( xub_StrLen nPos ) const;
+    bool IsDropCap( int nSwPos );
+    bool RequiresImplicitBookmark();
+
+    void NextPos() { nAktSwPos = SearchNext( nAktSwPos + 1 ); }
+
+    void OutAttr( xub_StrLen nSwPos, bool bRuby = false );
+    virtual const SfxPoolItem* HasTextItem( USHORT nWhich ) const;
+    virtual const SfxPoolItem& GetItem( USHORT nWhich ) const;
+    int OutAttrWithRange(xub_StrLen nPos);
+    const SwRedlineData* GetRedline( xub_StrLen nPos );
+    void OutFlys(xub_StrLen nSwPos);
+
+    xub_StrLen WhereNext() const    { return nAktSwPos; }
+    sal_uInt16 GetScript() const { return mnScript; }
+    bool IsCharRTL() const { return mbCharIsRTL; }
+    bool IsParaRTL() const { return mbParaIsRTL; }
+    rtl_TextEncoding GetCharSet() const { return meChrSet; }
+    String GetSnippet(const String &rStr, xub_StrLen nAktPos,
+        xub_StrLen nLen) const;
+    const SwFmtDrop& GetSwFmtDrop() const { return mrSwFmtDrop; }
+};
+
 /// Class to collect and output the styles table.
 class MSWordStyles
 {
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index cde7c02..040ac16 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2000, 2010 Oracle and/or its affiliates.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -955,11 +955,11 @@ void WW8AttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTe
     m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // delete
 
     if ( pTextNodeInfoInner.get() != NULL )
-    {         
+    {
         if ( pTextNodeInfoInner->isEndOfLine() )
         {
             TableRowEnd( pTextNodeInfoInner->getDepth() );
-            
+
             SVBT16 nSty;
             ShortToSVBT16( 0, nSty );
             m_rWW8Export.pO->Insert( (BYTE*)&nSty, 2, m_rWW8Export.pO->Count() );     // Style #
@@ -1166,7 +1166,7 @@ void WW8AttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern )
         m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsKern );
     else
         m_rWW8Export.pO->Insert( 107, m_rWW8Export.pO->Count() );
-    
+
     m_rWW8Export.InsUInt16( rAutoKern.GetValue() ? 1 : 0 );
 }
 
@@ -2217,12 +2217,12 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
 //                    }
 
                 }
-                
+
 
         if( nsSwTOXElement::TOX_OUTLINELEVEL & pTOX->GetCreateType() )
                   {
             // Take the TOC value of the max level to evaluate to as
-            // the starting point for the \o flag, but reduce it to the 
+            // the starting point for the \o flag, but reduce it to the
             // value of the highest outline level filled by a *standard*
             // Heading 1 - 9 style because \o "Builds a table of
             // contents from paragraphs formatted with built-in heading
@@ -2236,7 +2236,7 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
             // Heading 4
             // output
             // \o 1-2 \tcustom-style,3,Heading 3,4
- 
+
             // Search over all the outline styles used and figure out
             // what is the minimum outline level (if any) filled by a
             // non-standard style for that level, i.e. ignore headline
@@ -2259,20 +2259,20 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
                               nPosOfLowestNonStandardLvl = ::sal::static_int_cast<BYTE>(pColl->GetAssignedOutlineStyleLevel());
                           }
                       }
-  
+
             BYTE nMaxMSAutoEvaluate = nPosOfLowestNonStandardLvl < nTOXLvl ? nPosOfLowestNonStandardLvl : (BYTE)nTOXLvl;
-  
+
             //output \o 1-X where X is the highest normal outline style to be included in the toc
             if ( nMaxMSAutoEvaluate )
               {
             if (nMaxMSAutoEvaluate > WW8ListManager::nMaxLevel)
               nMaxMSAutoEvaluate = WW8ListManager::nMaxLevel;
-  
+
             sStr.APPEND_CONST_ASC( "\\o \"1-" );
             sStr += String::CreateFromInt32( nMaxMSAutoEvaluate );
             sStr.AppendAscii(sEntryEnd);
                       }
-  
+
             //collect up any other styles in the writer TOC which will
             //not already appear in the MS TOC and place then into the
             //\t option
@@ -2396,7 +2396,7 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect )
                 WRITEFIELD_CMD_END );
         }
     }
-        
+
     GetExport( ).bStartTOX = false;
 }
 
@@ -2566,7 +2566,7 @@ void WW8AttributeOutput::SetField( const SwField& rFld, ww::eField eType, const
     GetExport().OutputField(&rFld, eType, rCmd, WRITEFIELD_CLOSE);
 }
 
-void WW8AttributeOutput::PostitField( const SwField* pFld ) 
+void WW8AttributeOutput::PostitField( const SwField* pFld )
 {
     const SwPostItField *pPFld = (const SwPostItField*)pFld;
     m_rWW8Export.pAtn->Append( m_rWW8Export.Fc2Cp( m_rWW8Export.Strm().Tell() ), pPFld );
@@ -2773,12 +2773,12 @@ void AttributeOutputBase::TextField( const SwFmtFld& rField )
                         static String sQuotes('\"');
                         const SwDocInfoField * pDocInfoField =
                         dynamic_cast<const SwDocInfoField *> (pFld);
-                        
+
                         if (pDocInfoField != NULL)
                         {
                             String sFieldname = pDocInfoField->GetCntnt(TRUE);
                             xub_StrLen nIndex = sFieldname.Search(':');
-                            
+
                             if (nIndex != sFieldname.Len())
                                 sFieldname = sFieldname.Copy(nIndex + 1);
 
@@ -3756,7 +3756,7 @@ void WW8AttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
                 if ( rGrid.IsSnapToChars() )
                     nGridType = 3;
                 else
-                    nGridType = 1; 
+                    nGridType = 1;
                 break;
         }
         m_rWW8Export.InsUInt16( NS_sprm::LN_SClm );
@@ -3774,25 +3774,12 @@ void WW8AttributeOutput::FormatTextGrid( const SwTextGridItem& rGrid )
         if (pSwFmt != NULL)
         {
             nPageCharSize = ItemGet<SvxFontHeightItem>
-            (*pSwFmt, RES_CHRATR_CJK_FONTSIZE).GetHeight();
+            (*pSwFmt, RES_CHRATR_FONTSIZE).GetHeight();
         }
+        sal_uInt16 nPitch = rGrid.IsSquaredMode() ? rGrid.GetBaseHeight() :
+            rGrid.GetBaseWidth( );
+        INT32 nCharSpace = ( nPitch - nPageCharSize ) * 4096 / 20;
 
-        INT32 nCharWidth = rGrid.GetBaseWidth() - nPageCharSize;
-        INT32 nFraction = 0;
-        nFraction = nCharWidth % 20;
-        if ( nCharWidth < 0 )
-            nFraction = 20 + nFraction;
-        nFraction = ( nFraction * 0xFFF ) / 20;
-        nFraction = ( nFraction & 0x00000FFF );
-
-        INT32 nMain = 0;
-        nMain = nCharWidth / 20;
-        if ( nCharWidth < 0 )
-            nMain -= 1;
-        nMain = nMain * 0x1000;
-        nMain = ( nMain & 0xFFFFF000 );
-
-        UINT32 nCharSpace = nFraction + nMain;
         m_rWW8Export.InsUInt16( NS_sprm::LN_SDxtCharSpace );
         m_rWW8Export.InsUInt32( nCharSpace );
     }
@@ -4382,8 +4369,8 @@ void WW8AttributeOutput::FormatColumns_Impl( USHORT nCols, const SwFmtCol & rCol
     else
         m_rWW8Export.pO->Insert( 138, m_rWW8Export.pO->Count(  ) );
     m_rWW8Export.pO->Insert( bEven ? 1 : 0, m_rWW8Export.pO->Count(  ) );
-    
-#if 0 
+
+#if 0
     // FIXME what's the use of this code
     if ( bEven )
     {
@@ -4492,7 +4479,7 @@ void AttributeOutputBase::FormatColumns( const SwFmtCol& rCol )
                 break;
             }
         }
-        
+
         FormatColumns_Impl( nCols, rCol, bEven, nPageSize );
     }
 }
@@ -4995,11 +4982,11 @@ void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
 {
     bool bTabsRelativeToIndex = m_rWW8Export.pCurPam->GetDoc()->get( IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT );
     long nCurrentLeft = 0;
-    
+
     if ( bTabsRelativeToIndex )
     {
         const SfxPoolItem* pLR = m_rWW8Export.HasItem( RES_LR_SPACE );
-        
+
         if ( pLR != NULL )
             nCurrentLeft = ((const SvxLRSpaceItem*)pLR)->GetTxtLeft();
     }
@@ -5007,7 +4994,7 @@ void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
     // --> FLR 2009-03-17 #i100264#
     if ( m_rWW8Export.bStyDef &&
          m_rWW8Export.pCurrentStyle != NULL &&
-         m_rWW8Export.pCurrentStyle->DerivedFrom() != NULL ) 
+         m_rWW8Export.pCurrentStyle->DerivedFrom() != NULL )
     {
         SvxTabStopItem aTabs( 0, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP );
         const SwFmt *pParentStyle = m_rWW8Export.pCurrentStyle->DerivedFrom();
@@ -5016,7 +5003,7 @@ void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
         {
             aTabs.Insert( pParentTabs );
         }
-        
+
         ParaTabStopDelAdd( m_rWW8Export, aTabs, 0, rTabStops, 0 );
         return;
     }
@@ -5035,7 +5022,7 @@ void WW8AttributeOutput::ParaTabStop( const SvxTabStopItem& rTabStops )
     else
     {
         long nStyleLeft = 0;
-        
+
         if (bTabsRelativeToIndex)
         {
             const SvxLRSpaceItem &rStyleLR =
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index c064da2..cd0c986 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -74,7 +74,7 @@ public:
     virtual void RawText( const String& rText, bool bForceUnicode, rtl_TextEncoding eCharSet );
 
     /// Output ruby start.
-    virtual void StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby );
+    virtual void StartRuby( const SwTxtNode& rNode, xub_StrLen nPos, const SwFmtRuby& rRuby );
 
     /// Output ruby end.
     virtual void EndRuby();
@@ -139,7 +139,8 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const String& rName, bool bPapFmt,
-            USHORT nBase, USHORT nNext, USHORT nWwIdi, USHORT nId );
+            USHORT nBase, USHORT nNext, USHORT nWwIdi, USHORT nId,
+            bool bAutoUpdate );
 
     /// End of a style in the styles table.
     virtual void EndStyle();
commit db6af6a208ed578625ef2df23f50ec982b562ca6
Author: Miklos Vajna <vmiklos at frugalware.org>
Date:   Fri Sep 17 12:22:16 2010 +0200

    cws-vmiklos01.diff: Better RTF export filter

diff --git a/sw/source/filter/rtf/makefile.mk b/sw/source/filter/rtf/makefile.mk
index 2ff764d..e7310f2 100644
--- a/sw/source/filter/rtf/makefile.mk
+++ b/sw/source/filter/rtf/makefile.mk
@@ -46,18 +46,15 @@ CDEFS=$(CDEFS) -Dmydebug
 EXCEPTIONSFILES=	\
         $(SLO)$/rtffly.obj \
         $(SLO)$/rtfnum.obj \
-        $(SLO)$/swparrtf.obj \
-        $(SLO)$/wrtrtf.obj
+        $(SLO)$/swparrtf.obj
 
 
-SLOFILES =	\
-        $(SLO)$/rtfatr.obj \
+SLOFILES = \
         $(SLO)$/rtffld.obj \
         $(SLO)$/rtffly.obj \
         $(SLO)$/rtfnum.obj \
         $(SLO)$/rtftbl.obj \
-        $(SLO)$/swparrtf.obj \
-        $(SLO)$/wrtrtf.obj
+        $(SLO)$/swparrtf.obj
 
 # --- Tagets -------------------------------------------------------
 
diff --git a/sw/source/filter/rtf/rtfnum.cxx b/sw/source/filter/rtf/rtfnum.cxx
index c8aa398..07b2076 100644
--- a/sw/source/filter/rtf/rtfnum.cxx
+++ b/sw/source/filter/rtf/rtfnum.cxx
@@ -22,7 +22,6 @@
 #include <fltini.hxx>
 #include <swtypes.hxx>
 #include <swparrtf.hxx>
-#include <wrtrtf.hxx>
 #include <ndtxt.hxx>
 #include <doc.hxx>
 #include <docary.hxx>
@@ -1102,6 +1101,7 @@ BOOL lcl_IsExportNumRule( const SwNumRule& rRule, BYTE* pEnd = 0 )
     return nLvl != nEnd;
 }
 
+#if 0
 void SwRTFWriter::OutRTFListTab()
 {
     ByteString sOverrideList;
@@ -1430,3 +1430,4 @@ BOOL SwRTFWriter::OutListNum( const SwTxtNode& rNd )
     }
     return bRet;
 }
+#endif
diff --git a/sw/source/filter/rtf/swparrtf.cxx b/sw/source/filter/rtf/swparrtf.cxx
index fccac64..196ac04 100644
--- a/sw/source/filter/rtf/swparrtf.cxx
+++ b/sw/source/filter/rtf/swparrtf.cxx
@@ -179,6 +179,12 @@ ULONG RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const S
     return nRet;
 }
 
+ULONG RtfReader::Read(SvStream* pStream, SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam)
+{
+    pStrm = pStream;
+    return Read(rDoc, rBaseURL, rPam, rBaseURL);
+}
+
 SwRTFParser::SwRTFParser(SwDoc* pD,
         uno::Reference<document::XDocumentProperties> i_xDocProps,
         const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL,
diff --git a/sw/source/filter/rtf/swparrtf.hxx b/sw/source/filter/rtf/swparrtf.hxx
index a5a943f..8ff6878 100644
--- a/sw/source/filter/rtf/swparrtf.hxx
+++ b/sw/source/filter/rtf/swparrtf.hxx
@@ -81,6 +81,8 @@ struct SvxRTFPictureType;
 class RtfReader: public Reader
 {
     virtual ULONG Read( SwDoc &, const String& rBaseURL, SwPaM &,const String &);
+public:
+    virtual ULONG Read( SvStream* pStrm, SwDoc &, const String& rBaseURL, SwPaM &);
 };
 
 class SwNodeIdx : public SvxNodeIdx
diff --git a/sw/source/filter/ww8/README-rtf.txt b/sw/source/filter/ww8/README-rtf.txt
new file mode 100644
index 0000000..661813a
--- /dev/null
+++ b/sw/source/filter/ww8/README-rtf.txt
@@ -0,0 +1,226 @@
+
+---------------------------------------------------------------------
+
+Summary of new features in RtfExport
+
+---------------------------------------------------------------------
+
+Miklos Vajna
+
+<vmiklos at frugalware.org>
+---------------------------------------------------------------------
+
+Table of Contents
+
+1. Introduction
+
+    1.1. Terminology
+    1.2. General
+
+2. List if fixed bugs
+3. List of new features
+
+    3.1. Nested tables
+    3.2. Character properties
+    3.3. Sections
+    3.4. Graphics
+    3.5. Bookmarks
+    3.6. Fields
+    3.7. Drawing
+    3.8. Form fields
+    3.9. OLE objects
+
+4. Changes in the source code outside RTF
+
+
+---------------------------------------------------------------------
+
+1. Introduction
+
+---------------------------------------------------------------------
+
+The biggest difference is that the new exporter is an UNO component,
+and it?s based on the MSWord base classes, the vision here is that
+this way much less code can achieve the same set of features,
+reducing the amount of duplicated code.
+
+
+1.1. Terminology
+
+--------------
+
+  * The "MSO OK, OOo KO" and similar abbreviations describe if the
+    given new feature is supported by the OOo RTF importer or it can
+    be tested using Microsoft Office.
+  * RtfExport refers to the new UNO-based exporter, RtfWriter refers
+    to the old built-in one.
+
+
+1.2. General
+
+--------------
+
+RtfWriter sometimes created documents where the first { is closed in
+the middle of the document. MSO ignores this problem, but OOo stops
+parsing the rest of the document if this happens, in other words
+everything after such a bug is ignored. This can be reproduced by for
+example parprops.odt, but it?s triggered in several other cases as
+well. RtfExport has no automatic prevention for this, either - but
+during development I primarily test the output with OOo, so hopefully
+the bug will pop up less frequently.
+
+
+---------------------------------------------------------------------
+
+2. List if fixed bugs
+
+---------------------------------------------------------------------
+
+  * http://www.openoffice.org/issues/show_bug.cgi?id=51469 postit
+    fields
+  * http://www.openoffice.org/issues/show_bug.cgi?id=66619 page
+    margins
+  * http://www.openoffice.org/issues/show_bug.cgi?id=69856 page
+    numbers
+  * http://www.openoffice.org/issues/show_bug.cgi?id=81569 { and } in
+    document title
+  * http://www.openoffice.org/issues/show_bug.cgi?id=84703 redlines
+  * http://www.openoffice.org/issues/show_bug.cgi?id=91166 russian
+    chars
+  * http://www.openoffice.org/issues/show_bug.cgi?id=92673 bookmarks
+    across tables
+  * http://www.openoffice.org/issues/show_bug.cgi?id=100507 ole
+    object export
+  * http://www.openoffice.org/issues/show_bug.cgi?id=103993 same as #
+    81569 just for doc comments
+  * http://www.openoffice.org/issues/show_bug.cgi?id=106677
+    listoverride index starts at zero
+  * http://www.openoffice.org/issues/show_bug.cgi?id=38344 enhanced
+    character space
+
+
+---------------------------------------------------------------------
+
+3. List of new features
+
+---------------------------------------------------------------------
+
+
+3.1. Nested tables
+
+--------------
+
+This was new in Word2000 and it?s now supported by RtfExport (MSO OK,
+OOo KO)
+
+
+3.2. Character properties
+
+--------------
+
+The followings are now supported:
+
+  * blinking (MSO OK, OOo KO)
+  * expanded spacing (MSO OK, OOo OK)
+  * pair kerning (MSO OK, OOo OK)
+
+
+3.3. Sections
+
+--------------
+
+RtfExport writes:
+
+  * column breaks (MSO OK, OOo OK)
+  * special breaks (when the next page should be an odd or an even
+    page; MSO OK, OOo KO)
+  * the write-protected property of sections is experted properly
+    (MSO OK, OOo KO)
+  * better page numbers (inherited type from page styles, restarts;
+    MSO OK, OOo KO)
+  * line numbering (MSO OK, OOo KO)
+
+
+3.4. Graphics
+
+--------------
+
+PNG graphics are exported in WMF format as well, so that not only MSO
+and OOo can display graphics from the output document, but Wordpad as
+well.
+
+
+3.5. Bookmarks
+
+--------------
+
+Implicit bookmarks like reference to a footnote did not work in OOo
+(one got an Error: Reference source not found message when opening
+the result), this now works as expected. (MSO OK - the importer
+previously autocorrected this as well, OO OK)
+
+
+3.6. Fields
+
+--------------
+
+  * Table of contents is now written as a field, so it?s properly
+    read-only (MSO OK, OOo KO)
+  * Postit comments are now exported. (MSO OK, OOo KO)
+
+
+3.7. Drawing
+
+--------------
+
+Drawing objects for Word 97 through Word 2007 (shapes) are now
+implemented:
+
+  * basic shapes (rectangle, ellipse, etc.)
+  * lines, including free-form ones
+  * texts, including vertical ones and their (paragraph and
+    character) formatting
+
+(MSO OK, OOo KO)
+
+
+3.8. Form fields
+
+--------------
+
+All types supported by the RTF format are exported, namely:
+
+  * text boxes
+  * check boxes
+  * list boxes
+
+(MSO OK, OOo KO)
+
+
+3.9. OLE objects
+
+--------------
+
+Their result is exported as a picture - RtfWriter did not export
+anything. (MSO OK, OOo OK)
+
+For math, the native data is written as well, so you can edit the
+object, too. (MSO OK, OOo KO)
+
+
+---------------------------------------------------------------------
+
+4. Changes in the source code outside RTF
+
+---------------------------------------------------------------------
+
+These are refactorings I needed for RTF. To my best knowledge they do
+not change the output of other filters from a user?s point of view.
+
+  * The code that splits runs according to bookmarks is moved from
+    DocxExport to MSWordExportBase
+  * WW8_SdrAttrIter has been refactored to MSWord_SdrAttrIter
+  * MSWordExportBase::SubstituteBullet can avoid replacing bullets
+  * wwFontHelper::InitFontTable can really load all fonts
+  * An obvious typo in WW8AttributeOutput::CharTwoLines has been
+    fixed
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 07e2b54..1bb810c 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -116,131 +116,6 @@ bool DocxExport::CollapseScriptsforWordOk( USHORT nScript, USHORT nWhich )
     return true;
 }
 
-bool DocxExport::GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt,
-                    xub_StrLen nEnd, IMarkVector& rArr )
-{
-    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
-    ULONG nNd = rNd.GetIndex( );
-
-    const sal_Int32 nMarks = pMarkAccess->getMarksCount();
-    for ( sal_Int32 i = 0; i < nMarks; i++ )
-    {
-        IMark* pMark = ( pMarkAccess->getMarksBegin() + i )->get();
-
-        // Only keep the bookmarks starting or ending in this node
-        if ( pMark->GetMarkStart().nNode == nNd ||
-             pMark->GetMarkEnd().nNode == nNd )
-        {
-            xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
-            xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
-
-            // Keep only the bookmars starting or ending in the snippet
-            bool bIsStartOk = ( nBStart >= nStt ) && ( nBStart <= nEnd );
-            bool bIsEndOk = ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
-
-            if ( bIsStartOk || bIsEndOk )
-                rArr.push_back( pMark );
-        }
-    }
-    return ( rArr.size() > 0 );
-}
-
-class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
-{
-public:
-    inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
-    {
-        xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
-        xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
-
-        return nOEnd < nTEnd;
-    }
-};
-
-bool DocxExport::NearestBookmark( xub_StrLen& rNearest )
-{
-    bool bHasBookmark = false;
-
-    if ( m_rSortedMarksStart.size( ) > 0 )
-    {
-        IMark* pMarkStart = m_rSortedMarksStart.front();
-        rNearest = pMarkStart->GetMarkStart().nContent.GetIndex();
-        bHasBookmark = true;
-    }        
-
-    if ( m_rSortedMarksEnd.size( ) > 0 )
-    {
-        IMark* pMarkEnd = m_rSortedMarksEnd[0];
-        if ( !bHasBookmark )
-            rNearest = pMarkEnd->GetMarkEnd().nContent.GetIndex();
-        else
-            rNearest = std::min( rNearest, pMarkEnd->GetMarkEnd().nContent.GetIndex() );
-        bHasBookmark = true;
-    }
-
-    return bHasBookmark;
-}
-
-xub_StrLen DocxExport::GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos )
-{
-    // Get the bookmarks for the normal run
-    xub_StrLen nNextPos = MSWordExportBase::GetNextPos( pAttrIter, rNode, nAktPos );
-
-    GetSortedBookmarks( rNode, nAktPos, nNextPos - nAktPos );
-
-    xub_StrLen nNextBookmark = nNextPos;
-    NearestBookmark( nNextPos );
-    
-    return std::min( nNextPos, nNextBookmark );
-}
-
-void DocxExport::UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd )
-{
-    xub_StrLen nNextPos;
-
-    // either no bookmark, or it is not at the current position
-    if ( !NearestBookmark( nNextPos ) || nNextPos > nAktPos )
-    {
-        MSWordExportBase::UpdatePosition( pAttrIter, nAktPos, nEnd );
-    }
-}
-
-void DocxExport::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
-{
-    IMarkVector aMarksStart;
-    if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) ) 
-    {
-        IMarkVector aSortedEnd;
-        IMarkVector aSortedStart;
-        for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
-              it < end; ++it )
-        {
-            IMark* pMark = (*it);
-
-            // Remove the positions egals to the current pos
-            xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
-            xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
-
-            if ( nStart > nAktPos )
-                aSortedStart.push_back( pMark );
-
-            if ( nEnd > nAktPos )
-                aSortedEnd.push_back( pMark );
-        }
-
-        // Sort the bookmarks by end position
-        std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
-    
-        m_rSortedMarksStart.swap( aSortedStart );
-        m_rSortedMarksEnd.swap( aSortedEnd );
-    }
-    else
-    {
-        m_rSortedMarksStart.clear( );
-        m_rSortedMarksEnd.clear( );
-    }
-}
-
 void DocxExport::AppendBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
 {
     std::vector< OUString > aStarts;
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 5873f95..1bf9e22 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -76,11 +76,6 @@ class DocxExport : public MSWordExportBase
     /// Footer counter.
     sal_Int32 m_nFooters;
 
-    /// Used to split the runs according to the bookmarks start and ends
-    typedef std::vector< ::sw::mark::IMark* > IMarkVector;
-    IMarkVector m_rSortedMarksStart;
-    IMarkVector m_rSortedMarksEnd;
-
     /// Exporter of the VML shapes.
     oox::vml::VMLExport *m_pVMLExport;
 
@@ -163,24 +158,7 @@ protected:
                                      const SwFmtPageDesc* pNewPgDescFmt = 0,
                                      const SwPageDesc* pNewPgDesc = 0 );
 
-    /// Get the next position in the text node to output
-    virtual xub_StrLen GetNextPos( SwAttrIter* pAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos );
-
-    /// Update the information for GetNextPos().
-    virtual void UpdatePosition( SwAttrIter* pAttrIter, xub_StrLen nAktPos, xub_StrLen nEnd );
-
 private:
-    /// Find the nearest bookmark from the current position.
-    ///
-    /// Returns false when there is no bookmark.
-    bool NearestBookmark( xub_StrLen& rNearest );
-    
-    void GetSortedBookmarks( const SwTxtNode& rNd, xub_StrLen nAktPos, 
-                xub_StrLen nLen );
-
-    bool GetBookmarks( const SwTxtNode& rNd, xub_StrLen nStt, xub_StrLen nEnd,
-            IMarkVector& rArr );
-
     /// Setup pStyles and write styles.xml 
     void InitStyles();
 
diff --git a/sw/source/filter/ww8/docxexportfilter.cxx b/sw/source/filter/ww8/docxexportfilter.cxx
index 7004f08..bdf6616 100644
--- a/sw/source/filter/ww8/docxexportfilter.cxx
+++ b/sw/source/filter/ww8/docxexportfilter.cxx
@@ -1,7 +1,7 @@
 /*************************************************************************
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * 
+ *
  * Copyright 2000, 2010 Oracle and/or its affiliates.
  *
  * OpenOffice.org - a multi-platform office productivity suite
@@ -26,6 +26,8 @@
  ************************************************************************/
 
 #include "docxexportfilter.hxx"
+#include "rtfexportfilter.hxx"
+#include "rtfimportfilter.hxx"
 #include "docxexport.hxx"
 
 #include <docsh.hxx>
@@ -136,7 +138,7 @@ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceMan
         try
         {
             uno::Reference< registry::XRegistryKey > xNewKey1(
-                    static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(                                
+                    static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
                         OUString::createFromAscii( IMPL_NAME "/UNO/SERVICES/" ) ) );
             xNewKey1->createKey( DocxExport_getSupportedServiceNames().getConstArray()[0] );
 
@@ -144,7 +146,35 @@ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceMan
         }
         catch( registry::InvalidRegistryException& )
         {
-            OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
+            OSL_ENSURE( sal_False, "### InvalidRegistryException (docx)!" );
+        }
+
+        try
+        {
+            uno::Reference< registry::XRegistryKey > xNewKey1(
+                    static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
+                        OUString::createFromAscii( IMPL_NAME_RTFEXPORT "/UNO/SERVICES/" ) ) );
+            xNewKey1->createKey( RtfExport_getSupportedServiceNames().getConstArray()[0] );
+
+            bRet = sal_True;
+        }
+        catch( registry::InvalidRegistryException& )
+        {
+            OSL_ENSURE( sal_False, "### InvalidRegistryException (rtfexport)!" );
+        }
+
+        try
+        {
+            uno::Reference< registry::XRegistryKey > xNewKey1(
+                    static_cast< registry::XRegistryKey* >( pRegistryKey )->createKey(
+                        OUString::createFromAscii( IMPL_NAME_RTFIMPORT "/UNO/SERVICES/" ) ) );
+            xNewKey1->createKey( RtfExport_getSupportedServiceNames().getConstArray()[0] );
+
+            bRet = sal_True;
+        }
+        catch( registry::InvalidRegistryException& )
+        {
+            OSL_ENSURE( sal_False, "### InvalidRegistryException (rtfimport)!" );
         }
     }
 
@@ -157,6 +187,7 @@ SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /* pServiceMan
 
 SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /* pRegistryKey */ )
 {
+    OSL_TRACE("%s, pImplName is '%s'", OSL_THIS_FUNC, pImplName);
     uno::Reference< lang::XSingleServiceFactory > xFactory;
     void* pRet = 0;
 
@@ -169,6 +200,22 @@ SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplN
                     DocxExport_getImplementationName(),
                     DocxExport_createInstance,
                     DocxExport_getSupportedServiceNames() ) );
+    } else if ( rtl_str_compare( pImplName, IMPL_NAME_RTFEXPORT ) == 0 ) {
+        const OUString aServiceName( OUString::createFromAscii( IMPL_NAME_RTFEXPORT ) );
+
+        xFactory = uno::Reference< lang::XSingleServiceFactory >( ::cppu::createSingleFactory(
+                    reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
+                    RtfExport_getImplementationName(),
+                    RtfExport_createInstance,
+                    RtfExport_getSupportedServiceNames() ) );
+    } else if ( rtl_str_compare( pImplName, IMPL_NAME_RTFIMPORT ) == 0 ) {
+        const OUString aServiceName( OUString::createFromAscii( IMPL_NAME_RTFIMPORT ) );
+
+        xFactory = uno::Reference< lang::XSingleServiceFactory >( ::cppu::createSingleFactory(
+                    reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ),
+                    RtfImport_getImplementationName(),
+                    RtfImport_createInstance,
+                    RtfImport_getSupportedServiceNames() ) );
     }
 
     if ( xFactory.is() )
diff --git a/sw/source/filter/ww8/makefile.mk b/sw/source/filter/ww8/makefile.mk
index 653c36f..f3638e2 100644
--- a/sw/source/filter/ww8/makefile.mk
+++ b/sw/source/filter/ww8/makefile.mk
@@ -68,7 +68,12 @@ EXCEPTIONSFILES = \
         $(SLO)$/WW8TableInfo.obj \
         $(SLO)$/WW8FFData.obj \
         $(SLO)$/WW8Sttbf.obj \
-        $(SLO)$/WW8FibData.obj
+        $(SLO)$/WW8FibData.obj \
+        $(SLO)$/rtfexportfilter.obj \
+        $(SLO)$/rtfimportfilter.obj \
+        $(SLO)$/rtfattributeoutput.obj \
+        $(SLO)$/rtfsdrexport.obj \
+        $(SLO)$/rtfexport.obj
 
 
 SLOFILES =	\
@@ -100,7 +105,12 @@ SLOFILES =	\
         $(SLO)$/WW8TableInfo.obj \
         $(SLO)$/WW8FFData.obj \
         $(SLO)$/WW8Sttbf.obj \
-        $(SLO)$/WW8FibData.obj
+        $(SLO)$/WW8FibData.obj \
+        $(SLO)$/rtfexportfilter.obj \
+        $(SLO)$/rtfimportfilter.obj \
+        $(SLO)$/rtfattributeoutput.obj \
+        $(SLO)$/rtfsdrexport.obj \
+        $(SLO)$/rtfexport.obj
 
 
 # --- Tagets -------------------------------------------------------
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
new file mode 100644
index 0000000..c5ac3b1
--- /dev/null
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -0,0 +1,3356 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 Miklos Vajna.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtfattributeoutput.hxx"
+#include "rtfexport.hxx"
+#include "rtfsdrexport.hxx"
+#include "writerwordglue.hxx"
+#include "wrtww8.hxx"
+#include "ww8par.hxx"
+#include "fmtcntnt.hxx"
+#include "fmtsrnd.hxx"
+#include "fchrfmt.hxx"
+#include "tgrditem.hxx"
+#include "fmtruby.hxx"
+#include "charfmt.hxx"
+#include "breakit.hxx"
+
+#include <i18npool/mslangid.hxx>
+
+#include <hintids.hxx>
+
+#include <svl/poolitem.hxx>
+#include <svtools/rtfkeywd.hxx>
+
+#include <editeng/fontitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/brkitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <editeng/pgrditem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/fmglob.hxx>
+#include <svx/svdouno.hxx>
+#include <filter/msfilter/msoleexp.hxx>
+
+#include <docufld.hxx>
+#include <flddropdown.hxx>
+#include <format.hxx>
+#include <fmtclds.hxx>
+#include <fmtinfmt.hxx>
+#include <fmtfld.hxx>
+#include <fmtfsize.hxx>
+#include <fmtftn.hxx>
+#include <fmtrowsplt.hxx>
+#include <fmtline.hxx>
+#include <fmtanchr.hxx>
+#include <frmfmt.hxx>
+#include <frmatr.hxx>
+#include <ftninfo.hxx>
+#include <htmltbl.hxx>
+#include <ndgrf.hxx>
+#include <ndtxt.hxx>
+#include <node.hxx>
+#include <pagedesc.hxx>
+#include <paratr.hxx>
+#include <swmodule.hxx>
+#include <swtable.hxx>
+#include <txtftn.hxx>
+#include <txtinet.hxx>
+#include <numrule.hxx>
+#include <grfatr.hxx>
+#include <ndole.hxx>
+#include <lineinfo.hxx>
+#include <rtf.hxx>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+
+#include <tools/color.hxx>
+
+#include <vcl/cvtgrf.hxx>
+
+#include <com/sun/star/i18n/ScriptType.hdl>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+
+#include <osl/diagnose.h>
+
+using rtl::OString;
+using rtl::OStringBuffer;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OUStringToOString;
+
+using namespace nsSwDocInfoSubType;
+using namespace nsFieldFlags;
+using namespace sw::util;
+using namespace ::com::sun::star;
+
+static OString OutTBLBorderLine(RtfExport &rExport, const SvxBorderLine* pLine, const sal_Char* pStr)
+{
+    OStringBuffer aRet;
+    aRet.append(pStr);
+    if( pLine->GetInWidth() )
+    {
+        // double line
+        aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDB);
+        switch( pLine->GetInWidth() )
+        {
+            case DEF_LINE_WIDTH_0:
+                aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW "15");
+                break;
+            case DEF_LINE_WIDTH_1:
+                aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW "30");
+                break;
+            case DEF_LINE_WIDTH_2:
+            case DEF_LINE_WIDTH_3:
+                aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW "45");
+                break;
+        }
+    }
+    else
+    {
+        // single line
+        if( DEF_LINE_WIDTH_1 >= pLine->GetOutWidth() )
+            aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRS OOO_STRING_SVTOOLS_RTF_BRDRW).append((sal_Int32)pLine->GetOutWidth());
+        else
+            aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTH OOO_STRING_SVTOOLS_RTF_BRDRW).append((sal_Int32)pLine->GetOutWidth() / 2);
+    }
+
+    aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRCF);
+    aRet.append((sal_Int32)rExport.GetColor(pLine->GetColor()));
+    return aRet.makeStringAndClear();
+}
+
+static OString OutBorderLine(RtfExport &rExport, const SvxBorderLine* pLine,
+    const sal_Char* pStr, USHORT nDist)
+{
+    OStringBuffer aRet;
+    aRet.append(OutTBLBorderLine(rExport, pLine, pStr));
+    aRet.append(OOO_STRING_SVTOOLS_RTF_BRSP);
+    aRet.append((sal_Int32)nDist);
+    return aRet.makeStringAndClear();
+}
+
+static OString OutBorderLine( RtfExport &rExport, const SvxBorderLine* pLine,
+                            const char* pStr )
+{
+    OStringBuffer aRet;
+    aRet.append(pStr);
+    aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNCOL);
+    aRet.append((sal_Int32)rExport.GetColor( pLine->GetColor() ) );
+    aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNIN);
+    aRet.append((sal_Int32)pLine->GetInWidth());
+    aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNOUT);
+    aRet.append((sal_Int32)pLine->GetOutWidth());
+    aRet.append(OOO_STRING_SVTOOLS_RTF_BRDLNDIST);
+    aRet.append((sal_Int32)pLine->GetDistance());
+    return aRet.makeStringAndClear();
+}
+
+void RtfAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
+{
+    OSL_TRACE("%s", OSL_THIS_FUNC);
+    /*
+       You would have thought that
+       m_rExport.Strm() << (bIsRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficent here ,
+       but looks like word needs to see the other directional token to be
+       satisified that all is kosher, otherwise it seems in ver 2003 to go and
+       semi-randomlyly stick strike through about the place. Perhaps
+       strikethrough is some ms developers "something is wrong signal" debugging
+       code that we're triggering ?
+       */
+    if (bIsRTL) {
+        m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);

... etc. - the rest is truncated


More information about the ooo-build-commit mailing list