LCOV - code coverage report
Current view: top level - libreoffice/writerfilter/source/rtftok - rtfdocumentimpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2146 2624 81.8 %
Date: 2012-12-27 Functions: 75 79 94.9 %
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             :  * Version: MPL 1.1 / GPLv3+ / LGPLv3+
       4             :  *
       5             :  * The contents of this file are subject to the Mozilla Public License Version
       6             :  * 1.1 (the "License"); you may not use this file except in compliance with
       7             :  * the License. You may obtain a copy of the License at
       8             :  * http://www.mozilla.org/MPL/
       9             :  *
      10             :  * Software distributed under the License is distributed on an "AS IS" basis,
      11             :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12             :  * for the specific language governing rights and limitations under the
      13             :  * License.
      14             :  *
      15             :  * The Initial Developer of the Original Code is
      16             :  *       Miklos Vajna <vmiklos@frugalware.org>
      17             :  * Portions created by the Initial Developer are Copyright (C) 2011 the
      18             :  * Initial Developer. All Rights Reserved.
      19             :  *
      20             :  * Contributor(s):
      21             :  *
      22             :  * Alternatively, the contents of this file may be used under the terms of
      23             :  * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
      24             :  * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
      25             :  * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
      26             :  * instead of those above.
      27             :  */
      28             : 
      29             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      30             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      31             : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
      32             : #include <com/sun/star/graphic/GraphicProvider.hpp>
      33             : #include <com/sun/star/io/UnexpectedEOFException.hpp>
      34             : #include <com/sun/star/lang/XServiceInfo.hpp>
      35             : #include <com/sun/star/text/XTextFrame.hpp>
      36             : #include <com/sun/star/text/SizeType.hpp>
      37             : #include <com/sun/star/text/HoriOrientation.hpp>
      38             : #include <com/sun/star/text/VertOrientation.hpp>
      39             : #include <com/sun/star/text/RelOrientation.hpp>
      40             : #include <com/sun/star/text/WrapTextMode.hpp>
      41             : #include <rtl/tencinfo.h>
      42             : #include <svtools/wmf.hxx>
      43             : #include <svl/lngmisc.hxx>
      44             : #include <unotools/ucbstreamhelper.hxx>
      45             : #include <unotools/streamwrap.hxx>
      46             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      47             : #include <rtl/ustring.hxx>
      48             : #include <vcl/graph.hxx>
      49             : #include <svtools/grfmgr.hxx>
      50             : #include <vcl/svapp.hxx>
      51             : #include <filter/msfilter/util.hxx>
      52             : #include <filter/msfilter/escherex.hxx>
      53             : #include <comphelper/string.hxx>
      54             : #include <tools/globname.hxx>
      55             : #include <comphelper/classids.hxx>
      56             : #include <comphelper/embeddedobjectcontainer.hxx>
      57             : #include <sfx2/sfxbasemodel.hxx>
      58             : 
      59             : #include <oox/mathml/import.hxx>
      60             : #include <doctok/sprmids.hxx> // NS_sprm namespace
      61             : #include <doctok/resourceids.hxx> // NS_rtf namespace
      62             : #include <ooxml/resourceids.hxx> // NS_ooxml namespace
      63             : #include <ooxml/OOXMLFastTokens.hxx> // ooxml namespace
      64             : #include <oox/token/namespaces.hxx> // oox namespace
      65             : #include <oox/token/tokens.hxx>
      66             : 
      67             : #include <rtfsdrimport.hxx>
      68             : #include <rtftokenizer.hxx>
      69             : #include <rtfcharsets.hxx>
      70             : #include <rtfreferenceproperties.hxx>
      71             : #include <rtfskipdestination.hxx>
      72             : #include <rtffly.hxx>
      73             : 
      74             : #define TWIP_TO_MM100(TWIP)     ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
      75             : #define M_TOKEN(token) OOX_TOKEN(officeMath, token)
      76             : #define OPEN_M_TOKEN( rtftok, ooxtok ) \
      77             :         case RTF_M##rtftok: \
      78             :             m_aMathBuffer.appendOpeningTag(M_TOKEN(ooxtok)); \
      79             :             m_aStates.top().nDestinationState = DESTINATION_M##rtftok; \
      80             :             break
      81             : 
      82             : using std::make_pair;
      83             : using rtl::OString;
      84             : using rtl::OStringBuffer;
      85             : using rtl::OUString;
      86             : using rtl::OUStringBuffer;
      87             : using rtl::OUStringToOString;
      88             : 
      89             : namespace writerfilter {
      90             : namespace rtftok {
      91             : 
      92          69 : static Id lcl_getParagraphBorder(sal_uInt32 nIndex)
      93             : {
      94             :     static const Id aBorderIds[] =
      95             :     {
      96             :         NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight
      97             :     };
      98             : 
      99          69 :     return aBorderIds[nIndex];
     100             : }
     101             : 
     102        2051 : static void lcl_putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue,
     103             :         bool bOverwrite = true, bool bAttribute = true)
     104             : {
     105        2051 :     RTFValue::Pointer_t pParent = rSprms.find(nParent);
     106        2051 :     if (!pParent.get())
     107             :     {
     108         683 :         RTFSprms aAttributes;
     109         683 :         if (nParent == NS_ooxml::LN_CT_TcPrBase_shd)
     110             :         {
     111             :             // RTF default is 'auto', see writerfilter::dmapper::CellColorHandler
     112           1 :             aAttributes.set(NS_ooxml::LN_CT_Shd_color, RTFValue::Pointer_t(new RTFValue(0x0a)));
     113           1 :             aAttributes.set(NS_ooxml::LN_CT_Shd_fill, RTFValue::Pointer_t(new RTFValue(0x0a)));
     114             :         }
     115         683 :         RTFValue::Pointer_t pParentValue(new RTFValue(aAttributes));
     116         683 :         rSprms.set(nParent, pParentValue, bOverwrite);
     117         683 :         pParent = pParentValue;
     118             :     }
     119        2051 :     RTFSprms& rAttributes = (bAttribute ? pParent->getAttributes() : pParent->getSprms());
     120        2051 :     rAttributes.set(nId, pValue, bOverwrite);
     121        2051 : }
     122             : 
     123         804 : static void lcl_putNestedSprm(RTFSprms& rSprms, Id nParent, Id nId, RTFValue::Pointer_t pValue, bool bOverwrite = false)
     124             : {
     125         804 :     lcl_putNestedAttribute(rSprms, nParent, nId, pValue, bOverwrite, false);
     126         804 : }
     127             : 
     128          64 : static bool lcl_eraseNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId)
     129             : {
     130          64 :     RTFValue::Pointer_t pParent = rSprms.find(nParent);
     131          64 :     if (!pParent.get())
     132             :         // It doesn't even have a parent, we're done!
     133          64 :         return false;
     134           0 :     RTFSprms& rAttributes = pParent->getAttributes();
     135           0 :     return rAttributes.erase(nId);
     136             : }
     137             : 
     138         349 : static RTFSprms& lcl_getLastAttributes(RTFSprms& rSprms, Id nId)
     139             : {
     140         349 :     RTFValue::Pointer_t p = rSprms.find(nId);
     141         349 :     if (p.get() && p->getSprms().size())
     142         295 :         return p->getSprms().back().second->getAttributes();
     143             :     else
     144             :     {
     145             :         SAL_WARN("writerfilter", "trying to set property when no type is defined");
     146          54 :         return rSprms;
     147         349 :     }
     148             : }
     149             : 
     150         380 : static void lcl_putBorderProperty(std::stack<RTFParserState>& aStates, Id nId, RTFValue::Pointer_t pValue)
     151             : {
     152         380 :     RTFSprms* pAttributes = 0;
     153         380 :     if (aStates.top().nBorderState == BORDER_PARAGRAPH_BOX)
     154          65 :         for (int i = 0; i < 4; i++)
     155             :         {
     156          52 :             RTFValue::Pointer_t p = aStates.top().aParagraphSprms.find(lcl_getParagraphBorder(i));
     157          52 :             if (p.get())
     158             :             {
     159          52 :                 RTFSprms& rAttributes = p->getAttributes();
     160          52 :                 rAttributes.set(nId, pValue);
     161             :             }
     162          52 :         }
     163             :     // Attributes of the last border type
     164         367 :     else if (aStates.top().nBorderState == BORDER_PARAGRAPH)
     165           3 :         pAttributes = &lcl_getLastAttributes(aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr);
     166         364 :     else if (aStates.top().nBorderState == BORDER_CELL)
     167         346 :         pAttributes = &lcl_getLastAttributes(aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders);
     168          18 :     else if (aStates.top().nBorderState == BORDER_PAGE)
     169           0 :         pAttributes = &lcl_getLastAttributes(aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders);
     170         380 :     if (pAttributes)
     171         349 :         pAttributes->set(nId, pValue);
     172         380 : }
     173             : 
     174           2 : static OString lcl_DTTM22OString(long lDTTM)
     175             : {
     176           2 :     return msfilter::util::DateTimeToOString(msfilter::util::DTTM2DateTime(lDTTM));
     177             : }
     178             : 
     179           0 : static writerfilter::Reference<Properties>::Pointer_t lcl_getBookmarkProperties(int nPos, OUString& rString)
     180             : {
     181           0 :     RTFSprms aAttributes;
     182           0 :     RTFValue::Pointer_t pPos(new RTFValue(nPos));
     183           0 :     if (!rString.isEmpty())
     184             :     {
     185             :         // If present, this should be sent first.
     186           0 :         RTFValue::Pointer_t pString(new RTFValue(rString));
     187           0 :         aAttributes.set(NS_rtf::LN_BOOKMARKNAME, pString);
     188             :     }
     189           0 :     aAttributes.set(NS_rtf::LN_IBKL, pPos);
     190           0 :     return writerfilter::Reference<Properties>::Pointer_t(new RTFReferenceProperties(aAttributes));
     191             : }
     192             : 
     193           0 : static writerfilter::Reference<Properties>::Pointer_t lcl_getBookmarkProperties(int nPos)
     194             : {
     195           0 :     OUString aStr;
     196           0 :     return lcl_getBookmarkProperties(nPos, aStr);
     197             : }
     198             : 
     199           0 : static const char* lcl_RtfToString(RTFKeyword nKeyword)
     200             : {
     201           0 :     for (int i = 0; i < nRTFControlWords; i++)
     202             :     {
     203           0 :         if (nKeyword == aRTFControlWords[i].nIndex)
     204           0 :             return aRTFControlWords[i].sKeyword;
     205             :     }
     206           0 :     return NULL;
     207             : }
     208             : 
     209          89 : static util::DateTime lcl_getDateTime(std::stack<RTFParserState>& aStates)
     210             : {
     211         178 :     return util::DateTime(0 /*100sec*/, 0 /*sec*/, aStates.top().nMinute, aStates.top().nHour,
     212         267 :             aStates.top().nDay, aStates.top().nMonth, aStates.top().nYear);
     213             : }
     214             : 
     215        1264 : static void lcl_DestinationToMath(OUStringBuffer& rDestinationText, oox::formulaimport::XmlStreamBuilder& rMathBuffer)
     216             : {
     217        1264 :     OUString aStr = rDestinationText.makeStringAndClear();
     218        1264 :     if (!aStr.isEmpty())
     219             :     {
     220         493 :         rMathBuffer.appendOpeningTag(M_TOKEN(r));
     221         493 :         rMathBuffer.appendOpeningTag(M_TOKEN(t));
     222         493 :         rMathBuffer.appendCharacters(aStr);
     223         493 :         rMathBuffer.appendClosingTag(M_TOKEN(t));
     224         493 :         rMathBuffer.appendClosingTag(M_TOKEN(r));
     225        1264 :     }
     226        1264 : }
     227             : 
     228         138 : RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& xContext,
     229             :         uno::Reference<io::XInputStream> const& xInputStream,
     230             :         uno::Reference<lang::XComponent> const& xDstDoc,
     231             :         uno::Reference<frame::XFrame>    const& xFrame,
     232             :         uno::Reference<task::XStatusIndicator> const& xStatusIndicator)
     233             :     : m_xContext(xContext),
     234             :     m_xInputStream(xInputStream),
     235             :     m_xDstDoc(xDstDoc),
     236             :     m_xFrame(xFrame),
     237             :     m_xStatusIndicator(xStatusIndicator),
     238             :     m_aDefaultState(this),
     239             :     m_bSkipUnknown(false),
     240             :     m_aFontEncodings(),
     241             :     m_aFontIndexes(),
     242             :     m_aColorTable(),
     243             :     m_bFirstRun(true),
     244             :     m_bNeedPap(true),
     245             :     m_bNeedCr(false),
     246             :     m_bNeedPar(true),
     247             :     m_bNeedFinalPar(false),
     248             :     m_aListTableSprms(),
     249             :     m_aSettingsTableAttributes(),
     250             :     m_aSettingsTableSprms(),
     251             :     m_xStorage(),
     252             :     m_aTableBuffer(),
     253             :     m_aSuperBuffer(),
     254             :     m_aShapetextBuffer(),
     255             :     m_pCurrentBuffer(0),
     256             :     m_bHasFootnote(false),
     257             :     m_pSuperstream(0),
     258             :     m_nHeaderFooterPositions(),
     259             :     m_nGroupStartPos(0),
     260             :     m_aBookmarks(),
     261             :     m_aAuthors(),
     262             :     m_aFormfieldSprms(),
     263             :     m_aFormfieldAttributes(),
     264             :     m_nFormFieldType(FORMFIELD_NONE),
     265             :     m_aObjectSprms(),
     266             :     m_aObjectAttributes(),
     267             :     m_bObject(false),
     268             :     m_aFontTableEntries(),
     269             :     m_nCurrentFontIndex(0),
     270             :     m_aStyleTableEntries(),
     271             :     m_nCurrentStyleIndex(0),
     272             :     m_bFormField(false),
     273             :     m_bIsInFrame(false),
     274             :     m_aUnicodeBuffer(),
     275             :     m_aHexBuffer(),
     276             :     m_bIgnoreNextContSectBreak(false),
     277             :     m_bNeedSect(true),
     278             :     m_bWasInFrame(false),
     279             :     m_bHadPicture(false),
     280         138 :     m_bHadSect(false)
     281             : {
     282             :     OSL_ASSERT(xInputStream.is());
     283         138 :     m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True));
     284             : 
     285         138 :     m_xModelFactory.set(m_xDstDoc, uno::UNO_QUERY);
     286             : 
     287         138 :     uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(m_xDstDoc, uno::UNO_QUERY);
     288         138 :     if (xDocumentPropertiesSupplier.is())
     289         127 :         m_xDocumentProperties.set(xDocumentPropertiesSupplier->getDocumentProperties(), uno::UNO_QUERY);
     290             : 
     291         138 :     m_pGraphicHelper.reset(new oox::GraphicHelper(m_xContext, xFrame, m_xStorage));
     292             : 
     293         138 :     m_pTokenizer.reset(new RTFTokenizer(*this, m_pInStream.get(), m_xStatusIndicator));
     294         138 :     m_pSdrImport.reset(new RTFSdrImport(*this, m_xDstDoc));
     295         138 : }
     296             : 
     297         276 : RTFDocumentImpl::~RTFDocumentImpl()
     298             : {
     299         276 : }
     300             : 
     301     1546727 : SvStream& RTFDocumentImpl::Strm()
     302             : {
     303     1546727 :     return *m_pInStream;
     304             : }
     305             : 
     306       20740 : Stream& RTFDocumentImpl::Mapper()
     307             : {
     308       20740 :     return *m_pMapperStream;
     309             : }
     310             : 
     311           9 : void RTFDocumentImpl::setSuperstream(RTFDocumentImpl *pSuperstream)
     312             : {
     313           9 :     m_pSuperstream = pSuperstream;
     314           9 : }
     315             : 
     316           2 : void RTFDocumentImpl::setAuthor(rtl::OUString& rAuthor)
     317             : {
     318           2 :     m_aAuthor = rAuthor;
     319           2 : }
     320             : 
     321           2 : void RTFDocumentImpl::setAuthorInitials(rtl::OUString& rAuthorInitials)
     322             : {
     323           2 :     m_aAuthorInitials = rAuthorInitials;
     324           2 : }
     325             : 
     326         135 : bool RTFDocumentImpl::isSubstream() const
     327             : {
     328         135 :     return m_pSuperstream != 0;
     329             : }
     330             : 
     331           9 : void RTFDocumentImpl::finishSubstream()
     332             : {
     333           9 :     checkUnicode();
     334             :     // At the end of a footnote stream, we need to emit a run break when importing from Word.
     335             :     // We can't do so unconditionally, as Writer already writes a \par at the end of the footnote.
     336           9 :     if (m_bNeedCr)
     337             :     {
     338           0 :         Mapper().startCharacterGroup();
     339           0 :         runBreak();
     340           0 :         Mapper().endCharacterGroup();
     341             :     }
     342           9 : }
     343             : 
     344           9 : void RTFDocumentImpl::setIgnoreFirst(OUString& rIgnoreFirst)
     345             : {
     346           9 :     m_aIgnoreFirst = rIgnoreFirst;
     347           9 : }
     348             : 
     349           6 : void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId)
     350             : {
     351           6 :     OUString aStr;
     352           6 :     resolveSubstream(nPos, nId, aStr);
     353           6 : }
     354           9 : void RTFDocumentImpl::resolveSubstream(sal_uInt32 nPos, Id nId, OUString& rIgnoreFirst)
     355             : {
     356           9 :     sal_uInt32 nCurrent = Strm().Tell();
     357             :     // Seek to header position, parse, then seek back.
     358           9 :     RTFDocumentImpl::Pointer_t pImpl(new RTFDocumentImpl(m_xContext, m_xInputStream, m_xDstDoc, m_xFrame, m_xStatusIndicator));
     359           9 :     pImpl->setSuperstream(this);
     360           9 :     pImpl->setIgnoreFirst(rIgnoreFirst);
     361           9 :     if (!m_aAuthor.isEmpty())
     362             :     {
     363           2 :         pImpl->setAuthor(m_aAuthor);
     364           2 :         m_aAuthor = OUString();
     365             :     }
     366           9 :     if (!m_aAuthorInitials.isEmpty())
     367             :     {
     368           2 :         pImpl->setAuthorInitials(m_aAuthorInitials);
     369           2 :         m_aAuthorInitials = OUString();
     370             :     }
     371           9 :     pImpl->seek(nPos);
     372             :     SAL_INFO("writerfilter", "substream start");
     373           9 :     Mapper().substream(nId, pImpl);
     374             :     SAL_INFO("writerfilter", "substream end");
     375           9 :     Strm().Seek(nCurrent);
     376           9 :     nPos = 0;
     377           9 : }
     378             : 
     379        4954 : void RTFDocumentImpl::checkFirstRun()
     380             : {
     381        4954 :     if (m_bFirstRun)
     382             :     {
     383             :         // output settings table
     384         133 :         writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(m_aSettingsTableAttributes, m_aSettingsTableSprms));
     385         133 :         RTFReferenceTable::Entries_t aSettingsTableEntries;
     386         133 :         aSettingsTableEntries.insert(make_pair(0, pProp));
     387         133 :         writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aSettingsTableEntries));
     388         133 :         Mapper().table(NS_ooxml::LN_settings_settings, pTable);
     389             :         // start initial paragraph
     390         133 :         if (!m_pSuperstream)
     391         124 :             Mapper().startSectionGroup();
     392         133 :         Mapper().startParagraphGroup();
     393         133 :         m_bFirstRun = false;
     394             :     }
     395        4954 : }
     396             : 
     397         123 : bool RTFDocumentImpl::getFirstRun()
     398             : {
     399         123 :     return m_bFirstRun;
     400             : }
     401             : 
     402           6 : void RTFDocumentImpl::setNeedPar(bool bNeedPar)
     403             : {
     404           6 :     m_bNeedPar = bNeedPar;
     405           6 : }
     406             : 
     407       51195 : void RTFDocumentImpl::setNeedSect(bool bNeedSect)
     408             : {
     409       51195 :     m_bNeedSect = bNeedSect;
     410       51195 : }
     411             : 
     412        4436 : writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms)
     413             : {
     414        4436 :     int nStyle = m_aStates.top().nCurrentStyleIndex;
     415        4436 :     RTFReferenceTable::Entries_t::iterator it = m_aStyleTableEntries.find(nStyle);
     416        4436 :     if (it != m_aStyleTableEntries.end())
     417             :     {
     418         202 :         RTFReferenceProperties& rProps = *(RTFReferenceProperties*)it->second.get();
     419             :         // Get rid of direct formatting what is already in the style.
     420         202 :         rSprms.deduplicate(rProps.getSprms());
     421         202 :         rAttributes.deduplicate(rProps.getAttributes());
     422             :     }
     423        4436 :     writerfilter::Reference<Properties>::Pointer_t pRet(new RTFReferenceProperties(rAttributes, rSprms));
     424        4436 :     return pRet;
     425             : }
     426             : 
     427        4841 : void RTFDocumentImpl::checkNeedPap()
     428             : {
     429        4841 :     if (m_bNeedPap)
     430             :     {
     431         431 :         m_bNeedPap = false; // reset early, so we can avoid recursion when calling ourselves
     432         431 :         if (!m_pCurrentBuffer)
     433             :         {
     434             :             writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
     435         668 :                     getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
     436         668 :                     );
     437             : 
     438             :             // Writer will ignore a page break before a text frame, so guard it with empty paragraphs
     439         334 :             bool hasBreakBeforeFrame = m_aStates.top().aFrame.hasProperties() &&
     440         668 :                 m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PFPageBreakBefore).get();
     441         334 :             if (hasBreakBeforeFrame)
     442             :             {
     443           0 :                 dispatchSymbol(RTF_PAR);
     444           0 :                 m_bNeedPap = false;
     445             :             }
     446         334 :             Mapper().props(pParagraphProperties);
     447         334 :             if (hasBreakBeforeFrame)
     448           0 :                 dispatchSymbol(RTF_PAR);
     449             : 
     450         334 :             if (m_aStates.top().aFrame.hasProperties())
     451             :             {
     452             :                 writerfilter::Reference<Properties>::Pointer_t const pFrameProperties(
     453          17 :                         new RTFReferenceProperties(RTFSprms(), m_aStates.top().aFrame.getSprms()));
     454          17 :                 Mapper().props(pFrameProperties);
     455         334 :             }
     456             :         }
     457             :         else
     458             :         {
     459          97 :             RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
     460          97 :             m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     461             :         }
     462             :     }
     463        4841 : }
     464             : 
     465        4237 : void RTFDocumentImpl::runProps()
     466             : {
     467        4237 :     if (!m_pCurrentBuffer)
     468             :     {
     469        4078 :         writerfilter::Reference<Properties>::Pointer_t const pProperties = getProperties(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms);
     470        4078 :         Mapper().props(pProperties);
     471             :     }
     472             :     else
     473             :     {
     474         159 :         RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
     475         159 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     476             :     }
     477        4237 : }
     478             : 
     479         514 : void RTFDocumentImpl::runBreak()
     480             : {
     481         514 :     sal_uInt8 sBreak[] = { 0xd };
     482         514 :     Mapper().text(sBreak, 1);
     483         514 :     m_bNeedCr = false;
     484         514 : }
     485             : 
     486         123 : void RTFDocumentImpl::tableBreak()
     487             : {
     488         123 :     runBreak();
     489         123 :     Mapper().endParagraphGroup();
     490         123 :     Mapper().startParagraphGroup();
     491         123 : }
     492             : 
     493         388 : void RTFDocumentImpl::parBreak()
     494             : {
     495         388 :     checkFirstRun();
     496         388 :     checkNeedPap();
     497             :     // end previous paragraph
     498         388 :     Mapper().startCharacterGroup();
     499         388 :     runBreak();
     500         388 :     Mapper().endCharacterGroup();
     501         388 :     Mapper().endParagraphGroup();
     502             : 
     503         388 :     m_bHadPicture = false;
     504             : 
     505             :     // start new one
     506         388 :     Mapper().startParagraphGroup();
     507         388 : }
     508             : 
     509         137 : void RTFDocumentImpl::sectBreak(bool bFinal = false)
     510             : {
     511             :     SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect);
     512         137 :     bool bNeedSect = m_bNeedSect;
     513             :     // If there is no paragraph in this section, then insert a dummy one, as required by Writer
     514         137 :     if (m_bNeedPar)
     515           6 :         dispatchSymbol(RTF_PAR);
     516             :     // It's allowed to not have a non-table paragraph at the end of an RTF doc, add it now if required.
     517         137 :     if (m_bNeedFinalPar && bFinal)
     518             :     {
     519           1 :         dispatchFlag(RTF_PARD);
     520           1 :         dispatchSymbol(RTF_PAR);
     521             :     }
     522         278 :     while (m_nHeaderFooterPositions.size())
     523             :     {
     524           4 :         std::pair<Id, sal_uInt32> aPair = m_nHeaderFooterPositions.front();
     525           4 :         m_nHeaderFooterPositions.pop();
     526           4 :         resolveSubstream(aPair.second, aPair.first);
     527             :     }
     528             : 
     529             :     // Normally a section break at the end of the doc is necessary. Unless the
     530             :     // last control word in the document is a section break itself.
     531         137 :     if (!bNeedSect || !m_bHadSect)
     532             :     {
     533         131 :         RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
     534             :         // In case the last section is a continous one, we don't need to output a section break.
     535         131 :         if (bFinal && pBreak.get() && !pBreak->getInt())
     536          37 :             m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc);
     537             :     }
     538             : 
     539             :     // Section properties are a paragraph sprm.
     540         137 :     RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms));
     541         137 :     RTFSprms aAttributes;
     542         137 :     RTFSprms aSprms;
     543         137 :     aSprms.set(NS_ooxml::LN_CT_PPr_sectPr, pValue);
     544             :     writerfilter::Reference<Properties>::Pointer_t const pProperties(
     545         137 :             new RTFReferenceProperties(aAttributes, aSprms)
     546         274 :             );
     547             :     // The trick is that we send properties of the previous section right now, which will be exactly what dmapper expects.
     548         137 :     Mapper().props(pProperties);
     549         137 :     Mapper().endParagraphGroup();
     550         137 :     if (!m_pSuperstream)
     551         128 :         Mapper().endSectionGroup();
     552         137 :     if (!bFinal)
     553             :     {
     554           5 :         Mapper().startSectionGroup();
     555           5 :         Mapper().startParagraphGroup();
     556             :     }
     557         137 :     m_bNeedPar = true;
     558         137 :     m_bNeedSect = false;
     559         137 : }
     560             : 
     561           9 : void RTFDocumentImpl::seek(sal_uInt32 nPos)
     562             : {
     563           9 :     Strm().Seek(nPos);
     564           9 : }
     565             : 
     566         168 : sal_uInt32 RTFDocumentImpl::getColorTable(sal_uInt32 nIndex)
     567             : {
     568         168 :     if (nIndex < m_aColorTable.size())
     569         156 :         return m_aColorTable[nIndex];
     570          12 :     return 0;
     571             : }
     572             : 
     573        1140 : rtl_TextEncoding RTFDocumentImpl::getEncoding(sal_uInt32 nFontIndex)
     574             : {
     575        1140 :     if (!m_pSuperstream)
     576             :     {
     577        1136 :         std::map<int, rtl_TextEncoding>::iterator it = m_aFontEncodings.find(nFontIndex);
     578        1136 :         if (it != m_aFontEncodings.end())
     579         696 :             return it->second;
     580         440 :         return msfilter::util::getBestTextEncodingFromLocale(Application::GetSettings().GetLanguageTag().getLocale());
     581             :     }
     582             :     else
     583           4 :         return m_pSuperstream->getEncoding(nFontIndex);
     584             : }
     585             : 
     586        1468 : int RTFDocumentImpl::getFontIndex(int nIndex)
     587             : {
     588        1468 :     if (!m_pSuperstream)
     589        1467 :         return std::find(m_aFontIndexes.begin(), m_aFontIndexes.end(), nIndex) - m_aFontIndexes.begin();
     590             :     else
     591           1 :         return m_pSuperstream->getFontIndex(nIndex);
     592             : }
     593             : 
     594         328 : RTFParserState& RTFDocumentImpl::getDefaultState()
     595             : {
     596         328 :     if (!m_pSuperstream)
     597         318 :         return m_aDefaultState;
     598             :     else
     599          10 :         return m_pSuperstream->getDefaultState();
     600             : }
     601             : 
     602         138 : void RTFDocumentImpl::resolve(Stream & rMapper)
     603             : {
     604         138 :     m_pMapperStream = &rMapper;
     605         138 :     switch (m_pTokenizer->resolveParse())
     606             :     {
     607             :         case ERROR_OK:
     608             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": finished without errors");
     609         135 :             break;
     610             :         case ERROR_GROUP_UNDER:
     611             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unmatched '}'");
     612           0 :             break;
     613             :         case ERROR_GROUP_OVER:
     614             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unmatched '{'");
     615           2 :             throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
     616             :             break;
     617             :         case ERROR_EOF:
     618             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": unexpected end of file");
     619           0 :             throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
     620             :             break;
     621             :         case ERROR_HEX_INVALID:
     622             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": invalid hex char");
     623           0 :             throw io::WrongFormatException(m_pTokenizer->getPosition(), uno::Reference< uno::XInterface >());
     624             :             break;
     625             :         case ERROR_CHAR_OVER:
     626             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": characters after last '}'");
     627           0 :             break;
     628             :     }
     629         135 : }
     630             : 
     631           9 : int RTFDocumentImpl::resolvePict(bool bInline)
     632             : {
     633           9 :     SvMemoryStream aStream;
     634           9 :     SvStream *pStream = 0;
     635           9 :     if (!m_pBinaryData.get())
     636             :     {
     637           8 :         pStream = &aStream;
     638           8 :         int b = 0, count = 2;
     639             : 
     640             :         // Feed the destination text to a stream.
     641           8 :         OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
     642           8 :         const char *str = aStr.getStr();
     643       39696 :         for (int i = 0; i < aStr.getLength(); ++i)
     644             :         {
     645       39688 :             char ch = str[i];
     646       39688 :             if (ch != 0x0d && ch != 0x0a && ch != 0x20)
     647             :             {
     648       39688 :                 b = b << 4;
     649       39688 :                 sal_Int8 parsed = m_pTokenizer->asHex(ch);
     650       39688 :                 if (parsed == -1)
     651           0 :                     return ERROR_HEX_INVALID;
     652       39688 :                 b += parsed;
     653       39688 :                 count--;
     654       39688 :                 if (!count)
     655             :                 {
     656       19844 :                     aStream << (char)b;
     657       19844 :                     count = 2;
     658       19844 :                     b = 0;
     659             :                 }
     660             :             }
     661           8 :         }
     662             :     }
     663             :     else
     664           1 :         pStream = m_pBinaryData.get();
     665             : 
     666           9 :     if (!pStream->Tell())
     667             :         // No destination text? Then we'll get it later.
     668           1 :         return 0;
     669             : 
     670             :     // Store, and get its URL.
     671           8 :     pStream->Seek(0);
     672           8 :     uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(pStream));
     673           8 :     WMF_EXTERNALHEADER aExtHeader;
     674           8 :     aExtHeader.mapMode = m_aStates.top().aPicture.eWMetafile;
     675           8 :     aExtHeader.xExt = m_aStates.top().aPicture.nWidth;
     676           8 :     aExtHeader.yExt = m_aStates.top().aPicture.nHeight;
     677           8 :     WMF_EXTERNALHEADER* pExtHeader = &aExtHeader;
     678           8 :     uno::Reference<lang::XServiceInfo> xServiceInfo(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
     679           8 :     if (xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
     680           0 :         pExtHeader = 0;
     681           8 :     OUString aGraphicUrl = m_pGraphicHelper->importGraphicObject(xInputStream, pExtHeader);
     682             : 
     683           8 :     if (m_aStates.top().aPicture.nStyle != BMPSTYLE_NONE)
     684             :     {
     685             :         // In case of PNG/JPEG, the real size is known, don't use the values
     686             :         // provided by picw and pich.
     687           6 :         OString aURLBS(OUStringToOString(aGraphicUrl, RTL_TEXTENCODING_UTF8));
     688           6 :         const char aURLBegin[] = "vnd.sun.star.GraphicObject:";
     689           6 :         if (aURLBS.compareTo(aURLBegin, RTL_CONSTASCII_LENGTH(aURLBegin)) == 0)
     690             :         {
     691           6 :             Graphic aGraphic = GraphicObject(aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin))).GetTransformedGraphic();
     692           6 :             Size aSize(aGraphic.GetPrefSize());
     693           6 :             MapMode aMap(MAP_100TH_MM);
     694           6 :             if (aGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL)
     695           5 :                 aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMap);
     696             :             else
     697           1 :                 aSize = OutputDevice::LogicToLogic(aSize, aGraphic.GetPrefMapMode(), aMap);
     698           6 :             m_aStates.top().aPicture.nWidth = aSize.Width();
     699           6 :             m_aStates.top().aPicture.nHeight = aSize.Height();
     700           6 :         }
     701             :     }
     702             : 
     703             :     // Wrap it in an XShape.
     704           8 :     uno::Reference<drawing::XShape> xShape;
     705           8 :     if (m_xModelFactory.is())
     706           8 :         xShape.set(m_xModelFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY);
     707           8 :     uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
     708           8 :     uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier( m_xDstDoc, uno::UNO_QUERY);
     709           8 :     if ( xDrawSupplier.is() )
     710             :     {
     711           8 :         uno::Reference< drawing::XShapes > xShapes( xDrawSupplier->getDrawPage(), uno::UNO_QUERY );
     712           8 :         if ( xShapes.is() )
     713           8 :             xShapes->add( xShape );
     714             :     }
     715           8 :     if (m_bObject)
     716             :     {
     717             :         // Set bitmap
     718           0 :         beans::PropertyValues aMediaProperties(1);
     719           0 :         aMediaProperties[0].Name = "URL";
     720           0 :         aMediaProperties[0].Value <<= aGraphicUrl;
     721           0 :         uno::Reference<graphic::XGraphicProvider> xGraphicProvider(graphic::GraphicProvider::create(m_xContext));
     722           0 :         uno::Reference<graphic::XGraphic> xGraphic = xGraphicProvider->queryGraphic(aMediaProperties);
     723           0 :         xPropertySet->setPropertyValue("Graphic", uno::Any(xGraphic));
     724             : 
     725             :         // Set the object size
     726           0 :         awt::Size aSize;
     727           0 :         aSize.Width = (m_aStates.top().aPicture.nGoalWidth ? m_aStates.top().aPicture.nGoalWidth : m_aStates.top().aPicture.nWidth);
     728           0 :         aSize.Height = (m_aStates.top().aPicture.nGoalHeight ? m_aStates.top().aPicture.nGoalHeight : m_aStates.top().aPicture.nHeight);
     729           0 :         xShape->setSize( aSize );
     730             : 
     731           0 :         RTFValue::Pointer_t pShapeValue(new RTFValue(xShape));
     732           0 :         m_aObjectAttributes.set(NS_ooxml::LN_shape, pShapeValue);
     733           0 :         return 0;
     734             :     }
     735           8 :     if (xPropertySet.is())
     736           8 :         xPropertySet->setPropertyValue("GraphicURL", uno::Any(aGraphicUrl));
     737             : 
     738             :     // Send it to the dmapper.
     739           8 :     RTFSprms aSprms;
     740           8 :     RTFSprms aAttributes;
     741             :     // shape attribute
     742           8 :     RTFSprms aPicAttributes;
     743           8 :     RTFValue::Pointer_t pShapeValue(new RTFValue(xShape));
     744           8 :     aPicAttributes.set(NS_ooxml::LN_shape, pShapeValue);
     745             :     // pic sprm
     746           8 :     RTFSprms aGraphicDataAttributes;
     747           8 :     RTFSprms aGraphicDataSprms;
     748           8 :     RTFValue::Pointer_t pPicValue(new RTFValue(aPicAttributes));
     749           8 :     aGraphicDataSprms.set(NS_ooxml::LN_pic_pic, pPicValue);
     750             :     // graphicData sprm
     751           8 :     RTFSprms aGraphicAttributes;
     752           8 :     RTFSprms aGraphicSprms;
     753           8 :     RTFValue::Pointer_t pGraphicDataValue(new RTFValue(aGraphicDataAttributes, aGraphicDataSprms));
     754           8 :     aGraphicSprms.set(NS_ooxml::LN_CT_GraphicalObject_graphicData, pGraphicDataValue);
     755             :     // graphic sprm
     756           8 :     RTFValue::Pointer_t pGraphicValue(new RTFValue(aGraphicAttributes, aGraphicSprms));
     757             :     // extent sprm
     758           8 :     RTFSprms aExtentAttributes;
     759             :     int nXExt, nYExt;
     760           8 :     nXExt = (m_aStates.top().aPicture.nGoalWidth ? m_aStates.top().aPicture.nGoalWidth : m_aStates.top().aPicture.nWidth);
     761           8 :     nYExt = (m_aStates.top().aPicture.nGoalHeight ? m_aStates.top().aPicture.nGoalHeight : m_aStates.top().aPicture.nHeight);
     762           8 :     if (m_aStates.top().aPicture.nScaleX != 100)
     763           3 :         nXExt = (((long)m_aStates.top().aPicture.nScaleX) * ( nXExt - ( m_aStates.top().aPicture.nCropL + m_aStates.top().aPicture.nCropR ))) / 100L;
     764           8 :     if (m_aStates.top().aPicture.nScaleY != 100)
     765           3 :         nYExt = (((long)m_aStates.top().aPicture.nScaleY) * ( nYExt - ( m_aStates.top().aPicture.nCropT + m_aStates.top().aPicture.nCropB ))) / 100L;
     766           8 :     RTFValue::Pointer_t pXExtValue(new RTFValue(nXExt));
     767           8 :     RTFValue::Pointer_t pYExtValue(new RTFValue(nYExt));
     768           8 :     aExtentAttributes.set(NS_rtf::LN_XEXT, pXExtValue);
     769           8 :     aExtentAttributes.set(NS_rtf::LN_YEXT, pYExtValue);
     770           8 :     RTFValue::Pointer_t pExtentValue(new RTFValue(aExtentAttributes));
     771             :     // docpr sprm
     772           8 :     RTFSprms aDocprAttributes;
     773          10 :     for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin(); i != m_aStates.top().aCharacterAttributes.end(); ++i)
     774           2 :         if (i->first == NS_ooxml::LN_CT_NonVisualDrawingProps_name || i->first == NS_ooxml::LN_CT_NonVisualDrawingProps_descr)
     775           0 :             aDocprAttributes.set(i->first, i->second);
     776           8 :     RTFValue::Pointer_t pDocprValue(new RTFValue(aDocprAttributes));
     777           8 :     if (bInline)
     778             :     {
     779           6 :         RTFSprms aInlineAttributes;
     780           6 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distT, RTFValue::Pointer_t(new RTFValue(0)));
     781           6 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distB, RTFValue::Pointer_t(new RTFValue(0)));
     782           6 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distL, RTFValue::Pointer_t(new RTFValue(0)));
     783           6 :         aInlineAttributes.set(NS_ooxml::LN_CT_Inline_distR, RTFValue::Pointer_t(new RTFValue(0)));
     784           6 :         RTFSprms aInlineSprms;
     785           6 :         aInlineSprms.set(NS_ooxml::LN_CT_Inline_extent, pExtentValue);
     786           6 :         aInlineSprms.set(NS_ooxml::LN_CT_Inline_docPr, pDocprValue);
     787           6 :         aInlineSprms.set(NS_ooxml::LN_graphic_graphic, pGraphicValue);
     788             :         // inline sprm
     789           6 :         RTFValue::Pointer_t pValue(new RTFValue(aInlineAttributes, aInlineSprms));
     790           6 :         aSprms.set(NS_ooxml::LN_inline_inline, pValue);
     791             :     }
     792             :     else // anchored
     793             :     {
     794             :         // wrap sprm
     795           2 :         RTFSprms aAnchorWrapAttributes;
     796           4 :         for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin(); i != m_aStates.top().aCharacterAttributes.end(); ++i)
     797           2 :             if (i->first == NS_ooxml::LN_CT_WrapSquare_wrapText)
     798           2 :                 aAnchorWrapAttributes.set(i->first, i->second);
     799           2 :         RTFValue::Pointer_t pAnchorWrapValue(new RTFValue(aAnchorWrapAttributes));
     800           2 :         RTFSprms aAnchorAttributes;
     801           2 :         RTFSprms aAnchorSprms;
     802           2 :         aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_extent, pExtentValue);
     803           2 :         if (aAnchorWrapAttributes.size())
     804           2 :             aAnchorSprms.set(NS_ooxml::LN_EG_WrapType_wrapSquare, pAnchorWrapValue);
     805           2 :         aAnchorSprms.set(NS_ooxml::LN_CT_Anchor_docPr, pDocprValue);
     806           2 :         aAnchorSprms.set(NS_ooxml::LN_graphic_graphic, pGraphicValue);
     807             :         // anchor sprm
     808           2 :         RTFValue::Pointer_t pValue(new RTFValue(aAnchorAttributes, aAnchorSprms));
     809           2 :         aSprms.set(NS_ooxml::LN_anchor_anchor, pValue);
     810             :     }
     811           8 :     writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes, aSprms));
     812           8 :     checkFirstRun();
     813           8 :     if (!m_pCurrentBuffer)
     814           6 :         Mapper().props(pProperties);
     815             :     else
     816             :     {
     817           2 :         RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
     818           2 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
     819             :     }
     820             : 
     821             :     // Make sure we don't loose these properties with a too early reset.
     822           8 :     m_bHadPicture = true;
     823           8 :     return 0;
     824             : }
     825             : 
     826       27894 : int RTFDocumentImpl::resolveChars(char ch)
     827             : {
     828       27894 :     if (m_aStates.top().nInternalState == INTERNAL_BIN)
     829             :     {
     830           1 :         m_pBinaryData.reset(new SvMemoryStream());
     831           1 :         *m_pBinaryData << ch;
     832       21996 :         for (int i = 0; i < m_aStates.top().nBinaryToRead - 1; ++i)
     833             :         {
     834       21995 :             Strm() >> ch;
     835       21995 :             *m_pBinaryData << ch;
     836             :         }
     837           1 :         m_aStates.top().nInternalState = INTERNAL_NORMAL;
     838           1 :         return 0;
     839             :     }
     840             : 
     841       27893 :     if (m_aStates.top().nInternalState != INTERNAL_HEX)
     842        4534 :         checkUnicode(false, true);
     843             : 
     844       27893 :     OStringBuffer aBuf;
     845             : 
     846       27893 :     bool bUnicodeChecked = false;
     847       27893 :     bool bSkipped = false;
     848      796924 :     while(!Strm().IsEof() && ch != '{' && ch != '}' && ch != '\\')
     849             :     {
     850      764496 :         if (m_aStates.top().nInternalState == INTERNAL_HEX || (ch != 0x0d && ch != 0x0a))
     851             :         {
     852      759019 :             if (m_aStates.top().nCharsToSkip == 0)
     853             :             {
     854      758922 :                 if (!bUnicodeChecked)
     855             :                 {
     856       27795 :                     checkUnicode(true, false);
     857       27795 :                     bUnicodeChecked = true;
     858             :                 }
     859      758922 :                 aBuf.append(ch);
     860             :             }
     861             :             else
     862             :             {
     863          97 :                 bSkipped = true;
     864          97 :                 m_aStates.top().nCharsToSkip--;
     865             :             }
     866             :         }
     867             :         // read a single char if we're in hex mode
     868      764496 :         if (m_aStates.top().nInternalState == INTERNAL_HEX)
     869       23358 :             break;
     870      741138 :         Strm() >> ch;
     871             :     }
     872       27893 :     if (m_aStates.top().nInternalState != INTERNAL_HEX && !Strm().IsEof())
     873        4534 :         Strm().SeekRel(-1);
     874             : 
     875       27893 :     if (m_aStates.top().nInternalState == INTERNAL_HEX && m_aStates.top().nDestinationState != DESTINATION_LEVELNUMBERS)
     876             :     {
     877       23344 :         if (!bSkipped)
     878       23271 :             m_aHexBuffer.append(ch);
     879       23344 :         return 0;
     880             :     }
     881             : 
     882        4549 :     if (m_aStates.top().nDestinationState == DESTINATION_SKIP)
     883         479 :         return 0;
     884        4070 :     OString aStr = aBuf.makeStringAndClear();
     885        4070 :     if (m_aStates.top().nDestinationState == DESTINATION_LEVELNUMBERS)
     886             :     {
     887          25 :         if (aStr.toChar() != ';')
     888          15 :             m_aStates.top().aLevelNumbers.push_back(sal_Int32(ch));
     889          25 :         return 0;
     890             :     }
     891             : 
     892        4045 :     OUString aOUStr(OStringToOUString(aStr, m_aStates.top().nCurrentEncoding));
     893             :     SAL_INFO("writerfilter", OSL_THIS_FUNC << ": collected '" << aOUStr << "'");
     894             : 
     895        4045 :     if (m_aStates.top().nDestinationState == DESTINATION_COLORTABLE)
     896             :     {
     897             :         // we hit a ';' at the end of each color entry
     898         324 :         sal_uInt32 color = (m_aStates.top().aCurrentColor.nRed << 16) | ( m_aStates.top().aCurrentColor.nGreen << 8)
     899         324 :             | m_aStates.top().aCurrentColor.nBlue;
     900         162 :         m_aColorTable.push_back(color);
     901             :         // set components back to zero
     902         162 :         m_aStates.top().aCurrentColor = RTFColorTableEntry();
     903             :     }
     904        3883 :     else if (!aOUStr.isEmpty())
     905        3859 :         text(aOUStr);
     906             : 
     907        4045 :     return 0;
     908             : }
     909             : 
     910        5741 : bool RTFFrame::inFrame()
     911             : {
     912             :     return nW > 0
     913             :         || nH > 0
     914             :         || nX > 0
     915        5741 :         || nY > 0;
     916             : }
     917             : 
     918          24 : void RTFDocumentImpl::singleChar(sal_uInt8 nValue, bool bRunProps)
     919             : {
     920          24 :     sal_uInt8 sValue[] = { nValue };
     921          24 :     if (!m_pCurrentBuffer)
     922             :     {
     923          24 :         Mapper().startCharacterGroup();
     924             :         // Should we send run properties?
     925          24 :         if (bRunProps)
     926           2 :             runProps();
     927          24 :         Mapper().text(sValue, 1);
     928          24 :         Mapper().endCharacterGroup();
     929             :     }
     930             :     else
     931             :     {
     932           0 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_STARTRUN, RTFValue::Pointer_t()));
     933           0 :         RTFValue::Pointer_t pValue(new RTFValue(*sValue));
     934           0 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_TEXT, pValue));
     935           0 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_ENDRUN, RTFValue::Pointer_t()));
     936             :     }
     937          24 : }
     938             : 
     939        6214 : void RTFDocumentImpl::text(OUString& rString)
     940             : {
     941        6214 :     bool bRet = true;
     942        6214 :     switch (m_aStates.top().nDestinationState)
     943             :     {
     944             :         case DESTINATION_FONTTABLE:
     945             :         case DESTINATION_FONTENTRY:
     946             :         case DESTINATION_STYLESHEET:
     947             :         case DESTINATION_STYLEENTRY:
     948             :         case DESTINATION_REVISIONTABLE:
     949             :         case DESTINATION_REVISIONENTRY:
     950             :             {
     951             :                 // ; is the end of the entry
     952         858 :                 bool bEnd = false;
     953         858 :                 if (rString.endsWithAsciiL(";", 1))
     954             :                 {
     955         750 :                     rString = rString.copy(0, rString.getLength() - 1);
     956         750 :                     bEnd = true;
     957             :                 }
     958         858 :                 m_aStates.top().aDestinationText.append(rString);
     959         858 :                 if (bEnd)
     960             :                 {
     961         750 :                     switch (m_aStates.top().nDestinationState)
     962             :                     {
     963             :                         case DESTINATION_FONTTABLE:
     964             :                         case DESTINATION_FONTENTRY:
     965             :                             {
     966         467 :                                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
     967         467 :                                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_XSZFFN, pValue);
     968             : 
     969             :                                 writerfilter::Reference<Properties>::Pointer_t const pProp(
     970        1401 :                                         new RTFReferenceProperties(m_aStates.top().aTableAttributes, m_aStates.top().aTableSprms)
     971        1401 :                                         );
     972             : 
     973             :                                 //See fdo#47347 initial invalid font entry properties are inserted first,
     974             :                                 //so when we attempt to insert the correct ones, there's already an
     975             :                                 //entry in the map for them, so the new ones aren't inserted.
     976         467 :                                 RTFReferenceTable::Entries_t::iterator lb = m_aFontTableEntries.lower_bound(m_nCurrentFontIndex);
     977         467 :                                 if (lb != m_aFontTableEntries.end() && !(m_aFontTableEntries.key_comp()(m_nCurrentFontIndex, lb->first)))
     978           0 :                                     lb->second = pProp;
     979             :                                 else
     980         467 :                                     m_aFontTableEntries.insert(lb, make_pair(m_nCurrentFontIndex, pProp));
     981             :                             }
     982         467 :                             break;
     983             :                         case DESTINATION_STYLESHEET:
     984             :                         case DESTINATION_STYLEENTRY:
     985             :                             {
     986         282 :                                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
     987         282 :                                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_XSTZNAME1, pValue);
     988             : 
     989             :                                 writerfilter::Reference<Properties>::Pointer_t const pProp(
     990         282 :                                         new RTFReferenceProperties(mergeAttributes(), mergeSprms())
     991         564 :                                         );
     992         282 :                                 m_aStyleTableEntries.insert(make_pair(m_nCurrentStyleIndex, pProp));
     993             :                             }
     994         282 :                             break;
     995             :                         case DESTINATION_REVISIONTABLE:
     996             :                         case DESTINATION_REVISIONENTRY:
     997           1 :                             m_aAuthors[m_aAuthors.size()] = m_aStates.top().aDestinationText.makeStringAndClear();
     998           1 :                             break;
     999           0 :                         default: break;
    1000             :                     }
    1001         750 :                     resetAttributes();
    1002         750 :                     resetSprms();
    1003             :                 }
    1004             :             }
    1005         858 :             break;
    1006             :         case DESTINATION_LEVELTEXT:
    1007             :         case DESTINATION_SHAPEPROPERTYNAME:
    1008             :         case DESTINATION_SHAPEPROPERTYVALUE:
    1009             :         case DESTINATION_BOOKMARKEND:
    1010             :         case DESTINATION_PICT:
    1011             :         case DESTINATION_SHAPEPROPERTYVALUEPICT:
    1012             :         case DESTINATION_FORMFIELDNAME:
    1013             :         case DESTINATION_FORMFIELDLIST:
    1014             :         case DESTINATION_DATAFIELD:
    1015             :         case DESTINATION_AUTHOR:
    1016             :         case DESTINATION_KEYWORDS:
    1017             :         case DESTINATION_OPERATOR:
    1018             :         case DESTINATION_COMPANY:
    1019             :         case DESTINATION_COMMENT:
    1020             :         case DESTINATION_OBJDATA:
    1021             :         case DESTINATION_ANNOTATIONDATE:
    1022             :         case DESTINATION_ANNOTATIONAUTHOR:
    1023             :         case DESTINATION_FALT:
    1024             :         case DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER:
    1025             :         case DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE:
    1026             :         case DESTINATION_TITLE:
    1027             :         case DESTINATION_SUBJECT:
    1028             :         case DESTINATION_DOCCOMM:
    1029             :         case DESTINATION_ATNID:
    1030             :         case DESTINATION_MR:
    1031             :         case DESTINATION_MCHR:
    1032             :         case DESTINATION_MPOS:
    1033             :         case DESTINATION_MVERTJC:
    1034             :         case DESTINATION_MSTRIKEH:
    1035             :         case DESTINATION_MDEGHIDE:
    1036             :         case DESTINATION_MBEGCHR:
    1037             :         case DESTINATION_MSEPCHR:
    1038             :         case DESTINATION_MENDCHR:
    1039             :         case DESTINATION_MSUBHIDE:
    1040             :         case DESTINATION_MSUPHIDE:
    1041             :         case DESTINATION_MTYPE:
    1042             :         case DESTINATION_MGROW:
    1043        1244 :             m_aStates.top().aDestinationText.append(rString);
    1044        1244 :             break;
    1045        4112 :         default: bRet = false; break;
    1046             :     }
    1047        6214 :     if (bRet)
    1048        2102 :         return;
    1049             : 
    1050        4112 :     if (!m_aIgnoreFirst.isEmpty() && m_aIgnoreFirst.equals(rString))
    1051             :     {
    1052           0 :         m_aIgnoreFirst = OUString();
    1053           0 :         return;
    1054             :     }
    1055             : 
    1056             :     // Are we in the middle of the table definition? (No cell defs yet, but we already have some cell props.)
    1057        4113 :     if (m_aStates.top().aTableCellSprms.find(NS_ooxml::LN_CT_TcPrBase_vAlign).get() &&
    1058           1 :         m_aStates.top().nCells == 0)
    1059             :     {
    1060           1 :         m_aTableBuffer.push_back(make_pair(BUFFER_UTEXT, RTFValue::Pointer_t(new RTFValue(rString))));
    1061           1 :         return;
    1062             :     }
    1063             : 
    1064        4111 :     checkFirstRun();
    1065        4111 :     checkNeedPap();
    1066             : 
    1067             :     // Don't return earlier, a bookmark start has to be in a paragraph group.
    1068        4111 :     if (m_aStates.top().nDestinationState == DESTINATION_BOOKMARKSTART)
    1069             :     {
    1070           0 :         m_aStates.top().aDestinationText.append(rString);
    1071           0 :         return;
    1072             :     }
    1073             : 
    1074        4111 :     if (!m_pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
    1075        3957 :         Mapper().startCharacterGroup();
    1076         154 :     else if (m_pCurrentBuffer)
    1077             :     {
    1078         154 :         RTFValue::Pointer_t pValue;
    1079         154 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_STARTRUN, pValue));
    1080             :     }
    1081        4136 :     if (m_aStates.top().nDestinationState == DESTINATION_NORMAL
    1082          13 :             || m_aStates.top().nDestinationState == DESTINATION_FIELDRESULT
    1083          12 :             || m_aStates.top().nDestinationState == DESTINATION_SHAPETEXT)
    1084        4102 :         runProps();
    1085        4111 :     if (!m_pCurrentBuffer)
    1086        3957 :         Mapper().utext(reinterpret_cast<sal_uInt8 const*>(rString.getStr()), rString.getLength());
    1087             :     else
    1088             :     {
    1089         154 :         RTFValue::Pointer_t pValue(new RTFValue(rString));
    1090         154 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_UTEXT, pValue));
    1091             :     }
    1092        4111 :     m_bNeedCr = true;
    1093        4111 :     if (!m_pCurrentBuffer && m_aStates.top().nDestinationState != DESTINATION_FOOTNOTE)
    1094        3957 :         Mapper().endCharacterGroup();
    1095         154 :     else if(m_pCurrentBuffer)
    1096             :     {
    1097         154 :         RTFValue::Pointer_t pValue;
    1098         154 :         m_pCurrentBuffer->push_back(make_pair(BUFFER_ENDRUN, pValue));
    1099             :     }
    1100             : }
    1101             : 
    1102         174 : void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer)
    1103             : {
    1104        1096 :     while (rBuffer.size())
    1105             :     {
    1106         847 :         std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = rBuffer.front();
    1107         847 :         rBuffer.pop_front();
    1108         847 :         if (aPair.first == BUFFER_PROPS)
    1109             :         {
    1110             :             writerfilter::Reference<Properties>::Pointer_t const pProp(
    1111         843 :                     new RTFReferenceProperties(aPair.second->getAttributes(), aPair.second->getSprms())
    1112         843 :                     );
    1113         281 :             Mapper().props(pProp);
    1114             :         }
    1115         566 :         else if (aPair.first == BUFFER_CELLEND)
    1116             :         {
    1117          99 :             RTFValue::Pointer_t pValue(new RTFValue(1));
    1118          99 :             m_aStates.top().aTableCellSprms.set(NS_sprm::LN_PCell, pValue);
    1119             :             writerfilter::Reference<Properties>::Pointer_t const pTableCellProperties(
    1120         297 :                     new RTFReferenceProperties(m_aStates.top().aTableCellAttributes, m_aStates.top().aTableCellSprms)
    1121         297 :                     );
    1122          99 :             Mapper().props(pTableCellProperties);
    1123          99 :             tableBreak();
    1124          99 :             break;
    1125             :         }
    1126         467 :         else if (aPair.first == BUFFER_STARTRUN)
    1127         154 :             Mapper().startCharacterGroup();
    1128         313 :         else if (aPair.first == BUFFER_TEXT)
    1129             :         {
    1130           0 :             sal_uInt8 nValue = aPair.second->getInt();
    1131           0 :             Mapper().text(&nValue, 1);
    1132             :         }
    1133         313 :         else if (aPair.first == BUFFER_UTEXT)
    1134             :         {
    1135         155 :             OUString aString(aPair.second->getString());
    1136         155 :             Mapper().utext(reinterpret_cast<sal_uInt8 const*>(aString.getStr()), aString.getLength());
    1137             :         }
    1138         158 :         else if (aPair.first == BUFFER_ENDRUN)
    1139         154 :             Mapper().endCharacterGroup();
    1140           4 :         else if (aPair.first == BUFFER_PAR)
    1141           4 :             parBreak();
    1142             :         else
    1143             :             SAL_WARN("writerfilter", "should not happen");
    1144         847 :     }
    1145             : 
    1146         174 : }
    1147             : 
    1148        2962 : int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword)
    1149             : {
    1150        2962 :     checkUnicode();
    1151        2962 :     setNeedSect();
    1152        2962 :     RTFSkipDestination aSkip(*this);
    1153        2962 :     switch (nKeyword)
    1154             :     {
    1155             :         case RTF_RTF:
    1156         128 :             break;
    1157             :         case RTF_FONTTBL:
    1158          55 :             m_aStates.top().nDestinationState = DESTINATION_FONTTABLE;
    1159          55 :             break;
    1160             :         case RTF_COLORTBL:
    1161          41 :             m_aStates.top().nDestinationState = DESTINATION_COLORTABLE;
    1162          41 :             break;
    1163             :         case RTF_STYLESHEET:
    1164          42 :             m_aStates.top().nDestinationState = DESTINATION_STYLESHEET;
    1165          42 :             break;
    1166             :         case RTF_FIELD:
    1167           6 :             m_aStates.top().nDestinationState = DESTINATION_FIELD;
    1168           6 :             break;
    1169             :         case RTF_FLDINST:
    1170             :             {
    1171             :                 // Look for the field type
    1172           6 :                 sal_Int32 nPos = Strm().Tell();
    1173           6 :                 OStringBuffer aBuf;
    1174           6 :                 char ch = 0;
    1175           6 :                 bool bFoundCode = false;
    1176           6 :                 bool bInKeyword = false;
    1177          61 :                 while (!bFoundCode && ch != '}')
    1178             :                 {
    1179          49 :                     Strm() >> ch;
    1180          49 :                     if ('\\' == ch)
    1181           3 :                         bInKeyword = true;
    1182          49 :                     if (!bInKeyword  && isalnum(ch))
    1183          25 :                         aBuf.append(ch);
    1184          24 :                     else if (bInKeyword && isspace(ch))
    1185           1 :                         bInKeyword = false;
    1186          49 :                     if (aBuf.getLength() > 0 && !isalnum(ch))
    1187           6 :                         bFoundCode = true;
    1188             :                 }
    1189           6 :                 Strm().Seek(nPos);
    1190             : 
    1191             :                 // Form data should be handled only for form fields if any
    1192           6 :                 if (aBuf.toString().indexOf(OString("FORM")) != -1 )
    1193           0 :                     m_bFormField = true;
    1194             : 
    1195           6 :                 singleChar(0x13);
    1196           6 :                 m_aStates.top().nDestinationState = DESTINATION_FIELDINSTRUCTION;
    1197             :             }
    1198           6 :             break;
    1199             :         case RTF_FLDRSLT:
    1200           5 :             m_aStates.top().nDestinationState = DESTINATION_FIELDRESULT;
    1201           5 :             break;
    1202             :         case RTF_LISTTABLE:
    1203           5 :             m_aStates.top().nDestinationState = DESTINATION_LISTTABLE;
    1204           5 :             break;
    1205             :         case RTF_LIST:
    1206           5 :             m_aStates.top().nDestinationState = DESTINATION_LISTENTRY;
    1207           5 :             break;
    1208             :         case RTF_LISTOVERRIDETABLE:
    1209           5 :             m_aStates.top().nDestinationState = DESTINATION_LISTOVERRIDETABLE;
    1210           5 :             break;
    1211             :         case RTF_LISTOVERRIDE:
    1212           5 :             m_aStates.top().nDestinationState = DESTINATION_LISTOVERRIDEENTRY;
    1213           5 :             break;
    1214             :         case RTF_LISTLEVEL:
    1215           8 :             m_aStates.top().nDestinationState = DESTINATION_LISTLEVEL;
    1216           8 :             break;
    1217             :         case RTF_LEVELTEXT:
    1218          10 :             m_aStates.top().nDestinationState = DESTINATION_LEVELTEXT;
    1219          10 :             break;
    1220             :         case RTF_LEVELNUMBERS:
    1221          10 :             m_aStates.top().nDestinationState = DESTINATION_LEVELNUMBERS;
    1222          10 :             break;
    1223             :         case RTF_SHPPICT:
    1224           3 :             m_aStates.top().resetFrame();
    1225           3 :             m_aStates.top().nDestinationState = DESTINATION_SHPPICT;
    1226           3 :             break;
    1227             :         case RTF_PICT:
    1228           8 :             if (m_aStates.top().nDestinationState != DESTINATION_SHAPEPROPERTYVALUE)
    1229           6 :                 m_aStates.top().nDestinationState = DESTINATION_PICT; // as character
    1230             :             else
    1231           2 :                 m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUEPICT; // anchored inside a shape
    1232           8 :             break;
    1233             :         case RTF_PICPROP:
    1234           0 :             m_aStates.top().nDestinationState = DESTINATION_PICPROP;
    1235           0 :             break;
    1236             :         case RTF_SP:
    1237         163 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTY;
    1238         163 :             break;
    1239             :         case RTF_SN:
    1240         163 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYNAME;
    1241         163 :             break;
    1242             :         case RTF_SV:
    1243         163 :             m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUE;
    1244         163 :             break;
    1245             :         case RTF_SHP:
    1246          16 :             m_aStates.top().nDestinationState = DESTINATION_SHAPE;
    1247          16 :             break;
    1248             :         case RTF_SHPINST:
    1249             :             // Don't try to support shapes inside tables for now.
    1250          16 :             if (m_pCurrentBuffer != &m_aTableBuffer)
    1251          16 :                 m_aStates.top().nDestinationState = DESTINATION_SHAPEINSTRUCTION;
    1252             :             else
    1253           0 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1254          16 :             break;
    1255             :         case RTF_NESTTABLEPROPS:
    1256           0 :             m_aStates.top().nDestinationState = DESTINATION_NESTEDTABLEPROPERTIES;
    1257           0 :             break;
    1258             :         case RTF_HEADER:
    1259             :         case RTF_FOOTER:
    1260             :         case RTF_HEADERL:
    1261             :         case RTF_HEADERR:
    1262             :         case RTF_HEADERF:
    1263             :         case RTF_FOOTERL:
    1264             :         case RTF_FOOTERR:
    1265             :         case RTF_FOOTERF:
    1266           8 :             if (!m_pSuperstream)
    1267             :             {
    1268           4 :                 Id nId = 0;
    1269           4 :                 sal_uInt32 nPos = m_nGroupStartPos - 1;
    1270           4 :                 switch (nKeyword)
    1271             :                 {
    1272           3 :                     case RTF_HEADER: nId = NS_rtf::LN_headerr; break;
    1273           0 :                     case RTF_FOOTER: nId = NS_rtf::LN_footerr; break;
    1274           0 :                     case RTF_HEADERL: nId = NS_rtf::LN_headerl; break;
    1275           1 :                     case RTF_HEADERR: nId = NS_rtf::LN_headerr; break;
    1276           0 :                     case RTF_HEADERF: nId = NS_rtf::LN_headerf; break;
    1277           0 :                     case RTF_FOOTERL: nId = NS_rtf::LN_footerl; break;
    1278           0 :                     case RTF_FOOTERR: nId = NS_rtf::LN_footerr; break;
    1279           0 :                     case RTF_FOOTERF: nId = NS_rtf::LN_footerf; break;
    1280           0 :                     default: break;
    1281             :                 }
    1282           4 :                 m_nHeaderFooterPositions.push(make_pair(nId, nPos));
    1283           4 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1284             :             }
    1285           8 :             break;
    1286             :         case RTF_FOOTNOTE:
    1287           6 :             if (!m_pSuperstream)
    1288             :             {
    1289           3 :                 Id nId = NS_rtf::LN_footnote;
    1290             : 
    1291             :                 // Check if this is an endnote.
    1292           3 :                 OStringBuffer aBuf;
    1293             :                 char ch;
    1294          24 :                 for (int i = 0; i < 7; ++i)
    1295             :                 {
    1296          21 :                     Strm() >> ch;
    1297          21 :                     aBuf.append(ch);
    1298             :                 }
    1299           3 :                 OString aKeyword = aBuf.makeStringAndClear();
    1300           3 :                 if (aKeyword.equals("\\ftnalt"))
    1301           0 :                     nId = NS_rtf::LN_endnote;
    1302             : 
    1303           3 :                 m_bHasFootnote = true;
    1304           3 :                 if (m_pCurrentBuffer == &m_aSuperBuffer)
    1305           2 :                     m_pCurrentBuffer = 0;
    1306           3 :                 bool bCustomMark = false;
    1307           3 :                 OUString aCustomMark;
    1308           6 :                 while (m_aSuperBuffer.size())
    1309             :                 {
    1310           0 :                     std::pair<RTFBufferTypes, RTFValue::Pointer_t> aPair = m_aSuperBuffer.front();
    1311           0 :                     m_aSuperBuffer.pop_front();
    1312           0 :                     if (aPair.first == BUFFER_UTEXT)
    1313             :                     {
    1314           0 :                         aCustomMark = aPair.second->getString();
    1315           0 :                         bCustomMark = true;
    1316             :                     }
    1317           0 :                 }
    1318           3 :                 m_aStates.top().nDestinationState = DESTINATION_FOOTNOTE;
    1319           3 :                 if (bCustomMark)
    1320           0 :                     Mapper().startCharacterGroup();
    1321           3 :                 resolveSubstream(m_nGroupStartPos - 1, nId, aCustomMark);
    1322           3 :                 if (bCustomMark)
    1323             :                 {
    1324           0 :                     m_aStates.top().aCharacterAttributes.clear();
    1325           0 :                     m_aStates.top().aCharacterSprms.clear();
    1326           0 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    1327           0 :                     m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_FtnEdnRef_customMarkFollows, pValue);
    1328           0 :                     text(aCustomMark);
    1329           0 :                     Mapper().endCharacterGroup();
    1330             :                 }
    1331           3 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1332             :             }
    1333           6 :             break;
    1334             :         case RTF_BKMKSTART:
    1335           0 :             m_aStates.top().nDestinationState = DESTINATION_BOOKMARKSTART;
    1336           0 :             break;
    1337             :         case RTF_BKMKEND:
    1338           0 :             m_aStates.top().nDestinationState = DESTINATION_BOOKMARKEND;
    1339           0 :             break;
    1340             :         case RTF_REVTBL:
    1341           1 :             m_aStates.top().nDestinationState = DESTINATION_REVISIONTABLE;
    1342           1 :             break;
    1343             :         case RTF_ANNOTATION:
    1344           4 :             if (!m_pSuperstream)
    1345             :             {
    1346           2 :                 resolveSubstream(m_nGroupStartPos - 1, NS_rtf::LN_annotation);
    1347           2 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1348             :             }
    1349             :             else
    1350             :             {
    1351             :                 // If there is an author set, emit it now.
    1352           2 :                 if (!m_aAuthor.isEmpty() || !m_aAuthorInitials.isEmpty())
    1353             :                 {
    1354           2 :                     RTFSprms aAttributes;
    1355           2 :                     if (!m_aAuthor.isEmpty())
    1356             :                     {
    1357           2 :                         RTFValue::Pointer_t pValue(new RTFValue(m_aAuthor));
    1358           2 :                         aAttributes.set(NS_ooxml::LN_CT_TrackChange_author, pValue);
    1359             :                     }
    1360           2 :                     if (!m_aAuthorInitials.isEmpty())
    1361             :                     {
    1362           2 :                         RTFValue::Pointer_t pValue(new RTFValue(m_aAuthorInitials));
    1363           2 :                         aAttributes.set(NS_ooxml::LN_CT_Comment_initials, pValue);
    1364             :                     }
    1365           2 :                     writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
    1366           2 :                     Mapper().props(pProperties);
    1367             :                 }
    1368             :             }
    1369           4 :             break;
    1370             :         case RTF_SHPTXT:
    1371             :         case RTF_DPTXBXTEXT:
    1372           3 :             m_aStates.top().nDestinationState = DESTINATION_SHAPETEXT;
    1373           3 :             dispatchFlag(RTF_PARD);
    1374           3 :             m_bNeedPap = true;
    1375             :             OSL_ENSURE(!m_aShapetextBuffer.size(), "shapetext buffer is not empty");
    1376           3 :             m_pCurrentBuffer = &m_aShapetextBuffer;
    1377           3 :             break;
    1378             :         case RTF_FORMFIELD:
    1379           0 :             if (m_aStates.top().nDestinationState == DESTINATION_FIELDINSTRUCTION)
    1380           0 :                 m_aStates.top().nDestinationState = DESTINATION_FORMFIELD;
    1381           0 :             break;
    1382             :         case RTF_FFNAME:
    1383           0 :             m_aStates.top().nDestinationState = DESTINATION_FORMFIELDNAME;
    1384           0 :             break;
    1385             :         case RTF_FFL:
    1386           0 :             m_aStates.top().nDestinationState = DESTINATION_FORMFIELDLIST;
    1387           0 :             break;
    1388             :         case RTF_DATAFIELD:
    1389           0 :             m_aStates.top().nDestinationState = DESTINATION_DATAFIELD;
    1390           0 :             break;
    1391             :         case RTF_INFO:
    1392          41 :             m_aStates.top().nDestinationState = DESTINATION_INFO;
    1393          41 :             break;
    1394             :         case RTF_CREATIM:
    1395          32 :             m_aStates.top().nDestinationState = DESTINATION_CREATIONTIME;
    1396          32 :             break;
    1397             :         case RTF_REVTIM:
    1398          32 :             m_aStates.top().nDestinationState = DESTINATION_REVISIONTIME;
    1399          32 :             break;
    1400             :         case RTF_PRINTIM:
    1401          30 :             m_aStates.top().nDestinationState = DESTINATION_PRINTTIME;
    1402          30 :             break;
    1403             :         case RTF_AUTHOR:
    1404           5 :             m_aStates.top().nDestinationState = DESTINATION_AUTHOR;
    1405           5 :             break;
    1406             :         case RTF_KEYWORDS:
    1407           2 :             m_aStates.top().nDestinationState = DESTINATION_KEYWORDS;
    1408           2 :             break;
    1409             :         case RTF_OPERATOR:
    1410           3 :             m_aStates.top().nDestinationState = DESTINATION_OPERATOR;
    1411           3 :             break;
    1412             :         case RTF_COMPANY:
    1413           5 :             m_aStates.top().nDestinationState = DESTINATION_COMPANY;
    1414           5 :             break;
    1415             :         case RTF_COMMENT:
    1416          31 :             m_aStates.top().nDestinationState = DESTINATION_COMMENT;
    1417          31 :             break;
    1418             :         case RTF_OBJECT:
    1419           0 :             m_aStates.top().nDestinationState = DESTINATION_OBJECT;
    1420           0 :             m_bObject = true;
    1421           0 :             break;
    1422             :         case RTF_OBJDATA:
    1423           0 :             m_aStates.top().nDestinationState = DESTINATION_OBJDATA;
    1424           0 :             break;
    1425             :         case RTF_RESULT:
    1426           0 :             m_aStates.top().nDestinationState = DESTINATION_RESULT;
    1427           0 :             break;
    1428             :         case RTF_ATNDATE:
    1429           2 :             m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONDATE;
    1430           2 :             break;
    1431             :         case RTF_ATNAUTHOR:
    1432           2 :             m_aStates.top().nDestinationState = DESTINATION_ANNOTATIONAUTHOR;
    1433           2 :             break;
    1434             :         case RTF_FALT:
    1435         104 :             m_aStates.top().nDestinationState = DESTINATION_FALT;
    1436         104 :             break;
    1437             :         case RTF_FLYMAINCNT:
    1438           3 :             m_aStates.top().nDestinationState = DESTINATION_FLYMAINCONTENT;
    1439           3 :             break;
    1440             :         case RTF_LISTTEXT:
    1441             :             // Should be ignored by any reader that understands Word 97 through Word 2007 numbering.
    1442             :         case RTF_NONESTTABLES:
    1443             :             // This destination should be ignored by readers that support nested tables.
    1444           5 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1445           5 :             break;
    1446             :         case RTF_DO:
    1447          10 :             m_aStates.top().nDestinationState = DESTINATION_DRAWINGOBJECT;
    1448          10 :             break;
    1449             :         case RTF_PN:
    1450           4 :             m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING;
    1451           4 :             break;
    1452             :         case RTF_PNTEXT:
    1453             :             // This destination should be ignored by readers that support paragraph numbering.
    1454           0 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1455           0 :             break;
    1456             :         case RTF_PNTXTA:
    1457           3 :             m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER;
    1458           3 :             break;
    1459             :         case RTF_PNTXTB:
    1460           3 :             m_aStates.top().nDestinationState = DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE;
    1461           3 :             break;
    1462             :         case RTF_TITLE:
    1463           6 :             m_aStates.top().nDestinationState = DESTINATION_TITLE;
    1464           6 :             break;
    1465             :         case RTF_SUBJECT:
    1466           3 :             m_aStates.top().nDestinationState = DESTINATION_SUBJECT;
    1467           3 :             break;
    1468             :         case RTF_DOCCOMM:
    1469           4 :             m_aStates.top().nDestinationState = DESTINATION_DOCCOMM;
    1470           4 :             break;
    1471             :         case RTF_ATRFSTART:
    1472             :         case RTF_ATRFEND:
    1473             :             {
    1474             :                 // We could send the real value here, but that would make the
    1475             :                 // tokenizer more complicated, and dmapper doesn't read the
    1476             :                 // result anyway.
    1477           4 :                 RTFValue::Pointer_t pValue(new RTFValue(0));
    1478           4 :                 m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1479             : 
    1480           4 :                 RTFSprms aAttributes;
    1481           4 :                 if (nKeyword == RTF_ATRFSTART)
    1482           2 :                     aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeStart, pValue);
    1483             :                 else
    1484           2 :                     aAttributes.set(NS_ooxml::LN_EG_RangeMarkupElements_commentRangeEnd, pValue);
    1485           4 :                 writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
    1486           4 :                 Mapper().props(pProperties);
    1487             :             }
    1488           4 :             break;
    1489             :         case RTF_ATNID:
    1490           2 :             m_aStates.top().nDestinationState = DESTINATION_ATNID;
    1491           2 :             break;
    1492             :         case RTF_MMATH:
    1493             :         case RTF_MOMATHPARA:
    1494             :             // Nothing to do here (just enter the destination) till RTF_MMATHPR is implemented.
    1495          88 :             break;
    1496         490 :         case RTF_MR: m_aStates.top().nDestinationState = DESTINATION_MR; break;
    1497          38 :         case RTF_MCHR: m_aStates.top().nDestinationState = DESTINATION_MCHR; break;
    1498           4 :         case RTF_MPOS: m_aStates.top().nDestinationState = DESTINATION_MPOS; break;
    1499           3 :         case RTF_MVERTJC: m_aStates.top().nDestinationState = DESTINATION_MVERTJC; break;
    1500           2 :         case RTF_MSTRIKEH: m_aStates.top().nDestinationState = DESTINATION_MSTRIKEH; break;
    1501           4 :         case RTF_MDEGHIDE: m_aStates.top().nDestinationState = DESTINATION_MDEGHIDE; break;
    1502           6 :         case RTF_MTYPE: m_aStates.top().nDestinationState = DESTINATION_MTYPE; break;
    1503           2 :         case RTF_MGROW: m_aStates.top().nDestinationState = DESTINATION_MGROW; break;
    1504             :         case RTF_MHIDETOP:
    1505             :         case RTF_MHIDEBOT:
    1506             :         case RTF_MHIDELEFT:
    1507             :         case RTF_MHIDERIGHT:
    1508             :             // SmOoxmlImport::handleBorderBox will ignore these anyway, so silently ignore for now.
    1509           8 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1510           8 :             break;
    1511           2 :         case RTF_MSUBHIDE: m_aStates.top().nDestinationState = DESTINATION_MSUBHIDE; break;
    1512           2 :         case RTF_MSUPHIDE: m_aStates.top().nDestinationState = DESTINATION_MSUPHIDE; break;
    1513          32 :         case RTF_MBEGCHR: m_aStates.top().nDestinationState = DESTINATION_MBEGCHR; break;
    1514           3 :         case RTF_MSEPCHR: m_aStates.top().nDestinationState = DESTINATION_MSEPCHR; break;
    1515          32 :         case RTF_MENDCHR: m_aStates.top().nDestinationState = DESTINATION_MENDCHR; break;
    1516          59 :         OPEN_M_TOKEN(OMATH, oMath);
    1517          34 :         OPEN_M_TOKEN(F, f);
    1518          20 :         OPEN_M_TOKEN(FPR, fPr);
    1519         108 :         OPEN_M_TOKEN(CTRLPR, ctrlPr);
    1520          34 :         OPEN_M_TOKEN(NUM, num);
    1521          34 :         OPEN_M_TOKEN(DEN, den);
    1522          24 :         OPEN_M_TOKEN(ACC, acc);
    1523          24 :         OPEN_M_TOKEN(ACCPR, accPr);
    1524           2 :         OPEN_M_TOKEN(BAR, bar);
    1525           2 :         OPEN_M_TOKEN(BARPR, barPr);
    1526         197 :         OPEN_M_TOKEN(E, e);
    1527          45 :         OPEN_M_TOKEN(D, d);
    1528          45 :         OPEN_M_TOKEN(DPR, dPr);
    1529          12 :         OPEN_M_TOKEN(FUNC, func);
    1530          11 :         OPEN_M_TOKEN(FUNCPR, funcPr);
    1531          12 :         OPEN_M_TOKEN(FNAME, fName);
    1532           6 :         OPEN_M_TOKEN(LIMLOW, limLow);
    1533           3 :         OPEN_M_TOKEN(LIMLOWPR, limLowPr);
    1534          10 :         OPEN_M_TOKEN(LIM, lim);
    1535           2 :         OPEN_M_TOKEN(M, m);
    1536           1 :         OPEN_M_TOKEN(MPR, mPr);
    1537           4 :         OPEN_M_TOKEN(MR, mr);
    1538          13 :         OPEN_M_TOKEN(NARY, nary);
    1539          13 :         OPEN_M_TOKEN(NARYPR, naryPr);
    1540          29 :         OPEN_M_TOKEN(SUB, sub);
    1541          55 :         OPEN_M_TOKEN(SUP, sup);
    1542           4 :         OPEN_M_TOKEN(LIMUPP, limUpp);
    1543           2 :         OPEN_M_TOKEN(LIMUPPPR, limUppPr);
    1544           4 :         OPEN_M_TOKEN(GROUPCHR, groupChr);
    1545           4 :         OPEN_M_TOKEN(GROUPCHRPR, groupChrPr);
    1546           2 :         OPEN_M_TOKEN(BORDERBOX, borderBox);
    1547           2 :         OPEN_M_TOKEN(BORDERBOXPR, borderBoxPr);
    1548           6 :         OPEN_M_TOKEN(RAD, rad);
    1549           5 :         OPEN_M_TOKEN(RADPR, radPr);
    1550           6 :         OPEN_M_TOKEN(DEG, deg);
    1551           8 :         OPEN_M_TOKEN(SSUB, sSub);
    1552           4 :         OPEN_M_TOKEN(SSUBPR, sSubPr);
    1553          34 :         OPEN_M_TOKEN(SSUP, sSup);
    1554          17 :         OPEN_M_TOKEN(SSUPPR, sSupPr);
    1555           4 :         OPEN_M_TOKEN(SSUBSUP, sSubSup);
    1556           2 :         OPEN_M_TOKEN(SSUBSUPPR, sSubSupPr);
    1557           4 :         OPEN_M_TOKEN(SPRE, sPre);
    1558           2 :         OPEN_M_TOKEN(SPREPR, sPrePr);
    1559           1 :         OPEN_M_TOKEN(BOX, box);
    1560           6 :         OPEN_M_TOKEN(EQARR, eqArr);
    1561             :         default:
    1562             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle destination '" << lcl_RtfToString(nKeyword) << "'");
    1563             :             // Make sure we skip destinations (even without \*) till we don't handle them
    1564         109 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    1565         109 :             aSkip.setParsed(false);
    1566         109 :             break;
    1567             :     }
    1568             : 
    1569        2962 :     return 0;
    1570             : }
    1571             : 
    1572       24736 : int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
    1573             : {
    1574       24736 :     if (nKeyword != RTF_HEXCHAR)
    1575        1377 :         checkUnicode();
    1576       24736 :     setNeedSect();
    1577       24736 :     RTFSkipDestination aSkip(*this);
    1578       24736 :     sal_uInt8 cCh = 0;
    1579             : 
    1580             :     // Trivial symbols
    1581       24736 :     switch (nKeyword)
    1582             :     {
    1583          51 :         case RTF_LINE: cCh = '\n'; break;
    1584          41 :         case RTF_TAB: cCh = '\t'; break;
    1585          19 :         case RTF_BACKSLASH: cCh = '\\'; break;
    1586          23 :         case RTF_LBRACE: cCh = '{'; break;
    1587          20 :         case RTF_RBRACE: cCh = '}'; break;
    1588           9 :         case RTF_EMDASH: cCh = 151; break;
    1589          10 :         case RTF_ENDASH: cCh = 150; break;
    1590          15 :         case RTF_BULLET: cCh = 149; break;
    1591          16 :         case RTF_LQUOTE: cCh = 145; break;
    1592          13 :         case RTF_RQUOTE: cCh = 146; break;
    1593          22 :         case RTF_LDBLQUOTE: cCh = 147; break;
    1594           9 :         case RTF_RDBLQUOTE: cCh = 148; break;
    1595       24488 :         default: break;
    1596             :     }
    1597       24736 :     if (cCh > 0)
    1598             :     {
    1599         248 :         OUString aStr(OStringToOUString(OString(cCh), RTL_TEXTENCODING_MS_1252));
    1600         248 :         text(aStr);
    1601         248 :         return 0;
    1602             :     }
    1603             : 
    1604       24488 :     switch (nKeyword)
    1605             :     {
    1606             :         case RTF_IGNORE:
    1607         559 :             m_bSkipUnknown = true;
    1608         559 :             aSkip.setReset(false);
    1609         559 :             return 0;
    1610             :             break;
    1611             :         case RTF_PAR:
    1612             :             {
    1613         342 :                 checkFirstRun();
    1614         342 :                 bool bNeedPap = m_bNeedPap;
    1615         342 :                 checkNeedPap();
    1616         342 :                 if (bNeedPap)
    1617         133 :                     runProps();
    1618         342 :                 if (!m_pCurrentBuffer)
    1619         332 :                     parBreak();
    1620          10 :                 else if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT)
    1621             :                 {
    1622           7 :                     RTFValue::Pointer_t pValue;
    1623           7 :                     m_pCurrentBuffer->push_back(make_pair(BUFFER_PAR, pValue));
    1624             :                 }
    1625             :                 // but don't emit properties yet, since they may change till the first text token arrives
    1626         342 :                 m_bNeedPap = true;
    1627         342 :                 if (!m_aStates.top().aFrame.inFrame())
    1628         325 :                     m_bNeedPar = false;
    1629         342 :                 m_bNeedFinalPar = false;
    1630             :             }
    1631         342 :             break;
    1632             :         case RTF_SECT:
    1633             :             {
    1634           5 :                 m_bHadSect = true;
    1635           5 :                 if (m_bIgnoreNextContSectBreak)
    1636           2 :                     m_bIgnoreNextContSectBreak = false;
    1637             :                 else
    1638           3 :                     sectBreak();
    1639             :             }
    1640           5 :             break;
    1641             :         case RTF_NOBREAK:
    1642             :             {
    1643          19 :                 OUString aStr(SVT_HARD_SPACE);
    1644          19 :                 text(aStr);
    1645             :             }
    1646          19 :             break;
    1647             :         case RTF_NOBRKHYPH:
    1648             :             {
    1649           2 :                 OUString aStr(SVT_HARD_HYPHEN);
    1650           2 :                 text(aStr);
    1651             :             }
    1652           2 :             break;
    1653             :         case RTF_OPTHYPH:
    1654             :             {
    1655          13 :                 OUString aStr(SVT_SOFT_HYPHEN);
    1656          13 :                 text(aStr);
    1657             :             }
    1658          13 :             break;
    1659             :         case RTF_HEXCHAR:
    1660       23359 :             m_aStates.top().nInternalState = INTERNAL_HEX;
    1661       23359 :             break;
    1662             :         case RTF_CELL:
    1663             :         case RTF_NESTCELL:
    1664             :             {
    1665          99 :                 checkFirstRun();
    1666          99 :                 if (m_bNeedPap)
    1667             :                 {
    1668             :                     // There were no runs in the cell, so we need to send paragraph and character properties here.
    1669          16 :                     RTFValue::Pointer_t pPValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
    1670          16 :                     m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pPValue));
    1671          16 :                     RTFValue::Pointer_t pCValue(new RTFValue(m_aStates.top().aCharacterAttributes, m_aStates.top().aCharacterSprms));
    1672          16 :                     m_aTableBuffer.push_back(make_pair(BUFFER_PROPS, pCValue));
    1673             :                 }
    1674             : 
    1675          99 :                 RTFValue::Pointer_t pValue;
    1676          99 :                 m_aTableBuffer.push_back(make_pair(BUFFER_CELLEND, pValue));
    1677          99 :                 m_bNeedPap = true;
    1678             :             }
    1679          99 :             break;
    1680             :         case RTF_ROW:
    1681             :         case RTF_NESTROW:
    1682             :             {
    1683          24 :                 if (m_aStates.top().nCells)
    1684             :                 {
    1685             :                     // Make a backup before we start popping elements
    1686          24 :                     m_aStates.top().aTableInheritingCellsSprms = m_aStates.top().aTableCellsSprms;
    1687          24 :                     m_aStates.top().aTableInheritingCellsAttributes = m_aStates.top().aTableCellsAttributes;
    1688          24 :                     m_aStates.top().nInheritingCells = m_aStates.top().nCells;
    1689             :                 }
    1690             :                 else
    1691             :                 {
    1692             :                     // No table definition? Then inherit from the previous row
    1693           0 :                     m_aStates.top().aTableCellsSprms = m_aStates.top().aTableInheritingCellsSprms;
    1694           0 :                     m_aStates.top().aTableCellsAttributes = m_aStates.top().aTableInheritingCellsAttributes;
    1695           0 :                     m_aStates.top().nCells = m_aStates.top().nInheritingCells;
    1696             :                     // This can't be the first row, and we need cell width only there
    1697           0 :                     while(m_aStates.top().aTableRowSprms.erase(NS_ooxml::LN_CT_TblGridBase_gridCol)) ;
    1698             :                 }
    1699         188 :                 for (int i = 0; i < m_aStates.top().nCells; ++i)
    1700             :                 {
    1701         164 :                     m_aStates.top().aTableCellSprms = m_aStates.top().aTableCellsSprms.front();
    1702         164 :                     m_aStates.top().aTableCellsSprms.pop_front();
    1703         164 :                     m_aStates.top().aTableCellAttributes = m_aStates.top().aTableCellsAttributes.front();
    1704         164 :                     m_aStates.top().aTableCellsAttributes.pop_front();
    1705         164 :                     replayBuffer(m_aTableBuffer);
    1706             :                 }
    1707          24 :                 m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
    1708          24 :                 m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
    1709             : 
    1710             :                 writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
    1711          48 :                         getProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
    1712          48 :                         );
    1713          24 :                 Mapper().props(pParagraphProperties);
    1714             : 
    1715          24 :                 if (m_aStates.top().aFrame.hasProperties())
    1716             :                 {
    1717             :                     writerfilter::Reference<Properties>::Pointer_t const pFrameProperties(
    1718           0 :                             new RTFReferenceProperties(RTFSprms(), m_aStates.top().aFrame.getSprms()));
    1719           0 :                     Mapper().props(pFrameProperties);
    1720             :                 }
    1721             : 
    1722             :                 // Table width.
    1723          24 :                 RTFValue::Pointer_t pUnitValue(new RTFValue(3));
    1724          24 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    1725          48 :                         NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue);
    1726          24 :                 RTFValue::Pointer_t pWValue(new RTFValue(m_aStates.top().nCellX));
    1727          24 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    1728          48 :                         NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue);
    1729             : 
    1730          24 :                 RTFValue::Pointer_t pRowValue(new RTFValue(1));
    1731          24 :                 if (m_aStates.top().nCells > 0)
    1732          24 :                     m_aStates.top().aTableRowSprms.set(NS_sprm::LN_PRow, pRowValue);
    1733             : 
    1734          24 :                 RTFValue::Pointer_t pCellMar = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblCellMar);
    1735          24 :                 if (!pCellMar.get())
    1736             :                 {
    1737             :                     // If no cell margins are defined, the default left/right margin is 0 in Word, but not in Writer.
    1738          24 :                     RTFSprms aAttributes;
    1739          24 :                     aAttributes.set(NS_ooxml::LN_CT_TblWidth_type, RTFValue::Pointer_t(new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)));
    1740          24 :                     aAttributes.set(NS_ooxml::LN_CT_TblWidth_w, RTFValue::Pointer_t(new RTFValue(0)));
    1741          24 :                     lcl_putNestedSprm(m_aStates.top().aTableRowSprms,
    1742             :                             NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_left,
    1743          48 :                             RTFValue::Pointer_t(new RTFValue(aAttributes)));
    1744          24 :                     lcl_putNestedSprm(m_aStates.top().aTableRowSprms,
    1745             :                             NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right,
    1746          48 :                             RTFValue::Pointer_t(new RTFValue(aAttributes)));
    1747             :                 }
    1748             : 
    1749             :                 writerfilter::Reference<Properties>::Pointer_t const pTableRowProperties(
    1750          72 :                         new RTFReferenceProperties(m_aStates.top().aTableRowAttributes, m_aStates.top().aTableRowSprms)
    1751          72 :                         );
    1752          24 :                 Mapper().props(pTableRowProperties);
    1753             : 
    1754          24 :                 tableBreak();
    1755          24 :                 m_bNeedPap = true;
    1756          24 :                 m_bNeedFinalPar = true;
    1757          24 :                 m_aTableBuffer.clear();
    1758          24 :                 m_aStates.top().nCells = 0;
    1759          24 :                 m_aStates.top().aTableCellsSprms.clear();
    1760          24 :                 m_aStates.top().aTableCellsAttributes.clear();
    1761             :             }
    1762          24 :             break;
    1763             :         case RTF_COLUMN:
    1764             :             {
    1765           1 :                 bool bColumns = false; // If we have multiple columns
    1766           1 :                 RTFValue::Pointer_t pCols = m_aStates.top().aSectionSprms.find(NS_ooxml::LN_EG_SectPrContents_cols);
    1767           1 :                 if (pCols.get())
    1768             :                 {
    1769           0 :                     RTFValue::Pointer_t pNum = pCols->getAttributes().find(NS_ooxml::LN_CT_Columns_num);
    1770           0 :                     if (pNum.get() && pNum->getInt() > 1)
    1771           0 :                         bColumns = true;
    1772             :                 }
    1773           1 :                 if (bColumns)
    1774             :                 {
    1775           0 :                     sal_uInt8 sBreak[] = { 0xe };
    1776           0 :                     Mapper().startCharacterGroup();
    1777           0 :                     Mapper().text(sBreak, 1);
    1778           0 :                     Mapper().endCharacterGroup();
    1779             :                 }
    1780             :                 else
    1781           1 :                     dispatchSymbol(RTF_PAGE);
    1782             :             }
    1783           1 :             break;
    1784             :         case RTF_CHFTN:
    1785             :             // Nothing to do, dmapper assumes this is the default.
    1786           6 :             break;
    1787             :         case RTF_PAGE:
    1788             :             {
    1789             :                 // If we're inside a continous section, we should send a section break, not a page one.
    1790          55 :                 RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc);
    1791          55 :                 if (pBreak.get() && !pBreak->getInt())
    1792             :                 {
    1793           2 :                     if (m_bWasInFrame)
    1794             :                     {
    1795           2 :                         dispatchSymbol(RTF_PAR);
    1796           2 :                         m_bWasInFrame = false;
    1797             :                     }
    1798           2 :                     dispatchFlag(RTF_SBKPAGE);
    1799           2 :                     sectBreak();
    1800           2 :                     dispatchFlag(RTF_SBKNONE);
    1801           2 :                     if (m_bNeedPar)
    1802           2 :                         dispatchSymbol(RTF_PAR);
    1803           2 :                     m_bIgnoreNextContSectBreak = true;
    1804             :                 }
    1805             :                 else
    1806             :                 {
    1807          53 :                     sal_uInt8 sBreak[] = { 0xc };
    1808          53 :                     Mapper().text(sBreak, 1);
    1809          53 :                     if (!m_bNeedPap)
    1810          50 :                         parBreak();
    1811          55 :                 }
    1812             :             }
    1813          55 :             break;
    1814             :         case RTF_CHPGN:
    1815             :             {
    1816           2 :                 OUString aStr("PAGE");
    1817           2 :                 singleChar(0x13);
    1818           2 :                 text(aStr);
    1819           2 :                 singleChar(0x14, true);
    1820           2 :                 singleChar(0x15);
    1821             :             }
    1822           2 :             break;
    1823             :         default:
    1824             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle symbol '" << lcl_RtfToString(nKeyword) << "'");
    1825           2 :             aSkip.setParsed(false);
    1826           2 :             break;
    1827             :     }
    1828       23929 :     return 0;
    1829             : }
    1830             : 
    1831        8592 : int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
    1832             : {
    1833        8592 :     checkUnicode();
    1834        8592 :     setNeedSect();
    1835        8592 :     RTFSkipDestination aSkip(*this);
    1836        8592 :     int nParam = -1;
    1837        8592 :     int nSprm = -1;
    1838             : 
    1839             :     // Map all underline flags to a single sprm.
    1840        8592 :     switch (nKeyword)
    1841             :     {
    1842           0 :         case RTF_ULD: nSprm = 4; break;
    1843           0 :         case RTF_ULW: nSprm = 2; break;
    1844        8592 :         default: break;
    1845             :     }
    1846        8592 :     if (nSprm >= 0)
    1847             :     {
    1848           0 :         RTFValue::Pointer_t pValue(new RTFValue(nSprm));
    1849           0 :         m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
    1850           0 :         return 0;
    1851             :     }
    1852             : 
    1853             :     // Indentation
    1854        8592 :     switch (nKeyword)
    1855             :     {
    1856          10 :         case RTF_QC: nParam = 1; break;
    1857           3 :         case RTF_QJ: nParam = 3; break;
    1858          75 :         case RTF_QL: nParam = 0; break;
    1859          13 :         case RTF_QR: nParam = 2; break;
    1860           0 :         case RTF_QD: nParam = 4; break;
    1861        8491 :         default: break;
    1862             :     }
    1863        8592 :     if (nParam >= 0)
    1864             :     {
    1865         101 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1866         101 :         m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PJc, pValue);
    1867         101 :         return 0;
    1868             :     }
    1869             : 
    1870             :     // Font Alignment
    1871        8491 :     switch (nKeyword)
    1872             :     {
    1873             :         case RTF_FAFIXED:
    1874          84 :         case RTF_FAAUTO: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_auto; break;
    1875           0 :         case RTF_FAHANG: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_top; break;
    1876           0 :         case RTF_FACENTER: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_center; break;
    1877           0 :         case RTF_FAROMAN: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_baseline; break;
    1878           0 :         case RTF_FAVAR: nParam = NS_ooxml::LN_Value_wordprocessingml_ST_TextAlignment_bottom; break;
    1879        8407 :         default: break;
    1880             :     }
    1881        8491 :     if (nParam >= 0)
    1882             :     {
    1883          84 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1884          84 :         m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PWAlignFont, pValue);
    1885          84 :         return 0;
    1886             :     }
    1887             : 
    1888             :     // Tab kind.
    1889        8407 :     switch (nKeyword)
    1890             :     {
    1891           2 :         case RTF_TQR: nParam = 2; break;
    1892           0 :         case RTF_TQC: nParam = 1; break;
    1893           0 :         case RTF_TQDEC: nParam = 3; break;
    1894        8405 :         default: break;
    1895             :     }
    1896        8407 :     if (nParam >= 0)
    1897             :     {
    1898           2 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1899           2 :         m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_val, pValue);
    1900           2 :         return 0;
    1901             :     }
    1902             : 
    1903             :     // Tab lead.
    1904        8405 :     switch (nKeyword)
    1905             :     {
    1906           0 :         case RTF_TLDOT: nParam = 1; break;
    1907           0 :         case RTF_TLMDOT: nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot; break;
    1908           0 :         case RTF_TLHYPH: nParam = 2; break;
    1909           0 :         case RTF_TLUL: nParam = 3; break;
    1910           0 :         case RTF_TLTH: nParam = 2; break; // thick line is not supported by dmapper, this is just a hack
    1911           0 :         case RTF_TLEQ: nParam = 0; break; // equal sign isn't, either
    1912        8405 :         default: break;
    1913             :     }
    1914        8405 :     if (nParam >= 0)
    1915             :     {
    1916           0 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1917           0 :         m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_leader, pValue);
    1918           0 :         return 0;
    1919             :     }
    1920             : 
    1921             :     // Border types
    1922             :     {
    1923        8405 :         switch (nKeyword)
    1924             :         {
    1925             :             // brdrhair and brdrs are the same, brdrw will make a difference
    1926             :             // map to values in ooxml/model.xml resource ST_Border
    1927           3 :             case RTF_BRDRHAIR: nParam = 5; break;
    1928          21 :             case RTF_BRDRS: nParam = 1; break;
    1929           0 :             case RTF_BRDRDOT: nParam = 6; break;
    1930           0 :             case RTF_BRDRDASH: nParam = 7; break;
    1931          17 :             case RTF_BRDRDB: nParam = 3; break;
    1932           0 :             case RTF_BRDRTNTHSG: nParam = 11; break;
    1933           0 :             case RTF_BRDRTNTHMG: nParam = 14; break;
    1934           0 :             case RTF_BRDRTNTHLG: nParam = 17; break;
    1935          10 :             case RTF_BRDRTHTNSG: nParam = 12; break;
    1936          20 :             case RTF_BRDRTHTNMG: nParam = 15; break;
    1937          18 :             case RTF_BRDRTHTNLG: nParam = 18; break;
    1938          12 :             case RTF_BRDREMBOSS: nParam = 24; break;
    1939          12 :             case RTF_BRDRENGRAVE: nParam = 25; break;
    1940          22 :             case RTF_BRDROUTSET: nParam = 18; break;
    1941          20 :             case RTF_BRDRINSET: nParam = 17; break;
    1942          48 :             case RTF_BRDRNONE: nParam = 0; break;
    1943        8202 :             default: break;
    1944             :         }
    1945        8405 :         if (nParam >= 0)
    1946             :         {
    1947         203 :             RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1948         203 :             lcl_putBorderProperty(m_aStates, NS_rtf::LN_BRCTYPE, pValue);
    1949         203 :             return 0;
    1950             :         }
    1951             :     }
    1952             : 
    1953             :     // Section breaks
    1954        8202 :     switch (nKeyword)
    1955             :     {
    1956          41 :         case RTF_SBKNONE: nParam = 0; break;
    1957           0 :         case RTF_SBKCOL: nParam = 1; break;
    1958           3 :         case RTF_SBKPAGE: nParam = 2; break;
    1959           0 :         case RTF_SBKEVEN: nParam = 3; break;
    1960           0 :         case RTF_SBKODD: nParam = 4; break;
    1961        8158 :         default: break;
    1962             :     }
    1963        8202 :     if (nParam >= 0)
    1964             :     {
    1965          44 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1966          44 :         m_aStates.top().aSectionSprms.set(NS_sprm::LN_SBkc, pValue);
    1967          44 :         return 0;
    1968             :     }
    1969             : 
    1970             :     // Footnote numbering
    1971        8158 :     switch (nKeyword)
    1972             :     {
    1973          33 :         case RTF_FTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break;
    1974           0 :         case RTF_FTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break;
    1975           0 :         case RTF_FTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break;
    1976           0 :         case RTF_FTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break;
    1977           0 :         case RTF_FTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break;
    1978           0 :         case RTF_FTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break;
    1979        8125 :         default: break;
    1980             :     }
    1981        8158 :     if (nParam >= 0)
    1982             :     {
    1983          33 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1984          33 :         lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, pValue);
    1985          33 :         return 0;
    1986             :     }
    1987             : 
    1988             :     // Footnote restart type
    1989        8125 :     switch (nKeyword)
    1990             :     {
    1991           0 :         case RTF_FTNRSTPG: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage; break;
    1992           0 :         case RTF_FTNRESTART: nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect; break;
    1993          31 :         case RTF_FTNRSTCONT: nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous; break;
    1994        8094 :         default: break;
    1995             :     }
    1996        8125 :     if (nParam >= 0)
    1997             :     {
    1998          31 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    1999          31 :         lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
    2000          31 :         return 0;
    2001             :     }
    2002             : 
    2003             :     // Endnote numbering
    2004        8094 :     switch (nKeyword)
    2005             :     {
    2006           3 :         case RTF_AFTNNAR: nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; break;
    2007           0 :         case RTF_AFTNNALC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; break;
    2008           0 :         case RTF_AFTNNAUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; break;
    2009          31 :         case RTF_AFTNNRLC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; break;
    2010           0 :         case RTF_AFTNNRUC: nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; break;
    2011           0 :         case RTF_AFTNNCHI: nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; break;
    2012        8060 :         default: break;
    2013             :     }
    2014        8094 :     if (nParam >= 0)
    2015             :     {
    2016          34 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2017          34 :         lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_CT_EdnProps_numFmt, pValue);
    2018          34 :         return 0;
    2019             :     }
    2020             : 
    2021             :     // Cell Text Flow
    2022        8060 :     switch (nKeyword)
    2023             :     {
    2024         118 :         case RTF_CLTXLRTB:  nParam = 0; break;
    2025           0 :         case RTF_CLTXTBRL:  nParam = 1; break;
    2026           0 :         case RTF_CLTXBTLR:  nParam = 3; break;
    2027           0 :         case RTF_CLTXLRTBV: nParam = 4; break;
    2028           0 :         case RTF_CLTXTBRLV: nParam = 5; break;
    2029        7942 :         default: break;
    2030             :     }
    2031        8060 :     if (nParam >= 0)
    2032             :     {
    2033         118 :         RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2034         118 :         m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue);
    2035             :     }
    2036             : 
    2037             :     // Trivial paragraph flags
    2038        8060 :     switch (nKeyword)
    2039             :     {
    2040           0 :         case RTF_KEEP: if (m_pCurrentBuffer != &m_aTableBuffer) nParam = NS_sprm::LN_PFKeep; break;
    2041          39 :         case RTF_KEEPN: if (m_pCurrentBuffer != &m_aTableBuffer) nParam = NS_sprm::LN_PFKeepFollow; break;
    2042         223 :         case RTF_INTBL: m_pCurrentBuffer = &m_aTableBuffer; nParam = NS_sprm::LN_PFInTable; break;
    2043           2 :         case RTF_PAGEBB: nParam = NS_sprm::LN_PFPageBreakBefore; break;
    2044        7796 :         default: break;
    2045             :     }
    2046        8060 :     if (nParam >= 0)
    2047             :     {
    2048         373 :         RTFValue::Pointer_t pValue(new RTFValue(1));
    2049         373 :         m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PFInTable);
    2050         373 :         m_aStates.top().aParagraphSprms.set(nParam, pValue);
    2051         373 :         return 0;
    2052             :     }
    2053             : 
    2054        7687 :     switch (nKeyword)
    2055             :     {
    2056             :         case RTF_FNIL:
    2057             :         case RTF_FROMAN:
    2058             :         case RTF_FSWISS:
    2059             :         case RTF_FMODERN:
    2060             :         case RTF_FSCRIPT:
    2061             :         case RTF_FDECOR:
    2062             :         case RTF_FTECH:
    2063             :         case RTF_FBIDI:
    2064             :             // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper
    2065         578 :             break;
    2066             :         case RTF_ANSI:
    2067          57 :             m_aStates.top().nCurrentEncoding = RTL_TEXTENCODING_MS_1252;
    2068          57 :             break;
    2069             :         case RTF_PLAIN:
    2070             :             {
    2071         159 :                 m_aStates.top().aCharacterSprms = getDefaultState().aCharacterSprms;
    2072         159 :                 RTFValue::Pointer_t pValue = m_aStates.top().aCharacterSprms.find(NS_sprm::LN_CRgFtc0);
    2073         159 :                 if (pValue.get())
    2074         137 :                     m_aStates.top().nCurrentEncoding = getEncoding(pValue->getInt());
    2075         159 :                 m_aStates.top().aCharacterAttributes = getDefaultState().aCharacterAttributes;
    2076             :             }
    2077         159 :             break;
    2078             :         case RTF_PARD:
    2079         219 :             if (m_bHadPicture)
    2080           3 :                 dispatchSymbol(RTF_PAR);
    2081         219 :             m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms;
    2082         219 :             m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes;
    2083         219 :             m_aStates.top().resetFrame();
    2084         219 :             if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT)
    2085         215 :                 m_pCurrentBuffer = 0;
    2086         219 :             break;
    2087             :         case RTF_SECTD:
    2088          46 :             m_aStates.top().aSectionSprms = m_aDefaultState.aSectionSprms;
    2089          46 :             m_aStates.top().aSectionAttributes = m_aDefaultState.aSectionAttributes;
    2090          46 :             break;
    2091             :         case RTF_TROWD:
    2092          35 :             m_aStates.top().aTableRowSprms = m_aDefaultState.aTableRowSprms;
    2093          35 :             m_aStates.top().aTableRowAttributes = m_aDefaultState.aTableRowAttributes;
    2094          35 :             m_aStates.top().nCellX = 0;
    2095             :             // In case the table definition is in the middle of the row
    2096             :             // (invalid), make sure table definition is emitted.
    2097          35 :             m_bNeedPap = true;
    2098          35 :             break;
    2099             :         case RTF_WIDCTLPAR:
    2100             :         case RTF_NOWIDCTLPAR:
    2101             :             {
    2102         212 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_WIDCTLPAR));
    2103         212 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFWidowControl, pValue);
    2104             :             }
    2105         212 :             break;
    2106             :         case RTF_BOX:
    2107             :             {
    2108           4 :                 RTFSprms aAttributes;
    2109           4 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes));
    2110          20 :                 for (int i = 0; i < 4; i++)
    2111          16 :                     m_aStates.top().aParagraphSprms.set(lcl_getParagraphBorder(i), pValue);
    2112           4 :                 m_aStates.top().nBorderState = BORDER_PARAGRAPH_BOX;
    2113             :             }
    2114           4 :             break;
    2115             :         case RTF_LTRSECT:
    2116             :         case RTF_RTLSECT:
    2117             :             {
    2118           8 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRSECT ? 0 : 1));
    2119           8 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_STextFlow, pValue);
    2120             :             }
    2121           8 :             break;
    2122             :         case RTF_LTRPAR:
    2123             :         case RTF_RTLPAR:
    2124             :             {
    2125          84 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRPAR ? 0 : 1));
    2126          84 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFrameTextFlow, pValue);
    2127             :             }
    2128          84 :             break;
    2129             :         case RTF_LTRROW:
    2130             :         case RTF_RTLROW:
    2131             :             {
    2132          37 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LTRROW ? 0 : 1));
    2133          37 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_TTextFlow, pValue);
    2134             :             }
    2135          37 :             break;
    2136             :         case RTF_LTRCH:
    2137             :             // dmapper does not support this.
    2138         762 :             break;
    2139             :         case RTF_RTLCH:
    2140         756 :             if (m_aDefaultState.nCurrentEncoding == RTL_TEXTENCODING_MS_1255)
    2141           1 :                 m_aStates.top().nCurrentEncoding = m_aDefaultState.nCurrentEncoding;
    2142         756 :             break;
    2143             :         case RTF_ULNONE:
    2144             :             {
    2145           0 :                 RTFValue::Pointer_t pValue(new RTFValue(0));
    2146           0 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
    2147             :             }
    2148           0 :             break;
    2149             :         case RTF_NONSHPPICT:
    2150             :         case RTF_MMATHPICT: // Picture group used by readers not understanding \moMath group
    2151           0 :             m_aStates.top().nDestinationState = DESTINATION_SKIP;
    2152           0 :             break;
    2153             :         case RTF_CLBRDRT:
    2154             :         case RTF_CLBRDRL:
    2155             :         case RTF_CLBRDRB:
    2156             :         case RTF_CLBRDRR:
    2157             :             {
    2158         476 :                 RTFSprms aAttributes;
    2159         476 :                 RTFSprms aSprms;
    2160         476 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    2161         476 :                 switch (nKeyword)
    2162             :                 {
    2163         119 :                     case RTF_CLBRDRT: nParam = NS_ooxml::LN_CT_TcBorders_top; break;
    2164         119 :                     case RTF_CLBRDRL: nParam = NS_ooxml::LN_CT_TcBorders_left; break;
    2165         119 :                     case RTF_CLBRDRB: nParam = NS_ooxml::LN_CT_TcBorders_bottom; break;
    2166         119 :                     case RTF_CLBRDRR: nParam = NS_ooxml::LN_CT_TcBorders_right; break;
    2167           0 :                     default: break;
    2168             :                 }
    2169         476 :                 lcl_putNestedSprm(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_tcBorders, nParam, pValue);
    2170         476 :                 m_aStates.top().nBorderState = BORDER_CELL;
    2171             :             }
    2172         476 :             break;
    2173             :         case RTF_PGBRDRT:
    2174             :         case RTF_PGBRDRL:
    2175             :         case RTF_PGBRDRB:
    2176             :         case RTF_PGBRDRR:
    2177             :             {
    2178           0 :                 RTFSprms aAttributes;
    2179           0 :                 RTFSprms aSprms;
    2180           0 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    2181           0 :                 switch (nKeyword)
    2182             :                 {
    2183           0 :                     case RTF_PGBRDRT: nParam = NS_ooxml::LN_CT_PageBorders_top; break;
    2184           0 :                     case RTF_PGBRDRL: nParam = NS_ooxml::LN_CT_PageBorders_left; break;
    2185           0 :                     case RTF_PGBRDRB: nParam = NS_ooxml::LN_CT_PageBorders_bottom; break;
    2186           0 :                     case RTF_PGBRDRR: nParam = NS_ooxml::LN_CT_PageBorders_right; break;
    2187           0 :                     default: break;
    2188             :                 }
    2189           0 :                 lcl_putNestedSprm(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgBorders, nParam, pValue);
    2190           0 :                 m_aStates.top().nBorderState = BORDER_PAGE;
    2191             :             }
    2192           0 :             break;
    2193             :         case RTF_BRDRT:
    2194             :         case RTF_BRDRL:
    2195             :         case RTF_BRDRB:
    2196             :         case RTF_BRDRR:
    2197             :             {
    2198           1 :                 RTFSprms aAttributes;
    2199           1 :                 RTFSprms aSprms;
    2200           1 :                 RTFValue::Pointer_t pValue(new RTFValue(aAttributes, aSprms));
    2201           1 :                 switch (nKeyword)
    2202             :                 {
    2203           0 :                     case RTF_BRDRT: nParam = lcl_getParagraphBorder(0); break;
    2204           0 :                     case RTF_BRDRL: nParam = lcl_getParagraphBorder(1); break;
    2205           1 :                     case RTF_BRDRB: nParam = lcl_getParagraphBorder(2); break;
    2206           0 :                     case RTF_BRDRR: nParam = lcl_getParagraphBorder(3); break;
    2207           0 :                     default: break;
    2208             :                 }
    2209           1 :                 lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PrBase_pBdr, nParam, pValue);
    2210           1 :                 m_aStates.top().nBorderState = BORDER_PARAGRAPH;
    2211             :             }
    2212           1 :             break;
    2213             :         case RTF_CLVMGF:
    2214             :             {
    2215           0 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
    2216           0 :                 m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
    2217             :             }
    2218           0 :             break;
    2219             :         case RTF_CLVMRG:
    2220             :             {
    2221           0 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue));
    2222           0 :                 m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue);
    2223             :             }
    2224           0 :             break;
    2225             :         case RTF_CLVERTALT:
    2226             :         case RTF_CLVERTALC:
    2227             :         case RTF_CLVERTALB:
    2228             :             {
    2229         151 :                 switch (nKeyword)
    2230             :                 {
    2231         151 :                     case RTF_CLVERTALT: nParam = 0; break;
    2232           0 :                     case RTF_CLVERTALC: nParam = 1; break;
    2233           0 :                     case RTF_CLVERTALB: nParam = 3; break;
    2234           0 :                     default: break;
    2235             :                 }
    2236         151 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2237         151 :                 m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue);
    2238             :             }
    2239         151 :             break;
    2240             :         case RTF_TRKEEP:
    2241             :             {
    2242           0 :                 RTFValue::Pointer_t pValue(new RTFValue(1));
    2243           0 :                 m_aStates.top().aTableRowSprms.set(NS_sprm::LN_TCantSplit, pValue);
    2244             :             }
    2245             :         case RTF_SECTUNLOCKED:
    2246             :             {
    2247          31 :                 RTFValue::Pointer_t pValue(new RTFValue(!nParam));
    2248          31 :                 m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue);
    2249             :             }
    2250             :         case RTF_PGNDEC:
    2251             :         case RTF_PGNUCRM:
    2252             :         case RTF_PGNLCRM:
    2253             :         case RTF_PGNUCLTR:
    2254             :         case RTF_PGNLCLTR:
    2255             :         case RTF_PGNBIDIA:
    2256             :         case RTF_PGNBIDIB:
    2257             :             // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment.
    2258          92 :             break;
    2259             :         case RTF_LOCH:
    2260             :             // Noop, dmapper detects this automatically.
    2261        1050 :             break;
    2262             :         case RTF_HICH:
    2263         744 :             m_aStates.top().bIsCjk = true;
    2264         744 :             break;
    2265             :         case RTF_DBCH:
    2266        1132 :             m_aStates.top().bIsCjk = false;
    2267        1132 :             break;
    2268             :         case RTF_TITLEPG:
    2269             :             {
    2270           6 :                 RTFValue::Pointer_t pValue(new RTFValue(1));
    2271           6 :                 m_aStates.top().aSectionSprms.set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue);
    2272             :             }
    2273           6 :             break;
    2274             :         case RTF_SUPER:
    2275             :             {
    2276           9 :                 if (!m_pCurrentBuffer)
    2277           9 :                     m_pCurrentBuffer = &m_aSuperBuffer;
    2278           9 :                 RTFValue::Pointer_t pValue(new RTFValue("superscript"));
    2279           9 :                 m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
    2280             :             }
    2281           9 :             break;
    2282             :         case RTF_SUB:
    2283             :             {
    2284           0 :                 RTFValue::Pointer_t pValue(new RTFValue("subscript"));
    2285           0 :                 m_aStates.top().aCharacterSprms.set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue);
    2286             :             }
    2287           0 :             break;
    2288             :         case RTF_NOSUPERSUB:
    2289           1 :             if (m_pCurrentBuffer == &m_aSuperBuffer)
    2290             :             {
    2291           1 :                 replayBuffer(m_aSuperBuffer);
    2292           1 :                 m_pCurrentBuffer = 0;
    2293             :             }
    2294           1 :             m_aStates.top().aCharacterSprms.erase(NS_ooxml::LN_EG_RPrBase_vertAlign);
    2295           1 :             break;
    2296             :         case RTF_LINEPPAGE:
    2297             :         case RTF_LINECONT:
    2298             :             {
    2299           0 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_LINEPPAGE ? 0 : 2));
    2300           0 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    2301           0 :                         NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_restart, pValue);
    2302             :             }
    2303           0 :             break;
    2304             :         case RTF_AENDDOC:
    2305             :             // Noop, this is the default in Writer.
    2306          38 :             break;
    2307             :         case RTF_AENDNOTES:
    2308             :             // Noop, Writer does not support having endnotes at the end of section.
    2309           0 :             break;
    2310             :         case RTF_AFTNRSTCONT:
    2311             :             // Noop, this is the default in Writer.
    2312          31 :             break;
    2313             :         case RTF_AFTNRESTART:
    2314             :             // Noop, Writer does not support restarting endnotes at each section.
    2315           0 :             break;
    2316             :         case RTF_FTNBJ:
    2317             :             // Noop, this is the default in Writer.
    2318          42 :             break;
    2319             :         case RTF_ENDDOC:
    2320             :             {
    2321           0 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_ST_RestartNumber_eachSect));
    2322           0 :                 lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue);
    2323             :             }
    2324           0 :             break;
    2325             :         case RTF_NOLINE:
    2326          64 :             lcl_eraseNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance);
    2327          64 :             break;
    2328             :         case RTF_FORMSHADE:
    2329             :             // Noop, this is the default in Writer.
    2330          33 :             break;
    2331             :         case RTF_PNGBLIP:
    2332           5 :             m_aStates.top().aPicture.nStyle = BMPSTYLE_PNG;
    2333           5 :             break;
    2334             :         case RTF_JPEGBLIP:
    2335           1 :             m_aStates.top().aPicture.nStyle = BMPSTYLE_JPEG;
    2336           1 :             break;
    2337           2 :         case RTF_POSYT: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_top); break;
    2338           0 :         case RTF_POSYB: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_bottom); break;
    2339           0 :         case RTF_POSYC: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_center); break;
    2340           0 :         case RTF_POSYIN: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inside); break;
    2341           0 :         case RTF_POSYOUT: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_outside); break;
    2342           0 :         case RTF_POSYIL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, NS_ooxml::LN_Value_wordprocessingml_ST_YAlign_inline); break;
    2343             : 
    2344           1 :         case RTF_PHMRG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin); break;
    2345           0 :         case RTF_PVMRG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin); break;
    2346           8 :         case RTF_PHPG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_page); break;
    2347          10 :         case RTF_PVPG: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_page); break;
    2348           3 :         case RTF_PHCOL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_text); break;
    2349           3 :         case RTF_PVPARA: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_text); break;
    2350             : 
    2351           2 :         case RTF_POSXC: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_center); break;
    2352           0 :         case RTF_POSXI: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_inside); break;
    2353           0 :         case RTF_POSXO: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_outside); break;
    2354           0 :         case RTF_POSXL: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_left); break;
    2355           0 :         case RTF_POSXR: m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, NS_ooxml::LN_Value_wordprocessingml_ST_XAlign_right); break;
    2356             : 
    2357             :         case RTF_DPLINE:
    2358             :         case RTF_DPRECT:
    2359             :         case RTF_DPELLIPSE:
    2360             :         case RTF_DPTXBX:
    2361             :         case RTF_DPPOLYLINE:
    2362             :                 {
    2363          10 :                     sal_Int32 nType = 0;
    2364          10 :                     switch (nKeyword)
    2365             :                     {
    2366             :                         case RTF_DPLINE:
    2367           1 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.LineShape"), uno::UNO_QUERY);
    2368           1 :                             break;
    2369             :                         case RTF_DPPOLYLINE:
    2370             :                             // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info.
    2371           4 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"), uno::UNO_QUERY);
    2372           4 :                             break;
    2373             :                         case RTF_DPRECT:
    2374           3 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
    2375           3 :                             break;
    2376             :                         case RTF_DPELLIPSE:
    2377           0 :                             nType = ESCHER_ShpInst_Ellipse;
    2378           0 :                             break;
    2379             :                         case RTF_DPTXBX:
    2380             :                             {
    2381           2 :                                 m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.text.TextFrame"), uno::UNO_QUERY);
    2382             :                                 // These are the default in Word, but not in Writer
    2383           2 :                                 beans::PropertyValue aPropertyValue;
    2384           2 :                                 aPropertyValue.Name = "HoriOrient";
    2385           2 :                                 aPropertyValue.Value <<= text::HoriOrientation::NONE;
    2386           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2387           2 :                                 aPropertyValue.Name = "VertOrient";
    2388           2 :                                 aPropertyValue.Value <<= text::VertOrientation::NONE;
    2389           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2390           2 :                                 aPropertyValue.Name = "BackColorTransparency";
    2391           2 :                                 aPropertyValue.Value <<= sal_Int32(100);
    2392           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2393           2 :                                 aPropertyValue.Name = "LeftBorderDistance";
    2394           2 :                                 aPropertyValue.Value <<= sal_Int32(0);
    2395           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2396           2 :                                 aPropertyValue.Name = "RightBorderDistance";
    2397           2 :                                 aPropertyValue.Value <<= sal_Int32(0);
    2398           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2399           2 :                                 aPropertyValue.Name = "TopBorderDistance";
    2400           2 :                                 aPropertyValue.Value <<= sal_Int32(0);
    2401           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2402           2 :                                 aPropertyValue.Name = "BottomBorderDistance";
    2403           2 :                                 aPropertyValue.Value <<= sal_Int32(0);
    2404           2 :                                 m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2405             :                             }
    2406           2 :                             break;
    2407             :                         default:
    2408           0 :                             break;
    2409             :                     }
    2410          10 :                     if (nType)
    2411           0 :                             m_aStates.top().aDrawingObject.xShape.set(getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"), uno::UNO_QUERY);
    2412          10 :                     uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier( m_xDstDoc, uno::UNO_QUERY);
    2413          10 :                     if (xDrawSupplier.is())
    2414             :                     {
    2415          10 :                         uno::Reference<drawing::XShapes> xShapes(xDrawSupplier->getDrawPage(), uno::UNO_QUERY);
    2416          10 :                         if (xShapes.is() && nKeyword != RTF_DPTXBX)
    2417           8 :                             xShapes->add(m_aStates.top().aDrawingObject.xShape);
    2418             :                     }
    2419          10 :                     if (nType)
    2420             :                     {
    2421           0 :                             uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
    2422           0 :                             xDefaulter->createCustomShapeDefaults(OUString::valueOf(nType));
    2423             :                     }
    2424          10 :                     m_aStates.top().aDrawingObject.xPropertySet.set(m_aStates.top().aDrawingObject.xShape, uno::UNO_QUERY);
    2425          10 :                     std::vector<beans::PropertyValue>& rPendingProperties = m_aStates.top().aDrawingObject.aPendingProperties;
    2426          41 :                     for (std::vector<beans::PropertyValue>::iterator i = rPendingProperties.begin(); i != rPendingProperties.end(); ++i)
    2427          31 :                         m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue(i->Name, i->Value);
    2428          10 :                     m_pSdrImport->resolveDhgt(m_aStates.top().aDrawingObject.xPropertySet, m_aStates.top().aDrawingObject.nDhgt);
    2429             :                 }
    2430          10 :                 break;
    2431             :         case RTF_DOBXMARGIN:
    2432             :         case RTF_DOBYMARGIN:
    2433             :                 {
    2434           1 :                     beans::PropertyValue aPropertyValue;
    2435           1 :                     aPropertyValue.Name = (nKeyword == RTF_DOBXMARGIN ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
    2436           1 :                     aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA;
    2437           1 :                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2438             :                 }
    2439           1 :                 break;
    2440             :         case RTF_DOBXPAGE:
    2441             :         case RTF_DOBYPAGE:
    2442             :                 {
    2443           7 :                     beans::PropertyValue aPropertyValue;
    2444           7 :                     aPropertyValue.Name = (nKeyword == RTF_DOBXPAGE ? OUString("HoriOrientRelation") : OUString("VertOrientRelation"));
    2445           7 :                     aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME;
    2446           7 :                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2447             :                 }
    2448           7 :                 break;
    2449             :         case RTF_DOBYPARA:
    2450             :                 {
    2451           9 :                     beans::PropertyValue aPropertyValue;
    2452           9 :                     aPropertyValue.Name = OUString("VertOrientRelation");
    2453           9 :                     aPropertyValue.Value <<= text::RelOrientation::FRAME;
    2454           9 :                     m_aStates.top().aDrawingObject.aPendingProperties.push_back(aPropertyValue);
    2455             :                 }
    2456           9 :                 break;
    2457             :         case RTF_CONTEXTUALSPACE:
    2458             :                 {
    2459           2 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    2460           2 :                     m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PContextualSpacing, pValue);
    2461             :                 }
    2462           2 :                 break;
    2463             :         case RTF_LINKSTYLES:
    2464             :                 {
    2465           1 :                     RTFValue::Pointer_t pValue(new RTFValue(1));
    2466           1 :                     m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue);
    2467             :                 }
    2468           1 :                 break;
    2469             :         case RTF_PNLVLBODY:
    2470             :                 {
    2471           3 :                     RTFValue::Pointer_t pValue(new RTFValue(2));
    2472           3 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, pValue);
    2473             :                 }
    2474           3 :                 break;
    2475             :         case RTF_PNDEC:
    2476             :                 {
    2477           3 :                     RTFValue::Pointer_t pValue(new RTFValue(0)); // decimal, same as \levelnfc0
    2478           3 :                     m_aStates.top().aTableSprms.set(NS_rtf::LN_NFC, pValue);
    2479             :                 }
    2480           3 :                 break;
    2481             :         case RTF_PNLVLBLT:
    2482             :                 {
    2483           1 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, RTFValue::Pointer_t(new RTFValue(1)));
    2484           1 :                     m_aStates.top().aTableSprms.set(NS_rtf::LN_NFC, RTFValue::Pointer_t(new RTFValue(23))); // bullets, same as \levelnfc23
    2485             :                 }
    2486           1 :                 break;
    2487             :         case RTF_LANDSCAPE:
    2488           3 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, RTFValue::Pointer_t(new RTFValue(1)));
    2489           3 :                 break;
    2490             :         case RTF_FACINGP:
    2491           2 :                 m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_evenAndOddHeaders, RTFValue::Pointer_t(new RTFValue(1)));
    2492           2 :                 break;
    2493             :         case RTF_SHPBXPAGE:
    2494           7 :                 m_aStates.top().aShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
    2495           7 :                 break;
    2496             :         case RTF_SHPBYPAGE:
    2497           6 :                 m_aStates.top().aShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
    2498           6 :                 break;
    2499             :         case RTF_DPLINEHOLLOW:
    2500           2 :                 m_aStates.top().aDrawingObject.nFLine = 0;
    2501           2 :                 break;
    2502             :         case RTF_DPROUNDR:
    2503           0 :                 if (m_aStates.top().aDrawingObject.xPropertySet.is())
    2504             :                     // Seems this old syntax has no way to specify a custom radius, and this is the default
    2505           0 :                     m_aStates.top().aDrawingObject.xPropertySet->setPropertyValue("CornerRadius", uno::makeAny(sal_Int32(83)));
    2506           0 :                 break;
    2507             :         default:
    2508             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle flag '" << lcl_RtfToString(nKeyword) << "'");
    2509         768 :             aSkip.setParsed(false);
    2510         768 :             break;
    2511             :     }
    2512        7687 :     return 0;
    2513             : }
    2514             : 
    2515       14421 : int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
    2516             : {
    2517       14421 :     checkUnicode(nKeyword != RTF_U, true);
    2518       14421 :     setNeedSect();
    2519       14421 :     RTFSkipDestination aSkip(*this);
    2520       14421 :     int nSprm = 0;
    2521       14421 :     RTFValue::Pointer_t pIntValue(new RTFValue(nParam));
    2522             :     // Trivial table sprms.
    2523       14421 :     switch (nKeyword)
    2524             :     {
    2525         453 :         case RTF_FPRQ: nSprm = NS_rtf::LN_PRQ; break;
    2526           6 :         case RTF_LEVELJC: nSprm = NS_ooxml::LN_CT_Lvl_lvlJc; break;
    2527          10 :         case RTF_LEVELNFC: nSprm = NS_rtf::LN_NFC; break;
    2528          10 :         case RTF_LEVELSTARTAT: nSprm = NS_rtf::LN_ISTARTAT; break;
    2529       13942 :         default: break;
    2530             :     }
    2531       14421 :     if (nSprm > 0)
    2532             :     {
    2533         479 :         m_aStates.top().aTableSprms.set(nSprm, pIntValue);
    2534         479 :         return 0;
    2535             :     }
    2536             :     // Trivial character sprms.
    2537       13942 :     switch (nKeyword)
    2538             :     {
    2539        2854 :         case RTF_AF: nSprm = (m_aStates.top().bIsCjk ? NS_sprm::LN_CRgFtc1 : NS_sprm::LN_CRgFtc2); break;
    2540         312 :         case RTF_FS: nSprm = NS_sprm::LN_CHps; break;
    2541         256 :         case RTF_AFS: nSprm = NS_sprm::LN_CHpsBi; break;
    2542           0 :         case RTF_ANIMTEXT: nSprm = NS_sprm::LN_CSfxText; break;
    2543           0 :         case RTF_EXPNDTW: nSprm = NS_sprm::LN_CDxaSpace; break;
    2544         129 :         case RTF_KERNING: nSprm = NS_sprm::LN_CHpsKern; break;
    2545           0 :         case RTF_CHARSCALEX: nSprm = NS_sprm::LN_CCharScale; break;
    2546         236 :         case RTF_LANG: nSprm = NS_sprm::LN_CRgLid0; break;
    2547         221 :         case RTF_LANGFE: nSprm = NS_sprm::LN_CRgLid1; break;
    2548         182 :         case RTF_ALANG: nSprm = NS_sprm::LN_CLidBi; break;
    2549        9752 :         default: break;
    2550             :     }
    2551       13942 :     if (nSprm > 0)
    2552             :     {
    2553        4190 :         m_aStates.top().aCharacterSprms.set(nSprm, pIntValue);
    2554             :         // Language is a character property, but we should store it at a paragraph level as well for fields.
    2555        4190 :         if (nKeyword == RTF_LANG && m_bNeedPap)
    2556         234 :             m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
    2557        4190 :         return 0;
    2558             :     }
    2559             :     // Trivial paragraph sprms.
    2560        9752 :     switch (nKeyword)
    2561             :     {
    2562         103 :         case RTF_FI: nSprm = NS_sprm::LN_PDxaLeft1; break;
    2563          93 :         case RTF_LIN: nSprm = 0x845e; break;
    2564          89 :         case RTF_RI: nSprm = NS_sprm::LN_PDxaRight; break;
    2565          88 :         case RTF_RIN: nSprm = 0x845d; break;
    2566          31 :         case RTF_ITAP: nSprm = NS_sprm::LN_PTableDepth; break;
    2567        9348 :         default: break;
    2568             :     }
    2569        9752 :     if (nSprm > 0)
    2570             :     {
    2571         404 :         m_aStates.top().aParagraphSprms.set(nSprm, pIntValue);
    2572         404 :         if (nKeyword == RTF_ITAP && nParam > 0)
    2573             :             // Invalid tables may omit INTBL after ITAP
    2574           0 :             dispatchFlag(RTF_INTBL);
    2575         404 :         return 0;
    2576             :     }
    2577             : 
    2578             :     // Trivial table attributes.
    2579        9348 :     switch (nKeyword)
    2580             :     {
    2581         201 :         case RTF_SBASEDON: nSprm = NS_rtf::LN_ISTDBASE; break;
    2582         227 :         case RTF_SNEXT: nSprm = NS_rtf::LN_ISTDNEXT; break;
    2583        8920 :         default: break;
    2584             :     }
    2585        9348 :     if (nSprm > 0)
    2586             :     {
    2587         428 :         m_aStates.top().aTableAttributes.set(nSprm, pIntValue);
    2588         428 :         return 0;
    2589             :     }
    2590             : 
    2591             :     // Info group.
    2592        8920 :     switch (nKeyword)
    2593             :     {
    2594          94 :         case RTF_YR: m_aStates.top().nYear = nParam; nSprm = 1; break;
    2595          94 :         case RTF_MO: m_aStates.top().nMonth = nParam; nSprm = 1; break;
    2596          94 :         case RTF_DY: m_aStates.top().nDay = nParam; nSprm = 1; break;
    2597          94 :         case RTF_HR: m_aStates.top().nHour = nParam; nSprm = 1; break;
    2598          94 :         case RTF_MIN: m_aStates.top().nMinute = nParam; nSprm = 1; break;
    2599        8450 :         default: break;
    2600             :     }
    2601        8920 :     if (nSprm > 0)
    2602         470 :         return 0;
    2603             : 
    2604             :     // Frame size / position.
    2605        8450 :     Id nId = 0;
    2606        8450 :     switch (nKeyword)
    2607             :     {
    2608          14 :         case RTF_ABSW: nId = NS_sprm::LN_PDxaWidth; break;
    2609          14 :         case RTF_ABSH: nId = NS_sprm::LN_PWHeightAbs; break;
    2610          12 :         case RTF_POSX: nId = NS_ooxml::LN_CT_FramePr_x; m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, 0); break;
    2611          12 :         case RTF_POSY: nId = NS_ooxml::LN_CT_FramePr_y; m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, 0); break;
    2612        8398 :         default: break;
    2613             :     }
    2614        8450 :     if (nId > 0)
    2615             :     {
    2616          52 :         m_bNeedPap = true;
    2617             :         // Don't try to support text frames inside tables for now.
    2618          52 :         if (m_pCurrentBuffer != &m_aTableBuffer)
    2619          52 :             m_aStates.top().aFrame.setSprm(nId, nParam);
    2620          52 :         return 0;
    2621             :     }
    2622             : 
    2623             :     // Then check for the more complex ones.
    2624        8398 :     switch (nKeyword)
    2625             :     {
    2626             :         case RTF_F:
    2627        1466 :             if (m_aStates.top().nDestinationState == DESTINATION_FONTTABLE || m_aStates.top().nDestinationState == DESTINATION_FONTENTRY)
    2628             :             {
    2629         467 :                 m_aFontIndexes.push_back(nParam);
    2630         467 :                 m_nCurrentFontIndex = getFontIndex(nParam);
    2631             :             }
    2632             :             else
    2633             :             {
    2634         999 :                 int nFontIndex = getFontIndex(nParam);
    2635         999 :                 RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
    2636         999 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CRgFtc0, pValue);
    2637         999 :                 m_aStates.top().nCurrentEncoding = getEncoding(nFontIndex);
    2638             :             }
    2639        1466 :             break;
    2640             :         case RTF_RED:
    2641         124 :             m_aStates.top().aCurrentColor.nRed = nParam;
    2642         124 :             break;
    2643             :         case RTF_GREEN:
    2644         124 :             m_aStates.top().aCurrentColor.nGreen = nParam;
    2645         124 :             break;
    2646             :         case RTF_BLUE:
    2647         124 :             m_aStates.top().aCurrentColor.nBlue = nParam;
    2648         124 :             break;
    2649             :         case RTF_FCHARSET:
    2650             :             {
    2651             :                 // we always send text to the domain mapper in OUString, so no
    2652             :                 // need to send encoding info
    2653             :                 int i;
    2654        4215 :                 for (i = 0; i < nRTFEncodings; i++)
    2655             :                 {
    2656        4215 :                     if (aRTFEncodings[i].charset == nParam)
    2657         462 :                         break;
    2658             :                 }
    2659         462 :                 if (i == nRTFEncodings)
    2660             :                     // not found
    2661           0 :                     return 0;
    2662         462 :                 m_aFontEncodings[m_nCurrentFontIndex] = rtl_getTextEncodingFromWindowsCodePage(aRTFEncodings[i].codepage);
    2663             :             }
    2664         462 :             break;
    2665             :         case RTF_ANSICPG:
    2666          15 :             m_aDefaultState.nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
    2667          15 :             m_aStates.top().nCurrentEncoding = rtl_getTextEncodingFromWindowsCodePage(nParam);
    2668          15 :             break;
    2669             :         case RTF_CPG:
    2670           1 :             m_aFontEncodings[m_nCurrentFontIndex] = rtl_getTextEncodingFromWindowsCodePage(nParam);
    2671           1 :             break;
    2672             :         case RTF_CF:
    2673             :             {
    2674             :                 // NS_sprm::LN_CIco won't work, that would be an index in a static table
    2675         146 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2676         146 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_Color_val, pValue);
    2677             :             }
    2678         146 :             break;
    2679             :         case RTF_S:
    2680         377 :             m_aStates.top().nCurrentStyleIndex = nParam;
    2681         377 :             if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
    2682             :             {
    2683         256 :                 m_nCurrentStyleIndex = nParam;
    2684         256 :                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2685         256 :                 RTFValue::Pointer_t pValue(new RTFValue(1));
    2686         256 :                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_SGC, pValue); // paragraph style
    2687             :             }
    2688             :             else
    2689         121 :                 m_aStates.top().aParagraphAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2690         377 :             break;
    2691             :         case RTF_CS:
    2692          25 :             if (m_aStates.top().nDestinationState == DESTINATION_STYLESHEET || m_aStates.top().nDestinationState == DESTINATION_STYLEENTRY)
    2693             :             {
    2694          22 :                 m_nCurrentStyleIndex = nParam;
    2695          22 :                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2696          22 :                 RTFValue::Pointer_t pValue(new RTFValue(2));
    2697          22 :                 m_aStates.top().aTableAttributes.set(NS_rtf::LN_SGC, pValue); // character style
    2698             :             }
    2699             :             else
    2700           3 :                 m_aStates.top().aCharacterAttributes.set(NS_rtf::LN_ISTD, pIntValue);
    2701          25 :             break;
    2702             :         case RTF_DEFF:
    2703          53 :                 m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CRgFtc0, pIntValue);
    2704          53 :             break;
    2705             :         case RTF_DEFLANG:
    2706          11 :                 m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CRgLid0, pIntValue);
    2707          11 :             break;
    2708             :         case RTF_ADEFLANG:
    2709          37 :                 m_aDefaultState.aCharacterSprms.set(NS_sprm::LN_CLidBi, pIntValue);
    2710          37 :             break;
    2711             :         case RTF_CHCBPAT:
    2712             :             {
    2713           3 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam ? getColorTable(nParam) : COL_AUTO));
    2714           3 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms, NS_sprm::LN_CShd, NS_ooxml::LN_CT_Shd_fill, pValue);
    2715             :             }
    2716           3 :             break;
    2717             :         case RTF_CLCBPAT:
    2718             :             {
    2719           1 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2720           1 :                 lcl_putNestedAttribute(m_aStates.top().aTableCellSprms,
    2721           2 :                         NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_fill, pValue);
    2722             :             }
    2723           1 :             break;
    2724             :         case RTF_CBPAT:
    2725           2 :             if (nParam)
    2726             :             {
    2727           1 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2728           1 :                 lcl_putNestedAttribute(m_aStates.top().aParagraphSprms, NS_sprm::LN_PShd, NS_ooxml::LN_CT_Shd_fill, pValue);
    2729             :             }
    2730           2 :             break;
    2731             :         case RTF_ULC:
    2732             :             {
    2733           0 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2734           0 :                 m_aStates.top().aCharacterSprms.set(0x6877, pValue);
    2735             :             }
    2736           0 :             break;
    2737             :         case RTF_HIGHLIGHT:
    2738             :             {
    2739           0 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2740           0 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CHighlight, pValue);
    2741             :             }
    2742           0 :             break;
    2743             :         case RTF_UP:
    2744             :         case RTF_DN:
    2745             :             {
    2746           5 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam * (nKeyword == RTF_UP ? 1 : -1)));
    2747           5 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CHpsPos, pValue);
    2748             :             }
    2749           5 :             break;
    2750             :         case RTF_HORZVERT:
    2751             :             {
    2752           0 :                 RTFValue::Pointer_t pValue(new RTFValue(true));
    2753           0 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vert, pValue);
    2754           0 :                 if (nParam)
    2755             :                     // rotate fits to a single line
    2756           0 :                     m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_vertCompress, pValue);
    2757             :             }
    2758           0 :             break;
    2759             :         case RTF_EXPND:
    2760             :             {
    2761           0 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam/5));
    2762           0 :                 m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CDxaSpace, pValue);
    2763             :             }
    2764           0 :             break;
    2765             :         case RTF_TWOINONE:
    2766             :             {
    2767           0 :                 RTFValue::Pointer_t pValue(new RTFValue(true));
    2768           0 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combine, pValue);
    2769           0 :                 if (nParam > 0)
    2770           0 :                     m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_EastAsianLayout_combineBrackets, pIntValue);
    2771             :             }
    2772           0 :             break;
    2773             :         case RTF_SL:
    2774             :             {
    2775             :                 // This is similar to RTF_ABSH, negative value means 'exact', positive means 'at least'.
    2776          15 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_atLeast));
    2777          15 :                 if (nParam < 0)
    2778             :                 {
    2779           1 :                     pValue.reset(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_exact));
    2780           1 :                     pIntValue.reset(new RTFValue(-nParam));
    2781             :                 }
    2782          15 :                 m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
    2783          15 :                 m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_line, pIntValue);
    2784             :             }
    2785          15 :             break;
    2786             :         case RTF_SLMULT:
    2787          14 :             if (nParam > 0)
    2788             :             {
    2789          13 :                 RTFValue::Pointer_t pValue(new RTFValue(NS_ooxml::LN_Value_wordprocessingml_ST_LineSpacingRule_auto));
    2790          13 :                 m_aStates.top().aParagraphAttributes.set(NS_ooxml::LN_CT_Spacing_lineRule, pValue);
    2791             :             }
    2792          14 :             break;
    2793             :         case RTF_BRDRW:
    2794             :             {
    2795             :                 // dmapper expects it in 1/8 pt, we have it in twip - but avoid rounding 1 to 0
    2796         154 :                 if (nParam > 1)
    2797         151 :                     nParam = nParam * 2 / 5;
    2798         154 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam));
    2799         154 :                 lcl_putBorderProperty(m_aStates, NS_rtf::LN_DPTLINEWIDTH, pValue);
    2800             :             }
    2801         154 :             break;
    2802             :         case RTF_BRDRCF:
    2803             :             {
    2804          19 :                 RTFValue::Pointer_t pValue(new RTFValue(getColorTable(nParam)));
    2805          19 :                 lcl_putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_color, pValue);
    2806             :             }
    2807          19 :             break;
    2808             :         case RTF_BRSP:
    2809             :             {
    2810             :                 // dmapper expects it in points, we have it in twip
    2811           4 :                 RTFValue::Pointer_t pValue(new RTFValue(nParam / 20));
    2812           4 :                 lcl_putBorderProperty(m_aStates, NS_rtf::LN_DPTSPACE, pValue);
    2813             :             }
    2814           4 :             break;
    2815             :         case RTF_TX:
    2816             :             {
    2817          89 :                 m_aStates.top().aTabAttributes.set(NS_ooxml::LN_CT_TabStop_pos, pIntValue);
    2818          89 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aTabAttributes));
    2819          89 :                 lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_ooxml::LN_CT_Tabs_tab, pValue);
    2820          89 :                 m_aStates.top().aTabAttributes.clear();
    2821             :             }
    2822          89 :             break;
    2823             :         case RTF_ILVL:
    2824           6 :             lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_sprm::LN_PIlvl, pIntValue);
    2825           6 :             break;
    2826             :         case RTF_LISTTEMPLATEID:
    2827             :             // This one is not referenced anywhere, so it's pointless to store it at the moment.
    2828           5 :             break;
    2829             :         case RTF_LISTID:
    2830             :             {
    2831          10 :                 if (m_aStates.top().nDestinationState == DESTINATION_LISTENTRY)
    2832           5 :                     m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIntValue);
    2833           5 :                 else if (m_aStates.top().nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
    2834           5 :                     m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIntValue);
    2835             :             }
    2836          10 :             break;
    2837             :         case RTF_LS:
    2838             :             {
    2839          14 :                 if (m_aStates.top().nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
    2840           5 :                     m_aStates.top().aTableAttributes.set(NS_rtf::LN_LSID, pIntValue);
    2841             :                 else
    2842           9 :                     lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_sprm::LN_PIlfo, pIntValue);
    2843             :             }
    2844          14 :             break;
    2845             :         case RTF_UC:
    2846          12 :             if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
    2847          12 :                 m_aStates.top().nUc = nParam;
    2848          12 :             break;
    2849             :         case RTF_U:
    2850          96 :             if ((SAL_MIN_INT16 <= nParam) && (nParam <= SAL_MAX_INT16))
    2851             :             {
    2852          96 :                 m_aUnicodeBuffer.append(static_cast<sal_Unicode>(nParam));
    2853          96 :                 m_aStates.top().nCharsToSkip = m_aStates.top().nUc;
    2854             :             }
    2855          96 :             break;
    2856             :         case RTF_LEVELFOLLOW:
    2857          10 :             m_aStates.top().aTableAttributes.set(NS_rtf::LN_IXCHFOLLOW, pIntValue);
    2858          10 :             break;
    2859             :         case RTF_LISTOVERRIDECOUNT:
    2860             :             // Ignore this for now, the exporter always emits it with a zero parameter.
    2861           5 :             break;
    2862             :         case RTF_PICSCALEX:
    2863           5 :             m_aStates.top().aPicture.nScaleX = nParam;
    2864           5 :             break;
    2865             :         case RTF_PICSCALEY:
    2866           5 :             m_aStates.top().aPicture.nScaleY = nParam;
    2867           5 :             break;
    2868             :         case RTF_PICW:
    2869           6 :             m_aStates.top().aPicture.nWidth = nParam;
    2870           6 :             break;
    2871             :         case RTF_PICH:
    2872           6 :             m_aStates.top().aPicture.nHeight = nParam;
    2873           6 :             break;
    2874             :         case RTF_PICWGOAL:
    2875           6 :             m_aStates.top().aPicture.nGoalWidth = TWIP_TO_MM100(nParam);
    2876           6 :             break;
    2877             :         case RTF_PICHGOAL:
    2878           6 :             m_aStates.top().aPicture.nGoalHeight = TWIP_TO_MM100(nParam);
    2879           6 :             break;
    2880           3 :         case RTF_PICCROPL: m_aStates.top().aPicture.nCropL = TWIP_TO_MM100(nParam); break;
    2881           3 :         case RTF_PICCROPR: m_aStates.top().aPicture.nCropR = TWIP_TO_MM100(nParam); break;
    2882           3 :         case RTF_PICCROPT: m_aStates.top().aPicture.nCropT = TWIP_TO_MM100(nParam); break;
    2883           3 :         case RTF_PICCROPB: m_aStates.top().aPicture.nCropB = TWIP_TO_MM100(nParam); break;
    2884             :         case RTF_SHPWRK:
    2885             :             {
    2886          11 :                 int nValue = 0;
    2887          11 :                 switch (nParam)
    2888             :                 {
    2889          11 :                     case 0: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_bothSides; break;
    2890           0 :                     case 1: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_left; break;
    2891           0 :                     case 2: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_right; break;
    2892           0 :                     case 3: nValue = NS_ooxml::LN_Value_wordprocessingDrawing_ST_WrapText_largest; break;
    2893           0 :                     default: break;
    2894             :                 }
    2895          11 :                 RTFValue::Pointer_t pValue(new RTFValue(nValue));
    2896          11 :                 m_aStates.top().aCharacterAttributes.set(NS_ooxml::LN_CT_WrapSquare_wrapText, pValue);
    2897             :             }
    2898          11 :             break;
    2899             :         case RTF_SHPWR:
    2900             :             {
    2901          12 :                 switch (nParam)
    2902             :                 {
    2903             :                 case 1:
    2904           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_NONE; break;
    2905             :                 case 2:
    2906           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_PARALLEL; break;
    2907             :                 case 3:
    2908          12 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_THROUGHT; break;
    2909             :                 case 4:
    2910           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_PARALLEL; break;
    2911             :                 case 5:
    2912           0 :                     m_aStates.top().aShape.nWrap = com::sun::star::text::WrapTextMode_THROUGHT; break;
    2913             :                 }
    2914             :             }
    2915          12 :             break;
    2916             :         case RTF_CELLX:
    2917             :             {
    2918         164 :                 int nCellX = nParam - m_aStates.top().nCellX;
    2919             : 
    2920             :                 // If there is a negative left margin, then the first cellx is relateve to that.
    2921         164 :                 RTFValue::Pointer_t pTblInd = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblInd);
    2922         164 :                 if (m_aStates.top().nCellX == 0 && pTblInd.get())
    2923             :                 {
    2924          29 :                     RTFValue::Pointer_t pWidth = pTblInd->getAttributes().find(NS_ooxml::LN_CT_TblWidth_w);
    2925          29 :                     if (pWidth.get() && pWidth->getInt() < 0)
    2926          29 :                         nCellX = -1 * (pWidth->getInt() - nParam);
    2927             :                 }
    2928             : 
    2929         164 :                 m_aStates.top().nCellX = nParam;
    2930         164 :                 RTFValue::Pointer_t pXValue(new RTFValue(nCellX));
    2931         164 :                 m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue, false);
    2932         164 :                 m_aStates.top().nCells++;
    2933             : 
    2934             :                 // Push cell properties.
    2935         164 :                 m_aStates.top().aTableCellsSprms.push_back(m_aStates.top().aTableCellSprms);
    2936         164 :                 m_aStates.top().aTableCellsAttributes.push_back(m_aStates.top().aTableCellAttributes);
    2937         164 :                 m_aStates.top().aTableCellSprms = m_aDefaultState.aTableCellSprms;
    2938         164 :                 m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes;
    2939             :                 // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token
    2940         164 :                 dispatchFlag(RTF_INTBL);
    2941             :             }
    2942         164 :             break;
    2943             :         case RTF_TRRH:
    2944             :             {
    2945           3 :                 rtl::OUString hRule = rtl::OUString::createFromAscii("auto");
    2946           3 :                 if ( nParam < 0 )
    2947             :                 {
    2948           0 :                     RTFValue::Pointer_t pAbsValue(new RTFValue(-nParam));
    2949           0 :                     pIntValue.swap( pAbsValue );
    2950             : 
    2951           0 :                     hRule = rtl::OUString::createFromAscii("exact");
    2952             :                 }
    2953           3 :                 else if ( nParam > 0 )
    2954           3 :                     hRule = rtl::OUString::createFromAscii("atLeast");
    2955             : 
    2956           3 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    2957           6 :                         NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_val, pIntValue);
    2958             : 
    2959           3 :                 RTFValue::Pointer_t pHRule(new RTFValue(hRule));
    2960           3 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    2961           6 :                     NS_ooxml::LN_CT_TrPrBase_trHeight, NS_ooxml::LN_CT_Height_hRule, pHRule);
    2962             :             }
    2963           3 :             break;
    2964             :         case RTF_TRLEFT:
    2965             :             {
    2966             :                 // the value is in twips
    2967          29 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    2968             :                         NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_type,
    2969          58 :                         RTFValue::Pointer_t(new RTFValue(NS_ooxml::LN_Value_ST_TblWidth_dxa)));
    2970          29 :                 lcl_putNestedAttribute(m_aStates.top().aTableRowSprms,
    2971             :                         NS_ooxml::LN_CT_TblPrBase_tblInd, NS_ooxml::LN_CT_TblWidth_w,
    2972          58 :                         RTFValue::Pointer_t(new RTFValue(nParam)));
    2973             :             }
    2974          29 :             break;
    2975             :         case RTF_COLS:
    2976           0 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    2977           0 :                         NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_num, pIntValue);
    2978           0 :             break;
    2979             :         case RTF_COLSX:
    2980           4 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    2981           8 :                         NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_space, pIntValue);
    2982           4 :             break;
    2983             :         case RTF_COLNO:
    2984           0 :                 lcl_putNestedSprm(m_aStates.top().aSectionSprms,
    2985           0 :                         NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_col, pIntValue);
    2986           0 :             break;
    2987             :         case RTF_COLW:
    2988             :         case RTF_COLSR:
    2989             :             {
    2990           0 :                 RTFSprms& rAttributes = lcl_getLastAttributes(m_aStates.top().aSectionSprms, NS_ooxml::LN_EG_SectPrContents_cols);
    2991           0 :                 rAttributes.set((nKeyword == RTF_COLW ? NS_ooxml::LN_CT_Column_w : NS_ooxml::LN_CT_Column_space), pIntValue);
    2992             :             }
    2993           0 :             break;
    2994             :         case RTF_PAPERH: // fall through: set the default + current value
    2995             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    2996          47 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue, true);
    2997             :         case RTF_PGHSXN:
    2998          81 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    2999         162 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_h, pIntValue, true);
    3000          81 :             break;
    3001             :         case RTF_PAPERW: // fall through: set the default + current value
    3002             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3003          47 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue, true);
    3004             :         case RTF_PGWSXN:
    3005          81 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3006         162 :                     NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w, pIntValue, true);
    3007          81 :             break;
    3008             :         case RTF_MARGL: // fall through: set the default + current value
    3009             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3010          47 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue, true);
    3011             :         case RTF_MARGLSXN:
    3012          83 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3013         166 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left, pIntValue, true);
    3014          83 :             break;
    3015             :         case RTF_MARGR: // fall through: set the default + current value
    3016             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3017          47 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue, true);
    3018             :         case RTF_MARGRSXN:
    3019          83 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3020         166 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_right, pIntValue, true);
    3021          83 :             break;
    3022             :         case RTF_MARGT: // fall through: set the default + current value
    3023             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3024          46 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue, true);
    3025             :         case RTF_MARGTSXN:
    3026          81 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3027         162 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_top, pIntValue, true);
    3028          81 :             break;
    3029             :         case RTF_MARGB: // fall through: set the default + current value
    3030             :             lcl_putNestedAttribute(m_aDefaultState.aSectionSprms,
    3031          45 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue, true);
    3032             :         case RTF_MARGBSXN:
    3033          80 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3034         160 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_bottom, pIntValue, true);
    3035          80 :             break;
    3036             :         case RTF_HEADERY:
    3037           4 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3038           8 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_header, pIntValue, true);
    3039           4 :             break;
    3040             :         case RTF_FOOTERY:
    3041           3 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3042           6 :                     NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_footer, pIntValue, true);
    3043           3 :             break;
    3044             :         case RTF_DEFTAB:
    3045          35 :             m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_defaultTabStop, pIntValue);
    3046          35 :             break;
    3047             :         case RTF_LINEMOD:
    3048           0 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3049           0 :                     NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_countBy, pIntValue);
    3050           0 :             break;
    3051             :         case RTF_LINEX:
    3052           7 :             if (nParam)
    3053           0 :                 lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3054           0 :                         NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_distance, pIntValue);
    3055           7 :             break;
    3056             :         case RTF_LINESTARTS:
    3057           0 :             lcl_putNestedAttribute(m_aStates.top().aSectionSprms,
    3058           0 :                     NS_ooxml::LN_EG_SectPrContents_lnNumType, NS_ooxml::LN_CT_LineNumber_start, pIntValue);
    3059           0 :             break;
    3060             :         case RTF_REVAUTH:
    3061             :         case RTF_REVAUTHDEL:
    3062             :             {
    3063           0 :                 RTFValue::Pointer_t pValue(new RTFValue(m_aAuthors[nParam]));
    3064           0 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
    3065           0 :                         NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_author, pValue);
    3066             :             }
    3067           0 :             break;
    3068             :         case RTF_REVDTTM:
    3069             :         case RTF_REVDTTMDEL:
    3070             :             {
    3071           0 :                 OUString aStr(OStringToOUString(lcl_DTTM22OString(nParam), m_aStates.top().nCurrentEncoding));
    3072           0 :                 RTFValue::Pointer_t pValue(new RTFValue(aStr));
    3073           0 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
    3074           0 :                         NS_ooxml::LN_trackchange, NS_ooxml::LN_CT_TrackChange_date, pValue);
    3075             :             }
    3076           0 :             break;
    3077             :         case RTF_SHPLEFT:
    3078          15 :             m_aStates.top().aShape.nLeft = TWIP_TO_MM100(nParam);
    3079          15 :             break;
    3080             :         case RTF_SHPTOP:
    3081          15 :             m_aStates.top().aShape.nTop = TWIP_TO_MM100(nParam);
    3082          15 :             break;
    3083             :         case RTF_SHPRIGHT:
    3084          15 :             m_aStates.top().aShape.nRight = TWIP_TO_MM100(nParam);
    3085          15 :             break;
    3086             :         case RTF_SHPBOTTOM:
    3087          15 :             m_aStates.top().aShape.nBottom = TWIP_TO_MM100(nParam);
    3088          15 :             break;
    3089             :         case RTF_FFTYPE:
    3090           0 :             switch (nParam)
    3091             :             {
    3092           0 :                 case 0: m_nFormFieldType = FORMFIELD_TEXT; break;
    3093           0 :                 case 1: m_nFormFieldType = FORMFIELD_CHECKBOX; break;
    3094           0 :                 case 2: m_nFormFieldType = FORMFIELD_LIST; break;
    3095           0 :                 default: m_nFormFieldType = FORMFIELD_NONE; break;
    3096             :             }
    3097           0 :             break;
    3098             :         case RTF_FFDEFRES:
    3099           0 :             if (m_nFormFieldType == FORMFIELD_CHECKBOX)
    3100           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_default, pIntValue);
    3101           0 :             else if (m_nFormFieldType == FORMFIELD_LIST)
    3102           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_default, pIntValue);
    3103           0 :             break;
    3104             :         case RTF_FFRES:
    3105           0 :             if (m_nFormFieldType == FORMFIELD_CHECKBOX)
    3106           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFCheckBox_checked, pIntValue);
    3107           0 :             else if (m_nFormFieldType == FORMFIELD_LIST)
    3108           0 :                 m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_result, pIntValue);
    3109           0 :             break;
    3110             :         case RTF_EDMINS:
    3111           3 :             if (m_xDocumentProperties.is())
    3112           1 :                 m_xDocumentProperties->setEditingDuration(nParam);
    3113           3 :             break;
    3114             :         case RTF_NOFPAGES:
    3115             :         case RTF_NOFWORDS:
    3116             :         case RTF_NOFCHARS:
    3117             :         case RTF_NOFCHARSWS:
    3118          12 :             if (m_xDocumentProperties.is())
    3119             :             {
    3120           4 :                 uno::Sequence<beans::NamedValue> aSet = m_xDocumentProperties->getDocumentStatistics();
    3121           4 :                 OUString aName;
    3122           4 :                 switch (nKeyword)
    3123             :                 {
    3124           1 :                     case RTF_NOFPAGES: aName = "PageCount"; nParam = 99; break;
    3125           1 :                     case RTF_NOFWORDS: aName = "WordCount"; break;
    3126           1 :                     case RTF_NOFCHARS: aName = "CharacterCount"; break;
    3127           1 :                     case RTF_NOFCHARSWS: aName = "NonWhitespaceCharacterCount"; break;
    3128           0 :                     default: break;
    3129             :                 }
    3130           4 :                 if (!aName.isEmpty())
    3131             :                 {
    3132           4 :                     bool bFound = false;
    3133           4 :                     int nLen = aSet.getLength();
    3134          10 :                     for (int i = 0; i < nLen; ++i)
    3135           6 :                         if (aSet[i].Name.equals(aName))
    3136           0 :                             aSet[i].Value = uno::makeAny(sal_Int32(nParam));
    3137           4 :                     if (!bFound)
    3138             :                     {
    3139           4 :                         aSet.realloc(nLen + 1);
    3140           4 :                         aSet[nLen].Name = aName;
    3141           4 :                         aSet[nLen].Value = uno::makeAny(sal_Int32(nParam));
    3142             :                     }
    3143           4 :                     m_xDocumentProperties->setDocumentStatistics(aSet);
    3144           4 :                 }
    3145             :             }
    3146          12 :             break;
    3147             :         case RTF_VERSION:
    3148           3 :             if (m_xDocumentProperties.is())
    3149           1 :                 m_xDocumentProperties->setEditingCycles(nParam);
    3150           3 :             break;
    3151             :         case RTF_VERN:
    3152             :             // Ignore this for now, later the RTF writer version could be used to add hacks for older buggy writers.
    3153          34 :             break;
    3154             :         case RTF_FTNSTART:
    3155          35 :             lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
    3156          35 :             break;
    3157             :         case RTF_AFTNSTART:
    3158          33 :             lcl_putNestedSprm(m_aDefaultState.aParagraphSprms, NS_ooxml::LN_EG_SectPrContents_endnotePr, NS_ooxml::LN_EG_FtnEdnNumProps_numStart, pIntValue);
    3159          33 :             break;
    3160             :         case RTF_DFRMTXTX:
    3161           3 :             m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDxaFromText, nParam);
    3162           3 :             break;
    3163             :         case RTF_DFRMTXTY:
    3164           3 :             m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDyaFromText, nParam);
    3165           3 :             break;
    3166             :         case RTF_DXFRTEXT:
    3167           0 :             m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDxaFromText, nParam);
    3168           0 :             m_aStates.top().aFrame.setSprm(NS_sprm::LN_PDyaFromText, nParam);
    3169           0 :             break;
    3170             :         case RTF_FLYVERT:
    3171             :             {
    3172           3 :                 RTFVertOrient aVertOrient(nParam);
    3173           3 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_yAlign, aVertOrient.GetAlign());
    3174           3 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, aVertOrient.GetAnchor());
    3175             :             }
    3176           3 :             break;
    3177             :         case RTF_FLYHORZ:
    3178             :             {
    3179           3 :                 RTFHoriOrient aHoriOrient(nParam);
    3180           3 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_xAlign, aHoriOrient.GetAlign());
    3181           3 :                 m_aStates.top().aFrame.setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, aHoriOrient.GetAnchor());
    3182             :             }
    3183           3 :             break;
    3184             :         case RTF_FLYANCHOR:
    3185           3 :             m_aStates.top().aFrame.nAnchorType = nParam;
    3186           3 :             break;
    3187             :         case RTF_WMETAFILE:
    3188           1 :             m_aStates.top().aPicture.eWMetafile = nParam;
    3189           1 :             break;
    3190             :         case RTF_SB:
    3191         172 :             lcl_putNestedAttribute(m_aStates.top().aParagraphSprms,
    3192         344 :                     NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_before, pIntValue, true);
    3193         172 :             break;
    3194             :         case RTF_SA:
    3195         176 :             lcl_putNestedAttribute(m_aStates.top().aParagraphSprms,
    3196         352 :                     NS_ooxml::LN_CT_PPrBase_spacing, NS_ooxml::LN_CT_Spacing_after, pIntValue, true);
    3197         176 :             break;
    3198             :         case RTF_DPX:
    3199          10 :             m_aStates.top().aDrawingObject.nLeft = TWIP_TO_MM100(nParam);
    3200          10 :             break;
    3201             :         case RTF_DPY:
    3202          10 :             m_aStates.top().aDrawingObject.nTop = TWIP_TO_MM100(nParam);
    3203          10 :             break;
    3204             :         case RTF_DPXSIZE:
    3205          10 :             m_aStates.top().aDrawingObject.nRight = TWIP_TO_MM100(nParam);
    3206          10 :             break;
    3207             :         case RTF_DPYSIZE:
    3208          10 :             m_aStates.top().aDrawingObject.nBottom = TWIP_TO_MM100(nParam);
    3209          10 :             break;
    3210             :         case RTF_PNSTART:
    3211           4 :             m_aStates.top().aTableSprms.set(NS_rtf::LN_ISTARTAT, pIntValue);
    3212           4 :             break;
    3213             :         case RTF_PNF:
    3214             :             {
    3215           1 :                 int nFontIndex = getFontIndex(nParam);
    3216           1 :                 RTFValue::Pointer_t pValue(new RTFValue(nFontIndex));
    3217           1 :                 lcl_putNestedSprm(m_aStates.top().aTableSprms, NS_ooxml::LN_CT_Lvl_rPr, NS_sprm::LN_CRgFtc0, pValue);
    3218             :             }
    3219           1 :             break;
    3220             :         case RTF_VIEWSCALE:
    3221          39 :             m_aSettingsTableAttributes.set(NS_ooxml::LN_CT_Zoom_percent, pIntValue);
    3222          39 :             break;
    3223             :         case RTF_BIN:
    3224           1 :             m_aStates.top().nInternalState = INTERNAL_BIN;
    3225           1 :             m_aStates.top().nBinaryToRead = nParam;
    3226           1 :             break;
    3227             :         case RTF_DPLINECOR:
    3228           4 :             m_aStates.top().aDrawingObject.nLineColorR = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
    3229           4 :             break;
    3230             :         case RTF_DPLINECOG:
    3231           4 :             m_aStates.top().aDrawingObject.nLineColorG = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
    3232           4 :             break;
    3233             :         case RTF_DPLINECOB:
    3234           4 :             m_aStates.top().aDrawingObject.nLineColorB = nParam; m_aStates.top().aDrawingObject.bHasLineColor = true;
    3235           4 :             break;
    3236             :         case RTF_DPFILLBGCR:
    3237           3 :             m_aStates.top().aDrawingObject.nFillColorR = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
    3238           3 :             break;
    3239             :         case RTF_DPFILLBGCG:
    3240           3 :             m_aStates.top().aDrawingObject.nFillColorG = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
    3241           3 :             break;
    3242             :         case RTF_DPFILLBGCB:
    3243           3 :             m_aStates.top().aDrawingObject.nFillColorB = nParam; m_aStates.top().aDrawingObject.bHasFillColor = true;
    3244           3 :             break;
    3245             :         case RTF_LI:
    3246         147 :             m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft, pIntValue);
    3247             :             // It turns out \li should reset the \fi inherited from the stylesheet.
    3248             :             // So set the direct formatting to zero, if we don't have such direct formatting yet.
    3249         147 :             if (!m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PDxaLeft1).get())
    3250          88 :                 m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PDxaLeft1, RTFValue::Pointer_t(new RTFValue(0)));
    3251         147 :             break;
    3252             :         case RTF_CLSHDNG:
    3253             :             {
    3254           0 :                 int nValue = -1;
    3255           0 :                 switch (nParam)
    3256             :                 {
    3257           0 :                     case 500: nValue = 2; break;
    3258           0 :                     case 1000: nValue = 3; break;
    3259           0 :                     case 1200: nValue = 27; break;
    3260           0 :                     case 1500: nValue = 28; break;
    3261           0 :                     case 2000: nValue = 4; break;
    3262           0 :                     case 2500: nValue = 5; break;
    3263           0 :                     case 3000: nValue = 6; break;
    3264           0 :                     case 3500: nValue = 43; break;
    3265           0 :                     case 3700: nValue = 44; break;
    3266           0 :                     case 4000: nValue = 7; break;
    3267           0 :                     case 4500: nValue = 46; break;
    3268           0 :                     case 5000: nValue = 8; break;
    3269           0 :                     case 5500: nValue = 49; break;
    3270           0 :                     case 6000: nValue = 9; break;
    3271           0 :                     case 6200: nValue = 51; break;
    3272           0 :                     case 6500: nValue = 52; break;
    3273           0 :                     case 7000: nValue = 10; break;
    3274           0 :                     case 7500: nValue = 11; break;
    3275           0 :                     case 8000: nValue = 12; break;
    3276           0 :                     case 8500: nValue = 57; break;
    3277           0 :                     case 8700: nValue = 58; break;
    3278           0 :                     case 9000: nValue = 13; break;
    3279           0 :                     case 9500: nValue = 60; break;
    3280           0 :                     default: break;
    3281             :                 }
    3282           0 :                 if (nValue != -1)
    3283           0 :                     lcl_putNestedAttribute(m_aStates.top().aTableCellSprms, NS_ooxml::LN_CT_TcPrBase_shd, NS_ooxml::LN_CT_Shd_val, RTFValue::Pointer_t(new RTFValue(nValue)));
    3284             :             }
    3285           0 :             break;
    3286             :         case RTF_DODHGT:
    3287          10 :             m_aStates.top().aDrawingObject.nDhgt = nParam;
    3288          10 :             break;
    3289             :         case RTF_DPPOLYCOUNT:
    3290           4 :             if (nParam >= 0)
    3291             :             {
    3292           4 :                 m_aStates.top().aDrawingObject.nPolyLineCount = nParam;
    3293           4 :                 m_aStates.top().aDrawingObject.aPolyLinePoints.realloc(nParam);
    3294             :             }
    3295           4 :             break;
    3296             :         case RTF_DPPTX:
    3297             :             {
    3298           8 :                 RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
    3299           8 :                 rDrawingObject.aPolyLinePoints[rDrawingObject.aPolyLinePoints.getLength() - rDrawingObject.nPolyLineCount].X = TWIP_TO_MM100(nParam);
    3300             :             }
    3301           8 :             break;
    3302             :         case RTF_DPPTY:
    3303             :             {
    3304           8 :                 RTFDrawingObject& rDrawingObject = m_aStates.top().aDrawingObject;
    3305           8 :                 rDrawingObject.aPolyLinePoints[rDrawingObject.aPolyLinePoints.getLength() - rDrawingObject.nPolyLineCount].Y = TWIP_TO_MM100(nParam);
    3306           8 :                 rDrawingObject.nPolyLineCount--;
    3307           8 :                 if (rDrawingObject.nPolyLineCount == 0)
    3308             :                 {
    3309           4 :                     uno::Sequence< uno::Sequence<awt::Point> >aPointSequenceSequence(1);
    3310           4 :                     aPointSequenceSequence[0] = rDrawingObject.aPolyLinePoints;
    3311           4 :                     rDrawingObject.xPropertySet->setPropertyValue("PolyPolygon", uno::Any(aPointSequenceSequence));
    3312             :                 }
    3313             :             }
    3314           8 :             break;
    3315             :         default:
    3316             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle value '" << lcl_RtfToString(nKeyword) << "'");
    3317        3335 :             aSkip.setParsed(false);
    3318        3335 :             break;
    3319             :     }
    3320        8398 :     return 0;
    3321             : }
    3322             : 
    3323         484 : int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam)
    3324             : {
    3325         484 :     checkUnicode();
    3326         484 :     setNeedSect();
    3327         484 :     RTFSkipDestination aSkip(*this);
    3328         484 :     int nSprm = -1;
    3329         484 :     RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0));
    3330             : 
    3331             :     // Map all underline toggles to a single sprm.
    3332         484 :     switch (nKeyword)
    3333             :     {
    3334           6 :         case RTF_UL: nSprm = 1; break;
    3335           0 :         case RTF_ULDASH: nSprm = 7; break;
    3336           0 :         case RTF_ULDASHD: nSprm = 9; break;
    3337           0 :         case RTF_ULDASHDD: nSprm = 10; break;
    3338           0 :         case RTF_ULDB: nSprm = 3; break;
    3339           0 :         case RTF_ULHWAVE: nSprm = 27; break;
    3340           0 :         case RTF_ULLDASH: nSprm = 39; break;
    3341           0 :         case RTF_ULTH: nSprm = 6; break;
    3342           0 :         case RTF_ULTHD: nSprm = 20; break;
    3343           0 :         case RTF_ULTHDASH: nSprm = 23; break;
    3344           0 :         case RTF_ULTHDASHD: nSprm = 25; break;
    3345           0 :         case RTF_ULTHDASHDD: nSprm = 26; break;
    3346           0 :         case RTF_ULTHLDASH: nSprm = 55; break;
    3347           0 :         case RTF_ULULDBWAVE: nSprm = 43; break;
    3348           0 :         case RTF_ULWAVE: nSprm = 11; break;
    3349         478 :         default: break;
    3350             :     }
    3351         484 :     if (nSprm >= 0)
    3352             :     {
    3353           6 :         RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0));
    3354           6 :         m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKul, pValue);
    3355           6 :         return 0;
    3356             :     }
    3357             : 
    3358             :     // Accent characters (over dot / over coma).
    3359         478 :     switch (nKeyword)
    3360             :     {
    3361           0 :         case RTF_ACCNONE: nSprm = 0; break;
    3362           0 :         case RTF_ACCDOT: nSprm = 1; break;
    3363           0 :         case RTF_ACCCOMMA: nSprm = 2; break;
    3364           0 :         case RTF_ACCCIRCLE: nSprm = 3; break;
    3365           0 :         case RTF_ACCUNDERDOT: nSprm = 4; break;
    3366         478 :         default: break;
    3367             :     }
    3368         478 :     if (nSprm >= 0)
    3369             :     {
    3370           0 :         RTFValue::Pointer_t pValue(new RTFValue((!bParam || nParam != 0) ? nSprm : 0));
    3371           0 :         m_aStates.top().aCharacterSprms.set(NS_sprm::LN_CKcd, pValue);
    3372           0 :         return 0;
    3373             :     }
    3374             : 
    3375             :     // Trivial character sprms.
    3376         478 :     switch (nKeyword)
    3377             :     {
    3378          29 :         case RTF_B: nSprm = NS_sprm::LN_CFBold; break;
    3379          13 :         case RTF_AB: nSprm = NS_sprm::LN_CFBoldBi; break;
    3380         263 :         case RTF_I: nSprm = NS_sprm::LN_CFItalic; break;
    3381          30 :         case RTF_AI: nSprm = NS_sprm::LN_CFItalicBi; break;
    3382           0 :         case RTF_UL: nSprm = NS_sprm::LN_CKul; break;
    3383           0 :         case RTF_OUTL: nSprm = NS_sprm::LN_CFOutline; break;
    3384           0 :         case RTF_SHAD: nSprm = NS_sprm::LN_CFShadow; break;
    3385           0 :         case RTF_V: nSprm = NS_sprm::LN_CFVanish; break;
    3386           4 :         case RTF_STRIKE: nSprm = NS_sprm::LN_CFStrike; break;
    3387           0 :         case RTF_STRIKED: nSprm = NS_sprm::LN_CFDStrike; break;
    3388           5 :         case RTF_SCAPS: nSprm = NS_sprm::LN_CFSmallCaps; break;
    3389           0 :         case RTF_IMPR: nSprm = NS_sprm::LN_CFImprint; break;
    3390           1 :         case RTF_CAPS: nSprm = NS_sprm::LN_CFCaps; break;
    3391         133 :         default: break;
    3392             :     }
    3393         478 :     if (nSprm >= 0)
    3394             :     {
    3395         345 :         m_aStates.top().aCharacterSprms.set(nSprm, pBoolValue);
    3396         345 :         return 0;
    3397             :     }
    3398             : 
    3399         133 :     switch (nKeyword)
    3400             :     {
    3401             :         case RTF_ASPALPHA:
    3402          72 :             m_aStates.top().aParagraphSprms.set(NS_sprm::LN_PFAutoSpaceDE, pBoolValue);
    3403          72 :             break;
    3404             :         case RTF_DELETED:
    3405             :         case RTF_REVISED:
    3406             :             {
    3407           0 :                 RTFValue::Pointer_t pValue(new RTFValue(nKeyword == RTF_DELETED ? ooxml::OOXML_del : ooxml::OOXML_ins));
    3408           0 :                 lcl_putNestedAttribute(m_aStates.top().aCharacterSprms,
    3409           0 :                         NS_ooxml::LN_trackchange, NS_ooxml::LN_token, pValue);
    3410             :             }
    3411           0 :             break;
    3412             :         default:
    3413             :             SAL_INFO("writerfilter", OSL_THIS_FUNC << ": TODO handle toggle '" << lcl_RtfToString(nKeyword) << "'");
    3414          61 :             aSkip.setParsed(false);
    3415          61 :             break;
    3416             :     }
    3417         133 :     return 0;
    3418             : }
    3419             : 
    3420        5386 : int RTFDocumentImpl::pushState()
    3421             : {
    3422             :     //SAL_INFO("writerfilter", OSL_THIS_FUNC << " before push: " << m_pTokenizer->getGroup());
    3423             : 
    3424        5386 :     checkUnicode();
    3425        5386 :     m_nGroupStartPos = Strm().Tell();
    3426             : 
    3427        5386 :     if (m_aStates.empty())
    3428         138 :         m_aStates.push(m_aDefaultState);
    3429             :     else
    3430             :     {
    3431        5248 :         if (m_aStates.top().nDestinationState == DESTINATION_MR)
    3432         231 :             lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer);
    3433        5248 :         m_aStates.push(m_aStates.top());
    3434             :     }
    3435        5386 :     m_aStates.top().aDestinationText.setLength(0);
    3436             : 
    3437        5386 :     m_pTokenizer->pushGroup();
    3438             : 
    3439        5386 :     switch (m_aStates.top().nDestinationState)
    3440             :     {
    3441         465 :     case DESTINATION_FONTTABLE: m_aStates.top().nDestinationState = DESTINATION_FONTENTRY; break;
    3442         286 :     case DESTINATION_STYLESHEET: m_aStates.top().nDestinationState = DESTINATION_STYLEENTRY; break;
    3443             :     case DESTINATION_FIELDRESULT:
    3444             :     case DESTINATION_SHAPETEXT:
    3445             :     case DESTINATION_FORMFIELD:
    3446           3 :         m_aStates.top().nDestinationState = DESTINATION_NORMAL;
    3447           3 :     break;
    3448             :     case DESTINATION_MNUM:
    3449             :     case DESTINATION_MDEN:
    3450             :     case DESTINATION_ME:
    3451             :     case DESTINATION_MFNAME:
    3452             :     case DESTINATION_MLIM:
    3453             :     case DESTINATION_MSUB:
    3454             :     case DESTINATION_MSUP:
    3455             :     case DESTINATION_MDEG:
    3456         704 :         m_aStates.top().nDestinationState = DESTINATION_MR;
    3457         704 :     break;
    3458             :     case DESTINATION_FIELDINSTRUCTION:
    3459           2 :         m_aStates.top().nDestinationState = DESTINATION_NORMAL;
    3460           2 :     break;
    3461           1 :     case DESTINATION_REVISIONTABLE: m_aStates.top().nDestinationState = DESTINATION_REVISIONENTRY; break;
    3462         309 :     case DESTINATION_MOMATH: m_aStates.top().nDestinationState = DESTINATION_MR; break;
    3463        3616 :     default: break;
    3464             :     }
    3465             : 
    3466        5386 :     return 0;
    3467             : }
    3468             : 
    3469         282 : RTFSprms RTFDocumentImpl::mergeSprms()
    3470             : {
    3471         282 :     RTFSprms aSprms;
    3472         846 :     for (RTFSprms::Iterator_t i = m_aStates.top().aTableSprms.begin();
    3473         564 :             i != m_aStates.top().aTableSprms.end(); ++i)
    3474           0 :         aSprms.set(i->first, i->second);
    3475        3048 :     for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterSprms.begin();
    3476        2032 :             i != m_aStates.top().aCharacterSprms.end(); ++i)
    3477         734 :         aSprms.set(i->first, i->second);
    3478        2094 :     for (RTFSprms::Iterator_t i = m_aStates.top().aParagraphSprms.begin();
    3479        1396 :             i != m_aStates.top().aParagraphSprms.end(); ++i)
    3480         416 :         aSprms.set(i->first, i->second);
    3481         282 :     return aSprms;
    3482             : }
    3483             : 
    3484         750 : void RTFDocumentImpl::resetSprms()
    3485             : {
    3486         750 :     m_aStates.top().aTableSprms.clear();
    3487         750 :     m_aStates.top().aCharacterSprms.clear();
    3488         750 :     m_aStates.top().aParagraphSprms.clear();
    3489         750 : }
    3490             : 
    3491         282 : RTFSprms RTFDocumentImpl::mergeAttributes()
    3492             : {
    3493         282 :     RTFSprms aAttributes;
    3494        4644 :     for (RTFSprms::Iterator_t i = m_aStates.top().aTableAttributes.begin();
    3495        3096 :             i != m_aStates.top().aTableAttributes.end(); ++i)
    3496        1266 :         aAttributes.set(i->first, i->second);
    3497         936 :     for (RTFSprms::Iterator_t i = m_aStates.top().aCharacterAttributes.begin();
    3498         624 :             i != m_aStates.top().aCharacterAttributes.end(); ++i)
    3499          30 :         aAttributes.set(i->first, i->second);
    3500         852 :     for (RTFSprms::Iterator_t i = m_aStates.top().aParagraphAttributes.begin();
    3501         568 :             i != m_aStates.top().aParagraphAttributes.end(); ++i)
    3502           2 :         aAttributes.set(i->first, i->second);
    3503         282 :     return aAttributes;
    3504             : }
    3505             : 
    3506         750 : void RTFDocumentImpl::resetAttributes()
    3507             : {
    3508         750 :     m_aStates.top().aTableAttributes.clear();
    3509         750 :     m_aStates.top().aCharacterAttributes.clear();
    3510         750 :     m_aStates.top().aParagraphAttributes.clear();
    3511         750 : }
    3512             : 
    3513        5383 : int RTFDocumentImpl::popState()
    3514             : {
    3515             :     //SAL_INFO("writerfilter", OSL_THIS_FUNC << " before pop: m_pTokenizer->getGroup() " << m_pTokenizer->getGroup() <<
    3516             :     //                         ", dest state: " << m_aStates.top().nDestinationState);
    3517             : 
    3518        5383 :     checkUnicode();
    3519        5383 :     RTFParserState aState(m_aStates.top());
    3520        5383 :     m_bWasInFrame = aState.aFrame.inFrame();
    3521        5383 :     sal_Int32 nMathToken = 0;
    3522             : 
    3523        5383 :     switch (m_aStates.top().nDestinationState)
    3524             :     {
    3525             :     case DESTINATION_FONTTABLE:
    3526             :     {
    3527          55 :         writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(m_aFontTableEntries));
    3528          55 :         Mapper().table(NS_rtf::LN_FONTTABLE, pTable);
    3529             :     }
    3530          55 :     break;
    3531             :     case DESTINATION_STYLESHEET:
    3532             :     {
    3533          42 :         writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(m_aStyleTableEntries));
    3534          42 :         Mapper().table(NS_rtf::LN_STYLESHEET, pTable);
    3535             :     }
    3536          42 :     break;
    3537             :     case DESTINATION_LISTOVERRIDETABLE:
    3538             :     {
    3539           5 :         RTFSprms aListTableAttributes;
    3540           5 :         writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(aListTableAttributes, m_aListTableSprms));
    3541           5 :         RTFReferenceTable::Entries_t aListTableEntries;
    3542           5 :         aListTableEntries.insert(make_pair(0, pProp));
    3543           5 :         writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aListTableEntries));
    3544           5 :         Mapper().table(NS_rtf::LN_LISTTABLE, pTable);
    3545             :     }
    3546           5 :     break;
    3547             :     case DESTINATION_LISTENTRY:
    3548          13 :         for (RTFSprms::Iterator_t i = aState.aListLevelEntries.begin(); i != aState.aListLevelEntries.end(); ++i)
    3549           8 :             aState.aTableSprms.set(i->first, i->second, false);
    3550           5 :     break;
    3551             :     case DESTINATION_FIELDINSTRUCTION:
    3552             :         {
    3553           6 :             RTFValue::Pointer_t pValue(new RTFValue(m_aFormfieldAttributes, m_aFormfieldSprms));
    3554           6 :             RTFSprms aFFAttributes;
    3555           6 :             RTFSprms aFFSprms;
    3556           6 :             aFFSprms.set(NS_ooxml::LN_ffdata, pValue);
    3557           6 :             writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aFFAttributes, aFFSprms));
    3558           6 :             Mapper().props(pProperties);
    3559           6 :             m_aFormfieldAttributes.clear();
    3560           6 :             m_aFormfieldSprms.clear();
    3561             :         }
    3562           6 :         singleChar(0x14);
    3563           6 :     break;
    3564             :     case DESTINATION_FIELDRESULT:
    3565           5 :         singleChar(0x15);
    3566           5 :     break;
    3567             :     case DESTINATION_LEVELTEXT:
    3568             :     {
    3569          10 :         OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
    3570             : 
    3571             :         // The first character is the length of the string (the rest should be ignored).
    3572          10 :         sal_Int32 nLength(aStr.toChar());
    3573          10 :         OUString aValue;
    3574          10 :         if (nLength <= aStr.getLength())
    3575          10 :             aValue = aStr.copy(1, nLength);
    3576             :         else
    3577           0 :             aValue = aStr;
    3578          10 :         RTFValue::Pointer_t pValue(new RTFValue(aValue, true));
    3579          10 :         aState.aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
    3580             :     }
    3581          10 :     break;
    3582             :     case DESTINATION_LEVELNUMBERS:
    3583             :     {
    3584          10 :         RTFSprms& rAttributes = aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_lvlText)->getAttributes();
    3585          10 :         RTFValue::Pointer_t pValue = rAttributes.find(NS_ooxml::LN_CT_LevelText_val);
    3586          10 :         OUString aOrig = pValue->getString();
    3587             : 
    3588          10 :         OUStringBuffer aBuf;
    3589          10 :         sal_Int32 nReplaces = 1;
    3590          36 :         for (int i = 0; i < aOrig.getLength(); i++)
    3591             :         {
    3592         104 :             if (std::find(m_aStates.top().aLevelNumbers.begin(), m_aStates.top().aLevelNumbers.end(), i+1)
    3593         104 :                     != m_aStates.top().aLevelNumbers.end())
    3594             :             {
    3595          15 :                 aBuf.append(sal_Unicode('%'));
    3596             :                 // '1.1.1' -> '%1.%2.%3', but '1.' (with '2.' prefix omitted) is %2.
    3597          15 :                 aBuf.append(sal_Int32(nReplaces++ + m_aStates.top().nListLevelNum + 1 - m_aStates.top().aLevelNumbers.size()));
    3598             :             }
    3599             :             else
    3600          11 :                 aBuf.append(aOrig.copy(i, 1));
    3601             :         }
    3602          10 :         pValue->setString(aBuf.makeStringAndClear());
    3603             :     }
    3604          10 :     break;
    3605             :     case DESTINATION_SHAPEPROPERTYNAME:
    3606             :     case DESTINATION_SHAPEPROPERTYVALUE:
    3607             :     case DESTINATION_SHAPEPROPERTY:
    3608             :     {
    3609         489 :         if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYNAME)
    3610         163 :             aState.aShape.aProperties.push_back(make_pair(m_aStates.top().aDestinationText.makeStringAndClear(), OUString()));
    3611         326 :         else if (m_aStates.top().nDestinationState == DESTINATION_SHAPEPROPERTYVALUE && aState.aShape.aProperties.size())
    3612         162 :             aState.aShape.aProperties.back().second = m_aStates.top().aDestinationText.makeStringAndClear();
    3613             :     }
    3614         489 :     break;
    3615             :     case DESTINATION_PICPROP:
    3616             :     case DESTINATION_SHAPEINSTRUCTION:
    3617          16 :         if (!m_bObject)
    3618          16 :             m_pSdrImport->resolve(m_aStates.top().aShape);
    3619          16 :     break;
    3620             :     case DESTINATION_BOOKMARKSTART:
    3621             :     {
    3622           0 :         OUString aStr = m_aStates.top().aDestinationText.makeStringAndClear();
    3623           0 :         int nPos = m_aBookmarks.size();
    3624           0 :         m_aBookmarks[aStr] = nPos;
    3625           0 :         Mapper().props(lcl_getBookmarkProperties(nPos, aStr));
    3626             :     }
    3627           0 :     break;
    3628             :     case DESTINATION_BOOKMARKEND:
    3629           0 :         Mapper().props(lcl_getBookmarkProperties(m_aBookmarks[m_aStates.top().aDestinationText.makeStringAndClear()]));
    3630           0 :     break;
    3631             :     case DESTINATION_PICT:
    3632           7 :         resolvePict(true);
    3633           7 :     break;
    3634             :     case DESTINATION_SHAPETEXT:
    3635           3 :         m_pCurrentBuffer = 0; // Just disable buffering, don't empty it yet.
    3636           3 :     break;
    3637             :     case DESTINATION_FORMFIELDNAME:
    3638             :     {
    3639           0 :         RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
    3640           0 :         m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pValue);
    3641             :     }
    3642           0 :     break;
    3643             :     case DESTINATION_FORMFIELDLIST:
    3644             :     {
    3645           0 :         RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aDestinationText.makeStringAndClear()));
    3646           0 :         m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_listEntry, pValue);
    3647             :     }
    3648           0 :     break;
    3649             :     case DESTINATION_DATAFIELD:
    3650             :     {
    3651           0 :         OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), m_aStates.top().nCurrentEncoding);
    3652             :         // decode hex dump
    3653           0 :         OStringBuffer aBuf;
    3654           0 :         const char *str = aStr.getStr();
    3655           0 :         int b = 0, count = 2;
    3656           0 :         for (int i = 0; i < aStr.getLength(); ++i)
    3657             :         {
    3658           0 :             char ch = str[i];
    3659           0 :             if (ch != 0x0d && ch != 0x0a)
    3660             :             {
    3661           0 :                 b = b << 4;
    3662           0 :                 sal_Int8 parsed = m_pTokenizer->asHex(ch);
    3663           0 :                 if (parsed == -1)
    3664           0 :                     return ERROR_HEX_INVALID;
    3665           0 :                 b += parsed;
    3666           0 :                 count--;
    3667           0 :                 if (!count)
    3668             :                 {
    3669           0 :                     aBuf.append((char)b);
    3670           0 :                     count = 2;
    3671           0 :                     b = 0;
    3672             :                 }
    3673             :             }
    3674             :         }
    3675           0 :         aStr = aBuf.makeStringAndClear();
    3676             :         // ignore the first bytes
    3677           0 :         if (aStr.getLength() > 8)
    3678           0 :             aStr = aStr.copy(8);
    3679             :         // extract name
    3680           0 :         int nLength = aStr.toChar();
    3681           0 :         aStr = aStr.copy(1);
    3682           0 :         OString aName = aStr.copy(0, nLength);
    3683           0 :         aStr = aStr.copy(nLength+1); // zero-terminated string
    3684             :         // extract default text
    3685           0 :         nLength = aStr.toChar();
    3686           0 :         aStr = aStr.copy(1);
    3687           0 :         OString aDefaultText = aStr.copy(0, nLength);
    3688           0 :         RTFValue::Pointer_t pNValue(new RTFValue(OStringToOUString(aName, m_aStates.top().nCurrentEncoding)));
    3689           0 :         m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFData_name, pNValue);
    3690           0 :         RTFValue::Pointer_t pDValue(new RTFValue(OStringToOUString(aDefaultText, m_aStates.top().nCurrentEncoding)));
    3691           0 :         m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFTextInput_default, pDValue);
    3692             : 
    3693           0 :         m_bFormField = false;
    3694             :     }
    3695           0 :     break;
    3696             :     case DESTINATION_CREATIONTIME:
    3697          32 :     if (m_xDocumentProperties.is())
    3698          30 :         m_xDocumentProperties->setCreationDate(lcl_getDateTime(m_aStates));
    3699          32 :     break;
    3700             :     case DESTINATION_REVISIONTIME:
    3701          32 :     if (m_xDocumentProperties.is())
    3702          30 :         m_xDocumentProperties->setModificationDate(lcl_getDateTime(m_aStates));
    3703          32 :     break;
    3704             :     case DESTINATION_PRINTTIME:
    3705          30 :     if (m_xDocumentProperties.is())
    3706          29 :         m_xDocumentProperties->setPrintDate(lcl_getDateTime(m_aStates));
    3707          30 :     break;
    3708             :     case DESTINATION_AUTHOR:
    3709           5 :     if (m_xDocumentProperties.is())
    3710           3 :         m_xDocumentProperties->setAuthor(m_aStates.top().aDestinationText.makeStringAndClear());
    3711           5 :     break;
    3712             :     case DESTINATION_KEYWORDS:
    3713           2 :     if (m_xDocumentProperties.is())
    3714           2 :         m_xDocumentProperties->setKeywords(comphelper::string::convertCommaSeparated(m_aStates.top().aDestinationText.makeStringAndClear()));
    3715           2 :     break;
    3716             :     case DESTINATION_COMMENT:
    3717          60 :     if (m_xDocumentProperties.is())
    3718          58 :         m_xDocumentProperties->setGenerator(m_aStates.top().aDestinationText.makeStringAndClear());
    3719          60 :     break;
    3720             :     case DESTINATION_TITLE:
    3721           6 :     if (m_xDocumentProperties.is())
    3722           4 :         m_xDocumentProperties->setTitle(m_aStates.top().aDestinationText.makeStringAndClear());
    3723           6 :     break;
    3724             :     case DESTINATION_SUBJECT:
    3725           3 :     if (m_xDocumentProperties.is())
    3726           3 :         m_xDocumentProperties->setSubject(m_aStates.top().aDestinationText.makeStringAndClear());
    3727           3 :     break;
    3728             :     case DESTINATION_DOCCOMM:
    3729           4 :     if (m_xDocumentProperties.is())
    3730           4 :         m_xDocumentProperties->setDescription(m_aStates.top().aDestinationText.makeStringAndClear());
    3731           4 :     break;
    3732             :     case DESTINATION_OPERATOR:
    3733             :     case DESTINATION_COMPANY:
    3734             :     {
    3735           8 :         OUString aName = m_aStates.top().nDestinationState == DESTINATION_OPERATOR ? OUString("Operator") : OUString("Company");
    3736           8 :         if (m_xDocumentProperties.is())
    3737             :         {
    3738           4 :             uno::Reference<beans::XPropertyContainer> xUserDefinedProperties = m_xDocumentProperties->getUserDefinedProperties();
    3739           4 :             xUserDefinedProperties->addProperty(aName, beans::PropertyAttribute::REMOVEABLE,
    3740           4 :                     uno::makeAny(m_aStates.top().aDestinationText.makeStringAndClear()));
    3741           8 :         }
    3742             :     }
    3743           8 :     break;
    3744             :     case DESTINATION_OBJDATA:
    3745             :     {
    3746           0 :         m_pObjectData.reset(new SvMemoryStream());
    3747           0 :         int b = 0, count = 2;
    3748             : 
    3749             :         // Feed the destination text to a stream.
    3750           0 :         OString aStr = OUStringToOString(m_aStates.top().aDestinationText.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US);
    3751           0 :         const char *str = aStr.getStr();
    3752           0 :         for (int i = 0; i < aStr.getLength(); ++i)
    3753             :         {
    3754           0 :             char ch = str[i];
    3755           0 :             if (ch != 0x0d && ch != 0x0a)
    3756             :             {
    3757           0 :                 b = b << 4;
    3758           0 :                 sal_Int8 parsed = m_pTokenizer->asHex(ch);
    3759           0 :                 if (parsed == -1)
    3760           0 :                     return ERROR_HEX_INVALID;
    3761           0 :                 b += parsed;
    3762           0 :                 count--;
    3763           0 :                 if (!count)
    3764             :                 {
    3765           0 :                     *m_pObjectData << (char)b;
    3766           0 :                     count = 2;
    3767           0 :                     b = 0;
    3768             :                 }
    3769             :             }
    3770             :         }
    3771             : 
    3772           0 :         if (m_pObjectData->Tell())
    3773             :         {
    3774           0 :             m_pObjectData->Seek(0);
    3775             : 
    3776             :             // Skip ObjectHeader
    3777             :             sal_uInt32 nData;
    3778           0 :             *m_pObjectData >> nData; // OLEVersion
    3779           0 :             *m_pObjectData >> nData; // FormatID
    3780           0 :             *m_pObjectData >> nData; // ClassName
    3781           0 :             m_pObjectData->SeekRel(nData);
    3782           0 :             *m_pObjectData >> nData; // TopicName
    3783           0 :             m_pObjectData->SeekRel(nData);
    3784           0 :             *m_pObjectData >> nData; // ItemName
    3785           0 :             m_pObjectData->SeekRel(nData);
    3786           0 :             *m_pObjectData >> nData; // NativeDataSize
    3787             :         }
    3788             : 
    3789           0 :         uno::Reference<io::XInputStream> xInputStream(new utl::OInputStreamWrapper(m_pObjectData.get()));
    3790           0 :         RTFValue::Pointer_t pStreamValue(new RTFValue(xInputStream));
    3791             : 
    3792           0 :         RTFSprms aOLEAttributes;
    3793           0 :         aOLEAttributes.set(NS_ooxml::LN_inputstream, pStreamValue);
    3794           0 :         RTFValue::Pointer_t pValue(new RTFValue(aOLEAttributes));
    3795           0 :         m_aObjectSprms.set(NS_ooxml::LN_OLEObject_OLEObject, pValue);
    3796             :     }
    3797           0 :     break;
    3798             :     case DESTINATION_OBJECT:
    3799             :     {
    3800           0 :         RTFSprms aObjAttributes;
    3801           0 :         RTFSprms aObjSprms;
    3802           0 :         RTFValue::Pointer_t pValue(new RTFValue(m_aObjectAttributes, m_aObjectSprms));
    3803           0 :         aObjSprms.set(NS_ooxml::LN_object, pValue);
    3804           0 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aObjAttributes, aObjSprms));
    3805           0 :         uno::Reference<drawing::XShape> xShape;
    3806           0 :         RTFValue::Pointer_t pShape = m_aObjectAttributes.find(NS_ooxml::LN_shape);
    3807             :         OSL_ASSERT(pShape.get());
    3808           0 :         if (pShape.get())
    3809           0 :             pShape->getAny() >>= xShape;
    3810           0 :         Mapper().startShape(xShape);
    3811           0 :         Mapper().props(pProperties);
    3812           0 :         Mapper().endShape();
    3813           0 :         m_aObjectAttributes.clear();
    3814           0 :         m_aObjectSprms.clear();
    3815           0 :         m_bObject = false;
    3816             :     }
    3817           0 :     break;
    3818             :     case DESTINATION_ANNOTATIONDATE:
    3819             :     {
    3820           2 :         OUString aStr(OStringToOUString(lcl_DTTM22OString(m_aStates.top().aDestinationText.makeStringAndClear().toInt32()),
    3821           4 :                     m_aStates.top().nCurrentEncoding));
    3822           2 :         RTFValue::Pointer_t pValue(new RTFValue(aStr));
    3823           2 :         RTFSprms aAnnAttributes;
    3824           2 :         aAnnAttributes.set(NS_ooxml::LN_CT_TrackChange_date, pValue);
    3825           2 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAnnAttributes));
    3826           2 :         Mapper().props(pProperties);
    3827             :     }
    3828           2 :     break;
    3829             :     case DESTINATION_ANNOTATIONAUTHOR:
    3830           2 :         m_aAuthor = m_aStates.top().aDestinationText.makeStringAndClear();
    3831           2 :     break;
    3832             :     case DESTINATION_ATNID:
    3833           2 :         m_aAuthorInitials = m_aStates.top().aDestinationText.makeStringAndClear();
    3834           2 :     break;
    3835             :     case DESTINATION_FALT:
    3836             :     {
    3837         104 :         OUString aStr(m_aStates.top().aDestinationText.makeStringAndClear());
    3838         104 :         RTFValue::Pointer_t pValue(new RTFValue(aStr));
    3839         104 :         aState.aTableSprms.set(NS_ooxml::LN_CT_Font_altName, pValue);
    3840             :     }
    3841         104 :     break;
    3842             :     case DESTINATION_DRAWINGOBJECT:
    3843          10 :     if (m_aStates.top().aDrawingObject.xShape.is())
    3844             :     {
    3845          10 :         RTFDrawingObject& rDrawing = m_aStates.top().aDrawingObject;
    3846          10 :         uno::Reference<drawing::XShape> xShape(rDrawing.xShape);
    3847          10 :         uno::Reference<beans::XPropertySet> xPropertySet(rDrawing.xPropertySet);
    3848             : 
    3849          10 :         uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
    3850          10 :         bool bTextFrame = xServiceInfo->supportsService("com.sun.star.text.TextFrame");
    3851             : 
    3852          10 :         if (bTextFrame)
    3853             :         {
    3854           2 :             xPropertySet->setPropertyValue("HoriOrientPosition", uno::makeAny((sal_Int32)rDrawing.nLeft));
    3855           2 :             xPropertySet->setPropertyValue("VertOrientPosition", uno::makeAny((sal_Int32)rDrawing.nTop));
    3856             :         }
    3857             :         else
    3858             :         {
    3859           8 :             xShape->setPosition(awt::Point(rDrawing.nLeft, rDrawing.nTop));
    3860             :         }
    3861          10 :         xShape->setSize(awt::Size(rDrawing.nRight, rDrawing.nBottom));
    3862             : 
    3863          10 :         if (rDrawing.bHasLineColor)
    3864           4 :             xPropertySet->setPropertyValue("LineColor", uno::makeAny(sal_uInt32((rDrawing.nLineColorR<<16) + (rDrawing.nLineColorG<<8) + rDrawing.nLineColorB)));
    3865          10 :         if (rDrawing.bHasFillColor)
    3866           3 :             xPropertySet->setPropertyValue("FillColor", uno::makeAny(sal_uInt32((rDrawing.nFillColorR<<16) + (rDrawing.nFillColorG<<8) + rDrawing.nFillColorB)));
    3867           7 :         else if (!bTextFrame)
    3868             :             // If there is no fill, the Word default is 100% transparency.
    3869           5 :             xPropertySet->setPropertyValue("FillTransparence", uno::makeAny(sal_Int32(100)));
    3870             : 
    3871          10 :         m_pSdrImport->resolveFLine(xPropertySet, rDrawing.nFLine);
    3872             : 
    3873          10 :         Mapper().startShape(xShape);
    3874          10 :         replayShapetext();
    3875          10 :         Mapper().endShape();
    3876             :     }
    3877          10 :     break;
    3878             :     case DESTINATION_SHAPE:
    3879          16 :     if (m_aStates.top().aFrame.inFrame())
    3880             :     {
    3881           2 :         m_aStates.top().resetFrame();
    3882           2 :         parBreak();
    3883             :         // Save this state for later use, so we only reset frame status only for the first shape inside a frame.
    3884           2 :         aState = m_aStates.top();
    3885           2 :         m_bNeedPap = true;
    3886             :     }
    3887          16 :     break;
    3888             :     case DESTINATION_MOMATH:
    3889             :     {
    3890          59 :         m_aMathBuffer.appendClosingTag(M_TOKEN(oMath));
    3891             : 
    3892          59 :         SvGlobalName aGlobalName(SO3_SM_CLASSID);
    3893          59 :         comphelper::EmbeddedObjectContainer aContainer;
    3894          59 :         OUString aName;
    3895          59 :         uno::Reference<embed::XEmbeddedObject> xObject = aContainer.CreateEmbeddedObject(aGlobalName.GetByteSequence(), aName);
    3896          59 :         uno::Reference<util::XCloseable> xComponent(xObject->getComponent(), uno::UNO_QUERY);
    3897             : // gcc4.4 (and 4.3 and possibly older) have a problem with dynamic_cast directly to the target class,
    3898             : // so help it with an intermediate cast. I'm not sure what exactly the problem is, seems to be unrelated
    3899             : // to RTLD_GLOBAL, so most probably a gcc bug.
    3900          59 :         oox::FormulaImportBase* pImport = dynamic_cast<oox::FormulaImportBase*>(dynamic_cast<SfxBaseModel*>(xComponent.get()));
    3901             :         assert( pImport != NULL );
    3902          59 :         pImport->readFormulaOoxml(m_aMathBuffer);
    3903          59 :         RTFValue::Pointer_t pValue(new RTFValue(xObject));
    3904          59 :         RTFSprms aMathAttributes;
    3905          59 :         aMathAttributes.set(NS_ooxml::LN_starmath, pValue);
    3906          59 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aMathAttributes));
    3907          59 :         Mapper().props(pProperties);
    3908          59 :         m_aMathBuffer = oox::formulaimport::XmlStreamBuilder();
    3909             :     }
    3910          59 :     break;
    3911        1033 :     case DESTINATION_MR: lcl_DestinationToMath(m_aStates.top().aDestinationText, m_aMathBuffer); break;
    3912          34 :     case DESTINATION_MF: m_aMathBuffer.appendClosingTag(M_TOKEN(f)); break;
    3913          20 :     case DESTINATION_MFPR: m_aMathBuffer.appendClosingTag(M_TOKEN(fPr)); break;
    3914         108 :     case DESTINATION_MCTRLPR: m_aMathBuffer.appendClosingTag(M_TOKEN(ctrlPr)); break;
    3915          34 :     case DESTINATION_MNUM: m_aMathBuffer.appendClosingTag(M_TOKEN(num)); break;
    3916          34 :     case DESTINATION_MDEN: m_aMathBuffer.appendClosingTag(M_TOKEN(den)); break;
    3917          24 :     case DESTINATION_MACC: m_aMathBuffer.appendClosingTag(M_TOKEN(acc)); break;
    3918          24 :     case DESTINATION_MACCPR: m_aMathBuffer.appendClosingTag(M_TOKEN(accPr)); break;
    3919          38 :     case DESTINATION_MCHR: if (!nMathToken) nMathToken = M_TOKEN(chr);
    3920          42 :     case DESTINATION_MPOS: if (!nMathToken) nMathToken = M_TOKEN(pos);
    3921          45 :     case DESTINATION_MVERTJC: if (!nMathToken) nMathToken = M_TOKEN(vertJc);
    3922          47 :     case DESTINATION_MSTRIKEH: if (!nMathToken) nMathToken = M_TOKEN(strikeH);
    3923          51 :     case DESTINATION_MDEGHIDE: if (!nMathToken) nMathToken = M_TOKEN(degHide);
    3924          83 :     case DESTINATION_MBEGCHR: if (!nMathToken) nMathToken = M_TOKEN(begChr);
    3925          86 :     case DESTINATION_MSEPCHR: if (!nMathToken) nMathToken = M_TOKEN(sepChr);
    3926         118 :     case DESTINATION_MENDCHR: if (!nMathToken) nMathToken = M_TOKEN(endChr);
    3927         120 :     case DESTINATION_MSUBHIDE: if (!nMathToken) nMathToken = M_TOKEN(subHide);
    3928         122 :     case DESTINATION_MSUPHIDE: if (!nMathToken) nMathToken = M_TOKEN(supHide);
    3929         128 :     case DESTINATION_MTYPE: if (!nMathToken) nMathToken = M_TOKEN(type);
    3930         130 :     case DESTINATION_MGROW: if (!nMathToken) nMathToken = M_TOKEN(grow);
    3931             :     {
    3932         130 :         oox::formulaimport::XmlStream::AttributeList aAttribs;
    3933         130 :         aAttribs[M_TOKEN(val)] = m_aStates.top().aDestinationText.makeStringAndClear();
    3934         130 :         m_aMathBuffer.appendOpeningTag(nMathToken, aAttribs);
    3935         130 :         m_aMathBuffer.appendClosingTag(nMathToken);
    3936             :     }
    3937         130 :     break;
    3938         197 :     case DESTINATION_ME: m_aMathBuffer.appendClosingTag(M_TOKEN(e)); break;
    3939           2 :     case DESTINATION_MBAR: m_aMathBuffer.appendClosingTag(M_TOKEN(bar)); break;
    3940           2 :     case DESTINATION_MBARPR: m_aMathBuffer.appendClosingTag(M_TOKEN(barPr)); break;
    3941          45 :     case DESTINATION_MD: m_aMathBuffer.appendClosingTag(M_TOKEN(d)); break;
    3942          45 :     case DESTINATION_MDPR: m_aMathBuffer.appendClosingTag(M_TOKEN(dPr)); break;
    3943          12 :     case DESTINATION_MFUNC: m_aMathBuffer.appendClosingTag(M_TOKEN(func)); break;
    3944          11 :     case DESTINATION_MFUNCPR: m_aMathBuffer.appendClosingTag(M_TOKEN(funcPr)); break;
    3945          12 :     case DESTINATION_MFNAME: m_aMathBuffer.appendClosingTag(M_TOKEN(fName)); break;
    3946           6 :     case DESTINATION_MLIMLOW: m_aMathBuffer.appendClosingTag(M_TOKEN(limLow)); break;
    3947           3 :     case DESTINATION_MLIMLOWPR: m_aMathBuffer.appendClosingTag(M_TOKEN(limLowPr)); break;
    3948          10 :     case DESTINATION_MLIM: m_aMathBuffer.appendClosingTag(M_TOKEN(lim)); break;
    3949           2 :     case DESTINATION_MM: m_aMathBuffer.appendClosingTag(M_TOKEN(m)); break;
    3950           1 :     case DESTINATION_MMPR: m_aMathBuffer.appendClosingTag(M_TOKEN(mPr)); break;
    3951           4 :     case DESTINATION_MMR: m_aMathBuffer.appendClosingTag(M_TOKEN(mr)); break;
    3952          13 :     case DESTINATION_MNARY: m_aMathBuffer.appendClosingTag(M_TOKEN(nary)); break;
    3953          13 :     case DESTINATION_MNARYPR: m_aMathBuffer.appendClosingTag(M_TOKEN(naryPr)); break;
    3954          29 :     case DESTINATION_MSUB: m_aMathBuffer.appendClosingTag(M_TOKEN(sub)); break;
    3955          55 :     case DESTINATION_MSUP: m_aMathBuffer.appendClosingTag(M_TOKEN(sup)); break;
    3956           4 :     case DESTINATION_MLIMUPP: m_aMathBuffer.appendClosingTag(M_TOKEN(limUpp)); break;
    3957           2 :     case DESTINATION_MLIMUPPPR: m_aMathBuffer.appendClosingTag(M_TOKEN(limUppPr)); break;
    3958           4 :     case DESTINATION_MGROUPCHR: m_aMathBuffer.appendClosingTag(M_TOKEN(groupChr)); break;
    3959           4 :     case DESTINATION_MGROUPCHRPR: m_aMathBuffer.appendClosingTag(M_TOKEN(groupChrPr)); break;
    3960           2 :     case DESTINATION_MBORDERBOX: m_aMathBuffer.appendClosingTag(M_TOKEN(borderBox)); break;
    3961           2 :     case DESTINATION_MBORDERBOXPR: m_aMathBuffer.appendClosingTag(M_TOKEN(borderBoxPr)); break;
    3962           6 :     case DESTINATION_MRAD: m_aMathBuffer.appendClosingTag(M_TOKEN(rad)); break;
    3963           5 :     case DESTINATION_MRADPR: m_aMathBuffer.appendClosingTag(M_TOKEN(radPr)); break;
    3964           6 :     case DESTINATION_MDEG: m_aMathBuffer.appendClosingTag(M_TOKEN(deg)); break;
    3965           8 :     case DESTINATION_MSSUB: m_aMathBuffer.appendClosingTag(M_TOKEN(sSub)); break;
    3966           4 :     case DESTINATION_MSSUBPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sSubPr)); break;
    3967          34 :     case DESTINATION_MSSUP: m_aMathBuffer.appendClosingTag(M_TOKEN(sSup)); break;
    3968          17 :     case DESTINATION_MSSUPPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sSupPr)); break;
    3969           4 :     case DESTINATION_MSSUBSUP: m_aMathBuffer.appendClosingTag(M_TOKEN(sSubSup)); break;
    3970           2 :     case DESTINATION_MSSUBSUPPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sSubSupPr)); break;
    3971           4 :     case DESTINATION_MSPRE: m_aMathBuffer.appendClosingTag(M_TOKEN(sPre)); break;
    3972           2 :     case DESTINATION_MSPREPR: m_aMathBuffer.appendClosingTag(M_TOKEN(sPrePr)); break;
    3973           1 :     case DESTINATION_MBOX: m_aMathBuffer.appendClosingTag(M_TOKEN(box)); break;
    3974           6 :     case DESTINATION_MEQARR: m_aMathBuffer.appendClosingTag(M_TOKEN(eqArr)); break;
    3975        2333 :     default: break;
    3976             :     }
    3977             : 
    3978             :     // See if we need to end a track change
    3979        5383 :     RTFValue::Pointer_t pTrackchange = m_aStates.top().aCharacterSprms.find(NS_ooxml::LN_trackchange);
    3980        5383 :     if (pTrackchange.get())
    3981             :     {
    3982           0 :         RTFSprms aTCAttributes;
    3983           0 :         RTFValue::Pointer_t pValue(new RTFValue(0));
    3984           0 :         aTCAttributes.set(NS_ooxml::LN_endtrackchange, pValue);
    3985           0 :         writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aTCAttributes));
    3986           0 :         Mapper().props(pProperties);
    3987             :     }
    3988             : 
    3989             :     // This is the end of the doc, see if we need to close the last section.
    3990        5383 :     if (m_pTokenizer->getGroup() == 1 && !m_bFirstRun)
    3991             :     {
    3992         132 :         if (m_bNeedCr)
    3993           8 :             dispatchSymbol(RTF_PAR);
    3994         132 :         sectBreak(true);
    3995             :     }
    3996             : 
    3997        5383 :     m_aStates.pop();
    3998             : 
    3999        5383 :     m_pTokenizer->popGroup();
    4000             : 
    4001             :     // list table
    4002        5383 :     if (aState.nDestinationState == DESTINATION_LISTENTRY)
    4003             :     {
    4004           5 :         RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4005           5 :         m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pValue, false);
    4006             :     }
    4007        5378 :     else if (aState.nDestinationState == DESTINATION_PARAGRAPHNUMBERING)
    4008             :     {
    4009           4 :         RTFValue::Pointer_t pIdValue = aState.aTableAttributes.find(NS_rtf::LN_LSID);
    4010           4 :         if (pIdValue.get())
    4011             :         {
    4012             :             // Abstract numbering
    4013           4 :             RTFSprms aLeveltextAttributes;
    4014           4 :             OUString aTextValue;
    4015           4 :             RTFValue::Pointer_t pTextBefore = aState.aTableAttributes.find(NS_ooxml::LN_CT_LevelText_val);
    4016           4 :             if (pTextBefore.get())
    4017           3 :                 aTextValue += pTextBefore->getString();
    4018           4 :             aTextValue += "%1";
    4019           4 :             RTFValue::Pointer_t pTextAfter = aState.aTableAttributes.find(NS_ooxml::LN_CT_LevelSuffix_val);
    4020           4 :             if (pTextAfter.get())
    4021           3 :                 aTextValue += pTextAfter->getString();
    4022           4 :             RTFValue::Pointer_t pTextValue(new RTFValue(aTextValue));
    4023           4 :             aLeveltextAttributes.set(NS_ooxml::LN_CT_LevelText_val, pTextValue);
    4024             : 
    4025           4 :             RTFSprms aLevelAttributes;
    4026           4 :             RTFSprms aLevelSprms;
    4027           4 :             RTFValue::Pointer_t pIlvlValue(new RTFValue(0));
    4028           4 :             aLevelAttributes.set(NS_ooxml::LN_CT_Lvl_ilvl, pIlvlValue);
    4029             : 
    4030           4 :             RTFValue::Pointer_t pNfcValue = aState.aTableSprms.find(NS_rtf::LN_NFC);
    4031           4 :             if (pNfcValue.get())
    4032           4 :                 aLevelSprms.set(NS_rtf::LN_NFC, pNfcValue);
    4033             : 
    4034           4 :             RTFValue::Pointer_t pStartatValue = aState.aTableSprms.find(NS_rtf::LN_ISTARTAT);
    4035           4 :             if (pStartatValue.get())
    4036           4 :                 aLevelSprms.set(NS_rtf::LN_ISTARTAT, pStartatValue);
    4037             : 
    4038           4 :             RTFValue::Pointer_t pLeveltextValue(new RTFValue(aLeveltextAttributes));
    4039           4 :             aLevelSprms.set(NS_ooxml::LN_CT_Lvl_lvlText, pLeveltextValue);
    4040           4 :             RTFValue::Pointer_t pRunProps = aState.aTableSprms.find(NS_ooxml::LN_CT_Lvl_rPr);
    4041           4 :             if (pRunProps.get())
    4042           1 :                 aLevelSprms.set(NS_ooxml::LN_CT_Lvl_rPr, pRunProps);
    4043             : 
    4044           4 :             RTFSprms aAbstractAttributes;
    4045           4 :             RTFSprms aAbstractSprms;
    4046           4 :             aAbstractAttributes.set(NS_ooxml::LN_CT_AbstractNum_abstractNumId, pIdValue);
    4047           4 :             RTFValue::Pointer_t pLevelValue(new RTFValue(aLevelAttributes, aLevelSprms));
    4048           4 :             aAbstractSprms.set(NS_ooxml::LN_CT_AbstractNum_lvl, pLevelValue, false);
    4049             : 
    4050           4 :             RTFSprms aListTableSprms;
    4051           4 :             RTFValue::Pointer_t pAbstractValue(new RTFValue(aAbstractAttributes, aAbstractSprms));
    4052             :             // It's important that Numbering_abstractNum and Numbering_num never overwrites previous values.
    4053           4 :             aListTableSprms.set(NS_ooxml::LN_CT_Numbering_abstractNum, pAbstractValue, false);
    4054             : 
    4055             :             // Numbering
    4056           4 :             RTFSprms aNumberingAttributes;
    4057           4 :             RTFSprms aNumberingSprms;
    4058           4 :             aNumberingAttributes.set(NS_rtf::LN_LSID, pIdValue);
    4059           4 :             aNumberingSprms.set(NS_ooxml::LN_CT_Num_abstractNumId, pIdValue);
    4060           4 :             RTFValue::Pointer_t pNumberingValue(new RTFValue(aNumberingAttributes, aNumberingSprms));
    4061           4 :             aListTableSprms.set(NS_ooxml::LN_CT_Numbering_num, pNumberingValue, false);
    4062             : 
    4063             :             // Table
    4064           4 :             RTFSprms aListTableAttributes;
    4065           4 :             writerfilter::Reference<Properties>::Pointer_t const pProp(new RTFReferenceProperties(aListTableAttributes, aListTableSprms));
    4066             : 
    4067           4 :             RTFReferenceTable::Entries_t aListTableEntries;
    4068           4 :             aListTableEntries.insert(make_pair(0, pProp));
    4069           4 :             writerfilter::Reference<Table>::Pointer_t const pTable(new RTFReferenceTable(aListTableEntries));
    4070           4 :             Mapper().table(NS_rtf::LN_LISTTABLE, pTable);
    4071             : 
    4072             :             // Use it
    4073           4 :             lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_numPr, NS_sprm::LN_PIlvl, pIlvlValue);
    4074           4 :             lcl_putNestedSprm(m_aStates.top().aParagraphSprms, NS_ooxml::LN_CT_PPrBase_tabs, NS_sprm::LN_PIlfo, pIdValue);
    4075           4 :         }
    4076             :     }
    4077        5374 :     else if (aState.nDestinationState == DESTINATION_PARAGRAPHNUMBERING_TEXTAFTER)
    4078             :     {
    4079           3 :         RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
    4080           3 :         m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelSuffix_val, pValue);
    4081             :     }
    4082        5371 :     else if (aState.nDestinationState == DESTINATION_PARAGRAPHNUMBERING_TEXTBEFORE)
    4083             :     {
    4084           3 :         RTFValue::Pointer_t pValue(new RTFValue(aState.aDestinationText.makeStringAndClear(), true));
    4085           3 :         m_aStates.top().aTableAttributes.set(NS_ooxml::LN_CT_LevelText_val, pValue);
    4086             :     }
    4087        5368 :     else if (aState.nDestinationState == DESTINATION_LISTLEVEL)
    4088             :     {
    4089           8 :         RTFValue::Pointer_t pInnerValue(new RTFValue(m_aStates.top().nListLevelNum++));
    4090           8 :         aState.aTableAttributes.set(NS_ooxml::LN_CT_Lvl_ilvl, pInnerValue);
    4091             : 
    4092           8 :         RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4093           8 :         m_aStates.top().aListLevelEntries.set(NS_ooxml::LN_CT_AbstractNum_lvl, pValue, false);
    4094             :     }
    4095             :     // list override table
    4096        5360 :     else if (aState.nDestinationState == DESTINATION_LISTOVERRIDEENTRY)
    4097             :     {
    4098           5 :         RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes, aState.aTableSprms));
    4099           5 :         m_aListTableSprms.set(NS_ooxml::LN_CT_Numbering_num, pValue, false);
    4100             :     }
    4101        5355 :     else if (aState.nDestinationState == DESTINATION_LEVELTEXT)
    4102             :     {
    4103          10 :         RTFValue::Pointer_t pValue(new RTFValue(aState.aTableAttributes));
    4104          10 :         m_aStates.top().aTableSprms.set(NS_ooxml::LN_CT_Lvl_lvlText, pValue);
    4105             :     }
    4106        5345 :     else if (aState.nDestinationState == DESTINATION_LEVELNUMBERS)
    4107          10 :         m_aStates.top().aTableSprms = aState.aTableSprms;
    4108        5335 :     else if (aState.nDestinationState == DESTINATION_FIELDINSTRUCTION)
    4109           6 :         m_aStates.top().nFieldStatus = FIELD_INSTRUCTION;
    4110        5329 :     else if (aState.nDestinationState == DESTINATION_FIELDRESULT)
    4111           5 :         m_aStates.top().nFieldStatus = FIELD_RESULT;
    4112        5324 :     else if (aState.nDestinationState == DESTINATION_FIELD)
    4113             :     {
    4114           6 :         if (aState.nFieldStatus == FIELD_INSTRUCTION)
    4115           1 :             singleChar(0x15);
    4116             :     }
    4117        5318 :     else if (aState.nDestinationState == DESTINATION_SHAPEPROPERTYVALUEPICT)
    4118             :     {
    4119           2 :         m_aStates.top().aPicture = aState.aPicture;
    4120           2 :         m_aStates.top().aDestinationText = aState.aDestinationText;
    4121             :     }
    4122        5316 :     else if (aState.nDestinationState == DESTINATION_FALT)
    4123         104 :         m_aStates.top().aTableSprms = aState.aTableSprms;
    4124        5212 :     else if (m_aStates.size() && m_aStates.top().nDestinationState == DESTINATION_PICT)
    4125           2 :         m_aStates.top().aPicture = aState.aPicture;
    4126        5210 :     else if (aState.nDestinationState == DESTINATION_SHAPEPROPERTYNAME ||
    4127             :             aState.nDestinationState == DESTINATION_SHAPEPROPERTYVALUE ||
    4128             :             aState.nDestinationState == DESTINATION_SHAPEPROPERTY)
    4129             :     {
    4130         489 :         m_aStates.top().aShape = aState.aShape;
    4131         489 :         m_aStates.top().aPicture = aState.aPicture;
    4132         489 :         m_aStates.top().aCharacterAttributes = aState.aCharacterAttributes;
    4133             :     }
    4134        4721 :     else if (aState.nDestinationState == DESTINATION_FLYMAINCONTENT ||
    4135             :             aState.nDestinationState == DESTINATION_SHPPICT ||
    4136             :             aState.nDestinationState == DESTINATION_SHAPE)
    4137          22 :         m_aStates.top().aFrame = aState.aFrame;
    4138        5383 :     if (m_pCurrentBuffer == &m_aSuperBuffer)
    4139             :     {
    4140           6 :         if (!m_bHasFootnote)
    4141           6 :             replayBuffer(m_aSuperBuffer);
    4142           6 :         m_pCurrentBuffer = 0;
    4143           6 :         m_bHasFootnote = false;
    4144             :     }
    4145        5383 :     if (m_aStates.size())
    4146             :     {
    4147        5248 :         m_aStates.top().nCells = aState.nCells;
    4148        5248 :         m_aStates.top().aTableCellsSprms = aState.aTableCellsSprms;
    4149        5248 :         m_aStates.top().aTableCellsAttributes = aState.aTableCellsAttributes;
    4150             :     }
    4151             : 
    4152        5383 :     return 0;
    4153             : }
    4154             : 
    4155           0 : ::std::string RTFDocumentImpl::getType() const
    4156             : {
    4157           0 :     return "RTFDocumentImpl";
    4158             : }
    4159             : 
    4160          45 : uno::Reference<lang::XMultiServiceFactory> RTFDocumentImpl::getModelFactory()
    4161             : {
    4162          45 :     return m_xModelFactory;
    4163             : }
    4164             : 
    4165      253804 : RTFParserState& RTFDocumentImpl::getState()
    4166             : {
    4167      253804 :     return m_aStates.top();
    4168             : }
    4169             : 
    4170           2 : void RTFDocumentImpl::setDestinationText(OUString& rString)
    4171             : {
    4172           2 :     m_aStates.top().aDestinationText.setLength(0);
    4173           2 :     m_aStates.top().aDestinationText.append(rString);
    4174           2 : }
    4175             : 
    4176          24 : void RTFDocumentImpl::replayShapetext()
    4177             : {
    4178          24 :     Mapper().startParagraphGroup();
    4179          24 :     if (!m_aShapetextBuffer.empty())
    4180             :     {
    4181           3 :         replayBuffer(m_aShapetextBuffer);
    4182           3 :         Mapper().startCharacterGroup();
    4183           3 :         runBreak();
    4184           3 :         Mapper().endCharacterGroup();
    4185             :     }
    4186          24 :     Mapper().endParagraphGroup();
    4187          24 : }
    4188             : 
    4189       51405 : bool RTFDocumentImpl::getSkipUnknown()
    4190             : {
    4191       51405 :     return m_bSkipUnknown;
    4192             : }
    4193             : 
    4194         559 : void RTFDocumentImpl::setSkipUnknown(bool bSkipUnknown)
    4195             : {
    4196         559 :     m_bSkipUnknown = bSkipUnknown;
    4197         559 : }
    4198             : 
    4199       70943 : void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
    4200             : {
    4201       70943 :     if (bUnicode && m_aUnicodeBuffer.getLength() > 0)
    4202             :     {
    4203          96 :         OUString aString = m_aUnicodeBuffer.makeStringAndClear();
    4204          96 :         text(aString);
    4205             :     }
    4206       70943 :     if (bHex && m_aHexBuffer.getLength() > 0)
    4207             :     {
    4208        1975 :         OUString aString = OStringToOUString(m_aHexBuffer.makeStringAndClear(), m_aStates.top().nCurrentEncoding);
    4209        1975 :         text(aString);
    4210             :     }
    4211       70943 : }
    4212             : 
    4213         138 : RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl)
    4214             :     : m_pDocumentImpl(pDocumentImpl),
    4215             :     nInternalState(INTERNAL_NORMAL),
    4216             :     nDestinationState(DESTINATION_NORMAL),
    4217             :     nFieldStatus(FIELD_NONE),
    4218             :     nBorderState(BORDER_NONE),
    4219             :     aTableSprms(),
    4220             :     aTableAttributes(),
    4221             :     aCharacterSprms(),
    4222             :     aCharacterAttributes(),
    4223             :     aParagraphSprms(),
    4224             :     aParagraphAttributes(),
    4225             :     aSectionSprms(),
    4226             :     aSectionAttributes(),
    4227             :     aTableRowSprms(),
    4228             :     aTableRowAttributes(),
    4229             :     aTableCellSprms(),
    4230             :     aTableCellAttributes(),
    4231             :     aTableCellsSprms(),
    4232             :     aTableCellsAttributes(),
    4233             :     aTabAttributes(),
    4234             :     aCurrentColor(),
    4235             :     nCurrentEncoding(0),
    4236             :     nUc(1),
    4237             :     nCharsToSkip(0),
    4238             :     nBinaryToRead(0),
    4239             :     nListLevelNum(0),
    4240             :     aListLevelEntries(),
    4241             :     aLevelNumbers(),
    4242             :     aPicture(),
    4243             :     aShape(),
    4244             :     aDrawingObject(),
    4245             :     aFrame(this),
    4246             :     nCellX(0),
    4247             :     nCells(0),
    4248             :     nInheritingCells(0),
    4249             :     bIsCjk(false),
    4250             :     nYear(0),
    4251             :     nMonth(0),
    4252             :     nDay(0),
    4253             :     nHour(0),
    4254             :     nMinute(0),
    4255         138 :     nCurrentStyleIndex(-1)
    4256             : {
    4257         138 : }
    4258             : 
    4259         224 : void RTFParserState::resetFrame()
    4260             : {
    4261         224 :     aFrame = RTFFrame(this);
    4262         224 : }
    4263             : 
    4264         300 : RTFColorTableEntry::RTFColorTableEntry()
    4265             :     : nRed(0),
    4266             :     nGreen(0),
    4267         300 :     nBlue(0)
    4268             : {
    4269         300 : }
    4270             : 
    4271         138 : RTFPicture::RTFPicture()
    4272             :     : nWidth(0),
    4273             :     nHeight(0),
    4274             :     nGoalWidth(0),
    4275             :     nGoalHeight(0),
    4276             :     nScaleX(100),
    4277             :     nScaleY(100),
    4278             :     nCropT(0),
    4279             :     nCropB(0),
    4280             :     nCropL(0),
    4281             :     nCropR(0),
    4282             :     eWMetafile(0),
    4283         138 :     nStyle(BMPSTYLE_NONE)
    4284             : {
    4285         138 : }
    4286             : 
    4287         276 : RTFShape::RTFShape()
    4288             :     : nLeft(0),
    4289             :     nTop(0),
    4290             :     nRight(0),
    4291             :     nBottom(0),
    4292             :     nHoriOrientRelation(0),
    4293             :     nVertOrientRelation(0),
    4294         276 :     nWrap(-1)
    4295             : {
    4296         276 : }
    4297             : 
    4298         138 : RTFDrawingObject::RTFDrawingObject()
    4299             :     : nLineColorR(0),
    4300             :     nLineColorG(0),
    4301             :     nLineColorB(0),
    4302             :     bHasLineColor(false),
    4303             :     nFillColorR(0),
    4304             :     nFillColorG(0),
    4305             :     nFillColorB(0),
    4306             :     bHasFillColor(false),
    4307             :     nDhgt(0),
    4308             :     nFLine(-1),
    4309         138 :     nPolyLineCount(0)
    4310             : {
    4311         138 : }
    4312             : 
    4313         362 : RTFFrame::RTFFrame(RTFParserState* pParserState)
    4314             :     : m_pParserState(pParserState),
    4315             :     nX(0),
    4316             :     nY(0),
    4317             :     nW(0),
    4318             :     nH(0),
    4319             :     nHoriPadding(0),
    4320             :     nVertPadding(0),
    4321             :     nHoriAlign(0),
    4322             :     nHoriAnchor(0),
    4323             :     nVertAlign(0),
    4324             :     nVertAnchor(0),
    4325             :     nHRule(NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_auto),
    4326         362 :     nAnchorType(0)
    4327             : {
    4328         362 : }
    4329             : 
    4330         123 : void RTFFrame::setSprm(Id nId, Id nValue)
    4331             : {
    4332         123 :     if (m_pParserState->m_pDocumentImpl->getFirstRun())
    4333             :     {
    4334           6 :         m_pParserState->m_pDocumentImpl->checkFirstRun();
    4335           6 :         m_pParserState->m_pDocumentImpl->setNeedPar(false);
    4336             :     }
    4337         123 :     switch (nId)
    4338             :     {
    4339             :         case NS_sprm::LN_PDxaWidth:
    4340          14 :             nW = nValue;
    4341          14 :             break;
    4342             :         case NS_sprm::LN_PWHeightAbs:
    4343          14 :             nH = nValue;
    4344          14 :             break;
    4345             :         case NS_ooxml::LN_CT_FramePr_x:
    4346          12 :             nX = nValue;
    4347          12 :             break;
    4348             :         case NS_ooxml::LN_CT_FramePr_y:
    4349          12 :             nY = nValue;
    4350          12 :             break;
    4351             :         case NS_sprm::LN_PDxaFromText:
    4352           3 :             nHoriPadding = nValue;
    4353           3 :             break;
    4354             :         case NS_sprm::LN_PDyaFromText:
    4355           3 :             nVertPadding = nValue;
    4356           3 :             break;
    4357             :         case NS_ooxml::LN_CT_FramePr_xAlign:
    4358          17 :             nHoriAlign = nValue;
    4359          17 :             break;
    4360             :         case NS_ooxml::LN_CT_FramePr_hAnchor:
    4361          15 :             nHoriAnchor = nValue;
    4362          15 :             break;
    4363             :         case NS_ooxml::LN_CT_FramePr_yAlign:
    4364          17 :             nVertAlign = nValue;
    4365          17 :             break;
    4366             :         case NS_ooxml::LN_CT_FramePr_vAnchor:
    4367          16 :             nVertAnchor = nValue;
    4368          16 :             break;
    4369             :         default:
    4370           0 :             break;
    4371             :     }
    4372         123 : }
    4373             : 
    4374          17 : RTFSprms RTFFrame::getSprms()
    4375             : {
    4376          17 :     RTFSprms sprms;
    4377             : 
    4378             :     static Id pNames[] =
    4379             :     {
    4380             :         NS_ooxml::LN_CT_FramePr_x,
    4381             :         NS_ooxml::LN_CT_FramePr_y,
    4382             :         NS_ooxml::LN_CT_FramePr_hRule, // Make sure nHRule is processed before nH
    4383             :         NS_sprm::LN_PWHeightAbs,
    4384             :         NS_sprm::LN_PDxaWidth,
    4385             :         NS_sprm::LN_PDxaFromText,
    4386             :         NS_sprm::LN_PDyaFromText,
    4387             :         NS_ooxml::LN_CT_FramePr_hAnchor,
    4388             :         NS_ooxml::LN_CT_FramePr_vAnchor,
    4389             :         NS_ooxml::LN_CT_FramePr_xAlign,
    4390             :         NS_ooxml::LN_CT_FramePr_yAlign,
    4391             :         NS_sprm::LN_PWr,
    4392             :         NS_ooxml::LN_CT_FramePr_dropCap,
    4393             :         NS_ooxml::LN_CT_FramePr_lines
    4394             :     };
    4395             : 
    4396         255 :     for ( int i = 0, len = SAL_N_ELEMENTS(pNames); i < len; ++i )
    4397             :     {
    4398         238 :         Id nId = pNames[i];
    4399         238 :         RTFValue::Pointer_t pValue;
    4400             : 
    4401         238 :         switch ( nId )
    4402             :         {
    4403             :             case NS_ooxml::LN_CT_FramePr_x:
    4404          17 :                 if ( nX != 0 )
    4405          14 :                     pValue.reset(new RTFValue(nX));
    4406          17 :                 break;
    4407             :             case NS_ooxml::LN_CT_FramePr_y:
    4408          17 :                 if ( nY != 0 )
    4409          14 :                     pValue.reset(new RTFValue(nY));
    4410          17 :                 break;
    4411             :             case NS_sprm::LN_PWHeightAbs:
    4412          17 :                 if ( nH != 0 )
    4413             :                 {
    4414          17 :                     if (nHRule == NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact)
    4415          12 :                         pValue.reset(new RTFValue(-nH)); // The negative value just sets nHRule
    4416             :                     else
    4417           5 :                         pValue.reset(new RTFValue(nH));
    4418             :                 }
    4419          17 :                 break;
    4420             :             case NS_sprm::LN_PDxaWidth:
    4421          17 :                 if ( nW != 0 )
    4422          17 :                     pValue.reset(new RTFValue(nW));
    4423          17 :                 break;
    4424             :             case NS_sprm::LN_PDxaFromText:
    4425          17 :                 if ( nHoriPadding != 0 )
    4426           4 :                     pValue.reset(new RTFValue(nHoriPadding));
    4427          17 :                 break;
    4428             :             case NS_sprm::LN_PDyaFromText:
    4429          17 :                 if ( nVertPadding != 0 )
    4430           4 :                     pValue.reset(new RTFValue(nVertPadding));
    4431          17 :                 break;
    4432             :             case NS_ooxml::LN_CT_FramePr_hAnchor:
    4433          17 :                 if ( nHoriAnchor == 0 )
    4434           3 :                     nHoriAnchor = NS_ooxml::LN_Value_wordprocessingml_ST_HAnchor_margin;
    4435          17 :                 pValue.reset(new RTFValue(nHoriAnchor));
    4436          17 :                 break;
    4437             :             case NS_ooxml::LN_CT_FramePr_vAnchor:
    4438          17 :                 if ( nVertAnchor == 0 )
    4439           4 :                     nVertAnchor = NS_ooxml::LN_Value_wordprocessingml_ST_VAnchor_margin;
    4440          17 :                 pValue.reset(new RTFValue(nVertAnchor));
    4441          17 :                 break;
    4442             :             case NS_ooxml::LN_CT_FramePr_xAlign:
    4443          17 :                 pValue.reset(new RTFValue(nHoriAlign));
    4444          17 :                 break;
    4445             :             case NS_ooxml::LN_CT_FramePr_yAlign:
    4446          17 :                 pValue.reset(new RTFValue(nVertAlign));
    4447          17 :                 break;
    4448             :             case NS_ooxml::LN_CT_FramePr_hRule:
    4449             :                 {
    4450          17 :                     if ( nH < 0 )
    4451          12 :                         nHRule = NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_exact;
    4452           5 :                     else if ( nH > 0 )
    4453           5 :                         nHRule = NS_ooxml::LN_Value_wordprocessingml_ST_HeightRule_atLeast;
    4454          17 :                     pValue.reset(new RTFValue(nHRule));
    4455          17 :                     break;
    4456             :                 }
    4457             :             default:
    4458          51 :                 break;
    4459             :         }
    4460             : 
    4461         238 :         if (pValue.get())
    4462         155 :             sprms.set(nId, pValue);
    4463         238 :     }
    4464             : 
    4465          17 :     RTFSprms frameprSprms;
    4466          17 :     RTFValue::Pointer_t pFrameprValue(new RTFValue(sprms));
    4467          17 :     frameprSprms.set(NS_ooxml::LN_CT_PPrBase_framePr, pFrameprValue);
    4468             : 
    4469          17 :     return frameprSprms;
    4470             : }
    4471             : 
    4472         692 : bool RTFFrame::hasProperties()
    4473             : {
    4474             :     return nX != 0 || nY != 0 || nW != 0 || nH != 0 ||
    4475             :         nHoriPadding != 0 || nVertPadding != 0 ||
    4476             :         nHoriAlign != 0 || nHoriAnchor != 0 || nVertAlign != 0 || nVertAnchor != 0 ||
    4477         692 :         nAnchorType != 0;
    4478             : }
    4479             : 
    4480             : } // namespace rtftok
    4481          15 : } // namespace writerfilter
    4482             : 
    4483             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10