LCOV - code coverage report
Current view: top level - starmath/source - mathmlexport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 511 679 75.3 %
Date: 2012-08-25 Functions: 45 50 90.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 473 1108 42.7 %

           Branch data     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                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : 
      21                 :            : /*
      22                 :            :  Warning: The SvXMLElementExport helper class creates the beginning and
      23                 :            :  closing tags of xml elements in its constructor and destructor, so theres
      24                 :            :  hidden stuff going on, on occasion the ordering of these classes declarations
      25                 :            :  may be significant
      26                 :            : */
      27                 :            : 
      28                 :            : 
      29                 :            : #include <com/sun/star/xml/sax/XErrorHandler.hpp>
      30                 :            : #include <com/sun/star/xml/sax/XEntityResolver.hpp>
      31                 :            : #include <com/sun/star/xml/sax/InputSource.hpp>
      32                 :            : #include <com/sun/star/xml/sax/XDTDHandler.hpp>
      33                 :            : #include <com/sun/star/xml/sax/XParser.hpp>
      34                 :            : #include <com/sun/star/io/XActiveDataSource.hpp>
      35                 :            : #include <com/sun/star/io/XActiveDataControl.hpp>
      36                 :            : #include <com/sun/star/document/XDocumentProperties.hpp>
      37                 :            : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      38                 :            : #include <com/sun/star/packages/zip/ZipIOException.hpp>
      39                 :            : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
      40                 :            : #include <com/sun/star/beans/PropertyAttribute.hpp>
      41                 :            : #include <com/sun/star/container/XNameAccess.hpp>
      42                 :            : #include <com/sun/star/embed/ElementModes.hpp>
      43                 :            : #include <com/sun/star/util/MeasureUnit.hpp>
      44                 :            : #include <com/sun/star/uno/Any.h>
      45                 :            : 
      46                 :            : #include <rtl/math.hxx>
      47                 :            : #include <sfx2/frame.hxx>
      48                 :            : #include <sfx2/docfile.hxx>
      49                 :            : #include <osl/diagnose.h>
      50                 :            : #include <svtools/sfxecode.hxx>
      51                 :            : #include <unotools/saveopt.hxx>
      52                 :            : #include <svl/stritem.hxx>
      53                 :            : #include <svl/itemprop.hxx>
      54                 :            : #include <comphelper/processfactory.hxx>
      55                 :            : #include <unotools/streamwrap.hxx>
      56                 :            : #include <sax/tools/converter.hxx>
      57                 :            : #include <xmloff/xmlnmspe.hxx>
      58                 :            : #include <xmloff/xmltoken.hxx>
      59                 :            : #include <xmloff/nmspmap.hxx>
      60                 :            : #include <xmloff/attrlist.hxx>
      61                 :            : #include <xmloff/xmlmetai.hxx>
      62                 :            : #include <osl/mutex.hxx>
      63                 :            : #include <comphelper/genericpropertyset.hxx>
      64                 :            : #include <comphelper/servicehelper.hxx>
      65                 :            : 
      66                 :            : #include <memory>
      67                 :            : 
      68                 :            : #include "mathmlexport.hxx"
      69                 :            : #include <starmath.hrc>
      70                 :            : #include <unomodel.hxx>
      71                 :            : #include <document.hxx>
      72                 :            : #include <utility.hxx>
      73                 :            : #include <config.hxx>
      74                 :            : 
      75                 :            : using namespace ::com::sun::star::beans;
      76                 :            : using namespace ::com::sun::star::container;
      77                 :            : using namespace ::com::sun::star::document;
      78                 :            : using namespace ::com::sun::star::lang;
      79                 :            : using namespace ::com::sun::star::uno;
      80                 :            : using namespace ::com::sun::star;
      81                 :            : using namespace ::xmloff::token;
      82                 :            : 
      83                 :            : using ::rtl::OUString;
      84                 :            : using ::rtl::OUStringBuffer;
      85                 :            : 
      86                 :            : #define EXPORT_SVC_NAME "com.sun.star.xml.XMLExportFilter"
      87                 :            : 
      88                 :            : #undef WANTEXCEPT
      89                 :            : 
      90                 :            : 
      91                 :            : ////////////////////////////////////////////////////////////
      92                 :            : 
      93                 :        852 : sal_Bool SmXMLExportWrapper::Export(SfxMedium &rMedium)
      94                 :            : {
      95                 :        852 :     sal_Bool bRet=sal_True;
      96                 :            :     uno::Reference<lang::XMultiServiceFactory>
      97         [ +  - ]:        852 :         xServiceFactory(comphelper::getProcessServiceFactory());
      98                 :            :     OSL_ENSURE(xServiceFactory.is(),"got no service manager");
      99                 :            : 
     100                 :            :     //Get model
     101         [ +  - ]:        852 :     uno::Reference< lang::XComponent > xModelComp(xModel, uno::UNO_QUERY );
     102                 :            : 
     103                 :        852 :     sal_Bool bEmbedded = sal_False;
     104                 :        852 :     uno::Reference <lang::XUnoTunnel> xTunnel;
     105 [ +  - ][ +  - ]:        852 :     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
     106                 :            :     SmModel *pModel = reinterpret_cast<SmModel *>
     107 [ +  - ][ +  - ]:        852 :         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
                 [ +  - ]
     108                 :            : 
     109                 :            :     SmDocShell *pDocShell = pModel ?
     110 [ +  - ][ +  - ]:        852 :             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
     111   [ +  -  +  - ]:       1704 :     if ( pDocShell &&
                 [ +  - ]
     112                 :        852 :         SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
     113                 :        852 :         bEmbedded = sal_True;
     114                 :            : 
     115                 :        852 :     uno::Reference<task::XStatusIndicator> xStatusIndicator;
     116         [ -  + ]:        852 :     if (!bEmbedded)
     117                 :            :     {
     118         [ #  # ]:          0 :         if (pDocShell /*&& pDocShell->GetMedium()*/)
     119                 :            :         {
     120                 :            :             OSL_ENSURE( pDocShell->GetMedium() == &rMedium,
     121                 :            :                     "different SfxMedium found" );
     122                 :            : 
     123         [ #  # ]:          0 :             SfxItemSet* pSet = rMedium.GetItemSet();
     124         [ #  # ]:          0 :             if (pSet)
     125                 :            :             {
     126                 :            :                 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
     127         [ #  # ]:          0 :                     pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
     128         [ #  # ]:          0 :                 if (pItem)
     129         [ #  # ]:          0 :                     pItem->GetValue() >>= xStatusIndicator;
     130                 :            :             }
     131                 :            :         }
     132                 :            : 
     133                 :            :         // set progress range and start status indicator
     134         [ #  # ]:          0 :         if (xStatusIndicator.is())
     135                 :            :         {
     136         [ #  # ]:          0 :             sal_Int32 nProgressRange = bFlat ? 1 : 3;
     137         [ #  # ]:          0 :             xStatusIndicator->start(String(SmResId(STR_STATSTR_WRITING)),
     138 [ #  # ][ #  # ]:          0 :                 nProgressRange);
         [ #  # ][ #  # ]
                 [ #  # ]
     139                 :            :         }
     140                 :            :     }
     141                 :            : 
     142                 :            : 
     143                 :            :     // create XPropertySet with three properties for status indicator
     144                 :            :     comphelper::PropertyMapEntry aInfoMap[] =
     145                 :            :     {
     146                 :            :         { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
     147         [ +  - ]:        852 :               &::getBooleanCppuType(),
     148                 :            :               beans::PropertyAttribute::MAYBEVOID, 0},
     149                 :            :         { "BaseURI", sizeof("BaseURI")-1, 0,
     150         [ +  - ]:        852 :               &::getCppuType( (OUString *)0 ),
     151                 :            :               beans::PropertyAttribute::MAYBEVOID, 0 },
     152                 :            :         { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
     153         [ +  - ]:        852 :               &::getCppuType( (OUString *)0 ),
     154                 :            :               beans::PropertyAttribute::MAYBEVOID, 0 },
     155                 :            :         { "StreamName", sizeof("StreamName")-1, 0,
     156         [ +  - ]:        852 :               &::getCppuType( (OUString *)0 ),
     157                 :            :               beans::PropertyAttribute::MAYBEVOID, 0 },
     158                 :            :         { NULL, 0, 0, NULL, 0, 0 }
     159                 :       4260 :     };
     160                 :            :     uno::Reference< beans::XPropertySet > xInfoSet(
     161                 :            :                 comphelper::GenericPropertySet_CreateInstance(
     162         [ +  - ]:        852 :                             new comphelper::PropertySetInfo( aInfoMap ) ) );
     163                 :            : 
     164         [ +  - ]:        852 :     SvtSaveOptions aSaveOpt;
     165                 :        852 :     OUString sUsePrettyPrinting("UsePrettyPrinting");
     166 [ +  - ][ -  + ]:        852 :     sal_Bool bUsePrettyPrinting( bFlat || aSaveOpt.IsPrettyPrinting() );
                 [ +  - ]
     167                 :        852 :     Any aAny;
     168         [ +  - ]:        852 :     aAny.setValue( &bUsePrettyPrinting, ::getBooleanCppuType() );
     169 [ +  - ][ +  - ]:        852 :     xInfoSet->setPropertyValue( sUsePrettyPrinting, aAny );
     170                 :            : 
     171                 :            :     // Set base URI
     172                 :        852 :     OUString sPropName( "BaseURI" );
     173 [ +  - ][ +  - ]:        852 :     xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL( true ) ) );
         [ +  - ][ +  - ]
     174                 :            : 
     175                 :        852 :     sal_Int32 nSteps=0;
     176         [ -  + ]:        852 :     if (xStatusIndicator.is())
     177 [ #  # ][ #  # ]:          0 :             xStatusIndicator->setValue(nSteps++);
     178         [ +  - ]:        852 :     if (!bFlat) //Storage (Package) of Stream
     179                 :            :     {
     180         [ +  - ]:        852 :         uno::Reference < embed::XStorage > xStg = rMedium.GetOutputStorage();
     181         [ +  - ]:        852 :         sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
     182                 :            : 
     183                 :            :         // TODO/LATER: handle the case of embedded links gracefully
     184         [ +  - ]:        852 :         if ( bEmbedded ) //&& !pStg->IsRoot() )
     185                 :            :         {
     186                 :        852 :             OUString aName;
     187 [ +  - ][ +  - ]:        852 :             if ( rMedium.GetItemSet() )
     188                 :            :             {
     189                 :            :                 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
     190 [ +  - ][ +  - ]:        852 :                     rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
     191         [ +  - ]:        852 :                 if ( pDocHierarchItem )
     192         [ +  - ]:        852 :                     aName = pDocHierarchItem->GetValue();
     193                 :            :             }
     194                 :            : 
     195         [ +  - ]:        852 :             if ( !aName.isEmpty() )
     196                 :            :             {
     197                 :        852 :                 sPropName = "StreamRelPath";
     198 [ +  - ][ +  - ]:        852 :                 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
                 [ +  - ]
     199                 :        852 :             }
     200                 :            :         }
     201                 :            : 
     202         [ -  + ]:        852 :         if ( !bEmbedded )
     203                 :            :         {
     204         [ #  # ]:          0 :             if (xStatusIndicator.is())
     205 [ #  # ][ #  # ]:          0 :                 xStatusIndicator->setValue(nSteps++);
     206                 :            : 
     207                 :            :             bRet = WriteThroughComponent(
     208                 :            :                     xStg, xModelComp, "meta.xml", xServiceFactory, xInfoSet,
     209                 :            :                     (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaExporter"
     210                 :            :                             : "com.sun.star.comp.Math.XMLMetaExporter"),
     211 [ #  # ][ #  # ]:          0 :                     sal_False);
     212                 :            :         }
     213         [ +  - ]:        852 :         if ( bRet )
     214                 :            :         {
     215         [ -  + ]:        852 :            if (xStatusIndicator.is())
     216 [ #  # ][ #  # ]:          0 :                 xStatusIndicator->setValue(nSteps++);
     217                 :            : 
     218                 :            :             bRet = WriteThroughComponent(
     219                 :            :                     xStg, xModelComp, "content.xml", xServiceFactory, xInfoSet,
     220         [ +  - ]:        852 :                     "com.sun.star.comp.Math.XMLContentExporter");
     221                 :            :         }
     222                 :            : 
     223         [ +  - ]:        852 :         if ( bRet )
     224                 :            :         {
     225         [ -  + ]:        852 :             if (xStatusIndicator.is())
     226 [ #  # ][ #  # ]:          0 :                 xStatusIndicator->setValue(nSteps++);
     227                 :            : 
     228                 :            :             bRet = WriteThroughComponent(
     229                 :            :                     xStg, xModelComp, "settings.xml", xServiceFactory, xInfoSet,
     230                 :            :                     (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
     231 [ +  - ][ +  - ]:        852 :                             : "com.sun.star.comp.Math.XMLSettingsExporter") );
     232                 :        852 :         }
     233                 :            :     }
     234                 :            :     else
     235                 :            :     {
     236         [ #  # ]:          0 :         SvStream *pStream = rMedium.GetOutStream();
     237                 :            :         uno::Reference<io::XOutputStream> xOut(
     238 [ #  # ][ #  # ]:          0 :             new utl::OOutputStreamWrapper(*pStream) );
                 [ #  # ]
     239                 :            : 
     240         [ #  # ]:          0 :         if (xStatusIndicator.is())
     241 [ #  # ][ #  # ]:          0 :             xStatusIndicator->setValue(nSteps++);
     242                 :            : 
     243                 :            :         bRet = WriteThroughComponent(
     244                 :            :             xOut, xModelComp, xServiceFactory, xInfoSet,
     245         [ #  # ]:          0 :             "com.sun.star.comp.Math.XMLContentExporter");
     246                 :            :     }
     247                 :            : 
     248         [ -  + ]:        852 :     if (xStatusIndicator.is())
     249 [ #  # ][ #  # ]:          0 :         xStatusIndicator->end();
     250                 :            : 
     251         [ +  - ]:        852 :     return bRet;
     252                 :            : }
     253                 :            : 
     254                 :            : 
     255                 :            : /// export through an XML exporter component (output stream version)
     256                 :       1704 : sal_Bool SmXMLExportWrapper::WriteThroughComponent(
     257                 :            :     Reference<io::XOutputStream> xOutputStream,
     258                 :            :     Reference<XComponent> xComponent,
     259                 :            :     Reference<lang::XMultiServiceFactory> & rFactory,
     260                 :            :     Reference<beans::XPropertySet> & rPropSet,
     261                 :            :     const sal_Char* pComponentName )
     262                 :            : {
     263                 :            :     OSL_ENSURE(xOutputStream.is(), "I really need an output stream!");
     264                 :            :     OSL_ENSURE(xComponent.is(), "Need component!");
     265                 :            :     OSL_ENSURE(NULL != pComponentName, "Need component name!");
     266                 :            : 
     267                 :            :     // get component
     268                 :            :     Reference< io::XActiveDataSource > xSaxWriter(
     269         [ +  - ]:       1704 :         rFactory->createInstance( "com.sun.star.xml.sax.Writer" ),
     270 [ +  - ][ +  - ]:       1704 :         UNO_QUERY );
     271                 :            :     OSL_ENSURE( xSaxWriter.is(), "can't instantiate XML writer" );
     272         [ -  + ]:       1704 :     if (!xSaxWriter.is())
     273                 :          0 :         return sal_False;
     274                 :            : 
     275                 :            :     // connect XML writer to output stream
     276 [ +  - ][ +  - ]:       1704 :     xSaxWriter->setOutputStream( xOutputStream );
     277                 :            : 
     278                 :            :     // prepare arguments (prepend doc handler to given arguments)
     279         [ +  - ]:       1704 :     Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
     280                 :            : 
     281         [ +  - ]:       1704 :     Sequence<Any> aArgs( 2 );
     282 [ +  - ][ +  - ]:       1704 :     aArgs[0] <<= xDocHandler;
     283 [ +  - ][ +  - ]:       1704 :     aArgs[1] <<= rPropSet;
     284                 :            : 
     285                 :            :     // get filter component
     286                 :            :     Reference< document::XExporter > xExporter(
     287         [ +  - ]:       1704 :         rFactory->createInstanceWithArguments(
     288 [ +  - ][ +  - ]:       1704 :             OUString::createFromAscii(pComponentName), aArgs), UNO_QUERY);
     289                 :            :     OSL_ENSURE( xExporter.is(),
     290                 :            :             "can't instantiate export filter component" );
     291         [ -  + ]:       1704 :     if ( !xExporter.is() )
     292                 :          0 :         return sal_False;
     293                 :            : 
     294                 :            : 
     295                 :            :     // connect model and filter
     296 [ +  - ][ +  - ]:       1704 :     xExporter->setSourceDocument( xComponent );
     297                 :            : 
     298                 :            :     // filter!
     299         [ +  - ]:       1704 :     Reference < XFilter > xFilter( xExporter, UNO_QUERY );
     300         [ +  - ]:       1704 :     uno::Sequence< PropertyValue > aProps(0);
     301 [ +  - ][ +  - ]:       1704 :     xFilter->filter( aProps );
     302                 :            : 
     303                 :       1704 :     uno::Reference<lang::XUnoTunnel> xFilterTunnel;
     304                 :            :     xFilterTunnel = uno::Reference<lang::XUnoTunnel>
     305 [ +  - ][ +  - ]:       1704 :         ( xFilter, uno::UNO_QUERY );
     306                 :            :     SmXMLExport *pFilter = reinterpret_cast< SmXMLExport * >(
     307                 :            :                 sal::static_int_cast< sal_uIntPtr >(
     308 [ +  - ][ +  - ]:       1704 :                 xFilterTunnel->getSomething( SmXMLExport::getUnoTunnelId() )));
     309 [ +  - ][ +  - ]:       1704 :     return pFilter ? pFilter->GetSuccess() : sal_True;
                 [ +  - ]
     310                 :            : }
     311                 :            : 
     312                 :            : 
     313                 :            : /// export through an XML exporter component (storage version)
     314                 :       1704 : sal_Bool SmXMLExportWrapper::WriteThroughComponent(
     315                 :            :     const Reference < embed::XStorage >& xStorage,
     316                 :            :     Reference<XComponent> xComponent,
     317                 :            :     const sal_Char* pStreamName,
     318                 :            :     Reference<lang::XMultiServiceFactory> & rFactory,
     319                 :            :     Reference<beans::XPropertySet> & rPropSet,
     320                 :            :     const sal_Char* pComponentName,
     321                 :            :     sal_Bool bCompress
     322                 :            :     )
     323                 :            : {
     324                 :            :     OSL_ENSURE(xStorage.is(), "Need storage!");
     325                 :            :     OSL_ENSURE(NULL != pStreamName, "Need stream name!");
     326                 :            : 
     327                 :            :     // open stream
     328                 :       1704 :     Reference < io::XStream > xStream;
     329                 :       1704 :     OUString sStreamName = OUString::createFromAscii(pStreamName);
     330                 :            :     try
     331                 :            :     {
     332         [ +  - ]:       1704 :         xStream = xStorage->openStreamElement( sStreamName,
     333 [ +  - ][ +  - ]:       1704 :             embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
                 [ #  # ]
     334                 :            :     }
     335         [ #  # ]:          0 :     catch ( uno::Exception& )
     336                 :            :     {
     337                 :            :         OSL_FAIL( "Can't create output stream in package!" );
     338                 :          0 :         return sal_False;
     339                 :            :     }
     340                 :            : 
     341                 :       1704 :     OUString aPropName( "MediaType" );
     342                 :       1704 :     OUString aMime( "text/xml" );
     343                 :       1704 :     uno::Any aAny;
     344         [ +  - ]:       1704 :     aAny <<= aMime;
     345                 :            : 
     346         [ +  - ]:       1704 :     uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
     347 [ +  - ][ +  - ]:       1704 :     xSet->setPropertyValue( aPropName, aAny );
     348                 :            : 
     349         [ -  + ]:       1704 :     if ( !bCompress )
     350                 :            :     {
     351                 :          0 :         aPropName = "Compressed";
     352                 :          0 :         sal_Bool bFalse = sal_False;
     353         [ #  # ]:          0 :         aAny.setValue( &bFalse, ::getBooleanCppuType() );
     354 [ #  # ][ #  # ]:          0 :         xSet->setPropertyValue( aPropName, aAny );
     355                 :            :     }
     356                 :            : 
     357                 :            :     // even plain stream must be encrypted in encrypted document
     358                 :       1704 :     OUString aTmpPropName( "UseCommonStoragePasswordEncryption" );
     359                 :       1704 :     sal_Bool bTrue = sal_True;
     360         [ +  - ]:       1704 :     aAny.setValue( &bTrue, ::getBooleanCppuType() );
     361 [ +  - ][ +  - ]:       1704 :     xSet->setPropertyValue( aTmpPropName, aAny );
     362                 :            : 
     363                 :            :     // set Base URL
     364         [ +  - ]:       1704 :     if ( rPropSet.is() )
     365                 :            :     {
     366                 :       1704 :         OUString sPropName( "StreamName" );
     367 [ +  - ][ +  - ]:       1704 :         rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
                 [ +  - ]
     368                 :            :     }
     369                 :            : 
     370                 :            :     // write the stuff
     371         [ +  - ]:       1704 :     sal_Bool bRet = WriteThroughComponent( xStream->getOutputStream(), xComponent, rFactory,
     372 [ +  - ][ +  - ]:       3408 :         rPropSet, pComponentName );
     373                 :            : 
     374                 :       1704 :     return bRet;
     375                 :            : }
     376                 :            : 
     377                 :            : ////////////////////////////////////////////////////////////
     378                 :            : 
     379                 :       1716 : SmXMLExport::SmXMLExport(
     380                 :            :     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
     381                 :            :     sal_uInt16 nExportFlags)
     382                 :            : :   SvXMLExport(util::MeasureUnit::INCH, xServiceFactory, XML_MATH,
     383                 :            :                 nExportFlags)
     384                 :            : ,   pTree(0) ,
     385         [ +  - ]:       1716 :     bSuccess(sal_False)
     386                 :            : {
     387                 :       1716 : }
     388                 :            : 
     389                 :       1704 : sal_Int64 SAL_CALL SmXMLExport::getSomething(
     390                 :            :     const uno::Sequence< sal_Int8 >& rId )
     391                 :            : throw(uno::RuntimeException)
     392                 :            : {
     393   [ +  -  +  - ]:       3408 :     if ( rId.getLength() == 16 &&
                 [ +  - ]
     394                 :       1704 :         0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
     395                 :       3408 :         rId.getConstArray(), 16 ) )
     396                 :       1704 :     return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
     397                 :            : 
     398                 :       1704 :     return SvXMLExport::getSomething( rId );
     399                 :            : }
     400                 :            : 
     401                 :            : namespace
     402                 :            : {
     403                 :            :     class theSmXMLExportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSmXMLExportUnoTunnelId> {};
     404                 :            : }
     405                 :            : 
     406                 :       3408 : const uno::Sequence< sal_Int8 > & SmXMLExport::getUnoTunnelId() throw()
     407                 :            : {
     408                 :       3408 :     return theSmXMLExportUnoTunnelId::get().getSeq();
     409                 :            : }
     410                 :            : 
     411                 :         46 : OUString SAL_CALL SmXMLExport_getImplementationName() throw()
     412                 :            : {
     413                 :         46 :     return OUString( "com.sun.star.comp.Math.XMLExporter" );
     414                 :            : }
     415                 :            : 
     416                 :          2 : uno::Sequence< OUString > SAL_CALL SmXMLExport_getSupportedServiceNames()
     417                 :            :         throw()
     418                 :            : {
     419                 :          2 :     const OUString aServiceName( EXPORT_SVC_NAME );
     420         [ +  - ]:          2 :     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
     421                 :          2 :     return aSeq;
     422                 :            : }
     423                 :            : 
     424                 :          4 : uno::Reference< uno::XInterface > SAL_CALL SmXMLExport_createInstance(
     425                 :            :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     426                 :            :     throw( uno::Exception )
     427                 :            : {
     428                 :            :     // EXPORT_OASIS is required here allthough there is no differrence between
     429                 :            :     // OOo and OASIS, because without the flag, a transformation to OOo would
     430                 :            :     // be chained in.
     431 [ +  - ][ +  - ]:          4 :     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_ALL );
     432                 :            : }
     433                 :            : 
     434                 :            : ////////////////////////////////////////////////////////////
     435                 :            : 
     436                 :         30 : OUString SAL_CALL SmXMLExportMetaOOO_getImplementationName() throw()
     437                 :            : {
     438                 :         30 :     return OUString( "com.sun.star.comp.Math.XMLMetaExporter" );
     439                 :            : }
     440                 :            : 
     441                 :          2 : uno::Sequence< OUString > SAL_CALL SmXMLExportMetaOOO_getSupportedServiceNames()
     442                 :            :     throw()
     443                 :            : {
     444                 :          2 :     const OUString aServiceName( EXPORT_SVC_NAME );
     445         [ +  - ]:          2 :     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
     446                 :          2 :     return aSeq;
     447                 :            : }
     448                 :            : 
     449                 :          4 : uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMetaOOO_createInstance(
     450                 :            :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     451                 :            : throw( uno::Exception )
     452                 :            : {
     453 [ +  - ][ +  - ]:          4 :     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_META );
     454                 :            : }
     455                 :            : 
     456                 :            : ////////////////////////////////////////////////////////////
     457                 :            : 
     458                 :         26 : OUString SAL_CALL SmXMLExportMeta_getImplementationName() throw()
     459                 :            : {
     460                 :         26 :     return OUString( "com.sun.star.comp.Math.XMLOasisMetaExporter" );
     461                 :            : }
     462                 :            : 
     463                 :          0 : uno::Sequence< OUString > SAL_CALL SmXMLExportMeta_getSupportedServiceNames()
     464                 :            : throw()
     465                 :            : {
     466                 :          0 :     const OUString aServiceName( EXPORT_SVC_NAME );
     467         [ #  # ]:          0 :     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
     468                 :          0 :     return aSeq;
     469                 :            : }
     470                 :            : 
     471                 :          0 : uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMeta_createInstance(
     472                 :            :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     473                 :            : throw( uno::Exception )
     474                 :            : {
     475 [ #  # ][ #  # ]:          0 :     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_META );
     476                 :            : }
     477                 :            : 
     478                 :            : ////////////////////////////////////////////////////////////
     479                 :            : 
     480                 :         26 : OUString SAL_CALL SmXMLExportSettingsOOO_getImplementationName() throw()
     481                 :            : {
     482                 :         26 :     return OUString( "com.sun.star.comp.Math.XMLSettingsExporter" );
     483                 :            : }
     484                 :            : 
     485                 :          2 : uno::Sequence< OUString > SAL_CALL SmXMLExportSettingsOOO_getSupportedServiceNames()
     486                 :            : throw()
     487                 :            : {
     488                 :          2 :     const OUString aServiceName( EXPORT_SVC_NAME );
     489         [ +  - ]:          2 :     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
     490                 :          2 :     return aSeq;
     491                 :            : }
     492                 :            : 
     493                 :          4 : uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettingsOOO_createInstance(
     494                 :            :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     495                 :            : throw( uno::Exception )
     496                 :            : {
     497 [ +  - ][ +  - ]:          4 :     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_SETTINGS );
     498                 :            : }
     499                 :            : 
     500                 :            : ////////////////////////////////////////////////////////////
     501                 :            : 
     502                 :         28 : OUString SAL_CALL SmXMLExportSettings_getImplementationName() throw()
     503                 :            : {
     504                 :         28 :     return OUString( "com.sun.star.comp.Math.XMLOasisSettingsExporter" );
     505                 :            : }
     506                 :            : 
     507                 :          6 : uno::Sequence< OUString > SAL_CALL SmXMLExportSettings_getSupportedServiceNames()
     508                 :            : throw()
     509                 :            : {
     510                 :          6 :     const OUString aServiceName( EXPORT_SVC_NAME );
     511         [ +  - ]:          6 :     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
     512                 :          6 :     return aSeq;
     513                 :            : }
     514                 :            : 
     515                 :        852 : uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettings_createInstance(
     516                 :            :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     517                 :            : throw( uno::Exception )
     518                 :            : {
     519 [ +  - ][ +  - ]:        852 :     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_SETTINGS );
     520                 :            : }
     521                 :            : 
     522                 :            : ////////////////////////////////////////////////////////////
     523                 :            : 
     524                 :         22 : OUString SAL_CALL SmXMLExportContent_getImplementationName() throw()
     525                 :            : {
     526                 :         22 :     return OUString( "com.sun.star.comp.Math.XMLContentExporter" );
     527                 :            : }
     528                 :            : 
     529                 :          6 : uno::Sequence< OUString > SAL_CALL SmXMLExportContent_getSupportedServiceNames()
     530                 :            :         throw()
     531                 :            : {
     532                 :          6 :     const OUString aServiceName( EXPORT_SVC_NAME );
     533         [ +  - ]:          6 :     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
     534                 :          6 :     return aSeq;
     535                 :            : }
     536                 :            : 
     537                 :        852 : uno::Reference< uno::XInterface > SAL_CALL SmXMLExportContent_createInstance(
     538                 :            :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     539                 :            : throw( uno::Exception )
     540                 :            : {
     541                 :            :     // The EXPORT_OASIS flag is only required to avoid that a transformer is
     542                 :            :     // chanied in
     543 [ +  - ][ +  - ]:        852 :     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_CONTENT );
     544                 :            : }
     545                 :            : 
     546                 :            : ////////////////////////////////////////////////////////////
     547                 :            : 
     548                 :            : // XServiceInfo
     549                 :            : // override empty method from parent class
     550                 :         12 : rtl::OUString SAL_CALL SmXMLExport::getImplementationName()
     551                 :            : throw(uno::RuntimeException)
     552                 :            : {
     553                 :         12 :     OUString aTxt;
     554   [ -  -  -  + ]:         12 :     switch( getExportFlags() )
     555                 :            :     {
     556                 :            :         case EXPORT_META:
     557                 :          0 :             aTxt = SmXMLExportMeta_getImplementationName();
     558                 :          0 :             break;
     559                 :            :         case EXPORT_SETTINGS:
     560                 :          0 :             aTxt = SmXMLExportSettings_getImplementationName();
     561                 :          0 :             break;
     562                 :            :         case EXPORT_CONTENT:
     563                 :          0 :             aTxt = SmXMLExportContent_getImplementationName();
     564                 :          0 :             break;
     565                 :            :         case EXPORT_ALL:
     566                 :            :         default:
     567                 :         12 :             aTxt = SmXMLExport_getImplementationName();
     568                 :         12 :             break;
     569                 :            :     }
     570                 :         12 :     return aTxt;
     571                 :            : }
     572                 :            : 
     573                 :       1704 : sal_uInt32 SmXMLExport::exportDoc(enum XMLTokenEnum eClass)
     574                 :            : {
     575         [ +  + ]:       1704 :     if ( (getExportFlags() & EXPORT_CONTENT) == 0 )
     576                 :            :     {
     577                 :        852 :         SvXMLExport::exportDoc( eClass );
     578                 :            :     }
     579                 :            :     else
     580                 :            :     {
     581                 :        852 :         uno::Reference <frame::XModel> xModel = GetModel();
     582                 :        852 :         uno::Reference <lang::XUnoTunnel> xTunnel;
     583 [ +  - ][ +  - ]:        852 :         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
     584                 :            :         SmModel *pModel = reinterpret_cast<SmModel *>
     585 [ +  - ][ +  - ]:        852 :             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
                 [ +  - ]
     586                 :            : 
     587         [ +  - ]:        852 :         if (pModel)
     588                 :            :         {
     589                 :            :             SmDocShell *pDocShell =
     590         [ +  - ]:        852 :                 static_cast<SmDocShell*>(pModel->GetObjectShell());
     591                 :        852 :             pTree = pDocShell->GetFormulaTree();
     592         [ +  - ]:        852 :             aText = pDocShell->GetText();
     593                 :            :         }
     594                 :            : 
     595 [ +  - ][ +  - ]:        852 :         GetDocHandler()->startDocument();
     596                 :            : 
     597         [ +  - ]:        852 :         addChaffWhenEncryptedStorage();
     598                 :            : 
     599                 :            :         /*Add xmlns line*/
     600                 :        852 :         SvXMLAttributeList &rList = GetAttrList();
     601                 :            : 
     602                 :            :         // make use of a default namespace
     603         [ +  - ]:        852 :         ResetNamespaceMap();    // Math doesn't need namespaces from xmloff, since it now uses default namespaces (because that is common with current MathML usage in the web)
     604 [ +  - ][ +  - ]:        852 :         _GetNamespaceMap().Add( OUString(), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
     605                 :            : 
     606                 :        852 :         rList.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX),
     607         [ +  - ]:       1704 :                 GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX));
           [ +  -  +  - ]
     608                 :            : 
     609                 :            :         //I think we need something like ImplExportEntities();
     610         [ +  - ]:        852 :         _ExportContent();
     611 [ +  - ][ +  - ]:        852 :         GetDocHandler()->endDocument();
     612                 :            :     }
     613                 :            : 
     614                 :       1704 :     bSuccess=sal_True;
     615                 :       1704 :     return 0;
     616                 :            : }
     617                 :            : 
     618                 :        852 : void SmXMLExport::_ExportContent()
     619                 :            : {
     620         [ +  - ]:        852 :     SvXMLElementExport aEquation(*this, XML_NAMESPACE_MATH, XML_MATH, sal_True, sal_True);
     621                 :        852 :     SvXMLElementExport *pSemantics=0;
     622                 :            : 
     623         [ +  - ]:        852 :     if (aText.Len())
     624                 :            :     {
     625                 :            :         pSemantics = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     626 [ +  - ][ +  - ]:        852 :             XML_SEMANTICS, sal_True, sal_True);
     627                 :            :     }
     628                 :            : 
     629         [ +  - ]:        852 :     ExportNodes(pTree, 0);
     630                 :            : 
     631         [ +  - ]:        852 :     if (aText.Len())
     632                 :            :     {
     633                 :            :         // Convert symbol names
     634                 :        852 :         uno::Reference <frame::XModel> xModel = GetModel();
     635                 :        852 :         uno::Reference <lang::XUnoTunnel> xTunnel;
     636 [ +  - ][ +  - ]:        852 :         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
     637                 :            :         SmModel *pModel = reinterpret_cast<SmModel *>
     638 [ +  - ][ +  - ]:        852 :             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
                 [ +  - ]
     639                 :            :         SmDocShell *pDocShell = pModel ?
     640 [ +  - ][ +  - ]:        852 :             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
     641                 :            :         OSL_ENSURE( pDocShell, "doc shell missing" );
     642         [ +  - ]:        852 :         if (pDocShell)
     643                 :            :         {
     644                 :        852 :             SmParser &rParser = pDocShell->GetParser();
     645                 :        852 :             bool bVal = rParser.IsExportSymbolNames();
     646                 :        852 :             rParser.SetExportSymbolNames( true );
     647         [ +  - ]:        852 :             SmNode *pTmpTree = rParser.Parse( aText );
     648         [ +  - ]:        852 :             aText = rParser.GetText();
     649 [ +  - ][ +  - ]:        852 :             delete pTmpTree;
     650                 :        852 :             rParser.SetExportSymbolNames( bVal );
     651                 :            :         }
     652                 :            : 
     653                 :            :         AddAttribute(XML_NAMESPACE_MATH, XML_ENCODING,
     654         [ +  - ]:        852 :             OUString("StarMath 5.0"));
     655                 :            :         SvXMLElementExport aAnnotation(*this, XML_NAMESPACE_MATH,
     656         [ +  - ]:        852 :             XML_ANNOTATION, sal_True, sal_False);
     657 [ +  - ][ +  - ]:        852 :         GetDocHandler()->characters(OUString( aText ));
         [ +  - ][ +  - ]
     658                 :            :     }
     659 [ +  - ][ +  - ]:        852 :     delete pSemantics;
                 [ +  - ]
     660                 :        852 : }
     661                 :            : 
     662                 :        852 : void SmXMLExport::GetViewSettings( Sequence < PropertyValue >& aProps)
     663                 :            : {
     664                 :        852 :     uno::Reference <frame::XModel> xModel = GetModel();
     665         [ -  + ]:        852 :     if ( !xModel.is() )
     666                 :            :         return;
     667                 :            : 
     668                 :        852 :     uno::Reference <lang::XUnoTunnel> xTunnel;
     669 [ +  - ][ +  - ]:        852 :     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
     670                 :            :     SmModel *pModel = reinterpret_cast<SmModel *>
     671 [ +  - ][ +  - ]:        852 :         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
                 [ +  - ]
     672                 :            : 
     673         [ -  + ]:        852 :     if ( !pModel )
     674                 :            :         return;
     675                 :            : 
     676                 :            :     SmDocShell *pDocShell =
     677         [ +  - ]:        852 :         static_cast<SmDocShell*>(pModel->GetObjectShell());
     678         [ -  + ]:        852 :     if ( !pDocShell )
     679                 :            :         return;
     680                 :            : 
     681         [ +  - ]:        852 :     aProps.realloc( 4 );
     682         [ +  - ]:        852 :     PropertyValue *pValue = aProps.getArray();
     683                 :        852 :     sal_Int32 nIndex = 0;
     684                 :            : 
     685         [ +  - ]:        852 :     Rectangle aRect( pDocShell->GetVisArea() );
     686                 :            : 
     687                 :        852 :     pValue[nIndex].Name = "ViewAreaTop";
     688         [ +  - ]:        852 :     pValue[nIndex++].Value <<= aRect.Top();
     689                 :            : 
     690                 :        852 :     pValue[nIndex].Name = "ViewAreaLeft";
     691         [ +  - ]:        852 :     pValue[nIndex++].Value <<= aRect.Left();
     692                 :            : 
     693 [ +  - ][ +  - ]:        852 :     pValue[nIndex++].Value <<= aRect.GetWidth();
     694                 :            : 
     695                 :        852 :     pValue[nIndex].Name = "ViewAreaHeight";
     696 [ +  - ][ -  + ]:        852 :     pValue[nIndex++].Value <<= aRect.GetHeight();
         [ +  - ][ +  - ]
     697                 :            : }
     698                 :            : 
     699                 :        852 : void SmXMLExport::GetConfigurationSettings( Sequence < PropertyValue > & rProps)
     700                 :            : {
     701         [ +  - ]:        852 :     Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
     702         [ +  - ]:        852 :     if ( xProps.is() )
     703                 :            :     {
     704 [ +  - ][ +  - ]:        852 :         Reference< XPropertySetInfo > xPropertySetInfo = xProps->getPropertySetInfo();
     705         [ +  - ]:        852 :         if (xPropertySetInfo.is())
     706                 :            :         {
     707 [ +  - ][ +  - ]:        852 :             Sequence< Property > aProps = xPropertySetInfo->getProperties();
     708                 :        852 :             sal_Int32 nCount(aProps.getLength());
     709         [ +  - ]:        852 :             if (nCount > 0)
     710                 :            :             {
     711         [ +  - ]:        852 :                 rProps.realloc(nCount);
     712         [ +  - ]:        852 :                 PropertyValue* pProps = rProps.getArray();
     713         [ +  - ]:        852 :                 if (pProps)
     714                 :            :                 {
     715 [ +  - ][ +  - ]:        852 :                     SmConfig *pConfig = SM_MOD()->GetConfig();
     716 [ +  - ][ +  - ]:        852 :                     const bool bUsedSymbolsOnly = pConfig ? pConfig->IsSaveOnlyUsedSymbols() : false;
     717                 :            : 
     718                 :        852 :                     const OUString sFormula ( "Formula" );
     719                 :        852 :                     const OUString sBasicLibraries ( "BasicLibraries" );
     720                 :        852 :                     const OUString sDialogLibraries ( "DialogLibraries" );
     721                 :        852 :                     const OUString sRuntimeUID ( "RuntimeUID" );
     722         [ +  + ]:      56232 :                     for (sal_Int32 i = 0; i < nCount; i++, pProps++)
     723                 :            :                     {
     724         [ +  - ]:      55380 :                         const OUString &rPropName = aProps[i].Name;
     725   [ +  +  +  +  :     216408 :                         if (rPropName != sFormula &&
             +  +  +  + ]
                 [ +  + ]
     726                 :      54528 :                             rPropName != sBasicLibraries &&
     727                 :      53676 :                             rPropName != sDialogLibraries &&
     728                 :      52824 :                             rPropName != sRuntimeUID)
     729                 :            :                         {
     730                 :      51972 :                             pProps->Name = rPropName;
     731                 :            : 
     732                 :      51972 :                             rtl::OUString aActualName( rPropName );
     733                 :            : 
     734                 :            :                             // handle 'save used symbols only'
     735 [ +  + ][ +  + ]:      51972 :                             if (bUsedSymbolsOnly && rPropName == "Symbols" )
                 [ +  - ]
     736                 :        852 :                                 aActualName = "UserDefinedSymbolsInUse";
     737                 :            : 
     738 [ +  - ][ +  - ]:      51972 :                             pProps->Value = xProps->getPropertyValue( aActualName );
     739                 :            :                         }
     740                 :        852 :                     }
     741                 :            :                 }
     742         [ +  - ]:        852 :             }
     743                 :        852 :         }
     744                 :        852 :     }
     745                 :        852 : }
     746                 :            : 
     747                 :        852 : void SmXMLExport::ExportLine(const SmNode *pNode, int nLevel)
     748                 :            : {
     749                 :        852 :     ExportExpression(pNode, nLevel);
     750                 :        852 : }
     751                 :            : 
     752                 :        876 : void SmXMLExport::ExportBinaryHorizontal(const SmNode *pNode, int nLevel)
     753                 :            : {
     754                 :        876 :     ExportExpression(pNode, nLevel);
     755                 :        876 : }
     756                 :            : 
     757                 :         12 : void SmXMLExport::ExportUnaryHorizontal(const SmNode *pNode, int nLevel)
     758                 :            : {
     759                 :         12 :     ExportExpression(pNode, nLevel);
     760                 :         12 : }
     761                 :            : 
     762                 :       7068 : void SmXMLExport::ExportExpression(const SmNode *pNode, int nLevel)
     763                 :            : {
     764                 :       7068 :     SvXMLElementExport *pRow=0;
     765                 :       7068 :     sal_uLong  nSize = pNode->GetNumSubNodes();
     766                 :            : 
     767                 :            :     // #i115443: nodes of type expression always need to be grouped with mrow statement
     768 [ +  - ][ +  + ]:       7068 :     if (nSize > 1 || (pNode && pNode->GetType() == NEXPRESSION))
         [ +  + ][ +  + ]
     769         [ +  - ]:       5724 :         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW, sal_True, sal_True);
     770                 :            : 
     771         [ +  + ]:      17808 :         for (sal_uInt16 i = 0; i < nSize; i++)
     772         [ +  - ]:      10740 :         if (const SmNode *pTemp = pNode->GetSubNode(i))
     773                 :      10740 :             ExportNodes(pTemp, nLevel+1);
     774                 :            : 
     775         [ +  + ]:       7068 :     delete pRow;
     776                 :       7068 : }
     777                 :            : 
     778                 :        336 : void SmXMLExport::ExportBinaryVertical(const SmNode *pNode, int nLevel)
     779                 :            : {
     780                 :            :     OSL_ENSURE(pNode->GetNumSubNodes()==3,"Bad Fraction");
     781         [ +  - ]:        336 :     SvXMLElementExport aFraction(*this, XML_NAMESPACE_MATH, XML_MFRAC, sal_True, sal_True);
     782 [ +  - ][ +  - ]:        336 :     ExportNodes(pNode->GetSubNode(0), nLevel);
     783 [ +  - ][ +  - ]:        336 :     ExportNodes(pNode->GetSubNode(2), nLevel);
                 [ +  - ]
     784                 :        336 : }
     785                 :            : 
     786                 :        960 : void SmXMLExport::ExportTable(const SmNode *pNode, int nLevel)
     787                 :            : {
     788                 :        960 :     SvXMLElementExport *pTable=0;
     789                 :            : 
     790                 :        960 :     sal_uInt16 nSize = pNode->GetNumSubNodes();
     791                 :            : 
     792                 :            :     //If the list ends in newline then the last entry has
     793                 :            :     //no subnodes, the newline is superfulous so we just drop
     794                 :            :     //the last node, inclusion would create a bad MathML
     795                 :            :     //table
     796 [ -  + ][ -  + ]:        960 :     if (nSize >= 1 && pNode->GetSubNode(nSize-1)->GetNumSubNodes() == 0)
                 [ +  - ]
     797                 :          0 :         --nSize;
     798                 :            : 
     799                 :            :     // try to avoid creating a mtable element when the formula consists only
     800                 :            :     // of a single output line
     801 [ +  + ][ -  + ]:        960 :     if (nLevel || (nSize >1))
     802         [ +  - ]:        108 :         pTable = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
     803                 :            : 
     804         [ +  + ]:       2040 :     for (sal_uInt16 i = 0; i < nSize; i++)
     805         [ +  - ]:       1080 :         if (const SmNode *pTemp = pNode->GetSubNode(i))
     806                 :            :         {
     807                 :       1080 :             SvXMLElementExport *pRow=0;
     808                 :       1080 :             SvXMLElementExport *pCell=0;
     809         [ +  + ]:       1080 :             if (pTable)
     810                 :            :             {
     811         [ +  - ]:        228 :                 pRow  = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
     812         [ +  - ]:        228 :                 pCell = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
     813                 :            :             }
     814                 :       1080 :             ExportNodes(pTemp, nLevel+1);
     815         [ +  + ]:       1080 :             delete pCell;
     816         [ +  + ]:       1080 :             delete pRow;
     817                 :            :         }
     818                 :            : 
     819         [ +  + ]:        960 :     delete pTable;
     820                 :        960 : }
     821                 :            : 
     822                 :       1632 : void SmXMLExport::ExportMath(const SmNode *pNode, int /*nLevel*/)
     823                 :            : {
     824                 :       1632 :     const SmMathSymbolNode *pTemp = static_cast<const SmMathSymbolNode *>(pNode);
     825         [ +  - ]:       1632 :     SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO, sal_True, sal_False);
     826                 :            :     sal_Unicode nArse[2];
     827                 :       1632 :     nArse[0] = pTemp->GetText().GetChar(0);
     828         [ +  - ]:       1632 :     sal_Unicode cTmp = ConvertMathToMathML( nArse[0] );
     829         [ +  - ]:       1632 :     if (cTmp != 0)
     830                 :       1632 :         nArse[0] = cTmp;
     831                 :            :     OSL_ENSURE(nArse[0] != 0xffff,"Non existent symbol");
     832                 :       1632 :     nArse[1] = 0;
     833 [ +  - ][ +  - ]:       1632 :     GetDocHandler()->characters(nArse);
                 [ +  - ]
     834                 :       1632 : }
     835                 :            : 
     836                 :       5052 : void SmXMLExport::ExportText(const SmNode *pNode, int /*nLevel*/)
     837                 :            : {
     838                 :            :     SvXMLElementExport *pText;
     839                 :       5052 :     const SmTextNode *pTemp = static_cast<const SmTextNode *>(pNode);
     840      [ +  +  - ]:       5052 :     switch (pNode->GetToken().eType)
     841                 :            :     {
     842                 :            :         default:
     843                 :            :         case TIDENT:
     844                 :            :         {
     845                 :            :             //Note that we change the fontstyle to italic for strings that
     846                 :            :             //are italic and longer than a single character.
     847                 :       3540 :             sal_Bool bIsItalic = IsItalic( pTemp->GetFont() );
     848 [ +  + ][ +  + ]:       3540 :             if ((pTemp->GetText().Len() > 1) && bIsItalic)
                 [ +  + ]
     849                 :        180 :                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_ITALIC);
     850 [ +  + ][ -  + ]:       3360 :             else if ((pTemp->GetText().Len() == 1) && !bIsItalic)
                 [ -  + ]
     851                 :          0 :                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_NORMAL);
     852         [ +  - ]:       3540 :             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI,sal_True,sal_False);
     853                 :       3540 :             break;
     854                 :            :         }
     855                 :            :         case TNUMBER:
     856         [ +  - ]:       1512 :             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MN,sal_True,sal_False);
     857                 :       1512 :             break;
     858                 :            :         case TTEXT:
     859         [ #  # ]:          0 :             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTEXT,sal_True,sal_False);
     860                 :          0 :             break;
     861                 :            :         }
     862         [ +  - ]:       5052 :     GetDocHandler()->characters(OUString(pTemp->GetText().GetBuffer()));
     863         [ +  - ]:       5052 :     delete pText;
     864                 :       5052 : }
     865                 :            : 
     866                 :          0 : void SmXMLExport::ExportBlank(const SmNode * /*pNode*/, int /*nLevel*/)
     867                 :            : {
     868                 :            :     //!! exports an empty <mi> tag since for example "~_~" is allowed in
     869                 :            :     //!! Math (so it has no sense at all) but must not result in an empty
     870                 :            :     //!! <msub> tag in MathML !!
     871                 :            : 
     872                 :            :     SvXMLElementExport *pText;
     873                 :            : 
     874         [ #  # ]:          0 :     pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI, sal_True, sal_False);
     875                 :            : 
     876         [ #  # ]:          0 :     GetDocHandler()->characters( OUString() );
     877         [ #  # ]:          0 :     delete pText;
     878                 :          0 : }
     879                 :            : 
     880                 :        780 : void SmXMLExport::ExportSubSupScript(const SmNode *pNode, int nLevel)
     881                 :            : {
     882                 :        780 :     const SmNode *pSub  = 0;
     883                 :        780 :     const SmNode *pSup  = 0;
     884                 :        780 :     const SmNode *pCSub = 0;
     885                 :        780 :     const SmNode *pCSup = 0;
     886                 :        780 :     const SmNode *pLSub = 0;
     887                 :        780 :     const SmNode *pLSup = 0;
     888                 :        780 :     SvXMLElementExport *pThing = 0, *pThing2 = 0;
     889                 :            : 
     890                 :            :     //if we have prescripts at all then we must use the tensor notation
     891                 :            : 
     892                 :            :     //This is one of those excellent locations where scope is vital to
     893                 :            :     //arrange the construction and destruction of the element helper
     894                 :            :     //classes correctly
     895                 :        780 :     pLSub = pNode->GetSubNode(LSUB+1);
     896                 :        780 :     pLSup = pNode->GetSubNode(LSUP+1);
     897 [ -  + ][ +  + ]:        780 :     if (pLSub || pLSup)
     898                 :            :     {
     899                 :            :         SvXMLElementExport aMultiScripts(*this, XML_NAMESPACE_MATH,
     900         [ +  - ]:         48 :             XML_MMULTISCRIPTS, sal_True, sal_True);
     901                 :            : 
     902                 :            : 
     903 [ +  - ][ -  + ]:         48 :         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
         [ #  # ][ #  # ]
                 [ -  + ]
     904                 :            :             && NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
     905                 :            :         {
     906                 :            :             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     907 [ #  # ][ #  # ]:          0 :                 XML_MUNDEROVER, sal_True,sal_True);
     908                 :            :         }
     909 [ +  - ][ -  + ]:         48 :         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
     910                 :            :         {
     911                 :            :             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     912 [ #  # ][ #  # ]:          0 :                 XML_MUNDER, sal_True,sal_True);
     913                 :            :         }
     914 [ +  - ][ -  + ]:         48 :         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
     915                 :            :         {
     916                 :            :             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     917 [ #  # ][ #  # ]:          0 :                 XML_MOVER, sal_True,sal_True);
     918                 :            :         }
     919                 :            : 
     920 [ +  - ][ +  - ]:         48 :         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
     921                 :            : 
     922         [ -  + ]:         48 :         if (pCSub)
     923         [ #  # ]:          0 :             ExportNodes(pCSub, nLevel+1);
     924         [ -  + ]:         48 :         if (pCSup)
     925         [ #  # ]:          0 :             ExportNodes(pCSup, nLevel+1);
     926 [ -  + ][ #  # ]:         48 :         delete pThing2;
     927                 :            : 
     928         [ +  - ]:         48 :         pSub = pNode->GetSubNode(RSUB+1);
     929         [ +  - ]:         48 :         pSup = pNode->GetSubNode(RSUP+1);
     930 [ +  - ][ -  + ]:         48 :         if (pSub || pSup)
     931                 :            :         {
     932         [ #  # ]:          0 :             if (pSub)
     933         [ #  # ]:          0 :                 ExportNodes(pSub, nLevel+1);
     934                 :            :             else
     935                 :            :             {
     936 [ #  # ][ #  # ]:          0 :                 SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
     937                 :            :             }
     938         [ #  # ]:          0 :             if (pSup)
     939         [ #  # ]:          0 :                 ExportNodes(pSup, nLevel+1);
     940                 :            :             else
     941                 :            :             {
     942 [ #  # ][ #  # ]:          0 :                 SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
     943                 :            :             }
     944                 :            :         }
     945                 :            : 
     946                 :            :         //Seperator element between suffix and prefix sub/sup pairs
     947                 :            :         {
     948                 :            :             SvXMLElementExport aPrescripts(*this, XML_NAMESPACE_MATH,
     949 [ +  - ][ +  - ]:         48 :                 XML_MPRESCRIPTS, sal_True,sal_True);
     950                 :            :         }
     951                 :            : 
     952         [ +  - ]:         48 :         if (pLSub)
     953         [ +  - ]:         48 :             ExportNodes(pLSub, nLevel+1);
     954                 :            :         else
     955                 :            :         {
     956                 :            :             SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
     957 [ #  # ][ #  # ]:          0 :                 sal_True,sal_True);
     958                 :            : 
     959                 :            :         }
     960         [ +  - ]:         48 :         if (pLSup)
     961         [ +  - ]:         48 :             ExportNodes(pLSup, nLevel+1);
     962                 :            :         else
     963                 :            :         {
     964                 :            :             SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
     965 [ #  # ][ #  # ]:          0 :                 sal_True,sal_True);
     966                 :            : 
     967         [ +  - ]:         48 :         }
     968                 :            :     }
     969                 :            :     else
     970                 :            :     {
     971 [ +  + ][ +  + ]:        732 :         if (NULL != (pSub = pNode->GetSubNode(RSUB+1)) &&
                 [ +  + ]
     972                 :            :             NULL != (pSup = pNode->GetSubNode(RSUP+1)))
     973                 :            :         {
     974                 :            :             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     975         [ +  - ]:         48 :                 XML_MSUBSUP, sal_True,sal_True);
     976                 :            :         }
     977         [ +  + ]:        684 :         else if (NULL != (pSub = pNode->GetSubNode(RSUB+1)))
     978                 :            :         {
     979                 :            :             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUB,
     980         [ +  - ]:         96 :                 sal_True,sal_True);
     981                 :            :         }
     982         [ +  + ]:        588 :         else if (NULL != (pSup = pNode->GetSubNode(RSUP+1)))
     983                 :            :         {
     984                 :            :             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUP,
     985         [ +  - ]:        396 :                 sal_True,sal_True);
     986                 :            :         }
     987                 :            : 
     988 [ +  + ][ +  + ]:        732 :         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
                 [ +  + ]
     989                 :            :             && NULL != (pCSup=pNode->GetSubNode(CSUP+1)))
     990                 :            :         {
     991                 :            :             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     992         [ +  - ]:        120 :                 XML_MUNDEROVER, sal_True,sal_True);
     993                 :            :         }
     994         [ +  + ]:        612 :         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
     995                 :            :         {
     996                 :            :             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
     997         [ +  - ]:         48 :                 XML_MUNDER, sal_True,sal_True);
     998                 :            :         }
     999         [ +  + ]:        564 :         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
    1000                 :            :         {
    1001                 :            :             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
    1002         [ +  - ]:         24 :                 XML_MOVER, sal_True,sal_True);
    1003                 :            :         }
    1004                 :        732 :         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
    1005                 :            : 
    1006         [ +  + ]:        732 :         if (pCSub)
    1007                 :        168 :             ExportNodes(pCSub, nLevel+1);
    1008         [ +  + ]:        732 :         if (pCSup)
    1009                 :        144 :             ExportNodes(pCSup, nLevel+1);
    1010         [ +  + ]:        732 :         delete pThing2;
    1011                 :            : 
    1012         [ +  + ]:        732 :         if (pSub)
    1013                 :        144 :             ExportNodes(pSub, nLevel+1);
    1014         [ +  + ]:        732 :         if (pSup)
    1015                 :        444 :             ExportNodes(pSup, nLevel+1);
    1016         [ +  + ]:        732 :         delete pThing;
    1017                 :            :     }
    1018                 :        780 : }
    1019                 :            : 
    1020                 :        540 : void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
    1021                 :            : {
    1022                 :            :     const SmNode *pTemp;
    1023                 :        540 :     const SmNode *pLeft=pNode->GetSubNode(0);
    1024                 :        540 :     const SmNode *pRight=pNode->GetSubNode(2);
    1025                 :        540 :     SvXMLElementExport *pFences=0,*pRow=0;
    1026 [ +  - ][ +  -  :       1608 :     if ( ((pLeft) && (pLeft->GetToken().eType != TNONE)) &&
             +  +  +  + ]
         [ +  + ][ +  - ]
    1027                 :        540 :         ((pRight) && (pRight->GetToken().eType != TNONE)) &&
    1028                 :        528 :         (pNode->GetScaleMode() == SCALE_HEIGHT))
    1029                 :            :     {
    1030                 :            :         sal_Unicode nArse[2];
    1031                 :        504 :         nArse[1] = 0;
    1032                 :            :         nArse[0] = static_cast<
    1033                 :        504 :             const SmMathSymbolNode* >(pLeft)->GetText().GetChar(0);
    1034                 :            :         OSL_ENSURE(nArse[0] != 0xffff,"Non existent symbol");
    1035         [ +  - ]:        504 :         AddAttribute(XML_NAMESPACE_MATH, XML_OPEN,nArse);
    1036                 :            :         nArse[0] = static_cast<
    1037                 :        504 :             const SmMathSymbolNode* >(pRight)->GetText().GetChar(0);
    1038                 :            :         OSL_ENSURE(nArse[0] != 0xffff,"Non existent symbol");
    1039         [ +  - ]:        504 :         AddAttribute(XML_NAMESPACE_MATH, XML_CLOSE,nArse);
    1040                 :            :         pFences = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MFENCED,
    1041 [ +  - ][ +  - ]:        504 :             sal_True,sal_True);
    1042                 :            :     }
    1043 [ +  - ][ +  - ]:         36 :     else if (pLeft && (pLeft->GetToken().eType != TNONE))
                 [ +  - ]
    1044                 :            :     {
    1045                 :            :         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
    1046         [ +  - ]:         36 :             sal_True, sal_True);
    1047         [ +  + ]:         36 :         if (pNode->GetScaleMode() == SCALE_HEIGHT)
    1048                 :         12 :             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
    1049                 :            :         else
    1050                 :         24 :             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
    1051                 :         36 :         ExportNodes(pLeft, nLevel+1);
    1052                 :            :     }
    1053                 :            :     else
    1054                 :            :         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
    1055         [ #  # ]:          0 :             sal_True, sal_True);
    1056                 :            : 
    1057         [ +  - ]:        540 :     if (NULL != (pTemp = pNode->GetSubNode(1)))
    1058                 :        540 :         ExportNodes(pTemp, nLevel+1);
    1059         [ +  + ]:        540 :     if (pFences)
    1060         [ +  - ]:        504 :         delete pFences;
    1061 [ +  - ][ +  + ]:         36 :     else if (pRight && (pRight->GetToken().eType != TNONE))
                 [ +  + ]
    1062                 :            :     {
    1063         [ -  + ]:         24 :         if (pNode->GetScaleMode() == SCALE_HEIGHT)
    1064                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
    1065                 :            :         else
    1066                 :         24 :             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
    1067                 :         24 :         ExportNodes(pRight, nLevel+1);
    1068                 :            :     }
    1069         [ +  + ]:        540 :     delete pRow;
    1070                 :        540 : }
    1071                 :            : 
    1072                 :         72 : void SmXMLExport::ExportRoot(const SmNode *pNode, int nLevel)
    1073                 :            : {
    1074         [ +  + ]:         72 :     if (pNode->GetSubNode(0))
    1075                 :            :     {
    1076                 :            :         SvXMLElementExport aRoot(*this, XML_NAMESPACE_MATH, XML_MROOT,sal_True,
    1077         [ +  - ]:         24 :             sal_True);
    1078 [ +  - ][ +  - ]:         24 :         ExportNodes(pNode->GetSubNode(2), nLevel+1);
    1079 [ +  - ][ +  - ]:         24 :         ExportNodes(pNode->GetSubNode(0), nLevel+1);
                 [ +  - ]
    1080                 :            :     }
    1081                 :            :     else
    1082                 :            :     {
    1083                 :            :         SvXMLElementExport aSqrt(*this, XML_NAMESPACE_MATH, XML_MSQRT,sal_True,
    1084         [ +  - ]:         48 :             sal_True);
    1085 [ +  - ][ +  - ]:         48 :         ExportNodes(pNode->GetSubNode(2), nLevel+1);
                 [ +  - ]
    1086                 :            :     }
    1087                 :         72 : }
    1088                 :            : 
    1089                 :        168 : void SmXMLExport::ExportOperator(const SmNode *pNode, int nLevel)
    1090                 :            : {
    1091                 :            :     /*we need to either use content or font and size attributes
    1092                 :            :      *here*/
    1093                 :            :     SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MROW,
    1094         [ +  - ]:        168 :         sal_True, sal_True);
    1095 [ +  - ][ +  - ]:        168 :     ExportNodes(pNode->GetSubNode(0), nLevel+1);
    1096 [ +  - ][ +  - ]:        168 :     ExportNodes(pNode->GetSubNode(1), nLevel+1);
                 [ +  - ]
    1097                 :        168 : }
    1098                 :            : 
    1099                 :        336 : void SmXMLExport::ExportAttributes(const SmNode *pNode, int nLevel)
    1100                 :            : {
    1101                 :        336 :     SvXMLElementExport *pElement=0;
    1102                 :            : 
    1103         [ +  + ]:        336 :     if (pNode->GetToken().eType == TUNDERLINE)
    1104                 :            :     {
    1105                 :            :         AddAttribute(XML_NAMESPACE_MATH, XML_ACCENTUNDER,
    1106                 :         24 :             XML_TRUE);
    1107                 :            :         pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MUNDER,
    1108         [ +  - ]:         24 :             sal_True,sal_True);
    1109                 :            :     }
    1110         [ +  + ]:        312 :     else if (pNode->GetToken().eType != TOVERSTRIKE)
    1111                 :            :     {
    1112                 :            :         AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT,
    1113                 :        288 :             XML_TRUE);
    1114                 :            :         pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MOVER,
    1115         [ +  - ]:        288 :             sal_True,sal_True);
    1116                 :            :     }
    1117                 :            : 
    1118                 :        336 :     ExportNodes(pNode->GetSubNode(1), nLevel+1);
    1119   [ -  +  +  + ]:        336 :     switch (pNode->GetToken().eType)
    1120                 :            :     {
    1121                 :            :         case TOVERLINE:
    1122                 :            :             {
    1123                 :            :             //proper entity support required
    1124                 :            :             SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
    1125         [ #  # ]:          0 :                 sal_True,sal_True);
    1126                 :          0 :             sal_Unicode nArse[2] = {0xAF,0x00};
    1127 [ #  # ][ #  # ]:          0 :             GetDocHandler()->characters(nArse);
                 [ #  # ]
    1128                 :            :             }
    1129                 :          0 :             break;
    1130                 :            :         case TUNDERLINE:
    1131                 :            :             {
    1132                 :            :             //proper entity support required
    1133                 :            :             SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
    1134         [ +  - ]:         24 :                 sal_True,sal_True);
    1135                 :         24 :             sal_Unicode nArse[2] = {0x0332,0x00};
    1136 [ +  - ][ +  - ]:         24 :             GetDocHandler()->characters(nArse);
                 [ +  - ]
    1137                 :            :             }
    1138                 :         24 :             break;
    1139                 :            :         case TOVERSTRIKE:
    1140                 :         24 :             break;
    1141                 :            :         default:
    1142                 :        288 :             ExportNodes(pNode->GetSubNode(0), nLevel+1);
    1143                 :        288 :             break;
    1144                 :            :     }
    1145         [ +  + ]:        336 :     delete pElement;
    1146                 :        336 : }
    1147                 :            : 
    1148                 :          0 : static bool lcl_HasEffectOnMathvariant( const SmTokenType eType )
    1149                 :            : {
    1150                 :            :     return  eType == TBOLD || eType == TNBOLD ||
    1151                 :            :             eType == TITALIC || eType == TNITALIC ||
    1152 [ #  # ][ #  # ]:          0 :             eType == TSANS || eType == TSERIF || eType == TFIXED;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1153                 :            : }
    1154                 :            : 
    1155                 :          0 : void SmXMLExport::ExportFont(const SmNode *pNode, int nLevel)
    1156                 :            : {
    1157                 :          0 :     SvXMLElementExport *pElement = 0;
    1158                 :            : 
    1159                 :            :     //
    1160                 :            :     // gather the mathvariant attribut relevant data from all
    1161                 :            :     // successively following SmFontNodes...
    1162                 :            :     //
    1163                 :          0 :     int nBold   = -1;   // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
    1164                 :          0 :     int nItalic = -1;   // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
    1165                 :          0 :     int nSansSerifFixed   = -1;
    1166                 :          0 :     SmTokenType eNodeType = TUNKNOWN;
    1167         [ #  # ]:          0 :     while (lcl_HasEffectOnMathvariant( (eNodeType = pNode->GetToken().eType) ))
    1168                 :            :     {
    1169   [ #  #  #  #  :          0 :         switch (eNodeType)
             #  #  #  # ]
    1170                 :            :         {
    1171                 :          0 :             case TBOLD      : nBold   = 1; break;
    1172                 :          0 :             case TNBOLD     : nBold   = 0; break;
    1173                 :          0 :             case TITALIC    : nItalic = 1; break;
    1174                 :          0 :             case TNITALIC   : nItalic = 0; break;
    1175                 :          0 :             case TSANS      : nSansSerifFixed  = 0; break;
    1176                 :          0 :             case TSERIF     : nSansSerifFixed  = 1; break;
    1177                 :          0 :             case TFIXED     : nSansSerifFixed  = 2; break;
    1178                 :            :             default:
    1179                 :            :                 OSL_FAIL( "unexpected case" );
    1180                 :            :         }
    1181                 :            :         // According to the parser every node that is to be evaluated heres
    1182                 :            :         // has a single non-zero subnode at index 1!! Thus we only need to check
    1183                 :            :         // that single node for follow-up nodes that have an effect on the attribute.
    1184         [ #  # ]:          0 :         if (pNode->GetNumSubNodes() > 1 && pNode->GetSubNode(1) &&
           [ #  #  #  # ]
                 [ #  # ]
    1185                 :          0 :             lcl_HasEffectOnMathvariant( pNode->GetSubNode(1)->GetToken().eType))
    1186                 :            :         {
    1187                 :          0 :             pNode = pNode->GetSubNode(1);
    1188                 :            :         }
    1189                 :            :         else
    1190                 :          0 :             break;
    1191                 :            :     }
    1192                 :            : 
    1193   [ #  #  #  #  :          0 :     switch (pNode->GetToken().eType)
          #  #  #  #  #  
                #  #  # ]
    1194                 :            :     {
    1195                 :            :         //wrap a phantom element around everything*/
    1196                 :            :         case TPHANTOM:
    1197                 :            :             pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
    1198         [ #  # ]:          0 :                 XML_MPHANTOM, sal_True,sal_True);
    1199                 :          0 :             break;
    1200                 :            :         case TBLACK:
    1201                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLACK);
    1202                 :          0 :             break;
    1203                 :            :         case TWHITE:
    1204                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_WHITE);
    1205                 :          0 :             break;
    1206                 :            :         case TRED:
    1207                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_RED);
    1208                 :          0 :             break;
    1209                 :            :         case TGREEN:
    1210                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_GREEN);
    1211                 :          0 :             break;
    1212                 :            :         case TBLUE:
    1213                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLUE);
    1214                 :          0 :             break;
    1215                 :            :         case TCYAN:
    1216                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_AQUA);
    1217                 :          0 :             break;
    1218                 :            :         case TMAGENTA:
    1219                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_FUCHSIA);
    1220                 :          0 :             break;
    1221                 :            :         case TYELLOW:
    1222                 :          0 :             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_YELLOW);
    1223                 :          0 :             break;
    1224                 :            :         case TSIZE:
    1225                 :            :             {
    1226                 :          0 :                 const SmFontNode *pFontNode = static_cast<const SmFontNode *>(pNode);
    1227                 :          0 :                 const Fraction &aFrac = pFontNode->GetSizeParameter();
    1228                 :            : 
    1229                 :          0 :                 OUStringBuffer sStrBuf;
    1230   [ #  #  #  # ]:          0 :                 switch(pFontNode->GetSizeType())
    1231                 :            :                 {
    1232                 :            :                     case FNTSIZ_MULTIPLY:
    1233                 :            :                         ::sax::Converter::convertDouble(sStrBuf,
    1234 [ #  # ][ #  # ]:          0 :                             static_cast<double>(aFrac*Fraction(100.00)));
         [ #  # ][ #  # ]
    1235         [ #  # ]:          0 :                         sStrBuf.append(static_cast<sal_Unicode>('%'));
    1236                 :          0 :                         break;
    1237                 :            :                     case FNTSIZ_DIVIDE:
    1238                 :            :                         ::sax::Converter::convertDouble(sStrBuf,
    1239 [ #  # ][ #  # ]:          0 :                             static_cast<double>(Fraction(100.00)/aFrac));
         [ #  # ][ #  # ]
    1240         [ #  # ]:          0 :                         sStrBuf.append(static_cast<sal_Unicode>('%'));
    1241                 :          0 :                         break;
    1242                 :            :                     case FNTSIZ_ABSOLUT:
    1243                 :            :                         ::sax::Converter::convertDouble(sStrBuf,
    1244 [ #  # ][ #  # ]:          0 :                             static_cast<double>(aFrac));
    1245                 :            :                         sStrBuf.append(
    1246 [ #  # ][ #  # ]:          0 :                             GetXMLToken(XML_UNIT_PT));
    1247                 :          0 :                         break;
    1248                 :            :                     default:
    1249                 :            :                         {
    1250                 :            :                             //The problem here is that the wheels fall off because
    1251                 :            :                             //font size is stored in 100th's of a mm not pts, and
    1252                 :            :                             //rounding errors take their toll on the original
    1253                 :            :                             //value specified in points.
    1254                 :            : 
    1255                 :            :                             //Must fix StarMath to retain the original pt values
    1256                 :          0 :                             Fraction aTemp = Sm100th_mmToPts(pFontNode->GetFont().
    1257 [ #  # ][ #  # ]:          0 :                                 GetSize().Height());
    1258                 :            : 
    1259         [ #  # ]:          0 :                             if (pFontNode->GetSizeType() == FNTSIZ_MINUS)
    1260         [ #  # ]:          0 :                                 aTemp-=aFrac;
    1261                 :            :                             else
    1262         [ #  # ]:          0 :                                 aTemp+=aFrac;
    1263                 :            : 
    1264         [ #  # ]:          0 :                             double mytest = static_cast<double>(aTemp);
    1265                 :            : 
    1266                 :          0 :                             mytest = ::rtl::math::round(mytest,1);
    1267         [ #  # ]:          0 :                             ::sax::Converter::convertDouble(sStrBuf,mytest);
    1268 [ #  # ][ #  # ]:          0 :                             sStrBuf.append(GetXMLToken(XML_UNIT_PT));
    1269                 :            :                         }
    1270                 :          0 :                         break;
    1271                 :            :                 }
    1272                 :            : 
    1273         [ #  # ]:          0 :                 OUString sStr(sStrBuf.makeStringAndClear());
    1274         [ #  # ]:          0 :                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHSIZE, sStr);
    1275                 :            :             }
    1276                 :          0 :             break;
    1277                 :            :         case TBOLD:
    1278                 :            :         case TITALIC:
    1279                 :            :         case TNBOLD:
    1280                 :            :         case TNITALIC:
    1281                 :            :         case TFIXED:
    1282                 :            :         case TSANS:
    1283                 :            :         case TSERIF:
    1284                 :            :             {
    1285                 :            :                 // nBold:   -1 = yet undefined; 0 = false; 1 = true;
    1286                 :            :                 // nItalic: -1 = yet undefined; 0 = false; 1 = true;
    1287                 :            :                 // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
    1288                 :          0 :                 const sal_Char *pText = "normal";
    1289 [ #  # ][ #  # ]:          0 :                 if (nSansSerifFixed == -1 || nSansSerifFixed == 1)
    1290                 :            :                 {
    1291                 :          0 :                     pText = "normal";
    1292 [ #  # ][ #  # ]:          0 :                     if (nBold == 1 && nItalic != 1)
    1293                 :          0 :                         pText = "bold";
    1294 [ #  # ][ #  # ]:          0 :                     else if (nBold != 1 && nItalic == 1)
    1295                 :          0 :                         pText = "italic";
    1296 [ #  # ][ #  # ]:          0 :                     else if (nBold == 1 && nItalic == 1)
    1297                 :          0 :                         pText = "bold-italic";
    1298                 :            :                 }
    1299         [ #  # ]:          0 :                 else if (nSansSerifFixed == 0)
    1300                 :            :                 {
    1301                 :          0 :                     pText = "sans-serif";
    1302 [ #  # ][ #  # ]:          0 :                     if (nBold == 1 && nItalic != 1)
    1303                 :          0 :                         pText = "bold-sans-serif";
    1304 [ #  # ][ #  # ]:          0 :                     else if (nBold != 1 && nItalic == 1)
    1305                 :          0 :                         pText = "sans-serif-italic";
    1306 [ #  # ][ #  # ]:          0 :                     else if (nBold == 1 && nItalic == 1)
    1307                 :          0 :                         pText = "sans-serif-bold-italic";
    1308                 :            :                 }
    1309         [ #  # ]:          0 :                 else if (nSansSerifFixed == 2)
    1310                 :          0 :                     pText = "monospace";    // no modifiers allowed for monospace ...
    1311                 :            :                 else
    1312                 :            :                 {
    1313                 :            :                     OSL_FAIL( "unexpected case" );
    1314                 :            :                 }
    1315         [ #  # ]:          0 :                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, OUString::createFromAscii( pText ));
    1316                 :            :             }
    1317                 :          0 :             break;
    1318                 :            :         default:
    1319                 :          0 :             break;
    1320                 :            : 
    1321                 :            :     }
    1322                 :            :     //for now we will just always export with a style and not worry about
    1323                 :            :     //anyone else for the moment.
    1324                 :            :     {
    1325                 :            :         //wrap a style around it
    1326         [ #  # ]:          0 :         SvXMLElementExport aStyle(*this, XML_NAMESPACE_MATH, XML_MSTYLE, sal_True,sal_True);
    1327 [ #  # ][ #  # ]:          0 :         ExportExpression(pNode, nLevel);
    1328                 :            :     }
    1329                 :            : 
    1330         [ #  # ]:          0 :     delete pElement;
    1331                 :          0 : }
    1332                 :            : 
    1333                 :            : 
    1334                 :         48 : void SmXMLExport::ExportVerticalBrace(const SmNode *pNode, int nLevel)
    1335                 :            : {
    1336                 :            :     //Place the overbrace value OVER a vertical brace and then place that
    1337                 :            :     //expression OVER the overbrace value, If someone can find a
    1338                 :            :     //dedicated term in MathML to handle this overbrace/underbrace concept
    1339                 :            :     //let me know. C.
    1340                 :            :     XMLTokenEnum which;
    1341                 :            : 
    1342         [ +  + ]:         48 :     switch (pNode->GetToken().eType)
    1343                 :            :     {
    1344                 :            :         case TOVERBRACE:
    1345                 :            :         default:
    1346                 :         24 :             which = XML_MOVER;
    1347                 :         24 :             break;
    1348                 :            :         case TUNDERBRACE:
    1349                 :         24 :             which = XML_MUNDER;
    1350                 :         24 :             break;
    1351                 :            :     }
    1352                 :            : 
    1353                 :            :     OSL_ENSURE(pNode->GetNumSubNodes()==3,"Bad Vertical Brace");
    1354         [ +  - ]:         48 :     SvXMLElementExport aOver1(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
    1355                 :            :     {//Scoping
    1356                 :            :         // using accents will draw the over-/underbraces too close to the base
    1357                 :            :         // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
    1358                 :            :         // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
    1359         [ +  - ]:         48 :         SvXMLElementExport aOver2(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
    1360 [ +  - ][ +  - ]:         48 :         ExportNodes(pNode->GetSubNode(0), nLevel);
    1361 [ +  - ][ +  - ]:         48 :         ExportNodes(pNode->GetSubNode(1), nLevel);
                 [ +  - ]
    1362                 :            :     }
    1363 [ +  - ][ +  - ]:         48 :     ExportNodes(pNode->GetSubNode(2), nLevel);
                 [ +  - ]
    1364                 :         48 : }
    1365                 :            : 
    1366                 :         24 : void SmXMLExport::ExportMatrix(const SmNode *pNode, int nLevel)
    1367                 :            : {
    1368         [ +  - ]:         24 :     SvXMLElementExport aTable(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
    1369                 :         24 :     const SmMatrixNode *pMatrix = static_cast<const SmMatrixNode *>(pNode);
    1370                 :         24 :     sal_uInt16 i=0;
    1371         [ +  + ]:         72 :     for (sal_uLong y = 0; y < pMatrix->GetNumRows(); y++)
    1372                 :            :     {
    1373         [ +  - ]:         48 :         SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
    1374         [ +  + ]:        144 :         for (sal_uLong x = 0; x < pMatrix->GetNumCols(); x++)
    1375 [ +  - ][ +  - ]:         96 :             if (const SmNode *pTemp = pNode->GetSubNode(i++))
    1376                 :            :             {
    1377         [ +  - ]:         96 :                 SvXMLElementExport aCell(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
    1378 [ +  - ][ +  - ]:         96 :                 ExportNodes(pTemp, nLevel+1);
    1379                 :            :             }
    1380 [ +  - ][ +  - ]:         72 :     }
    1381                 :         24 : }
    1382                 :            : 
    1383                 :      17016 : void SmXMLExport::ExportNodes(const SmNode *pNode, int nLevel)
    1384                 :            : {
    1385         [ -  + ]:      17016 :     if (!pNode)
    1386                 :      17016 :         return;
    1387   [ +  +  +  +  :      17016 :     switch(pNode->GetType())
          +  +  +  +  +  
          +  +  +  +  +  
             -  +  +  -  
                      - ]
    1388                 :            :     {
    1389                 :            :         case NTABLE:
    1390                 :        960 :             ExportTable(pNode, nLevel);
    1391                 :        960 :             break;
    1392                 :            :         case NALIGN:
    1393                 :            :         case NBRACEBODY:
    1394                 :            :         case NEXPRESSION:
    1395                 :       5328 :             ExportExpression(pNode, nLevel);
    1396                 :       5328 :             break;
    1397                 :            :         case NLINE:
    1398                 :        852 :             ExportLine(pNode, nLevel);
    1399                 :        852 :             break;
    1400                 :            :         case NTEXT:
    1401                 :       5052 :             ExportText(pNode, nLevel);
    1402                 :       5052 :             break;
    1403                 :            :         case NSPECIAL: //NSPECIAL requires some sort of Entity preservation in the XML engine.
    1404                 :            :         case NGLYPH_SPECIAL:
    1405                 :            :         case NMATH:
    1406                 :            :             {
    1407                 :       1560 :                 sal_Unicode cTmp = 0;
    1408                 :       1560 :                 const SmTextNode *pTemp = static_cast< const SmTextNode * >(pNode);
    1409         [ +  - ]:       1560 :                 if (pTemp->GetText().Len() > 0)
    1410                 :       1560 :                     cTmp = ConvertMathToMathML( pTemp->GetText().GetChar(0) );
    1411         [ -  + ]:       1560 :                 if (cTmp == 0)
    1412                 :            :                 {
    1413                 :            :                     // no conversion to MathML implemented -> export it as text
    1414                 :            :                     // thus at least it will not vanish into nothing
    1415                 :          0 :                     ExportText(pNode, nLevel);
    1416                 :            :                 }
    1417                 :            :                 else
    1418                 :            :                 {
    1419                 :            :                     //To fully handle generic MathML we need to implement the full
    1420                 :            :                     //operator dictionary, we will generate MathML with explicit
    1421                 :            :                     //stretchiness for now.
    1422                 :       1560 :                     sal_Int16 nLength = GetAttrList().getLength();
    1423                 :       1560 :                     sal_Bool bAddStretch=sal_True;
    1424         [ +  + ]:       1620 :                     for ( sal_Int16 i = 0; i < nLength; i++ )
    1425                 :            :                     {
    1426                 :         60 :                         OUString sLocalName;
    1427                 :         60 :                         sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName(
    1428   [ +  -  +  - ]:        120 :                             GetAttrList().getNameByIndex(i), &sLocalName );
    1429                 :            : 
    1430 [ +  - ][ +  - ]:        120 :                         if ( ( XML_NAMESPACE_MATH == nPrefix ) &&
                 [ +  - ]
    1431         [ +  - ]:         60 :                             IsXMLToken(sLocalName, XML_STRETCHY) )
    1432                 :            :                         {
    1433                 :         60 :                             bAddStretch = sal_False;
    1434                 :            :                             break;
    1435                 :            :                         }
    1436         [ -  + ]:         60 :                     }
    1437         [ +  + ]:       1560 :                     if (bAddStretch)
    1438                 :            :                     {
    1439                 :       1500 :                         AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
    1440                 :            :                     }
    1441                 :       1560 :                     ExportMath(pNode, nLevel);
    1442                 :            :                 }
    1443                 :            :             }
    1444                 :       1560 :             break;
    1445                 :            :         case NPLACE:
    1446                 :         72 :             ExportMath(pNode, nLevel);
    1447                 :         72 :             break;
    1448                 :            :         case NBINHOR:
    1449                 :        876 :             ExportBinaryHorizontal(pNode, nLevel);
    1450                 :        876 :             break;
    1451                 :            :         case NUNHOR:
    1452                 :         12 :             ExportUnaryHorizontal(pNode, nLevel);
    1453                 :         12 :             break;
    1454                 :            :         case NBRACE:
    1455                 :        540 :             ExportBrace(pNode, nLevel);
    1456                 :        540 :             break;
    1457                 :            :         case NBINVER:
    1458                 :        336 :             ExportBinaryVertical(pNode, nLevel);
    1459                 :        336 :             break;
    1460                 :            :         case NSUBSUP:
    1461                 :        780 :             ExportSubSupScript(pNode, nLevel);
    1462                 :        780 :             break;
    1463                 :            :         case NROOT:
    1464                 :         72 :             ExportRoot(pNode, nLevel);
    1465                 :         72 :             break;
    1466                 :            :         case NOPER:
    1467                 :        168 :             ExportOperator(pNode, nLevel);
    1468                 :        168 :             break;
    1469                 :            :         case NATTRIBUT:
    1470                 :        336 :             ExportAttributes(pNode, nLevel);
    1471                 :        336 :             break;
    1472                 :            :         case NFONT:
    1473                 :          0 :             ExportFont(pNode, nLevel);
    1474                 :          0 :             break;
    1475                 :            :         case NVERTICAL_BRACE:
    1476                 :         48 :             ExportVerticalBrace(pNode, nLevel);
    1477                 :         48 :             break;
    1478                 :            :         case NMATRIX:
    1479                 :         24 :             ExportMatrix(pNode, nLevel);
    1480                 :         24 :             break;
    1481                 :            :         case NBLANK:
    1482                 :          0 :             ExportBlank(pNode, nLevel);
    1483                 :          0 :             break;
    1484                 :            :        default:
    1485                 :            :             OSL_FAIL( "Warning: failed to export a node?" );
    1486                 :          0 :             break;
    1487                 :            : 
    1488                 :            :     }
    1489 [ +  - ][ +  - ]:         30 : }
    1490                 :            : 
    1491                 :            : ////////////////////////////////////////////////////////////
    1492                 :            : 
    1493                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10