[Libreoffice-commits] core.git: starmath/inc starmath/Library_sm.mk starmath/source

dante (via logerrit) logerrit at kemper.freedesktop.org
Mon Aug 9 15:49:56 UTC 2021


 starmath/Library_sm.mk              |    1 
 starmath/inc/mathml/element.hxx     |   62 +++++++++++++++++
 starmath/inc/mathml/iterator.hxx    |  125 ++++++++++++++++++++++++++++++++++++
 starmath/source/mathml/element.cxx  |    1 
 starmath/source/mathml/iterator.cxx |   71 ++++++++++++++++++++
 5 files changed, 260 insertions(+)

New commits:
commit e8d8dad6bba2bd0a4307ee3c1fc40f117680c1f3
Author:     dante <dante19031999 at gmail.com>
AuthorDate: Sun Aug 8 23:27:56 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Mon Aug 9 17:49:22 2021 +0200

    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 at collabora.co.uk>

diff --git a/starmath/Library_sm.mk b/starmath/Library_sm.mk
index 297cca650684..e9bb53676b91 100644
--- a/starmath/Library_sm.mk
+++ b/starmath/Library_sm.mk
@@ -104,6 +104,7 @@ $(eval $(call gb_Library_add_exception_objects,sm,\
         starmath/source/mathml/mathmlexport \
         starmath/source/mathml/mathmlimport \
         starmath/source/mathml/mathmlMo \
+        starmath/source/mathml/iterator \
         starmath/source/mathml/attribute \
         starmath/source/mathml/element \
         starmath/source/mathml/def \
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();
 
@@ -92,6 +113,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: */
diff --git a/starmath/source/mathml/element.cxx b/starmath/source/mathml/element.cxx
index 826193674a20..e1109c267c7d 100644
--- a/starmath/source/mathml/element.cxx
+++ b/starmath/source/mathml/element.cxx
@@ -96,6 +96,7 @@ void SmMlElement::setSubElement(size_t nPos, SmMlElement* aElement)
 {
     // This is the new parent element
     aElement->setParentElement(this);
+    aElement->setSubElementId(nPos);
     // Check if the vector is long enough
     // Careful nOldSize can be 0 and -1 will underflow
     // We must put something on the empty locations
diff --git a/starmath/source/mathml/iterator.cxx b/starmath/source/mathml/iterator.cxx
new file mode 100644
index 000000000000..5e88a717f6c1
--- /dev/null
+++ b/starmath/source/mathml/iterator.cxx
@@ -0,0 +1,71 @@
+/* -*- 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/.
+ */
+
+#include <mathml/iterator.hxx>
+
+#include <stdlib.h>
+
+/** 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
+{
+static inline void deleteElement(SmMlElement* aSmMlElement, void*) { delete aSmMlElement; }
+
+static inline void cloneElement(SmMlElement* aSmMlElement, void* aData)
+{
+    // Prepare data
+    SmMlElement* aNewSmMlElement = new SmMlElement(*aSmMlElement);
+    SmMlElement* aCopyTree = *static_cast<SmMlElement**>(aData);
+
+    // Append data
+    aCopyTree->setSubElement(aCopyTree->getSubElementsCount(), aNewSmMlElement);
+
+    // Prepare for following
+    // If it has sub elements, then it will be the next
+    if (aSmMlElement->getSubElementsCount() != 0)
+        aCopyTree = aNewSmMlElement;
+    else // Otherwise remounts up to where it should be
+    {
+        while (aSmMlElement->getParentElement() != nullptr)
+        {
+            // get parent
+            SmMlElement* pParent = aSmMlElement->getParentElement();
+            aCopyTree = aCopyTree->getParentElement();
+            // was this the last branch ?
+            if (aSmMlElement->getSubElementId() + 1 != pParent->getSubElementsCount())
+                break; // no -> stop going up
+            // Prepare for next round
+            aSmMlElement = pParent;
+        }
+    }
+
+    // Closing extras
+    *static_cast<SmMlElement**>(aData) = aCopyTree;
+}
+
+void SmMlIteratorFree(SmMlElement* pMlElementTree)
+{
+    SmMlIteratorBottomToTop(pMlElementTree, deleteElement, nullptr);
+}
+
+SmMlElement* SmMlIteratorCopy(SmMlElement* pMlElementTree)
+{
+    SmMlElement* aDummyElement = new SmMlElement();
+    SmMlIteratorTopToBottom(pMlElementTree, cloneElement, &aDummyElement);
+    SmMlElement* aResultElement = aDummyElement->getSubElement(0);
+    delete aDummyElement;
+    return aResultElement;
+}
+
+} // end namespace mathml
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */


More information about the Libreoffice-commits mailing list