summaryrefslogtreecommitdiff
path: root/starmath
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2011-08-16 13:56:29 +0200
committerLuboš Luňák <l.lunak@suse.cz>2011-08-18 15:33:45 +0200
commit047a5de1fe8fdc60ffb07c68125c6d0a08353e0d (patch)
tree409cb94778058f34c147dae568d62adac4767f75 /starmath
parent2e5e29471f9ac61ec454bf90a985525a0ad5cb1c (diff)
starting work on OOXML export of formulas
Diffstat (limited to 'starmath')
-rw-r--r--starmath/Library_sm.mk1
-rw-r--r--starmath/inc/document.hxx3
-rw-r--r--starmath/source/document.cxx14
-rw-r--r--starmath/source/ooxml.cxx396
-rw-r--r--starmath/source/ooxml.hxx57
-rw-r--r--starmath/source/unomodel.cxx2
6 files changed, 471 insertions, 2 deletions
diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk
index 20564240e150..98d792da9c6d 100644
--- a/starmath/Library_sm.mk
+++ b/starmath/Library_sm.mk
@@ -78,6 +78,7 @@ $(eval $(call gb_Library_add_exception_objects,sm,\
starmath/source/mathmlimport \
starmath/source/mathtype \
starmath/source/node \
+ starmath/source/ooxml \
starmath/source/parse \
starmath/source/rect \
starmath/source/register \
diff --git a/starmath/inc/document.hxx b/starmath/inc/document.hxx
index 562763e12fc8..d8e042c3e230 100644
--- a/starmath/inc/document.hxx
+++ b/starmath/inc/document.hxx
@@ -39,6 +39,7 @@
#include <svl/lstner.hxx>
#include <vcl/jobset.hxx>
#include <vcl/virdev.hxx>
+#include <sax/fshelper.hxx>
#include <set>
@@ -172,6 +173,8 @@ class SmDocShell : public SfxObjectShell, public SfxListener
*/
void InvalidateCursor();
+ bool writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer );
+
public:
TYPEINFO();
SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+1)
diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx
index b0ec43e32615..b9db1f5db35e 100644
--- a/starmath/source/document.cxx
+++ b/starmath/source/document.cxx
@@ -95,6 +95,7 @@
#include <utility.hxx>
#include <view.hxx>
#include "mathtype.hxx"
+#include "ooxml.hxx"
#include "mathmlimport.hxx"
#include "mathmlexport.hxx"
#include <sfx2/sfxsids.hrc>
@@ -990,6 +991,18 @@ sal_Bool SmDocShell::ConvertTo( SfxMedium &rMedium )
return bRet;
}
+bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer )
+{
+ RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::writeFormulaOoxml" );
+
+ if( !pTree )
+ Parse();
+ if( pTree && !IsFormulaArranged() )
+ ArrangeFormula();
+ SmOoxml aEquation( aText, pTree );
+ return aEquation.ConvertFromStarMath( m_pSerializer );
+}
+
sal_Bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage )
{
RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveCompleted" );
@@ -1433,5 +1446,4 @@ bool SmDocShell::WriteAsMathType3( SfxMedium& rMedium )
return bRet;
}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxml.cxx b/starmath/source/ooxml.cxx
new file mode 100644
index 000000000000..e702b4c15bb2
--- /dev/null
+++ b/starmath/source/ooxml.cxx
@@ -0,0 +1,396 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Lubos Lunak <l.lunak@suse.cz> (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_starmath.hxx"
+
+#include "ooxml.hxx"
+
+#include <oox/token/tokens.hxx>
+
+using namespace oox;
+
+// TODO duped from MathType
+
+static sal_Unicode Convert(sal_Unicode nIn)
+{
+ //Find the best match in accepted unicode for our private area symbols
+ static sal_Unicode aStarMathPrivateToUnicode[] =
+ {
+ 0x2030, 0xF613, 0xF612, 0x002B, 0x003C, 0x003E, 0xE425, 0xE421, 0xE088, 0x2208,
+ 0x0192, 0x2026, 0x2192, 0x221A, 0x221A, 0x221A, 0xE090, 0x005E, 0x02C7, 0x02D8,
+ 0x00B4, 0x0060, 0x02DC, 0x00AF, 0x0362, 0xE099, 0xE09A, 0x20DB, 0xE09C, 0xE09D,
+ 0x0028, 0x0029, 0x2220, 0x22AF, 0xE0A2, 0xE0A3, 0xE0A4, 0xE0A5, 0xE0A6, 0xE0A7,
+ 0x002F, 0x005C, 0x274F, 0xE0AB, 0x0393, 0x0394, 0x0398, 0x039b, 0x039e, 0x03A0,
+ 0x03a3, 0x03a5, 0x03a6, 0x03a8, 0x03A9, 0x03B1, 0x03B2, 0x03b3, 0x03b4, 0x03b5,
+ 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03b5,
+ 0x03d1, 0x03d6, 0xE0D2, 0x03db, 0x2118, 0x2202, 0x2129, 0xE0D7, 0xE0D8, 0x22A4,
+ 0xE0DA, 0x2190, 0x2191, 0x2193
+ };
+ if ((nIn >= 0xE080) && (nIn <= 0xE0DD))
+ nIn = aStarMathPrivateToUnicode[nIn-0xE080];
+
+ //For whatever unicode glyph that equation editor doesn't ship with that
+ //we have a possible match we can munge it to.
+ switch (nIn)
+ {
+ case 0x2223:
+ nIn = '|';
+ break;
+ default:
+ break;
+ }
+
+ return nIn;
+}
+
+SmOoxml::SmOoxml(String &rIn,SmNode *pIn)
+: str( rIn )
+, pTree( pIn )
+{
+}
+
+bool SmOoxml::ConvertFromStarMath( ::sax_fastparser::FSHelperPtr serializer )
+{
+ if( pTree == NULL )
+ return false;
+ m_pSerializer = serializer;
+// TODO check that the document includes the m namespace
+ m_pSerializer->startElementNS( XML_m, XML_oMath,
+ FSNS( XML_xmlns, XML_m ), "http://schemas.openxmlformats.org/wordprocessingml/2006/math", FSEND );
+ HandleNodes( pTree, 0 );
+ m_pSerializer->endElementNS( XML_m, XML_oMath );
+ return true;
+}
+
+void SmOoxml::HandleNodes(SmNode *pNode,int nLevel)
+{
+ fprintf(stderr,"XX %d %d\n", nLevel, pNode->GetType());
+ switch(pNode->GetType())
+ {
+#if 0
+ case NATTRIBUT:
+ HandleAttributes(pNode,nLevel);
+ break;
+#endif
+ case NTEXT:
+ HandleText(pNode,nLevel);
+ break;
+#if 0
+ case NVERTICAL_BRACE:
+ HandleVerticalBrace(pNode,nLevel);
+ break;
+ case NBRACE:
+ HandleBrace(pNode,nLevel);
+ break;
+ case NOPER:
+ HandleOperator(pNode,nLevel);
+ break;
+ case NBINVER:
+ HandleFractions(pNode,nLevel);
+ break;
+ case NROOT:
+ HandleRoot(pNode,nLevel);
+ break;
+ case NSPECIAL:
+ {
+ SmTextNode *pText=(SmTextNode *)pNode;
+ //if the token str and the result text are the same then this
+ //is to be seen as text, else assume its a mathchar
+ if (pText->GetText() == pText->GetToken().aText)
+ HandleText(pText,nLevel);
+ else
+ HandleMath(pText,nLevel);
+ }
+ break;
+#endif
+ case NMATH:
+ HandleMath(pNode,nLevel);
+ break;
+#if 0
+ case NSUBSUP:
+ HandleSubSupScript(pNode,nLevel);
+ break;
+#endif
+ case NEXPRESSION:
+ {
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ }
+ break;
+ case NTABLE:
+ //Root Node, PILE equivalent, i.e. vertical stack
+ HandleTable(pNode,nLevel);
+ break;
+#if 0
+ case NMATRIX:
+ HandleSmMatrix((SmMatrixNode *)pNode,nLevel);
+ break;
+#endif
+ case NLINE:
+ {
+// TODO
+// *pS << sal_uInt8(LINE);
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+// *pS << sal_uInt8(END);
+ }
+ break;
+#if 0
+ case NALIGN:
+ HandleMAlign(pNode,nLevel);
+ break;
+ case NBLANK:
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x98);
+ if (pNode->GetToken().eType == TSBLANK)
+ *pS << sal_uInt16(0xEB04);
+ else
+ *pS << sal_uInt16(0xEB05);
+ break;
+#endif
+ default:
+ {
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ HandleNodes(pTemp,nLevel+1);
+ }
+ break;
+ }
+}
+
+//Root Node, PILE equivalent, i.e. vertical stack
+void SmOoxml::HandleTable(SmNode *pNode,int nLevel)
+{
+ sal_uInt16 nSize = pNode->GetNumSubNodes();
+ //The root of the starmath is a table, if
+ //we convert this them each iteration of
+ //conversion from starmath to mathtype will
+ //add an extra unnecessary level to the
+ //mathtype output stack which would grow
+ //without bound in a multi step conversion
+
+// TODO
+// if ( nLevel || (nSize >1))
+// {
+// *pS << sal_uInt8(PILE);
+// *pS << sal_uInt8(nHAlign); //vAlign ?
+// *pS << sal_uInt8(0x01); //hAlign
+// }
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ if (SmNode *pTemp = pNode->GetSubNode(i))
+ {
+// *pS << sal_uInt8(LINE);
+ HandleNodes(pTemp,nLevel+1);
+// *pS << sal_uInt8(END);
+ }
+// if (nLevel || (nSize>1))
+// *pS << sal_uInt8(END);
+}
+
+void SmOoxml::HandleText(SmNode *pNode, int /*nLevel*/)
+{
+ m_pSerializer->startElementNS( XML_m, XML_r, FSEND );
+ m_pSerializer->startElementNS( XML_m, XML_t, FSEND );
+ SmTextNode *pTemp=(SmTextNode *)pNode;
+ fprintf(stderr, "T %s\n", rtl::OUStringToOString( pTemp->GetText(), RTL_TEXTENCODING_UTF8 ).getStr());
+ for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
+ {
+#if 0
+ if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << sal_uInt8(0x22); //char, with attributes right
+ //after the character
+ }
+ else
+ *pS << sal_uInt8(CHAR);
+
+ sal_uInt8 nFace = 0x1;
+ if (pNode->GetFont().GetItalic() == ITALIC_NORMAL)
+ nFace = 0x3;
+ else if (pNode->GetFont().GetWeight() == WEIGHT_BOLD)
+ nFace = 0x7;
+ *pS << sal_uInt8(nFace+128); //typeface
+#endif
+ sal_uInt16 nChar = pTemp->GetText().GetChar(i);
+ m_pSerializer->write( rtl::OUString( Convert(nChar)));
+
+#if 0
+ //Mathtype can only have these sort of character
+ //attributes on a single character, starmath can put them
+ //anywhere, when the entity involved is a text run this is
+ //a large effort to place the character attribute on the
+ //central mathtype character so that it does pretty much
+ //what the user probably has in mind. The attributes
+ //filled in here are dummy ones which are replaced in the
+ //ATTRIBUT handler if a suitable location for the
+ //attributes was found here. Unfortunately it is
+ //possible for starmath to place character attributes on
+ //entities which cannot occur in mathtype e.g. a Summation
+ //symbol so these attributes may be lost
+ if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << sal_uInt8(EMBEL);
+ while (nPendingAttributes)
+ {
+ *pS << sal_uInt8(2);
+ //wedge the attributes in here and clear
+ //the pending stack
+ nPendingAttributes--;
+ }
+ nInsertion=pS->Tell();
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+#endif
+ }
+ m_pSerializer->endElementNS( XML_m, XML_t );
+ m_pSerializer->endElementNS( XML_m, XML_r );
+}
+
+void SmOoxml::HandleMath(SmNode *pNode,int nLevel)
+{
+ HandleText( pNode, nLevel );
+#if 0
+ if (pNode->GetToken().eType == TMLINE)
+ {
+ *pS << sal_uInt8(END);
+ *pS << sal_uInt8(LINE);
+ bIsReInterpBrace=1;
+ return;
+ }
+ SmMathSymbolNode *pTemp=(SmMathSymbolNode *)pNode;
+ for(xub_StrLen i=0;i<pTemp->GetText().Len();i++)
+ {
+ sal_Unicode nArse = Convert(pTemp->GetText().GetChar(i));
+ if ((nArse == 0x2224) || (nArse == 0x2288) || (nArse == 0x2285) ||
+ (nArse == 0x2289))
+ {
+ *pS << sal_uInt8(CHAR|0x20);
+ }
+ else if ((nPendingAttributes) &&
+ (i == ((pTemp->GetText().Len()+1)/2)-1))
+ {
+ *pS << sal_uInt8(0x22);
+ }
+ else
+ *pS << sal_uInt8(CHAR); //char without formula recognition
+ //The typeface seems to be MTEXTRA for unicode characters,
+ //though how to determine when mathtype chooses one over
+ //the other is unknown. This should do the trick
+ //nevertheless.
+ sal_uInt8 nBias;
+ if ( (nArse == 0x2213) || (nArse == 0x2218) ||
+ (nArse == 0x210F) || (
+ (nArse >= 0x22EE) && (nArse <= 0x22FF)
+ ))
+ {
+ nBias = 0xB; //typeface
+ }
+ else if ((nArse > 0x2000) || (nArse == 0x00D7))
+ nBias = 0x6; //typeface
+ else if (nArse == 0x3d1)
+ nBias = 0x4;
+ else if ((nArse > 0xFF) && ((nArse < 0x393) || (nArse > 0x3c9)))
+ nBias = 0xB; //typeface
+ else if ((nArse == 0x2F) || (nArse == 0x2225))
+ nBias = 0x2; //typeface
+ else
+ nBias = 0x3; //typeface
+
+ *pS << sal_uInt8(nSpec+nBias+128); //typeface
+
+ if (nArse == 0x2224)
+ {
+ *pS << sal_uInt16(0x7C);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else if (nArse == 0x2225)
+ *pS << sal_uInt16(0xEC09);
+ else if (nArse == 0xE421)
+ *pS << sal_uInt16(0x2265);
+ else if (nArse == 0x230A)
+ *pS << sal_uInt16(0xF8F0);
+ else if (nArse == 0x230B)
+ *pS << sal_uInt16(0xF8FB);
+ else if (nArse == 0xE425)
+ *pS << sal_uInt16(0x2264);
+ else if (nArse == 0x226A)
+ {
+ *pS << sal_uInt16(0x3C);
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x98);
+ *pS << sal_uInt16(0xEB01);
+ *pS << sal_uInt8(CHAR);
+ *pS << sal_uInt8(0x86);
+ *pS << sal_uInt16(0x3c);
+ }
+ else if (nArse == 0x2288)
+ {
+ *pS << sal_uInt16(0x2286);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else if (nArse == 0x2289)
+ {
+ *pS << sal_uInt16(0x2287);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else if (nArse == 0x2285)
+ {
+ *pS << sal_uInt16(0x2283);
+ *pS << sal_uInt8(EMBEL);
+ *pS << sal_uInt8(0x0A);
+ *pS << sal_uInt8(END); //end embel
+ *pS << sal_uInt8(END); //end embel
+ }
+ else
+ *pS << nArse;
+ }
+ nPendingAttributes = 0;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxml.hxx b/starmath/source/ooxml.hxx
new file mode 100644
index 000000000000..70de500ebff5
--- /dev/null
+++ b/starmath/source/ooxml.hxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 Lubos Lunak <l.lunak@suse.cz> (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef SM_OOXML_HXX
+#define SM_OOXML_HXX
+
+#include "node.hxx"
+
+#include <sax/fshelper.hxx>
+
+/**
+ Class implementing writing of formulas to OOXML.
+ */
+class SmOoxml
+{
+public:
+ SmOoxml(String &rIn,SmNode *pIn);
+ bool ConvertFromStarMath( ::sax_fastparser::FSHelperPtr m_pSerializer );
+private:
+ void HandleNodes(SmNode *pNode,int nLevel);
+ void HandleTable(SmNode *pNode,int nLevel);
+ void HandleText(SmNode *pNode,int nLevel);
+ void HandleMath(SmNode *pNode,int nLevel);
+ String str;
+ SmNode *pTree;
+ ::sax_fastparser::FSHelperPtr m_pSerializer;
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/unomodel.cxx b/starmath/source/unomodel.cxx
index 1820420e7c4c..d44485a605cb 100644
--- a/starmath/source/unomodel.cxx
+++ b/starmath/source/unomodel.cxx
@@ -1134,7 +1134,7 @@ void SAL_CALL SmModel::setParent( const uno::Reference< uno::XInterface >& xPare
void SmModel::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer )
{
-// static_cast< SmDocShell* >( GetObjectShell())->writeFormulaOoxml( m_pSerializer );
+ static_cast< SmDocShell* >( GetObjectShell())->writeFormulaOoxml( m_pSerializer );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */