[ooo-build-commit] .: patches/dev300

Miklos Vajna vmiklos at kemper.freedesktop.org
Wed Aug 4 05:00:00 PDT 2010


 patches/dev300/apply              |    3 
 patches/dev300/cws-vmiklos01.diff | 7932 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 7935 insertions(+)

New commits:
commit c4b7336cf597aa276cef098c6a56f6ac7dbce6fd
Author: Miklos Vajna <vmiklos at frugalware.org>
Date:   Wed Aug 4 13:57:13 2010 +0200

    Backport 'RTF export rewrite' CWS
    
    * patches/dev300/apply: add it to the CWSBackports section
    * patches/dev300/cws-vmiklos01.diff: backport vmiklos01 cws (and
      additional bits to adapt for ooo-build)

diff --git a/patches/dev300/apply b/patches/dev300/apply
index c29decc..2c3d3aa 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -188,6 +188,9 @@ cws-koheichart02-xmloff.diff, kohei
 cws-koheicopyborder-sc.diff,  kohei
 cws-koheicopyborder-svx.diff, kohei
 
+# vmiklos01 cws (gsoc, rewrite rtf filter)
+cws-vmiklos01.diff, vmiklos
+
 [ LinuxOnly ]
 # add accelerator to the OK and Cancel buttons.
 ok-cancel-btn-add-accel.diff, kohei
diff --git a/patches/dev300/cws-vmiklos01.diff b/patches/dev300/cws-vmiklos01.diff
new file mode 100644
index 0000000..91c13d4
--- /dev/null
+++ b/patches/dev300/cws-vmiklos01.diff
@@ -0,0 +1,7932 @@
+--- filter/source/config/fragments/filters/Rich_Text_Format.xcu
++++ filter/source/config/fragments/filters/Rich_Text_Format.xcu
+@@ -1,7 +1,7 @@
+     <node oor:name="Rich Text Format" oor:op="replace">
+-        <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN PREFERRED</value></prop>
++        <prop oor:name="Flags"><value>IMPORT EXPORT ALIEN 3RDPARTYFILTER PREFERRED</value></prop>
+         <prop oor:name="UIComponent"/>
+-        <prop oor:name="FilterService"/>
++	<prop oor:name="FilterService"><value>com.sun.star.comp.Writer.RtfFilter</value></prop>
+         <prop oor:name="UserData"><value>RTF</value></prop>
+         <prop oor:name="UIName">
+             <value xml:lang="x-default">Rich Text Format</value>
+--- svtools/inc/rtfkeywd.hxx
++++ svtools/inc/rtfkeywd.hxx
+@@ -39,6 +39,7 @@
+ #define OOO_STRING_SVTOOLS_RTF_ALT "\\alt"
+ #define OOO_STRING_SVTOOLS_RTF_ANNOTATION "\\annotation"
+ #define OOO_STRING_SVTOOLS_RTF_ANSI "\\ansi"
++#define OOO_STRING_SVTOOLS_RTF_ATNDATE "\\atndate"
+ #define OOO_STRING_SVTOOLS_RTF_ATNID "\\atnid"
+ #define OOO_STRING_SVTOOLS_RTF_AUTHOR "\\author"
+ #define OOO_STRING_SVTOOLS_RTF_B "\\b"
+@@ -978,12 +979,15 @@
+ #define OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN "\\shpbxcolumn"
+ #define OOO_STRING_SVTOOLS_RTF_SHPBXMARGIN "\\shpbxmargin"
+ #define OOO_STRING_SVTOOLS_RTF_SHPBXPAGE "\\shpbxpage"
++#define OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE "\\shpbxignore"
+ #define OOO_STRING_SVTOOLS_RTF_SHPBYMARGIN "\\shpbymargin"
+ #define OOO_STRING_SVTOOLS_RTF_SHPBYPAGE "\\shpbypage"
+ #define OOO_STRING_SVTOOLS_RTF_SHPBYPARA "\\shpbypara"
++#define OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE "\\shpbyignore"
+ #define OOO_STRING_SVTOOLS_RTF_SHPFBLWTXT "\\shpfblwtxt"
+ #define OOO_STRING_SVTOOLS_RTF_SHPFHDR "\\shpfhdr"
+ #define OOO_STRING_SVTOOLS_RTF_SHPGRP "\\shpgrp"
++#define OOO_STRING_SVTOOLS_RTF_SHPINST "\\shpinst"
+ #define OOO_STRING_SVTOOLS_RTF_SHPLEFT "\\shpleft"
+ #define OOO_STRING_SVTOOLS_RTF_SHPLID "\\shplid"
+ #define OOO_STRING_SVTOOLS_RTF_SHPLOCKANCHOR "\\shplockanchor"
+@@ -995,6 +999,7 @@
+ #define OOO_STRING_SVTOOLS_RTF_SHPWRK "\\shpwrk"
+ #define OOO_STRING_SVTOOLS_RTF_SHPWR "\\shpwr"
+ #define OOO_STRING_SVTOOLS_RTF_SHPZ "\\shpz"
++#define OOO_STRING_SVTOOLS_RTF_SP "\\sp"
+ #define OOO_STRING_SVTOOLS_RTF_SPRSBSP "\\sprsbsp"
+ #define OOO_STRING_SVTOOLS_RTF_SPRSLNSP "\\sprslnsp"
+ #define OOO_STRING_SVTOOLS_RTF_SPRSTSM "\\sprstsm"
+@@ -1140,4 +1145,11 @@
+ #define OOO_STRING_SVTOOLS_RTF_OLHWAVE "\\olhwave"
+ #define OOO_STRING_SVTOOLS_RTF_OLOLDBWAVE "\\ololdbwave"
+ 
++// Support for nested tables
++#define OOO_STRING_SVTOOLS_RTF_ITAP "\\itap"
++#define OOO_STRING_SVTOOLS_RTF_NESTCELL "\\nestcell"
++#define OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS "\\nesttableprops"
++#define OOO_STRING_SVTOOLS_RTF_NESTROW "\\nestrow"
++#define OOO_STRING_SVTOOLS_RTF_NONESTTABLES "\\nonesttables"
++
+ #endif // _RTFKEYWD_HXX
+--- sw/source/filter/rtf/makefile.mk
++++ 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 \
+         $(SLO)$/rtffld.obj \
+         $(SLO)$/rtffly.obj \
+         $(SLO)$/rtfnum.obj \
+         $(SLO)$/rtftbl.obj \
+-        $(SLO)$/swparrtf.obj \
+-        $(SLO)$/wrtrtf.obj
++        $(SLO)$/swparrtf.obj
+ 
+ # --- Tagets -------------------------------------------------------
+ 
+--- sw/source/filter/rtf/rtfnum.cxx
++++ 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
+--- sw/source/filter/rtf/swparrtf.cxx
++++ 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,
+--- sw/source/filter/rtf/swparrtf.hxx
++++ 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
+--- sw/source/filter/rtf/wrtrtf.cxx
++++ sw/source/filter/rtf/wrtrtf.cxx
+@@ -1761,11 +1761,6 @@ RTFSaveData::~RTFSaveData()
+     rWrt.bOutSection = bOldOutSection;
+ }
+ 
+-extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportRTF( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
+-{
+-    xRet = new SwRTFWriter( rFltName, rBaseURL );
+-}
+-
+ short SwRTFWriter::GetCurrentPageDirection() const
+ {
+     const SwFrmFmt  &rFmt = pAktPageDesc
+--- /dev/null
++++ sw/source/filter/ww8/README-rtf.txt
+@@ -0,0 +1,227 @@
++
++---------------------------------------------------------------------
++
++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
++
+--- sw/source/filter/ww8/docxexport.cxx
++++ 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;
+--- sw/source/filter/ww8/docxexport.hxx
++++ 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;
+ 
+@@ -166,24 +161,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();
+ 
+--- sw/source/filter/ww8/docxexportfilter.cxx
++++ sw/source/filter/ww8/docxexportfilter.cxx
+@@ -26,6 +26,8 @@
+  ************************************************************************/
+ 
+ #include "docxexportfilter.hxx"
++#include "rtfexportfilter.hxx"
++#include "rtfimportfilter.hxx"
+ #include "docxexport.hxx"
+ 
+ #include <docsh.hxx>
+@@ -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'", __PRETTY_FUNCTION__, 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() )
+--- sw/source/filter/ww8/makefile.mk
++++ sw/source/filter/ww8/makefile.mk
+@@ -69,7 +69,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 =	\
+@@ -101,7 +106,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 -------------------------------------------------------
+--- /dev/null
++++ sw/source/filter/ww8/rtfattributeoutput.cxx
+@@ -0,0 +1,3302 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * Copyright 2000, 2010 Oracle and/or its affiliates.
++ * 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", __PRETTY_FUNCTION__);
++    /*
++       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_aRun.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
++        m_aRun.append(' ');
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
++    } else {
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
++        m_aRun.append(' ');
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
++    }
++
++    switch (nScript) {
++        case i18n::ScriptType::LATIN:
++            m_aRun.append(OOO_STRING_SVTOOLS_RTF_LOCH);
++            break;
++        case i18n::ScriptType::ASIAN:
++            m_aRun.append(OOO_STRING_SVTOOLS_RTF_DBCH);
++            break;
++        case i18n::ScriptType::COMPLEX:
++            /* noop */
++            break;
++        default:
++            /* should not happen? */
++            break;
++    }
++}
++
++void RtfAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    // Output table/table row/table cell starts if needed
++    if ( pTextNodeInfo.get() )
++    {
++        sal_uInt32 nRow = pTextNodeInfo->getRow();
++        sal_uInt32 nCell = pTextNodeInfo->getCell();
++
++        // New cell/row?
++        if ( m_nTableDepth > 0 && !m_bTableCellOpen )
++        {
++            ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
++            if ( pDeepInner->getCell() == 0 )
++                StartTableRow( pDeepInner );
++
++            StartTableCell( pDeepInner );
++        }
++
++        if ( nRow == 0 && nCell == 0 )
++        {
++            // Do we have to start the table?
++            // [If we are at the rigth depth already, it means that we
++            // continue the table cell]
++            sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
++
++            if ( nCurrentDepth > m_nTableDepth )
++            {
++                // Start all the tables that begin here
++                for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
++                {
++                    ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
++
++                    StartTable( pInner );
++                    StartTableRow( pInner );
++                    StartTableCell( pInner );
++                }
++
++                m_nTableDepth = nCurrentDepth;
++            }
++        }
++    }
++
++    OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty");
++}
++
++void RtfAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    FinishTableRowCell( pTextNodeInfoInner );
++
++    OStringBuffer aParagraph;
++
++    aParagraph.append(m_aRun.makeStringAndClear());
++    aParagraph.append(m_aAfterRuns.makeStringAndClear());
++    if (m_bTblAfterCell)
++        m_bTblAfterCell = false;
++    else
++    {
++        aParagraph.append(m_rExport.sNewLine);
++        aParagraph.append(OOO_STRING_SVTOOLS_RTF_PAR);
++        aParagraph.append(' ');
++    }
++    if (m_nColBreakNeeded)
++    {
++        aParagraph.append(OOO_STRING_SVTOOLS_RTF_COLUMN);
++        m_nColBreakNeeded = false;
++    }
++
++    if (!m_bBufferSectionHeaders)
++        m_rExport.Strm() << aParagraph.makeStringAndClear();
++    else
++        m_aSectionHeaders.append(aParagraph.makeStringAndClear());
++}
++
++void RtfAttributeOutput::EmptyParagraph()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << m_rExport.sNewLine << OOO_STRING_SVTOOLS_RTF_PAR << ' ';
++}
++
++void RtfAttributeOutput::StartParagraphProperties( const SwTxtNode& rNode )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
++
++    // output page/section breaks
++    SwNodeIndex aNextIndex( rNode, 1 );
++    m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
++    m_bBufferSectionBreaks = true;
++
++    // output section headers / footers
++    if (!m_bBufferSectionHeaders)
++        m_rExport.Strm() << m_aSectionHeaders.makeStringAndClear();
++
++    if ( aNextIndex.GetNode().IsTxtNode() )
++    {
++        const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >( &aNextIndex.GetNode() );
++        m_rExport.OutputSectionBreaks( pTxtNode->GetpSwAttrSet(), *pTxtNode );
++    }
++    else if ( aNextIndex.GetNode().IsTableNode() )
++    {
++        const SwTableNode* pTableNode = static_cast< SwTableNode* >( &aNextIndex.GetNode() );
++        const SwFrmFmt *pFmt = pTableNode->GetTable().GetFrmFmt();
++        m_rExport.OutputSectionBreaks( &(pFmt->GetAttrSet()), *pTableNode );
++    }
++    m_bBufferSectionBreaks = false;
++
++    OStringBuffer aPar;
++    aPar.append(OOO_STRING_SVTOOLS_RTF_PARD);
++    aPar.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
++    aPar.append(' ');
++    if (!m_bBufferSectionHeaders)
++        m_rExport.Strm() << aPar.makeStringAndClear();
++    else
++        m_aSectionHeaders.append(aPar.makeStringAndClear());
++}
++
++void RtfAttributeOutput::EndParagraphProperties()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_aStyles.append(m_aStylesEnd.makeStringAndClear());
++    m_rExport.Strm() << m_aStyles.makeStringAndClear();
++}
++
++void RtfAttributeOutput::StartRun( const SwRedlineData* pRedlineData )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aRun.append('{');
++
++    // if there is some redlining in the document, output it
++    Redline( pRedlineData );
++
++    OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
++}
++
++void RtfAttributeOutput::EndRun()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_aRun.append(m_rExport.sNewLine);
++    m_aRun.append(m_aRunText.makeStringAndClear());
++    m_aRun.append('}');
++}
++
++void RtfAttributeOutput::StartRunProperties()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
++}
++
++void RtfAttributeOutput::EndRunProperties( const SwRedlineData* /*pRedlineData*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_aStyles.append(m_aStylesEnd.makeStringAndClear());
++    m_aRun.append(m_aStyles.makeStringAndClear());
++}
++
++void RtfAttributeOutput::RunText( const String& rText, rtl_TextEncoding eCharSet )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    RawText( rText, 0, eCharSet );
++}
++
++OStringBuffer& RtfAttributeOutput::RunText()
++{
++    return m_aRunText;
++}
++
++OStringBuffer& RtfAttributeOutput::Styles()
++{
++    return m_aStyles;
++}
++
++void RtfAttributeOutput::RawText( const String& rText, bool /*bForceUnicode*/, rtl_TextEncoding eCharSet )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_aRunText.append(m_rExport.OutString(rText, eCharSet));
++}
++
++void RtfAttributeOutput::StartRuby( const SwTxtNode& /*rNode*/, xub_StrLen /*nPos*/, const SwFmtRuby& /*rRuby*/ )
++{
++    OSL_TRACE("TODO: %s", __PRETTY_FUNCTION__);
++}
++
++void RtfAttributeOutput::EndRuby()
++{
++    OSL_TRACE("TODO: %s", __PRETTY_FUNCTION__);
++}
++
++bool RtfAttributeOutput::StartURL( const String& rUrl, const String& rTarget )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append('{');
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FIELD);
++    m_aStyles.append('{');
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
++    m_aStyles.append(" HYPERLINK ");
++
++    String sURL( rUrl );
++    if( sURL.Len() )
++    {
++        m_aStyles.append("\"");
++        m_aStyles.append(m_rExport.OutString( sURL, m_rExport.eCurrentEncoding));
++        m_aStyles.append("\" ");
++    }
++
++    if( rTarget.Len() )
++    {
++        m_aStyles.append("\\\\t \"");
++        m_aStyles.append(m_rExport.OutString( rTarget, m_rExport.eCurrentEncoding));
++        m_aStyles.append("\" ");
++    }
++
++    m_aStyles.append("}");
++    return true;
++}
++
++bool RtfAttributeOutput::EndURL()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    // close the fldrslt group
++    m_aRunText.append('}');
++    // close the field group
++    m_aRunText.append('}');
++    return true;
++}
++
++void RtfAttributeOutput::FieldVanish( const String& /*rTxt*/, ww::eField /*eType*/ )
++{
++    OSL_TRACE("TODO: %s", __PRETTY_FUNCTION__);
++}
++
++void RtfAttributeOutput::Redline( const SwRedlineData* pRedline )
++{
++    if (!pRedline)
++        return;
++
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if (pRedline->GetType() == nsRedlineType_t::REDLINE_INSERT)
++    {
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVISED);
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
++        m_aRun.append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
++    }
++    else if(pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
++    {
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_DELETED);
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
++        m_aRun.append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
++        m_aRun.append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
++    }
++    m_aRun.append((sal_Int32)sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()));
++    m_aRun.append(' ');
++}
++
++void RtfAttributeOutput::FormatDrop( const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, USHORT /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/ )
++{
++    OSL_TRACE("TODO: %s", __PRETTY_FUNCTION__);
++}
++
++void RtfAttributeOutput::ParagraphStyle( USHORT nStyle )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    OString *pStyle = m_rExport.GetStyle(nStyle);
++    OStringBuffer aStyle;
++    aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
++    aStyle.append((sal_Int32)nStyle);
++    if (pStyle)
++        aStyle.append(pStyle->getStr());
++    if (!m_bBufferSectionHeaders)
++        m_rExport.Strm() << aStyle.makeStringAndClear();
++    else
++        m_aSectionHeaders.append(aStyle.makeStringAndClear());
++}
++
++void RtfAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
++    if ( m_nTableDepth > 1 )
++    {
++        m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
++        m_aStyles.append((sal_Int32)m_nTableDepth);
++    }
++}
++
++void RtfAttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /* noop */
++}
++
++void RtfAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if ( !m_pTableWrt )
++        InitTableHelper( pTableTextNodeInfoInner );
++
++    const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
++    SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
++
++    m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
++    TableOrientation( pTableTextNodeInfoInner );
++    TableBidi( pTableTextNodeInfoInner );
++    TableHeight( pTableTextNodeInfoInner );
++    TableCanSplit( pTableTextNodeInfoInner );
++
++    // Cell margins
++    const SvxBoxItem& rBox = pFmt->GetBox( );
++    static const USHORT aBorders[] =
++    {
++        BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
++    };
++
++    static const char* aRowPadNames[] =
++    {
++        OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
++    };
++
++    static const char* aRowPadUnits[] =
++    {
++        OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
++    };
++
++    for (int i = 0; i < 4; ++i)
++    {
++        m_aRowDefs.append(aRowPadUnits[i]);
++        m_aRowDefs.append((sal_Int32)3);
++        m_aRowDefs.append(aRowPadNames[i]);
++        m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
++    }
++
++    // The cell-dependent properties
++    const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
++    SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
++    SwTwips nSz = 0;
++    Point aPt;
++    SwRect aRect( pFmt->FindLayoutRect( false, &aPt ));
++    SwTwips nPageSize = aRect.Width();
++    SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
++    for( USHORT i = 0; i < pRow->GetCells().Count(); i++ )
++    {
++        SwWriteTableCell *pCell = pRow->GetCells( )[ i ];
++        const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
++
++        pTableTextNodeInfoInner->setCell( i );
++        TableCellProperties(pTableTextNodeInfoInner);
++
++        // Right boundary: this can't be in TableCellProperties as the old
++        // value of nSz is needed.
++        nSz += pCellFmt->GetFrmSize().GetWidth();
++        m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
++        SwTwips nCalc = nSz;
++        nCalc *= nPageSize;
++        nCalc /= nTblSz;
++        m_aRowDefs.append( (sal_Int32)(pFmt->GetLRSpace().GetLeft() + nCalc) );
++    }
++}
++
++void RtfAttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /*
++     * The function name is a bit misleading: given that we write borders
++     * before each row, we just have borders, not default ones. Additionally,
++     * this function actually writes borders for a specific cell only and is
++     * called for each cell.
++     */
++
++    const SwTableBox *pTblBox = pTableTextNodeInfoInner->getTableBox( );
++    SwFrmFmt *pFmt = pTblBox->GetFrmFmt( );
++    const SvxBoxItem& rDefault = pFmt->GetBox( );
++    const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
++    SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
++    SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
++    const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
++    const SfxPoolItem* pItem;
++    if (SFX_ITEM_SET == pCellFmt->GetAttrSet().GetItemState(RES_BOX, TRUE, &pItem))
++    {
++        const SvxBoxItem& rBox = (SvxBoxItem&)*pItem;
++        static const USHORT aBorders[] =
++        {
++            BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
++        };
++        static const char* aBorderNames[] =
++        {
++            OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
++        };
++        //Yes left and top are swapped with eachother for cell padding! Because
++        //that's what the thunderingly annoying rtf export/import word xp does.
++        static const char* aCellPadNames[] =
++        {
++            OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
++        };
++        static const char* aCellPadUnits[] =
++        {
++            OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
++        };
++        for (int i = 0; i < 4; ++i)
++        {
++            if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
++                m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
++            if (rDefault.GetDistance(aBorders[i]) !=
++                    rBox.GetDistance(aBorders[i]))
++            {
++                m_aRowDefs.append(aCellPadUnits[i]);
++                m_aRowDefs.append((sal_Int32)3);
++                m_aRowDefs.append(aCellPadNames[i]);
++                m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
++            }
++        }
++    }
++}
++
++void RtfAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
++    SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
++    SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
++    const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
++    const SfxPoolItem* pItem;
++    if( SFX_ITEM_SET == pCellFmt->GetAttrSet().GetItemState(
++                RES_BACKGROUND, TRUE, &pItem ))
++    {
++        const SvxBrushItem& rBack = (SvxBrushItem&)*pItem;
++        if( !rBack.GetColor().GetTransparency() )
++        {
++            m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
++            m_aRowDefs.append((sal_Int32)m_rExport.GetColor(rBack.GetColor()));
++        }
++    }
++}
++
++void RtfAttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
++    const SwTableLine * pTabLine = pTabBox->GetUpper();
++    const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
++    const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
++
++    if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() )
++    {
++        sal_Int32 nHeight = 0;
++
++        switch ( rLSz.GetHeightSizeType() )
++        {
++            case ATT_FIX_SIZE: nHeight = -rLSz.GetHeight(); break;
++            case ATT_MIN_SIZE: nHeight = rLSz.GetHeight(); break;
++            default:           break;
++        }
++
++        if ( nHeight )
++        {
++            m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
++            m_aRowDefs.append(nHeight);
++        }
++    }
++}
++
++void RtfAttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
++    const SwTableLine * pTabLine = pTabBox->GetUpper();
++    const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt();
++    const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit( );
++
++    // The rtf default is to allow a row to break
++    if (rSplittable.GetValue() == 0)
++        m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
++}
++
++void RtfAttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwTable * pTable = pTableTextNodeInfoInner->getTable();
++    const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt();
++
++    if ( m_rExport.TrueFrameDirection( *pFrmFmt ) != FRMDIR_HORI_RIGHT_TOP )
++        m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
++    else
++        m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
++}
++
++void RtfAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
++    SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
++    SwWriteTableCell *pCell = pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
++    const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
++    const SfxPoolItem* pItem;
++
++    // vertical merges
++    if (pCell->GetRowSpan() > 1)
++        m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
++    else if (pCell->GetRowSpan() == 0)
++        m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
++
++    // vertical alignment
++    if( SFX_ITEM_SET == pCellFmt->GetAttrSet().GetItemState(
++                RES_VERT_ORIENT, TRUE, &pItem ) )
++        switch( ((SwFmtVertOrient*)pItem)->GetVertOrient() )
++        {
++            case text::VertOrientation::CENTER: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC); break;
++            case text::VertOrientation::BOTTOM: m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB); break;
++            default:                            m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT); break;
++        }
++}
++
++void RtfAttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /* noop */
++}
++
++void RtfAttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    // This is called when the nested table ends in a cell, and there's no
++    // paragraph benhind that; so we must check for the ends of cell, rows,
++    // and tables
++    // ['true' to write an empty paragraph, MS Word insists on that]
++    FinishTableRowCell( pNodeInfoInner, true );
++}
++
++void RtfAttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwTable *pTable = pTableTextNodeInfoInner->getTable();
++    SwFrmFmt *pFmt = pTable->GetFrmFmt( );
++
++    OStringBuffer aTblAdjust( OOO_STRING_SVTOOLS_RTF_TRQL );
++    switch (pFmt->GetHoriOrient().GetHoriOrient())
++    {
++        case text::HoriOrientation::CENTER:
++            aTblAdjust.setLength(0);
++            aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
++            break;
++        case text::HoriOrientation::RIGHT:
++            aTblAdjust.setLength(0);
++            aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
++            break;
++        case text::HoriOrientation::NONE:
++        case text::HoriOrientation::LEFT_AND_WIDTH:
++            aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
++            aTblAdjust.append((sal_Int32)pFmt->GetLRSpace().GetLeft());
++            break;
++        default:
++            break;
++    }
++
++    m_aRowDefs.append(aTblAdjust.makeStringAndClear());
++}
++
++void RtfAttributeOutput::TableSpacing( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
++{
++    OSL_TRACE("TODO: %s", __PRETTY_FUNCTION__);
++}
++
++void RtfAttributeOutput::TableRowEnd( sal_uInt32 /*nDepth*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /* noop, see EndTableRow() */
++}
++
++/*
++ * Our private table methods.
++ */
++
++void RtfAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    sal_uInt32 nPageSize = 0;
++    bool bRelBoxSize = false;
++
++    // Create the SwWriteTable instance to use col spans
++    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, 
++                (USHORT)nTblSz, false);
++}
++
++void RtfAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /* noop */
++}
++
++void RtfAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
++    OSL_TRACE("%s, (depth is %d)", __PRETTY_FUNCTION__, (int)nCurrentDepth);
++
++    TableDefinition(pTableTextNodeInfoInner);
++
++    // We'll write the table definition for nested tables later
++    if ( nCurrentDepth > 1 )
++        return;
++    m_rExport.Strm() << m_aRowDefs.makeStringAndClear();
++}
++
++void RtfAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_bTableCellOpen = true;
++}
++
++void RtfAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    TableDefaultBorders(pTableTextNodeInfoInner);
++    TableBackgrounds(pTableTextNodeInfoInner);
++    TableVerticalCell(pTableTextNodeInfoInner);
++}
++
++void RtfAttributeOutput::EndTableCell( )
++{
++    OSL_TRACE("%s, (depth is %d)", __PRETTY_FUNCTION__, (int)m_nTableDepth);
++
++    if ( m_nTableDepth > 1 )
++        m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
++    else
++        m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
++
++    m_bTableCellOpen = false;
++    m_bTblAfterCell = true;
++}
++
++void RtfAttributeOutput::EndTableRow( )
++{
++    OSL_TRACE("%s, (depth is %d)", __PRETTY_FUNCTION__, (int)m_nTableDepth);
++
++    if ( m_nTableDepth > 1 )
++    {
++        m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
++        m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
++        m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW "}" "{" OOO_STRING_SVTOOLS_RTF_NONESTTABLES OOO_STRING_SVTOOLS_RTF_PAR "}");
++    }
++    else
++        m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW);
++}
++
++void RtfAttributeOutput::EndTable()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if ( m_nTableDepth > 0 )
++        m_nTableDepth--;
++
++    // We closed the table; if it is a nested table, the cell that contains it
++    // still continues
++    m_bTableCellOpen = true;
++
++    // Cleans the table helper
++    delete m_pTableWrt, m_pTableWrt = NULL;
++}
++
++void RtfAttributeOutput::FinishTableRowCell( ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool /*bForceEmptyParagraph*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if ( pInner.get() )
++    {
++        // Where are we in the table
++        sal_uInt32 nRow = pInner->getRow( );
++
++        const SwTable *pTable = pInner->getTable( );
++        const SwTableLines& rLines = pTable->GetTabLines( );
++        USHORT nLinesCount = rLines.Count( );
++
++        if ( pInner->isEndOfCell() )
++            EndTableCell();
++
++        // This is a line end
++        if ( pInner->isEndOfLine() )
++            EndTableRow();
++
++        // This is the end of the table
++        if ( pInner->isEndOfLine( ) && ( nRow + 1 ) == nLinesCount )
++            EndTable();
++    }
++}
++
++void RtfAttributeOutput::StartStyles()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_rExport.Strm() << m_rExport.sNewLine << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL;
++    m_rExport.OutColorTable();
++    OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
++    m_aStylesheet.append(m_rExport.sNewLine);
++    m_aStylesheet.append('{');
++    m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
++}
++
++void RtfAttributeOutput::EndStyles( USHORT /*nNumberOfStyles*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_rExport.Strm() << '}';
++    m_rExport.Strm() << m_aStylesheet.makeStringAndClear();
++    m_rExport.Strm() << '}';
++}
++
++void RtfAttributeOutput::DefaultStyle( USHORT /*nStyle*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /* noop, the default style is always 0 in RTF */
++}
++
++void RtfAttributeOutput::StartStyle( const String& rName, bool /*bPapFmt*/,
++        USHORT nBase, USHORT nNext, USHORT /*nWwId*/, USHORT nId, bool /*bAutoUpdate*/ )
++{
++    OSL_TRACE("%s, rName = '%s'", __PRETTY_FUNCTION__,
++            OUStringToOString( OUString( rName ), m_rExport.eCurrentEncoding ).getStr());
++
++    m_aStylesheet.append('{');
++    m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
++    m_aStylesheet.append( (sal_Int32)nId );
++
++    if ( nBase != 0x0FFF )
++    {
++        m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
++        m_aStylesheet.append((sal_Int32)nBase);
++    }
++
++    m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
++    m_aStylesheet.append((sal_Int32)nNext);
++
++    m_rStyleName = rName;
++    m_nStyleId = nId;
++}
++
++void RtfAttributeOutput::EndStyle()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    m_aStyles.append(m_aStylesEnd.makeStringAndClear());
++    OString aStyles = m_aStyles.makeStringAndClear();
++    m_rExport.InsStyle(m_nStyleId, aStyles);
++    m_aStylesheet.append(aStyles);
++    m_aStylesheet.append(' ');
++    m_aStylesheet.append(OUStringToOString( OUString( m_rStyleName ), m_rExport.eCurrentEncoding ));
++    m_aStylesheet.append(";}");
++    m_aStylesheet.append(m_rExport.sNewLine);
++}
++
++void RtfAttributeOutput::StartStyleProperties( bool /*bParProp*/, USHORT /*nStyle*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    /* noop */
++}
++
++void RtfAttributeOutput::EndStyleProperties( bool /*bParProp*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++    /* noop */
++}
++
++void RtfAttributeOutput::OutlineNumbering( BYTE nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if ( nLvl >= WW8ListManager::nMaxLevel )
++        nLvl = WW8ListManager::nMaxLevel - 1;
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LEVEL);
++    m_aStyles.append((sal_Int32)nLvl);
++}
++
++void RtfAttributeOutput::PageBreakBefore( bool bBreak )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if (bBreak)
++    {
++        m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_PAGEBB;
++    }
++}
++
++void RtfAttributeOutput::SectionBreak( BYTE nC, const WW8_SepInfo* pSectionInfo )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    switch (nC)
++    {
++        case msword::ColumnBreak:
++            m_nColBreakNeeded = true;
++            break;
++        case msword::PageBreak:
++            if ( pSectionInfo )
++                m_rExport.SectionProperties( *pSectionInfo );
++            break;
++    }
++}
++
++void RtfAttributeOutput::StartSection()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECT OOO_STRING_SVTOOLS_RTF_SECTD);
++    if (!m_bBufferSectionBreaks)
++        m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
++}
++
++void RtfAttributeOutput::EndSection()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /*
++     * noop, \sect must go to StartSection or Word won't notice multiple
++     * columns...
++     */
++}
++
++void RtfAttributeOutput::SectionFormProtection( bool bProtected )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
++    m_aSectionBreaks.append((sal_Int32)!bProtected);
++}
++
++void RtfAttributeOutput::SectionLineNumbering( ULONG /*nRestartNo*/, const SwLineNumberInfo& rLnNumInfo )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINEMOD;
++    m_rExport.OutLong(rLnNumInfo.GetCountBy());
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINEX;
++    m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
++    if (!rLnNumInfo.IsRestartEachPage())
++        m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LINECONT;
++}
++
++void RtfAttributeOutput::SectionTitlePage()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    /*
++     * noop, handled in RtfExport::WriteHeaderFooter()
++     */
++}
++
++void RtfAttributeOutput::SectionPageBorders( const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SvxBoxItem& rBox = pFmt->GetBox();
++    const SvxBorderLine *pLine = rBox.GetTop();
++    if(pLine)
++        m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
++                    OOO_STRING_SVTOOLS_RTF_PGBRDRT,
++                    rBox.GetDistance(BOX_LINE_TOP) ));
++    pLine = rBox.GetBottom();
++    if(pLine)
++        m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
++                    OOO_STRING_SVTOOLS_RTF_PGBRDRB,
++                    rBox.GetDistance(BOX_LINE_BOTTOM) ));
++    pLine = rBox.GetLeft();
++    if(pLine)
++        m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
++                    OOO_STRING_SVTOOLS_RTF_PGBRDRL,
++                    rBox.GetDistance(BOX_LINE_LEFT) ));
++    pLine = rBox.GetRight();
++    if(pLine)
++        m_aSectionBreaks.append(OutBorderLine( m_rExport, pLine,
++                    OOO_STRING_SVTOOLS_RTF_PGBRDRR,
++                    rBox.GetDistance(BOX_LINE_RIGHT) ));
++}
++
++void RtfAttributeOutput::SectionBiDi( bool bBiDi )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << (bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT : OOO_STRING_SVTOOLS_RTF_LTRSECT);
++}
++
++void RtfAttributeOutput::SectionPageNumbering( USHORT nNumType, USHORT nPageRestartNumber )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if (nPageRestartNumber > 0)
++    {
++        m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
++        m_aSectionBreaks.append((sal_Int32)nPageRestartNumber);
++        m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
++    }
++
++    const char* pStr = 0;
++    switch ( nNumType )
++    {
++        case SVX_NUM_CHARS_UPPER_LETTER:
++        case SVX_NUM_CHARS_UPPER_LETTER_N:  pStr = OOO_STRING_SVTOOLS_RTF_PGNUCLTR; break;
++        case SVX_NUM_CHARS_LOWER_LETTER:
++        case SVX_NUM_CHARS_LOWER_LETTER_N:  pStr = OOO_STRING_SVTOOLS_RTF_PGNLCLTR; break;
++        case SVX_NUM_ROMAN_UPPER:           pStr = OOO_STRING_SVTOOLS_RTF_PGNUCRM;  break;
++        case SVX_NUM_ROMAN_LOWER:           pStr = OOO_STRING_SVTOOLS_RTF_PGNLCRM;  break;
++
++        case SVX_NUM_ARABIC:                pStr = OOO_STRING_SVTOOLS_RTF_PGNDEC;     break;
++    }
++    if (pStr)
++        m_aSectionBreaks.append(pStr);
++}
++
++void RtfAttributeOutput::SectionType( BYTE nBreakCode )
++{
++    OSL_TRACE("%s, nBreakCode = %d", __PRETTY_FUNCTION__, nBreakCode);
++
++    /*
++     * break code:   0 No break, 1 New column
++     * 2 New page, 3 Even page, 4 Odd page
++     */
++    const char* sType = NULL;
++    switch ( nBreakCode )
++    {
++        case 1:  sType = OOO_STRING_SVTOOLS_RTF_SBKCOL; break;
++        case 2:  sType = OOO_STRING_SVTOOLS_RTF_SBKPAGE; break;
++        case 3:  sType = OOO_STRING_SVTOOLS_RTF_SBKEVEN; break;
++        case 4:  sType = OOO_STRING_SVTOOLS_RTF_SBKODD; break;
++        default: sType = OOO_STRING_SVTOOLS_RTF_SBKNONE; break;
++    }
++    m_aSectionBreaks.append(sType);
++    if (!m_bBufferSectionBreaks)
++        m_rExport.Strm() << m_aSectionBreaks.makeStringAndClear();
++}
++
++void RtfAttributeOutput::NumberingDefinition( USHORT nId, const SwNumRule &/*rRule*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE;
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTID;
++    m_rExport.OutULong(nId);
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT << '0';
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LS;
++    m_rExport.OutULong(nId) << '}';
++}
++
++void RtfAttributeOutput::StartAbstractNumbering( USHORT nId )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LIST << OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID;
++    m_rExport.OutULong( nId );
++    m_nListId = nId;
++}
++
++void RtfAttributeOutput::EndAbstractNumbering()
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LISTID;
++    m_rExport.OutULong( m_nListId ) << '}' << m_rExport.sNewLine;
++}
++
++void RtfAttributeOutput::NumberingLevel( BYTE nLevel,
++        USHORT nStart,
++        USHORT nNumberingType,
++        SvxAdjust eAdjust,
++        const BYTE * pNumLvlPos,
++        BYTE /*nFollow*/,
++        const wwFont * pFont,
++        const SfxItemSet * pOutSet,
++        sal_Int16 nIndentAt,
++        sal_Int16 nFirstLineIndex,
++        sal_Int16 /*nListTabPos*/,
++        const String &rNumberingString )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_rExport.Strm() << m_rExport.sNewLine;
++    if( nLevel > 8 ) // RTF knows only 9 levels
++        m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_IGNORE << OOO_STRING_SVTOOLS_RTF_SOUTLVL;
++
++    m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LISTLEVEL;
++
++    USHORT nVal = 0;
++    switch( nNumberingType )
++    {
++        case SVX_NUM_ROMAN_UPPER:                   nVal = 1;       break;
++        case SVX_NUM_ROMAN_LOWER:                   nVal = 2;       break;
++        case SVX_NUM_CHARS_UPPER_LETTER:
++        case SVX_NUM_CHARS_UPPER_LETTER_N:  nVal = 3;       break;
++        case SVX_NUM_CHARS_LOWER_LETTER:
++        case SVX_NUM_CHARS_LOWER_LETTER_N:  nVal = 4;       break;
++
++        case SVX_NUM_BITMAP:
++        case SVX_NUM_CHAR_SPECIAL:                  nVal = 23;      break;
++    }
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELNFC;
++    m_rExport.OutULong( nVal );
++
++    switch( eAdjust )
++    {
++        case SVX_ADJUST_CENTER:             nVal = 1;       break;
++        case SVX_ADJUST_RIGHT:              nVal = 2;       break;
++        default:                            nVal = 0;       break;
++    }
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELJC;
++    m_rExport.OutULong( nVal );
++
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT;
++    m_rExport.OutULong( nStart );
++
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW << "0";
++
++    // leveltext group
++    m_rExport.Strm() << '{' << OOO_STRING_SVTOOLS_RTF_LEVELTEXT << ' ';
++
++    if( SVX_NUM_CHAR_SPECIAL == nNumberingType ||
++            SVX_NUM_BITMAP == nNumberingType )
++    {
++        m_rExport.Strm() << "\\'01";
++        sal_Unicode cChar = rNumberingString.GetChar(0);
++        m_rExport.Strm() << "\\u";
++        m_rExport.OutULong(cChar);
++        m_rExport.Strm() << " ?";
++    }
++    else
++    {
++        m_rExport.Strm() << "\\'" << m_rExport.OutHex( rNumberingString.Len(), 2 );
++        m_rExport.Strm() << m_rExport.OutString( rNumberingString, m_rExport.eDefaultEncoding );
++    }
++
++    m_rExport.Strm() << ";}";
++
++    // write the levelnumbers
++    m_rExport.Strm() << "{" << OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS;
++    for( BYTE i = 0; i <= nLevel && pNumLvlPos[ i ]; ++i )
++    {
++        m_rExport.Strm() << "\\'" << m_rExport.OutHex(pNumLvlPos[ i ], 2).getStr();
++    }
++    m_rExport.Strm() << ";}";
++
++    if( pOutSet )
++    {
++        if (pFont)
++        {
++            m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_F;
++            m_rExport.OutULong(m_rExport.maFontHelper.GetId(*pFont));
++        }
++        m_rExport.OutputItemSet( *pOutSet, false, true, i18n::ScriptType::LATIN );
++        m_rExport.Strm() << m_aStyles.makeStringAndClear();
++    }
++
++    m_rExport.Strm() << OOO_STRING_SVTOOLS_RTF_FI;
++    m_rExport.OutLong( nFirstLineIndex ) << OOO_STRING_SVTOOLS_RTF_LI;
++    m_rExport.OutLong( nIndentAt );
++    
++    m_rExport.Strm() << '}';
++    if( nLevel > 8 )
++        m_rExport.Strm() << '}';
++}
++
++void RtfAttributeOutput::WriteField_Impl( const SwField* pFld, ww::eField /*eType*/, const String& rFldCmd, BYTE /*nMode*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    // NEEDSWORK this has beeen tested only with page numbers
++    m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
++    m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " ");
++    m_aRunText.append(m_rExport.OutString(rFldCmd, m_rExport.eCurrentEncoding));
++    m_aRunText.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
++    if (pFld)
++        m_aRunText.append(m_rExport.OutString(pFld->GetCntnt(), m_rExport.eDefaultEncoding));
++    m_aRunText.append("}}");
++}
++
++void RtfAttributeOutput::WriteBookmarks_Impl( std::vector< rtl::OUString >& rStarts, std::vector< rtl::OUString >& rEnds )
++{
++    for ( std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it < end; ++it )
++    {
++        m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKSTART " ");
++        m_aRun.append(m_rExport.OutString(*it, m_rExport.eCurrentEncoding));
++        m_aRun.append('}');
++    }
++    rStarts.clear();
++
++    for ( std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it < end; ++it )
++    {
++        m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKEND " ");
++        m_aRun.append(m_rExport.OutString(*it, m_rExport.eCurrentEncoding));
++        m_aRun.append('}');
++    }
++    rEnds.clear();
++}
++
++void RtfAttributeOutput::WriteHeaderFooter_Impl( const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr )
++{
++    OStringBuffer aSectionBreaks = m_aSectionBreaks;
++    m_aSectionBreaks.setLength(0);
++    OStringBuffer aRun = m_aRun;
++    m_aRun.setLength(0);
++
++    m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY : OOO_STRING_SVTOOLS_RTF_FOOTERY);
++    m_aSectionHeaders.append((sal_Int32)m_rExport.pAktPageDesc->GetMaster().GetULSpace().GetUpper());
++    m_aSectionHeaders.append('{');
++    m_aSectionHeaders.append(pStr);
++    m_bBufferSectionHeaders = true;
++    m_rExport.WriteHeaderFooterText(rFmt, bHeader);
++    m_bBufferSectionHeaders = false;
++    m_aSectionHeaders.append('}');
++
++    m_aSectionBreaks = aSectionBreaks;
++    m_aRun = aRun;
++}
++
++void RtfAttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFrame, const Point& /*rNdTopLeft*/ )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const SwNode *pNode = rFrame.GetContent();
++    const SwGrfNode *pGrfNode = pNode ? pNode->GetGrfNode() : 0;
++
++    switch ( rFrame.GetWriterType() )
++    {
++        case sw::Frame::eGraphic:
++            if (!rFrame.IsInline())
++            {
++                m_rExport.mpParentFrame = &rFrame;
++                m_rExport.bRTFFlySyntax = true;
++                m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
++                m_rExport.bRTFFlySyntax = false;
++                m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
++                m_rExport.OutputFormat( rFrame.GetFrmFmt(), false, false, true );
++                m_aRunText.append('}');
++                m_rExport.mpParentFrame = NULL;
++            }
++
++            if ( pGrfNode )
++                FlyFrameGraphic( *pGrfNode, rFrame.GetLayoutSize() );
++            break;
++        case sw::Frame::eDrawing:
++            {
++                const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
++                if ( pSdrObj )
++                {
++                    bool bSwapInPage = false;
++                    if ( !pSdrObj->GetPage() )
++                    {
++                        if ( SdrModel* pModel = m_rExport.pDoc->GetDrawModel() )
++                        {
++                            if ( SdrPage *pPage = pModel->GetPage( 0 ) )
++                            {
++                                bSwapInPage = true;
++                                const_cast< SdrObject* >( pSdrObj )->SetPage( pPage );
++                            }
++                        }
++                    }
++
++                    m_aRunText.append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
++                    m_aRunText.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
++                    m_aRunText.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
++                    m_aRunText.append(" SHAPE ");
++                    m_aRunText.append("}" "{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
++
++                    m_rExport.SdrExporter().AddSdrObject( *pSdrObj );
++
++                    m_aRunText.append('}');
++                    m_aRunText.append('}');
++
++                    if ( bSwapInPage )
++                        const_cast< SdrObject* >( pSdrObj )->SetPage( 0 );
++                }
++            }
++            break;
++        case sw::Frame::eFormControl:
++            {
++                const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
++                const SdrObject *pObject = rFrmFmt.FindRealSdrObject();
++
++                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
++                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST);
++
++                if (pObject && pObject->GetObjInventor() == FmFormInventor)
++                {
++                    if (SdrUnoObj *pFormObj = PTR_CAST(SdrUnoObj,pObject))
++                    {
++                        uno::Reference< awt::XControlModel > xControlModel =
++                            pFormObj->GetUnoControlModel();
++                        uno::Reference< lang::XServiceInfo > xInfo(xControlModel, uno::UNO_QUERY);
++                        uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
++                        uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo();
++                        OUString sName;
++                        if (xInfo->supportsService(C2U("com.sun.star.form.component.CheckBox")))
++                        {
++
++                            m_aRun.append(OUStringToOString(OUString(FieldString(ww::eFORMCHECKBOX)), m_rExport.eCurrentEncoding));
++                            m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFTYPE "1"); // 1 = checkbox
++                            // checkbox size in half points, this seems to be always 20, see WW8Export::DoCheckBox()
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFHPS "20");
++
++                            OUString aStr;
++                            sName = C2U("Name");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aStr;
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
++                                m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            sName = C2U("HelpText");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aStr;
++                                m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
++                                m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            sName = C2U("HelpF1Text");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aStr;
++                                m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
++                                m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            sal_Int16 nTemp = 0;
++                            xPropSet->getPropertyValue(C2U("DefaultState")) >>= nTemp;
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
++                            m_aRun.append((sal_Int32)nTemp);
++                            xPropSet->getPropertyValue(C2U("State")) >>= nTemp;
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFRES);
++                            m_aRun.append((sal_Int32)nTemp);
++
++                            m_aRun.append("}}");
++
++                            // field result is empty, ffres already contains the form result
++                            m_aRun.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
++                        }
++                        else if (xInfo->supportsService(C2U("com.sun.star.form.component.TextField")))
++                        {
++                            OStringBuffer aBuf;
++                            OString aStr;
++                            OUString aTmp;
++                            const sal_Char* pStr;
++
++                            m_aRun.append(OUStringToOString(OUString(FieldString(ww::eFORMTEXT)), m_rExport.eCurrentEncoding));
++                            m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_DATAFIELD " ");
++                            for (int i = 0; i < 8; i++) aBuf.append((sal_Char)0x00);
++                            xPropSet->getPropertyValue(C2U("Name")) >>= aTmp;
++                            aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
++                            aBuf.append((sal_Char)aStr.getLength());
++                            aBuf.append(aStr);
++                            aBuf.append((sal_Char)0x00);
++                            xPropSet->getPropertyValue(C2U("DefaultText")) >>= aTmp;
++                            aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
++                            aBuf.append((sal_Char)aStr.getLength());
++                            aBuf.append(aStr);
++                            for (int i = 0; i < 11; i++) aBuf.append((sal_Char)0x00);
++                            aStr = aBuf.makeStringAndClear();
++                            pStr = aStr.getStr();
++                            for (int i = 0; i < aStr.getLength(); i++, pStr++)
++                                m_aRun.append(m_rExport.OutHex(*pStr, 2));
++                            m_aRun.append('}');
++                            m_aRun.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
++                            xPropSet->getPropertyValue(C2U("Text")) >>= aTmp;
++                            m_aRun.append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
++                            m_aRun.append('}');
++                            m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
++                            sName = C2U("HelpText");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aTmp;
++                                m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
++                                m_aRun.append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            sName = C2U("HelpF1Text");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aTmp;
++                                m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
++                                m_aRun.append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++                            m_aRun.append("}");
++                        }
++                        else if (xInfo->supportsService(C2U("com.sun.star.form.component.ListBox")))
++                        {
++                            OUString aStr;
++                            uno::Sequence<sal_Int16> aIntSeq;
++                            uno::Sequence<OUString> aStrSeq;
++
++                            m_aRun.append(OUStringToOString(OUString(FieldString(ww::eFORMDROPDOWN)), m_rExport.eCurrentEncoding));
++                            m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFTYPE "2"); // 2 = list
++
++                            xPropSet->getPropertyValue(C2U("DefaultSelection")) >>= aIntSeq;
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
++                            // a dropdown list can have only one 'selected item by default'
++                            m_aRun.append((sal_Int32)aIntSeq[0]);
++
++                            xPropSet->getPropertyValue(C2U("SelectedItems")) >>= aIntSeq;
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFRES);
++                            // a dropdown list can have only one 'currently selected item'
++                            m_aRun.append((sal_Int32)aIntSeq[0]);
++
++                            sName = C2U("Name");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aStr;
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
++                                m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            sName = C2U("HelpText");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aStr;
++                                m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
++                                m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            sName = C2U("HelpF1Text");
++                            if (xPropSetInfo->hasPropertyByName(sName))
++                            {
++                                xPropSet->getPropertyValue(sName) >>= aStr;
++                                m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
++                                m_aRun.append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
++                                m_aRun.append('}');
++                            }
++
++                            m_aRun.append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX);
++
++                            xPropSet->getPropertyValue(C2U("StringItemList")) >>= aStrSeq;
++                            sal_uInt32 nListItems = aStrSeq.getLength();
++                            for (sal_uInt32 i = 0; i < nListItems; i++)
++                                m_aRun.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFL " ")
++                                    .append(OUStringToOString(aStrSeq[i], m_rExport.eCurrentEncoding)).append('}');
++
++                            m_aRun.append("}}");
++
++                            // field result is empty, ffres already contains the form result
++                            m_aRun.append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
++                        }
++                        else
++                            OSL_TRACE("%s unhandled form control: '%s'", __PRETTY_FUNCTION__,
++                                    OUStringToOString(xInfo->getImplementationName(), m_rExport.eCurrentEncoding).getStr());
++                        m_aRun.append('}');
++                    }
++                }
++
++                m_aRun.append('}');
++            }
++            break;
++        case sw::Frame::eOle:
++            {
++                const SwFrmFmt &rFrmFmt = rFrame.GetFrmFmt();
++                const SdrObject *pSdrObj = rFrmFmt.FindRealSdrObject();
++                if ( pSdrObj )
++                {
++                    SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
++                    SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
++                    FlyFrameOLE(rOLENd, rFrame.GetLayoutSize());
++                }
++            }
++            break;
++        default:
++            OSL_TRACE("%s: unknown type (%d)", __PRETTY_FUNCTION__, rFrame.GetWriterType());
++            break;
++    }
++}
++
++void RtfAttributeOutput::CharCaseMap( const SvxCaseMapItem& rCaseMap )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    switch ( rCaseMap.GetValue() )
++    {
++        case SVX_CASEMAP_KAPITAELCHEN:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
++            break;
++        case SVX_CASEMAP_VERSALIEN:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
++            break;
++        default: // Something that rtf does not support
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
++            m_aStyles.append((sal_Int32)0);
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
++            m_aStyles.append((sal_Int32)0);
++            break;
++    }
++}
++
++void RtfAttributeOutput::CharColor( const SvxColorItem& rColor )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const Color aColor( rColor.GetValue() );
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CF);
++    m_aStyles.append( (sal_Int32)m_rExport.GetColor( aColor ));
++}
++
++void RtfAttributeOutput::CharContour( const SvxContourItem& rContour )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTL);
++    if ( !rContour.GetValue() )
++        m_aStyles.append((sal_Int32)0);
++}
++
++void RtfAttributeOutput::CharCrossedOut( const SvxCrossedOutItem& rCrossedOut )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    switch ( rCrossedOut.GetStrikeout() )
++    {
++        case STRIKEOUT_NONE:
++            if (!m_bStrikeDouble)
++                m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
++            else
++                m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
++            m_aStyles.append((sal_Int32)0);
++            break;
++        case STRIKEOUT_DOUBLE:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
++            m_aStyles.append((sal_Int32)1);
++            break;
++        default:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
++            break;
++    }
++}
++
++void RtfAttributeOutput::CharEscapement( const SvxEscapementItem& rEsc )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const char * pUpDn;
++
++    SwTwips nH = ((SvxFontHeightItem&)m_rExport.GetItem( RES_CHRATR_FONTSIZE )).GetHeight();
++
++    if( 0 < rEsc.GetEsc() )
++        pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
++    else if( 0 > rEsc.GetEsc() )
++    {
++        pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
++        nH = -nH;
++    }
++    else
++        return;
++
++    short nEsc = rEsc.GetEsc();
++    short nProp = rEsc.GetProp() * 100;
++    if( DFLT_ESC_AUTO_SUPER == nEsc )
++    {
++        nEsc = 100 - rEsc.GetProp();
++        ++nProp;
++    }
++    else if( DFLT_ESC_AUTO_SUB == nEsc )
++    {
++        nEsc = - 100 + rEsc.GetProp();
++        ++nProp;
++    }
++
++    m_aStyles.append('{');
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
++    m_aStyles.append( (sal_Int32)nProp );
++    m_aStyles.append('}');
++    m_aStyles.append(pUpDn);
++
++    /*
++     * Calculate the act. FontSize and the percentage of the displacement;
++     * RTF file expects half points, while internally it's in twips.
++     * Formally :            (FontSize * 1/20 ) pts         x * 2
++     *                    -----------------------  = ------------
++     *                      100%                       Escapement
++     */
++
++    m_aStyles.append( (sal_Int32) ( (long( nEsc ) * nH) + 500L ) / 1000L );
++    // 500L to round !!
++}
++
++void RtfAttributeOutput::CharFont( const SvxFontItem& rFont)
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
++    m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_F);
++    m_aStylesEnd.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
++    m_rExport.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(sw::ms::rtl_TextEncodingToWinCharset(rFont.GetCharSet()));
++}
++
++void RtfAttributeOutput::CharFontSize( const SvxFontHeightItem& rFontSize)
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    switch ( rFontSize.Which() )
++    {
++        case RES_CHRATR_FONTSIZE:
++            m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_FS);
++            m_aStylesEnd.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
++            break;
++        case RES_CHRATR_CJK_FONTSIZE:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
++            m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
++            break;
++        case RES_CHRATR_CTL_FONTSIZE:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AFS);
++            m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10 ));
++            break;
++    }
++}
++
++void RtfAttributeOutput::CharKerning( const SvxKerningItem& rKerning )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    // in quater points then in twips
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
++    m_aStyles.append((sal_Int32)(rKerning.GetValue() / 5));
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
++    m_aStyles.append((sal_Int32)(rKerning.GetValue()));
++}
++
++void RtfAttributeOutput::CharLanguage( const SvxLanguageItem& rLanguage )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    switch (rLanguage.Which())
++    {
++        case RES_CHRATR_LANGUAGE:
++            m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LANG);
++            m_aStylesEnd.append((sal_Int32)rLanguage.GetLanguage());
++            break;
++        case RES_CHRATR_CJK_LANGUAGE:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
++            m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
++            break;
++        case RES_CHRATR_CTL_LANGUAGE:
++            m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANG);
++            m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
++            break;
++    }
++}
++
++void RtfAttributeOutput::CharPosture( const SvxPostureItem& rPosture )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
++    if ( rPosture.GetPosture() == ITALIC_NONE )
++        m_aStyles.append((sal_Int32)0);
++}
++
++void RtfAttributeOutput::CharShadow( const SvxShadowedItem& rShadow )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
++    if ( !rShadow.GetValue() )
++        m_aStyles.append((sal_Int32)0);
++}
++
++void RtfAttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    const char* pStr = 0;
++    const SfxPoolItem* pItem = m_rExport.HasItem( RES_CHRATR_WORDLINEMODE );
++    bool bWord = false;
++    if (pItem)
++        bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
++    switch(rUnderline.GetLineStyle() )
++    {
++        case UNDERLINE_SINGLE:
++            pStr = bWord ? OOO_STRING_SVTOOLS_RTF_ULW : OOO_STRING_SVTOOLS_RTF_UL;
++            break;
++        case UNDERLINE_DOUBLE:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
++            break;
++        case UNDERLINE_NONE:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
++            break;
++        case UNDERLINE_DOTTED:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULD;
++            break;
++        case UNDERLINE_DASH:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
++            break;
++        case UNDERLINE_DASHDOT:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
++            break;
++        case UNDERLINE_DASHDOTDOT:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
++            break;
++        case UNDERLINE_BOLD:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
++            break;
++        case UNDERLINE_WAVE:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
++            break;
++        case UNDERLINE_BOLDDOTTED:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
++            break;
++        case UNDERLINE_BOLDDASH:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
++            break;
++        case UNDERLINE_LONGDASH:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
++            break;
++        case UNDERLINE_BOLDLONGDASH:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
++            break;
++        case UNDERLINE_BOLDDASHDOT:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
++            break;
++        case UNDERLINE_BOLDDASHDOTDOT:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
++            break;
++        case UNDERLINE_BOLDWAVE:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
++            break;
++        case UNDERLINE_DOUBLEWAVE:
++            pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
++            break;
++        default:
++            break;
++    }
++
++    if( pStr )
++    {
++        m_aStyles.append(pStr);
++        // NEEDSWORK looks like here rUnderline.GetColor() is always black,
++        // even if the color in the odt is for example green...
++        m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
++        m_aStyles.append( (sal_Int32)m_rExport.GetColor(rUnderline.GetColor()) );
++    }
++}
++
++void RtfAttributeOutput::CharWeight( const SvxWeightItem& rWeight )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
++    if ( rWeight.GetWeight() != WEIGHT_BOLD )
++        m_aStyles.append((sal_Int32)0);
++}
++
++void RtfAttributeOutput::CharAutoKern( const SvxAutoKernItem& rAutoKern)
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
++    m_aStyles.append((sal_Int32) (rAutoKern.GetValue() ? 1 : 0));
++}
++
++void RtfAttributeOutput::CharAnimatedText( const SvxBlinkItem& rBlink )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
++    m_aStyles.append((sal_Int32) (rBlink.GetValue() ? 2 : 0));
++}
++
++void RtfAttributeOutput::CharBackground( const SvxBrushItem& rBrush )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    if( !rBrush.GetColor().GetTransparency() )
++    {
++        m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHCBPAT);
++        m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
++    }
++}
++
++void RtfAttributeOutput::CharFontCJK( const SvxFontItem& rFont )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HICH);
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
++    m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
++}
++
++void RtfAttributeOutput::CharFontSizeCJK( const SvxFontHeightItem& rFontSize )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    CharFontSize( rFontSize );
++}
++
++void RtfAttributeOutput::CharLanguageCJK( const SvxLanguageItem& rLanguageItem )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    CharLanguage( rLanguageItem );
++}
++
++void RtfAttributeOutput::CharPostureCJK( const SvxPostureItem& rPosture )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
++    if ( rPosture.GetPosture() == ITALIC_NONE )
++        m_aStyles.append((sal_Int32)0);
++}
++
++void RtfAttributeOutput::CharWeightCJK( const SvxWeightItem& rWeight )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
++    if ( rWeight.GetWeight() != WEIGHT_BOLD )
++        m_aStyles.append((sal_Int32)0);
++}
++
++void RtfAttributeOutput::CharFontCTL( const SvxFontItem& rFont )
++{
++    OSL_TRACE("%s", __PRETTY_FUNCTION__);
++
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
++    m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
++    m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
++}
++

... etc. - the rest is truncated


More information about the ooo-build-commit mailing list