LCOV - code coverage report
Current view: top level - sw/source/filter/ww8 - rtfattributeoutput.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1664 2179 76.4 %
Date: 2014-11-03 Functions: 148 180 82.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <cstring>
      21             : #include "rtfattributeoutput.hxx"
      22             : #include "rtfsdrexport.hxx"
      23             : #include "writerwordglue.hxx"
      24             : #include "ww8par.hxx"
      25             : #include "fmtcntnt.hxx"
      26             : #include "fchrfmt.hxx"
      27             : #include <svtools/rtfkeywd.hxx>
      28             : #include <editeng/fontitem.hxx>
      29             : #include <editeng/tstpitem.hxx>
      30             : #include <editeng/adjustitem.hxx>
      31             : #include <editeng/spltitem.hxx>
      32             : #include <editeng/widwitem.hxx>
      33             : #include <editeng/keepitem.hxx>
      34             : #include <editeng/brushitem.hxx>
      35             : #include <editeng/postitem.hxx>
      36             : #include <editeng/wghtitem.hxx>
      37             : #include <editeng/kernitem.hxx>
      38             : #include <editeng/crossedoutitem.hxx>
      39             : #include <editeng/cmapitem.hxx>
      40             : #include <editeng/wrlmitem.hxx>
      41             : #include <editeng/udlnitem.hxx>
      42             : #include <editeng/langitem.hxx>
      43             : #include <editeng/escapementitem.hxx>
      44             : #include <editeng/fhgtitem.hxx>
      45             : #include <editeng/colritem.hxx>
      46             : #include <editeng/hyphenzoneitem.hxx>
      47             : #include <editeng/ulspitem.hxx>
      48             : #include <editeng/boxitem.hxx>
      49             : #include <editeng/contouritem.hxx>
      50             : #include <editeng/shdditem.hxx>
      51             : #include <editeng/autokernitem.hxx>
      52             : #include <editeng/emphasismarkitem.hxx>
      53             : #include <editeng/twolinesitem.hxx>
      54             : #include <editeng/charscaleitem.hxx>
      55             : #include <editeng/charrotateitem.hxx>
      56             : #include <editeng/charreliefitem.hxx>
      57             : #include <editeng/paravertalignitem.hxx>
      58             : #include <editeng/frmdiritem.hxx>
      59             : #include <editeng/blinkitem.hxx>
      60             : #include <editeng/charhiddenitem.hxx>
      61             : #include <editeng/shaditem.hxx>
      62             : #include <editeng/opaqitem.hxx>
      63             : #include <svx/fmglob.hxx>
      64             : #include <svx/svdouno.hxx>
      65             : #include <filter/msfilter/rtfutil.hxx>
      66             : #include <sfx2/sfxbasemodel.hxx>
      67             : #include <svx/xflgrit.hxx>
      68             : #include <drawdoc.hxx>
      69             : #include <docufld.hxx>
      70             : #include <fmtclds.hxx>
      71             : #include <fmtinfmt.hxx>
      72             : #include <fmtftn.hxx>
      73             : #include <fmtrowsplt.hxx>
      74             : #include <fmtline.hxx>
      75             : #include <fmtanchr.hxx>
      76             : #include <htmltbl.hxx>
      77             : #include <ndgrf.hxx>
      78             : #include <ndtxt.hxx>
      79             : #include <pagedesc.hxx>
      80             : #include <swmodule.hxx>
      81             : #include <txtftn.hxx>
      82             : #include <txtinet.hxx>
      83             : #include <grfatr.hxx>
      84             : #include <ndole.hxx>
      85             : #include <lineinfo.hxx>
      86             : #include <rtf.hxx>
      87             : #include <IDocumentDrawModelAccess.hxx>
      88             : #include <vcl/cvtgrf.hxx>
      89             : #include <oox/mathml/export.hxx>
      90             : #include <com/sun/star/i18n/ScriptType.hpp>
      91             : 
      92             : using ::editeng::SvxBorderLine;
      93             : using namespace nsSwDocInfoSubType;
      94             : using namespace nsFieldFlags;
      95             : using namespace sw::util;
      96             : using namespace ::com::sun::star;
      97             : 
      98         906 : static OString OutTBLBorderLine(RtfExport& rExport, const SvxBorderLine* pLine, const sal_Char* pStr)
      99             : {
     100         906 :     OStringBuffer aRet;
     101         906 :     if (!pLine->isEmpty())
     102             :     {
     103         906 :         aRet.append(pStr);
     104             :         // single line
     105         906 :         switch (pLine->GetBorderLineStyle())
     106             :         {
     107             :         case table::BorderLineStyle::SOLID:
     108             :         {
     109         906 :             if (DEF_LINE_WIDTH_0 == pLine->GetWidth())
     110         764 :                 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRHAIR);
     111             :             else
     112         142 :                 aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRS);
     113             :         }
     114         906 :         break;
     115             :         case table::BorderLineStyle::DOTTED:
     116           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDOT);
     117           0 :             break;
     118             :         case table::BorderLineStyle::DASHED:
     119           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDASH);
     120           0 :             break;
     121             :         case table::BorderLineStyle::DOUBLE:
     122           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRDB);
     123           0 :             break;
     124             :         case table::BorderLineStyle::THINTHICK_SMALLGAP:
     125           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHSG);
     126           0 :             break;
     127             :         case table::BorderLineStyle::THINTHICK_MEDIUMGAP:
     128           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHMG);
     129           0 :             break;
     130             :         case table::BorderLineStyle::THINTHICK_LARGEGAP:
     131           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTNTHLG);
     132           0 :             break;
     133             :         case table::BorderLineStyle::THICKTHIN_SMALLGAP:
     134           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNSG);
     135           0 :             break;
     136             :         case table::BorderLineStyle::THICKTHIN_MEDIUMGAP:
     137           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNMG);
     138           0 :             break;
     139             :         case table::BorderLineStyle::THICKTHIN_LARGEGAP:
     140           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTHTNLG);
     141           0 :             break;
     142             :         case table::BorderLineStyle::EMBOSSED:
     143           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDREMBOSS);
     144           0 :             break;
     145             :         case table::BorderLineStyle::ENGRAVED:
     146           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRENGRAVE);
     147           0 :             break;
     148             :         case table::BorderLineStyle::OUTSET:
     149           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDROUTSET);
     150           0 :             break;
     151             :         case table::BorderLineStyle::INSET:
     152           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRINSET);
     153           0 :             break;
     154             :         case table::BorderLineStyle::NONE:
     155             :         default:
     156           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRNONE);
     157           0 :             break;
     158             :         }
     159             : 
     160         906 :         double const fConverted(::editeng::ConvertBorderWidthToWord(pLine->GetBorderLineStyle(), pLine->GetWidth()));
     161         906 :         if (255 >= pLine->GetWidth())   // That value comes from RTF specs
     162             :         {
     163         906 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRW).append(static_cast<sal_Int32>(fConverted));
     164             :         }
     165             :         else
     166             :         {
     167             :             // use \brdrth to double the value range...
     168           0 :             aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRTH OOO_STRING_SVTOOLS_RTF_BRDRW);
     169           0 :             aRet.append(static_cast<sal_Int32>(fConverted) / 2);
     170             :         }
     171             : 
     172         906 :         aRet.append(OOO_STRING_SVTOOLS_RTF_BRDRCF);
     173         906 :         aRet.append((sal_Int32)rExport.GetColor(pLine->GetColor()));
     174             :     }
     175         906 :     return aRet.makeStringAndClear();
     176             : }
     177             : 
     178         106 : static OString OutBorderLine(RtfExport& rExport, const SvxBorderLine* pLine,
     179             :                              const sal_Char* pStr, sal_uInt16 nDist, SvxShadowLocation eShadowLocation = SVX_SHADOW_NONE)
     180             : {
     181         106 :     OStringBuffer aRet;
     182         106 :     aRet.append(OutTBLBorderLine(rExport, pLine, pStr));
     183         106 :     aRet.append(OOO_STRING_SVTOOLS_RTF_BRSP);
     184         106 :     aRet.append((sal_Int32)nDist);
     185         106 :     if (eShadowLocation == SVX_SHADOW_BOTTOMRIGHT)
     186          12 :         aRet.append(LO_STRING_SVTOOLS_RTF_BRDRSH);
     187         106 :     return aRet.makeStringAndClear();
     188             : }
     189             : 
     190        1388 : void RtfAttributeOutput::RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript)
     191             : {
     192             :     /*
     193             :        You would have thought that
     194             :        m_rExport.Strm() << (bIsRTL ? OOO_STRING_SVTOOLS_RTF_RTLCH : OOO_STRING_SVTOOLS_RTF_LTRCH); would be sufficient here ,
     195             :        but looks like word needs to see the other directional token to be
     196             :        satisified that all is kosher, otherwise it seems in ver 2003 to go and
     197             :        semi-randomlyly stick strike through about the place. Perhaps
     198             :        strikethrough is some ms developers "something is wrong signal" debugging
     199             :        code that we're triggering ?
     200             :        */
     201        1388 :     if (bIsRTL)
     202             :     {
     203           0 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
     204           0 :         m_aStylesEnd.append(' ');
     205           0 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
     206             :     }
     207             :     else
     208             :     {
     209        1388 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_RTLCH);
     210        1388 :         m_aStylesEnd.append(' ');
     211        1388 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LTRCH);
     212             :     }
     213             : 
     214        1388 :     switch (nScript)
     215             :     {
     216             :     case i18n::ScriptType::LATIN:
     217        1292 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
     218        1292 :         break;
     219             :     case i18n::ScriptType::ASIAN:
     220           2 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_DBCH);
     221           2 :         break;
     222             :     case i18n::ScriptType::COMPLEX:
     223             :         /* noop */
     224           0 :         break;
     225             :     default:
     226             :         /* should not happen? */
     227          94 :         break;
     228             :     }
     229        1388 : }
     230             : 
     231        1174 : void RtfAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo)
     232             : {
     233             :     // Output table/table row/table cell starts if needed
     234        1174 :     if (pTextNodeInfo.get())
     235             :     {
     236         380 :         sal_uInt32 nRow = pTextNodeInfo->getRow();
     237         380 :         sal_uInt32 nCell = pTextNodeInfo->getCell();
     238             : 
     239             :         // New cell/row?
     240         380 :         if (m_nTableDepth > 0 && !m_bTableCellOpen)
     241             :         {
     242         292 :             ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner(pTextNodeInfo->getInnerForDepth(m_nTableDepth));
     243             :             OSL_ENSURE(pDeepInner, "TableNodeInfoInner not found");
     244             :             // Make sure we always start a row between ending one and starting a cell.
     245             :             // In case of subtables, we may not get the first cell.
     246         292 :             if (pDeepInner && (pDeepInner->getCell() == 0 || m_bTableRowEnded))
     247             :             {
     248          78 :                 m_bTableRowEnded = false;
     249          78 :                 StartTableRow(pDeepInner);
     250             :             }
     251             : 
     252         292 :             StartTableCell(pDeepInner);
     253             :         }
     254             : 
     255             :         // Again, if depth was incremented, start a new table even if we skipped the first cell.
     256         380 :         if ((nRow == 0 && nCell == 0) || (m_nTableDepth == 0 && pTextNodeInfo->getDepth()))
     257             :         {
     258             :             // Do we have to start the table?
     259             :             // [If we are at the right depth already, it means that we
     260             :             // continue the table cell]
     261          40 :             sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
     262             : 
     263          40 :             if (nCurrentDepth > m_nTableDepth)
     264             :             {
     265             :                 // Start all the tables that begin here
     266          80 :                 for (sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth)
     267             :                 {
     268          40 :                     ww8::WW8TableNodeInfoInner::Pointer_t pInner(pTextNodeInfo->getInnerForDepth(nDepth));
     269             : 
     270          40 :                     m_bLastTable = (nDepth == pTextNodeInfo->getDepth());
     271          40 :                     StartTable(pInner);
     272          40 :                     StartTableRow(pInner);
     273          40 :                     StartTableCell(pInner);
     274          40 :                 }
     275             : 
     276          40 :                 m_nTableDepth = nCurrentDepth;
     277             :             }
     278             :         }
     279             :     }
     280             : 
     281             :     OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty");
     282        1174 : }
     283             : 
     284        1174 : void RtfAttributeOutput::EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)
     285             : {
     286        1174 :     bool bLastPara = false;
     287        1174 :     if (m_rExport.nTxtTyp == TXT_FTN || m_rExport.nTxtTyp == TXT_EDN)
     288             :     {
     289             :         // We're ending a paragraph that is the last paragraph of a footnote or endnote.
     290           6 :         bLastPara = m_rExport.m_nCurrentNodeIndex && m_rExport.m_nCurrentNodeIndex == m_rExport.pCurPam->End()->nNode.GetIndex();
     291             :     }
     292             : 
     293        1174 :     FinishTableRowCell(pTextNodeInfoInner);
     294             : 
     295        1174 :     RtfStringBuffer aParagraph;
     296             : 
     297        1174 :     aParagraph.appendAndClear(m_aRun);
     298        1174 :     aParagraph->append(m_aAfterRuns.makeStringAndClear());
     299        1174 :     if (m_bTblAfterCell)
     300         332 :         m_bTblAfterCell = false;
     301             :     else
     302             :     {
     303         842 :         aParagraph->append(SAL_NEWLINE_STRING);
     304             :         // RTF_PAR at the end of the footnote would cause an additional empty paragraph.
     305         842 :         if (!bLastPara)
     306             :         {
     307         836 :             aParagraph->append(OOO_STRING_SVTOOLS_RTF_PAR);
     308         836 :             aParagraph->append(' ');
     309             :         }
     310             :     }
     311        1174 :     if (m_nColBreakNeeded)
     312             :     {
     313          14 :         aParagraph->append(OOO_STRING_SVTOOLS_RTF_COLUMN);
     314          14 :         m_nColBreakNeeded = false;
     315             :     }
     316             : 
     317        1174 :     if (!m_bBufferSectionHeaders)
     318        1156 :         aParagraph.makeStringAndClear(this);
     319             :     else
     320          18 :         m_aSectionHeaders.append(aParagraph.makeStringAndClear());
     321        1174 : }
     322             : 
     323           0 : void RtfAttributeOutput::EmptyParagraph()
     324             : {
     325           0 :     m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAR).WriteChar(' ');
     326           0 : }
     327             : 
     328        1174 : void RtfAttributeOutput::SectionBreaks(const SwTxtNode& rNode)
     329             : {
     330             :     OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
     331             : 
     332             :     // output page/section breaks
     333        1174 :     SwNodeIndex aNextIndex(rNode, 1);
     334        1174 :     m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
     335        1174 :     m_bBufferSectionBreaks = true;
     336             : 
     337             :     // output section headers / footers
     338        1174 :     if (!m_bBufferSectionHeaders)
     339        1156 :         m_rExport.Strm().WriteCharPtr(m_aSectionHeaders.makeStringAndClear().getStr());
     340             : 
     341        1174 :     if (aNextIndex.GetNode().IsTxtNode())
     342             :     {
     343         590 :         const SwTxtNode* pTxtNode = static_cast< SwTxtNode* >(&aNextIndex.GetNode());
     344         590 :         m_rExport.OutputSectionBreaks(pTxtNode->GetpSwAttrSet(), *pTxtNode);
     345             :         // Save the current page description for now, so later we will be able to access the previous one.
     346         590 :         m_pPrevPageDesc = pTxtNode->FindPageDesc(false);
     347             :     }
     348         584 :     else if (aNextIndex.GetNode().IsTableNode())
     349             :     {
     350          20 :         const SwTableNode* pTableNode = static_cast< SwTableNode* >(&aNextIndex.GetNode());
     351          20 :         const SwFrmFmt* pFmt = pTableNode->GetTable().GetFrmFmt();
     352          20 :         m_rExport.OutputSectionBreaks(&(pFmt->GetAttrSet()), *pTableNode);
     353             :     }
     354        1174 :     m_bBufferSectionBreaks = false;
     355        1174 : }
     356             : 
     357        1174 : void RtfAttributeOutput::StartParagraphProperties()
     358             : {
     359        1174 :     OStringBuffer aPar;
     360        1174 :     if (!m_rExport.bRTFFlySyntax)
     361             :     {
     362        1128 :         aPar.append(OOO_STRING_SVTOOLS_RTF_PARD);
     363        1128 :         aPar.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
     364        1128 :         aPar.append(' ');
     365             :     }
     366        1174 :     if (!m_bBufferSectionHeaders)
     367        1156 :         m_rExport.Strm().WriteCharPtr(aPar.makeStringAndClear().getStr());
     368             :     else
     369          18 :         m_aSectionHeaders.append(aPar.makeStringAndClear());
     370        1174 : }
     371             : 
     372        1174 : void RtfAttributeOutput::EndParagraphProperties(const SfxItemSet& /*rParagraphMarkerProperties*/, const SwRedlineData* /*pRedlineData*/, const SwRedlineData* /*pRedlineParagraphMarkerDeleted*/, const SwRedlineData* /*pRedlineParagraphMarkerInserted*/)
     373             : {
     374        1174 :     m_aStyles.append(m_aStylesEnd.makeStringAndClear());
     375        1174 :     m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
     376        1174 : }
     377             : 
     378        1398 : void RtfAttributeOutput::StartRun(const SwRedlineData* pRedlineData, bool bSingleEmptyRun)
     379             : {
     380             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", bSingleEmptyRun: " << bSingleEmptyRun);
     381             : 
     382        1398 :     m_bInRun = true;
     383        1398 :     m_bSingleEmptyRun = bSingleEmptyRun;
     384        1398 :     if (!m_bSingleEmptyRun)
     385         896 :         m_aRun->append('{');
     386             : 
     387             :     // if there is some redlining in the document, output it
     388        1398 :     Redline(pRedlineData);
     389             : 
     390             :     OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
     391        1398 : }
     392             : 
     393        1398 : void RtfAttributeOutput::EndRun()
     394             : {
     395        1398 :     m_aRun->append(SAL_NEWLINE_STRING);
     396        1398 :     m_aRun.appendAndClear(m_aRunText);
     397        1398 :     if (!m_bSingleEmptyRun && m_bInRun)
     398         896 :         m_aRun->append('}');
     399        1398 :     m_bInRun = false;
     400        1398 : }
     401             : 
     402        1388 : void RtfAttributeOutput::StartRunProperties()
     403             : {
     404             :     OSL_ENSURE(m_aStyles.getLength() == 0, "m_aStyles is not empty");
     405        1388 : }
     406             : 
     407        1388 : void RtfAttributeOutput::EndRunProperties(const SwRedlineData* /*pRedlineData*/)
     408             : {
     409        1388 :     m_aStyles.append(m_aStylesEnd.makeStringAndClear());
     410        1388 :     m_aRun->append(m_aStyles.makeStringAndClear());
     411        1388 : }
     412             : 
     413         730 : void RtfAttributeOutput::RunText(const OUString& rText, rtl_TextEncoding /*eCharSet*/)
     414             : {
     415             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rText: " << rText);
     416         730 :     RawText(rText, false, m_rExport.eCurrentEncoding);
     417         730 : }
     418             : 
     419        4836 : OStringBuffer& RtfAttributeOutput::RunText()
     420             : {
     421        4836 :     return m_aRunText.getLastBuffer();
     422             : }
     423             : 
     424         730 : void RtfAttributeOutput::RawText(const OUString& rText, bool /*bForceUnicode*/, rtl_TextEncoding eCharSet)
     425             : {
     426         730 :     m_aRunText->append(msfilter::rtfutil::OutString(rText, eCharSet));
     427         730 : }
     428             : 
     429           0 : void RtfAttributeOutput::StartRuby(const SwTxtNode& /*rNode*/, sal_Int32 /*nPos*/, const SwFmtRuby& /*rRuby*/)
     430             : {
     431             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     432           0 : }
     433             : 
     434           0 : void RtfAttributeOutput::EndRuby()
     435             : {
     436             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     437           0 : }
     438             : 
     439           6 : bool RtfAttributeOutput::StartURL(const OUString& rUrl, const OUString& rTarget)
     440             : {
     441           6 :     m_aStyles.append('{');
     442           6 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FIELD);
     443           6 :     m_aStyles.append('{');
     444           6 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
     445           6 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FLDINST);
     446           6 :     m_aStyles.append(" HYPERLINK ");
     447             : 
     448           6 :     OUString sURL(rUrl);
     449           6 :     if (!sURL.isEmpty())
     450             :     {
     451           6 :         m_aStyles.append("\"");
     452           6 :         m_aStyles.append(msfilter::rtfutil::OutString(sURL, m_rExport.eCurrentEncoding));
     453           6 :         m_aStyles.append("\" ");
     454             :     }
     455             : 
     456           6 :     if (!rTarget.isEmpty())
     457             :     {
     458           0 :         m_aStyles.append("\\\\t \"");
     459           0 :         m_aStyles.append(msfilter::rtfutil::OutString(rTarget, m_rExport.eCurrentEncoding));
     460           0 :         m_aStyles.append("\" ");
     461             :     }
     462             : 
     463           6 :     m_aStyles.append("}");
     464           6 :     m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
     465           6 :     return true;
     466             : }
     467             : 
     468           6 : bool RtfAttributeOutput::EndURL(bool const isAtEndOfParagraph)
     469             : {
     470             :     // UGLY: usually EndRun is called earlier, but there is an extra
     471             :     // call to OutAttrWithRange() when at the end of the paragraph,
     472             :     // so in that special case the output needs to be appended to the
     473             :     // new run's text instead of the previous run
     474           6 :     if (isAtEndOfParagraph)
     475             :     {
     476             :         // close the fldrslt group
     477           2 :         m_aRunText->append("}}");
     478             :         // close the field group
     479           2 :         m_aRunText->append('}');
     480             :     }
     481             :     else
     482             :     {
     483             :         // close the fldrslt group
     484           4 :         m_aRun->append("}}");
     485             :         // close the field group
     486           4 :         m_aRun->append('}');
     487             :     }
     488           6 :     return true;
     489             : }
     490             : 
     491           0 : void RtfAttributeOutput::FieldVanish(const OUString& /*rTxt*/, ww::eField /*eType*/)
     492             : {
     493             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     494           0 : }
     495             : 
     496        1398 : void RtfAttributeOutput::Redline(const SwRedlineData* pRedline)
     497             : {
     498        1398 :     if (!pRedline)
     499        2796 :         return;
     500             : 
     501           0 :     if (pRedline->GetType() == nsRedlineType_t::REDLINE_INSERT)
     502             :     {
     503           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED);
     504           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH);
     505           0 :         m_aRun->append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
     506           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM);
     507             :     }
     508           0 :     else if (pRedline->GetType() == nsRedlineType_t::REDLINE_DELETE)
     509             :     {
     510           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_DELETED);
     511           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL);
     512           0 :         m_aRun->append((sal_Int32)m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())));
     513           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL);
     514             :     }
     515           0 :     m_aRun->append((sal_Int32)sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()));
     516           0 :     m_aRun->append(' ');
     517             : }
     518             : 
     519           0 : void RtfAttributeOutput::FormatDrop(const SwTxtNode& /*rNode*/, const SwFmtDrop& /*rSwFmtDrop*/, sal_uInt16 /*nStyle*/, ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, ww8::WW8TableNodeInfoInner::Pointer_t /*pTextNodeInfoInner*/)
     520             : {
     521             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     522           0 : }
     523             : 
     524        1174 : void RtfAttributeOutput::ParagraphStyle(sal_uInt16 nStyle)
     525             : {
     526        1174 :     OString* pStyle = m_rExport.GetStyle(nStyle);
     527        1174 :     OStringBuffer aStyle;
     528        1174 :     aStyle.append(OOO_STRING_SVTOOLS_RTF_S);
     529        1174 :     aStyle.append((sal_Int32)nStyle);
     530        1174 :     if (pStyle)
     531        1174 :         aStyle.append(pStyle->getStr());
     532        1174 :     if (!m_bBufferSectionHeaders)
     533        1156 :         m_rExport.Strm().WriteCharPtr(aStyle.makeStringAndClear().getStr());
     534             :     else
     535          18 :         m_aSectionHeaders.append(aStyle.makeStringAndClear());
     536        1174 : }
     537             : 
     538         380 : void RtfAttributeOutput::TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
     539             : {
     540         380 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_INTBL);
     541         380 :     if (m_nTableDepth > 1)
     542             :     {
     543           0 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ITAP);
     544           0 :         m_aStyles.append((sal_Int32)m_nTableDepth);
     545             :     }
     546         380 :     m_bWroteCellInfo = true;
     547         380 : }
     548             : 
     549           0 : void RtfAttributeOutput::TableInfoRow(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfo*/)
     550             : {
     551             :     /* noop */
     552           0 : }
     553             : 
     554         118 : void RtfAttributeOutput::TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     555             : {
     556         118 :     if (!m_pTableWrt)
     557          40 :         InitTableHelper(pTableTextNodeInfoInner);
     558             : 
     559         118 :     const SwTable* pTbl = pTableTextNodeInfoInner->getTable();
     560         118 :     SwFrmFmt* pFmt = pTbl->GetFrmFmt();
     561             : 
     562         118 :     m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TROWD);
     563         118 :     TableOrientation(pTableTextNodeInfoInner);
     564         118 :     TableBidi(pTableTextNodeInfoInner);
     565         118 :     TableHeight(pTableTextNodeInfoInner);
     566         118 :     TableCanSplit(pTableTextNodeInfoInner);
     567             : 
     568             :     // Cell margins
     569         118 :     const SvxBoxItem& rBox = pFmt->GetBox();
     570             :     static const sal_uInt16 aBorders[] =
     571             :     {
     572             :         BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
     573             :     };
     574             : 
     575             :     static const char* aRowPadNames[] =
     576             :     {
     577             :         OOO_STRING_SVTOOLS_RTF_TRPADDT, OOO_STRING_SVTOOLS_RTF_TRPADDL, OOO_STRING_SVTOOLS_RTF_TRPADDB, OOO_STRING_SVTOOLS_RTF_TRPADDR
     578             :     };
     579             : 
     580             :     static const char* aRowPadUnits[] =
     581             :     {
     582             :         OOO_STRING_SVTOOLS_RTF_TRPADDFT, OOO_STRING_SVTOOLS_RTF_TRPADDFL, OOO_STRING_SVTOOLS_RTF_TRPADDFB, OOO_STRING_SVTOOLS_RTF_TRPADDFR
     583             :     };
     584             : 
     585         590 :     for (int i = 0; i < 4; ++i)
     586             :     {
     587         472 :         m_aRowDefs.append(aRowPadUnits[i]);
     588         472 :         m_aRowDefs.append((sal_Int32)3);
     589         472 :         m_aRowDefs.append(aRowPadNames[i]);
     590         472 :         m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
     591             :     }
     592             : 
     593             :     // The cell-dependent properties
     594         118 :     const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
     595         118 :     SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
     596         118 :     SwTwips nSz = 0;
     597         118 :     Point aPt;
     598         118 :     SwRect aRect(pFmt->FindLayoutRect(false, &aPt));
     599         118 :     SwTwips nPageSize = aRect.Width();
     600             : 
     601             :     // Handle the page size when not rendered
     602         118 :     if (0 == nPageSize)
     603             :     {
     604         100 :         const SwNode* pNode = pTableTextNodeInfoInner->getNode();
     605         104 :         const SwFrmFmt* pFrmFmt = GetExport().mpParentFrame ? &GetExport().mpParentFrame->GetFrmFmt() :
     606         104 :                                   GetExport().pDoc->GetPageDesc(0).GetPageFmtOfNode(*pNode, false);
     607             : 
     608         100 :         const SvxLRSpaceItem& rLR = pFrmFmt->GetLRSpace();
     609         200 :         nPageSize = pFrmFmt->GetFrmSize().GetWidth() -
     610         200 :                     rLR.GetLeft() - rLR.GetRight();
     611             :     }
     612         118 :     SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
     613             :     // Not using m_nTableDepth, which is not yet incremented here.
     614         118 :     sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
     615         118 :     m_aCells[nCurrentDepth] = pRow->GetCells().size();
     616         512 :     for (sal_uInt16 i = 0; i < m_aCells[nCurrentDepth]; i++)
     617             :     {
     618         394 :         const SwWriteTableCell* pCell = &pRow->GetCells()[ i ];
     619         394 :         const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
     620             : 
     621         394 :         pTableTextNodeInfoInner->setCell(i);
     622         394 :         TableCellProperties(pTableTextNodeInfoInner);
     623             : 
     624             :         // Right boundary: this can't be in TableCellProperties as the old
     625             :         // value of nSz is needed.
     626         394 :         nSz += pCellFmt->GetFrmSize().GetWidth();
     627         394 :         m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CELLX);
     628         394 :         SwTwips nCalc = nSz;
     629         394 :         nCalc *= nPageSize;
     630         394 :         nCalc /= nTblSz;
     631         394 :         m_aRowDefs.append((sal_Int32)(pFmt->GetLRSpace().GetLeft() + nCalc));
     632             :     }
     633         118 : }
     634             : 
     635         394 : void RtfAttributeOutput::TableDefaultBorders(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     636             : {
     637             :     /*
     638             :      * The function name is a bit misleading: given that we write borders
     639             :      * before each row, we just have borders, not default ones. Additionally,
     640             :      * this function actually writes borders for a specific cell only and is
     641             :      * called for each cell.
     642             :      */
     643             : 
     644         394 :     const SwTableBox* pTblBox = pTableTextNodeInfoInner->getTableBox();
     645         394 :     SwFrmFmt* pFmt = pTblBox->GetFrmFmt();
     646         394 :     const SvxBoxItem& rDefault = pFmt->GetBox();
     647         394 :     const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
     648         394 :     SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
     649         394 :     const SwWriteTableCell* pCell = &pRow->GetCells()[ pTableTextNodeInfoInner->getCell() ];
     650         394 :     const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
     651             :     const SfxPoolItem* pItem;
     652         394 :     if (pCellFmt->GetAttrSet().HasItem(RES_BOX, &pItem))
     653             :     {
     654         386 :         const SvxBoxItem& rBox = (SvxBoxItem&)*pItem;
     655             :         static const sal_uInt16 aBorders[] =
     656             :         {
     657             :             BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
     658             :         };
     659             :         static const char* aBorderNames[] =
     660             :         {
     661             :             OOO_STRING_SVTOOLS_RTF_CLBRDRT, OOO_STRING_SVTOOLS_RTF_CLBRDRL, OOO_STRING_SVTOOLS_RTF_CLBRDRB, OOO_STRING_SVTOOLS_RTF_CLBRDRR
     662             :         };
     663             :         //Yes left and top are swapped with eachother for cell padding! Because
     664             :         //that's what the thunderingly annoying rtf export/import word xp does.
     665             :         static const char* aCellPadNames[] =
     666             :         {
     667             :             OOO_STRING_SVTOOLS_RTF_CLPADL, OOO_STRING_SVTOOLS_RTF_CLPADT, OOO_STRING_SVTOOLS_RTF_CLPADB, OOO_STRING_SVTOOLS_RTF_CLPADR
     668             :         };
     669             :         static const char* aCellPadUnits[] =
     670             :         {
     671             :             OOO_STRING_SVTOOLS_RTF_CLPADFL, OOO_STRING_SVTOOLS_RTF_CLPADFT, OOO_STRING_SVTOOLS_RTF_CLPADFB, OOO_STRING_SVTOOLS_RTF_CLPADFR
     672             :         };
     673        1930 :         for (int i = 0; i < 4; ++i)
     674             :         {
     675        1544 :             if (const SvxBorderLine* pLn = rBox.GetLine(aBorders[i]))
     676         800 :                 m_aRowDefs.append(OutTBLBorderLine(m_rExport, pLn, aBorderNames[i]));
     677        3088 :             if (rDefault.GetDistance(aBorders[i]) !=
     678        1544 :                     rBox.GetDistance(aBorders[i]))
     679             :             {
     680           8 :                 m_aRowDefs.append(aCellPadUnits[i]);
     681           8 :                 m_aRowDefs.append((sal_Int32)3);
     682           8 :                 m_aRowDefs.append(aCellPadNames[i]);
     683           8 :                 m_aRowDefs.append((sal_Int32)rBox.GetDistance(aBorders[i]));
     684             :             }
     685             :         }
     686             :     }
     687         394 : }
     688             : 
     689         394 : void RtfAttributeOutput::TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     690             : {
     691         394 :     const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
     692         394 :     SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
     693         394 :     const SwWriteTableCell* pCell = &pRow->GetCells()[ pTableTextNodeInfoInner->getCell() ];
     694         394 :     const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
     695             :     const SfxPoolItem* pItem;
     696         394 :     if (pCellFmt->GetAttrSet().HasItem(RES_BACKGROUND, &pItem))
     697             :     {
     698          26 :         const SvxBrushItem& rBack = (SvxBrushItem&)*pItem;
     699          26 :         if (!rBack.GetColor().GetTransparency())
     700             :         {
     701           6 :             m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLCBPAT);
     702           6 :             m_aRowDefs.append((sal_Int32)m_rExport.GetColor(rBack.GetColor()));
     703             :         }
     704             :     }
     705         394 : }
     706             : 
     707           0 : void RtfAttributeOutput::TableRowRedline(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
     708             : {
     709           0 : }
     710             : 
     711           0 : void RtfAttributeOutput::TableCellRedline(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
     712             : {
     713           0 : }
     714             : 
     715         118 : void RtfAttributeOutput::TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     716             : {
     717         118 :     const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
     718         118 :     const SwTableLine* pTabLine = pTabBox->GetUpper();
     719         118 :     const SwFrmFmt* pLineFmt = pTabLine->GetFrmFmt();
     720         118 :     const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize();
     721             : 
     722         118 :     if (ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight())
     723             :     {
     724          34 :         sal_Int32 nHeight = 0;
     725             : 
     726          34 :         switch (rLSz.GetHeightSizeType())
     727             :         {
     728             :         case ATT_FIX_SIZE:
     729          30 :             nHeight = -rLSz.GetHeight();
     730          30 :             break;
     731             :         case ATT_MIN_SIZE:
     732           4 :             nHeight = rLSz.GetHeight();
     733           4 :             break;
     734             :         default:
     735           0 :             break;
     736             :         }
     737             : 
     738          34 :         if (nHeight)
     739             :         {
     740          34 :             m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRRH);
     741          34 :             m_aRowDefs.append(nHeight);
     742             :         }
     743             :     }
     744         118 : }
     745             : 
     746         118 : void RtfAttributeOutput::TableCanSplit(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     747             : {
     748         118 :     const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
     749         118 :     const SwTableLine* pTabLine = pTabBox->GetUpper();
     750         118 :     const SwFrmFmt* pLineFmt = pTabLine->GetFrmFmt();
     751         118 :     const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit();
     752             : 
     753             :     // The rtf default is to allow a row to break
     754         118 :     if (!rSplittable.GetValue())
     755           0 :         m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_TRKEEP);
     756         118 : }
     757             : 
     758         118 : void RtfAttributeOutput::TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     759             : {
     760         118 :     const SwTable* pTable = pTableTextNodeInfoInner->getTable();
     761         118 :     const SwFrmFmt* pFrmFmt = pTable->GetFrmFmt();
     762             : 
     763         118 :     if (m_rExport.TrueFrameDirection(*pFrmFmt) != FRMDIR_HORI_RIGHT_TOP)
     764         118 :         m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_LTRROW);
     765             :     else
     766           0 :         m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_RTLROW);
     767         118 : }
     768             : 
     769         394 : void RtfAttributeOutput::TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     770             : {
     771         394 :     const SwWriteTableRows& aRows = m_pTableWrt->GetRows();
     772         394 :     SwWriteTableRow* pRow = aRows[ pTableTextNodeInfoInner->getRow() ];
     773         394 :     const SwWriteTableCell* pCell = &pRow->GetCells()[ pTableTextNodeInfoInner->getCell() ];
     774         394 :     const SwFrmFmt* pCellFmt = pCell->GetBox()->GetFrmFmt();
     775             :     const SfxPoolItem* pItem;
     776             : 
     777             :     // vertical merges
     778         394 :     if (pCell->GetRowSpan() > 1)
     779           0 :         m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMGF);
     780         394 :     else if (pCell->GetRowSpan() == 0)
     781           0 :         m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVMRG);
     782             : 
     783             :     // vertical alignment
     784         394 :     if (pCellFmt->GetAttrSet().HasItem(RES_VERT_ORIENT, &pItem))
     785         330 :         switch (((SwFmtVertOrient*)pItem)->GetVertOrient())
     786             :         {
     787             :         case text::VertOrientation::CENTER:
     788         326 :             m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALC);
     789         326 :             break;
     790             :         case text::VertOrientation::BOTTOM:
     791           0 :             m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALB);
     792           0 :             break;
     793             :         default:
     794           4 :             m_aRowDefs.append(OOO_STRING_SVTOOLS_RTF_CLVERTALT);
     795           4 :             break;
     796             :         }
     797         394 : }
     798             : 
     799           0 : void RtfAttributeOutput::TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t /*pNodeInfo*/)
     800             : {
     801             :     /* noop */
     802           0 : }
     803             : 
     804         664 : void RtfAttributeOutput::TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner)
     805             : {
     806             :     // This is called when the nested table ends in a cell, and there's no
     807             :     // paragraph benhind that; so we must check for the ends of cell, rows,
     808             :     // and tables
     809             :     // ['true' to write an empty paragraph, MS Word insists on that]
     810         664 :     FinishTableRowCell(pNodeInfoInner, true);
     811         664 : }
     812             : 
     813         118 : void RtfAttributeOutput::TableOrientation(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     814             : {
     815         118 :     const SwTable* pTable = pTableTextNodeInfoInner->getTable();
     816         118 :     SwFrmFmt* pFmt = pTable->GetFrmFmt();
     817             : 
     818         118 :     OStringBuffer aTblAdjust(OOO_STRING_SVTOOLS_RTF_TRQL);
     819         118 :     switch (pFmt->GetHoriOrient().GetHoriOrient())
     820             :     {
     821             :     case text::HoriOrientation::CENTER:
     822           0 :         aTblAdjust.setLength(0);
     823           0 :         aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQC);
     824           0 :         break;
     825             :     case text::HoriOrientation::RIGHT:
     826           0 :         aTblAdjust.setLength(0);
     827           0 :         aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRQR);
     828           0 :         break;
     829             :     case text::HoriOrientation::NONE:
     830             :     case text::HoriOrientation::LEFT_AND_WIDTH:
     831          34 :         aTblAdjust.append(OOO_STRING_SVTOOLS_RTF_TRLEFT);
     832          34 :         aTblAdjust.append((sal_Int32)pFmt->GetLRSpace().GetLeft());
     833          34 :         break;
     834             :     default:
     835          84 :         break;
     836             :     }
     837             : 
     838         118 :     m_aRowDefs.append(aTblAdjust.makeStringAndClear());
     839         118 : }
     840             : 
     841           0 : void RtfAttributeOutput::TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
     842             : {
     843             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
     844           0 : }
     845             : 
     846           0 : void RtfAttributeOutput::TableRowEnd(sal_uInt32 /*nDepth*/)
     847             : {
     848             :     /* noop, see EndTableRow() */
     849           0 : }
     850             : 
     851             : /*
     852             :  * Our private table methods.
     853             :  */
     854             : 
     855          40 : void RtfAttributeOutput::InitTableHelper(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     856             : {
     857          40 :     sal_uInt32 nPageSize = 0;
     858          40 :     bool bRelBoxSize = false;
     859             : 
     860             :     // Create the SwWriteTable instance to use col spans
     861          40 :     GetTablePageSize(pTableTextNodeInfoInner.get(), nPageSize, bRelBoxSize);
     862             : 
     863          40 :     const SwTable* pTable = pTableTextNodeInfoInner->getTable();
     864          40 :     const SwFrmFmt* pFmt = pTable->GetFrmFmt();
     865          40 :     SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
     866             : 
     867          40 :     const SwHTMLTableLayout* pLayout = pTable->GetHTMLTableLayout();
     868          40 :     if (pLayout && pLayout->IsExportable())
     869           0 :         m_pTableWrt = new SwWriteTable(pLayout);
     870             :     else
     871             :         m_pTableWrt = new SwWriteTable(pTable->GetTabLines(), (sal_uInt16)nPageSize,
     872          40 :                                        (sal_uInt16)nTblSz, false);
     873          40 : }
     874             : 
     875          40 : void RtfAttributeOutput::StartTable(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
     876             : {
     877             :     // To trigger calling InitTableHelper()
     878          40 :     delete m_pTableWrt, m_pTableWrt = NULL;
     879          40 : }
     880             : 
     881         118 : void RtfAttributeOutput::StartTableRow(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     882             : {
     883         118 :     sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
     884             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << nCurrentDepth << ")");
     885             : 
     886         118 :     TableDefinition(pTableTextNodeInfoInner);
     887             : 
     888         118 :     if (!m_bLastTable)
     889           0 :         m_aTables.push_back(m_aRowDefs.makeStringAndClear());
     890             : 
     891             :     // We'll write the table definition for nested tables later
     892         118 :     if (nCurrentDepth > 1)
     893         118 :         return;
     894             :     // Empty the previous row closing buffer before starting the new one,
     895             :     // necessary for subtables.
     896         118 :     m_rExport.Strm().WriteCharPtr(m_aAfterRuns.makeStringAndClear().getStr());
     897         118 :     m_rExport.Strm().WriteCharPtr(m_aRowDefs.makeStringAndClear().getStr());
     898             : }
     899             : 
     900         332 : void RtfAttributeOutput::StartTableCell(ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/)
     901             : {
     902         332 :     m_bTableCellOpen = true;
     903         332 : }
     904             : 
     905         394 : void RtfAttributeOutput::TableCellProperties(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner)
     906             : {
     907         394 :     TableDefaultBorders(pTableTextNodeInfoInner);
     908         394 :     TableBackgrounds(pTableTextNodeInfoInner);
     909         394 :     TableVerticalCell(pTableTextNodeInfoInner);
     910         394 : }
     911             : 
     912         332 : void RtfAttributeOutput::EndTableCell()
     913             : {
     914             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
     915             : 
     916         332 :     if (!m_bWroteCellInfo)
     917             :     {
     918           0 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_INTBL);
     919           0 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ITAP);
     920           0 :         m_aAfterRuns.append((sal_Int32)m_nTableDepth);
     921             :     }
     922         332 :     if (m_nTableDepth > 1)
     923           0 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTCELL);
     924             :     else
     925         332 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
     926             : 
     927         332 :     m_bTableCellOpen = false;
     928         332 :     m_bTblAfterCell = true;
     929         332 :     m_bWroteCellInfo = false;
     930         332 :     if (m_aCells[m_nTableDepth] > 0)
     931         330 :         m_aCells[m_nTableDepth]--;
     932         332 : }
     933             : 
     934          92 : void RtfAttributeOutput::EndTableRow()
     935             : {
     936             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", (depth is " << m_nTableDepth << ")");
     937             : 
     938             :     // Trying to end the row without writing the required number of cells? Fill with empty ones.
     939         118 :     for (sal_uInt16 i = 0; i < m_aCells[m_nTableDepth]; i++)
     940          26 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
     941             : 
     942          92 :     if (m_nTableDepth > 1)
     943             :     {
     944           0 :         m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
     945           0 :         if (!m_aRowDefs.isEmpty())
     946           0 :             m_aAfterRuns.append(m_aRowDefs.makeStringAndClear());
     947           0 :         else if (!m_aTables.empty())
     948             :         {
     949           0 :             m_aAfterRuns.append(m_aTables.back());
     950           0 :             m_aTables.pop_back();
     951             :         }
     952           0 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_NESTROW "}" "{" OOO_STRING_SVTOOLS_RTF_NONESTTABLES OOO_STRING_SVTOOLS_RTF_PAR "}");
     953             :     }
     954             :     else
     955             :     {
     956          92 :         if (!m_aTables.empty())
     957             :         {
     958           0 :             m_aAfterRuns.append(m_aTables.back());
     959           0 :             m_aTables.pop_back();
     960             :         }
     961          92 :         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
     962             :     }
     963          92 :     m_bTableRowEnded = true;
     964          92 : }
     965             : 
     966          40 : void RtfAttributeOutput::EndTable()
     967             : {
     968          40 :     if (m_nTableDepth > 0)
     969             :     {
     970          40 :         m_nTableDepth--;
     971          40 :         delete m_pTableWrt, m_pTableWrt = NULL;
     972             :     }
     973             : 
     974             :     // We closed the table; if it is a nested table, the cell that contains it
     975             :     // still continues
     976          40 :     m_bTableCellOpen = true;
     977             : 
     978             :     // Cleans the table helper
     979          40 :     delete m_pTableWrt, m_pTableWrt = NULL;
     980          40 : }
     981             : 
     982        1838 : void RtfAttributeOutput::FinishTableRowCell(ww8::WW8TableNodeInfoInner::Pointer_t pInner, bool /*bForceEmptyParagraph*/)
     983             : {
     984        1838 :     if (pInner.get())
     985             :     {
     986             :         // Where are we in the table
     987        1044 :         sal_uInt32 nRow = pInner->getRow();
     988             : 
     989        1044 :         const SwTable* pTable = pInner->getTable();
     990        1044 :         const SwTableLines& rLines = pTable->GetTabLines();
     991        1044 :         sal_uInt16 nLinesCount = rLines.size();
     992             : 
     993        1044 :         if (pInner->isEndOfCell())
     994         332 :             EndTableCell();
     995             : 
     996             :         // This is a line end
     997        1044 :         if (pInner->isEndOfLine())
     998          92 :             EndTableRow();
     999             : 
    1000             :         // This is the end of the table
    1001        1044 :         if (pInner->isEndOfLine() && (nRow + 1) == nLinesCount)
    1002          40 :             EndTable();
    1003             :     }
    1004        1838 : }
    1005             : 
    1006         138 : void RtfAttributeOutput::StartStyles()
    1007             : {
    1008         138 :     m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING).WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLORTBL);
    1009         138 :     m_rExport.OutColorTable();
    1010             :     OSL_ENSURE(m_aStylesheet.getLength() == 0, "m_aStylesheet is not empty");
    1011         138 :     m_aStylesheet.append(SAL_NEWLINE_STRING);
    1012         138 :     m_aStylesheet.append('{');
    1013         138 :     m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_STYLESHEET);
    1014         138 : }
    1015             : 
    1016         138 : void RtfAttributeOutput::EndStyles(sal_uInt16 /*nNumberOfStyles*/)
    1017             : {
    1018         138 :     m_rExport.Strm().WriteChar('}');
    1019         138 :     m_rExport.Strm().WriteCharPtr(m_aStylesheet.makeStringAndClear().getStr());
    1020         138 :     m_rExport.Strm().WriteChar('}');
    1021         138 : }
    1022             : 
    1023        1904 : void RtfAttributeOutput::DefaultStyle(sal_uInt16 /*nStyle*/)
    1024             : {
    1025             :     /* noop, the default style is always 0 in RTF */
    1026        1904 : }
    1027             : 
    1028        1320 : void RtfAttributeOutput::StartStyle(const OUString& rName, StyleType eType,
    1029             :                                     sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId,
    1030             :                                     bool /* bAutoUpdate */)
    1031             : {
    1032             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", rName = '" << rName << "'");
    1033             : 
    1034        1320 :     m_aStylesheet.append('{');
    1035        1320 :     if (eType == STYLE_TYPE_PARA)
    1036        1054 :         m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_S);
    1037             :     else
    1038         266 :         m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_CS);
    1039        1320 :     m_aStylesheet.append((sal_Int32)nId);
    1040             : 
    1041        1320 :     if (nBase != 0x0FFF)
    1042             :     {
    1043         936 :         m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SBASEDON);
    1044         936 :         m_aStylesheet.append((sal_Int32)nBase);
    1045             :     }
    1046             : 
    1047        1320 :     m_aStylesheet.append(OOO_STRING_SVTOOLS_RTF_SNEXT);
    1048        1320 :     m_aStylesheet.append((sal_Int32)nNext);
    1049             : 
    1050        1320 :     m_rStyleName = rName;
    1051        1320 :     m_nStyleId = nId;
    1052        1320 : }
    1053             : 
    1054        1320 : void RtfAttributeOutput::EndStyle()
    1055             : {
    1056        1320 :     m_aStyles.append(m_aStylesEnd.makeStringAndClear());
    1057        1320 :     OString aStyles = m_aStyles.makeStringAndClear();
    1058        1320 :     m_rExport.InsStyle(m_nStyleId, aStyles);
    1059        1320 :     m_aStylesheet.append(aStyles);
    1060        1320 :     m_aStylesheet.append(' ');
    1061        1320 :     m_aStylesheet.append(msfilter::rtfutil::OutString(m_rStyleName, m_rExport.eCurrentEncoding));
    1062        1320 :     m_aStylesheet.append(";}");
    1063        1320 :     m_aStylesheet.append(SAL_NEWLINE_STRING);
    1064        1320 : }
    1065             : 
    1066        2374 : void RtfAttributeOutput::StartStyleProperties(bool /*bParProp*/, sal_uInt16 /*nStyle*/)
    1067             : {
    1068             :     /* noop */
    1069        2374 : }
    1070             : 
    1071        2374 : void RtfAttributeOutput::EndStyleProperties(bool /*bParProp*/)
    1072             : {
    1073             :     /* noop */
    1074        2374 : }
    1075             : 
    1076          24 : void RtfAttributeOutput::OutlineNumbering(sal_uInt8 nLvl, const SwNumFmt& /*rNFmt*/, const SwFmt& /*rFmt*/)
    1077             : {
    1078          24 :     if (nLvl >= WW8ListManager::nMaxLevel)
    1079           2 :         nLvl = WW8ListManager::nMaxLevel - 1;
    1080             : 
    1081          24 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
    1082          24 :     m_aStyles.append((sal_Int32)nLvl);
    1083          24 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTLINELEVEL);
    1084          24 :     m_aStyles.append((sal_Int32)nLvl);
    1085          24 : }
    1086             : 
    1087          12 : void RtfAttributeOutput::PageBreakBefore(bool bBreak)
    1088             : {
    1089          12 :     if (bBreak)
    1090             :     {
    1091          10 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PAGEBB);
    1092             :     }
    1093          12 : }
    1094             : 
    1095          24 : void RtfAttributeOutput::SectionBreak(sal_uInt8 nC, const WW8_SepInfo* pSectionInfo)
    1096             : {
    1097          24 :     switch (nC)
    1098             :     {
    1099             :     case msword::ColumnBreak:
    1100          14 :         m_nColBreakNeeded = true;
    1101          14 :         break;
    1102             :     case msword::PageBreak:
    1103          10 :         if (pSectionInfo)
    1104          10 :             m_rExport.SectionProperties(*pSectionInfo);
    1105          10 :         break;
    1106             :     }
    1107          24 : }
    1108             : 
    1109          10 : void RtfAttributeOutput::StartSection()
    1110             : {
    1111          10 :     m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECT OOO_STRING_SVTOOLS_RTF_SECTD);
    1112          10 :     if (!m_bBufferSectionBreaks)
    1113           0 :         m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
    1114          10 : }
    1115             : 
    1116          10 : void RtfAttributeOutput::EndSection()
    1117             : {
    1118             :     /*
    1119             :      * noop, \sect must go to StartSection or Word won't notice multiple
    1120             :      * columns...
    1121             :      */
    1122          10 : }
    1123             : 
    1124          10 : void RtfAttributeOutput::SectionFormProtection(bool bProtected)
    1125             : {
    1126          10 :     m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_SECTUNLOCKED);
    1127          10 :     m_aSectionBreaks.append((sal_Int32)!bProtected);
    1128          10 : }
    1129             : 
    1130           2 : void RtfAttributeOutput::SectionLineNumbering(sal_uLong /*nRestartNo*/, const SwLineNumberInfo& rLnNumInfo)
    1131             : {
    1132           2 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEMOD);
    1133           2 :     m_rExport.OutLong(rLnNumInfo.GetCountBy());
    1134           2 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINEX);
    1135           2 :     m_rExport.OutLong(rLnNumInfo.GetPosFromLeft());
    1136           2 :     if (!rLnNumInfo.IsRestartEachPage())
    1137           2 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LINECONT);
    1138           2 : }
    1139             : 
    1140           0 : void RtfAttributeOutput::SectionTitlePage()
    1141             : {
    1142             :     /*
    1143             :      * noop, handled in RtfExport::WriteHeaderFooter()
    1144             :      */
    1145           0 : }
    1146             : 
    1147          10 : void RtfAttributeOutput::SectionPageBorders(const SwFrmFmt* pFmt, const SwFrmFmt* /*pFirstPageFmt*/)
    1148             : {
    1149          10 :     const SvxBoxItem& rBox = pFmt->GetBox();
    1150          10 :     const SvxBorderLine* pLine = rBox.GetTop();
    1151          10 :     if (pLine)
    1152             :         m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
    1153             :                                               OOO_STRING_SVTOOLS_RTF_PGBRDRT,
    1154           6 :                                               rBox.GetDistance(BOX_LINE_TOP)));
    1155          10 :     pLine = rBox.GetBottom();
    1156          10 :     if (pLine)
    1157             :         m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
    1158             :                                               OOO_STRING_SVTOOLS_RTF_PGBRDRB,
    1159           6 :                                               rBox.GetDistance(BOX_LINE_BOTTOM)));
    1160          10 :     pLine = rBox.GetLeft();
    1161          10 :     if (pLine)
    1162             :         m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
    1163             :                                               OOO_STRING_SVTOOLS_RTF_PGBRDRL,
    1164           6 :                                               rBox.GetDistance(BOX_LINE_LEFT)));
    1165          10 :     pLine = rBox.GetRight();
    1166          10 :     if (pLine)
    1167             :         m_aSectionBreaks.append(OutBorderLine(m_rExport, pLine,
    1168             :                                               OOO_STRING_SVTOOLS_RTF_PGBRDRR,
    1169           6 :                                               rBox.GetDistance(BOX_LINE_RIGHT)));
    1170          10 : }
    1171             : 
    1172           0 : void RtfAttributeOutput::SectionBiDi(bool bBiDi)
    1173             : {
    1174           0 :     m_rExport.Strm().WriteCharPtr((bBiDi ? OOO_STRING_SVTOOLS_RTF_RTLSECT : OOO_STRING_SVTOOLS_RTF_LTRSECT));
    1175           0 : }
    1176             : 
    1177         330 : void RtfAttributeOutput::SectionPageNumbering(sal_uInt16 nNumType, ::boost::optional<sal_uInt16> oPageRestartNumber)
    1178             : {
    1179         330 :     if (oPageRestartNumber)
    1180             :     {
    1181           0 :         m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNSTARTS);
    1182           0 :         m_aSectionBreaks.append((sal_Int32)oPageRestartNumber.get());
    1183           0 :         m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGNRESTART);
    1184             :     }
    1185             : 
    1186         330 :     const char* pStr = 0;
    1187         330 :     switch (nNumType)
    1188             :     {
    1189             :     case SVX_NUM_CHARS_UPPER_LETTER:
    1190             :     case SVX_NUM_CHARS_UPPER_LETTER_N:
    1191           0 :         pStr = OOO_STRING_SVTOOLS_RTF_PGNUCLTR;
    1192           0 :         break;
    1193             :     case SVX_NUM_CHARS_LOWER_LETTER:
    1194             :     case SVX_NUM_CHARS_LOWER_LETTER_N:
    1195           0 :         pStr = OOO_STRING_SVTOOLS_RTF_PGNLCLTR;
    1196           0 :         break;
    1197             :     case SVX_NUM_ROMAN_UPPER:
    1198           0 :         pStr = OOO_STRING_SVTOOLS_RTF_PGNUCRM;
    1199           0 :         break;
    1200             :     case SVX_NUM_ROMAN_LOWER:
    1201           0 :         pStr = OOO_STRING_SVTOOLS_RTF_PGNLCRM;
    1202           0 :         break;
    1203             : 
    1204             :     case SVX_NUM_ARABIC:
    1205         330 :         pStr = OOO_STRING_SVTOOLS_RTF_PGNDEC;
    1206         330 :         break;
    1207             :     }
    1208         330 :     if (pStr)
    1209         330 :         m_aSectionBreaks.append(pStr);
    1210         330 : }
    1211             : 
    1212          10 : void RtfAttributeOutput::SectionType(sal_uInt8 nBreakCode)
    1213             : {
    1214             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << ", nBreakCode = " << int(nBreakCode));
    1215             : 
    1216             :     /*
    1217             :      * break code:   0 No break, 1 New column
    1218             :      * 2 New page, 3 Even page, 4 Odd page
    1219             :      */
    1220          10 :     const char* sType = NULL;
    1221          10 :     switch (nBreakCode)
    1222             :     {
    1223             :     case 1:
    1224           0 :         sType = OOO_STRING_SVTOOLS_RTF_SBKCOL;
    1225           0 :         break;
    1226             :     case 2:
    1227          10 :         sType = OOO_STRING_SVTOOLS_RTF_SBKPAGE;
    1228          10 :         break;
    1229             :     case 3:
    1230           0 :         sType = OOO_STRING_SVTOOLS_RTF_SBKEVEN;
    1231           0 :         break;
    1232             :     case 4:
    1233           0 :         sType = OOO_STRING_SVTOOLS_RTF_SBKODD;
    1234           0 :         break;
    1235             :     default:
    1236           0 :         sType = OOO_STRING_SVTOOLS_RTF_SBKNONE;
    1237           0 :         break;
    1238             :     }
    1239          10 :     m_aSectionBreaks.append(sType);
    1240          10 :     if (!m_bBufferSectionBreaks)
    1241           0 :         m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
    1242          10 : }
    1243             : 
    1244          34 : void RtfAttributeOutput::NumberingDefinition(sal_uInt16 nId, const SwNumRule& /*rRule*/)
    1245             : {
    1246          34 :     m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDE);
    1247          34 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
    1248          34 :     m_rExport.OutULong(nId);
    1249          34 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTOVERRIDECOUNT).WriteChar('0');
    1250          34 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LS);
    1251          34 :     m_rExport.OutULong(nId).WriteChar('}');
    1252          34 : }
    1253             : 
    1254          34 : void RtfAttributeOutput::StartAbstractNumbering(sal_uInt16 nId)
    1255             : {
    1256          34 :     m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LIST).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTTEMPLATEID);
    1257          34 :     m_rExport.OutULong(nId);
    1258          34 :     m_nListId = nId;
    1259          34 : }
    1260             : 
    1261          34 : void RtfAttributeOutput::EndAbstractNumbering()
    1262             : {
    1263          34 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTID);
    1264          34 :     m_rExport.OutULong(m_nListId).WriteChar('}').WriteCharPtr(SAL_NEWLINE_STRING);
    1265          34 : }
    1266             : 
    1267         306 : void RtfAttributeOutput::NumberingLevel(sal_uInt8 nLevel,
    1268             :                                         sal_uInt16 nStart,
    1269             :                                         sal_uInt16 nNumberingType,
    1270             :                                         SvxAdjust eAdjust,
    1271             :                                         const sal_uInt8* pNumLvlPos,
    1272             :                                         sal_uInt8 nFollow,
    1273             :                                         const wwFont* pFont,
    1274             :                                         const SfxItemSet* pOutSet,
    1275             :                                         sal_Int16 nIndentAt,
    1276             :                                         sal_Int16 nFirstLineIndex,
    1277             :                                         sal_Int16 /*nListTabPos*/,
    1278             :                                         const OUString& rNumberingString,
    1279             :                                         const SvxBrushItem* pBrush)
    1280             : {
    1281         306 :     m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
    1282         306 :     if (nLevel > 8)  // RTF knows only 9 levels
    1283           0 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_IGNORE).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SOUTLVL);
    1284             : 
    1285         306 :     m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LISTLEVEL);
    1286             : 
    1287         306 :     sal_uInt16 nVal = 0;
    1288         306 :     switch (nNumberingType)
    1289             :     {
    1290             :     case SVX_NUM_ROMAN_UPPER:
    1291           0 :         nVal = 1;
    1292           0 :         break;
    1293             :     case SVX_NUM_ROMAN_LOWER:
    1294           2 :         nVal = 2;
    1295           2 :         break;
    1296             :     case SVX_NUM_CHARS_UPPER_LETTER:
    1297             :     case SVX_NUM_CHARS_UPPER_LETTER_N:
    1298           2 :         nVal = 3;
    1299           2 :         break;
    1300             :     case SVX_NUM_CHARS_LOWER_LETTER:
    1301             :     case SVX_NUM_CHARS_LOWER_LETTER_N:
    1302           2 :         nVal = 4;
    1303           2 :         break;
    1304             : 
    1305             :     case SVX_NUM_BITMAP:
    1306             :     case SVX_NUM_CHAR_SPECIAL:
    1307          38 :         nVal = 23;
    1308          38 :         break;
    1309             :     case SVX_NUM_NUMBER_NONE:
    1310         120 :         nVal = 255;
    1311         120 :         break;
    1312             :     }
    1313         306 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNFC);
    1314         306 :     m_rExport.OutULong(nVal);
    1315             : 
    1316         306 :     switch (eAdjust)
    1317             :     {
    1318             :     case SVX_ADJUST_CENTER:
    1319           0 :         nVal = 1;
    1320           0 :         break;
    1321             :     case SVX_ADJUST_RIGHT:
    1322           0 :         nVal = 2;
    1323           0 :         break;
    1324             :     default:
    1325         306 :         nVal = 0;
    1326         306 :         break;
    1327             :     }
    1328         306 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELJC);
    1329         306 :     m_rExport.OutULong(nVal);
    1330             : 
    1331             :     // bullet
    1332         306 :     if (nNumberingType == SVX_NUM_BITMAP && pBrush)
    1333             :     {
    1334           2 :         int nIndex = m_rExport.GetGrfIndex(*pBrush);
    1335           2 :         if (nIndex != -1)
    1336             :         {
    1337           2 :             m_rExport.Strm().WriteCharPtr(LO_STRING_SVTOOLS_RTF_LEVELPICTURE);
    1338           2 :             m_rExport.OutULong(nIndex);
    1339             :         }
    1340             :     }
    1341             : 
    1342         306 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELSTARTAT);
    1343         306 :     m_rExport.OutULong(nStart);
    1344             : 
    1345         306 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELFOLLOW);
    1346         306 :     m_rExport.OutULong(nFollow);
    1347             : 
    1348             :     // leveltext group
    1349         306 :     m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELTEXT).WriteChar(' ');
    1350             : 
    1351         306 :     if (SVX_NUM_CHAR_SPECIAL == nNumberingType ||
    1352             :             SVX_NUM_BITMAP == nNumberingType)
    1353             :     {
    1354          38 :         m_rExport.Strm().WriteCharPtr("\\'01");
    1355          38 :         sal_Unicode cChar = rNumberingString[0];
    1356          38 :         m_rExport.Strm().WriteCharPtr("\\u");
    1357          38 :         m_rExport.OutULong(cChar);
    1358          38 :         m_rExport.Strm().WriteCharPtr(" ?");
    1359             :     }
    1360             :     else
    1361             :     {
    1362         268 :         m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(msfilter::rtfutil::OutHex(rNumberingString.getLength(), 2).getStr());
    1363         268 :         m_rExport.Strm().WriteCharPtr(msfilter::rtfutil::OutString(rNumberingString, m_rExport.eDefaultEncoding, /*bUnicode =*/ false).getStr());
    1364             :     }
    1365             : 
    1366         306 :     m_rExport.Strm().WriteCharPtr(";}");
    1367             : 
    1368             :     // write the levelnumbers
    1369         306 :     m_rExport.Strm().WriteCharPtr("{").WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LEVELNUMBERS);
    1370         460 :     for (sal_uInt8 i = 0; i <= nLevel && pNumLvlPos[ i ]; ++i)
    1371             :     {
    1372         154 :         m_rExport.Strm().WriteCharPtr("\\'").WriteCharPtr(msfilter::rtfutil::OutHex(pNumLvlPos[ i ], 2).getStr());
    1373             :     }
    1374         306 :     m_rExport.Strm().WriteCharPtr(";}");
    1375             : 
    1376         306 :     if (pOutSet)
    1377             :     {
    1378          94 :         if (pFont)
    1379             :         {
    1380          38 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_F);
    1381          38 :             m_rExport.OutULong(m_rExport.maFontHelper.GetId(*pFont));
    1382             :         }
    1383          94 :         m_rExport.OutputItemSet(*pOutSet, false, true, i18n::ScriptType::LATIN, m_rExport.mbExportModeRTF);
    1384          94 :         m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
    1385             :     }
    1386             : 
    1387         306 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FI);
    1388         306 :     m_rExport.OutLong(nFirstLineIndex).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_LI);
    1389         306 :     m_rExport.OutLong(nIndentAt);
    1390             : 
    1391         306 :     m_rExport.Strm().WriteChar('}');
    1392         306 :     if (nLevel > 8)
    1393           0 :         m_rExport.Strm().WriteChar('}');
    1394         306 : }
    1395             : 
    1396          70 : void RtfAttributeOutput::WriteField_Impl(const SwField* pFld, ww::eField /*eType*/, const OUString& rFldCmd, sal_uInt8 /*nMode*/)
    1397             : {
    1398             :     // If there are no field instructions, don't export it as a field.
    1399          70 :     bool bHasInstructions = !rFldCmd.isEmpty();
    1400          70 :     if (bHasInstructions)
    1401             :     {
    1402          68 :         m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
    1403          68 :         m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " ");
    1404          68 :         m_aRunText->append(msfilter::rtfutil::OutString(rFldCmd, m_rExport.eCurrentEncoding));
    1405          68 :         m_aRunText->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
    1406             :     }
    1407          70 :     if (pFld)
    1408          66 :         m_aRunText->append(msfilter::rtfutil::OutString(pFld->ExpandField(true), m_rExport.eDefaultEncoding));
    1409          70 :     if (bHasInstructions)
    1410          68 :         m_aRunText->append("}}");
    1411          70 : }
    1412             : 
    1413        2560 : void RtfAttributeOutput::WriteBookmarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds)
    1414             : {
    1415        2562 :     for (std::vector< OUString >::const_iterator it = rStarts.begin(), end = rStarts.end(); it != end; ++it)
    1416             :     {
    1417           2 :         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKSTART " ");
    1418           2 :         m_aRun->append(msfilter::rtfutil::OutString(*it, m_rExport.eCurrentEncoding));
    1419           2 :         m_aRun->append('}');
    1420             :     }
    1421        2560 :     rStarts.clear();
    1422             : 
    1423        2562 :     for (std::vector< OUString >::const_iterator it = rEnds.begin(), end = rEnds.end(); it != end; ++it)
    1424             :     {
    1425           2 :         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_BKMKEND " ");
    1426           2 :         m_aRun->append(msfilter::rtfutil::OutString(*it, m_rExport.eCurrentEncoding));
    1427           2 :         m_aRun->append('}');
    1428             :     }
    1429        2560 :     rEnds.clear();
    1430        2560 : }
    1431             : 
    1432        2560 : void RtfAttributeOutput::WriteAnnotationMarks_Impl(std::vector< OUString >& rStarts, std::vector< OUString >& rEnds)
    1433             : {
    1434        2566 :     for (std::vector< OUString >::const_iterator i = rStarts.begin(), end = rStarts.end(); i != end; ++i)
    1435             :     {
    1436           6 :         OString rName = OUStringToOString(*i, RTL_TEXTENCODING_UTF8);
    1437             : 
    1438             :         // Output the annotation mark
    1439           6 :         sal_uInt16 nId = m_nNextAnnotationMarkId++;
    1440           6 :         m_rOpenedAnnotationMarksIds[rName] = nId;
    1441           6 :         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFSTART " ");
    1442           6 :         m_aRun->append(OString::number(nId).getStr());
    1443           6 :         m_aRun->append('}');
    1444           6 :     }
    1445        2560 :     rStarts.clear();
    1446             : 
    1447        2566 :     for (std::vector< OUString >::const_iterator i = rEnds.begin(), end = rEnds.end(); i != end; ++i)
    1448             :     {
    1449           6 :         OString rName = OUStringToOString(*i, RTL_TEXTENCODING_UTF8);
    1450             : 
    1451             :         // Get the id of the annotation mark
    1452           6 :         std::map<OString, sal_uInt16>::iterator it = m_rOpenedAnnotationMarksIds.find(rName);
    1453           6 :         if (it != m_rOpenedAnnotationMarksIds.end())
    1454             :         {
    1455           6 :             sal_uInt16 nId = it->second;
    1456           6 :             m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATRFEND " ");
    1457           6 :             m_aRun->append(OString::number(nId).getStr());
    1458           6 :             m_aRun->append('}');
    1459           6 :             m_rOpenedAnnotationMarksIds.erase(rName);
    1460             : 
    1461           6 :             if (m_aPostitFields.find(nId) != m_aPostitFields.end())
    1462             :             {
    1463           6 :                 m_aRunText->append("{");
    1464           6 :                 m_nCurrentAnnotationMarkId = nId;
    1465           6 :                 PostitField(m_aPostitFields[nId]);
    1466           6 :                 m_nCurrentAnnotationMarkId = -1;
    1467           6 :                 m_aRunText->append("}");
    1468             :             }
    1469             :         }
    1470           6 :     }
    1471        2560 :     rEnds.clear();
    1472        2560 : }
    1473             : 
    1474          12 : void RtfAttributeOutput::WriteHeaderFooter_Impl(const SwFrmFmt& rFmt, bool bHeader, const sal_Char* pStr, bool bTitlepg)
    1475             : {
    1476          12 :     OStringBuffer aSectionBreaks = m_aSectionBreaks;
    1477          12 :     m_aSectionBreaks.setLength(0);
    1478          24 :     RtfStringBuffer aRun = m_aRun;
    1479          12 :     m_aRun.clear();
    1480             : 
    1481          12 :     m_aSectionHeaders.append(bHeader ? OOO_STRING_SVTOOLS_RTF_HEADERY : OOO_STRING_SVTOOLS_RTF_FOOTERY);
    1482          12 :     m_aSectionHeaders.append((sal_Int32)m_rExport.pAktPageDesc->GetMaster().GetULSpace().GetUpper());
    1483          12 :     if (bTitlepg)
    1484           0 :         m_aSectionHeaders.append(OOO_STRING_SVTOOLS_RTF_TITLEPG);
    1485          12 :     m_aSectionHeaders.append('{');
    1486          12 :     m_aSectionHeaders.append(pStr);
    1487          12 :     m_bBufferSectionHeaders = true;
    1488          12 :     m_rExport.WriteHeaderFooterText(rFmt, bHeader);
    1489          12 :     m_bBufferSectionHeaders = false;
    1490          12 :     m_aSectionHeaders.append('}');
    1491             : 
    1492          12 :     m_aSectionBreaks = aSectionBreaks;
    1493          24 :     m_aRun = aRun;
    1494          12 : }
    1495             : 
    1496          24 : void lcl_TextFrameShadow(std::vector< std::pair<OString, OString> >& rFlyProperties, const SwFrmFmt& rFrmFmt)
    1497             : {
    1498          24 :     SvxShadowItem aShadowItem = rFrmFmt.GetShadow();
    1499          24 :     if (aShadowItem.GetLocation() == SVX_SHADOW_NONE)
    1500          42 :         return;
    1501             : 
    1502           6 :     rFlyProperties.push_back(std::make_pair<OString, OString>("fShadow", OString::number(1)));
    1503             : 
    1504           6 :     const Color& rColor = aShadowItem.GetColor();
    1505             :     // We in fact need RGB to BGR, but the transformation is symmetric.
    1506           6 :     rFlyProperties.push_back(std::make_pair<OString, OString>("shadowColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
    1507             : 
    1508             :     // Twips -> points -> EMUs -- hacky, the intermediate step hides rounding errors on roundtrip.
    1509          12 :     OString aShadowWidth = OString::number(sal_Int32(aShadowItem.GetWidth() / 20) * 12700);
    1510          12 :     OString aOffsetX;
    1511          12 :     OString aOffsetY;
    1512           6 :     switch (aShadowItem.GetLocation())
    1513             :     {
    1514             :     case SVX_SHADOW_TOPLEFT:
    1515           0 :         aOffsetX = "-" + aShadowWidth;
    1516           0 :         aOffsetY = "-" + aShadowWidth;
    1517           0 :         break;
    1518             :     case SVX_SHADOW_TOPRIGHT:
    1519           0 :         aOffsetX = aShadowWidth;
    1520           0 :         aOffsetY = "-" + aShadowWidth;
    1521           0 :         break;
    1522             :     case SVX_SHADOW_BOTTOMLEFT:
    1523           0 :         aOffsetX = "-" + aShadowWidth;
    1524           0 :         aOffsetY = aShadowWidth;
    1525           0 :         break;
    1526             :     case SVX_SHADOW_BOTTOMRIGHT:
    1527           6 :         aOffsetX = aShadowWidth;
    1528           6 :         aOffsetY = aShadowWidth;
    1529           6 :         break;
    1530             :     case SVX_SHADOW_NONE:
    1531             :     case SVX_SHADOW_END:
    1532           0 :         break;
    1533             :     }
    1534           6 :     if (!aOffsetX.isEmpty())
    1535           6 :         rFlyProperties.push_back(std::make_pair<OString, OString>("shadowOffsetX", OString(aOffsetX)));
    1536           6 :     if (!aOffsetY.isEmpty())
    1537          12 :         rFlyProperties.push_back(std::make_pair<OString, OString>("shadowOffsetY", OString(aOffsetY)));
    1538             : }
    1539             : 
    1540          24 : void lcl_TextFrameRelativeSize(std::vector< std::pair<OString, OString> >& rFlyProperties, const SwFrmFmt& rFrmFmt)
    1541             : {
    1542          24 :     const SwFmtFrmSize& rSize = rFrmFmt.GetFrmSize();
    1543             : 
    1544             :     // Relative size of the Text Frame.
    1545          24 :     if (rSize.GetWidthPercent())
    1546             :     {
    1547           2 :         rFlyProperties.push_back(std::make_pair<OString, OString>("pctHoriz", OString::number(rSize.GetWidthPercent() * 10)));
    1548             : 
    1549           2 :         OString aRelation;
    1550           2 :         switch (rSize.GetWidthPercentRelation())
    1551             :         {
    1552             :         case text::RelOrientation::PAGE_FRAME:
    1553           2 :             aRelation = "1"; // page
    1554           2 :             break;
    1555             :         default:
    1556           0 :             aRelation = "0"; // margin
    1557           0 :             break;
    1558             :         }
    1559           2 :         rFlyProperties.push_back(std::make_pair("sizerelh", aRelation));
    1560             :     }
    1561          24 :     if (rSize.GetHeightPercent())
    1562             :     {
    1563           2 :         rFlyProperties.push_back(std::make_pair<OString, OString>("pctVert", OString::number(rSize.GetHeightPercent() * 10)));
    1564             : 
    1565           2 :         OString aRelation;
    1566           2 :         switch (rSize.GetHeightPercentRelation())
    1567             :         {
    1568             :         case text::RelOrientation::PAGE_FRAME:
    1569           0 :             aRelation = "1"; // page
    1570           0 :             break;
    1571             :         default:
    1572           2 :             aRelation = "0"; // margin
    1573           2 :             break;
    1574             :         }
    1575           2 :         rFlyProperties.push_back(std::make_pair("sizerelv", aRelation));
    1576             :     }
    1577          24 : }
    1578             : 
    1579          26 : void RtfAttributeOutput::writeTextFrame(const sw::Frame& rFrame, bool bTextBox)
    1580             : {
    1581          26 :     RtfStringBuffer aRunText;
    1582          26 :     if (bTextBox)
    1583             :     {
    1584           2 :         m_rExport.setStream();
    1585           2 :         aRunText = m_aRunText;
    1586           2 :         m_aRunText.clear();
    1587             :     }
    1588             : 
    1589          26 :     m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHPTXT);
    1590             : 
    1591             :     {
    1592             :         // Save table state, in case the inner text also contains a table.
    1593          26 :         ww8::WW8TableInfo::Pointer_t pTableInfoOrig = m_rExport.mpTableInfo;
    1594          26 :         m_rExport.mpTableInfo = ww8::WW8TableInfo::Pointer_t(new ww8::WW8TableInfo());
    1595          26 :         SwWriteTable* pTableWrt = m_pTableWrt;
    1596          26 :         m_pTableWrt = 0;
    1597          26 :         sal_uInt32 nTableDepth = m_nTableDepth;
    1598             : 
    1599          26 :         m_nTableDepth = 0;
    1600             :         /*
    1601             :          * Save m_aRun as we should not lose the opening brace.
    1602             :          * OTOH, just drop the contents of m_aRunText in case something
    1603             :          * would be there, causing a problem later.
    1604             :          */
    1605          52 :         OString aSave = m_aRun.makeStringAndClear();
    1606             :         // Also back m_bInRun and m_bSingleEmptyRun up.
    1607          26 :         bool bInRunOrig = m_bInRun;
    1608          26 :         m_bInRun = false;
    1609          26 :         bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
    1610          26 :         m_bSingleEmptyRun = false;
    1611          26 :         m_rExport.bRTFFlySyntax = true;
    1612             : 
    1613          26 :         const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
    1614          26 :         const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
    1615          26 :         sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
    1616          26 :         sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
    1617          26 :         m_rExport.SaveData(nStt, nEnd);
    1618          26 :         m_rExport.mpParentFrame = &rFrame;
    1619          26 :         m_rExport.WriteText();
    1620          26 :         m_rExport.RestoreData();
    1621             : 
    1622          26 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PARD);
    1623          26 :         m_rExport.bRTFFlySyntax = false;
    1624          26 :         m_aRun->append(aSave);
    1625          26 :         m_aRunText.clear();
    1626          26 :         m_bInRun = bInRunOrig;
    1627          26 :         m_bSingleEmptyRun = bSingleEmptyRunOrig;
    1628             : 
    1629             :         // Restore table state.
    1630          26 :         m_rExport.mpTableInfo = pTableInfoOrig;
    1631          26 :         delete m_pTableWrt;
    1632          26 :         m_pTableWrt = pTableWrt;
    1633          52 :         m_nTableDepth = nTableDepth;
    1634             :     }
    1635             : 
    1636          26 :     m_rExport.mpParentFrame = NULL;
    1637             : 
    1638          26 :     m_rExport.Strm().WriteChar('}');   // shptxt
    1639             : 
    1640          26 :     if (bTextBox)
    1641             :     {
    1642           2 :         m_aRunText = aRunText;
    1643           2 :         m_aRunText->append(m_rExport.getStream());
    1644           2 :         m_rExport.resetStream();
    1645          26 :     }
    1646          26 : }
    1647             : 
    1648         118 : void RtfAttributeOutput::OutputFlyFrame_Impl(const sw::Frame& rFrame, const Point& /*rNdTopLeft*/)
    1649             : {
    1650         118 :     const SwNode* pNode = rFrame.GetContent();
    1651         118 :     const SwGrfNode* pGrfNode = pNode ? pNode->GetGrfNode() : 0;
    1652             : 
    1653         118 :     switch (rFrame.GetWriterType())
    1654             :     {
    1655             :     case sw::Frame::eTxtBox:
    1656             :     {
    1657             :         // If this is a TextBox of a shape, then ignore: it's handled in RtfSdrExport::StartShape().
    1658          26 :         if (m_rExport.SdrExporter().isTextBox(rFrame.GetFrmFmt()))
    1659           2 :             break;
    1660             : 
    1661             :         OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty");
    1662          24 :         m_rExport.mpParentFrame = &rFrame;
    1663             : 
    1664          24 :         m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP);
    1665          24 :         m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPINST);
    1666             : 
    1667             :         // Shape properties.
    1668          24 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("shapeType", OString::number(ESCHER_ShpInst_TextBox)));
    1669             : 
    1670             :         // When a frame has some low height, but automatically expanded due
    1671             :         // to lots of contents, this size contains the real size.
    1672          24 :         const Size aSize = rFrame.GetSize();
    1673          24 :         m_pFlyFrameSize = &aSize;
    1674             : 
    1675          24 :         m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
    1676          24 :         m_rExport.OutputFormat(rFrame.GetFrmFmt(), false, false, true);
    1677          24 :         m_rExport.Strm().WriteCharPtr(m_aRunText.makeStringAndClear().getStr());
    1678          24 :         m_rExport.Strm().WriteCharPtr(m_aStyles.makeStringAndClear().getStr());
    1679          24 :         m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
    1680          24 :         m_pFlyFrameSize = 0;
    1681             : 
    1682          24 :         const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
    1683          24 :         lcl_TextFrameShadow(m_aFlyProperties, rFrmFmt);
    1684          24 :         lcl_TextFrameRelativeSize(m_aFlyProperties, rFrmFmt);
    1685             : 
    1686         400 :         for (size_t i = 0; i < m_aFlyProperties.size(); ++i)
    1687             :         {
    1688         376 :             m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{");
    1689         376 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SN " ");
    1690         376 :             m_rExport.Strm().WriteCharPtr(m_aFlyProperties[i].first.getStr());
    1691         376 :             m_rExport.Strm().WriteCharPtr("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
    1692         376 :             m_rExport.Strm().WriteCharPtr(m_aFlyProperties[i].second.getStr());
    1693         376 :             m_rExport.Strm().WriteCharPtr("}}");
    1694             :         }
    1695          24 :         m_aFlyProperties.clear();
    1696             : 
    1697          24 :         writeTextFrame(rFrame);
    1698             : 
    1699          24 :         m_rExport.Strm().WriteChar('}');   // shpinst
    1700          24 :         m_rExport.Strm().WriteChar('}');   // shp
    1701             : 
    1702          24 :         m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
    1703             :     }
    1704          24 :     break;
    1705             :     case sw::Frame::eGraphic:
    1706          14 :         if (!rFrame.IsInline())
    1707             :         {
    1708           8 :             m_rExport.mpParentFrame = &rFrame;
    1709           8 :             m_rExport.bRTFFlySyntax = true;
    1710           8 :             m_rExport.OutputFormat(rFrame.GetFrmFmt(), false, false, true);
    1711           8 :             m_rExport.bRTFFlySyntax = false;
    1712           8 :             m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE);
    1713           8 :             m_rExport.OutputFormat(rFrame.GetFrmFmt(), false, false, true);
    1714           8 :             m_aRunText->append('}');
    1715           8 :             m_rExport.mpParentFrame = NULL;
    1716             :         }
    1717             : 
    1718          14 :         if (pGrfNode)
    1719          14 :             m_aRunText.append(dynamic_cast<const SwFlyFrmFmt*>(&rFrame.GetFrmFmt()), pGrfNode);
    1720          14 :         break;
    1721             :     case sw::Frame::eDrawing:
    1722             :     {
    1723          18 :         const SdrObject* pSdrObj = rFrame.GetFrmFmt().FindRealSdrObject();
    1724          18 :         if (pSdrObj)
    1725             :         {
    1726          18 :             bool bSwapInPage = false;
    1727          18 :             if (!pSdrObj->GetPage())
    1728             :             {
    1729           0 :                 if (SwDrawModel* pModel = m_rExport.pDoc->getIDocumentDrawModelAccess().GetDrawModel())
    1730             :                 {
    1731           0 :                     if (SdrPage* pPage = pModel->GetPage(0))
    1732             :                     {
    1733           0 :                         bSwapInPage = true;
    1734           0 :                         const_cast< SdrObject* >(pSdrObj)->SetPage(pPage);
    1735             :                     }
    1736             :                 }
    1737             :             }
    1738             : 
    1739          18 :             m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{");
    1740          18 :             m_aRunText->append(OOO_STRING_SVTOOLS_RTF_IGNORE);
    1741          18 :             m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLDINST);
    1742          18 :             m_aRunText->append(" SHAPE ");
    1743          18 :             m_aRunText->append("}" "{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
    1744             : 
    1745          18 :             m_rExport.SdrExporter().AddSdrObject(*pSdrObj);
    1746             : 
    1747          18 :             m_aRunText->append('}');
    1748          18 :             m_aRunText->append('}');
    1749             : 
    1750          18 :             if (bSwapInPage)
    1751           0 :                 const_cast< SdrObject* >(pSdrObj)->SetPage(0);
    1752             :         }
    1753             :     }
    1754          18 :     break;
    1755             :     case sw::Frame::eFormControl:
    1756             :     {
    1757           0 :         const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
    1758           0 :         const SdrObject* pObject = rFrmFmt.FindRealSdrObject();
    1759             : 
    1760           0 :         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
    1761           0 :         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST);
    1762             : 
    1763           0 :         if (pObject && pObject->GetObjInventor() == FmFormInventor)
    1764             :         {
    1765           0 :             if (const SdrUnoObj* pFormObj = PTR_CAST(SdrUnoObj,pObject))
    1766             :             {
    1767             :                 uno::Reference< awt::XControlModel > xControlModel =
    1768           0 :                     pFormObj->GetUnoControlModel();
    1769           0 :                 uno::Reference< lang::XServiceInfo > xInfo(xControlModel, uno::UNO_QUERY);
    1770           0 :                 uno::Reference<beans::XPropertySet> xPropSet(xControlModel, uno::UNO_QUERY);
    1771           0 :                 uno::Reference<beans::XPropertySetInfo> xPropSetInfo = xPropSet->getPropertySetInfo();
    1772           0 :                 OUString sName;
    1773           0 :                 if (xInfo->supportsService("com.sun.star.form.component.CheckBox"))
    1774             :                 {
    1775             : 
    1776           0 :                     m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMCHECKBOX)), m_rExport.eCurrentEncoding));
    1777           0 :                     m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
    1778           0 :                     m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "1"); // 1 = checkbox
    1779             :                     // checkbox size in half points, this seems to be always 20, see WW8Export::DoCheckBox()
    1780           0 :                     m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHPS "20");
    1781             : 
    1782           0 :                     OUString aStr;
    1783           0 :                     sName = "Name";
    1784           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1785             :                     {
    1786           0 :                         xPropSet->getPropertyValue(sName) >>= aStr;
    1787           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
    1788           0 :                         m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
    1789           0 :                         m_aRun->append('}');
    1790             :                     }
    1791             : 
    1792           0 :                     sName = "HelpText";
    1793           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1794             :                     {
    1795           0 :                         xPropSet->getPropertyValue(sName) >>= aStr;
    1796           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
    1797           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
    1798           0 :                         m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
    1799           0 :                         m_aRun->append('}');
    1800             :                     }
    1801             : 
    1802           0 :                     sName = "HelpF1Text";
    1803           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1804             :                     {
    1805           0 :                         xPropSet->getPropertyValue(sName) >>= aStr;
    1806           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
    1807           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
    1808           0 :                         m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
    1809           0 :                         m_aRun->append('}');
    1810             :                     }
    1811             : 
    1812           0 :                     sal_Int16 nTemp = 0;
    1813           0 :                     xPropSet->getPropertyValue("DefaultState") >>= nTemp;
    1814           0 :                     m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
    1815           0 :                     m_aRun->append((sal_Int32)nTemp);
    1816           0 :                     xPropSet->getPropertyValue("State") >>= nTemp;
    1817           0 :                     m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
    1818           0 :                     m_aRun->append((sal_Int32)nTemp);
    1819             : 
    1820           0 :                     m_aRun->append("}}");
    1821             : 
    1822             :                     // field result is empty, ffres already contains the form result
    1823           0 :                     m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
    1824             :                 }
    1825           0 :                 else if (xInfo->supportsService("com.sun.star.form.component.TextField"))
    1826             :                 {
    1827           0 :                     OStringBuffer aBuf;
    1828           0 :                     OString aStr;
    1829           0 :                     OUString aTmp;
    1830             :                     const sal_Char* pStr;
    1831             : 
    1832           0 :                     m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMTEXT)), m_rExport.eCurrentEncoding));
    1833           0 :                     m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_DATAFIELD " ");
    1834           0 :                     for (int i = 0; i < 8; i++) aBuf.append((sal_Char)0x00);
    1835           0 :                     xPropSet->getPropertyValue("Name") >>= aTmp;
    1836           0 :                     aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
    1837           0 :                     aBuf.append((sal_Char)aStr.getLength());
    1838           0 :                     aBuf.append(aStr);
    1839           0 :                     aBuf.append((sal_Char)0x00);
    1840           0 :                     xPropSet->getPropertyValue("DefaultText") >>= aTmp;
    1841           0 :                     aStr = OUStringToOString(aTmp, m_rExport.eCurrentEncoding);
    1842           0 :                     aBuf.append((sal_Char)aStr.getLength());
    1843           0 :                     aBuf.append(aStr);
    1844           0 :                     for (int i = 0; i < 11; i++) aBuf.append((sal_Char)0x00);
    1845           0 :                     aStr = aBuf.makeStringAndClear();
    1846           0 :                     pStr = aStr.getStr();
    1847           0 :                     for (int i = 0; i < aStr.getLength(); i++, pStr++)
    1848           0 :                         m_aRun->append(msfilter::rtfutil::OutHex(*pStr, 2));
    1849           0 :                     m_aRun->append('}');
    1850           0 :                     m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
    1851           0 :                     xPropSet->getPropertyValue("Text") >>= aTmp;
    1852           0 :                     m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
    1853           0 :                     m_aRun->append('}');
    1854           0 :                     m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
    1855           0 :                     sName = "HelpText";
    1856           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1857             :                     {
    1858           0 :                         xPropSet->getPropertyValue(sName) >>= aTmp;
    1859           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
    1860           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
    1861           0 :                         m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
    1862           0 :                         m_aRun->append('}');
    1863             :                     }
    1864             : 
    1865           0 :                     sName = "HelpF1Text";
    1866           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1867             :                     {
    1868           0 :                         xPropSet->getPropertyValue(sName) >>= aTmp;
    1869           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
    1870           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
    1871           0 :                         m_aRun->append(OUStringToOString(aTmp, m_rExport.eCurrentEncoding));
    1872           0 :                         m_aRun->append('}');
    1873             :                     }
    1874           0 :                     m_aRun->append("}");
    1875             :                 }
    1876           0 :                 else if (xInfo->supportsService("com.sun.star.form.component.ListBox"))
    1877             :                 {
    1878           0 :                     OUString aStr;
    1879           0 :                     uno::Sequence<sal_Int16> aIntSeq;
    1880           0 :                     uno::Sequence<OUString> aStrSeq;
    1881             : 
    1882           0 :                     m_aRun->append(OUStringToOString(OUString(FieldString(ww::eFORMDROPDOWN)), m_rExport.eCurrentEncoding));
    1883           0 :                     m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD "{");
    1884           0 :                     m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFTYPE "2"); // 2 = list
    1885           0 :                     m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX);
    1886             : 
    1887           0 :                     xPropSet->getPropertyValue("DefaultSelection") >>= aIntSeq;
    1888           0 :                     if (aIntSeq.getLength())
    1889             :                     {
    1890           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFDEFRES);
    1891             :                         // a dropdown list can have only one 'selected item by default'
    1892           0 :                         m_aRun->append((sal_Int32)aIntSeq[0]);
    1893             :                     }
    1894             : 
    1895           0 :                     xPropSet->getPropertyValue("SelectedItems") >>= aIntSeq;
    1896           0 :                     if (aIntSeq.getLength())
    1897             :                     {
    1898           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFRES);
    1899             :                         // a dropdown list can have only one 'currently selected item'
    1900           0 :                         m_aRun->append((sal_Int32)aIntSeq[0]);
    1901             :                     }
    1902             : 
    1903           0 :                     sName = "Name";
    1904           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1905             :                     {
    1906           0 :                         xPropSet->getPropertyValue(sName) >>= aStr;
    1907           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFNAME " ");
    1908           0 :                         m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
    1909           0 :                         m_aRun->append('}');
    1910             :                     }
    1911             : 
    1912           0 :                     sName = "HelpText";
    1913           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1914             :                     {
    1915           0 :                         xPropSet->getPropertyValue(sName) >>= aStr;
    1916           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNHELP);
    1917           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFHELPTEXT " ");
    1918           0 :                         m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
    1919           0 :                         m_aRun->append('}');
    1920             :                     }
    1921             : 
    1922           0 :                     sName = "HelpF1Text";
    1923           0 :                     if (xPropSetInfo->hasPropertyByName(sName))
    1924             :                     {
    1925           0 :                         xPropSet->getPropertyValue(sName) >>= aStr;
    1926           0 :                         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FFOWNSTAT);
    1927           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFSTATTEXT " ");
    1928           0 :                         m_aRun->append(OUStringToOString(aStr, m_rExport.eCurrentEncoding));
    1929           0 :                         m_aRun->append('}');
    1930             :                     }
    1931             : 
    1932           0 :                     xPropSet->getPropertyValue("StringItemList") >>= aStrSeq;
    1933           0 :                     sal_uInt32 nListItems = aStrSeq.getLength();
    1934           0 :                     for (sal_uInt32 i = 0; i < nListItems; i++)
    1935           0 :                         m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFL " ")
    1936           0 :                         .append(OUStringToOString(aStrSeq[i], m_rExport.eCurrentEncoding)).append('}');
    1937             : 
    1938           0 :                     m_aRun->append("}}");
    1939             : 
    1940             :                     // field result is empty, ffres already contains the form result
    1941           0 :                     m_aRun->append("}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " ");
    1942             :                 }
    1943             :                 else
    1944             :                     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " unhandled form control: '" << xInfo->getImplementationName()<< "'");
    1945           0 :                 m_aRun->append('}');
    1946             :             }
    1947             :         }
    1948             : 
    1949           0 :         m_aRun->append('}');
    1950             :     }
    1951           0 :     break;
    1952             :     case sw::Frame::eOle:
    1953             :     {
    1954          60 :         const SwFrmFmt& rFrmFmt = rFrame.GetFrmFmt();
    1955          60 :         const SdrObject* pSdrObj = rFrmFmt.FindRealSdrObject();
    1956          60 :         if (pSdrObj)
    1957             :         {
    1958          60 :             SwNodeIndex aIdx(*rFrmFmt.GetCntnt().GetCntntIdx(), 1);
    1959          60 :             SwOLENode& rOLENd = *aIdx.GetNode().GetOLENode();
    1960          60 :             FlyFrameOLE(dynamic_cast<const SwFlyFrmFmt*>(&rFrmFmt), rOLENd, rFrame.GetLayoutSize());
    1961             :         }
    1962             :     }
    1963          60 :     break;
    1964             :     default:
    1965             :         SAL_INFO("sw.rtf", OSL_THIS_FUNC << ": unknown type (" << (int)rFrame.GetWriterType() << ")");
    1966           0 :         break;
    1967             :     }
    1968         118 : }
    1969             : 
    1970          22 : void RtfAttributeOutput::CharCaseMap(const SvxCaseMapItem& rCaseMap)
    1971             : {
    1972          22 :     switch (rCaseMap.GetValue())
    1973             :     {
    1974             :     case SVX_CASEMAP_KAPITAELCHEN:
    1975           8 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
    1976           8 :         break;
    1977             :     case SVX_CASEMAP_VERSALIEN:
    1978          10 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
    1979          10 :         break;
    1980             :     default: // Something that rtf does not support
    1981           4 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SCAPS);
    1982           4 :         m_aStyles.append((sal_Int32)0);
    1983           4 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CAPS);
    1984           4 :         m_aStyles.append((sal_Int32)0);
    1985           4 :         break;
    1986             :     }
    1987          22 : }
    1988             : 
    1989         436 : void RtfAttributeOutput::CharColor(const SvxColorItem& rColor)
    1990             : {
    1991         436 :     const Color aColor(rColor.GetValue());
    1992             : 
    1993         436 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CF);
    1994         436 :     m_aStyles.append((sal_Int32)m_rExport.GetColor(aColor));
    1995         436 : }
    1996             : 
    1997           6 : void RtfAttributeOutput::CharContour(const SvxContourItem& rContour)
    1998             : {
    1999           6 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_OUTL);
    2000           6 :     if (!rContour.GetValue())
    2001           6 :         m_aStyles.append((sal_Int32)0);
    2002           6 : }
    2003             : 
    2004           0 : void RtfAttributeOutput::CharCrossedOut(const SvxCrossedOutItem& rCrossedOut)
    2005             : {
    2006           0 :     switch (rCrossedOut.GetStrikeout())
    2007             :     {
    2008             :     case STRIKEOUT_NONE:
    2009           0 :         if (!m_bStrikeDouble)
    2010           0 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
    2011             :         else
    2012           0 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
    2013           0 :         m_aStyles.append((sal_Int32)0);
    2014           0 :         break;
    2015             :     case STRIKEOUT_DOUBLE:
    2016           0 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKED);
    2017           0 :         m_aStyles.append((sal_Int32)1);
    2018           0 :         break;
    2019             :     default:
    2020           0 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_STRIKE);
    2021           0 :         break;
    2022             :     }
    2023           0 : }
    2024             : 
    2025          24 : void RtfAttributeOutput::CharEscapement(const SvxEscapementItem& rEsc)
    2026             : {
    2027          24 :     short nEsc = rEsc.GetEsc();
    2028          24 :     if (rEsc.GetProp() == DFLT_ESC_PROP)
    2029             :     {
    2030          24 :         if (DFLT_ESC_SUB == nEsc || DFLT_ESC_AUTO_SUB == nEsc)
    2031           2 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUB);
    2032          22 :         else if (DFLT_ESC_SUPER == nEsc || DFLT_ESC_AUTO_SUPER == nEsc)
    2033          22 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SUPER);
    2034          48 :         return;
    2035             :     }
    2036             : 
    2037             :     const char* pUpDn;
    2038             : 
    2039           0 :     SwTwips nH = ((SvxFontHeightItem&)m_rExport.GetItem(RES_CHRATR_FONTSIZE)).GetHeight();
    2040             : 
    2041           0 :     if (0 < rEsc.GetEsc())
    2042           0 :         pUpDn = OOO_STRING_SVTOOLS_RTF_UP;
    2043           0 :     else if (0 > rEsc.GetEsc())
    2044             :     {
    2045           0 :         pUpDn = OOO_STRING_SVTOOLS_RTF_DN;
    2046           0 :         nH = -nH;
    2047             :     }
    2048             :     else
    2049           0 :         return;
    2050             : 
    2051           0 :     short nProp = rEsc.GetProp() * 100;
    2052           0 :     if (DFLT_ESC_AUTO_SUPER == nEsc)
    2053             :     {
    2054           0 :         nEsc = 100 - rEsc.GetProp();
    2055           0 :         ++nProp;
    2056             :     }
    2057           0 :     else if (DFLT_ESC_AUTO_SUB == nEsc)
    2058             :     {
    2059           0 :         nEsc = - 100 + rEsc.GetProp();
    2060           0 :         ++nProp;
    2061             :     }
    2062             : 
    2063           0 :     m_aStyles.append('{');
    2064           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
    2065           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_UPDNPROP);
    2066           0 :     m_aStyles.append((sal_Int32)nProp);
    2067           0 :     m_aStyles.append('}');
    2068           0 :     m_aStyles.append(pUpDn);
    2069             : 
    2070             :     /*
    2071             :      * Calculate the act. FontSize and the percentage of the displacement;
    2072             :      * RTF file expects half points, while internally it's in twips.
    2073             :      * Formally :            (FontSize * 1/20 ) pts         x * 2
    2074             :      *                    -----------------------  = ------------
    2075             :      *                      100%                       Escapement
    2076             :      */
    2077             : 
    2078           0 :     m_aStyles.append((sal_Int32)((long(nEsc) * nH) + 500L) / 1000L);
    2079             :     // 500L to round !!
    2080             : }
    2081             : 
    2082        1148 : void RtfAttributeOutput::CharFont(const SvxFontItem& rFont)
    2083             : {
    2084        1148 :     m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LOCH);
    2085        1148 :     m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_F);
    2086        1148 :     m_aStylesEnd.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
    2087             :     // FIXME: this may be a tad expensive... but the charset needs to be
    2088             :     // consistent with what wwFont::WriteRtf() does
    2089        1148 :     FontMapExport aTmp(rFont.GetFamilyName());
    2090        1148 :     sal_uInt8 nWindowsCharset = sw::ms::rtl_TextEncodingToWinCharsetRTF(aTmp.msPrimary, aTmp.msSecondary, rFont.GetCharSet());
    2091        1148 :     m_rExport.eCurrentEncoding = rtl_getTextEncodingFromWindowsCharset(nWindowsCharset);
    2092        1148 :     if (m_rExport.eCurrentEncoding == RTL_TEXTENCODING_DONTKNOW)
    2093           0 :         m_rExport.eCurrentEncoding = m_rExport.eDefaultEncoding;
    2094        1148 : }
    2095             : 
    2096        2502 : void RtfAttributeOutput::CharFontSize(const SvxFontHeightItem& rFontSize)
    2097             : {
    2098        2502 :     switch (rFontSize.Which())
    2099             :     {
    2100             :     case RES_CHRATR_FONTSIZE:
    2101        1338 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_FS);
    2102        1338 :         m_aStylesEnd.append((sal_Int32)(rFontSize.GetHeight() / 10));
    2103        1338 :         break;
    2104             :     case RES_CHRATR_CJK_FONTSIZE:
    2105           2 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FS);
    2106           2 :         m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10));
    2107           2 :         break;
    2108             :     case RES_CHRATR_CTL_FONTSIZE:
    2109        1162 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AFS);
    2110        1162 :         m_aStyles.append((sal_Int32)(rFontSize.GetHeight() / 10));
    2111        1162 :         break;
    2112             :     }
    2113        2502 : }
    2114             : 
    2115          12 : void RtfAttributeOutput::CharKerning(const SvxKerningItem& rKerning)
    2116             : {
    2117             :     // in quarter points then in twips
    2118          12 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPND);
    2119          12 :     m_aStyles.append((sal_Int32)(rKerning.GetValue() / 5));
    2120          12 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_EXPNDTW);
    2121          12 :     m_aStyles.append((sal_Int32)(rKerning.GetValue()));
    2122          12 : }
    2123             : 
    2124         888 : void RtfAttributeOutput::CharLanguage(const SvxLanguageItem& rLanguage)
    2125             : {
    2126         888 :     switch (rLanguage.Which())
    2127             :     {
    2128             :     case RES_CHRATR_LANGUAGE:
    2129         266 :         m_aStylesEnd.append(OOO_STRING_SVTOOLS_RTF_LANG);
    2130         266 :         m_aStylesEnd.append((sal_Int32)rLanguage.GetLanguage());
    2131         266 :         break;
    2132             :     case RES_CHRATR_CJK_LANGUAGE:
    2133         318 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LANGFE);
    2134         318 :         m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
    2135         318 :         break;
    2136             :     case RES_CHRATR_CTL_LANGUAGE:
    2137         304 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ALANG);
    2138         304 :         m_aStyles.append((sal_Int32)rLanguage.GetLanguage());
    2139         304 :         break;
    2140             :     }
    2141         888 : }
    2142             : 
    2143         266 : void RtfAttributeOutput::CharPosture(const SvxPostureItem& rPosture)
    2144             : {
    2145         266 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
    2146         266 :     if (rPosture.GetPosture() == ITALIC_NONE)
    2147          78 :         m_aStyles.append((sal_Int32)0);
    2148         266 : }
    2149             : 
    2150           0 : void RtfAttributeOutput::CharShadow(const SvxShadowedItem& rShadow)
    2151             : {
    2152           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SHAD);
    2153           0 :     if (!rShadow.GetValue())
    2154           0 :         m_aStyles.append((sal_Int32)0);
    2155           0 : }
    2156             : 
    2157         104 : void RtfAttributeOutput::CharUnderline(const SvxUnderlineItem& rUnderline)
    2158             : {
    2159         104 :     const char* pStr = 0;
    2160         104 :     const SfxPoolItem* pItem = m_rExport.HasItem(RES_CHRATR_WORDLINEMODE);
    2161         104 :     bool bWord = false;
    2162         104 :     if (pItem)
    2163           0 :         bWord = ((const SvxWordLineModeItem*)pItem)->GetValue() ? true : false;
    2164         104 :     switch (rUnderline.GetLineStyle())
    2165             :     {
    2166             :     case UNDERLINE_SINGLE:
    2167          28 :         pStr = bWord ? OOO_STRING_SVTOOLS_RTF_ULW : OOO_STRING_SVTOOLS_RTF_UL;
    2168          28 :         break;
    2169             :     case UNDERLINE_DOUBLE:
    2170           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULDB;
    2171           0 :         break;
    2172             :     case UNDERLINE_NONE:
    2173          70 :         pStr = OOO_STRING_SVTOOLS_RTF_ULNONE;
    2174          70 :         break;
    2175             :     case UNDERLINE_DOTTED:
    2176           6 :         pStr = OOO_STRING_SVTOOLS_RTF_ULD;
    2177           6 :         break;
    2178             :     case UNDERLINE_DASH:
    2179           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULDASH;
    2180           0 :         break;
    2181             :     case UNDERLINE_DASHDOT:
    2182           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULDASHD;
    2183           0 :         break;
    2184             :     case UNDERLINE_DASHDOTDOT:
    2185           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULDASHDD;
    2186           0 :         break;
    2187             :     case UNDERLINE_BOLD:
    2188           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULTH;
    2189           0 :         break;
    2190             :     case UNDERLINE_WAVE:
    2191           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULWAVE;
    2192           0 :         break;
    2193             :     case UNDERLINE_BOLDDOTTED:
    2194           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULTHD;
    2195           0 :         break;
    2196             :     case UNDERLINE_BOLDDASH:
    2197           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASH;
    2198           0 :         break;
    2199             :     case UNDERLINE_LONGDASH:
    2200           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULLDASH;
    2201           0 :         break;
    2202             :     case UNDERLINE_BOLDLONGDASH:
    2203           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULTHLDASH;
    2204           0 :         break;
    2205             :     case UNDERLINE_BOLDDASHDOT:
    2206           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHD;
    2207           0 :         break;
    2208             :     case UNDERLINE_BOLDDASHDOTDOT:
    2209           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULTHDASHDD;
    2210           0 :         break;
    2211             :     case UNDERLINE_BOLDWAVE:
    2212           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULHWAVE;
    2213           0 :         break;
    2214             :     case UNDERLINE_DOUBLEWAVE:
    2215           0 :         pStr = OOO_STRING_SVTOOLS_RTF_ULULDBWAVE;
    2216           0 :         break;
    2217             :     default:
    2218           0 :         break;
    2219             :     }
    2220             : 
    2221         104 :     if (pStr)
    2222             :     {
    2223         104 :         m_aStyles.append(pStr);
    2224             :         // NEEDSWORK looks like here rUnderline.GetColor() is always black,
    2225             :         // even if the color in the odt is for example green...
    2226         104 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ULC);
    2227         104 :         m_aStyles.append((sal_Int32)m_rExport.GetColor(rUnderline.GetColor()));
    2228             :     }
    2229         104 : }
    2230             : 
    2231         434 : void RtfAttributeOutput::CharWeight(const SvxWeightItem& rWeight)
    2232             : {
    2233         434 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
    2234         434 :     if (rWeight.GetWeight() != WEIGHT_BOLD)
    2235         182 :         m_aStyles.append((sal_Int32)0);
    2236         434 : }
    2237             : 
    2238         170 : void RtfAttributeOutput::CharAutoKern(const SvxAutoKernItem& rAutoKern)
    2239             : {
    2240         170 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KERNING);
    2241         170 :     m_aStyles.append((sal_Int32)(rAutoKern.GetValue() ? 1 : 0));
    2242         170 : }
    2243             : 
    2244           0 : void RtfAttributeOutput::CharAnimatedText(const SvxBlinkItem& rBlink)
    2245             : {
    2246           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ANIMTEXT);
    2247           0 :     m_aStyles.append((sal_Int32)(rBlink.GetValue() ? 2 : 0));
    2248           0 : }
    2249             : 
    2250         158 : void RtfAttributeOutput::CharBackground(const SvxBrushItem& rBrush)
    2251             : {
    2252         158 :     if (!rBrush.GetColor().GetTransparency())
    2253             :     {
    2254          50 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HIGHLIGHT);
    2255          50 :         m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
    2256             :     }
    2257         158 : }
    2258             : 
    2259         524 : void RtfAttributeOutput::CharFontCJK(const SvxFontItem& rFont)
    2260             : {
    2261         524 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
    2262         524 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
    2263         524 :     m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
    2264         524 : }
    2265             : 
    2266           2 : void RtfAttributeOutput::CharFontSizeCJK(const SvxFontHeightItem& rFontSize)
    2267             : {
    2268           2 :     CharFontSize(rFontSize);
    2269           2 : }
    2270             : 
    2271         318 : void RtfAttributeOutput::CharLanguageCJK(const SvxLanguageItem& rLanguageItem)
    2272             : {
    2273         318 :     CharLanguage(rLanguageItem);
    2274         318 : }
    2275             : 
    2276           0 : void RtfAttributeOutput::CharPostureCJK(const SvxPostureItem& rPosture)
    2277             : {
    2278           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_I);
    2279           0 :     if (rPosture.GetPosture() == ITALIC_NONE)
    2280           0 :         m_aStyles.append((sal_Int32)0);
    2281           0 : }
    2282             : 
    2283           0 : void RtfAttributeOutput::CharWeightCJK(const SvxWeightItem& rWeight)
    2284             : {
    2285           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_B);
    2286           0 :     if (rWeight.GetWeight() != WEIGHT_BOLD)
    2287           0 :         m_aStyles.append((sal_Int32)0);
    2288           0 : }
    2289             : 
    2290         720 : void RtfAttributeOutput::CharFontCTL(const SvxFontItem& rFont)
    2291             : {
    2292         720 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_DBCH);
    2293         720 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AF);
    2294         720 :     m_aStyles.append((sal_Int32)m_rExport.maFontHelper.GetId(rFont));
    2295         720 : }
    2296             : 
    2297        1162 : void RtfAttributeOutput::CharFontSizeCTL(const SvxFontHeightItem& rFontSize)
    2298             : {
    2299        1162 :     CharFontSize(rFontSize);
    2300        1162 : }
    2301             : 
    2302         304 : void RtfAttributeOutput::CharLanguageCTL(const SvxLanguageItem& rLanguageItem)
    2303             : {
    2304         304 :     CharLanguage(rLanguageItem);
    2305         304 : }
    2306             : 
    2307         242 : void RtfAttributeOutput::CharPostureCTL(const SvxPostureItem& rPosture)
    2308             : {
    2309         242 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AI);
    2310         242 :     if (rPosture.GetPosture() == ITALIC_NONE)
    2311          50 :         m_aStyles.append((sal_Int32)0);
    2312         242 : }
    2313             : 
    2314         374 : void RtfAttributeOutput::CharWeightCTL(const SvxWeightItem& rWeight)
    2315             : {
    2316         374 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_AB);
    2317         374 :     if (rWeight.GetWeight() != WEIGHT_BOLD)
    2318         174 :         m_aStyles.append((sal_Int32)0);
    2319         374 : }
    2320             : 
    2321           0 : void RtfAttributeOutput::CharBidiRTL(const SfxPoolItem&)
    2322             : {
    2323           0 : }
    2324             : 
    2325           6 : void RtfAttributeOutput::CharIdctHint(const SfxPoolItem&)
    2326             : {
    2327           6 : }
    2328             : 
    2329           4 : void RtfAttributeOutput::CharRotate(const SvxCharRotateItem& rRotate)
    2330             : {
    2331           4 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HORZVERT);
    2332           4 :     m_aStyles.append((sal_Int32)(rRotate.IsFitToLine() ? 1 : 0));
    2333           4 : }
    2334             : 
    2335          12 : void RtfAttributeOutput::CharEmphasisMark(const SvxEmphasisMarkItem& rEmphasisMark)
    2336             : {
    2337          12 :     switch (rEmphasisMark.GetEmphasisMark())
    2338             :     {
    2339             :     case EMPHASISMARK_NONE:
    2340           4 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCNONE);
    2341           4 :         break;
    2342             :     case EMPHASISMARK_DOT | EMPHASISMARK_POS_ABOVE:
    2343           2 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCDOT);
    2344           2 :         break;
    2345             :     case EMPHASISMARK_ACCENT | EMPHASISMARK_POS_ABOVE:
    2346           2 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCOMMA);
    2347           2 :         break;
    2348             :     case EMPHASISMARK_CIRCLE | EMPHASISMARK_POS_ABOVE:
    2349           2 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCCIRCLE);
    2350           2 :         break;
    2351             :     case EMPHASISMARK_DOT|EMPHASISMARK_POS_BELOW:
    2352           2 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ACCUNDERDOT);
    2353           2 :         break;
    2354             :     }
    2355          12 : }
    2356             : 
    2357           0 : void RtfAttributeOutput::CharTwoLines(const SvxTwoLinesItem& rTwoLines)
    2358             : {
    2359           0 :     if (rTwoLines.GetValue())
    2360             :     {
    2361           0 :         sal_Unicode cStart = rTwoLines.GetStartBracket();
    2362           0 :         sal_Unicode cEnd =   rTwoLines.GetEndBracket();
    2363             : 
    2364             :         sal_uInt16 nType;
    2365           0 :         if (!cStart && !cEnd)
    2366           0 :             nType = 0;
    2367           0 :         else if ('{' == cStart || '}' == cEnd)
    2368           0 :             nType = 4;
    2369           0 :         else if ('<' == cStart || '>' == cEnd)
    2370           0 :             nType = 3;
    2371           0 :         else if ('[' == cStart || ']' == cEnd)
    2372           0 :             nType = 2;
    2373             :         else                            // all other kind of brackets
    2374           0 :             nType = 1;
    2375             : 
    2376           0 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TWOINONE);
    2377           0 :         m_aStyles.append((sal_Int32)nType);
    2378             :     }
    2379           0 : }
    2380             : 
    2381           0 : void RtfAttributeOutput::CharScaleWidth(const SvxCharScaleWidthItem& rScaleWidth)
    2382             : {
    2383           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CHARSCALEX);
    2384           0 :     m_aStyles.append((sal_Int32)rScaleWidth.GetValue());
    2385           0 : }
    2386             : 
    2387          10 : void RtfAttributeOutput::CharRelief(const SvxCharReliefItem& rRelief)
    2388             : {
    2389             :     const sal_Char* pStr;
    2390          10 :     switch (rRelief.GetValue())
    2391             :     {
    2392             :     case RELIEF_EMBOSSED:
    2393           0 :         pStr = OOO_STRING_SVTOOLS_RTF_EMBO;
    2394           0 :         break;
    2395             :     case RELIEF_ENGRAVED:
    2396           0 :         pStr = OOO_STRING_SVTOOLS_RTF_IMPR;
    2397           0 :         break;
    2398             :     default:
    2399          10 :         pStr = 0;
    2400          10 :         break;
    2401             :     }
    2402             : 
    2403          10 :     if (pStr)
    2404           0 :         m_aStyles.append(pStr);
    2405          10 : }
    2406             : 
    2407           0 : void RtfAttributeOutput::CharHidden(const SvxCharHiddenItem& rHidden)
    2408             : {
    2409           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_V);
    2410           0 :     if (!rHidden.GetValue())
    2411           0 :         m_aStyles.append((sal_Int32)0);
    2412           0 : }
    2413             : 
    2414           4 : void RtfAttributeOutput::CharBorder(const SvxBorderLine* pAllBorder, const sal_uInt16 nDist, const bool bShadow)
    2415             : {
    2416           4 :     m_aStyles.append(OutBorderLine(m_rExport, pAllBorder, OOO_STRING_SVTOOLS_RTF_CHBRDR, nDist, bShadow ? SVX_SHADOW_BOTTOMRIGHT : SVX_SHADOW_NONE));
    2417           4 : }
    2418             : 
    2419          10 : void RtfAttributeOutput::TextINetFormat(const SwFmtINetFmt& rURL)
    2420             : {
    2421          10 :     if (!rURL.GetValue().isEmpty())
    2422             :     {
    2423             :         const SwCharFmt* pFmt;
    2424          10 :         const SwTxtINetFmt* pTxtAtr = rURL.GetTxtINetFmt();
    2425             : 
    2426          10 :         if (pTxtAtr && 0 != (pFmt = pTxtAtr->GetCharFmt()))
    2427             :         {
    2428          10 :             sal_uInt16 nStyle = m_rExport.GetId(pFmt);
    2429          10 :             OString* pString = m_rExport.GetStyle(nStyle);
    2430          10 :             if (pString)
    2431          10 :                 m_aStyles.append(*pString);
    2432             :         }
    2433             :     }
    2434          10 : }
    2435             : 
    2436           0 : void RtfAttributeOutput::TextCharFormat(const SwFmtCharFmt& rCharFmt)
    2437             : {
    2438           0 :     sal_uInt16 nStyle = m_rExport.GetId(rCharFmt.GetCharFmt());
    2439           0 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CS);
    2440           0 :     m_aStyles.append((sal_Int32)nStyle);
    2441           0 :     OString* pString = m_rExport.GetStyle(nStyle);
    2442           0 :     if (pString)
    2443           0 :         m_aStyles.append(*pString);
    2444           0 : }
    2445             : 
    2446          12 : void RtfAttributeOutput::WriteTextFootnoteNumStr(const SwFmtFtn& rFootnote)
    2447             : {
    2448          12 :     if (rFootnote.GetNumStr().isEmpty())
    2449          12 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_CHFTN);
    2450             :     else
    2451           0 :         m_aRun->append(msfilter::rtfutil::OutString(rFootnote.GetNumStr(), m_rExport.eCurrentEncoding));
    2452          12 : }
    2453             : 
    2454           6 : void RtfAttributeOutput::TextFootnote_Impl(const SwFmtFtn& rFootnote)
    2455             : {
    2456             :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " start");
    2457             : 
    2458           6 :     m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_SUPER " ");
    2459           6 :     WriteTextFootnoteNumStr(rFootnote);
    2460           6 :     m_aRun->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FOOTNOTE);
    2461           6 :     if (rFootnote.IsEndNote())
    2462           0 :         m_aRun->append(OOO_STRING_SVTOOLS_RTF_FTNALT);
    2463           6 :     m_aRun->append(' ');
    2464           6 :     WriteTextFootnoteNumStr(rFootnote);
    2465             : 
    2466             :     /*
    2467             :      * The footnote contains a whole paragraph, so we have to:
    2468             :      * 1) Reset, then later restore the contents of our run buffer and run state.
    2469             :      * 2) Buffer the output of the whole paragraph, as we do so for section headers already.
    2470             :      */
    2471           6 :     const SwNodeIndex* pIndex = rFootnote.GetTxtFtn()->GetStartNode();
    2472           6 :     RtfStringBuffer aRun = m_aRun;
    2473           6 :     m_aRun.clear();
    2474           6 :     bool bInRunOrig = m_bInRun;
    2475           6 :     m_bInRun = false;
    2476           6 :     bool bSingleEmptyRunOrig = m_bSingleEmptyRun;
    2477           6 :     m_bSingleEmptyRun = false;
    2478           6 :     m_bBufferSectionHeaders = true;
    2479           6 :     m_rExport.WriteSpecialText(pIndex->GetIndex() + 1,
    2480           6 :                                pIndex->GetNode().EndOfSectionIndex(),
    2481          18 :                                !rFootnote.IsEndNote() ? TXT_FTN : TXT_EDN);
    2482           6 :     m_bBufferSectionHeaders = false;
    2483           6 :     m_bInRun = bInRunOrig;
    2484           6 :     m_bSingleEmptyRun = bSingleEmptyRunOrig;
    2485           6 :     m_aRun = aRun;
    2486           6 :     m_aRun->append(m_aSectionHeaders.makeStringAndClear());
    2487             : 
    2488           6 :     m_aRun->append("}");
    2489           6 :     m_aRun->append("}");
    2490             : 
    2491           6 :     SAL_INFO("sw.rtf", OSL_THIS_FUNC << " end");
    2492           6 : }
    2493             : 
    2494         296 : void RtfAttributeOutput::ParaLineSpacing_Impl(short nSpace, short nMulti)
    2495             : {
    2496         296 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SL);
    2497         296 :     m_aStyles.append((sal_Int32)nSpace);
    2498         296 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SLMULT);
    2499         296 :     m_aStyles.append((sal_Int32)nMulti);
    2500             : 
    2501         296 : }
    2502             : 
    2503         788 : void RtfAttributeOutput::ParaAdjust(const SvxAdjustItem& rAdjust)
    2504             : {
    2505         788 :     switch (rAdjust.GetAdjust())
    2506             :     {
    2507             :     case SVX_ADJUST_LEFT:
    2508         312 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QL);
    2509         312 :         break;
    2510             :     case SVX_ADJUST_RIGHT:
    2511          12 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QR);
    2512          12 :         break;
    2513             :     case SVX_ADJUST_BLOCKLINE:
    2514             :     case SVX_ADJUST_BLOCK:
    2515          90 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QJ);
    2516          90 :         break;
    2517             :     case SVX_ADJUST_CENTER:
    2518         374 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_QC);
    2519         374 :         break;
    2520             :     default:
    2521           0 :         break;
    2522             :     }
    2523         788 : }
    2524             : 
    2525          62 : void RtfAttributeOutput::ParaSplit(const SvxFmtSplitItem& rSplit)
    2526             : {
    2527          62 :     if (!rSplit.GetValue())
    2528          62 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEP);
    2529          62 : }
    2530             : 
    2531         252 : void RtfAttributeOutput::ParaWidows(const SvxWidowsItem& rWidows)
    2532             : {
    2533         252 :     if (rWidows.GetValue())
    2534          86 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_WIDCTLPAR);
    2535             :     else
    2536         166 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOWIDCTLPAR);
    2537         252 : }
    2538             : 
    2539         372 : void RtfAttributeOutput::ParaTabStop(const SvxTabStopItem& rTabStop)
    2540             : {
    2541         372 :     long nOffset = ((SvxLRSpaceItem&)m_rExport.GetItem(RES_LR_SPACE)).GetTxtLeft();
    2542         706 :     for (sal_uInt16 n = 0; n < rTabStop.Count(); n++)
    2543             :     {
    2544         334 :         const SvxTabStop& rTS = rTabStop[ n ];
    2545         334 :         if (SVX_TAB_ADJUST_DEFAULT != rTS.GetAdjustment())
    2546             :         {
    2547         194 :             const char* pFill = 0;
    2548         194 :             switch (rTS.GetFill())
    2549             :             {
    2550             :             case cDfltFillChar:
    2551         126 :                 break;
    2552             : 
    2553             :             case '.':
    2554          68 :                 pFill = OOO_STRING_SVTOOLS_RTF_TLDOT;
    2555          68 :                 break;
    2556             :             case '_':
    2557           0 :                 pFill = OOO_STRING_SVTOOLS_RTF_TLUL;
    2558           0 :                 break;
    2559             :             case '-':
    2560           0 :                 pFill = OOO_STRING_SVTOOLS_RTF_TLTH;
    2561           0 :                 break;
    2562             :             case '=':
    2563           0 :                 pFill = OOO_STRING_SVTOOLS_RTF_TLEQ;
    2564           0 :                 break;
    2565             :             default:
    2566           0 :                 break;
    2567             :             }
    2568         194 :             if (pFill)
    2569          68 :                 m_aStyles.append(pFill);
    2570             : 
    2571         194 :             const sal_Char* pAdjStr = 0;
    2572         194 :             switch (rTS.GetAdjustment())
    2573             :             {
    2574             :             case SVX_TAB_ADJUST_RIGHT:
    2575          84 :                 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQR;
    2576          84 :                 break;
    2577             :             case SVX_TAB_ADJUST_DECIMAL:
    2578           0 :                 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQDEC;
    2579           0 :                 break;
    2580             :             case SVX_TAB_ADJUST_CENTER:
    2581          12 :                 pAdjStr = OOO_STRING_SVTOOLS_RTF_TQC;
    2582          12 :                 break;
    2583             :             default:
    2584          98 :                 break;
    2585             :             }
    2586         194 :             if (pAdjStr)
    2587          96 :                 m_aStyles.append(pAdjStr);
    2588         194 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TX);
    2589         194 :             m_aStyles.append((sal_Int32)(rTS.GetTabPos() + nOffset));
    2590             :         }
    2591             :         else
    2592             :         {
    2593         140 :             m_aTabStop.append(OOO_STRING_SVTOOLS_RTF_DEFTAB);
    2594         140 :             m_aTabStop.append((sal_Int32)rTabStop[0].GetTabPos());
    2595             :         }
    2596             :     }
    2597         372 : }
    2598             : 
    2599         144 : void RtfAttributeOutput::ParaHyphenZone(const SvxHyphenZoneItem& rHyphenZone)
    2600             : {
    2601         144 :     sal_Int32 nFlags = rHyphenZone.IsHyphen() ? 1 : 0;
    2602         144 :     if (rHyphenZone.IsPageEnd())
    2603         144 :         nFlags += 2;
    2604         144 :     m_aStyles.append('{');
    2605         144 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_IGNORE);
    2606         144 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHEN);
    2607         144 :     m_aStyles.append((sal_Int32)nFlags);
    2608         144 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHLEAD);
    2609         144 :     m_aStyles.append((sal_Int32)rHyphenZone.GetMinLead());
    2610         144 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHTRAIL);
    2611         144 :     m_aStyles.append((sal_Int32)rHyphenZone.GetMinTrail());
    2612         144 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_HYPHMAX);
    2613         144 :     m_aStyles.append((sal_Int32)rHyphenZone.GetMaxHyphens());
    2614         144 :     m_aStyles.append('}');
    2615         144 : }
    2616             : 
    2617         136 : void RtfAttributeOutput::ParaNumRule_Impl(const SwTxtNode* pTxtNd, sal_Int32 nLvl, sal_Int32 nNumId)
    2618             : {
    2619         136 :     if (USHRT_MAX == nNumId || 0 == nNumId || 0 == pTxtNd)
    2620         176 :         return;
    2621             : 
    2622          96 :     const SwNumRule* pRule = pTxtNd->GetNumRule();
    2623             : 
    2624          96 :     if (pRule && pTxtNd->IsInList())
    2625             :     {
    2626             :         SAL_WARN_IF(pTxtNd->GetActualListLevel() < 0 || pTxtNd->GetActualListLevel() >= MAXLEVEL, "sw.rtf", "text node does not have valid list level");
    2627             : 
    2628          96 :         const SwNumFmt* pFmt = pRule->GetNumFmt(nLvl);
    2629          96 :         if (!pFmt)
    2630           0 :             pFmt = &pRule->Get(nLvl);
    2631             : 
    2632          96 :         const SfxItemSet& rNdSet = pTxtNd->GetSwAttrSet();
    2633             : 
    2634          96 :         m_aStyles.append('{');
    2635          96 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LISTTEXT);
    2636          96 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PARD);
    2637          96 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_PLAIN);
    2638          96 :         m_aStyles.append(' ');
    2639             : 
    2640          96 :         SvxLRSpaceItem aLR((SvxLRSpaceItem&)rNdSet.Get(RES_LR_SPACE));
    2641          96 :         aLR.SetTxtLeft(aLR.GetTxtLeft() + pFmt->GetIndentAt());
    2642          96 :         aLR.SetTxtFirstLineOfst(pFmt->GetFirstLineOffset());
    2643             : 
    2644          96 :         sal_uInt16 nStyle = m_rExport.GetId(pFmt->GetCharFmt());
    2645          96 :         OString* pString = m_rExport.GetStyle(nStyle);
    2646          96 :         if (pString)
    2647          12 :             m_aStyles.append(*pString);
    2648             : 
    2649             :         {
    2650          96 :             OUString sTxt;
    2651          96 :             if (SVX_NUM_CHAR_SPECIAL == pFmt->GetNumberingType() || SVX_NUM_BITMAP == pFmt->GetNumberingType())
    2652           2 :                 sTxt = OUString(pFmt->GetBulletChar());
    2653             :             else
    2654          94 :                 sTxt = pTxtNd->GetNumString();
    2655             : 
    2656          96 :             if (!sTxt.isEmpty())
    2657             :             {
    2658          30 :                 m_aStyles.append(' ');
    2659          30 :                 m_aStyles.append(msfilter::rtfutil::OutString(sTxt, m_rExport.eDefaultEncoding));
    2660             :             }
    2661             : 
    2662          96 :             if (OUTLINE_RULE != pRule->GetRuleType())
    2663             :             {
    2664          30 :                 if (!sTxt.isEmpty())
    2665          30 :                     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB);
    2666          30 :                 m_aStyles.append('}');
    2667          30 :                 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ILVL);
    2668          30 :                 if (nLvl > 8)             // RTF knows only 9 levels
    2669             :                 {
    2670           0 :                     m_aStyles.append((sal_Int32)8);
    2671           0 :                     m_aStyles.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SOUTLVL);
    2672           0 :                     m_aStyles.append((sal_Int32)nLvl);
    2673           0 :                     m_aStyles.append('}');
    2674             :                 }
    2675             :                 else
    2676          30 :                     m_aStyles.append((sal_Int32)nLvl);
    2677             :             }
    2678             :             else
    2679          66 :                 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_TAB "}");
    2680          96 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LS);
    2681          96 :             m_aStyles.append((sal_Int32)m_rExport.GetId(*pRule)+1);
    2682          96 :             m_aStyles.append(' ');
    2683             :         }
    2684          96 :         FormatLRSpace(aLR);
    2685             :     }
    2686             : }
    2687             : 
    2688          36 : void RtfAttributeOutput::ParaScriptSpace(const SfxBoolItem& rScriptSpace)
    2689             : {
    2690          36 :     if (!rScriptSpace.GetValue())
    2691          36 :         return;
    2692             : 
    2693          36 :     m_aStyles.append(OOO_STRING_SVTOOLS_RTF_ASPALPHA);
    2694             : }
    2695             : 
    2696          36 : void RtfAttributeOutput::ParaHangingPunctuation(const SfxBoolItem&)
    2697             : {
    2698             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    2699          36 : }
    2700             : 
    2701          36 : void RtfAttributeOutput::ParaForbiddenRules(const SfxBoolItem&)
    2702             : {
    2703             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    2704          36 : }
    2705             : 
    2706          14 : void RtfAttributeOutput::ParaVerticalAlign(const SvxParaVertAlignItem& rAlign)
    2707             : {
    2708             :     const char* pStr;
    2709          14 :     switch (rAlign.GetValue())
    2710             :     {
    2711             :     case SvxParaVertAlignItem::TOP:
    2712           0 :         pStr = OOO_STRING_SVTOOLS_RTF_FAHANG;
    2713           0 :         break;
    2714             :     case SvxParaVertAlignItem::BOTTOM:
    2715           0 :         pStr = OOO_STRING_SVTOOLS_RTF_FAVAR;
    2716           0 :         break;
    2717             :     case SvxParaVertAlignItem::CENTER:
    2718           0 :         pStr = OOO_STRING_SVTOOLS_RTF_FACENTER;
    2719           0 :         break;
    2720             :     case SvxParaVertAlignItem::BASELINE:
    2721           0 :         pStr = OOO_STRING_SVTOOLS_RTF_FAROMAN;
    2722           0 :         break;
    2723             : 
    2724             :     default:
    2725          14 :         pStr = OOO_STRING_SVTOOLS_RTF_FAAUTO;
    2726          14 :         break;
    2727             :     }
    2728          14 :     m_aStyles.append(pStr);
    2729          14 : }
    2730             : 
    2731           0 : void RtfAttributeOutput::ParaSnapToGrid(const SvxParaGridItem& /*rGrid*/)
    2732             : {
    2733             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    2734           0 : }
    2735             : 
    2736         386 : void RtfAttributeOutput::FormatFrameSize(const SwFmtFrmSize& rSize)
    2737             : {
    2738         386 :     if (m_rExport.bOutPageDescs)
    2739             :     {
    2740         330 :         m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGWSXN);
    2741         330 :         m_aSectionBreaks.append((sal_Int32)rSize.GetWidth());
    2742         330 :         m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_PGHSXN);
    2743         330 :         m_aSectionBreaks.append((sal_Int32)rSize.GetHeight());
    2744         330 :         if (!m_bBufferSectionBreaks)
    2745         320 :             m_rExport.Strm().WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
    2746             :     }
    2747         386 : }
    2748             : 
    2749           0 : void RtfAttributeOutput::FormatPaperBin(const SvxPaperBinItem&)
    2750             : {
    2751             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    2752           0 : }
    2753             : 
    2754         716 : void RtfAttributeOutput::FormatLRSpace(const SvxLRSpaceItem& rLRSpace)
    2755             : {
    2756         716 :     if (!m_rExport.bOutFlyFrmAttrs)
    2757             :     {
    2758         666 :         if (m_rExport.bOutPageDescs)
    2759             :         {
    2760         330 :             if (rLRSpace.GetLeft())
    2761             :             {
    2762         328 :                 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGLSXN);
    2763         328 :                 m_aSectionBreaks.append((sal_Int32)rLRSpace.GetLeft());
    2764             :             }
    2765         330 :             if (rLRSpace.GetRight())
    2766             :             {
    2767         328 :                 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGRSXN);
    2768         328 :                 m_aSectionBreaks.append((sal_Int32)rLRSpace.GetRight());
    2769             :             }
    2770         330 :             if (!m_bBufferSectionBreaks)
    2771         320 :                 m_rExport.Strm().                    WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
    2772             :         }
    2773             :         else
    2774             :         {
    2775         336 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LI);
    2776         336 :             m_aStyles.append((sal_Int32) rLRSpace.GetTxtLeft());
    2777         336 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RI);
    2778         336 :             m_aStyles.append((sal_Int32) rLRSpace.GetRight());
    2779         336 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LIN);
    2780         336 :             m_aStyles.append((sal_Int32) rLRSpace.GetTxtLeft());
    2781         336 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RIN);
    2782         336 :             m_aStyles.append((sal_Int32) rLRSpace.GetRight());
    2783         336 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_FI);
    2784         336 :             m_aStyles.append((sal_Int32) rLRSpace.GetTxtFirstLineOfst());
    2785             :         }
    2786             :     }
    2787          50 :     else if (m_rExport.bRTFFlySyntax)
    2788             :     {
    2789             :         // Wrap: top and bottom spacing, convert from twips to EMUs.
    2790          44 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxWrapDistLeft", OString::number(rLRSpace.GetLeft() * 635)));
    2791          44 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxWrapDistRight", OString::number(rLRSpace.GetRight() * 635)));
    2792             :     }
    2793         716 : }
    2794             : 
    2795        1198 : void RtfAttributeOutput::FormatULSpace(const SvxULSpaceItem& rULSpace)
    2796             : {
    2797        1198 :     if (!m_rExport.bOutFlyFrmAttrs)
    2798             :     {
    2799        1154 :         if (m_rExport.bOutPageDescs)
    2800             :         {
    2801             :             OSL_ENSURE(m_rExport.GetCurItemSet(), "Impossible");
    2802         330 :             if (!m_rExport.GetCurItemSet())
    2803        1198 :                 return;
    2804             : 
    2805         330 :             HdFtDistanceGlue aDistances(*m_rExport.GetCurItemSet());
    2806             : 
    2807         330 :             if (aDistances.dyaTop)
    2808             :             {
    2809         328 :                 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGTSXN);
    2810         328 :                 m_aSectionBreaks.append((sal_Int32)aDistances.dyaTop);
    2811             :             }
    2812         330 :             if (aDistances.HasHeader())
    2813             :             {
    2814          26 :                 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_HEADERY);
    2815          26 :                 m_aSectionBreaks.append((sal_Int32)aDistances.dyaHdrTop);
    2816             :             }
    2817             : 
    2818         330 :             if (aDistances.dyaBottom)
    2819             :             {
    2820         328 :                 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_MARGBSXN);
    2821         328 :                 m_aSectionBreaks.append((sal_Int32)aDistances.dyaBottom);
    2822             :             }
    2823         330 :             if (aDistances.HasFooter())
    2824             :             {
    2825          30 :                 m_aSectionBreaks.append(OOO_STRING_SVTOOLS_RTF_FOOTERY);
    2826          30 :                 m_aSectionBreaks.append((sal_Int32)aDistances.dyaHdrBottom);
    2827             :             }
    2828         330 :             if (!m_bBufferSectionBreaks)
    2829         320 :                 m_rExport.Strm().                    WriteCharPtr(m_aSectionBreaks.makeStringAndClear().getStr());
    2830             :         }
    2831             :         else
    2832             :         {
    2833         824 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SB);
    2834         824 :             m_aStyles.append((sal_Int32) rULSpace.GetUpper());
    2835         824 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_SA);
    2836         824 :             m_aStyles.append((sal_Int32) rULSpace.GetLower());
    2837         824 :             if (rULSpace.GetContext())
    2838           2 :                 m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CONTEXTUALSPACE);
    2839             :         }
    2840             :     }
    2841          44 :     else if (m_rExport.bRTFFlySyntax)
    2842             :     {
    2843             :         // Wrap: top and bottom spacing, convert from twips to EMUs.
    2844          40 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyWrapDistTop", OString::number(rULSpace.GetUpper() * 635)));
    2845          40 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyWrapDistBottom", OString::number(rULSpace.GetLower() * 635)));
    2846             :     }
    2847             : }
    2848             : 
    2849          56 : void RtfAttributeOutput::FormatSurround(const SwFmtSurround& rSurround)
    2850             : {
    2851          56 :     if (m_rExport.bOutFlyFrmAttrs && !m_rExport.bRTFFlySyntax)
    2852             :     {
    2853           8 :         SwSurround eSurround = rSurround.GetSurround();
    2854           8 :         bool bGold = SURROUND_IDEAL == eSurround;
    2855           8 :         if (bGold)
    2856           2 :             eSurround = SURROUND_PARALLEL;
    2857           8 :         RTFSurround aMC(bGold, static_cast< sal_uInt8 >(eSurround));
    2858           8 :         m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYMAINCNT);
    2859           8 :         m_aRunText->append((sal_Int32) aMC.GetValue());
    2860             :     }
    2861          48 :     else if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
    2862             :     {
    2863             :         // See DocxSdrExport::startDMLAnchorInline() for SwFmtSurround -> WR / WRK mappings.
    2864          48 :         sal_Int32 nWr = -1;
    2865          48 :         boost::optional<sal_Int32> oWrk;
    2866          48 :         switch (rSurround.GetValue())
    2867             :         {
    2868             :         case SURROUND_NONE:
    2869           0 :             nWr = 1; // top and bottom
    2870           0 :             break;
    2871             :         case SURROUND_THROUGHT:
    2872          16 :             nWr = 3; // none
    2873          16 :             break;
    2874             :         case SURROUND_PARALLEL:
    2875          28 :             nWr = 2; // around
    2876          28 :             oWrk = 0; // both sides
    2877          28 :             break;
    2878             :         case SURROUND_IDEAL:
    2879             :         default:
    2880           4 :             nWr = 2; // around
    2881           4 :             oWrk = 3; // largest
    2882           4 :             break;
    2883             :         }
    2884             : 
    2885          48 :         if (rSurround.IsContour())
    2886           4 :             nWr = 4; // tight
    2887             : 
    2888          48 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWR);
    2889          48 :         m_rExport.OutLong(nWr);
    2890          48 :         if (oWrk)
    2891             :         {
    2892          32 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPWRK);
    2893          32 :             m_rExport.OutLong(*oWrk);
    2894          48 :         }
    2895             :     }
    2896          56 : }
    2897             : 
    2898          56 : void RtfAttributeOutput::FormatVertOrientation(const SwFmtVertOrient& rFlyVert)
    2899             : {
    2900          56 :     if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
    2901             :     {
    2902          48 :         switch (rFlyVert.GetRelationOrient())
    2903             :         {
    2904             :         case text::RelOrientation::PAGE_FRAME:
    2905           2 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelv", OString::number(1)));
    2906           2 :             break;
    2907             :         default:
    2908          46 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelv", OString::number(2)));
    2909          46 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYPARA).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBYIGNORE);
    2910          46 :             break;
    2911             :         }
    2912             : 
    2913          48 :         switch (rFlyVert.GetVertOrient())
    2914             :         {
    2915             :         case text::VertOrientation::TOP:
    2916             :         case text::VertOrientation::LINE_TOP:
    2917          14 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(1)));
    2918          14 :             break;
    2919             :         case text::VertOrientation::BOTTOM:
    2920             :         case text::VertOrientation::LINE_BOTTOM:
    2921           0 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(3)));
    2922           0 :             break;
    2923             :         case text::VertOrientation::CENTER:
    2924             :         case text::VertOrientation::LINE_CENTER:
    2925           0 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posv", OString::number(2)));
    2926           0 :             break;
    2927             :         default:
    2928          34 :             break;
    2929             :         }
    2930             : 
    2931          48 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPTOP);
    2932          48 :         m_rExport.OutLong(rFlyVert.GetPos());
    2933          48 :         if (m_pFlyFrameSize)
    2934             :         {
    2935          32 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBOTTOM);
    2936          32 :             m_rExport.OutLong(rFlyVert.GetPos() + m_pFlyFrameSize->Height());
    2937             :         }
    2938             :     }
    2939          56 : }
    2940             : 
    2941          56 : void RtfAttributeOutput::FormatHorizOrientation(const SwFmtHoriOrient& rFlyHori)
    2942             : {
    2943          56 :     if (m_rExport.bOutFlyFrmAttrs && m_rExport.bRTFFlySyntax)
    2944             :     {
    2945          48 :         switch (rFlyHori.GetRelationOrient())
    2946             :         {
    2947             :         case text::RelOrientation::PAGE_FRAME:
    2948           4 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelh", OString::number(1)));
    2949           4 :             break;
    2950             :         default:
    2951          44 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posrelh", OString::number(2)));
    2952          44 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXCOLUMN).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPBXIGNORE);
    2953          44 :             break;
    2954             :         }
    2955             : 
    2956          48 :         switch (rFlyHori.GetHoriOrient())
    2957             :         {
    2958             :         case text::HoriOrientation::LEFT:
    2959           0 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(1)));
    2960           0 :             break;
    2961             :         case text::HoriOrientation::CENTER:
    2962          22 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(2)));
    2963          22 :             break;
    2964             :         case text::HoriOrientation::RIGHT:
    2965           0 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("posh", OString::number(3)));
    2966           0 :             break;
    2967             :         default:
    2968          26 :             break;
    2969             :         }
    2970             : 
    2971          48 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPLEFT);
    2972          48 :         m_rExport.OutLong(rFlyHori.GetPos());
    2973          48 :         if (m_pFlyFrameSize)
    2974             :         {
    2975          32 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SHPRIGHT);
    2976          32 :             m_rExport.OutLong(rFlyHori.GetPos() + m_pFlyFrameSize->Width());
    2977             :         }
    2978             :     }
    2979          56 : }
    2980             : 
    2981          56 : void RtfAttributeOutput::FormatAnchor(const SwFmtAnchor& rAnchor)
    2982             : {
    2983          56 :     if (!m_rExport.bRTFFlySyntax)
    2984             :     {
    2985           8 :         sal_uInt16 nId = static_cast< sal_uInt16 >(rAnchor.GetAnchorId());
    2986           8 :         m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYANCHOR);
    2987           8 :         m_aRunText->append((sal_Int32)nId);
    2988           8 :         switch (nId)
    2989             :         {
    2990             :         case FLY_AT_PAGE:
    2991           2 :             m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYPAGE);
    2992           2 :             m_aRunText->append((sal_Int32)rAnchor.GetPageNum());
    2993           2 :             break;
    2994             :         case FLY_AT_PARA:
    2995             :         case FLY_AS_CHAR:
    2996           2 :             m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLYCNTNT);
    2997           2 :             break;
    2998             :         }
    2999             :     }
    3000          56 : }
    3001             : 
    3002           4 : void RtfAttributeOutput::FormatBackground(const SvxBrushItem& rBrush)
    3003             : {
    3004           4 :     if (m_rExport.bRTFFlySyntax)
    3005             :     {
    3006           4 :         const Color& rColor = rBrush.GetColor();
    3007             :         // We in fact need RGB to BGR, but the transformation is symmetric.
    3008           4 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
    3009             :     }
    3010           0 :     else if (!rBrush.GetColor().GetTransparency())
    3011             :     {
    3012           0 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_CBPAT);
    3013           0 :         m_aStyles.append((sal_Int32)m_rExport.GetColor(rBrush.GetColor()));
    3014             :     }
    3015           4 : }
    3016             : 
    3017        1442 : void RtfAttributeOutput::FormatFillStyle(const XFillStyleItem& rFillStyle)
    3018             : {
    3019        1442 :     m_oFillStyle.reset(rFillStyle.GetValue());
    3020        1442 : }
    3021             : 
    3022           4 : void RtfAttributeOutput::FormatFillGradient(const XFillGradientItem& rFillGradient)
    3023             : {
    3024           4 :     if (*m_oFillStyle == drawing::FillStyle_GRADIENT)
    3025             :     {
    3026           4 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillType", OString::number(7))); // Shade using the fillAngle
    3027             : 
    3028           4 :         const XGradient& rGradient = rFillGradient.GetGradientValue();
    3029           4 :         const Color& rStartColor = rGradient.GetStartColor();
    3030           4 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillBackColor", OString::number(msfilter::util::BGRToRGB(rStartColor.GetColor()))));
    3031             : 
    3032           4 :         const Color& rEndColor = rGradient.GetEndColor();
    3033           4 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillColor", OString::number(msfilter::util::BGRToRGB(rEndColor.GetColor()))));
    3034             : 
    3035           4 :         switch (rGradient.GetGradientStyle())
    3036             :         {
    3037             :         case XGRAD_LINEAR:
    3038           0 :             break;
    3039             :         case XGRAD_AXIAL:
    3040           4 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("fillFocus", OString::number(50)));
    3041           4 :             break;
    3042             :         case XGRAD_RADIAL:
    3043           0 :             break;
    3044             :         case XGRAD_ELLIPTICAL:
    3045           0 :             break;
    3046             :         case XGRAD_SQUARE:
    3047           0 :             break;
    3048             :         case XGRAD_RECT:
    3049           0 :             break;
    3050             :         }
    3051             :     }
    3052           4 : }
    3053             : 
    3054          90 : void RtfAttributeOutput::FormatBox(const SvxBoxItem& rBox)
    3055             : {
    3056             :     static const sal_uInt16 aBorders[] =
    3057             :     {
    3058             :         BOX_LINE_TOP, BOX_LINE_LEFT, BOX_LINE_BOTTOM, BOX_LINE_RIGHT
    3059             :     };
    3060             :     static const sal_Char* aBorderNames[] =
    3061             :     {
    3062             :         OOO_STRING_SVTOOLS_RTF_BRDRT, OOO_STRING_SVTOOLS_RTF_BRDRL, OOO_STRING_SVTOOLS_RTF_BRDRB, OOO_STRING_SVTOOLS_RTF_BRDRR
    3063             :     };
    3064             : 
    3065          90 :     sal_uInt16 nDist = rBox.GetDistance();
    3066             : 
    3067          90 :     if (m_rExport.bRTFFlySyntax)
    3068             :     {
    3069             :         // Borders: spacing to contents, convert from twips to EMUs.
    3070          50 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxTextLeft", OString::number(rBox.GetDistance(BOX_LINE_LEFT) * 635)));
    3071          50 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyTextTop", OString::number(rBox.GetDistance(BOX_LINE_TOP) * 635)));
    3072          50 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dxTextRight", OString::number(rBox.GetDistance(BOX_LINE_RIGHT) * 635)));
    3073          50 :         m_aFlyProperties.push_back(std::make_pair<OString, OString>("dyTextBottom", OString::number(rBox.GetDistance(BOX_LINE_BOTTOM) * 635)));
    3074             : 
    3075          50 :         const SvxBorderLine* pLeft = rBox.GetLine(BOX_LINE_LEFT);
    3076          50 :         const SvxBorderLine* pRight = rBox.GetLine(BOX_LINE_RIGHT);
    3077          50 :         const SvxBorderLine* pTop = rBox.GetLine(BOX_LINE_TOP);
    3078          50 :         const SvxBorderLine* pBottom = rBox.GetLine(BOX_LINE_BOTTOM);
    3079          50 :         if (pLeft && pRight && pTop && pBottom && *pLeft == *pRight && *pLeft == *pTop && *pLeft == *pBottom)
    3080             :         {
    3081          34 :             const Color& rColor = pTop->GetColor();
    3082             :             // We in fact need RGB to BGR, but the transformation is symmetric.
    3083          34 :             m_aFlyProperties.push_back(std::make_pair<OString, OString>("lineColor", OString::number(msfilter::util::BGRToRGB(rColor.GetColor()))));
    3084             : 
    3085          34 :             if (pTop->GetBorderLineStyle() != table::BorderLineStyle::NONE)
    3086             :             {
    3087          30 :                 double const fConverted(editeng::ConvertBorderWidthToWord(pTop->GetBorderLineStyle(), pTop->GetWidth()));
    3088          30 :                 sal_Int32 nWidth = sal_Int32(fConverted * 635); // Twips -> EMUs
    3089          30 :                 m_aFlyProperties.push_back(std::make_pair<OString, OString>("lineWidth", OString::number(nWidth)));
    3090             :             }
    3091             :             else
    3092             :                 // No border: no line.
    3093           4 :                 m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0"));
    3094             :         }
    3095             : 
    3096         140 :         return;
    3097             :     }
    3098             : 
    3099         122 :     if (rBox.GetTop() && rBox.GetBottom() &&
    3100          60 :             rBox.GetLeft() && rBox.GetRight() &&
    3101          40 :             *rBox.GetTop() == *rBox.GetBottom() &&
    3102          40 :             *rBox.GetTop() == *rBox.GetLeft() &&
    3103          40 :             *rBox.GetTop() == *rBox.GetRight() &&
    3104          28 :             nDist == rBox.GetDistance(BOX_LINE_TOP) &&
    3105          10 :             nDist == rBox.GetDistance(BOX_LINE_LEFT) &&
    3106          44 :             nDist == rBox.GetDistance(BOX_LINE_BOTTOM) &&
    3107           2 :             nDist == rBox.GetDistance(BOX_LINE_RIGHT))
    3108           2 :         m_aSectionBreaks.append(OutBorderLine(m_rExport, rBox.GetTop(), OOO_STRING_SVTOOLS_RTF_BOX, nDist));
    3109             :     else
    3110             :     {
    3111          38 :         SvxShadowLocation eShadowLocation = SVX_SHADOW_NONE;
    3112          38 :         if (const SfxPoolItem* pItem = GetExport().HasItem(RES_SHADOW))
    3113          22 :             eShadowLocation = static_cast<const SvxShadowItem*>(pItem)->GetLocation();
    3114             : 
    3115          38 :         const sal_uInt16* pBrd = aBorders;
    3116          38 :         const sal_Char** pBrdNms = (const sal_Char**)aBorderNames;
    3117         190 :         for (int i = 0; i < 4; ++i, ++pBrd, ++pBrdNms)
    3118             :         {
    3119         152 :             if (const SvxBorderLine* pLn = rBox.GetLine(*pBrd))
    3120             :             {
    3121             :                 m_aSectionBreaks.append(OutBorderLine(m_rExport, pLn, *pBrdNms,
    3122          76 :                                                       rBox.GetDistance(*pBrd), eShadowLocation));
    3123             :             }
    3124             :         }
    3125             :     }
    3126             : 
    3127          40 :     if (!m_bBufferSectionBreaks)
    3128          32 :         m_aStyles.append(m_aSectionBreaks.makeStringAndClear());
    3129             : }
    3130             : 
    3131          14 : void RtfAttributeOutput::FormatColumns_Impl(sal_uInt16 nCols, const SwFmtCol& rCol, bool bEven, SwTwips nPageSize)
    3132             : {
    3133          14 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLS);
    3134          14 :     m_rExport.OutLong(nCols);
    3135             : 
    3136          14 :     if (bEven)
    3137             :     {
    3138          14 :         m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSX);
    3139          14 :         m_rExport.OutLong(rCol.GetGutterWidth(true));
    3140             :     }
    3141             :     else
    3142             :     {
    3143           0 :         const SwColumns& rColumns = rCol.GetColumns();
    3144           0 :         for (sal_uInt16 n = 0; n < nCols;)
    3145             :         {
    3146           0 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLNO);
    3147           0 :             m_rExport.OutLong(n+1);
    3148             : 
    3149           0 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLW);
    3150           0 :             m_rExport.OutLong(rCol.CalcPrtColWidth(n, nPageSize));
    3151             : 
    3152           0 :             if (++n != nCols)
    3153             :             {
    3154           0 :                 m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_COLSR);
    3155           0 :                 m_rExport.OutLong(rColumns[ n-1 ].GetRight() +
    3156           0 :                                   rColumns[ n ].GetLeft());
    3157             :             }
    3158             :         }
    3159             :     }
    3160          14 : }
    3161             : 
    3162         232 : void RtfAttributeOutput::FormatKeep(const SvxFmtKeepItem& rItem)
    3163             : {
    3164         232 :     if (rItem.GetValue())
    3165         224 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_KEEPN);
    3166         232 : }
    3167             : 
    3168         328 : void RtfAttributeOutput::FormatTextGrid(const SwTextGridItem& /*rGrid*/)
    3169             : {
    3170             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    3171         328 : }
    3172             : 
    3173         364 : void RtfAttributeOutput::FormatLineNumbering(const SwFmtLineNumber& rNumbering)
    3174             : {
    3175         364 :     if (!rNumbering.IsCount())
    3176         358 :         m_aStyles.append(OOO_STRING_SVTOOLS_RTF_NOLINE);
    3177         364 : }
    3178             : 
    3179         454 : void RtfAttributeOutput::FormatFrameDirection(const SvxFrameDirectionItem& rDirection)
    3180             : {
    3181         454 :     if (!m_rExport.bOutPageDescs)
    3182             :     {
    3183         124 :         if (rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP)
    3184           0 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_RTLPAR);
    3185             :         else
    3186         124 :             m_aStyles.append(OOO_STRING_SVTOOLS_RTF_LTRPAR);
    3187             :     }
    3188         454 : }
    3189             : 
    3190           0 : void RtfAttributeOutput::ParaGrabBag(const SfxGrabBagItem& /*rItem*/)
    3191             : {
    3192           0 : }
    3193             : 
    3194          36 : void RtfAttributeOutput::CharGrabBag(const SfxGrabBagItem& /*rItem*/)
    3195             : {
    3196          36 : }
    3197             : 
    3198          92 : void RtfAttributeOutput::ParaOutlineLevel(const SfxUInt16Item& /*rItem*/)
    3199             : {
    3200          92 : }
    3201             : 
    3202           0 : void RtfAttributeOutput::WriteExpand(const SwField* pFld)
    3203             : {
    3204           0 :     OUString sCmd;        // for optional Parameters
    3205           0 :     switch (pFld->GetTyp()->Which())
    3206             :     {
    3207             :     //#i119803# Export user field and DB field for RTF filter
    3208             :     case RES_DBFLD:
    3209           0 :         sCmd = FieldString(ww::eMERGEFIELD);
    3210             :     // no break !!
    3211             :     case RES_USERFLD:
    3212           0 :         sCmd += pFld->GetTyp()->GetName();
    3213           0 :         m_rExport.OutputField(pFld, ww::eNONE, sCmd);
    3214           0 :         break;
    3215             :     default:
    3216           0 :         m_rExport.OutputField(pFld, ww::eUNKNOWN, sCmd);
    3217           0 :         break;
    3218           0 :     }
    3219           0 : }
    3220             : 
    3221           0 : void RtfAttributeOutput::RefField(const SwField& /*rFld*/, const OUString& /*rRef*/)
    3222             : {
    3223             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    3224           0 : }
    3225             : 
    3226           0 : void RtfAttributeOutput::HiddenField(const SwField& /*rFld*/)
    3227             : {
    3228             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    3229           0 : }
    3230             : 
    3231           0 : void RtfAttributeOutput::SetField(const SwField& /*rFld*/, ww::eField /*eType*/, const OUString& /*rCmd*/)
    3232             : {
    3233             :     SAL_INFO("sw.rtf", "TODO: " << OSL_THIS_FUNC);
    3234           0 : }
    3235             : 
    3236          14 : void RtfAttributeOutput::PostitField(const SwField* pFld)
    3237             : {
    3238          14 :     const SwPostItField& rPFld = *(SwPostItField*)pFld;
    3239             : 
    3240          14 :     OString aName = OUStringToOString(rPFld.GetName(), RTL_TEXTENCODING_UTF8);
    3241          14 :     std::map<OString, sal_uInt16>::iterator it = m_rOpenedAnnotationMarksIds.find(aName);
    3242          14 :     if (it != m_rOpenedAnnotationMarksIds.end())
    3243             :     {
    3244             :         // In case this field is inside annotation marks, we want to write the
    3245             :         // annotation itself after the annotation mark is closed, not here.
    3246           6 :         m_aPostitFields[it->second] = &rPFld;
    3247          20 :         return;
    3248             :     }
    3249             : 
    3250           8 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " ");
    3251           8 :     m_aRunText->append(OUStringToOString(OUString(rPFld.GetInitials()), m_rExport.eCurrentEncoding));
    3252           8 :     m_aRunText->append("}");
    3253           8 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNAUTHOR " ");
    3254           8 :     m_aRunText->append(OUStringToOString(OUString(rPFld.GetPar1()), m_rExport.eCurrentEncoding));
    3255           8 :     m_aRunText->append("}");
    3256           8 :     m_aRunText->append(OOO_STRING_SVTOOLS_RTF_CHATN);
    3257             : 
    3258           8 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ANNOTATION);
    3259             : 
    3260           8 :     if (m_nCurrentAnnotationMarkId != -1)
    3261             :     {
    3262           6 :         m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNREF " ");
    3263           6 :         m_aRunText->append(m_nCurrentAnnotationMarkId);
    3264           6 :         m_aRunText->append('}');
    3265             :     }
    3266           8 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNDATE " ");
    3267           8 :     m_aRunText->append((sal_Int32)sw::ms::DateTime2DTTM(rPFld.GetDateTime()));
    3268           8 :     m_aRunText->append('}');
    3269           8 :     m_aRunText->append(OUStringToOString(OUString(rPFld.GetTxt()), m_rExport.eCurrentEncoding));
    3270           8 :     m_aRunText->append('}');
    3271             : }
    3272             : 
    3273           0 : bool RtfAttributeOutput::DropdownField(const SwField* /*pFld*/)
    3274             : {
    3275             :     // this is handled in OutputFlyFrame_Impl()
    3276           0 :     return true;
    3277             : }
    3278             : 
    3279           2 : bool RtfAttributeOutput::PlaceholderField(const SwField* pField)
    3280             : {
    3281           2 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FLDINST " MACROBUTTON  None ");
    3282           2 :     RunText(pField->GetPar1());
    3283           2 :     m_aRunText->append("}}");
    3284           2 :     return false; // do not expand
    3285             : }
    3286             : 
    3287         138 : RtfAttributeOutput::RtfAttributeOutput(RtfExport& rExport)
    3288             :     : m_rExport(rExport),
    3289             :       m_nStyleId(0),
    3290             :       m_nListId(0),
    3291             :       m_bStrikeDouble(false),
    3292             :       m_nNextAnnotationMarkId(0),
    3293             :       m_nCurrentAnnotationMarkId(-1),
    3294             :       m_pTableWrt(NULL),
    3295             :       m_bTableCellOpen(false),
    3296             :       m_nTableDepth(0),
    3297             :       m_bTblAfterCell(false),
    3298             :       m_nColBreakNeeded(false),
    3299             :       m_bBufferSectionBreaks(false),
    3300             :       m_bBufferSectionHeaders(false),
    3301             :       m_bLastTable(true),
    3302             :       m_bWroteCellInfo(false),
    3303             :       m_bTableRowEnded(false),
    3304             :       m_aCells(),
    3305             :       m_bSingleEmptyRun(false),
    3306             :       m_bInRun(false),
    3307             :       m_pFlyFrameSize(0),
    3308         138 :       m_pPrevPageDesc(0)
    3309             : {
    3310         138 : }
    3311             : 
    3312         276 : RtfAttributeOutput::~RtfAttributeOutput()
    3313             : {
    3314         276 : }
    3315             : 
    3316        4178 : MSWordExportBase& RtfAttributeOutput::GetExport()
    3317             : {
    3318        4178 :     return m_rExport;
    3319             : }
    3320             : 
    3321             : // These are used by wwFont::WriteRtf()
    3322             : 
    3323             : /// Start the font.
    3324        1014 : void RtfAttributeOutput::StartFont(const OUString& rFamilyName) const
    3325             : {
    3326             :     // write the font name hex-encoded, but without Unicode - Word at least
    3327             :     // cannot read *both* Unicode and fallback as written by OutString
    3328        1014 :     m_rExport.Strm().WriteCharPtr(
    3329        2028 :         msfilter::rtfutil::OutString(rFamilyName, m_rExport.eCurrentEncoding, false).getStr());
    3330        1014 : }
    3331             : 
    3332             : /// End the font.
    3333        1014 : void RtfAttributeOutput::EndFont() const
    3334             : {
    3335        1014 :     m_rExport.Strm().WriteCharPtr(";}");
    3336        1014 :     m_rExport.eCurrentEncoding = m_rExport.eDefaultEncoding;
    3337        1014 : }
    3338             : 
    3339             : /// Alternate name for the font.
    3340         270 : void RtfAttributeOutput::FontAlternateName(const OUString& rName) const
    3341             : {
    3342         270 :     m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_IGNORE).WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FALT).WriteChar(' ');
    3343             :     // write the font name hex-encoded, but without Unicode - Word at least
    3344             :     // cannot read *both* Unicode and fallback as written by OutString
    3345         270 :     m_rExport.Strm().WriteCharPtr(
    3346         540 :         msfilter::rtfutil::OutString(rName, m_rExport.eCurrentEncoding, false).getStr()).WriteChar('}');
    3347         270 : }
    3348             : 
    3349             : /// Font charset.
    3350        1014 : void RtfAttributeOutput::FontCharset(sal_uInt8 nCharSet) const
    3351             : {
    3352        1014 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FCHARSET);
    3353        1014 :     m_rExport.OutULong(nCharSet);
    3354        1014 :     m_rExport.Strm().WriteChar(' ');
    3355        1014 :     m_rExport.eCurrentEncoding =rtl_getTextEncodingFromWindowsCharset(nCharSet);
    3356        1014 : }
    3357             : 
    3358             : /// Font family.
    3359        1014 : void RtfAttributeOutput::FontFamilyType(FontFamily eFamily, const wwFont& rFont) const
    3360             : {
    3361        1014 :     m_rExport.Strm().WriteChar('{').WriteCharPtr(OOO_STRING_SVTOOLS_RTF_F);
    3362             : 
    3363        1014 :     const char* pStr = OOO_STRING_SVTOOLS_RTF_FNIL;
    3364        1014 :     switch (eFamily)
    3365             :     {
    3366             :     case FAMILY_ROMAN:
    3367         474 :         pStr = OOO_STRING_SVTOOLS_RTF_FROMAN;
    3368         474 :         break;
    3369             :     case FAMILY_SWISS:
    3370         312 :         pStr = OOO_STRING_SVTOOLS_RTF_FSWISS;
    3371         312 :         break;
    3372             :     case FAMILY_MODERN:
    3373           6 :         pStr = OOO_STRING_SVTOOLS_RTF_FMODERN;
    3374           6 :         break;
    3375             :     case FAMILY_SCRIPT:
    3376           0 :         pStr = OOO_STRING_SVTOOLS_RTF_FSCRIPT;
    3377           0 :         break;
    3378             :     case FAMILY_DECORATIVE:
    3379           0 :         pStr = OOO_STRING_SVTOOLS_RTF_FDECOR;
    3380           0 :         break;
    3381             :     default:
    3382         222 :         break;
    3383             :     }
    3384        1014 :     m_rExport.OutULong(m_rExport.maFontHelper.GetId(rFont)).WriteCharPtr(pStr);
    3385        1014 : }
    3386             : 
    3387             : /// Font pitch.
    3388        1014 : void RtfAttributeOutput::FontPitchType(FontPitch ePitch) const
    3389             : {
    3390        1014 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FPRQ);
    3391             : 
    3392        1014 :     sal_uInt16 nVal = 0;
    3393        1014 :     switch (ePitch)
    3394             :     {
    3395             :     case PITCH_FIXED:
    3396           4 :         nVal = 1;
    3397           4 :         break;
    3398             :     case PITCH_VARIABLE:
    3399         962 :         nVal = 2;
    3400         962 :         break;
    3401             :     default:
    3402          48 :         break;
    3403             :     }
    3404        1014 :     m_rExport.OutULong(nVal);
    3405        1014 : }
    3406             : 
    3407           0 : static bool IsEMF(const sal_uInt8* pGraphicAry, unsigned long nSize)
    3408             : {
    3409           0 :     if (pGraphicAry && (nSize > 0x2c))
    3410             :     {
    3411             :         // check the magic number
    3412           0 :         if ((pGraphicAry[0x28] == 0x20) && (pGraphicAry[0x29] == 0x45) && (pGraphicAry[0x2a] == 0x4d) && (pGraphicAry[0x2b] == 0x46))
    3413             :         {
    3414             :             //emf detected
    3415           0 :             return true;
    3416             :         }
    3417             :     }
    3418           0 :     return false;
    3419             : }
    3420             : 
    3421          70 : static bool StripMetafileHeader(const sal_uInt8*& rpGraphicAry, unsigned long& rSize)
    3422             : {
    3423          70 :     if (rpGraphicAry && (rSize > 0x22))
    3424             :     {
    3425          70 :         if ((rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) && (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a))
    3426             :         {
    3427             :             // we have to get rid of the metafileheader
    3428          70 :             rpGraphicAry += 22;
    3429          70 :             rSize -= 22;
    3430          70 :             return true;
    3431             :         }
    3432             :     }
    3433           0 :     return false;
    3434             : }
    3435             : 
    3436         150 : OString RtfAttributeOutput::WriteHex(const sal_uInt8* pData, sal_uInt32 nSize, SvStream* pStream, sal_uInt32 nLimit)
    3437             : {
    3438         150 :     OStringBuffer aRet;
    3439             : 
    3440         150 :     sal_uInt32 nBreak = 0;
    3441    10414254 :     for (sal_uInt32 i = 0; i < nSize; i++)
    3442             :     {
    3443    10414104 :         OString sNo = OString::number(pData[i], 16);
    3444    10414104 :         if (sNo.getLength() < 2)
    3445             :         {
    3446     2737279 :             if (pStream)
    3447     2277669 :                 pStream->WriteChar('0');
    3448             :             else
    3449      459610 :                 aRet.append('0');
    3450             :         }
    3451    10414104 :         if (pStream)
    3452     9789462 :             pStream->WriteCharPtr(sNo.getStr());
    3453             :         else
    3454      624642 :             aRet.append(sNo);
    3455    10414104 :         if (++nBreak == nLimit)
    3456             :         {
    3457      162648 :             if (pStream)
    3458      152950 :                 pStream->WriteCharPtr(SAL_NEWLINE_STRING);
    3459             :             else
    3460        9698 :                 aRet.append(SAL_NEWLINE_STRING);
    3461      162648 :             nBreak = 0;
    3462             :         }
    3463    10414104 :     }
    3464             : 
    3465         150 :     return aRet.makeStringAndClear();
    3466             : }
    3467             : 
    3468         264 : static void lcl_AppendSP(OStringBuffer& rBuffer,
    3469             :                          const char cName[],
    3470             :                          const OUString& rValue,
    3471             :                          const RtfExport& rExport)
    3472             : {
    3473         264 :     rBuffer.append("{" OOO_STRING_SVTOOLS_RTF_SP "{");   // "{\sp{"
    3474         264 :     rBuffer.append(OOO_STRING_SVTOOLS_RTF_SN " ");  //" \sn "
    3475         264 :     rBuffer.append(cName);   //"PropName"
    3476         264 :     rBuffer.append("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
    3477             : // "}{ \sv "
    3478         264 :     rBuffer.append(msfilter::rtfutil::OutString(rValue, rExport.eCurrentEncoding));
    3479         264 :     rBuffer.append("}}");
    3480         264 : }
    3481             : 
    3482         140 : static OString ExportPICT(const SwFlyFrmFmt* pFlyFrmFmt, const Size& rOrig, const Size& rRendered, const Size& rMapped,
    3483             :                           const SwCropGrf& rCr, const char* pBLIPType, const sal_uInt8* pGraphicAry,
    3484             :                           unsigned long nSize, const RtfExport& rExport, SvStream* pStream = 0, bool bWritePicProp = true)
    3485             : {
    3486         140 :     OStringBuffer aRet;
    3487         140 :     if (pBLIPType && nSize && pGraphicAry)
    3488             :     {
    3489         140 :         bool bIsWMF = std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
    3490             : 
    3491         140 :         aRet.append("{" OOO_STRING_SVTOOLS_RTF_PICT);
    3492             : 
    3493         140 :         if (pFlyFrmFmt && bWritePicProp)
    3494             :         {
    3495         132 :             OUString sDescription = pFlyFrmFmt->GetObjDescription();
    3496             :             //write picture properties - wzDescription at first
    3497             :             //looks like: "{\*\picprop{\sp{\sn PropertyName}{\sv PropertyValue}}}"
    3498         132 :             aRet.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_PICPROP);  //"{\*\picprop
    3499         132 :             lcl_AppendSP(aRet, "wzDescription", sDescription, rExport);
    3500         264 :             OUString sName = pFlyFrmFmt->GetObjTitle();
    3501         132 :             lcl_AppendSP(aRet, "wzName", sName, rExport);
    3502         264 :             aRet.append("}");   //"}"
    3503             :         }
    3504             : 
    3505         140 :         long nXCroppedSize = rOrig.Width()-(rCr.GetLeft() + rCr.GetRight());
    3506         140 :         long nYCroppedSize = rOrig.Height()-(rCr.GetTop() + rCr.GetBottom());
    3507             :         /* Graphic with a zero height or width, typically copied from webpages, caused crashes. */
    3508         140 :         if (!nXCroppedSize)
    3509           2 :             nXCroppedSize = 100;
    3510         140 :         if (!nYCroppedSize)
    3511           2 :             nYCroppedSize = 100;
    3512             : 
    3513             :         //Given the original size and taking cropping into account
    3514             :         //first, how much has the original been scaled to get the
    3515             :         //final rendered size
    3516         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEX);
    3517         140 :         aRet.append((sal_Int32)((100 * rRendered.Width()) / nXCroppedSize));
    3518         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICSCALEY);
    3519         140 :         aRet.append((sal_Int32)((100 * rRendered.Height()) / nYCroppedSize));
    3520             : 
    3521         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPL);
    3522         140 :         aRet.append((sal_Int32)rCr.GetLeft());
    3523         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPR);
    3524         140 :         aRet.append((sal_Int32)rCr.GetRight());
    3525         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPT);
    3526         140 :         aRet.append((sal_Int32)rCr.GetTop());
    3527         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICCROPB);
    3528         140 :         aRet.append((sal_Int32)rCr.GetBottom());
    3529             : 
    3530         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICW);
    3531         140 :         aRet.append((sal_Int32)rMapped.Width());
    3532         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICH);
    3533         140 :         aRet.append((sal_Int32)rMapped.Height());
    3534             : 
    3535         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
    3536         140 :         aRet.append((sal_Int32)rOrig.Width());
    3537         140 :         aRet.append(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
    3538         140 :         aRet.append((sal_Int32)rOrig.Height());
    3539             : 
    3540         140 :         aRet.append(pBLIPType);
    3541         140 :         if (bIsWMF)
    3542             :         {
    3543          70 :             aRet.append((sal_Int32)8);
    3544          70 :             StripMetafileHeader(pGraphicAry, nSize);
    3545             :         }
    3546         140 :         aRet.append(SAL_NEWLINE_STRING);
    3547         140 :         if (pStream)
    3548          20 :             pStream->WriteCharPtr(aRet.makeStringAndClear().getStr());
    3549         140 :         if (pStream)
    3550          20 :             RtfAttributeOutput::WriteHex(pGraphicAry, nSize, pStream);
    3551             :         else
    3552         120 :             aRet.append(RtfAttributeOutput::WriteHex(pGraphicAry, nSize));
    3553         140 :         aRet.append('}');
    3554         140 :         if (pStream)
    3555          20 :             pStream->WriteCharPtr(aRet.makeStringAndClear().getStr());
    3556             :     }
    3557         140 :     return aRet.makeStringAndClear();
    3558             : }
    3559             : 
    3560          60 : void RtfAttributeOutput::FlyFrameOLEReplacement(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
    3561             : {
    3562          60 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
    3563          60 :     Size aSize(sw::util::GetSwappedInSize(rOLENode));
    3564          60 :     Size aRendered(aSize);
    3565          60 :     aRendered.Width() = rSize.Width();
    3566          60 :     aRendered.Height() = rSize.Height();
    3567          60 :     const Graphic* pGraphic = rOLENode.GetGraphic();
    3568          60 :     Size aMapped(pGraphic->GetPrefSize());
    3569          60 :     const SwCropGrf& rCr = (const SwCropGrf&)rOLENode.GetAttr(RES_GRFATR_CROPGRF);
    3570          60 :     const sal_Char* pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
    3571          60 :     const sal_uInt8* pGraphicAry = 0;
    3572          60 :     SvMemoryStream aStream;
    3573          60 :     if (GraphicConverter::Export(aStream, *pGraphic, CVT_PNG) != ERRCODE_NONE)
    3574             :         OSL_FAIL("failed to export the graphic");
    3575          60 :     aStream.Seek(STREAM_SEEK_TO_END);
    3576          60 :     sal_uInt32 nSize = aStream.Tell();
    3577          60 :     pGraphicAry = (sal_uInt8*)aStream.GetData();
    3578          60 :     m_aRunText->append(ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport));
    3579          60 :     m_aRunText->append("}"); // shppict
    3580          60 :     m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT);
    3581          60 :     pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
    3582         120 :     SvMemoryStream aWmfStream;
    3583          60 :     if (GraphicConverter::Export(aWmfStream, *pGraphic, CVT_WMF) != ERRCODE_NONE)
    3584             :         OSL_FAIL("failed to export the graphic");
    3585          60 :     aWmfStream.Seek(STREAM_SEEK_TO_END);
    3586          60 :     nSize = aWmfStream.Tell();
    3587          60 :     pGraphicAry = (sal_uInt8*)aWmfStream.GetData();
    3588          60 :     m_aRunText->append(ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport));
    3589         120 :     m_aRunText->append("}"); // nonshppict
    3590          60 : }
    3591             : 
    3592          60 : bool RtfAttributeOutput::FlyFrameOLEMath(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
    3593             : {
    3594          60 :     uno::Reference <embed::XEmbeddedObject> xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
    3595          60 :     sal_Int64 nAspect = rOLENode.GetAspect();
    3596         120 :     svt::EmbeddedObjectRef aObjRef(xObj, nAspect);
    3597         120 :     SvGlobalName aObjName(aObjRef->getClassID());
    3598             : 
    3599          60 :     if (!SotExchange::IsMath(aObjName))
    3600           0 :         return false;
    3601             : 
    3602          60 :     m_aRunText->append("{" LO_STRING_SVTOOLS_RTF_MMATH " ");
    3603         120 :     uno::Reference<util::XCloseable> xClosable(xObj->getComponent(), uno::UNO_QUERY);
    3604          60 :     if (!xClosable.is())
    3605           0 :         return false;
    3606             : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
    3607             : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
    3608             : // to RTLD_GLOBAL, so most probably a gcc bug.
    3609          60 :     oox::FormulaExportBase* pBase = dynamic_cast<oox::FormulaExportBase*>(dynamic_cast<SfxBaseModel*>(xClosable.get()));
    3610             :     assert(pBase != NULL);
    3611         120 :     OStringBuffer aBuf;
    3612          60 :     if (pBase)
    3613          60 :         pBase->writeFormulaRtf(aBuf, m_rExport.eCurrentEncoding);
    3614          60 :     m_aRunText->append(aBuf.makeStringAndClear());
    3615             :     // Replacement graphic.
    3616          60 :     m_aRunText->append("{" LO_STRING_SVTOOLS_RTF_MMATHPICT " ");
    3617          60 :     FlyFrameOLEReplacement(pFlyFrmFmt, rOLENode, rSize);
    3618          60 :     m_aRunText->append("}"); // mmathPict
    3619          60 :     m_aRunText->append("}"); // mmath
    3620             : 
    3621         120 :     return true;
    3622             : }
    3623             : 
    3624          60 : void RtfAttributeOutput::FlyFrameOLE(const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize)
    3625             : {
    3626          60 :     if (FlyFrameOLEMath(pFlyFrmFmt, rOLENode, rSize))
    3627         120 :         return;
    3628             : 
    3629           0 :     FlyFrameOLEReplacement(pFlyFrmFmt, rOLENode, rSize);
    3630             : }
    3631             : 
    3632          14 : void RtfAttributeOutput::FlyFrameGraphic(const SwFlyFrmFmt* pFlyFrmFmt, const SwGrfNode* pGrfNode)
    3633             : {
    3634          14 :     SvMemoryStream aStream;
    3635          14 :     const sal_uInt8* pGraphicAry = 0;
    3636          14 :     sal_uInt32 nSize = 0;
    3637             : 
    3638          14 :     const Graphic& rGraphic(pGrfNode->GetGrf());
    3639             : 
    3640             :     // If there is no graphic there is not much point in parsing it
    3641          14 :     if (rGraphic.GetType()==GRAPHIC_NONE)
    3642          14 :         return;
    3643             : 
    3644          14 :     bool bSwapped = rGraphic.IsSwapOut();
    3645          14 :     if (bSwapped)
    3646             :     {
    3647             :         // always swapin via the Node
    3648           0 :         const_cast<SwGrfNode*>(pGrfNode)->SwapIn();
    3649             :     }
    3650             : 
    3651          28 :     GfxLink aGraphicLink;
    3652          14 :     const sal_Char* pBLIPType = 0;
    3653          14 :     if (rGraphic.IsLink())
    3654             :     {
    3655          12 :         aGraphicLink = rGraphic.GetLink();
    3656          12 :         nSize = aGraphicLink.GetDataSize();
    3657          12 :         pGraphicAry = aGraphicLink.GetData();
    3658          12 :         switch (aGraphicLink.GetType())
    3659             :         {
    3660             :         // #i15508# trying to add BMP type for better exports, need to check if this works
    3661             :         // checked, does not work. Also need to reset pGraphicAry to NULL to force conversion
    3662             :         // to PNG, else the BMP array will be used.
    3663             :         // It may work using direct DIB data, but that needs to be checked eventually
    3664             :         //
    3665             :         // #i15508# before GFX_LINK_TYPE_NATIVE_BMP was added the graphic data
    3666             :         // (to be hold in pGraphicAry) was not available; thus for now to stay
    3667             :         // compatible, keep it that way by assigning NULL value to pGraphicAry
    3668             :         case GFX_LINK_TYPE_NATIVE_BMP:
    3669             :             //    pBLIPType = OOO_STRING_SVTOOLS_RTF_WBITMAP;
    3670           0 :             pGraphicAry = 0;
    3671           0 :             break;
    3672             : 
    3673             :         case GFX_LINK_TYPE_NATIVE_JPG:
    3674           0 :             pBLIPType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
    3675           0 :             break;
    3676             :         case GFX_LINK_TYPE_NATIVE_PNG:
    3677          10 :             pBLIPType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
    3678          10 :             break;
    3679             :         case GFX_LINK_TYPE_NATIVE_WMF:
    3680             :             pBLIPType =
    3681           0 :                 IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
    3682           0 :             break;
    3683             :         default:
    3684           2 :             break;
    3685             :         }
    3686             :     }
    3687             : 
    3688          14 :     GraphicType eGraphicType = rGraphic.GetType();
    3689          14 :     if (!pGraphicAry)
    3690             :     {
    3691           2 :         if (ERRCODE_NONE == GraphicConverter::Export(aStream, rGraphic,
    3692           2 :                 (eGraphicType == GRAPHIC_BITMAP) ? CVT_PNG : CVT_WMF))
    3693             :         {
    3694             :             pBLIPType = (eGraphicType == GRAPHIC_BITMAP) ?
    3695           2 :                         OOO_STRING_SVTOOLS_RTF_PNGBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
    3696           2 :             aStream.Seek(STREAM_SEEK_TO_END);
    3697           2 :             nSize = aStream.Tell();
    3698           2 :             pGraphicAry = (sal_uInt8*)aStream.GetData();
    3699             :         }
    3700             :     }
    3701             : 
    3702          14 :     Size aMapped(eGraphicType == GRAPHIC_BITMAP ? rGraphic.GetSizePixel() : rGraphic.GetPrefSize());
    3703             : 
    3704          14 :     const SwCropGrf& rCr = (const SwCropGrf&)pGrfNode->GetAttr(RES_GRFATR_CROPGRF);
    3705             : 
    3706             :     //Get original size in twips
    3707          14 :     Size aSize(sw::util::GetSwappedInSize(*pGrfNode));
    3708          14 :     Size aRendered(aSize);
    3709             : 
    3710          14 :     const SwFmtFrmSize& rS = pFlyFrmFmt->GetFrmSize();
    3711          14 :     aRendered.Width() = rS.GetWidth();
    3712          14 :     aRendered.Height() = rS.GetHeight();
    3713             : 
    3714          14 :     sw::Frame* pFrame = 0;
    3715          18 :     for (sw::FrameIter it = m_rExport.maFrames.begin(); it != m_rExport.maFrames.end(); ++it)
    3716             :     {
    3717          12 :         if (pFlyFrmFmt == &it->GetFrmFmt())
    3718             :         {
    3719           8 :             pFrame = &(*it);
    3720           8 :             break;
    3721             :         }
    3722             :     }
    3723             : 
    3724             :     /*
    3725             :        If the graphic is not of type WMF then we will have to store two
    3726             :        graphics, one in the native format wrapped in shppict, and the other in
    3727             :        the wmf format wrapped in nonshppict, so as to keep wordpad happy. If its
    3728             :        a wmf already then we don't need any such wrapping
    3729             :        */
    3730          14 :     bool bIsWMF = pBLIPType && std::strcmp(pBLIPType, OOO_STRING_SVTOOLS_RTF_WMETAFILE) == 0;
    3731          14 :     if (!pFrame || pFrame->IsInline())
    3732             :     {
    3733           6 :         if (!bIsWMF)
    3734           6 :             m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
    3735             :     }
    3736             :     else
    3737             :     {
    3738           8 :         m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SHP "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPINST);
    3739           8 :         m_pFlyFrameSize = &aRendered;
    3740           8 :         m_rExport.mpParentFrame = pFrame;
    3741           8 :         m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = true;
    3742           8 :         m_rExport.OutputFormat(pFrame->GetFrmFmt(), false, false, true);
    3743           8 :         m_rExport.bOutFlyFrmAttrs = m_rExport.bRTFFlySyntax = false;
    3744           8 :         m_rExport.mpParentFrame = NULL;
    3745           8 :         m_pFlyFrameSize = 0;
    3746             : 
    3747           8 :         std::vector< std::pair<OString, OString> > aFlyProperties;
    3748           8 :         aFlyProperties.push_back(std::make_pair<OString, OString>("shapeType", OString::number(ESCHER_ShpInst_PictureFrame)));
    3749           8 :         aFlyProperties.push_back(std::make_pair<OString, OString>("wzDescription", msfilter::rtfutil::OutString(pFlyFrmFmt->GetObjDescription(), m_rExport.eCurrentEncoding)));
    3750           8 :         aFlyProperties.push_back(std::make_pair<OString, OString>("wzName", msfilter::rtfutil::OutString(pFlyFrmFmt->GetObjTitle(), m_rExport.eCurrentEncoding)));
    3751             : 
    3752             :         // If we have a wrap polygon, then handle that here.
    3753           8 :         if (pFlyFrmFmt->GetSurround().IsContour())
    3754             :         {
    3755           2 :             if (const SwNoTxtNode* pNd = sw::util::GetNoTxtNodeFromSwFrmFmt(*pFlyFrmFmt))
    3756             :             {
    3757           2 :                 const tools::PolyPolygon* pPolyPoly = pNd->HasContour();
    3758           2 :                 if (pPolyPoly && pPolyPoly->Count())
    3759             :                 {
    3760           2 :                     Polygon aPoly = sw::util::CorrectWordWrapPolygonForExport(*pPolyPoly, pNd);
    3761           4 :                     OStringBuffer aVerticies;
    3762          24 :                     for (sal_uInt16 i = 0; i < aPoly.GetSize(); ++i)
    3763          22 :                         aVerticies.append(";(").append(aPoly[i].X()).append(",").append(aPoly[i].Y()).append(")");
    3764           4 :                     aFlyProperties.push_back(std::make_pair<OString, OString>("pWrapPolygonVertices", "8;" + OString::number(aPoly.GetSize()) + aVerticies.makeStringAndClear()));
    3765             :                 }
    3766             :             }
    3767             :         }
    3768             : 
    3769             :         // Below text, behind document, opaque: they all refer to the same thing.
    3770           8 :         if (!pFlyFrmFmt->GetOpaque().GetValue())
    3771           2 :             aFlyProperties.push_back(std::make_pair<OString, OString>("fBehindDocument", "1"));
    3772             : 
    3773          36 :         for (size_t i = 0; i < aFlyProperties.size(); ++i)
    3774             :         {
    3775          28 :             m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{");
    3776          28 :             m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_SN " ");
    3777          28 :             m_rExport.Strm().WriteCharPtr(aFlyProperties[i].first.getStr());
    3778          28 :             m_rExport.Strm().WriteCharPtr("}{" OOO_STRING_SVTOOLS_RTF_SV " ");
    3779          28 :             m_rExport.Strm().WriteCharPtr(aFlyProperties[i].second.getStr());
    3780          28 :             m_rExport.Strm().WriteCharPtr("}}");
    3781             :         }
    3782           8 :         m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_SP "{" OOO_STRING_SVTOOLS_RTF_SN " pib" "}{" OOO_STRING_SVTOOLS_RTF_SV " ");
    3783             :     }
    3784             : 
    3785          14 :     bool bWritePicProp = !pFrame || pFrame->IsInline();
    3786          14 :     if (pBLIPType)
    3787          12 :         ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm(), bWritePicProp);
    3788             :     else
    3789             :     {
    3790           2 :         aStream.Seek(0);
    3791           2 :         GraphicConverter::Export(aStream, rGraphic, CVT_WMF);
    3792           2 :         pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
    3793           2 :         aStream.Seek(STREAM_SEEK_TO_END);
    3794           2 :         nSize = aStream.Tell();
    3795           2 :         pGraphicAry = (sal_uInt8*)aStream.GetData();
    3796             : 
    3797           2 :         ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm(), bWritePicProp);
    3798             :     }
    3799             : 
    3800          14 :     if (!pFrame || pFrame->IsInline())
    3801             :     {
    3802           6 :         if (!bIsWMF)
    3803             :         {
    3804           6 :             m_rExport.Strm().WriteCharPtr("}" "{" OOO_STRING_SVTOOLS_RTF_NONSHPPICT);
    3805             : 
    3806           6 :             aStream.Seek(0);
    3807           6 :             GraphicConverter::Export(aStream, rGraphic, CVT_WMF);
    3808           6 :             pBLIPType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
    3809           6 :             aStream.Seek(STREAM_SEEK_TO_END);
    3810           6 :             nSize = aStream.Tell();
    3811           6 :             pGraphicAry = (sal_uInt8*)aStream.GetData();
    3812             : 
    3813           6 :             ExportPICT(pFlyFrmFmt, aSize, aRendered, aMapped, rCr, pBLIPType, pGraphicAry, nSize, m_rExport, &m_rExport.Strm());
    3814             : 
    3815           6 :             m_rExport.Strm().WriteChar('}');
    3816             :         }
    3817             :     }
    3818             :     else
    3819           8 :         m_rExport.Strm().WriteCharPtr("}}}}"); // Close SV, SP, SHPINST and SHP.
    3820             : 
    3821          14 :     if (bSwapped)
    3822           0 :         const_cast<Graphic&>(rGraphic).SwapOut();
    3823             : 
    3824          28 :     m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
    3825             : }
    3826             : 
    3827           2 : void RtfAttributeOutput::BulletDefinition(int /*nId*/, const Graphic& rGraphic, Size aSize)
    3828             : {
    3829           2 :     m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_SHPPICT);
    3830           2 :     m_rExport.Strm().WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT OOO_STRING_SVTOOLS_RTF_PNGBLIP);
    3831             : 
    3832           2 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
    3833           2 :     m_rExport.OutULong(aSize.Width());
    3834           2 :     m_rExport.Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
    3835           2 :     m_rExport.OutULong(aSize.Height());
    3836             : 
    3837           2 :     m_rExport.Strm().WriteCharPtr(SAL_NEWLINE_STRING);
    3838           2 :     const sal_uInt8* pGraphicAry = 0;
    3839           2 :     SvMemoryStream aStream;
    3840           2 :     if (GraphicConverter::Export(aStream, rGraphic, CVT_PNG) != ERRCODE_NONE)
    3841             :         SAL_WARN("sw.rtf", "failed to export the numbering picture bullet");
    3842           2 :     aStream.Seek(STREAM_SEEK_TO_END);
    3843           2 :     sal_uInt32 nSize = aStream.Tell();
    3844           2 :     pGraphicAry = (sal_uInt8*)aStream.GetData();
    3845           2 :     RtfAttributeOutput::WriteHex(pGraphicAry, nSize, &m_rExport.Strm());
    3846           2 :     m_rExport.Strm().WriteCharPtr("}}");   // pict, shppict
    3847         104 : }
    3848             : 
    3849             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10