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: */
|