From a0b5963a30e0818f626a92277be8ce971e1b53bd Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 25 Jul 2012 11:31:03 +0200 Subject: export RTF_M{OMATH,R,F,FPR,TYPE,NUM,DEN,MATH} Change-Id: If717d5d3b2179210516eec61959af0afa8b38319 --- oox/inc/oox/mathml/export.hxx | 4 +- starmath/Library_sm.mk | 1 + starmath/inc/document.hxx | 2 + starmath/inc/unomodel.hxx | 1 + starmath/source/document.cxx | 11 ++ starmath/source/rtfexport.cxx | 228 ++++++++++++++++++++++++++++ starmath/source/rtfexport.hxx | 70 +++++++++ starmath/source/unomodel.cxx | 5 + sw/source/filter/ww8/rtfattributeoutput.cxx | 31 ++++ sw/source/filter/ww8/rtfattributeoutput.hxx | 2 + 10 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 starmath/source/rtfexport.cxx create mode 100644 starmath/source/rtfexport.hxx diff --git a/oox/inc/oox/mathml/export.hxx b/oox/inc/oox/mathml/export.hxx index 6c35feba4b92..7d6a7dbb91d9 100644 --- a/oox/inc/oox/mathml/export.hxx +++ b/oox/inc/oox/mathml/export.hxx @@ -29,6 +29,7 @@ #define _OOXMLEXPORT_HXX #include +#include #include #include @@ -36,13 +37,14 @@ namespace oox { /** - Interface class, StarMath will implement writeFormulaOoxml() to write out OOXML + Interface class, StarMath will implement writeFormula*() to write out markup representing the formula. */ class OOX_DLLPUBLIC FormulaExportBase { public: virtual void writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oox::core::OoxmlVersion version ) = 0; + virtual void writeFormulaRtf( OStringBuffer& rBuffer ) = 0; protected: FormulaExportBase(); diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk index f23cfd94eb0c..779895d4a294 100644 --- a/starmath/Library_sm.mk +++ b/starmath/Library_sm.mk @@ -75,6 +75,7 @@ $(eval $(call gb_Library_add_exception_objects,sm,\ starmath/source/node \ starmath/source/ooxmlexport \ starmath/source/ooxmlimport \ + starmath/source/rtfexport \ starmath/source/parse \ starmath/source/rect \ starmath/source/register \ diff --git a/starmath/inc/document.hxx b/starmath/inc/document.hxx index 6d25a96d487c..43aefaaad229 100644 --- a/starmath/inc/document.hxx +++ b/starmath/inc/document.hxx @@ -23,6 +23,7 @@ #define SMDLL 1 #include +#include #include #include #include @@ -155,6 +156,7 @@ class SmDocShell : public SfxObjectShell, public SfxListener void InvalidateCursor(); bool writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oox::core::OoxmlVersion version ); + void writeFormulaRtf(OStringBuffer& rBuffer); bool readFormulaOoxml( oox::formulaimport::XmlStream& stream ); public: diff --git a/starmath/inc/unomodel.hxx b/starmath/inc/unomodel.hxx index bdbbae9532a4..fc6808974a04 100644 --- a/starmath/inc/unomodel.hxx +++ b/starmath/inc/unomodel.hxx @@ -93,6 +93,7 @@ public: // oox::FormulaExportBase virtual void writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oox::core::OoxmlVersion version ); + virtual void writeFormulaRtf(OStringBuffer& rBuffer); // oox::FormulaImportBase virtual void readFormulaOoxml( oox::formulaimport::XmlStream& stream ); virtual Size getFormulaSize() const; diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx index 2aa4b8213d8a..65f246832e6e 100644 --- a/starmath/source/document.cxx +++ b/starmath/source/document.cxx @@ -84,6 +84,7 @@ #include "mathtype.hxx" #include "ooxmlexport.hxx" #include "ooxmlimport.hxx" +#include "rtfexport.hxx" #include "mathmlimport.hxx" #include "mathmlexport.hxx" #include @@ -986,6 +987,16 @@ bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, return aEquation.ConvertFromStarMath( m_pSerializer ); } +void SmDocShell::writeFormulaRtf(OStringBuffer& rBuffer) +{ + if (!pTree) + Parse(); + if (pTree && !IsFormulaArranged()) + ArrangeFormula(); + SmRtfExport aEquation(pTree); + aEquation.ConvertFromStarMath(rBuffer); +} + bool SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream& stream ) { RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::readFormulaOoxml" ); diff --git a/starmath/source/rtfexport.cxx b/starmath/source/rtfexport.cxx new file mode 100644 index 000000000000..f4e560f12539 --- /dev/null +++ b/starmath/source/rtfexport.cxx @@ -0,0 +1,228 @@ +/* -*- 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) 2012 Miklos Vajna (SUSE, Inc.) + * + * 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. + */ + + +#include "rtfexport.hxx" + +#include +#include + +SmRtfExport::SmRtfExport(const SmNode* pIn) + : m_pTree(pIn) + , m_pBuffer(0) +{ +} + +bool SmRtfExport::ConvertFromStarMath(OStringBuffer& rBuffer) +{ + if (m_pTree == NULL) + return false; + m_pBuffer = &rBuffer; + m_pBuffer->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE "\\moMath"); + HandleNode(m_pTree, 0); + m_pBuffer->append("}"); + return true; +} + +// NOTE: This is still work in progress and unfinished, but it already covers a good +// part of the rtf math stuff. + +void SmRtfExport::HandleNode(const SmNode* pNode, int nLevel) +{ + SAL_INFO("starmath.rtf", "Node: " << nLevel << " " << int(pNode->GetType()) << " " << pNode->GetNumSubNodes()); + + switch(pNode->GetType()) + { + case NTEXT: + HandleText(pNode,nLevel); + break; + case NBINHOR: + HandleBinaryOperation(static_cast(pNode), nLevel); + break; + case NBINVER: + HandleFractions(pNode, nLevel); + break; + case NMATH: + HandleMath(pNode, nLevel); + break; + case NEXPRESSION: + HandleAllSubNodes(pNode, nLevel); + break; + case NTABLE: + //Root Node, PILE equivalent, i.e. vertical stack + HandleTable(pNode,nLevel); + break; + case NLINE: + HandleAllSubNodes(pNode, nLevel); + break; + default: + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC << " unhandled node type"); + break; + } +} + +//Root Node, PILE equivalent, i.e. vertical stack +void SmRtfExport::HandleTable(const SmNode* pNode, int nLevel) +{ + if (nLevel || pNode->GetNumSubNodes() > 1) + HandleVerticalStack(pNode, nLevel); + else + HandleAllSubNodes(pNode, nLevel); +} + +void SmRtfExport::HandleAllSubNodes(const SmNode* pNode, int nLevel) +{ + int size = pNode->GetNumSubNodes(); + for (int i = 0; i < size; ++i) + { + if (!pNode->GetSubNode(i)) + { + OSL_FAIL("Subnode is NULL, parent node not handled properly"); + continue; + } + HandleNode(pNode->GetSubNode(i), nLevel + 1); + } +} + +void SmRtfExport::HandleVerticalStack(const SmNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleText(const SmNode* pNode, int /*nLevel*/) +{ + m_pBuffer->append("{\\mr "); + + SmTextNode* pTemp=(SmTextNode* )pNode; + SAL_INFO("starmath.rtf", "Text: " << pTemp->GetText()); + for (xub_StrLen i = 0; i < pTemp->GetText().Len(); i++) + { + sal_uInt16 nChar = pTemp->GetText().GetChar(i); + // TODO special/non-ascii chars? + m_pBuffer->append(OUStringToOString(OUString(SmTextNode::ConvertSymbolToUnicode(nChar)), RTL_TEXTENCODING_UTF8)); + } + + m_pBuffer->append("}"); +} + +void SmRtfExport::HandleFractions(const SmNode* pNode, int nLevel, const char* type) +{ + m_pBuffer->append("{\\mf "); + if (type) + { + m_pBuffer->append("{\\mfPr "); + m_pBuffer->append("{\\mtype "); + m_pBuffer->append(type); + m_pBuffer->append("}"); // mtype + m_pBuffer->append("}"); // mfPr + } + OSL_ASSERT(pNode->GetNumSubNodes() == 3); + m_pBuffer->append("{\\mnum "); + HandleNode(pNode->GetSubNode(0), nLevel + 1); + m_pBuffer->append("}"); // mnum + m_pBuffer->append("{\\mden "); + HandleNode(pNode->GetSubNode(2), nLevel + 1); + m_pBuffer->append("}"); // mden + m_pBuffer->append("}"); // mf +} + +void SmRtfExport::HandleUnaryOperation(const SmUnHorNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleBinaryOperation(const SmBinHorNode* pNode, int nLevel) +{ + SAL_INFO("starmath.rtf", "Binary: " << int(pNode->Symbol()->GetToken().eType)); + // update HandleMath() when adding new items + switch (pNode->Symbol()->GetToken().eType) + { + case TDIVIDEBY: + return HandleFractions(pNode, nLevel, "lin"); + default: + HandleAllSubNodes(pNode, nLevel); + break; + } +} + +void SmRtfExport::HandleAttribute(const SmAttributNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleMath(const SmNode* pNode, int nLevel) +{ + SAL_INFO("starmath.rtf", "Math: " << int(pNode->GetToken().eType)); + switch (pNode->GetToken().eType) + { + case TDIVIDEBY: + case TACUTE: + // these are handled elsewhere, e.g. when handling BINHOR + OSL_ASSERT(false); + default: + HandleText(pNode, nLevel); + break; + } +} + +void SmRtfExport::HandleRoot(const SmRootNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleOperator(const SmOperNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleSubSupScript(const SmSubSupNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleSubSupScriptInternal(const SmSubSupNode* /*pNode*/, int /*nLevel*/, int /*flags*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleMatrix(const SmMatrixNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleBrace(const SmBraceNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +void SmRtfExport::HandleVerticalBrace(const SmVerticalBraceNode* /*pNode*/, int /*nLevel*/) +{ + SAL_INFO("starmath.rtf", "TODO: " << OSL_THIS_FUNC); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/starmath/source/rtfexport.hxx b/starmath/source/rtfexport.hxx new file mode 100644 index 000000000000..9e1f6c355cd9 --- /dev/null +++ b/starmath/source/rtfexport.hxx @@ -0,0 +1,70 @@ +/* -*- 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) 2012 Miklos Vajna (SUSE, Inc.) + * + * 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_RTFEXPORT_HXX +#define SM_RTFEXPORT_HXX + +#include "node.hxx" + +#include + +/** + Class implementing writing of formulas to RTF. + */ +class SmRtfExport +{ +public: + SmRtfExport(const SmNode* pIn); + bool ConvertFromStarMath(OStringBuffer& rBuffer); +private: + void HandleNode(const SmNode* pNode, int nLevel); + void HandleAllSubNodes(const SmNode* pNode, int nLevel); + void HandleTable(const SmNode* pNode, int nLevel); + void HandleVerticalStack(const SmNode* pNode, int nLevel); + void HandleText(const SmNode* pNode, int nLevel); + void HandleMath(const SmNode* pNode, int nLevel); + void HandleFractions(const SmNode* pNode, int nLevel, const char* type = NULL); + void HandleUnaryOperation(const SmUnHorNode* pNode, int nLevel); + void HandleBinaryOperation(const SmBinHorNode* pNode, int nLevel); + void HandleRoot(const SmRootNode* pNode, int nLevel); + void HandleAttribute(const SmAttributNode* pNode, int nLevel); + void HandleOperator(const SmOperNode* pNode, int nLevel); + void HandleSubSupScript(const SmSubSupNode* pNode, int nLevel); + void HandleSubSupScriptInternal(const SmSubSupNode* pNode, int nLevel, int flags); + void HandleMatrix(const SmMatrixNode* pNode, int nLevel); + void HandleBrace(const SmBraceNode* pNode, int nLevel); + void HandleVerticalBrace(const SmVerticalBraceNode* pNode, int nLevel); + + const SmNode* const m_pTree; + OStringBuffer* m_pBuffer; +}; + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/starmath/source/unomodel.cxx b/starmath/source/unomodel.cxx index 601536ca998b..dadb8f3454f3 100644 --- a/starmath/source/unomodel.cxx +++ b/starmath/source/unomodel.cxx @@ -1123,6 +1123,11 @@ void SmModel::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oo static_cast< SmDocShell* >( GetObjectShell())->writeFormulaOoxml( m_pSerializer, version ); } +void SmModel::writeFormulaRtf(OStringBuffer& rBuffer) +{ + static_cast(GetObjectShell())->writeFormulaRtf(rBuffer); +} + void SmModel::readFormulaOoxml( oox::formulaimport::XmlStream& stream ) { static_cast< SmDocShell* >( GetObjectShell())->readFormulaOoxml( stream ); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 5b8de5ce37f0..3328ff0770ff 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -102,6 +102,7 @@ #include #include +#include #include @@ -3372,10 +3373,40 @@ void RtfAttributeOutput::FlyFrameOLEData( SwOLENode& rOLENode ) } } +bool RtfAttributeOutput::FlyFrameOLEMath(SwOLENode& rOLENode) +{ + SAL_INFO("sw.rtf", OSL_THIS_FUNC); + + uno::Reference xObj(const_cast(rOLENode).GetOLEObj().GetOleRef()); + sal_Int64 nAspect = rOLENode.GetAspect(); + svt::EmbeddedObjectRef aObjRef(xObj, nAspect); + SvGlobalName aObjName(aObjRef->getClassID()); + + if (!SotExchange::IsMath(aObjName)) + return false; + + uno::Reference xClosable(xObj->getComponent(), uno::UNO_QUERY); + oox::FormulaExportBase* pBase = dynamic_cast(xClosable.get()); + SAL_WARN_IF(!pBase, "sw.rtf", "Math OLE object cannot write out RTF"); + if (pBase) + { + m_aRunText->append("{\\mmath"); + OStringBuffer aBuf; + pBase->writeFormulaRtf(aBuf); + m_aRunText->append(aBuf.makeStringAndClear()); + m_aRunText->append("}"); + } + + return true; +} + void RtfAttributeOutput::FlyFrameOLE( const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize ) { SAL_INFO("sw.rtf", OSL_THIS_FUNC); + if (FlyFrameOLEMath(rOLENode)) + return; + SvMemoryStream aStream; const sal_uInt8* pGraphicAry = 0; sal_uInt32 nSize = 0; diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index c9b34bc27f20..aa2d85dac137 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -420,6 +420,8 @@ private: void FlyFrameGraphic( const SwFlyFrmFmt* pFlyFrmFmt, const SwGrfNode* pGrfNode ); void FlyFrameOLE( const SwFlyFrmFmt* pFlyFrmFmt, SwOLENode& rOLENode, const Size& rSize ); void FlyFrameOLEData( SwOLENode& rOLENode ); + /// Math export. + bool FlyFrameOLEMath(SwOLENode& rOLENode); /* * Table methods. -- cgit