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

Generated by: LCOV version 1.10