diff options
author | dante <dante19031999@gmail.com> | 2021-08-08 23:27:56 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-08-09 17:49:22 +0200 |
commit | e8d8dad6bba2bd0a4307ee3c1fc40f117680c1f3 (patch) | |
tree | 93a255cf27c7c923df2de6face39fc2dcd5a048d /starmath/inc | |
parent | ccb1d71fe4c0585a42721f09d984fb699ff8f081 (diff) |
Add an iterator for the new starmath matml elements
Change-Id: I7b57951795e8acd704f418d10e5fd0aded3f2b34
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120187
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'starmath/inc')
-rw-r--r-- | starmath/inc/mathml/element.hxx | 62 | ||||
-rw-r--r-- | starmath/inc/mathml/iterator.hxx | 125 |
2 files changed, 187 insertions, 0 deletions
diff --git a/starmath/inc/mathml/element.hxx b/starmath/inc/mathml/element.hxx index 8843d5e8767d..2c5ec40ab019 100644 --- a/starmath/inc/mathml/element.hxx +++ b/starmath/inc/mathml/element.hxx @@ -10,6 +10,7 @@ #pragma once #include "attribute.hxx" +#include "starmathdatabase.hxx" #include <rect.hxx> #include <editeng/editdata.hxx> @@ -27,6 +28,7 @@ public: , m_aAttributePosList(0) , m_aSubElements(0) , m_aParentElement(nullptr) + , m_nSubElementId(0) { SmImplAttributeType(); }; @@ -39,10 +41,26 @@ protected: , m_aESelection(0, 0, 0, 0) , m_aSubElements(0) , m_aParentElement(nullptr) + , m_nSubElementId(0) { SmImplAttributeType(); }; +public: + SmMlElement(const SmMlElement& aElement) + : SmRect(static_cast<SmRect>(aElement)) + , m_aElementType(aElement.getMlElementType()) + , m_aText(aElement.getText()) + , m_aESelection(aElement.getESelectionReference()) + , m_aSubElements(0) + , m_aParentElement(nullptr) + , m_nSubElementId(aElement.getSubElementId()) + { + m_aAttributePosList = std::vector<SmMlAttributePos>(aElement.getAttributeCount()); + for (size_t i = 0; i < aElement.getAttributeCount(); ++i) + setAttributeForce(i, aElement.getAttributePointer(i)); + }; + private: // Type of element SmMlElementType m_aElementType; @@ -65,6 +83,9 @@ private: // Parent element SmMlElement* m_aParentElement; + // Child id, so it is possible to iterata + size_t m_nSubElementId; + private: void SmImplAttributeType(); @@ -93,6 +114,12 @@ public: // location in the source ESelection getESelection() const { return m_aESelection; }; /** + * Returns the location in the source code of the node type + * @return selection + */ + const ESelection& getESelectionReference() const { return m_aESelection; }; + + /** * Sets the location in the source code of the node type * @param aESelection */ @@ -147,6 +174,30 @@ public: // attributes */ void setAttribute(const SmMlAttribute* aAttribute); +protected: // attributes + /** + * Get's a given attribute. + * If no available returns empty attribute. + * @param nAttributePos + * @return given attribute. + */ + const SmMlAttribute* getAttributePointer(size_t nAttributePos) const + { + return nAttributePos < m_aAttributeList.size() ? &m_aAttributeList[nAttributePos] : nullptr; + } + + /** + * Set's a given attribute. + * If no available undefined behaviour. + * @param nAttributePos + * @param aAttribute + * @return given attribute. + */ + void setAttributeForce(size_t nAttributePos, const SmMlAttribute* aAttribute) + { + m_aAttributeList[nAttributePos].setMlAttributeValue(aAttribute); + } + public: // sub elements /** * Returns the sub elements count @@ -181,6 +232,17 @@ public: // sub elements */ void setSubElement(size_t nPos, SmMlElement* aElement); + /** + * Get's subelement id + */ + size_t getSubElementId() const { return m_nSubElementId; } + + /** + * Set's subelement id + * @param nSubElementId + */ + void setSubElementId(size_t nSubElementId) { m_nSubElementId = nSubElementId; } + public: // parent elements /** * Returns the parent element diff --git a/starmath/inc/mathml/iterator.hxx b/starmath/inc/mathml/iterator.hxx new file mode 100644 index 000000000000..559829ce82f1 --- /dev/null +++ b/starmath/inc/mathml/iterator.hxx @@ -0,0 +1,125 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "element.hxx" + +/** The purpose of this iterator is to be able to iterate threw an infinite element tree + * infinite -> as much as your memory can hold + * No call-backs that will end up in out of stack + */ + +namespace mathml +{ +template <typename runType> +void SmMlIteratorBottomToTop(SmMlElement* pMlElementTree, runType aRunType, void* aData) +{ + if (pMlElementTree == nullptr) + return; + + SmMlElement* pCurrent; + + // Fetch the deepest element + pCurrent = pMlElementTree; + while (pCurrent->getSubElementsCount() != 0) + { + if (pCurrent->getSubElement(0) == nullptr) + break; + pCurrent = pCurrent->getSubElement(0); + } + + do + { + // Fetch next element + size_t nId = pCurrent->getSubElementId(); + // We are back to the top. + if (pCurrent->getParentElement() == nullptr) + break; + // If this was the last, then turn back to the parent + if (nId + 1 == pCurrent->getParentElement()->getSubElementsCount()) + pCurrent = pCurrent->getParentElement(); + else // If not, next is the one near it + { + // It could have sub elements + if (pCurrent->getParentElement()->getSubElement(nId + 1) == nullptr) + break; + pCurrent = pCurrent->getParentElement()->getSubElement(nId + 1); + // Fetch the deepest element + while (pCurrent->getSubElementsCount() != 0) + { + if (pCurrent->getSubElement(0) == nullptr) + break; + pCurrent = pCurrent->getSubElement(0); + } + } + + // Just in case of, but should be forbidden + if (pCurrent != nullptr) + aRunType(pCurrent, aData); + + } while (pCurrent != nullptr); +} + +template <typename runType> +void SmMlIteratorTopToBottom(SmMlElement* pMlElementTree, runType aRunType, void* aData) +{ + if (pMlElementTree == nullptr) + return; + + SmMlElement* pCurrent; + + // Fetch the deepest element + pCurrent = pMlElementTree; + aRunType(pCurrent, aData); + while (pCurrent->getSubElementsCount() != 0) + { + if (pCurrent->getSubElement(0) == nullptr) + break; + pCurrent = pCurrent->getSubElement(0); + aRunType(pCurrent, aData); + } + + do + { + // Fetch next element + size_t nId = pCurrent->getSubElementId(); + // We are back to the top. + if (pCurrent->getParentElement() == nullptr) + break; + // If this was the last, then turn back to the parent + if (nId + 1 == pCurrent->getParentElement()->getSubElementsCount()) + pCurrent = pCurrent->getParentElement(); + else // If not, next is the one near it + { + // It could have sub elements + if (pCurrent->getParentElement()->getSubElement(nId + 1) == nullptr) + break; + pCurrent = pCurrent->getParentElement()->getSubElement(nId + 1); + aRunType(pCurrent, aData); + // Fetch the deepest element + while (pCurrent->getSubElementsCount() != 0) + { + if (pCurrent->getSubElement(0) == nullptr) + break; + pCurrent = pCurrent->getSubElement(0); + aRunType(pCurrent, aData); + } + } + + } while (pCurrent != nullptr); +} + +void SmMlIteratorFree(SmMlElement* pMlElementTree); + +SmMlElement* SmMlIteratorCopy(SmMlElement* pMlElementTree); + +} // end namespace mathml + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |