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-17 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          84 : SmOoxmlExport::SmOoxmlExport( const SmNode* pIn, OoxmlVersion v )
      39             : : SmWordExportBase( pIn )
      40          84 : , version( v )
      41             : {
      42          84 : }
      43             : 
      44          84 : bool SmOoxmlExport::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serializer )
      45             : {
      46          84 :     if( m_pTree == NULL )
      47           0 :         return false;
      48          84 :     m_pSerializer = serializer;
      49             :     m_pSerializer->startElementNS( XML_m, XML_oMath,
      50          84 :         FSNS( XML_xmlns, XML_m ), "http://schemas.openxmlformats.org/officeDocument/2006/math", FSEND );
      51          84 :     HandleNode( m_pTree, 0 );
      52          84 :     m_pSerializer->endElementNS( XML_m, XML_oMath );
      53          84 :     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           8 : void SmOoxmlExport::HandleVerticalStack( const SmNode* pNode, int nLevel )
      60             : {
      61           8 :     m_pSerializer->startElementNS( XML_m, XML_eqArr, FSEND );
      62           8 :     int size = pNode->GetNumSubNodes();
      63          24 :     for( int i = 0;
      64             :          i < size;
      65             :          ++i )
      66             :     {
      67          16 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
      68          16 :         HandleNode( pNode->GetSubNode( i ), nLevel + 1 );
      69          16 :         m_pSerializer->endElementNS( XML_m, XML_e );
      70             :     }
      71           8 :     m_pSerializer->endElementNS( XML_m, XML_eqArr );
      72           8 : }
      73             : 
      74         484 : void SmOoxmlExport::HandleText( const SmNode* pNode, int /*nLevel*/)
      75             : {
      76         484 :     m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
      77             : 
      78         484 :     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         484 :     m_pSerializer->startElementNS( XML_m, XML_t, FSNS( XML_xml, XML_space ), "preserve", FSEND );
      86         484 :     SmTextNode* pTemp=(SmTextNode* )pNode;
      87             :     SAL_INFO( "starmath.ooxml", "Text:" << OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
      88        1038 :     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         554 :         sal_uInt16 nChar = pTemp->GetText()[i];
     108         554 :         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         484 :     m_pSerializer->endElementNS( XML_m, XML_t );
     141         484 :     m_pSerializer->endElementNS( XML_m, XML_r );
     142         484 : }
     143             : 
     144          30 : void SmOoxmlExport::HandleFractions( const SmNode* pNode, int nLevel, const char* type )
     145             : {
     146          30 :     m_pSerializer->startElementNS( XML_m, XML_f, FSEND );
     147          30 :     if( type != NULL )
     148             :     {
     149           2 :         m_pSerializer->startElementNS( XML_m, XML_fPr, FSEND );
     150           2 :         m_pSerializer->singleElementNS( XML_m, XML_type, FSNS( XML_m, XML_val ), type, FSEND );
     151           2 :         m_pSerializer->endElementNS( XML_m, XML_fPr );
     152             :     }
     153             :     OSL_ASSERT( pNode->GetNumSubNodes() == 3 );
     154          30 :     m_pSerializer->startElementNS( XML_m, XML_num, FSEND );
     155          30 :     HandleNode( pNode->GetSubNode( 0 ), nLevel + 1 );
     156          30 :     m_pSerializer->endElementNS( XML_m, XML_num );
     157          30 :     m_pSerializer->startElementNS( XML_m, XML_den, FSEND );
     158          30 :     HandleNode( pNode->GetSubNode( 2 ), nLevel + 1 );
     159          30 :     m_pSerializer->endElementNS( XML_m, XML_den );
     160          30 :     m_pSerializer->endElementNS( XML_m, XML_f );
     161          30 : }
     162             : 
     163          28 : void SmOoxmlExport::HandleAttribute( const SmAttributNode* pNode, int nLevel )
     164             : {
     165          28 :     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          24 :             m_pSerializer->startElementNS( XML_m, XML_acc, FSEND );
     184          24 :             m_pSerializer->startElementNS( XML_m, XML_accPr, FSEND );
     185             :             OString value = OUStringToOString(
     186          24 :                 OUString( pNode->Attribute()->GetToken().cMathChar ), RTL_TEXTENCODING_UTF8 );
     187          24 :             m_pSerializer->singleElementNS( XML_m, XML_chr, FSNS( XML_m, XML_val ), value.getStr(), FSEND );
     188          24 :             m_pSerializer->endElementNS( XML_m, XML_accPr );
     189          24 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     190          24 :             HandleNode( pNode->Body(), nLevel + 1 );
     191          24 :             m_pSerializer->endElementNS( XML_m, XML_e );
     192          24 :             m_pSerializer->endElementNS( XML_m, XML_acc );
     193          24 :             break;
     194             :         }
     195             :         case TOVERLINE:
     196             :         case TUNDERLINE:
     197           2 :             m_pSerializer->startElementNS( XML_m, XML_bar, FSEND );
     198           2 :             m_pSerializer->startElementNS( XML_m, XML_barPr, FSEND );
     199             :             m_pSerializer->singleElementNS( XML_m, XML_pos, FSNS( XML_m, XML_val ),
     200           2 :                 ( pNode->Attribute()->GetToken().eType == TUNDERLINE ) ? "bot" : "top", FSEND );
     201           2 :             m_pSerializer->endElementNS( XML_m, XML_barPr );
     202           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     203           2 :             HandleNode( pNode->Body(), nLevel + 1 );
     204           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     205           2 :             m_pSerializer->endElementNS( XML_m, XML_bar );
     206           2 :             break;
     207             :         case TOVERSTRIKE:
     208           2 :             m_pSerializer->startElementNS( XML_m, XML_borderBox, FSEND );
     209           2 :             m_pSerializer->startElementNS( XML_m, XML_borderBoxPr, FSEND );
     210           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideTop, FSNS( XML_m, XML_val ), "1", FSEND );
     211           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideBot, FSNS( XML_m, XML_val ), "1", FSEND );
     212           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideLeft, FSNS( XML_m, XML_val ), "1", FSEND );
     213           2 :             m_pSerializer->singleElementNS( XML_m, XML_hideRight, FSNS( XML_m, XML_val ), "1", FSEND );
     214           2 :             m_pSerializer->singleElementNS( XML_m, XML_strikeH, FSNS( XML_m, XML_val ), "1", FSEND );
     215           2 :             m_pSerializer->endElementNS( XML_m, XML_borderBoxPr );
     216           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     217           2 :             HandleNode( pNode->Body(), nLevel + 1 );
     218           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     219           2 :             m_pSerializer->endElementNS( XML_m, XML_borderBox );
     220           2 :             break;
     221             :         default:
     222           0 :             HandleAllSubNodes( pNode, nLevel );
     223           0 :             break;
     224             :     }
     225          28 : }
     226             : 
     227           6 : void SmOoxmlExport::HandleRoot( const SmRootNode* pNode, int nLevel )
     228             : {
     229           6 :     m_pSerializer->startElementNS( XML_m, XML_rad, FSEND );
     230           6 :     if( const SmNode* argument = pNode->Argument())
     231             :     {
     232           2 :         m_pSerializer->startElementNS( XML_m, XML_deg, FSEND );
     233           2 :         HandleNode( argument, nLevel + 1 );
     234           2 :         m_pSerializer->endElementNS( XML_m, XML_deg );
     235             :     }
     236             :     else
     237             :     {
     238           4 :         m_pSerializer->startElementNS( XML_m, XML_radPr, FSEND );
     239           4 :         m_pSerializer->singleElementNS( XML_m, XML_degHide, FSNS( XML_m, XML_val ), "1", FSEND );
     240           4 :         m_pSerializer->endElementNS( XML_m, XML_radPr );
     241           4 :         m_pSerializer->singleElementNS( XML_m, XML_deg, FSEND ); // empty but present
     242             :     }
     243           6 :     m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     244           6 :     HandleNode( pNode->Body(), nLevel + 1 );
     245           6 :     m_pSerializer->endElementNS( XML_m, XML_e );
     246           6 :     m_pSerializer->endElementNS( XML_m, XML_rad );
     247           6 : }
     248             : 
     249         108 : static OString mathSymbolToString( const SmNode* node )
     250             : {
     251             :     assert( node->GetType() == NMATH );
     252         108 :     const SmTextNode* txtnode = static_cast< const SmTextNode* >( node );
     253             :     assert( txtnode->GetText().getLength() == 1 );
     254         108 :     sal_Unicode chr = SmTextNode::ConvertSymbolToUnicode( txtnode->GetText()[0] );
     255         108 :     return OUStringToOString( OUString( chr ), RTL_TEXTENCODING_UTF8 );
     256             : }
     257             : 
     258          14 : void SmOoxmlExport::HandleOperator( const SmOperNode* pNode, int nLevel )
     259             : {
     260             :     SAL_INFO( "starmath.ooxml", "Operator: " << int( pNode->GetToken().eType ));
     261          14 :     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          12 :             const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
     274          12 :                 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL;
     275          12 :             const SmNode* operation = subsup != NULL ? subsup->GetBody() : pNode->GetSubNode( 0 );
     276          12 :             m_pSerializer->startElementNS( XML_m, XML_nary, FSEND );
     277          12 :             m_pSerializer->startElementNS( XML_m, XML_naryPr, FSEND );
     278             :             m_pSerializer->singleElementNS( XML_m, XML_chr,
     279          12 :                 FSNS( XML_m, XML_val ), mathSymbolToString( operation ).getStr(), FSEND );
     280          12 :             if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
     281           2 :                 m_pSerializer->singleElementNS( XML_m, XML_subHide, FSNS( XML_m, XML_val ), "1", FSEND );
     282          12 :             if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
     283           2 :                 m_pSerializer->singleElementNS( XML_m, XML_supHide, FSNS( XML_m, XML_val ), "1", FSEND );
     284          12 :             m_pSerializer->endElementNS( XML_m, XML_naryPr );
     285          12 :             if( subsup == NULL || subsup->GetSubSup( CSUB ) == NULL )
     286           2 :                 m_pSerializer->singleElementNS( XML_m, XML_sub, FSEND );
     287             :             else
     288             :             {
     289          10 :                 m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     290          10 :                 HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
     291          10 :                 m_pSerializer->endElementNS( XML_m, XML_sub );
     292             :             }
     293          12 :             if( subsup == NULL || subsup->GetSubSup( CSUP ) == NULL )
     294           2 :                 m_pSerializer->singleElementNS( XML_m, XML_sup, FSEND );
     295             :             else
     296             :             {
     297          10 :                 m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     298          10 :                 HandleNode( subsup->GetSubSup( CSUP ), nLevel + 1 );
     299          10 :                 m_pSerializer->endElementNS( XML_m, XML_sup );
     300             :             }
     301          12 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     302          12 :             HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
     303          12 :             m_pSerializer->endElementNS( XML_m, XML_e );
     304          12 :             m_pSerializer->endElementNS( XML_m, XML_nary );
     305          12 :             break;
     306             :         }
     307             :         case TLIM:
     308           2 :             m_pSerializer->startElementNS( XML_m, XML_func, FSEND );
     309           2 :             m_pSerializer->startElementNS( XML_m, XML_fName, FSEND );
     310           2 :             m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
     311           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     312           2 :             HandleNode( pNode->GetSymbol(), nLevel + 1 );
     313           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     314           2 :             m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     315           4 :             if( const SmSubSupNode* subsup = pNode->GetSubNode( 0 )->GetType() == NSUBSUP
     316           2 :                 ? static_cast< const SmSubSupNode* >( pNode->GetSubNode( 0 )) : NULL )
     317             :             {
     318           2 :                 if( subsup->GetSubSup( CSUB ) != NULL )
     319           2 :                     HandleNode( subsup->GetSubSup( CSUB ), nLevel + 1 );
     320             :             }
     321           2 :             m_pSerializer->endElementNS( XML_m, XML_lim );
     322           2 :             m_pSerializer->endElementNS( XML_m, XML_limLow );
     323           2 :             m_pSerializer->endElementNS( XML_m, XML_fName );
     324           2 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     325           2 :             HandleNode( pNode->GetSubNode( 1 ), nLevel + 1 ); // body
     326           2 :             m_pSerializer->endElementNS( XML_m, XML_e );
     327           2 :             m_pSerializer->endElementNS( XML_m, XML_func );
     328           2 :             break;
     329             :         default:
     330             :             OSL_FAIL( "Unhandled operation" );
     331           0 :             HandleAllSubNodes( pNode, nLevel );
     332           0 :             break;
     333             :     }
     334          14 : }
     335             : 
     336          52 : 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          52 :     if( flags == 0 ) // none
     341          52 :         return;
     342          52 :     if(( flags & ( 1 << RSUP | 1 << RSUB )) == ( 1 << RSUP | 1 << RSUB ))
     343             :     { // m:sSubSup
     344           4 :         m_pSerializer->startElementNS( XML_m, XML_sSubSup, FSEND );
     345           4 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     346           4 :         flags &= ~( 1 << RSUP | 1 << RSUB );
     347           4 :         if( flags == 0 )
     348           4 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     349             :         else
     350           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     351           4 :         m_pSerializer->endElementNS( XML_m, XML_e );
     352           4 :         m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     353           4 :         HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
     354           4 :         m_pSerializer->endElementNS( XML_m, XML_sub );
     355           4 :         m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     356           4 :         HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
     357           4 :         m_pSerializer->endElementNS( XML_m, XML_sup );
     358           4 :         m_pSerializer->endElementNS( XML_m, XML_sSubSup );
     359             :     }
     360          48 :     else if(( flags & ( 1 << RSUB )) == 1 << RSUB )
     361             :     { // m:sSub
     362           8 :         m_pSerializer->startElementNS( XML_m, XML_sSub, FSEND );
     363           8 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     364           8 :         flags &= ~( 1 << RSUB );
     365           8 :         if( flags == 0 )
     366           8 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     367             :         else
     368           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     369           8 :         m_pSerializer->endElementNS( XML_m, XML_e );
     370           8 :         m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     371           8 :         HandleNode( pNode->GetSubSup( RSUB ), nLevel + 1 );
     372           8 :         m_pSerializer->endElementNS( XML_m, XML_sub );
     373           8 :         m_pSerializer->endElementNS( XML_m, XML_sSub );
     374             :     }
     375          40 :     else if(( flags & ( 1 << RSUP )) == 1 << RSUP )
     376             :     { // m:sSup
     377          32 :         m_pSerializer->startElementNS( XML_m, XML_sSup, FSEND );
     378          32 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     379          32 :         flags &= ~( 1 << RSUP );
     380          32 :         if( flags == 0 )
     381          32 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     382             :         else
     383           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     384          32 :         m_pSerializer->endElementNS( XML_m, XML_e );
     385          32 :         m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     386          32 :         HandleNode( pNode->GetSubSup( RSUP ), nLevel + 1 );
     387          32 :         m_pSerializer->endElementNS( XML_m, XML_sup );
     388          32 :         m_pSerializer->endElementNS( XML_m, XML_sSup );
     389             :     }
     390           8 :     else if(( flags & ( 1 << LSUP | 1 << LSUB )) == ( 1 << LSUP | 1 << LSUB ))
     391             :     { // m:sPre
     392           4 :         m_pSerializer->startElementNS( XML_m, XML_sPre, FSEND );
     393           4 :         m_pSerializer->startElementNS( XML_m, XML_sub, FSEND );
     394           4 :         HandleNode( pNode->GetSubSup( LSUB ), nLevel + 1 );
     395           4 :         m_pSerializer->endElementNS( XML_m, XML_sub );
     396           4 :         m_pSerializer->startElementNS( XML_m, XML_sup, FSEND );
     397           4 :         HandleNode( pNode->GetSubSup( LSUP ), nLevel + 1 );
     398           4 :         m_pSerializer->endElementNS( XML_m, XML_sup );
     399           4 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     400           4 :         flags &= ~( 1 << LSUP | 1 << LSUB );
     401           4 :         if( flags == 0 )
     402           4 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     403             :         else
     404           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     405           4 :         m_pSerializer->endElementNS( XML_m, XML_e );
     406           4 :         m_pSerializer->endElementNS( XML_m, XML_sPre );
     407             :     }
     408           4 :     else if(( flags & ( 1 << CSUB )) == ( 1 << CSUB ))
     409             :     { // m:limLow looks like a good element for central superscript
     410           2 :         m_pSerializer->startElementNS( XML_m, XML_limLow, FSEND );
     411           2 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     412           2 :         flags &= ~( 1 << CSUB );
     413           2 :         if( flags == 0 )
     414           0 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     415             :         else
     416           2 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     417           2 :         m_pSerializer->endElementNS( XML_m, XML_e );
     418           2 :         m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     419           2 :         HandleNode( pNode->GetSubSup( CSUB ), nLevel + 1 );
     420           2 :         m_pSerializer->endElementNS( XML_m, XML_lim );
     421           2 :         m_pSerializer->endElementNS( XML_m, XML_limLow );
     422             :     }
     423           2 :     else if(( flags & ( 1 << CSUP )) == ( 1 << CSUP ))
     424             :     { // m:limUpp looks like a good element for central superscript
     425           2 :         m_pSerializer->startElementNS( XML_m, XML_limUpp, FSEND );
     426           2 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     427           2 :         flags &= ~( 1 << CSUP );
     428           2 :         if( flags == 0 )
     429           2 :             HandleNode( pNode->GetBody(), nLevel + 1 );
     430             :         else
     431           0 :             HandleSubSupScriptInternal( pNode, nLevel, flags );
     432           2 :         m_pSerializer->endElementNS( XML_m, XML_e );
     433           2 :         m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     434           2 :         HandleNode( pNode->GetSubSup( CSUP ), nLevel + 1 );
     435           2 :         m_pSerializer->endElementNS( XML_m, XML_lim );
     436           2 :         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           2 : void SmOoxmlExport::HandleMatrix( const SmMatrixNode* pNode, int nLevel )
     447             : {
     448           2 :     m_pSerializer->startElementNS( XML_m, XML_m, FSEND );
     449           6 :     for( int row = 0; row < pNode->GetNumRows(); ++row )
     450             :     {
     451           4 :         m_pSerializer->startElementNS( XML_m, XML_mr, FSEND );
     452          12 :         for( int col = 0; col < pNode->GetNumCols(); ++col )
     453             :         {
     454           8 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     455           8 :             if( const SmNode* node = pNode->GetSubNode( row * pNode->GetNumCols() + col ))
     456           8 :                 HandleNode( node, nLevel + 1 );
     457           8 :             m_pSerializer->endElementNS( XML_m, XML_e );
     458             :         }
     459           4 :         m_pSerializer->endElementNS( XML_m, XML_mr );
     460             :     }
     461           2 :     m_pSerializer->endElementNS( XML_m, XML_m );
     462           2 : }
     463             : 
     464          44 : void SmOoxmlExport::HandleBrace( const SmBraceNode* pNode, int nLevel )
     465             : {
     466          44 :     m_pSerializer->startElementNS( XML_m, XML_d, FSEND );
     467          44 :     m_pSerializer->startElementNS( XML_m, XML_dPr, FSEND );
     468             :     m_pSerializer->singleElementNS( XML_m, XML_begChr,
     469          44 :         FSNS( XML_m, XML_val ), mathSymbolToString( pNode->OpeningBrace()).getStr(), FSEND );
     470          44 :     std::vector< const SmNode* > subnodes;
     471          44 :     if( pNode->Body()->GetType() == NBRACEBODY )
     472             :     {
     473          44 :         const SmBracebodyNode* body = static_cast< const SmBracebodyNode* >( pNode->Body());
     474          44 :         bool separatorWritten = false; // assume all separators are the same
     475          96 :         for( int i = 0; i < body->GetNumSubNodes(); ++i )
     476             :         {
     477          52 :             const SmNode* subnode = body->GetSubNode( i );
     478          52 :             if( subnode->GetType() == NMATH )
     479             :             { // do not write, but write what separator it is
     480           6 :                 const SmMathSymbolNode* math = static_cast< const SmMathSymbolNode* >( subnode );
     481           6 :                 if( !separatorWritten )
     482             :                 {
     483             :                     m_pSerializer->singleElementNS( XML_m, XML_sepChr,
     484           4 :                         FSNS( XML_m, XML_val ), mathSymbolToString( math ).getStr(), FSEND );
     485           4 :                     separatorWritten = true;
     486             :                 }
     487             :             }
     488             :             else
     489          46 :                 subnodes.push_back( subnode );
     490             :         }
     491             :     }
     492             :     else
     493           0 :         subnodes.push_back( pNode->Body());
     494             :     m_pSerializer->singleElementNS( XML_m, XML_endChr,
     495          44 :         FSNS( XML_m, XML_val ), mathSymbolToString( pNode->ClosingBrace()).getStr(), FSEND );
     496          44 :     m_pSerializer->endElementNS( XML_m, XML_dPr );
     497          90 :     for( unsigned int i = 0; i < subnodes.size(); ++i )
     498             :     {
     499          46 :         m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     500          46 :         HandleNode( subnodes[ i ], nLevel + 1 );
     501          46 :         m_pSerializer->endElementNS( XML_m, XML_e );
     502             :     }
     503          44 :     m_pSerializer->endElementNS( XML_m, XML_d );
     504          44 : }
     505             : 
     506           4 : void SmOoxmlExport::HandleVerticalBrace( const SmVerticalBraceNode* pNode, int nLevel )
     507             : {
     508             :     SAL_INFO( "starmath.ooxml", "Vertical: " << int( pNode->GetToken().eType ));
     509           4 :     switch( pNode->GetToken().eType )
     510             :     {
     511             :         case TOVERBRACE:
     512             :         case TUNDERBRACE:
     513             :         {
     514           4 :             bool top = ( pNode->GetToken().eType == TOVERBRACE );
     515           4 :             m_pSerializer->startElementNS( XML_m, top ? XML_limUpp : XML_limLow, FSEND );
     516           4 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     517           4 :             m_pSerializer->startElementNS( XML_m, XML_groupChr, FSEND );
     518           4 :             m_pSerializer->startElementNS( XML_m, XML_groupChrPr, FSEND );
     519             :             m_pSerializer->singleElementNS( XML_m, XML_chr,
     520           4 :                 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           4 :                 FSNS( XML_m, XML_val ), top ? "top" : "bot", FSEND );
     524           4 :             m_pSerializer->singleElementNS( XML_m, XML_vertJc, FSNS( XML_m, XML_val ), top ? "bot" : "top", FSEND );
     525           4 :             m_pSerializer->endElementNS( XML_m, XML_groupChrPr );
     526           4 :             m_pSerializer->startElementNS( XML_m, XML_e, FSEND );
     527           4 :             HandleNode( pNode->Body(), nLevel + 1 );
     528           4 :             m_pSerializer->endElementNS( XML_m, XML_e );
     529           4 :             m_pSerializer->endElementNS( XML_m, XML_groupChr );
     530           4 :             m_pSerializer->endElementNS( XML_m, XML_e );
     531           4 :             m_pSerializer->startElementNS( XML_m, XML_lim, FSEND );
     532           4 :             HandleNode( pNode->Script(), nLevel + 1 );
     533           4 :             m_pSerializer->endElementNS( XML_m, XML_lim );
     534           4 :             m_pSerializer->endElementNS( XML_m, top ? XML_limUpp : XML_limLow );
     535           4 :             break;
     536             :         }
     537             :         default:
     538             :             OSL_FAIL( "Unhandled vertical brace" );
     539           0 :             HandleAllSubNodes( pNode, nLevel );
     540           0 :             break;
     541             :     }
     542           4 : }
     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          18 : }
     552             : 
     553             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10