LCOV - code coverage report
Current view: top level - starmath/source - ooxmlexport.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 289 312 92.6 %
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 "ooxmlexport.hxx"
      12             : 
      13             : #include <oox/token/tokens.hxx>
      14             : #include <rtl/ustring.hxx>
      15             : 
      16             : using namespace oox;
      17             : using namespace oox::core;
      18             : 
      19         138 : SmOoxmlExport::SmOoxmlExport( const SmNode* pIn, OoxmlVersion v )
      20             : : SmWordExportBase( pIn )
      21         138 : , version( v )
      22             : {
      23         138 : }
      24             : 
      25         138 : bool SmOoxmlExport::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serializer )
      26             : {
      27         138 :     if( m_pTree == NULL )
      28           0 :         return false;
      29         138 :     m_pSerializer = serializer;
      30             :     m_pSerializer->startElementNS( XML_m, XML_oMath,
      31         138 :         FSNS( XML_xmlns, XML_m ), "http://schemas.openxmlformats.org/officeDocument/2006/math", FSEND );
      32         138 :     HandleNode( m_pTree, 0 );
      33         138 :     m_pSerializer->endElementNS( XML_m, XML_oMath );
      34         138 :     return true;
      35             : }
      36             : 
      37             : // NOTE: This is still work in progress and unfinished, but it already covers a good
      38             : // part of the ooxml math stuff.
      39             : 
      40          14 : void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
      41             : {
      42          14 :     m_pSerializer->startElementNS( XML_m, XML_eqArr, FSEND );
      43          14 :     int size = pNode->GetNumSubNodes();
      44          42 :     for( int i = 0;
      45             :          i < size;
      46             :          ++i )
      47             :     {
      48          28 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
      49          28 :         HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
      50          28 :         m_pSerializer->endElementNS( XML_m, XML_e );
      51             :     }
      52          14 :     m_pSerializer->endElementNS( XML_m, XML_eqArr );
      53          14 : }
      54             : 
      55         770 : void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
      56             : {
      57         770 :     m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
      58             : 
      59         770 :     if( pNode->GetToken().eType == TTEXT ) // literal text (in quotes)
      60             :     {
      61          10 :         m_pSerializer->startElementNS( XML_m, XML_rPr, FSEND );
      62          10 :         m_pSerializer->singleElementNS( XML_m, XML_lit, FSEND );
      63          10 :         m_pSerializer->singleElementNS( XML_m, XML_nor, FSEND );
      64          10 :         m_pSerializer->endElementNS( XML_m, XML_rPr );
      65             :     }
      66         770 :     if( version == ECMA_DIALECT )
      67             :     { // HACK: MSOffice2007 does not import characters properly unless this font is explicitly given
      68           0 :         m_pSerializer->startElementNS( XML_w, XML_rPr, FSEND );
      69             :         m_pSerializer->singleElementNS( XML_w, XML_rFonts, FSNS( XML_w, XML_ascii ), "Cambria Math",
      70           0 :             FSNS( XML_w, XML_hAnsi ), "Cambria Math", FSEND );
      71           0 :         m_pSerializer->endElementNS( XML_w, XML_rPr );
      72             :     }
      73         770 :     m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
      74         770 :     SmTextNode* pTemp=(SmTextNode* )pNode;
      75             :     SAL_INFO( "starmath.ooxml", "Text:" << OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
      76        1670 :     for(sal_Int32 i=0;i<pTemp->GetText().getLength();i++)
      77             :     {
      78             : #if 0
      79             :         if ((nPendingAttributes) &&
      80             :             (i == ((pTemp->GetText().getLength()+1)/2)-1))
      81             :         {
      82             :             *pS << sal_uInt8(0x22);     //char, with attributes right
      83             :                                 //after the character
      84             :         }
      85             :         else
      86             :             *pS << sal_uInt8(CHAR);
      87             : 
      88             :         sal_uInt8 nFace = 0x1;
      89             :         if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
      90             :             nFace = 0x3;
      91             :         else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
      92             :             nFace = 0x7;
      93             :         *pS << sal_uInt8(nFace+128); //typeface
      94             : #endif
      95         900 :         sal_uInt16 nChar = pTemp->GetText()[i];
      96         900 :         m_pSerializer->writeEscaped( OUString( SmTextNode::ConvertSymbolToUnicode(nChar)));
      97             : 
      98             : #if 0
      99             :         //Mathtype can only have these sort of character
     100             :         //attributes on a single character, starmath can put them
     101             :         //anywhere, when the entity involved is a text run this is
     102             :         //a large effort to place the character attribute on the
     103             :         //central mathtype character so that it does pretty much
     104             :         //what the user probably has in mind. The attributes
     105             :         //filled in here are dummy ones which are replaced in the
     106             :         //ATTRIBUT handler if a suitable location for the
     107             :         //attributes was found here. Unfortunately it is
     108             :         //possible for starmath to place character attributes on
     109             :         //entities which cannot occur in mathtype e.g. a Summation
     110             :         //symbol so these attributes may be lost
     111             :         if ((nPendingAttributes) &&
     112             :             (i == ((pTemp->GetText().getLength()+1)/2)-1))
     113             :         {
     114             :             *pS << sal_uInt8(EMBEL);
     115             :             while (nPendingAttributes)
     116             :             {
     117             :                 *pS << sal_uInt8(2);
     118             :                 //wedge the attributes in here and clear
     119             :                 //the pending stack
     120             :                 nPendingAttributes--;
     121             :             }
     122             :             nInsertion=pS->Tell();
     123             :             *pS << sal_uInt8(END); //end embel
     124             :             *pS << sal_uInt8(END); //end embel
     125             :         }
     126             : #endif
     127             :     }
     128         770 :     m_pSerializer->endElementNS( XML_m, XML_t );
     129         770 :     m_pSerializer->endElementNS( XML_m, XML_r );
     130         770 : }
     131             : 
     132          38 : void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char* type )
     133             : {
     134          38 :     m_pSerializer->startElementNS( XML_m, XML_f, FSEND );
     135          38 :     if( type != NULL )
     136             :     {
     137           2 :         m_pSerializer->startElementNS( XML_m, XML_fPr, FSEND );
     138           2 :         m_pSerializer->singleElementNS( XML_m, XML_type, FSNS( XML_m, XML_val ), type, FSEND );
     139           2 :         m_pSerializer->endElementNS( XML_m, XML_fPr );
     140             :     }
     141             :     OSL_ASSERT( pNode->GetNumSubNodes() == 3 );
     142          38 :     m_pSerializer->startElementNS( XML_m, XML_num, FSEND );
     143          38 :     HandleNode( pNode->GetSubNode( 0 ), nLevel + 1 );
     144          38 :     m_pSerializer->endElementNS( XML_m, XML_num );
     145          38 :     m_pSerializer->startElementNS( XML_m, XML_den, FSEND );
     146          38 :     HandleNode( pNode->GetSubNode( 2 ), nLevel + 1 );
     147          38 :     m_pSerializer->endElementNS( XML_m, XML_den );
     148          38 :     m_pSerializer->endElementNS( XML_m, XML_f );
     149          38 : }
     150             : 
     151          28 : void SmOoxmlExport::HandleAttribute( const SmAttributNode* pNode, int nLevel )
     152             : {
     153          28 :     switch( pNode->Attribute()->GetToken().eType )
     154             :     {
     155             :         case TCHECK:
     156             :         case TACUTE:
     157             :         case TGRAVE:
     158             :         case TBREVE:
     159             :         case TCIRCLE:
     160             :         case TVEC:
     161             :         case TTILDE:
     162             :         case THAT:
     163             :         case TDOT:
     164             :         case TDDOT:
     165             :         case TDDDOT:
     166             :         case TWIDETILDE:
     167             :         case TWIDEHAT:
     168             :         case TWIDEVEC:
     169             :         case TBAR:
     170             :         {
     171          24 :             m_pSerializer->startElementNS( XML_m, XML_acc, FSEND );
     172          24 :             m_pSerializer->startElementNS( XML_m, XML_accPr, FSEND );
     173             :             OString value = OUStringToOString(
     174          24 :                 OUString( pNode->Attribute()->GetToken().cMathChar ), RTL_TEXTENCODING_UTF8 );
     175          24 :             m_pSerializer->singleElementNS( XML_m, XML_chr, FSNS( XML_m, XML_val ), value.getStr(), FSEND );
     176          24 :             m_pSerializer->endElementNS( XML_m, XML_accPr );
     177          24 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     178          24 :             HandleNode( pNode->Body(), nLevel + 1 );
     179          24 :             m_pSerializer->endElementNS( XML_m, XML_e );
     180          24 :             m_pSerializer->endElementNS( XML_m, XML_acc );
     181          24 :             break;
     182             :         }
     183             :         case TOVERLINE:
     184             :         case TUNDERLINE:
     185           2 :             m_pSerializer->startElementNS( XML_m, XML_bar, FSEND );
     186           2 :             m_pSerializer->startElementNS( XML_m, XML_barPr, FSEND );
     187             :             m_pSerializer->singleElementNS( XML_m, XML_pos, FSNS( XML_m, XML_val ),
     188           2 :                 ( pNode->Attribute()->GetToken().eType == TUNDERLINE ) ? "bot" : "top", FSEND );
     189           2 :             m_pSerializer->endElementNS( XML_m, XML_barPr );
     190           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     191           2 :             HandleNode( pNode->Body(), nLevel + 1 );
     192           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     193           2 :             m_pSerializer->endElementNS( XML_m, XML_bar );
     194           2 :             break;
     195             :         case TOVERSTRIKE:
     196           2 :             m_pSerializer->startElementNS( XML_m, XML_borderBox, FSEND );
     197           2 :             m_pSerializer->startElementNS( XML_m, XML_borderBoxPr, FSEND );
     198           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideTop, FSNS( XML_m, XML_val ), "1", FSEND );
     199           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideBot, FSNS( XML_m, XML_val ), "1", FSEND );
     200           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideLeft, FSNS( XML_m, XML_val ), "1", FSEND );
     201           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideRight, FSNS( XML_m, XML_val ), "1", FSEND );
     202           2 :             m_pSerializer->singleElementNS( XML_m, XML_strikeH, FSNS( XML_m, XML_val ), "1", FSEND );
     203           2 :             m_pSerializer->endElementNS( XML_m, XML_borderBoxPr );
     204           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     205           2 :             HandleNode( pNode->Body(), nLevel + 1 );
     206           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     207           2 :             m_pSerializer->endElementNS( XML_m, XML_borderBox );
     208           2 :             break;
     209             :         default:
     210           0 :             HandleAllSubNodes( pNode, nLevel );
     211           0 :             break;
     212             :     }
     213          28 : }
     214             : 
     215          14 : void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
     216             : {
     217          14 :     m_pSerializer->startElementNS( XML_m, XML_rad, FSEND );
     218          14 :     if( const SmNode* argument = pNode->Argument())
     219             :     {
     220           2 :         m_pSerializer->startElementNS( XML_m, XML_deg, FSEND );
     221           2 :         HandleNode( argument, nLevel + 1 );
     222           2 :         m_pSerializer->endElementNS( XML_m, XML_deg );
     223             :     }
     224             :     else
     225             :     {
     226          12 :         m_pSerializer->startElementNS( XML_m, XML_radPr, FSEND );
     227          12 :         m_pSerializer->singleElementNS( XML_m, XML_degHide, FSNS( XML_m, XML_val ), "1", FSEND );
     228          12 :         m_pSerializer->endElementNS( XML_m, XML_radPr );
     229          12 :         m_pSerializer->singleElementNS( XML_m, XML_deg, FSEND ); // empty but present
     230             :     }
     231          14 :     m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     232          14 :     HandleNode( pNode->Body(), nLevel + 1 );
     233          14 :     m_pSerializer->endElementNS( XML_m, XML_e );
     234          14 :     m_pSerializer->endElementNS( XML_m, XML_rad );
     235          14 : }
     236             : 
     237         160 : static OString mathSymbolToString( const SmNode* node )
     238             : {
     239             :     assert( node->GetType() == NMATH || node->GetType() == NMATHIDENT );
     240         160 :     const SmTextNode* txtnode = static_cast< const SmTextNode* >( node );
     241             :     assert( txtnode->GetText().getLength() == 1 );
     242         160 :     sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode( txtnode->GetText()[0] );
     243         160 :     return OUStringToOString( OUString( chr ), RTL_TEXTENCODING_UTF8 );
     244             : }
     245             : 
     246          22 : void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
     247             : {
     248             :     SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode->GetToken().eType ));
     249          22 :     switch( pNode->GetToken().eType )
     250             :     {
     251             :         case TINT:
     252             :         case TINTD:
     253             :         case TIINT:
     254             :         case TIIINT:
     255             :         case TLINT:
     256             :         case TLLINT:
     257             :         case TLLLINT:
     258             :         case TPROD:
     259             :         case TCOPROD:
     260             :         case TSUM:
     261             :         {
     262          20 :             const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
     263          20 :                 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
     264          20 :             const SmNode* operation = subsup != NULL ? subsup->GetBody() : pNode->GetSubNode( 0 );
     265          20 :             m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
     266          20 :             m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
     267             :             m_pSerializer->singleElementNS( XML_m, XML_chr,
     268          20 :                 FSNS( XML_m, XML_val ), mathSymbolToString( operation ).getStr(), FSEND );
     269          20 :             if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
     270           2 :                 m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
     271          20 :             if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
     272           2 :                 m_pSerializer->singleElementNS( XML_m, XML_supHide, FSNS( XML_m, XML_val ), "1", FSEND );
     273          20 :             m_pSerializer->endElementNS( XML_m, XML_naryPr );
     274          20 :             if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
     275           2 :                 m_pSerializer->singleElementNS( XML_m, XML_sub, FSEND );
     276             :             else
     277             :             {
     278          18 :                 m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     279          18 :                 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
     280          18 :                 m_pSerializer->endElementNS( XML_m, XML_sub );
     281             :             }
     282          20 :             if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
     283           2 :                 m_pSerializer->singleElementNS( XML_m, XML_sup, FSEND );
     284             :             else
     285             :             {
     286          18 :                 m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     287          18 :                 HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
     288          18 :                 m_pSerializer->endElementNS( XML_m, XML_sup );
     289             :             }
     290          20 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     291          20 :             HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
     292          20 :             m_pSerializer->endElementNS( XML_m, XML_e );
     293          20 :             m_pSerializer->endElementNS( XML_m, XML_nary );
     294          20 :             break;
     295             :         }
     296             :         case TLIM:
     297           2 :             m_pSerializer->startElementNS( XML_m, XML_func, FSEND );
     298           2 :             m_pSerializer->startElementNS( XML_m, XML_fName, FSEND );
     299           2 :             m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
     300           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     301           2 :             HandleNode( pNode->GetSymbol(), nLevel + 1 );
     302           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     303           2 :             m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     304           4 :             if( const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
     305           2 :                 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL )
     306             :             {
     307           2 :                 if( subsup->GetSubSup( CSUB ) != NULL )
     308           2 :                     HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
     309             :             }
     310           2 :             m_pSerializer->endElementNS( XML_m, XML_lim );
     311           2 :             m_pSerializer->endElementNS( XML_m, XML_limLow );
     312           2 :             m_pSerializer->endElementNS( XML_m, XML_fName );
     313           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     314           2 :             HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
     315           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     316           2 :             m_pSerializer->endElementNS( XML_m, XML_func );
     317           2 :             break;
     318             :         default:
     319             :             SAL_WARN("starmath.ooxml", "Unhandled operation");
     320           0 :             HandleAllSubNodes( pNode, nLevel );
     321           0 :             break;
     322             :     }
     323          22 : }
     324             : 
     325         100 : void SmOoxmlExport::HandleSubSupScriptInternal( const SmSubSupNode* pNode, int nLevel, int flags )
     326             : {
     327             : // docx supports only a certain combination of sub/super scripts, but LO can have any,
     328             : // so try to merge it using several tags if necessary
     329         100 :     if( flags == 0 ) // none
     330         100 :         return;
     331         100 :     if(( flags & ( 1 << RSUP | 1 << RSUB )) == ( 1 << RSUP | 1 << RSUB ))
     332             :     { // m:sSubSup
     333          20 :         m_pSerializer->startElementNS( XML_m, XML_sSubSup, FSEND );
     334          20 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     335          20 :         flags &= ~( 1 << RSUP | 1 << RSUB );
     336          20 :         if( flags == 0 )
     337          20 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     338             :         else
     339           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     340          20 :         m_pSerializer->endElementNS( XML_m, XML_e );
     341          20 :         m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     342          20 :         HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
     343          20 :         m_pSerializer->endElementNS( XML_m, XML_sub );
     344          20 :         m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     345          20 :         HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
     346          20 :         m_pSerializer->endElementNS( XML_m, XML_sup );
     347          20 :         m_pSerializer->endElementNS( XML_m, XML_sSubSup );
     348             :     }
     349          80 :     else if(( flags & ( 1 << RSUB )) == 1 << RSUB )
     350             :     { // m:sSub
     351          16 :         m_pSerializer->startElementNS( XML_m, XML_sSub, FSEND );
     352          16 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     353          16 :         flags &= ~( 1 << RSUB );
     354          16 :         if( flags == 0 )
     355          16 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     356             :         else
     357           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     358          16 :         m_pSerializer->endElementNS( XML_m, XML_e );
     359          16 :         m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     360          16 :         HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
     361          16 :         m_pSerializer->endElementNS( XML_m, XML_sub );
     362          16 :         m_pSerializer->endElementNS( XML_m, XML_sSub );
     363             :     }
     364          64 :     else if(( flags & ( 1 << RSUP )) == 1 << RSUP )
     365             :     { // m:sSup
     366          56 :         m_pSerializer->startElementNS( XML_m, XML_sSup, FSEND );
     367          56 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     368          56 :         flags &= ~( 1 << RSUP );
     369          56 :         if( flags == 0 )
     370          56 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     371             :         else
     372           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     373          56 :         m_pSerializer->endElementNS( XML_m, XML_e );
     374          56 :         m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     375          56 :         HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
     376          56 :         m_pSerializer->endElementNS( XML_m, XML_sup );
     377          56 :         m_pSerializer->endElementNS( XML_m, XML_sSup );
     378             :     }
     379           8 :     else if(( flags & ( 1 << LSUP | 1 << LSUB )) == ( 1 << LSUP | 1 << LSUB ))
     380             :     { // m:sPre
     381           4 :         m_pSerializer->startElementNS( XML_m, XML_sPre, FSEND );
     382           4 :         m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     383           4 :         HandleNode( pNode->GetSubSup( LSUB ), nLevel + 1 );
     384           4 :         m_pSerializer->endElementNS( XML_m, XML_sub );
     385           4 :         m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     386           4 :         HandleNode( pNode->GetSubSup( LSUP ), nLevel + 1 );
     387           4 :         m_pSerializer->endElementNS( XML_m, XML_sup );
     388           4 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     389           4 :         flags &= ~( 1 << LSUP | 1 << LSUB );
     390           4 :         if( flags == 0 )
     391           4 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     392             :         else
     393           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     394           4 :         m_pSerializer->endElementNS( XML_m, XML_e );
     395           4 :         m_pSerializer->endElementNS( XML_m, XML_sPre );
     396             :     }
     397           4 :     else if(( flags & ( 1 << CSUB )) == ( 1 << CSUB ))
     398             :     { // m:limLow looks like a good element for central superscript
     399           2 :         m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
     400           2 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     401           2 :         flags &= ~( 1 << CSUB );
     402           2 :         if( flags == 0 )
     403           0 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     404             :         else
     405           2 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     406           2 :         m_pSerializer->endElementNS( XML_m, XML_e );
     407           2 :         m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     408           2 :         HandleNode( pNode->GetSubSup( CSUB ), nLevel + 1 );
     409           2 :         m_pSerializer->endElementNS( XML_m, XML_lim );
     410           2 :         m_pSerializer->endElementNS( XML_m, XML_limLow );
     411             :     }
     412           2 :     else if(( flags & ( 1 << CSUP )) == ( 1 << CSUP ))
     413             :     { // m:limUpp looks like a good element for central superscript
     414           2 :         m_pSerializer->startElementNS( XML_m, XML_limUpp, FSEND );
     415           2 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     416           2 :         flags &= ~( 1 << CSUP );
     417           2 :         if( flags == 0 )
     418           2 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     419             :         else
     420           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     421           2 :         m_pSerializer->endElementNS( XML_m, XML_e );
     422           2 :         m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     423           2 :         HandleNode( pNode->GetSubSup( CSUP ), nLevel + 1 );
     424           2 :         m_pSerializer->endElementNS( XML_m, XML_lim );
     425           2 :         m_pSerializer->endElementNS( XML_m, XML_limUpp );
     426             :     }
     427             :     else
     428             :     {
     429             :         SAL_WARN("starmath.ooxml", "Unhandled sub/sup combination");
     430             :         // TODO do not do anything, this should be probably an assert()
     431             :         // HandleAllSubNodes( pNode, nLevel );
     432             :     }
     433             : }
     434             : 
     435           2 : void SmOoxmlExport::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
     436             : {
     437           2 :     m_pSerializer->startElementNS( XML_m, XML_m, FSEND );
     438           6 :     for( int row = 0; row < pNode->GetNumRows(); ++row )
     439             :     {
     440           4 :         m_pSerializer->startElementNS( XML_m, XML_mr, FSEND );
     441          12 :         for( int col = 0; col < pNode->GetNumCols(); ++col )
     442             :         {
     443           8 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     444           8 :             if( const SmNode* node = pNode->GetSubNode( row * pNode->GetNumCols() + col ))
     445           8 :                 HandleNode( node, nLevel + 1 );
     446           8 :             m_pSerializer->endElementNS( XML_m, XML_e );
     447             :         }
     448           4 :         m_pSerializer->endElementNS( XML_m, XML_mr );
     449             :     }
     450           2 :     m_pSerializer->endElementNS( XML_m, XML_m );
     451           2 : }
     452             : 
     453          68 : void SmOoxmlExport::HandleBrace( const SmBraceNode* pNode, int nLevel )
     454             : {
     455          68 :     m_pSerializer->startElementNS( XML_m, XML_d, FSEND );
     456          68 :     m_pSerializer->startElementNS( XML_m, XML_dPr, FSEND );
     457             : 
     458             :     //check if the node has an opening brace
     459          68 :     if( TNONE == pNode->GetSubNode(0)->GetToken().eType )
     460             :         m_pSerializer->singleElementNS( XML_m, XML_begChr,
     461           2 :             FSNS( XML_m, XML_val ), "", FSEND );
     462             :     else
     463             :         m_pSerializer->singleElementNS( XML_m, XML_begChr,
     464          66 :             FSNS( XML_m, XML_val ), mathSymbolToString( pNode->OpeningBrace()).getStr(), FSEND );
     465             : 
     466          68 :     std::vector< const SmNode* > subnodes;
     467          68 :     if( pNode->Body()->GetType() == NBRACEBODY )
     468             :     {
     469          68 :         const SmBracebodyNode* body = static_cast< const SmBracebodyNode* >( pNode->Body());
     470          68 :         bool separatorWritten = false; // assume all separators are the same
     471         142 :         for( int i = 0; i < body->GetNumSubNodes(); ++i )
     472             :         {
     473          74 :             const SmNode* subnode = body->GetSubNode( i );
     474          74 :             if (subnode->GetType() == NMATH || subnode->GetType() == NMATHIDENT)
     475             :             { // do not write, but write what separator it is
     476           6 :                 const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
     477           6 :                 if( !separatorWritten )
     478             :                 {
     479             :                     m_pSerializer->singleElementNS( XML_m, XML_sepChr,
     480           4 :                         FSNS( XML_m, XML_val ), mathSymbolToString( math ).getStr(), FSEND );
     481           4 :                     separatorWritten = true;
     482             :                 }
     483             :             }
     484             :             else
     485          68 :                 subnodes.push_back( subnode );
     486             :         }
     487             :     }
     488             :     else
     489           0 :         subnodes.push_back( pNode->Body());
     490             : 
     491          68 :     if( TNONE == pNode->GetSubNode(2)->GetToken().eType )
     492             :         m_pSerializer->singleElementNS( XML_m, XML_endChr,
     493           2 :             FSNS( XML_m, XML_val ), "", FSEND );
     494             :     else
     495             :         m_pSerializer->singleElementNS( XML_m, XML_endChr,
     496          66 :             FSNS( XML_m, XML_val ), mathSymbolToString( pNode->ClosingBrace()).getStr(), FSEND );
     497             : 
     498          68 :     m_pSerializer->endElementNS( XML_m, XML_dPr );
     499         136 :     for( unsigned int i = 0; i < subnodes.size(); ++i )
     500             :     {
     501          68 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     502          68 :         HandleNode( subnodes[ i ], nLevel + 1 );
     503          68 :         m_pSerializer->endElementNS( XML_m, XML_e );
     504             :     }
     505          68 :     m_pSerializer->endElementNS( XML_m, XML_d );
     506          68 : }
     507             : 
     508           4 : void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel )
     509             : {
     510             :     SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode->GetToken().eType ));
     511           4 :     switch( pNode->GetToken().eType )
     512             :     {
     513             :         case TOVERBRACE:
     514             :         case TUNDERBRACE:
     515             :         {
     516           4 :             bool top = ( pNode->GetToken().eType == TOVERBRACE );
     517           4 :             m_pSerializer->startElementNS( XML_m, top ? XML_limUpp : XML_limLow, FSEND );
     518           4 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     519           4 :             m_pSerializer->startElementNS( XML_m, XML_groupChr, FSEND );
     520           4 :             m_pSerializer->startElementNS( XML_m, XML_groupChrPr, FSEND );
     521             :             m_pSerializer->singleElementNS( XML_m, XML_chr,
     522           4 :                 FSNS( XML_m, XML_val ), mathSymbolToString( pNode->Brace()).getStr(), FSEND );
     523             :             // TODO not sure if pos and vertJc are correct
     524             :             m_pSerializer->singleElementNS( XML_m, XML_pos,
     525           4 :                 FSNS( XML_m, XML_val ), top ? "top" : "bot", FSEND );
     526           4 :             m_pSerializer->singleElementNS( XML_m, XML_vertJc, FSNS( XML_m, XML_val ), top ? "bot" : "top", FSEND );
     527           4 :             m_pSerializer->endElementNS( XML_m, XML_groupChrPr );
     528           4 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     529           4 :             HandleNode( pNode->Body(), nLevel + 1 );
     530           4 :             m_pSerializer->endElementNS( XML_m, XML_e );
     531           4 :             m_pSerializer->endElementNS( XML_m, XML_groupChr );
     532           4 :             m_pSerializer->endElementNS( XML_m, XML_e );
     533           4 :             m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     534           4 :             HandleNode( pNode->Script(), nLevel + 1 );
     535           4 :             m_pSerializer->endElementNS( XML_m, XML_lim );
     536           4 :             m_pSerializer->endElementNS( XML_m, top ? XML_limUpp : XML_limLow );
     537           4 :             break;
     538             :         }
     539             :         default:
     540             :             SAL_WARN("starmath.ooxml", "Unhandled vertical brace");
     541           0 :             HandleAllSubNodes( pNode, nLevel );
     542           0 :             break;
     543             :     }
     544           4 : }
     545             : 
     546           0 : void SmOoxmlExport::HandleBlank()
     547             : {
     548           0 :     m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
     549           0 :     m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
     550           0 :     m_pSerializer->write( " " );
     551           0 :     m_pSerializer->endElementNS( XML_m, XML_t );
     552           0 :     m_pSerializer->endElementNS( XML_m, XML_r );
     553          72 : }
     554             : 
     555             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10