LCOV - code coverage report
Current view: top level - starmath/source - rtfexport.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 301 317 95.0 %
Date: 2014-11-03 Functions: 15 16 93.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : 
      11             : #include "rtfexport.hxx"
      12             : 
      13             : #include <svtools/rtfkeywd.hxx>
      14             : #include <filter/msfilter/rtfutil.hxx>
      15             : 
      16          60 : SmRtfExport::SmRtfExport(const SmNode* pIn)
      17             :     : SmWordExportBase(pIn)
      18             :     , m_pBuffer(0)
      19          60 :     , m_nEncoding(RTL_TEXTENCODING_DONTKNOW)
      20             : {
      21          60 : }
      22             : 
      23          60 : bool SmRtfExport::ConvertFromStarMath(OStringBuffer& rBuffer, rtl_TextEncoding nEncoding)
      24             : {
      25          60 :     if (!m_pTree)
      26           0 :         return false;
      27          60 :     m_pBuffer = &rBuffer;
      28          60 :     m_nEncoding = nEncoding;
      29          60 :     m_pBuffer->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE LO_STRING_SVTOOLS_RTF_MOMATH " ");
      30          60 :     HandleNode(m_pTree, 0);
      31          60 :     m_pBuffer->append("}"); // moMath
      32          60 :     return true;
      33             : }
      34             : 
      35             : // NOTE: This is still work in progress and unfinished, but it already covers a good
      36             : // part of the rtf math stuff.
      37             : 
      38          10 : void SmRtfExport::HandleVerticalStack(const SmNode* pNode, int nLevel)
      39             : {
      40          10 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MEQARR " ");
      41          10 :     int size = pNode->GetNumSubNodes();
      42          32 :     for (int i = 0; i < size; ++i)
      43             :     {
      44          22 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
      45          22 :         HandleNode(pNode->GetSubNode(i), nLevel + 1);
      46          22 :         m_pBuffer->append("}"); // me
      47             :     }
      48          10 :     m_pBuffer->append("}"); // meqArr
      49          10 : }
      50             : 
      51         530 : void SmRtfExport::HandleText(const SmNode* pNode, int /*nLevel*/)
      52             : {
      53         530 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MR " ");
      54             : 
      55         530 :     if (pNode->GetToken().eType == TTEXT)  // literal text
      56           6 :         m_pBuffer->append(LO_STRING_SVTOOLS_RTF_MNOR " ");
      57             : 
      58         530 :     SmTextNode* pTemp=(SmTextNode*)pNode;
      59             :     SAL_INFO("starmath.rtf", "Text: " << pTemp->GetText());
      60        1156 :     for (sal_Int32 i = 0; i < pTemp->GetText().getLength(); i++)
      61             :     {
      62         626 :         sal_uInt16 nChar = pTemp->GetText()[i];
      63         626 :         OUString aValue(SmTextNode::ConvertSymbolToUnicode(nChar));
      64         626 :         m_pBuffer->append(msfilter::rtfutil::OutString(aValue, m_nEncoding));
      65         626 :     }
      66             : 
      67         530 :     m_pBuffer->append("}"); // mr
      68         530 : }
      69             : 
      70          30 : void SmRtfExport::HandleFractions(const SmNode* pNode, int nLevel, const char* type)
      71             : {
      72          30 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MF " ");
      73          30 :     if (type)
      74             :     {
      75           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MFPR " ");
      76           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MTYPE " ");
      77           2 :         m_pBuffer->append(type);
      78           2 :         m_pBuffer->append("}"); // mtype
      79           2 :         m_pBuffer->append("}"); // mfPr
      80             :     }
      81             :     OSL_ASSERT(pNode->GetNumSubNodes() == 3);
      82          30 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MNUM " ");
      83          30 :     HandleNode(pNode->GetSubNode(0), nLevel + 1);
      84          30 :     m_pBuffer->append("}"); // mnum
      85          30 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEN " ");
      86          30 :     HandleNode(pNode->GetSubNode(2), nLevel + 1);
      87          30 :     m_pBuffer->append("}"); // mden
      88          30 :     m_pBuffer->append("}"); // mf
      89          30 : }
      90             : 
      91          28 : void SmRtfExport::HandleAttribute(const SmAttributNode* pNode, int nLevel)
      92             : {
      93          28 :     switch (pNode->Attribute()->GetToken().eType)
      94             :     {
      95             :     case TCHECK:
      96             :     case TACUTE:
      97             :     case TGRAVE:
      98             :     case TBREVE:
      99             :     case TCIRCLE:
     100             :     case TVEC:
     101             :     case TTILDE:
     102             :     case THAT:
     103             :     case TDOT:
     104             :     case TDDOT:
     105             :     case TDDDOT:
     106             :     case TWIDETILDE:
     107             :     case TWIDEHAT:
     108             :     case TWIDEVEC:
     109             :     case TBAR:
     110             :     {
     111          24 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MACC " ");
     112          24 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MACCPR " ");
     113          24 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MCHR " ");
     114          24 :         OUString aValue(pNode->Attribute()->GetToken().cMathChar);
     115          24 :         m_pBuffer->append(msfilter::rtfutil::OutString(aValue, m_nEncoding));
     116          24 :         m_pBuffer->append("}"); // mchr
     117          24 :         m_pBuffer->append("}"); // maccPr
     118          24 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     119          24 :         HandleNode(pNode->Body(), nLevel + 1);
     120          24 :         m_pBuffer->append("}"); // me
     121          24 :         m_pBuffer->append("}"); // macc
     122          24 :         break;
     123             :     }
     124             :     case TOVERLINE:
     125             :     case TUNDERLINE:
     126           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBAR " ");
     127           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBARPR " ");
     128           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MPOS " ");
     129           2 :         m_pBuffer->append((pNode->Attribute()->GetToken().eType == TUNDERLINE) ? "bot" : "top");
     130           2 :         m_pBuffer->append("}"); // mpos
     131           2 :         m_pBuffer->append("}"); // mbarPr
     132           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     133           2 :         HandleNode(pNode->Body(), nLevel + 1);
     134           2 :         m_pBuffer->append("}"); // me
     135           2 :         m_pBuffer->append("}"); // mbar
     136           2 :         break;
     137             :     case TOVERSTRIKE:
     138           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBORDERBOX " ");
     139           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBORDERBOXPR " ");
     140           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDETOP " 1}");
     141           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDEBOT " 1}");
     142           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDELEFT " 1}");
     143           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MHIDERIGHT " 1}");
     144           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSTRIKEH " 1}");
     145           2 :         m_pBuffer->append("}"); // mborderBoxPr
     146           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     147           2 :         HandleNode(pNode->Body(), nLevel + 1);
     148           2 :         m_pBuffer->append("}"); // me
     149           2 :         m_pBuffer->append("}"); // mborderBox
     150           2 :         break;
     151             :     default:
     152           0 :         HandleAllSubNodes(pNode, nLevel);
     153           0 :         break;
     154             :     }
     155          28 : }
     156             : 
     157           6 : void SmRtfExport::HandleRoot(const SmRootNode* pNode, int nLevel)
     158             : {
     159           6 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MRAD " ");
     160           6 :     if (const SmNode* argument = pNode->Argument())
     161             :     {
     162           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEG " ");
     163           2 :         HandleNode(argument, nLevel + 1);
     164           2 :         m_pBuffer->append("}"); // mdeg
     165             :     }
     166             :     else
     167             :     {
     168           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MRADPR " ");
     169           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEGHIDE " 1}");
     170           4 :         m_pBuffer->append("}"); // mradPr
     171           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDEG " }"); // empty but present
     172             :     }
     173           6 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     174           6 :     HandleNode(pNode->Body(), nLevel + 1);
     175           6 :     m_pBuffer->append("}"); // me
     176           6 :     m_pBuffer->append("}"); // mrad
     177           6 : }
     178             : 
     179             : namespace
     180             : {
     181         116 : OString mathSymbolToString(const SmNode* node, rtl_TextEncoding nEncoding)
     182             : {
     183             :     assert(node->GetType() == NMATH || node->GetType() == NMATHIDENT);
     184         116 :     const SmTextNode* txtnode = static_cast<const SmTextNode*>(node);
     185         116 :     if (txtnode->GetText().isEmpty())
     186           2 :         return OString();
     187             :     assert(txtnode->GetText().getLength() == 1);
     188         114 :     sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode(txtnode->GetText()[0]);
     189         114 :     OUString aValue(chr);
     190         114 :     return msfilter::rtfutil::OutString(aValue, nEncoding);
     191             : }
     192             : }
     193             : 
     194          18 : void SmRtfExport::HandleOperator(const SmOperNode* pNode, int nLevel)
     195             : {
     196             :     SAL_INFO("starmath.rtf", "Operator: " << int(pNode->GetToken().eType));
     197          18 :     switch (pNode->GetToken().eType)
     198             :     {
     199             :     case TINT:
     200             :     case TINTD:
     201             :     case TIINT:
     202             :     case TIIINT:
     203             :     case TLINT:
     204             :     case TLLINT:
     205             :     case TLLLINT:
     206             :     case TPROD:
     207             :     case TCOPROD:
     208             :     case TSUM:
     209             :     {
     210          16 :         const SmSubSupNode* subsup = pNode->GetSubNode(0)->GetType() == NSUBSUP ? static_cast<const SmSubSupNode*>(pNode->GetSubNode(0)) : 0;
     211          16 :         const SmNode* operation = subsup ? subsup->GetBody() : pNode->GetSubNode(0);
     212          16 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MNARY " ");
     213          16 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MNARYPR " ");
     214          16 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MCHR " ");
     215          16 :         m_pBuffer->append(mathSymbolToString(operation, m_nEncoding));
     216          16 :         m_pBuffer->append("}"); // mchr
     217          16 :         if (!subsup || !subsup->GetSubSup(CSUB))
     218           2 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUBHIDE " 1}");
     219          16 :         if (!subsup || !subsup->GetSubSup(CSUP))
     220           2 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUPHIDE " 1}");
     221          16 :         m_pBuffer->append("}"); // mnaryPr
     222          16 :         if (!subsup || !subsup->GetSubSup(CSUB))
     223           2 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " }");
     224             :         else
     225             :         {
     226          14 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
     227          14 :             HandleNode(subsup->GetSubSup(CSUB), nLevel + 1);
     228          14 :             m_pBuffer->append("}"); // msub
     229             :         }
     230          16 :         if (!subsup || !subsup->GetSubSup(CSUP))
     231           2 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " }");
     232             :         else
     233             :         {
     234          14 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
     235          14 :             HandleNode(subsup->GetSubSup(CSUP), nLevel + 1);
     236          14 :             m_pBuffer->append("}"); // msup
     237             :         }
     238          16 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     239          16 :         HandleNode(pNode->GetSubNode(1), nLevel + 1); // body
     240          16 :         m_pBuffer->append("}"); // me
     241          16 :         m_pBuffer->append("}"); // mnary
     242          16 :         break;
     243             :     }
     244             :     case TLIM:
     245           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MFUNC " ");
     246           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MFNAME " ");
     247           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMLOW " ");
     248           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     249           2 :         HandleNode(pNode->GetSymbol(), nLevel + 1);
     250           2 :         m_pBuffer->append("}"); // me
     251           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
     252           2 :         if (const SmSubSupNode* subsup = pNode->GetSubNode(0)->GetType() == NSUBSUP ? static_cast<const SmSubSupNode*>(pNode->GetSubNode(0)) : 0)
     253           2 :             if (subsup->GetSubSup(CSUB))
     254           2 :                 HandleNode(subsup->GetSubSup(CSUB), nLevel + 1);
     255           2 :         m_pBuffer->append("}"); // mlim
     256           2 :         m_pBuffer->append("}"); // mlimLow
     257           2 :         m_pBuffer->append("}"); // mfName
     258           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     259           2 :         HandleNode(pNode->GetSubNode(1), nLevel + 1); // body
     260           2 :         m_pBuffer->append("}"); // me
     261           2 :         m_pBuffer->append("}"); // mfunc
     262           2 :         break;
     263             :     default:
     264             :         SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled oper type");
     265           0 :         break;
     266             :     }
     267          18 : }
     268             : 
     269          54 : void SmRtfExport::HandleSubSupScriptInternal(const SmSubSupNode* pNode, int nLevel, int flags)
     270             : {
     271             : // rtf supports only a certain combination of sub/super scripts, but LO can have any,
     272             : // so try to merge it using several tags if necessary
     273          54 :     if (flags == 0) // none
     274          54 :         return;
     275          54 :     if ((flags & (1 << RSUP | 1 << RSUB)) == (1 << RSUP | 1 << RSUB))
     276             :     {
     277             :         // m:sSubSup
     278           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSSUBSUP " ");
     279           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     280           4 :         flags &= ~(1 << RSUP | 1 << RSUB);
     281           4 :         if (flags == 0)
     282           4 :             HandleNode(pNode->GetBody(), nLevel + 1);
     283             :         else
     284           0 :             HandleSubSupScriptInternal(pNode, nLevel, flags);
     285           4 :         m_pBuffer->append("}"); // me
     286           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
     287           4 :         HandleNode(pNode->GetSubSup(RSUB), nLevel + 1);
     288           4 :         m_pBuffer->append("}"); // msub
     289           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
     290           4 :         HandleNode(pNode->GetSubSup(RSUP), nLevel + 1);
     291           4 :         m_pBuffer->append("}"); // msup
     292           4 :         m_pBuffer->append("}"); // msubSup
     293             :     }
     294          50 :     else if ((flags & (1 << RSUB)) == 1 << RSUB)
     295             :     {
     296             :         // m:sSub
     297           8 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSSUB " ");
     298           8 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     299           8 :         flags &= ~(1 << RSUB);
     300           8 :         if (flags == 0)
     301           8 :             HandleNode(pNode->GetBody(), nLevel + 1);
     302             :         else
     303           0 :             HandleSubSupScriptInternal(pNode, nLevel, flags);
     304           8 :         m_pBuffer->append("}"); // me
     305           8 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
     306           8 :         HandleNode(pNode->GetSubSup(RSUB), nLevel + 1);
     307           8 :         m_pBuffer->append("}"); // msub
     308           8 :         m_pBuffer->append("}"); // msSub
     309             :     }
     310          42 :     else if ((flags & (1 << RSUP)) == 1 << RSUP)
     311             :     {
     312             :         // m:sSup
     313          34 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSSUP " ");
     314          34 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     315          34 :         flags &= ~(1 << RSUP);
     316          34 :         if (flags == 0)
     317          34 :             HandleNode(pNode->GetBody(), nLevel + 1);
     318             :         else
     319           0 :             HandleSubSupScriptInternal(pNode, nLevel, flags);
     320          34 :         m_pBuffer->append("}"); // me
     321          34 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
     322          34 :         HandleNode(pNode->GetSubSup(RSUP), nLevel + 1);
     323          34 :         m_pBuffer->append("}"); // msup
     324          34 :         m_pBuffer->append("}"); // msSup
     325             :     }
     326           8 :     else if ((flags & (1 << LSUP | 1 << LSUB)) == (1 << LSUP | 1 << LSUB))
     327             :     {
     328             :         // m:sPre
     329           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSPRE " ");
     330           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUB " ");
     331           4 :         HandleNode(pNode->GetSubSup(LSUB), nLevel + 1);
     332           4 :         m_pBuffer->append("}"); // msub
     333           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSUP " ");
     334           4 :         HandleNode(pNode->GetSubSup(LSUP), nLevel + 1);
     335           4 :         m_pBuffer->append("}"); // msup
     336           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     337           4 :         flags &= ~(1 << LSUP | 1 << LSUB);
     338           4 :         if (flags == 0)
     339           4 :             HandleNode(pNode->GetBody(), nLevel + 1);
     340             :         else
     341           0 :             HandleSubSupScriptInternal(pNode, nLevel, flags);
     342           4 :         m_pBuffer->append("}"); // me
     343           4 :         m_pBuffer->append("}"); // msPre
     344             :     }
     345           4 :     else if ((flags & (1 << CSUB)) == (1 << CSUB))
     346             :     {
     347             :         // m:limLow looks like a good element for central superscript
     348           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMLOW " ");
     349           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     350           2 :         flags &= ~(1 << CSUB);
     351           2 :         if (flags == 0)
     352           0 :             HandleNode(pNode->GetBody(), nLevel + 1);
     353             :         else
     354           2 :             HandleSubSupScriptInternal(pNode, nLevel, flags);
     355           2 :         m_pBuffer->append("}"); // me
     356           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
     357           2 :         HandleNode(pNode->GetSubSup(CSUB), nLevel + 1);
     358           2 :         m_pBuffer->append("}"); // mlim
     359           2 :         m_pBuffer->append("}"); // mlimLow
     360             :     }
     361           2 :     else if ((flags & (1 << CSUP)) == (1 << CSUP))
     362             :     {
     363             :         // m:limUpp looks like a good element for central superscript
     364           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMUPP " ");
     365           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     366           2 :         flags &= ~(1 << CSUP);
     367           2 :         if (flags == 0)
     368           2 :             HandleNode(pNode->GetBody(), nLevel + 1);
     369             :         else
     370           0 :             HandleSubSupScriptInternal(pNode, nLevel, flags);
     371           2 :         m_pBuffer->append("}"); // me
     372           2 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
     373           2 :         HandleNode(pNode->GetSubSup(CSUP), nLevel + 1);
     374           2 :         m_pBuffer->append("}"); // mlim
     375           2 :         m_pBuffer->append("}"); // mlimUpp
     376             :     }
     377             :     else
     378             :         SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled subsup type");
     379             : }
     380             : 
     381           2 : void SmRtfExport::HandleMatrix(const SmMatrixNode* pNode, int nLevel)
     382             : {
     383           2 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MM " ");
     384           6 :     for (int row = 0; row < pNode->GetNumRows(); ++row)
     385             :     {
     386           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MMR " ");
     387          12 :         for (int col = 0; col < pNode->GetNumCols(); ++col)
     388             :         {
     389           8 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     390           8 :             if (const SmNode* node = pNode->GetSubNode(row * pNode->GetNumCols() + col))
     391           8 :                 HandleNode(node, nLevel + 1);
     392           8 :             m_pBuffer->append("}"); // me
     393             :         }
     394           4 :         m_pBuffer->append("}"); // mmr
     395             :     }
     396           2 :     m_pBuffer->append("}"); // mm
     397           2 : }
     398             : 
     399          46 : void SmRtfExport::HandleBrace(const SmBraceNode* pNode, int nLevel)
     400             : {
     401          46 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MD " ");
     402          46 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MDPR " ");
     403          46 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MBEGCHR " ");
     404          46 :     m_pBuffer->append(mathSymbolToString(pNode->OpeningBrace(), m_nEncoding));
     405          46 :     m_pBuffer->append("}"); // mbegChr
     406          46 :     std::vector< const SmNode* > subnodes;
     407          46 :     if (pNode->Body()->GetType() == NBRACEBODY)
     408             :     {
     409          46 :         const SmBracebodyNode* body = static_cast<const SmBracebodyNode*>(pNode->Body());
     410          46 :         bool separatorWritten = false; // assume all separators are the same
     411         100 :         for (int i = 0; i < body->GetNumSubNodes(); ++i)
     412             :         {
     413          54 :             const SmNode* subnode = body->GetSubNode(i);
     414          54 :             if (subnode->GetType() == NMATH || subnode->GetType() == NMATHIDENT)
     415             :             {
     416             :                 // do not write, but write what separator it is
     417           6 :                 const SmMathSymbolNode* math = static_cast<const SmMathSymbolNode*>(subnode);
     418           6 :                 if (!separatorWritten)
     419             :                 {
     420           4 :                     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MSEPCHR " ");
     421           4 :                     m_pBuffer->append(mathSymbolToString(math, m_nEncoding));
     422           4 :                     m_pBuffer->append("}"); // msepChr
     423           4 :                     separatorWritten = true;
     424             :                 }
     425             :             }
     426             :             else
     427          48 :                 subnodes.push_back(subnode);
     428             :         }
     429             :     }
     430             :     else
     431           0 :         subnodes.push_back(pNode->Body());
     432          46 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MENDCHR " ");
     433          46 :     m_pBuffer->append(mathSymbolToString(pNode->ClosingBrace(), m_nEncoding));
     434          46 :     m_pBuffer->append("}"); // mendChr
     435          46 :     m_pBuffer->append("}"); // mdPr
     436          94 :     for (unsigned int i = 0; i < subnodes.size(); ++i)
     437             :     {
     438          48 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     439          48 :         HandleNode(subnodes[ i ], nLevel + 1);
     440          48 :         m_pBuffer->append("}"); // me
     441             :     }
     442          46 :     m_pBuffer->append("}"); // md
     443          46 : }
     444             : 
     445           4 : void SmRtfExport::HandleVerticalBrace(const SmVerticalBraceNode* pNode, int nLevel)
     446             : {
     447             :     SAL_INFO("starmath.rtf", "Vertical: " << int(pNode->GetToken().eType));
     448           4 :     switch (pNode->GetToken().eType)
     449             :     {
     450             :     case TOVERBRACE:
     451             :     case TUNDERBRACE:
     452             :     {
     453           4 :         bool top = (pNode->GetToken().eType == TOVERBRACE);
     454           4 :         if (top)
     455           2 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMUPP " ");
     456             :         else
     457           2 :             m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIMLOW " ");
     458           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     459           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MGROUPCHR " ");
     460           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MGROUPCHRPR " ");
     461           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MCHR " ");
     462           4 :         m_pBuffer->append(mathSymbolToString(pNode->Brace(), m_nEncoding));
     463           4 :         m_pBuffer->append("}"); // mchr
     464             :         // TODO not sure if pos and vertJc are correct
     465           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MPOS " ").append(top ? "top" : "bot").append("}");
     466           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MVERTJC " ").append(top ? "bot" : "top").append("}");
     467           4 :         m_pBuffer->append("}"); // mgroupChrPr
     468           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_ME " ");
     469           4 :         HandleNode(pNode->Body(), nLevel + 1);
     470           4 :         m_pBuffer->append("}"); // me
     471           4 :         m_pBuffer->append("}"); // mgroupChr
     472           4 :         m_pBuffer->append("}"); // me
     473           4 :         m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MLIM " ");
     474           4 :         HandleNode(pNode->Script(), nLevel + 1);
     475           4 :         m_pBuffer->append("}"); // mlim
     476           4 :         m_pBuffer->append("}"); // mlimUpp or mlimLow
     477           4 :         break;
     478             :     }
     479             :     default:
     480             :         SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled vertical brace type");
     481           0 :         break;
     482             :     }
     483           4 : }
     484             : 
     485           0 : void SmRtfExport::HandleBlank()
     486             : {
     487           0 :     m_pBuffer->append("{" LO_STRING_SVTOOLS_RTF_MR " ");
     488           0 :     m_pBuffer->append(" ");
     489           0 :     m_pBuffer->append("}"); // mr
     490          72 : }
     491             : 
     492             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10