summaryrefslogtreecommitdiffstats
path: root/starmath/inc
diff options
context:
space:
mode:
Diffstat (limited to 'starmath/inc')
-rw-r--r--starmath/inc/ElementsDockingWindow.hxx78
-rw-r--r--starmath/inc/action.hxx42
-rw-r--r--starmath/inc/caret.hxx424
-rw-r--r--starmath/inc/cfgitem.hxx207
-rw-r--r--starmath/inc/cursor.hxx428
-rw-r--r--starmath/inc/dialog.hxx498
-rw-r--r--starmath/inc/document.hxx233
-rw-r--r--starmath/inc/edit.hxx136
-rw-r--r--starmath/inc/format.hxx156
-rw-r--r--starmath/inc/helpids.h55
-rw-r--r--starmath/inc/mathml/attribute.hxx203
-rw-r--r--starmath/inc/mathml/def.hxx330
-rw-r--r--starmath/inc/mathml/element.hxx300
-rw-r--r--starmath/inc/mathml/export.hxx239
-rw-r--r--starmath/inc/mathml/import.hxx148
-rw-r--r--starmath/inc/mathml/iterator.hxx125
-rw-r--r--starmath/inc/mathml/mathmlMo.hxx110
-rw-r--r--starmath/inc/mathml/mathmlattr.hxx79
-rw-r--r--starmath/inc/mathml/mathmlexport.hxx125
-rw-r--r--starmath/inc/mathml/mathmlimport.hxx112
-rw-r--r--starmath/inc/mathml/starmathdatabase.hxx326
-rw-r--r--starmath/inc/mathml/xparsmlbase.hxx53
-rw-r--r--starmath/inc/node.hxx2096
-rw-r--r--starmath/inc/nodetype.hxx97
-rw-r--r--starmath/inc/parse.hxx37
-rw-r--r--starmath/inc/parse5.hxx122
-rw-r--r--starmath/inc/parsebase.hxx117
-rw-r--r--starmath/inc/pch/precompiled_sm.cxx12
-rw-r--r--starmath/inc/pch/precompiled_sm.hxx188
-rw-r--r--starmath/inc/rect.hxx216
-rw-r--r--starmath/inc/smdll.hxx29
-rw-r--r--starmath/inc/smdllapi.hxx20
-rw-r--r--starmath/inc/smediteng.hxx59
-rw-r--r--starmath/inc/smmod.hrc92
-rw-r--r--starmath/inc/smmod.hxx100
-rw-r--r--starmath/inc/starmath.hrc78
-rw-r--r--starmath/inc/strings.hrc411
-rw-r--r--starmath/inc/strings.hxx338
-rw-r--r--starmath/inc/symbol.hxx107
-rw-r--r--starmath/inc/token.hxx289
-rw-r--r--starmath/inc/types.hxx210
-rw-r--r--starmath/inc/unomodel.hxx95
-rw-r--r--starmath/inc/utility.hxx130
-rw-r--r--starmath/inc/view.hxx333
-rw-r--r--starmath/inc/visitors.hxx538
45 files changed, 10121 insertions, 0 deletions
diff --git a/starmath/inc/ElementsDockingWindow.hxx b/starmath/inc/ElementsDockingWindow.hxx
new file mode 100644
index 0000000000..6bbb4a5427
--- /dev/null
+++ b/starmath/inc/ElementsDockingWindow.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/dockwin.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/resmgr.hxx>
+
+#include "node.hxx"
+#include "parsebase.hxx"
+
+#include <memory>
+#include <vector>
+
+class SmDocShell;
+class SvTreeListBox;
+struct ElementData;
+
+class SmElementsControl
+{
+ std::unique_ptr<AbstractSmParser> maParser;
+
+ SmDocShell* mpDocShell;
+ SmFormat maFormat;
+ int mnCurrentSetIndex;
+ sal_Int16 m_nSmSyntaxVersion;
+
+ std::vector<std::unique_ptr<ElementData>> maItemDatas;
+ std::unique_ptr<weld::IconView> mpIconView;
+
+ Link<OUString, void> maSelectHdlLink;
+
+ void addElement(const OUString& aElementVisual, const OUString& aElementSource, const OUString& aHelpText);
+ void addElements(int nCategory);
+
+ void build();
+
+ DECL_LINK(QueryTooltipHandler, const weld::TreeIter&, OUString);
+ DECL_LINK(ElementActivatedHandler, weld::IconView&, bool);
+
+ static OUString GetElementSource(const OUString& itemId);
+ static OUString GetElementHelpText(const OUString& itemId);
+
+public:
+
+ explicit SmElementsControl(std::unique_ptr<weld::IconView> pIconView);
+ ~SmElementsControl();
+
+ static const std::vector<TranslateId>& categories();
+ void setElementSetIndex(int nSetIndex);
+
+ void setSmSyntaxVersion(sal_Int16 nSmSyntaxVersion);
+
+ void SetSelectHdl(const Link<OUString, void>& rLink) { maSelectHdlLink = rLink; }
+
+ static Color GetTextColor();
+ static Color GetControlBackground();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/action.hxx b/starmath/inc/action.hxx
new file mode 100644
index 0000000000..aaec785490
--- /dev/null
+++ b/starmath/inc/action.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <svl/undo.hxx>
+#include "format.hxx"
+
+class SmDocShell;
+
+class SmFormatAction final : public SfxUndoAction
+{
+ SmDocShell* pDoc;
+ SmFormat aOldFormat;
+ SmFormat aNewFormat;
+
+public:
+ SmFormatAction(SmDocShell* pDocSh, const SmFormat& rOldFormat, const SmFormat& rNewFormat);
+
+ virtual void Undo() override;
+ virtual void Redo() override;
+ virtual void Repeat(SfxRepeatTarget& rDocSh) override;
+ virtual OUString GetComment() const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/caret.hxx b/starmath/inc/caret.hxx
new file mode 100644
index 0000000000..eff810792c
--- /dev/null
+++ b/starmath/inc/caret.hxx
@@ -0,0 +1,424 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 <sal/config.h>
+#include "node.hxx"
+
+/** Representation of caret position with an equation */
+struct SmCaretPos
+{
+ SmCaretPos(SmNode* selectedNode = nullptr, int iIndex = 0)
+ : pSelectedNode(selectedNode)
+ , nIndex(iIndex)
+ {
+ assert(nIndex >= 0);
+ }
+
+ /** Selected node */
+ SmNode* pSelectedNode;
+
+ /** Index (invariant: non-negative) within the selected node
+ *
+ * 0: Position in front of a node
+ * 1: Position after a node or after first char in SmTextNode
+ * n: Position after n char in SmTextNode
+ *
+ * Notice how there's special cases for SmTextNode.
+ */
+ //TODO: Special cases for SmBlankNode is needed
+ //TODO: Consider forgetting about the todo above... As it's really unpleasant.
+ int nIndex;
+
+ /** True, if this is a valid caret position */
+ bool IsValid() const { return pSelectedNode != nullptr; }
+ bool operator==(const SmCaretPos& pos) const
+ {
+ return pos.pSelectedNode == pSelectedNode && nIndex == pos.nIndex;
+ }
+ /** Get the caret position after pNode, regardless of pNode
+ *
+ * Gets the caret position following pNode, this is SmCaretPos(pNode, 1).
+ * Unless pNode is an instance of SmTextNode, then the index is the text length.
+ */
+ static SmCaretPos GetPosAfter(SmNode* pNode)
+ {
+ if (pNode && pNode->GetType() == SmNodeType::Text)
+ return SmCaretPos(pNode, static_cast<SmTextNode*>(pNode)->GetText().getLength());
+ return SmCaretPos(pNode, 1);
+ }
+};
+
+/** A line that represents a caret */
+class SmCaretLine
+{
+public:
+ SmCaretLine(tools::Long left = 0, tools::Long top = 0, tools::Long height = 0)
+ {
+ _top = top;
+ _left = left;
+ _height = height;
+ }
+ tools::Long GetTop() const { return _top; }
+ tools::Long GetLeft() const { return _left; }
+ tools::Long GetHeight() const { return _height; }
+ tools::Long SquaredDistanceX(const SmCaretLine& line) const
+ {
+ return (GetLeft() - line.GetLeft()) * (GetLeft() - line.GetLeft());
+ }
+ tools::Long SquaredDistanceX(const Point& pos) const
+ {
+ return (GetLeft() - pos.X()) * (GetLeft() - pos.X());
+ }
+ tools::Long SquaredDistanceY(const SmCaretLine& line) const
+ {
+ tools::Long d = GetTop() - line.GetTop();
+ if (d < 0)
+ d = (d * -1) - GetHeight();
+ else
+ d = d - line.GetHeight();
+ if (d < 0)
+ return 0;
+ return d * d;
+ }
+ tools::Long SquaredDistanceY(const Point& pos) const
+ {
+ tools::Long d = GetTop() - pos.Y();
+ if (d < 0)
+ d = (d * -1) - GetHeight();
+ if (d < 0)
+ return 0;
+ return d * d;
+ }
+
+private:
+ tools::Long _top;
+ tools::Long _left;
+ tools::Long _height;
+};
+
+// SmCaretPosGraph
+
+/** An entry in SmCaretPosGraph */
+struct SmCaretPosGraphEntry
+{
+ SmCaretPosGraphEntry(SmCaretPos pos, SmCaretPosGraphEntry* left, SmCaretPosGraphEntry* right)
+ : CaretPos{ pos }
+ , Left{ left }
+ , Right{ right }
+ {
+ }
+ /** Caret position */
+ const SmCaretPos CaretPos;
+ /** Entry to the left visually */
+ SmCaretPosGraphEntry* Left;
+ /** Entry to the right visually */
+ SmCaretPosGraphEntry* Right;
+ void SetRight(SmCaretPosGraphEntry* right) { Right = right; }
+ void SetLeft(SmCaretPosGraphEntry* left) { Left = left; }
+};
+
+/** A graph over all caret positions
+ * @remarks Graphs can only grow, entries cannot be removed!
+ */
+class SmCaretPosGraph
+{
+public:
+ SmCaretPosGraph();
+
+ ~SmCaretPosGraph();
+
+ /** Add a caret position
+ * @remarks If left is NULL, they will point back to the entry.
+ */
+ SmCaretPosGraphEntry* Add(SmCaretPos pos, SmCaretPosGraphEntry* left = nullptr);
+
+ std::vector<std::unique_ptr<SmCaretPosGraphEntry>>::iterator begin()
+ {
+ return mvEntries.begin();
+ }
+
+ std::vector<std::unique_ptr<SmCaretPosGraphEntry>>::iterator end() { return mvEntries.end(); }
+
+private:
+ std::vector<std::unique_ptr<SmCaretPosGraphEntry>> mvEntries;
+};
+
+/** \page visual_formula_editing Visual Formula Editing
+ * A visual formula editor allows users to easily edit formulas without having to learn and
+ * use complicated commands. A visual formula editor is a WYSIWYG editor. For OpenOffice Math
+ * this essentially means that you can click on the formula image, to get a caret, which you
+ * can move with arrow keys, and use to modify the formula by entering text, clicking buttons
+ * or using shortcuts.
+ *
+ * \subsection formula_trees Formula Trees
+ * A formula in OpenOffice Math is a tree of nodes, take for instance the formula
+ * "A + {B cdot C} over D", it looks like this
+ * \f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$. The tree for this formula
+ * looks like this:
+ *
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Equation: \"A + {B cdot C} over D\"";
+ * size = "9,9";
+ * n0 [label="SmTableNode (1)"];
+ * n0 -> n1 [label="0"];
+ * n1 [label="SmLineNode (2)"];
+ * n1 -> n2 [label="0"];
+ * n2 [label="SmExpressionNode (3)"];
+ * n2 -> n3 [label="0"];
+ * n3 [label="SmBinHorNode (4)"];
+ * n3 -> n4 [label="0"];
+ * n4 [label="SmTextNode: A (5)"];
+ * n3 -> n5 [label="1"];
+ * n5 [label="SmMathSymbolNode: + (6)"];
+ * n3 -> n6 [label="2"];
+ * n6 [label="SmBinVerNode (7)"];
+ * n6 -> n7 [label="0"];
+ * n7 [label="SmExpressionNode (8)"];
+ * n7 -> n8 [label="0"];
+ * n8 [label="SmBinHorNode (9)"];
+ * n8 -> n9 [label="0"];
+ * n9 [label="SmTextNode: B (10)"];
+ * n8 -> n10 [label="1"];
+ * n10 [label="SmMathSymbolNode: &#183; (11)"];
+ * n8 -> n11 [label="2"];
+ * n11 [label="SmTextNode: C (12)"];
+ * n6 -> n12 [label="1"];
+ * n12 [label="SmRectangleNode (13)"];
+ * n6 -> n13 [label="2"];
+ * n13 [label="SmTextNode: D (14)"];
+ * }
+ * \enddot
+ *
+ * The vertices are nodes, their label says what kind of node and the number in parentheses is
+ * the identifier of the node (In practices a pointer is used instead of the id). The direction
+ * of the edges tells which node is parent and which is child. The label of the edges are the
+ * child node index number, given to SmNode::GetSubNode() of the parent to get the child node.
+ *
+ *
+ * \subsection visual_lines Visual Lines
+ *
+ * Inorder to do caret movement in visual lines, we need a definition of caret position and
+ * visual line. In a tree such as the above there are three visual lines. There's the outer most
+ * line, with entries such as
+ * \f$\mbox{A}\f$, \f$ + \f$ and \f$ \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$. Then there's
+ * the numerator line of the fraction it has entries \f$ \mbox{B} \f$, \f$ \cdot \f$ and \f$ \mbox{C} \f$.
+ * And last by not least there's the denominator line of the fraction it's only entry is \f$ \mbox{D} \f$.
+ *
+ * For visual editing it should be possible to place a caret on both sides of any line entry,
+ * consider a line entry a character or construction that in a line is treated as a character.
+ * Imagine the caret is placed to the right of the plus sign (id: 6), now if user presses
+ * backspace this should delete the plus sign (id: 6), and if the user presses delete this
+ * should delete the entire fraction (id: 7). This is because the caret is in the outer most
+ * line where the fraction is considered a line entry.
+ *
+ * However, inorder to prevent users from accidentally deleting large subtrees, just because
+ * they logically placed there caret a in the wrong line, require that complex constructions
+ * such as a fraction is selected before it is deleted. Thus in this case it wouldn't be
+ * deleted, but only selected and then deleted if the user hit delete again. Anyway, this is
+ * slightly off topic for now.
+ *
+ * Important about visual lines is that they don't always have an SmExpressionNode as root
+ * and the entries in a visual line is all the nodes of a subtree ordered left to right that
+ * isn't either an SmExpressionNode, SmBinHorNode or SmUnHorNode.
+ *
+ *
+ * \subsection caret_positions Caret Positions
+ *
+ * A caret position in OpenOffice Math is represented by an instance of SmCaretPos.
+ * That is a caret position is a node and an index related to this node. For most nodes the
+ * index 0, means caret is in front of this node, the index 1 means caret is after this node.
+ * For SmTextNode the index is the caret position after the specified number of characters,
+ * imagine an SmTextNode with the number 1337. The index 3 in such SmTextNode would mean a
+ * caret placed right before 7, e.g. "133|7".
+ *
+ * For SmExpressionNode, SmBinHorNode and SmUnHorNode the only legal index is 0, which means
+ * in front of the node. Actually the index 0 may only because for the first caret position
+ * in a visual line. From the example above, consider the following subtree that constitutes
+ * a visual line:
+ *
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Subtree that constitutes a visual line";
+ * size = "7,5";
+ * n7 [label="SmExpressionNode (8)"];
+ * n7 -> n8 [label="0"];
+ * n8 [label="SmBinHorNode (9)"];
+ * n8 -> n9 [label="0"];
+ * n9 [label="SmTextNode: B (10)"];
+ * n8 -> n10 [label="1"];
+ * n10 [label="SmMathSymbolNode: &#183; (11)"];
+ * n8 -> n11 [label="2"];
+ * n11 [label="SmTextNode: C (12)"];
+ * }
+ * \enddot
+ * Here the caret positions are:
+ *
+ * <TABLE>
+ * <TR><TD><B>Caret position:</B></TD><TD><B>Example:</B></TD>
+ * </TR><TR>
+ * <TD>{id: 8, index: 0}</TD>
+ * <TD>\f$ \mid \mbox{C} \cdot \mbox{C} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 10, index: 1}</TD>
+ * <TD>\f$ \mbox{C} \mid \cdot \mbox{C} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 11, index: 1}</TD>
+ * <TD>\f$ \mbox{C} \cdot \mid \mbox{C} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 12, index: 1}</TD>
+ * <TD>\f$ \mbox{C} \cdot \mbox{C} \mid \f$</TD>
+ * </TR><TR>
+ * </TABLE>
+ *
+ * Where \f$ \mid \f$ is used to denote caret position.
+ *
+ * With these exceptions included in the definition the id and index: {id: 11, index: 0} does
+ * \b not constitute a caret position in the given context. Note the method
+ * SmCaretPos::IsValid() does not check if this invariant holds true, but code in SmCaret,
+ * SmSetSelectionVisitor and other places depends on this invariant to hold.
+ *
+ *
+ * \subsection caret_movement Caret Movement
+ *
+ * As the placement of caret positions depends very much on the context within which a node
+ * appears it is not trivial to find all caret positions and determine which follows which.
+ * In OpenOffice Math this is done by the SmCaretPosGraphBuildingVisitor. This visitor builds
+ * graph (an instance of SmCaretPosGraph) over the caret positions. For details on how this
+ * graph is build, and how new methods should be implemented see SmCaretPosGraphBuildingVisitor.
+ *
+ * The result of the SmCaretPosGraphBuildingVisitor is a graph over the caret positions in a
+ * formula, represented by an instance of SmCaretPosGraph. Each entry (instances of SmCaretPosGraphEntry)
+ * has a pointer to the entry to the left and right of itself. This way we can easily find
+ * the caret position to a right or left of a given caret position. Note each caret position
+ * only appears once in this graph.
+ *
+ * When searching for a caret position after a left click on the formula this map is also used.
+ * We simply iterate over all entries, uses the SmCaretPos2LineVisitor to find a line for each
+ * caret position. Then the distance from the click to the line is computed and we choose the
+ * caret position closest to the click.
+ *
+ * For up and down movement, we also iterator over all caret positions and use SmCaretPos2LineVisitor
+ * to find a line for each caret position. Then we compute the distance from the current
+ * caret position to every other caret position and chooses the one closest that is either
+ * above or below the current caret position, depending on whether we're doing up or down movement.
+ *
+ * This result of this approach to caret movement is that we have logically predictable
+ * movement for left and right, whilst leftclick, up and down movement depends on the sizes
+ * and placement of all node and may be less logically predictable. This solution also means
+ * that we only have one complex visitor generating the graph, imagine the nightmare if we
+ * had a visitor for movement in each direction.
+ *
+ * Making up and down movement independent of node sizes and placement wouldn't necessarily
+ * be a good thing either. Consider the formula \f$ \frac{1+2+3+4+5}{6} \f$, if the caret is
+ * placed as displayed here: \f$ \frac{1+2+3+4+5}{6 \mid} \f$, up movement should move to right
+ * after "3": \f$ \frac{1+2+3|+4+5}{6} \f$. However, such a move depends on the sizes and placement
+ * of all nodes in the fraction.
+ *
+ *
+ * \subsubsection caretpos_graph_example Example of Caret Position Graph
+ *
+ * If we consider the formula
+ * \f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$ from \ref formula_trees.
+ * It has the following caret positions:
+ *
+ * <TABLE>
+ * <TR>
+ * <TD><B>Caret position:</B></TD>
+ * <TD><B>Example:</B></TD>
+ * </TR><TR>
+ * <TD>{id: 3, index: 0}</TD>
+ * <TD>\f$ \mid\mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 5, index: 1}</TD>
+ * <TD>\f$ \mbox{A}\mid + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 6, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \mid \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 8, index: 0}</TD>
+ * <TD>\f$ \mbox{A} + \frac{ \mid \mbox{B} \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 10, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \mid \cdot \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 11, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mid \mbox{C}}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 12, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C} \mid}{\mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 14, index: 0}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mid \mbox{D}} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 14, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D} \mid} \f$</TD>
+ * </TR><TR>
+ * <TD>{id: 7, index: 1}</TD>
+ * <TD>\f$ \mbox{A} + \frac{\mbox{B} \cdot \mbox{C}}{\mbox{D}} \mid \f$</TD>
+ * </TR>
+ * </TABLE>
+ *
+ * Below is a directed graph over the caret positions and how you can move between them.
+ * \dot
+ * digraph {
+ * labelloc = "t";
+ * label= "Caret Position Graph";
+ * size = "4,6";
+ * p0 [label = "{id: 3, index: 0}"];
+ * p0 -> p1 [fontsize = 10.0, label = "right"];
+ * p1 [label = "{id: 5, index: 1}"];
+ * p1 -> p0 [fontsize = 10.0, label = "left"];
+ * p1 -> p2 [fontsize = 10.0, label = "right"];
+ * p2 [label = "{id: 6, index: 1}"];
+ * p2 -> p1 [fontsize = 10.0, label = "left"];
+ * p2 -> p3 [fontsize = 10.0, label = "right"];
+ * p3 [label = "{id: 8, index: 0}"];
+ * p3 -> p2 [fontsize = 10.0, label = "left"];
+ * p3 -> p4 [fontsize = 10.0, label = "right"];
+ * p4 [label = "{id: 10, index: 1}"];
+ * p4 -> p3 [fontsize = 10.0, label = "left"];
+ * p4 -> p5 [fontsize = 10.0, label = "right"];
+ * p5 [label = "{id: 11, index: 1}"];
+ * p5 -> p4 [fontsize = 10.0, label = "left"];
+ * p5 -> p6 [fontsize = 10.0, label = "right"];
+ * p6 [label = "{id: 12, index: 1}"];
+ * p6 -> p5 [fontsize = 10.0, label = "left"];
+ * p6 -> p9 [fontsize = 10.0, label = "right"];
+ * p7 [label = "{id: 14, index: 0}"];
+ * p7 -> p2 [fontsize = 10.0, label = "left"];
+ * p7 -> p8 [fontsize = 10.0, label = "right"];
+ * p8 [label = "{id: 14, index: 1}"];
+ * p8 -> p7 [fontsize = 10.0, label = "left"];
+ * p8 -> p9 [fontsize = 10.0, label = "right"];
+ * p9 [label = "{id: 7, index: 1}"];
+ * p9 -> p6 [fontsize = 10.0, label = "left"];
+ * }
+ * \enddot
+ */
+
+/* TODO: Write documentation about the following keywords:
+ *
+ * Visual Selections:
+ * - Show images
+ * - Talk about how the visitor does this
+ *
+ * Modifying a Visual Line:
+ * - Find top most non-compo of the line (e.g. The subtree that constitutes a line)
+ * - Make the line into a list
+ * - Edit the list, add/remove/modify nodes
+ * - Parse the list back into a subtree
+ * - Insert the new subtree where the old was taken
+ */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/cfgitem.hxx b/starmath/inc/cfgitem.hxx
new file mode 100644
index 0000000000..08a6e834f1
--- /dev/null
+++ b/starmath/inc/cfgitem.hxx
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "utility.hxx"
+
+#include <string_view>
+#include <rtl/ustring.hxx>
+#include <svl/SfxBroadcaster.hxx>
+#include <unotools/configitem.hxx>
+
+#include "types.hxx"
+
+namespace com::sun::star::uno
+{
+template <class E> class Sequence;
+}
+
+class SmSym;
+class SmSymbolManager;
+class SmFormat;
+namespace vcl
+{
+class Font;
+}
+struct SmCfgOther;
+class SfxItemSet;
+
+struct SmFontFormat
+{
+ OUString aName;
+ sal_Int16 nCharSet;
+ sal_Int16 nFamily;
+ sal_Int16 nPitch;
+ sal_Int16 nWeight;
+ sal_Int16 nItalic;
+
+ SmFontFormat();
+ explicit SmFontFormat(const vcl::Font& rFont);
+
+ vcl::Font GetFont() const;
+ bool operator==(const SmFontFormat& rFntFmt) const;
+};
+
+struct SmFntFmtListEntry
+{
+ OUString aId;
+ SmFontFormat aFntFmt;
+
+ SmFntFmtListEntry(OUString aId, SmFontFormat rFntFmt);
+};
+
+class SmFontFormatList
+{
+ std::vector<SmFntFmtListEntry> aEntries;
+ bool bModified;
+
+ SmFontFormatList(const SmFontFormatList&) = delete;
+ SmFontFormatList& operator=(const SmFontFormatList&) = delete;
+
+public:
+ SmFontFormatList();
+
+ void Clear();
+ void AddFontFormat(const OUString& rFntFmtId, const SmFontFormat& rFntFmt);
+ void RemoveFontFormat(std::u16string_view rFntFmtId);
+
+ const SmFontFormat* GetFontFormat(std::u16string_view rFntFmtId) const;
+ const SmFontFormat* GetFontFormat(size_t nPos) const;
+ OUString GetFontFormatId(const SmFontFormat& rFntFmt) const;
+ OUString GetFontFormatId(const SmFontFormat& rFntFmt, bool bAdd);
+ OUString GetFontFormatId(size_t nPos) const;
+ OUString GetNewFontFormatId() const;
+ size_t GetCount() const { return aEntries.size(); }
+
+ bool IsModified() const { return bModified; }
+ void SetModified(bool bVal) { bModified = bVal; }
+};
+
+class SmMathConfig final : public utl::ConfigItem, public SfxBroadcaster
+{
+ std::unique_ptr<SmFormat> pFormat;
+ std::unique_ptr<SmCfgOther> pOther;
+ std::unique_ptr<SmFontFormatList> pFontFormatList;
+ std::unique_ptr<SmSymbolManager> pSymbolMgr;
+ bool bIsOtherModified;
+ bool bIsFormatModified;
+ SmFontPickList vFontPickList[8];
+ sal_Int32 m_nCommitLock = 0;
+
+ SmMathConfig(const SmMathConfig&) = delete;
+ SmMathConfig& operator=(const SmMathConfig&) = delete;
+
+ void StripFontFormatList(const std::vector<SmSym>& rSymbols);
+
+ void Save();
+
+ void ReadSymbol(SmSym& rSymbol, const OUString& rSymbolName,
+ std::u16string_view rBaseNode) const;
+ void ReadFontFormat(SmFontFormat& rFontFormat, std::u16string_view rSymbolName,
+ std::u16string_view rBaseNode) const;
+
+ bool SetOtherIfNotEqual(bool& rbItem, bool bNewVal);
+
+ void LoadOther();
+ void SaveOther();
+ void LoadFormat();
+ void SaveFormat();
+ void LoadFontFormatList();
+ void SaveFontFormatList();
+
+ void SetOtherModified(bool bVal);
+ bool IsOtherModified() const { return bIsOtherModified; }
+ void SetFormatModified(bool bVal);
+ bool IsFormatModified() const { return bIsFormatModified; }
+
+ SmFontFormatList& GetFontFormatList();
+ const SmFontFormatList& GetFontFormatList() const
+ {
+ return const_cast<SmMathConfig*>(this)->GetFontFormatList();
+ }
+
+ virtual void ImplCommit() override;
+ void LockCommit() { ++m_nCommitLock; }
+ void UnlockCommit();
+ // Used to avoid tens of atomic commits in e.g. ItemSetToConfig that calls individual setters
+ friend struct CommitLocker;
+ struct CommitLocker
+ {
+ SmMathConfig& m_rConfig;
+ CommitLocker(SmMathConfig& rConfig)
+ : m_rConfig(rConfig)
+ {
+ m_rConfig.LockCommit();
+ }
+ ~CommitLocker() { m_rConfig.UnlockCommit(); }
+ };
+
+ void Clear();
+
+public:
+ SmMathConfig();
+ virtual ~SmMathConfig() override;
+
+ // utl::ConfigItem
+ virtual void Notify(const css::uno::Sequence<OUString>& rPropertyNames) override;
+
+ SmSymbolManager& GetSymbolManager();
+ void GetSymbols(std::vector<SmSym>& rSymbols) const;
+ void SetSymbols(const std::vector<SmSym>& rNewSymbols);
+
+ const SmFormat& GetStandardFormat() const;
+ void SetStandardFormat(const SmFormat& rFormat, bool bSaveFontFormatList = false);
+
+ bool IsPrintTitle() const;
+ void SetPrintTitle(bool bVal);
+ bool IsPrintFormulaText() const;
+ void SetPrintFormulaText(bool bVal);
+ bool IsPrintFrame() const;
+ void SetPrintFrame(bool bVal);
+ SmPrintSize GetPrintSize() const;
+ void SetPrintSize(SmPrintSize eSize);
+ sal_uInt16 GetPrintZoomFactor() const;
+ void SetPrintZoomFactor(sal_uInt16 nVal);
+ sal_uInt16 GetSmEditWindowZoomFactor() const;
+ void SetSmEditWindowZoomFactor(sal_uInt16 nVal);
+
+ bool IsSaveOnlyUsedSymbols() const;
+ void SetSaveOnlyUsedSymbols(bool bVal);
+ bool IsAutoCloseBrackets() const;
+ void SetAutoCloseBrackets(bool bVal);
+ bool IsInlineEditEnable() const;
+ void SetInlineEditEnable(bool bVal);
+ bool IsIgnoreSpacesRight() const;
+ void SetIgnoreSpacesRight(bool bVal);
+ bool IsAutoRedraw() const;
+ void SetAutoRedraw(bool bVal);
+ bool IsShowFormulaCursor() const;
+ void SetShowFormulaCursor(bool bVal);
+
+ sal_Int16 GetDefaultSmSyntaxVersion() const;
+ void SetDefaultSmSyntaxVersion(sal_Int16 nVal);
+
+ SmFontPickList& GetFontPickList(sal_uInt16 nIdent) { return vFontPickList[nIdent]; }
+
+ void ItemSetToConfig(const SfxItemSet& rSet);
+ void ConfigToItemSet(SfxItemSet& rSet) const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx
new file mode 100644
index 0000000000..a44c9ed613
--- /dev/null
+++ b/starmath/inc/cursor.hxx
@@ -0,0 +1,428 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "caret.hxx"
+
+#include <list>
+
+/** Factor to multiple the squared horizontal distance with
+ * Used for Up and Down movement.
+ */
+#define HORIZONTICAL_DISTANCE_FACTOR 10
+
+/** Enum of direction for movement */
+enum SmMovementDirection
+{
+ MoveUp,
+ MoveDown,
+ MoveLeft,
+ MoveRight
+};
+
+/** Enum of elements that can inserted into a formula */
+enum SmFormulaElement
+{
+ BlankElement,
+ FactorialElement,
+ PlusElement,
+ MinusElement,
+ CDotElement,
+ EqualElement,
+ LessThanElement,
+ GreaterThanElement,
+ PercentElement
+};
+
+/** Bracket types that can be inserted */
+enum class SmBracketType
+{
+ /** Round brackets, left command "(" */
+ Round,
+ /**Square brackets, left command "[" */
+ Square,
+ /** Curly brackets, left command "lbrace" */
+ Curly,
+};
+
+/** A list of nodes */
+typedef std::list<SmNode*> SmNodeList;
+
+typedef std::list<std::unique_ptr<SmNode>> SmClipboard;
+
+class SmDocShell;
+
+/** Formula cursor
+ *
+ * This class is used to represent a cursor in a formula, which can be used to manipulate
+ * a formula programmatically.
+ * @remarks This class is a very intimate friend of SmDocShell.
+ */
+class SmCursor
+{
+public:
+ SmCursor(SmNode* tree, SmDocShell* pShell)
+ : mpAnchor(nullptr)
+ , mpPosition(nullptr)
+ , mpTree(tree)
+ , mpDocShell(pShell)
+ , mnEditSections(0)
+ , mbIsEnabledSetModifiedSmDocShell(false)
+ {
+ //Build graph
+ BuildGraph();
+ }
+
+ /** Get position */
+ const SmCaretPos& GetPosition() const { return mpPosition->CaretPos; }
+
+ /** True, if the cursor has a selection */
+ bool HasSelection() const { return mpAnchor != mpPosition; }
+
+ /** Move the position of this cursor */
+ void Move(OutputDevice* pDev, SmMovementDirection direction, bool bMoveAnchor = true);
+
+ /** Move to the caret position closest to a given point */
+ void MoveTo(OutputDevice* pDev, const Point& pos, bool bMoveAnchor);
+
+ /** Delete the current selection or do nothing */
+ void Delete();
+
+ /** Delete selection, previous element or merge lines
+ *
+ * This method implements the behaviour of backspace.
+ */
+ void DeletePrev(OutputDevice* pDev);
+
+ /** Insert text at the current position */
+ void InsertText(const OUString& aString);
+
+ /** Insert an element into the formula */
+ void InsertElement(SmFormulaElement element);
+
+ /** Insert command text translated into line entries at position
+ *
+ * Note: This method uses the parser to translate a command text into a
+ * tree, then it copies line entries from this tree into the current tree.
+ * Will not work for commands such as newline or ##, if position is in a matrix.
+ * This will work for stuff like "A intersection B". But stuff spanning multiple lines
+ * or dependent on the context which position is placed in will not work!
+ */
+ void InsertCommandText(const OUString& aCommandText);
+
+ /** Insert a special node created from aString
+ *
+ * Used for handling insert request from the "catalog" dialog.
+ * The provided string should be formatted as the desired command: %phi
+ * Note: this method ONLY supports commands defined in Math.xcu
+ *
+ * For more complex expressions use InsertCommandText, this method doesn't
+ * use SmParser, this means that it's faster, but not as strong.
+ */
+ void InsertSpecial(std::u16string_view aString);
+
+ /** Create sub-/super script
+ *
+ * If there's a selection, it will be move into the appropriate sub-/super scription
+ * of the node in front of it. If there's no node in front of position (or the selection),
+ * a sub-/super scription of a new SmPlaceNode will be made.
+ *
+ * If there's is an existing subscription of the node, the caret will be moved into it,
+ * and any selection will replace it.
+ */
+ void InsertSubSup(SmSubSup eSubSup);
+
+ /** Insert a new row or newline
+ *
+ * Inserts a new row if position is in a matrix or stack command.
+ * Otherwise a newline is inserted if we're in a toplevel line.
+ *
+ * @returns True, if a new row/line could be inserted.
+ *
+ * @remarks If the caret is placed in a subline of a command that doesn't support
+ * this operator the method returns FALSE, and doesn't do anything.
+ */
+ bool InsertRow();
+
+ /** Insert a fraction, use selection as numerator */
+ void InsertFraction();
+
+ /** Create brackets around current selection, or new SmPlaceNode */
+ void InsertBrackets(SmBracketType eBracketType);
+
+ /** Copy the current selection */
+ void Copy(vcl::Window* pWindow = nullptr);
+ /** Cut the current selection */
+ void Cut(vcl::Window* pWindow = nullptr)
+ {
+ Copy(pWindow);
+ Delete();
+ }
+ /** Paste the clipboard */
+ void Paste(vcl::Window* pWindow = nullptr);
+
+ /** Returns true if more than one node is selected
+ *
+ * This method is used for implementing backspace and delete.
+ * If one of these causes a complex selection, e.g. a node with
+ * subnodes or similar, this should not be deleted immediately.
+ */
+ bool HasComplexSelection();
+
+ /** Finds the topmost node in a visual line
+ *
+ * If MoveUpIfSelected is true, this will move up to the parent line
+ * if the parent of the current line is selected.
+ */
+ static SmNode* FindTopMostNodeInLine(SmNode* pSNode, bool MoveUpIfSelected = false);
+
+ /** Draw the caret */
+ void Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible);
+
+ tools::Rectangle GetCaretRectangle(OutputDevice& rOutDev) const;
+ tools::Rectangle GetSelectionRectangle(OutputDevice& rOutDev) const;
+
+ bool IsAtTailOfBracket(SmBracketType eBracketType) const;
+
+private:
+ friend class SmDocShell;
+
+ SmCaretPosGraphEntry *mpAnchor, *mpPosition;
+ /** Formula tree */
+ SmNode* mpTree;
+ /** Owner of the formula tree */
+ SmDocShell* mpDocShell;
+ /** Graph over caret position in the current tree */
+ std::unique_ptr<SmCaretPosGraph> mpGraph;
+
+ /** Returns a node that is selected, if any could be found */
+ SmNode* FindSelectedNode(SmNode* pNode);
+
+ /** Is this one of the nodes used to compose a line
+ *
+ * These are SmExpression, SmBinHorNode, SmUnHorNode etc.
+ */
+ static bool IsLineCompositionNode(SmNode const* pNode);
+
+ /** Count number of selected nodes, excluding line composition nodes
+ *
+ * Note this function doesn't count line composition nodes and it
+ * does count all subnodes as well as the owner nodes.
+ *
+ * Used by SmCursor::HasComplexSelection()
+ */
+ int CountSelectedNodes(SmNode* pNode);
+
+ /** Convert a visual line to a list
+ *
+ * Note this method will delete all the nodes that will no longer be needed.
+ * that includes pLine!
+ * This method also deletes SmErrorNode's as they're just meta info in the line.
+ */
+ static void LineToList(SmStructureNode* pLine, SmNodeList& rList);
+
+ /** Auxiliary function for calling LineToList on a node
+ *
+ * This method sets pNode = NULL and remove it from its parent.
+ * (Assuming it has a parent, and is a child of it).
+ */
+ static void NodeToList(SmNode*& rpNode, SmNodeList& rList)
+ {
+ //Remove from parent and NULL rpNode
+ SmNode* pNode = rpNode;
+ if (rpNode && rpNode->GetParent())
+ { //Don't remove this, correctness relies on it
+ int index = rpNode->GetParent()->IndexOfSubNode(rpNode);
+ assert(index >= 0);
+ rpNode->GetParent()->SetSubNode(index, nullptr);
+ }
+ rpNode = nullptr;
+ //Create line from node
+ if (pNode && IsLineCompositionNode(pNode))
+ {
+ LineToList(static_cast<SmStructureNode*>(pNode), rList);
+ return;
+ }
+ if (pNode)
+ rList.push_front(pNode);
+ }
+
+ /** Clone a visual line to a clipboard
+ *
+ * ... but the selected part only.
+ * Doesn't clone SmErrorNodes, which are ignored as they are context dependent metadata.
+ */
+ static void CloneLineToClipboard(SmStructureNode* pLine, SmClipboard* pClipboard);
+
+ /** Build pGraph over caret positions */
+ void BuildGraph();
+
+ /** Insert new nodes in the tree after position */
+ void InsertNodes(std::unique_ptr<SmNodeList> pNewNodes);
+
+ /** tries to set position to a specific SmCaretPos
+ *
+ * @returns false on failure to find the position in pGraph.
+ */
+ bool SetCaretPosition(SmCaretPos pos);
+
+ /** Set selected on nodes of the tree */
+ void AnnotateSelection() const;
+
+ /** Clone list of nodes in a clipboard (creates a deep clone) */
+ static std::unique_ptr<SmNodeList> CloneList(SmClipboard& rClipboard);
+
+ /** Find an iterator pointing to the node in pLineList following rCaretPos
+ *
+ * If rCaretPos.pSelectedNode cannot be found it is assumed that it's in front of pLineList,
+ * thus not an element in pLineList. In this case this method returns an iterator to the
+ * first element in pLineList.
+ *
+ * If the current position is inside an SmTextNode, this node will be split in two, for this
+ * reason you should beaware that iterators to elements in pLineList may be invalidated, and
+ * that you should call PatchLineList() with this iterator if no action is taken.
+ */
+ static SmNodeList::iterator FindPositionInLineList(SmNodeList* pLineList,
+ const SmCaretPos& rCaretPos);
+
+ /** Patch a line list after modification, merge SmTextNode, remove SmPlaceNode etc.
+ *
+ * @param pLineList The line list to patch
+ * @param aIter Iterator pointing to the element that needs to be patched with its previous.
+ *
+ * When the list is patched text nodes before and after aIter will be merged.
+ * If there's an, in the context, inappropriate SmPlaceNode before or after aIter it will also be
+ * removed.
+ *
+ * @returns A caret position equivalent to one selecting the node before aIter, the method returns
+ * an invalid SmCaretPos to indicate placement in front of the line.
+ */
+ static SmCaretPos PatchLineList(SmNodeList* pLineList, SmNodeList::iterator aIter);
+
+ /** Take selected nodes from a list
+ *
+ * Puts the selected nodes into pSelectedNodes, or if pSelectedNodes is NULL deletes
+ * the selected nodes.
+ * Note: If there's a selection inside an SmTextNode this node will be split, and it
+ * will not be merged when the selection have been taken. Use PatchLineList on the
+ * iterator returns to fix this.
+ *
+ * @returns An iterator pointing to the element following the selection taken.
+ */
+ static SmNodeList::iterator TakeSelectedNodesFromList(SmNodeList* pLineList,
+ SmNodeList* pSelectedNodes = nullptr);
+
+ /** Create an instance of SmMathSymbolNode usable for brackets */
+ static SmNode* CreateBracket(SmBracketType eBracketType, bool bIsLeft);
+
+ /** The number of times BeginEdit have been called
+ * Used to allow nesting of BeginEdit() and EndEdit() sections
+ */
+ int mnEditSections;
+ /** Holds data for BeginEdit() and EndEdit() */
+ bool mbIsEnabledSetModifiedSmDocShell;
+ /** Begin edit section where the tree will be modified */
+ void BeginEdit();
+ /** End edit section where the tree will be modified */
+ void EndEdit();
+ /** Finish editing
+ *
+ * Finishes editing by parsing pLineList and inserting back into pParent at nParentIndex.
+ * This method also rebuilds the graph, annotates the selection, sets caret position and
+ * Calls EndEdit.
+ *
+ * @remarks Please note that this method will delete pLineList, as the elements are taken.
+ *
+ * @param pLineList List the constitutes the edited line.
+ * @param pParent Parent to which the line should be inserted.
+ * @param nParentIndex Index in parent where the line should be inserted.
+ * @param PosAfterEdit Caret position to look for after rebuilding graph.
+ * @param pStartLine Line to take first position in, if PosAfterEdit cannot be found,
+ * leave it NULL for pLineList.
+ */
+ void FinishEdit(std::unique_ptr<SmNodeList> pLineList, SmStructureNode* pParent,
+ int nParentIndex, SmCaretPos PosAfterEdit, SmNode* pStartLine = nullptr);
+ /** Request the formula is repainted */
+ void RequestRepaint();
+};
+
+/** Minimalistic recursive decent SmNodeList parser
+ *
+ * This parser is used to take a list of nodes that constitutes a line
+ * and parse them to a tree of SmBinHorNode, SmUnHorNode and SmExpression.
+ *
+ * Please note, this will not handle all kinds of nodes, only nodes that
+ * constitutes and entry in a line.
+ *
+ * Below is an EBNF representation of the grammar used for this parser:
+ * \code
+ * Expression -> Relation*
+ * Relation -> Sum [(=|<|>|...) Sum]*
+ * Sum -> Product [(+|-) Product]*
+ * Product -> Factor [(*|/) Factor]*
+ * Factor -> [+|-|-+|...]* Factor | Postfix
+ * Postfix -> node [!]*
+ * \endcode
+ */
+class SmNodeListParser
+{
+public:
+ /** Create an instance of SmNodeListParser */
+ SmNodeListParser() { pList = nullptr; }
+ /** Parse a list of nodes to an expression.
+ *
+ * Old error nodes will be deleted.
+ */
+ SmNode* Parse(SmNodeList* list);
+ /** True, if the token is an operator */
+ static bool IsOperator(const SmToken& token);
+ /** True, if the token is a relation operator */
+ static bool IsRelationOperator(const SmToken& token);
+ /** True, if the token is a sum operator */
+ static bool IsSumOperator(const SmToken& token);
+ /** True, if the token is a product operator */
+ static bool IsProductOperator(const SmToken& token);
+ /** True, if the token is a unary operator */
+ static bool IsUnaryOperator(const SmToken& token);
+ /** True, if the token is a postfix operator */
+ static bool IsPostfixOperator(const SmToken& token);
+
+private:
+ SmNodeList* pList;
+ /** Get the current terminal */
+ SmNode* Terminal()
+ {
+ if (!pList->empty())
+ return pList->front();
+ return nullptr;
+ }
+ /** Move to next terminal */
+ SmNode* Next()
+ {
+ pList->pop_front();
+ return Terminal();
+ }
+ /** Take the current terminal */
+ SmNode* Take()
+ {
+ SmNode* pRetVal = Terminal();
+ Next();
+ return pRetVal;
+ }
+ SmNode* Expression();
+ SmNode* Relation();
+ SmNode* Sum();
+ SmNode* Product();
+ SmNode* Factor();
+ SmNode* Postfix();
+ static SmNode* Error();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/dialog.hxx b/starmath/inc/dialog.hxx
new file mode 100644
index 0000000000..3b4f80b8e6
--- /dev/null
+++ b/starmath/inc/dialog.hxx
@@ -0,0 +1,498 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/customweld.hxx>
+#include "symbol.hxx"
+
+class SubsetMap;
+class SmFormat;
+class FontList;
+class SvxShowCharSet;
+
+#define CATEGORY_NONE 0xFFFF
+
+/**************************************************************************/
+
+void SetFontStyle(std::u16string_view rStyleName, vcl::Font &rFont);
+
+/**************************************************************************/
+
+class SmPrintOptionsTabPage final : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xTitle;
+ std::unique_ptr<weld::Widget> m_xTitleImg;
+ std::unique_ptr<weld::CheckButton> m_xText;
+ std::unique_ptr<weld::Widget> m_xTextImg;
+ std::unique_ptr<weld::CheckButton> m_xFrame;
+ std::unique_ptr<weld::Widget> m_xFrameImg;
+ std::unique_ptr<weld::RadioButton> m_xSizeNormal;
+ std::unique_ptr<weld::RadioButton> m_xSizeScaled;
+ std::unique_ptr<weld::RadioButton> m_xSizeZoomed;
+ std::unique_ptr<weld::Widget> m_xLockPrintImg;
+ std::unique_ptr<weld::MetricSpinButton> m_xZoom;
+ std::unique_ptr<weld::CheckButton> m_xEnableInlineEdit;
+ std::unique_ptr<weld::Widget> m_xEnableInlineEditImg;
+ std::unique_ptr<weld::CheckButton> m_xNoRightSpaces;
+ std::unique_ptr<weld::Widget> m_xNoRightSpacesImg;
+ std::unique_ptr<weld::CheckButton> m_xSaveOnlyUsedSymbols;
+ std::unique_ptr<weld::Widget> m_xSaveOnlyUsedSymbolsImg;
+ std::unique_ptr<weld::CheckButton> m_xAutoCloseBrackets;
+ std::unique_ptr<weld::Widget> m_xAutoCloseBracketsImg;
+ std::unique_ptr<weld::MetricSpinButton> m_xSmZoom;
+ std::unique_ptr<weld::Widget> m_xSmZoomImg;
+
+ DECL_LINK(SizeButtonClickHdl, weld::Toggleable&, void);
+
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+public:
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet);
+
+ SmPrintOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rOptions);
+ virtual ~SmPrintOptionsTabPage() override;
+
+ virtual OUString GetAllStrings() override;
+};
+
+/**************************************************************************/
+
+class SmShowFont final : public weld::CustomWidgetController
+{
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+
+ vcl::Font maFont;
+
+public:
+ SmShowFont()
+ {
+ }
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ void SetFont(const vcl::Font& rFont);
+};
+
+class SmFontDialog : public weld::GenericDialogController
+{
+ vcl::Font maFont;
+ SmShowFont m_aShowFont;
+ std::unique_ptr<weld::EntryTreeView> m_xFontBox;
+ std::unique_ptr<weld::Widget> m_xAttrFrame;
+ std::unique_ptr<weld::CheckButton> m_xBoldCheckBox;
+ std::unique_ptr<weld::CheckButton> m_xItalicCheckBox;
+ std::unique_ptr<weld::CustomWeld> m_xShowFont;
+
+ DECL_LINK(FontSelectHdl, weld::ComboBox&, void);
+ DECL_LINK(AttrChangeHdl, weld::Toggleable&, void);
+
+public:
+ SmFontDialog(weld::Window* pParent, OutputDevice *pFntListDevice, bool bHideCheckboxes);
+ virtual ~SmFontDialog() override;
+
+ const vcl::Font& GetFont() const
+ {
+ return maFont;
+ }
+ void SetFont(const vcl::Font &rFont);
+};
+
+/**************************************************************************/
+
+class SmFontSizeDialog final : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::MetricSpinButton> m_xBaseSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xTextSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xIndexSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xFunctionSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xOperatorSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xBorderSize;
+ std::unique_ptr<weld::Button> m_xDefaultButton;
+
+ DECL_LINK(DefaultButtonClickHdl, weld::Button&, void);
+
+public:
+ SmFontSizeDialog(weld::Window *pParent);
+ virtual ~SmFontSizeDialog() override;
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) const;
+};
+
+/**************************************************************************/
+
+class SmFontTypeDialog final : public weld::GenericDialogController
+{
+ VclPtr<OutputDevice> pFontListDev;
+
+ std::unique_ptr<SmFontPickListBox> m_xMathFont;
+ std::unique_ptr<SmFontPickListBox> m_xVariableFont;
+ std::unique_ptr<SmFontPickListBox> m_xFunctionFont;
+ std::unique_ptr<SmFontPickListBox> m_xNumberFont;
+ std::unique_ptr<SmFontPickListBox> m_xTextFont;
+ std::unique_ptr<SmFontPickListBox> m_xSerifFont;
+ std::unique_ptr<SmFontPickListBox> m_xSansFont;
+ std::unique_ptr<SmFontPickListBox> m_xFixedFont;
+ std::unique_ptr<weld::MenuButton> m_xMenuButton;
+ std::unique_ptr<weld::Button> m_xDefaultButton;
+
+ DECL_LINK(MenuSelectHdl, const OUString&, void);
+ DECL_LINK(DefaultButtonClickHdl, weld::Button&, void);
+
+public:
+ SmFontTypeDialog(weld::Window* pParent, OutputDevice *pFntListDevice);
+ virtual ~SmFontTypeDialog() override;
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) const;
+};
+
+/**************************************************************************/
+
+#define NOCATEGORIES 10
+
+class SmCategoryDesc
+{
+ OUString Name;
+ OUString Strings[4];
+ std::unique_ptr<weld::Widget> Graphics[4]; /* regular bitmaps */
+ sal_uInt16 Minimum[4];
+ sal_uInt16 Maximum[4];
+ sal_uInt16 Value[4];
+
+public:
+ SmCategoryDesc(weld::Builder& rBuilder, sal_uInt16 nCategoryIdx);
+ ~SmCategoryDesc();
+
+ const OUString& GetName() const { return Name; }
+ const OUString& GetString(sal_uInt16 Index) const { return Strings[Index]; }
+ sal_uInt16 GetMinimum(sal_uInt16 Index) { return Minimum[Index]; }
+ sal_uInt16 GetMaximum(sal_uInt16 Index) { return Maximum[Index]; }
+ sal_uInt16 GetValue(sal_uInt16 Index) const { return Value[Index]; }
+ void SetValue(sal_uInt16 Index, sal_uInt16 nVal) { Value[Index] = nVal;}
+
+ weld::Widget* GetGraphic(sal_uInt16 Index) const
+ {
+ return Graphics[Index].get();
+ }
+};
+
+class SmDistanceDialog final : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Frame> m_xFrame;
+ std::unique_ptr<weld::Label> m_xFixedText1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMetricField1;
+ std::unique_ptr<weld::Label> m_xFixedText2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMetricField2;
+ std::unique_ptr<weld::Label> m_xFixedText3;
+ std::unique_ptr<weld::MetricSpinButton> m_xMetricField3;
+ std::unique_ptr<weld::CheckButton> m_xCheckBox1;
+ std::unique_ptr<weld::Label> m_xFixedText4;
+ std::unique_ptr<weld::MetricSpinButton> m_xMetricField4;
+ std::unique_ptr<weld::MenuButton> m_xMenuButton;
+ std::unique_ptr<weld::Button> m_xDefaultButton;
+ std::unique_ptr<weld::Widget> m_xBitmap;
+
+ weld::Widget* m_pCurrentImage;
+
+ std::unique_ptr<SmCategoryDesc> m_xCategories[NOCATEGORIES];
+ sal_uInt16 nActiveCategory;
+ bool bScaleAllBrackets;
+
+ DECL_LINK(GetFocusHdl, weld::Widget&, void);
+ DECL_LINK(MenuSelectHdl, const OUString&, void);
+ DECL_LINK(DefaultButtonClickHdl, weld::Button&, void);
+ DECL_LINK(CheckBoxClickHdl, weld::Toggleable&, void);
+
+ void SetCategory(sal_uInt16 Category);
+
+public:
+ SmDistanceDialog(weld::Window *pParent);
+ virtual ~SmDistanceDialog() override;
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat);
+};
+
+/**************************************************************************/
+
+
+class SmAlignDialog final : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::RadioButton> m_xLeft;
+ std::unique_ptr<weld::RadioButton> m_xCenter;
+ std::unique_ptr<weld::RadioButton> m_xRight;
+ std::unique_ptr<weld::Button> m_xDefaultButton;
+
+ DECL_LINK(DefaultButtonClickHdl, weld::Button&, void);
+
+public:
+ SmAlignDialog(weld::Window *pParent);
+ virtual ~SmAlignDialog() override;
+
+ void ReadFrom(const SmFormat &rFormat);
+ void WriteTo (SmFormat &rFormat) const;
+};
+
+/**************************************************************************/
+
+class SmShowSymbolSet final : public weld::CustomWidgetController
+{
+ SmViewShell &m_rViewShell;
+ Size m_aOldSize;
+ SymbolPtrVec_t aSymbolSet;
+ Link<SmShowSymbolSet&,void> aSelectHdlLink;
+ Link<SmShowSymbolSet&,void> aDblClickHdlLink;
+ tools::Long nLen;
+ sal_Int32 nRows, nColumns;
+ tools::Long nXOffset, nYOffset;
+ sal_uInt16 nSelectSymbol;
+ std::unique_ptr<weld::ScrolledWindow> m_xScrolledWindow;
+
+ void SetScrollBarRange();
+ Point OffsetPoint(const Point &rPoint) const;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual bool KeyInput(const KeyEvent& rKEvt) override;
+ virtual void Resize() override;
+
+ DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);
+
+public:
+ SmShowSymbolSet(std::unique_ptr<weld::ScrolledWindow> pScrolledWindow, SmViewShell &rViewShell);
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ m_aOldSize = Size(pDrawingArea->get_approximate_digit_width() * 27,
+ pDrawingArea->get_text_height() * 9);
+ pDrawingArea->set_size_request(m_aOldSize.Width(), m_aOldSize.Height());
+ SetOutputSizePixel(m_aOldSize);
+ calccols(pDrawingArea->get_ref_device());
+ }
+
+ void calccols(const vcl::RenderContext& rRenderContext);
+ void SelectSymbol(sal_uInt16 nSymbol);
+ sal_uInt16 GetSelectSymbol() const { return nSelectSymbol; }
+ void SetSymbolSet(const SymbolPtrVec_t & rSymbolSet);
+ void SetSelectHdl(const Link<SmShowSymbolSet&,void>& rLink) { aSelectHdlLink = rLink; }
+ void SetDblClickHdl(const Link<SmShowSymbolSet&,void>& rLink) { aDblClickHdlLink = rLink; }
+};
+
+class SmShowSymbol final : public weld::CustomWidgetController
+{
+private:
+ SmViewShell &m_rViewShell;
+ vcl::Font m_aFont;
+ OUString m_aText;
+
+ Link<SmShowSymbol&,void> aDblClickHdlLink;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+
+ void setFontSize(vcl::Font &rFont) const;
+
+public:
+ SmShowSymbol(SmViewShell &rViewShell);
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 27,
+ pDrawingArea->get_text_height() * 9);
+ }
+
+ void SetText(const OUString& rText) { m_aText = rText; }
+ const OUString& GetText() const { return m_aText; }
+
+ void SetFont(const vcl::Font& rFont) { m_aFont = rFont; }
+ const vcl::Font& GetFont() const { return m_aFont; }
+
+ void SetSymbol(const SmSym *pSymbol);
+ void SetDblClickHdl(const Link<SmShowSymbol&,void> &rLink) { aDblClickHdlLink = rLink; }
+};
+
+class SmSymbolDialog final : public weld::GenericDialogController
+{
+ SmViewShell &rViewSh;
+ SmSymbolManager &rSymbolMgr;
+
+ OUString aSymbolSetName;
+ SymbolPtrVec_t aSymbolSet;
+
+ VclPtr<OutputDevice> pFontListDev;
+
+ SmShowSymbol m_aSymbolDisplay;
+
+ std::unique_ptr<weld::ComboBox> m_xSymbolSets;
+ std::unique_ptr<SmShowSymbolSet> m_xSymbolSetDisplay;
+ std::unique_ptr<weld::CustomWeld> m_xSymbolSetDisplayArea;
+ std::unique_ptr<weld::Label> m_xSymbolName;
+ std::unique_ptr<weld::CustomWeld> m_xSymbolDisplay;
+ std::unique_ptr<weld::Button> m_xGetBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+
+ DECL_LINK(SymbolSetChangeHdl, weld::ComboBox&, void);
+ DECL_LINK(SymbolChangeHdl, SmShowSymbolSet&, void);
+ DECL_LINK(SymbolDblClickHdl, SmShowSymbol&, void);
+ DECL_LINK(SymbolDblClickHdl2, SmShowSymbolSet&, void);
+ DECL_LINK(EditClickHdl, weld::Button&, void);
+ DECL_LINK(GetClickHdl, weld::Button&, void);
+ void SymbolDblClickHdl();
+
+ void FillSymbolSets();
+ const SmSym *GetSymbol() const;
+
+public:
+ SmSymbolDialog(weld::Window* pParent, OutputDevice *pFntListDevice,
+ SmSymbolManager &rSymbolMgr, SmViewShell &rViewShell);
+ virtual ~SmSymbolDialog() override;
+
+ bool SelectSymbolSet(const OUString &rSymbolSetName);
+ void SelectSymbol(sal_uInt16 nSymbolPos);
+};
+
+class SmShowChar final : public weld::CustomWidgetController
+{
+private:
+ OUString m_aText;
+ vcl::Font m_aFont;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual void Resize() override;
+
+public:
+ SmShowChar()
+ {
+ }
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 7,
+ pDrawingArea->get_text_height() * 3);
+ }
+
+ void SetSymbol(const SmSym *pSym);
+ void SetSymbol(sal_UCS4 cChar, const vcl::Font &rFont);
+ void SetText(const OUString& rText) { m_aText = rText; }
+ const OUString& GetText() const { return m_aText; }
+ void SetFont(const vcl::Font& rFont) { m_aFont = rFont; }
+ const vcl::Font& GetFont() const { return m_aFont; }
+};
+
+class SmSymDefineDialog final : public weld::GenericDialogController
+{
+ VclPtr<VirtualDevice> m_xVirDev;
+ SmSymbolManager m_aSymbolMgrCopy;
+ SmSymbolManager& m_rSymbolMgr;
+ SmShowChar m_aOldSymbolDisplay;
+ SmShowChar m_aSymbolDisplay;
+ std::unique_ptr<SmSym> m_xOrigSymbol;
+ std::unique_ptr<SubsetMap> m_xSubsetMap;
+ std::unique_ptr<FontList> m_xFontList;
+ std::unique_ptr<weld::ComboBox> m_xOldSymbols;
+ std::unique_ptr<weld::ComboBox> m_xOldSymbolSets;
+ std::unique_ptr<weld::ComboBox> m_xSymbols;
+ std::unique_ptr<weld::ComboBox> m_xSymbolSets;
+ std::unique_ptr<weld::ComboBox> m_xFonts;
+ std::unique_ptr<weld::ComboBox> m_xFontsSubsetLB;
+ std::unique_ptr<weld::ComboBox> m_xStyles;
+ std::unique_ptr<weld::Label> m_xOldSymbolName;
+ std::unique_ptr<weld::Label> m_xOldSymbolSetName;
+ std::unique_ptr<weld::Label> m_xSymbolName;
+ std::unique_ptr<weld::Label> m_xSymbolSetName;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xChangeBtn;
+ std::unique_ptr<weld::Button> m_xDeleteBtn;
+ std::unique_ptr<weld::CustomWeld> m_xOldSymbolDisplay;
+ std::unique_ptr<weld::CustomWeld> m_xSymbolDisplay;
+ std::unique_ptr<SvxShowCharSet> m_xCharsetDisplay;
+ std::unique_ptr<weld::CustomWeld> m_xCharsetDisplayArea;
+
+ DECL_LINK(OldSymbolChangeHdl, weld::ComboBox&, void);
+ DECL_LINK(OldSymbolSetChangeHdl, weld::ComboBox&, void);
+ DECL_LINK(ModifyHdl, weld::ComboBox&, void);
+ DECL_LINK(FontChangeHdl, weld::ComboBox&, void);
+ DECL_LINK(SubsetChangeHdl, weld::ComboBox&, void);
+ DECL_LINK(StyleChangeHdl, weld::ComboBox&, void);
+ DECL_LINK(CharHighlightHdl, SvxShowCharSet*, void);
+ DECL_LINK(AddClickHdl, weld::Button&, void);
+ DECL_LINK(ChangeClickHdl, weld::Button&, void);
+ DECL_LINK(DeleteClickHdl, weld::Button&, void);
+
+ void FillSymbols(weld::ComboBox& rComboBox, bool bDeleteText = true);
+ void FillSymbolSets(weld::ComboBox& rComboBox, bool bDeleteText = true);
+ void FillFonts();
+ void FillStyles();
+
+ void SetSymbolSetManager(const SmSymbolManager &rMgr);
+ void SetFont(const OUString &rFontName, std::u16string_view rStyleName);
+ void SetOrigSymbol(const SmSym *pSymbol, const OUString &rSymbolSetName);
+ void UpdateButtons();
+
+ bool SelectSymbolSet(weld::ComboBox &rComboBox, std::u16string_view rSymbolSetName,
+ bool bDeleteText);
+ bool SelectSymbol(weld::ComboBox& rComboBox, const OUString &rSymbolName,
+ bool bDeleteText);
+ bool SelectFont(const OUString &rFontName, bool bApplyFont);
+ bool SelectStyle(const OUString &rStyleName, bool bApplyFont);
+
+ SmSym* GetSymbol(const weld::ComboBox& rComboBox);
+ const SmSym* GetSymbol(const weld::ComboBox& rComboBox) const
+ {
+ return const_cast<SmSymDefineDialog *>(this)->GetSymbol(rComboBox);
+ }
+
+public:
+ SmSymDefineDialog(weld::Window *pParent, OutputDevice *pFntListDevice, SmSymbolManager &rMgr);
+ virtual ~SmSymDefineDialog() override;
+
+ virtual short run() override;
+
+ void SelectOldSymbolSet(std::u16string_view rSymbolSetName)
+ {
+ SelectSymbolSet(*m_xOldSymbolSets, rSymbolSetName, false);
+ }
+
+ void SelectOldSymbol(const OUString &rSymbolName)
+ {
+ SelectSymbol(*m_xOldSymbols, rSymbolName, false);
+ }
+
+ bool SelectSymbolSet(std::u16string_view rSymbolSetName)
+ {
+ return SelectSymbolSet(*m_xSymbolSets, rSymbolSetName, false);
+ }
+
+ bool SelectSymbol(const OUString &rSymbolName)
+ {
+ return SelectSymbol(*m_xSymbols, rSymbolName, false);
+ }
+
+ bool SelectFont(const OUString &rFontName) { return SelectFont(rFontName, true); }
+ bool SelectStyle(const OUString &rStyleName) { return SelectStyle(rStyleName, true); };
+ void SelectChar(sal_Unicode cChar);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/document.hxx b/starmath/inc/document.hxx
new file mode 100644
index 0000000000..c73723a434
--- /dev/null
+++ b/starmath/inc/document.hxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/strbuf.hxx>
+#include <sfx2/docfac.hxx>
+#include <sfx2/objsh.hxx>
+#include <svl/lstner.hxx>
+#include <svl/itempool.hxx>
+#include <sax/fshelper.hxx>
+#include <unotools/lingucfg.hxx>
+#include <oox/core/filterbase.hxx>
+#include <oox/export/utils.hxx>
+
+#include "format.hxx"
+#include "node.hxx"
+#include "parsebase.hxx"
+#include "smdllapi.hxx"
+#include "mathml/iterator.hxx"
+
+class SfxPrinter;
+class Printer;
+class SmCursor;
+
+namespace oox::formulaimport { class XmlStream; }
+
+#define STAROFFICE_XML "StarOffice XML (Math)"
+inline constexpr OUString MATHML_XML = u"MathML XML (Math)"_ustr;
+
+/* Access to printer should happen through this class only
+ * ==========================================================================
+ *
+ * The printer can belong to the document or the OLE-Container. If the document
+ * is an OLE-Document the printer generally belongs to the container too.
+ * But the container maybe works with a different MapUnit than the server.
+ * Referring to the MapMode the printer will be accordingly adjusted in the
+ * constructor and restored in the destructor. This brings that this class
+ * is always allowed to exists only a short time (e.g. while painting).
+ * The control whether the printer is self-generated, gotten from the server
+ * or is NULL then, is taken by the DocShell in the method GetPrt(), for
+ * which the access is friend of the DocShell too.
+ */
+
+class SmDocShell;
+class EditEngine;
+class SmEditEngine;
+class SmPrintUIOptions;
+
+class SmPrinterAccess
+{
+ VclPtr<Printer> pPrinter;
+ VclPtr<OutputDevice> pRefDev;
+public:
+ explicit SmPrinterAccess( SmDocShell &rDocShell );
+ ~SmPrinterAccess();
+ Printer* GetPrinter() { return pPrinter.get(); }
+ OutputDevice* GetRefDev() { return pRefDev.get(); }
+};
+
+
+class SM_DLLPUBLIC SmDocShell final : public SfxObjectShell, public SfxListener
+{
+ friend class SmPrinterAccess;
+ friend class SmCursor;
+
+ OUString maText;
+ SmFormat maFormat;
+ OUString maAccText;
+ SvtLinguOptions maLinguOptions;
+ std::unique_ptr<SmTableNode> mpTree;
+ SmMlElement* m_pMlElementTree;
+ rtl::Reference<SfxItemPool> mpEditEngineItemPool;
+ std::unique_ptr<SmEditEngine> mpEditEngine;
+ VclPtr<SfxPrinter> mpPrinter; //q.v. comment to SmPrinter Access!
+ VclPtr<Printer> mpTmpPrinter; //ditto
+ sal_uInt16 mnModifyCount;
+ bool mbFormulaArranged;
+ sal_Int16 mnSmSyntaxVersion;
+ std::unique_ptr<AbstractSmParser> maParser;
+ std::unique_ptr<SmCursor> mpCursor;
+ std::set< OUString > maUsedSymbols; // to export used symbols only when saving
+
+
+ virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
+
+ bool WriteAsMathType3( SfxMedium& );
+
+ virtual void Draw(OutputDevice *pDevice,
+ const JobSetup & rSetup,
+ sal_uInt16 nAspect,
+ bool bOutputForScreen) override;
+
+ virtual void FillClass(SvGlobalName* pClassName,
+ SotClipboardFormatId* pFormat,
+ OUString* pFullTypeName,
+ sal_Int32 nFileFormat,
+ bool bTemplate = false ) const override;
+
+ virtual void OnDocumentPrinterChanged( Printer * ) override;
+ virtual bool InitNew( const css::uno::Reference< css::embed::XStorage >& xStorage ) override;
+ virtual bool Load( SfxMedium& rMedium ) override;
+ virtual bool Save() override;
+ virtual bool SaveAs( SfxMedium& rMedium ) override;
+
+ Printer *GetPrt();
+ OutputDevice* GetRefDev();
+
+ void SetFormulaArranged(bool bVal) { mbFormulaArranged = bVal; }
+
+ virtual bool ConvertFrom(SfxMedium &rMedium) override;
+
+ /** Called whenever the formula is changed
+ * Deletes the current cursor
+ */
+ void InvalidateCursor();
+
+public:
+ SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+SfxInterfaceId(1))
+
+ SFX_DECL_OBJECTFACTORY();
+
+private:
+ /// SfxInterface initializer.
+ static void InitInterface_Impl();
+
+public:
+ explicit SmDocShell( SfxModelFlags i_nSfxCreationFlags );
+ virtual ~SmDocShell() override;
+
+ virtual bool ConvertTo( SfxMedium &rMedium ) override;
+
+ // For unit tests, not intended to use in other context
+ void SetGreekCharStyle(sal_Int16 nVal) { maFormat.SetGreekCharStyle(nVal); }
+
+ static void LoadSymbols();
+ static void SaveSymbols();
+
+ void ArrangeFormula();
+
+ //Access for the View. This access is not for the OLE-case!
+ //and for the communication with the SFX!
+ //All internal printer uses should work with the SmPrinterAccess only
+ bool HasPrinter() const { return mpPrinter != nullptr; }
+ SfxPrinter *GetPrinter() { GetPrt(); return mpPrinter; }
+ void SetPrinter( SfxPrinter * );
+
+ OUString GetComment() const;
+
+ // to replace chars that can not be saved with the document...
+ void ReplaceBadChars();
+
+ void UpdateText();
+ void SetText(const OUString& rBuffer);
+ const OUString& GetText() const { return maText; }
+ void SetFormat(SmFormat const & rFormat);
+ const SmFormat& GetFormat() const { return maFormat; }
+
+ void Parse();
+ AbstractSmParser* GetParser() { return maParser.get(); }
+ const SmTableNode *GetFormulaTree() const { return mpTree.get(); }
+ void SetFormulaTree(SmTableNode *pTree) { mpTree.reset(pTree); }
+ sal_Int16 GetSmSyntaxVersion() const { return mnSmSyntaxVersion; }
+ void SetSmSyntaxVersion(sal_Int16 nSmSyntaxVersion);
+
+ const std::set< OUString > & GetUsedSymbols() const { return maUsedSymbols; }
+
+ OUString const & GetAccessibleText();
+
+ EditEngine & GetEditEngine();
+
+ void DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection = false);
+ Size GetSize();
+
+ void Repaint();
+
+ virtual SfxUndoManager *GetUndoManager () override;
+
+ static SfxItemPool& GetPool();
+
+ void Execute( SfxRequest& rReq );
+ void GetState(SfxItemSet &);
+
+ virtual void SetVisArea (const tools::Rectangle & rVisArea) override;
+ virtual void SetModified(bool bModified = true) override;
+
+ /** Get a cursor for modifying this document
+ * @remarks Don't store this reference, a new cursor may be made...
+ */
+ SmCursor& GetCursor();
+ /** True, if cursor have previously been requested and thus
+ * has some sort of position.
+ */
+ bool HasCursor() const;
+
+ void writeFormulaOoxml(const ::sax_fastparser::FSHelperPtr& pSerializer,
+ oox::core::OoxmlVersion version,
+ oox::drawingml::DocumentType documentType,
+ const sal_Int8 nAlign);
+ void writeFormulaRtf(OStringBuffer& rBuffer, rtl_TextEncoding nEncoding);
+ void readFormulaOoxml( oox::formulaimport::XmlStream& stream );
+
+ void UpdateEditEngineDefaultFonts();
+
+ SmMlElement* GetMlElementTree() { return m_pMlElementTree; }
+ void SetMlElementTree(SmMlElement* pMlElementTree) {
+ mathml::SmMlIteratorFree(m_pMlElementTree);
+ m_pMlElementTree = pMlElementTree;
+ }
+
+ void SetRightToLeft(bool bRTL);
+
+ void Impl_Print(OutputDevice& rOutDev, const SmPrintUIOptions& rPrintUIOptions,
+ tools::Rectangle aOutRect);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/edit.hxx b/starmath/inc/edit.hxx
new file mode 100644
index 0000000000..2fd6fac636
--- /dev/null
+++ b/starmath/inc/edit.hxx
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <svx/weldeditview.hxx>
+#include <vcl/idle.hxx>
+
+class SmDocShell;
+class SmViewShell;
+class EditView;
+class EditEngine;
+class EditStatus;
+class DataChangedEvent;
+class SmCmdBoxWindow;
+class CommandEvent;
+class Timer;
+
+void SmGetLeftSelectionPart(const ESelection& rSelection, sal_Int32& nPara, sal_uInt16& nPos);
+
+class SmEditWindow;
+
+class SmEditTextWindow : public WeldEditView
+{
+private:
+ SmEditWindow& mrEditWindow;
+
+ Idle aModifyIdle;
+ Idle aCursorMoveIdle;
+
+ ESelection aOldSelection;
+
+ DECL_LINK(ModifyTimerHdl, Timer*, void);
+ DECL_LINK(CursorMoveTimerHdl, Timer*, void);
+ DECL_LINK(EditStatusHdl, EditStatus&, void);
+
+public:
+ SmEditTextWindow(SmEditWindow& rEditWindow);
+ virtual ~SmEditTextWindow() override;
+
+ virtual EditEngine* GetEditEngine() const override;
+
+ virtual void EditViewScrollStateChange() override;
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+
+ virtual bool KeyInput(const KeyEvent& rKeyEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rEvt) override;
+ virtual bool Command(const CommandEvent& rCEvt) override;
+ virtual void GetFocus() override;
+ virtual void LoseFocus() override;
+ virtual void StyleUpdated() override;
+
+ void SetText(const OUString& rText);
+ void InsertText(const OUString& rText);
+ void SelNextMark();
+ ESelection GetSelection() const;
+ void UserPossiblyChangedText();
+ void Flush();
+ void UpdateStatus(bool bSetDocModified);
+ void StartCursorMove();
+};
+
+class SmEditWindow final
+{
+ SmCmdBoxWindow& rCmdBox;
+ std::unique_ptr<weld::ScrolledWindow> mxScrolledWindow;
+ std::unique_ptr<SmEditTextWindow> mxTextControl;
+ std::unique_ptr<weld::CustomWeld> mxTextControlWin;
+
+ DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);
+
+ void CreateEditView(weld::Builder& rBuilder);
+
+public:
+ SmEditWindow(SmCmdBoxWindow& rMyCmdBoxWin, weld::Builder& rBuilder);
+ ~SmEditWindow() COVERITY_NOEXCEPT_FALSE;
+
+ weld::Window* GetFrameWeld() const;
+
+ SmDocShell* GetDoc();
+ SmViewShell* GetView();
+ EditView* GetEditView() const;
+ EditEngine* GetEditEngine();
+ SmCmdBoxWindow& GetCmdBox() const { return rCmdBox; }
+
+ void SetText(const OUString& rText);
+ OUString GetText() const;
+ void Flush();
+ void GrabFocus();
+
+ css::uno::Reference<css::datatransfer::clipboard::XClipboard> GetClipboard() const
+ {
+ return mxTextControl->GetClipboard();
+ }
+
+ ESelection GetSelection() const;
+ void SetSelection(const ESelection& rSel);
+ void UpdateStatus();
+
+ bool IsEmpty() const;
+ bool IsSelected() const;
+ bool IsAllSelected() const;
+ void SetScrollBarRanges();
+ tools::Rectangle AdjustScrollBars();
+ void InvalidateSlots();
+ void Cut();
+ void Copy();
+ void Paste();
+ void Delete();
+ void SelectAll();
+ void InsertText(const OUString& rText);
+ void MarkError(const Point& rPos);
+ void SelNextMark();
+ void SelPrevMark();
+
+ void DeleteEditView();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/format.hxx b/starmath/inc/format.hxx
new file mode 100644
index 0000000000..bcb052e6d4
--- /dev/null
+++ b/starmath/inc/format.hxx
@@ -0,0 +1,156 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "smdllapi.hxx"
+#include <svl/hint.hxx>
+#include <svl/SfxBroadcaster.hxx>
+#include "utility.hxx"
+#include "types.hxx"
+
+
+inline constexpr OUString FNTNAME_TIMES = u"Times New Roman"_ustr;
+inline constexpr OUString FNTNAME_HELV = u"Helvetica"_ustr;
+inline constexpr OUString FNTNAME_COUR = u"Courier"_ustr;
+#define FNTNAME_MATH FONTNAME_MATH
+
+
+// symbolic names used as array indices
+#define SIZ_BEGIN 0
+#define SIZ_TEXT 0
+#define SIZ_INDEX 1
+#define SIZ_FUNCTION 2
+#define SIZ_OPERATOR 3
+#define SIZ_LIMITS 4
+#define SIZ_END 4
+
+// symbolic names used as array indices
+#define FNT_BEGIN 0
+#define FNT_VARIABLE 0
+#define FNT_FUNCTION 1
+#define FNT_NUMBER 2
+#define FNT_TEXT 3
+#define FNT_SERIF 4
+#define FNT_SANS 5
+#define FNT_FIXED 6
+#define FNT_MATH 7
+#define FNT_END 7
+
+// symbolic names used as array indices
+#define DIS_BEGIN 0
+#define DIS_HORIZONTAL 0
+#define DIS_VERTICAL 1
+#define DIS_ROOT 2
+#define DIS_SUPERSCRIPT 3
+#define DIS_SUBSCRIPT 4
+#define DIS_NUMERATOR 5
+#define DIS_DENOMINATOR 6
+#define DIS_FRACTION 7
+#define DIS_STROKEWIDTH 8
+#define DIS_UPPERLIMIT 9
+#define DIS_LOWERLIMIT 10
+#define DIS_BRACKETSIZE 11
+#define DIS_BRACKETSPACE 12
+#define DIS_MATRIXROW 13
+#define DIS_MATRIXCOL 14
+#define DIS_ORNAMENTSIZE 15
+#define DIS_ORNAMENTSPACE 16
+#define DIS_OPERATORSIZE 17
+#define DIS_OPERATORSPACE 18
+#define DIS_LEFTSPACE 19
+#define DIS_RIGHTSPACE 20
+#define DIS_TOPSPACE 21
+#define DIS_BOTTOMSPACE 22
+#define DIS_NORMALBRACKETSIZE 23
+#define DIS_END 23
+
+
+enum class SmHorAlign {
+ Left,
+ Center,
+ Right
+};
+
+class SM_DLLPUBLIC SmFormat final : public SfxBroadcaster
+{
+ SmFace vFont[FNT_END + 1];
+ bool bDefaultFont[FNT_END + 1];
+ Size aBaseSize;
+ sal_uInt16 vSize[SIZ_END + 1];
+ sal_uInt16 vDist[DIS_END + 1];
+ SmHorAlign eHorAlign;
+ sal_Int16 nGreekCharStyle;
+ bool bIsTextmode,
+ bIsRightToLeft,
+ bScaleNormalBrackets;
+
+public:
+ SmFormat();
+ SmFormat(const SmFormat &rFormat) : SfxBroadcaster() { *this = rFormat; }
+
+ const Size & GetBaseSize() const { return aBaseSize; }
+ void SetBaseSize(const Size &rSize) { aBaseSize = rSize; }
+
+ const SmFace & GetFont(sal_uInt16 nIdent) const { return vFont[nIdent]; }
+ void SetFont(sal_uInt16 nIdent, const SmFace &rFont, bool bDefault = false);
+ void SetFontSize(sal_uInt16 nIdent, const Size &rSize) { vFont[nIdent].SetSize( rSize ); }
+
+ void SetDefaultFont(sal_uInt16 nIdent, bool bVal) { bDefaultFont[nIdent] = bVal; }
+ bool IsDefaultFont(sal_uInt16 nIdent) const { return bDefaultFont[nIdent]; }
+
+ sal_uInt16 GetRelSize(sal_uInt16 nIdent) const { return vSize[nIdent]; }
+ void SetRelSize(sal_uInt16 nIdent, sal_uInt16 nVal) { vSize[nIdent] = nVal;}
+
+ sal_uInt16 GetDistance(sal_uInt16 nIdent) const { return vDist[nIdent]; }
+ void SetDistance(sal_uInt16 nIdent, sal_uInt16 nVal) { vDist[nIdent] = nVal; }
+
+ SmHorAlign GetHorAlign() const { return eHorAlign; }
+ void SetHorAlign(SmHorAlign eAlign) { eHorAlign = eAlign; }
+
+ bool IsTextmode() const { return bIsTextmode; }
+ void SetTextmode(bool bVal) { bIsTextmode = bVal; }
+
+ bool IsRightToLeft() const { return bIsRightToLeft; }
+ void SetRightToLeft(bool bVal) { bIsRightToLeft = bVal; }
+
+ sal_Int16 GetGreekCharStyle() const { return nGreekCharStyle; }
+ void SetGreekCharStyle(sal_Int16 nVal) { nGreekCharStyle = nVal; }
+
+ bool IsScaleNormalBrackets() const { return bScaleNormalBrackets; }
+ void SetScaleNormalBrackets(bool bVal) { bScaleNormalBrackets = bVal; }
+
+ SmFormat & operator = (const SmFormat &rFormat);
+
+ bool operator == (const SmFormat &rFormat) const;
+ inline bool operator != (const SmFormat &rFormat) const;
+
+ void RequestApplyChanges()
+ {
+ Broadcast(SfxHint(SfxHintId::MathFormatChanged));
+ }
+
+};
+
+inline bool SmFormat::operator != (const SmFormat &rFormat) const
+{
+ return !(*this == rFormat);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/helpids.h b/starmath/inc/helpids.h
new file mode 100644
index 0000000000..22e1e1dc1f
--- /dev/null
+++ b/starmath/inc/helpids.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+inline constexpr OUString HID_SMA_MAIN_HELP = u"STARMATH_HID_SMA_MAIN_HELP"_ustr;
+inline constexpr OUString HID_SMA_WIN_DOCUMENT = u"STARMATH_HID_SMA_WIN_DOCUMENT"_ustr;
+inline constexpr OUString HID_SMA_COMMAND_WIN_EDIT = u"STARMATH_HID_SMA_COMMAND_WIN_EDIT"_ustr;
+
+inline constexpr OUString HID_SMA_COMMAND_WIN = u"STARMATH_HID_SMA_COMMAND_WIN"_ustr;
+
+inline constexpr OUString HID_SMA_DEFAULT_DIST = u"STARMATH_HID_SMA_DEFAULT_DIST"_ustr;
+inline constexpr OUString HID_SMA_LINE_DIST = u"STARMATH_HID_SMA_LINE_DIST"_ustr;
+inline constexpr OUString HID_SMA_ROOT_DIST = u"STARMATH_HID_SMA_ROOT_DIST"_ustr;
+inline constexpr OUString HID_SMA_SUP_DIST = u"STARMATH_HID_SMA_SUP_DIST"_ustr;
+inline constexpr OUString HID_SMA_SUB_DIST = u"STARMATH_HID_SMA_SUB_DIST"_ustr;
+inline constexpr OUString HID_SMA_NUMERATOR_DIST = u"STARMATH_HID_SMA_NUMERATOR_DIST"_ustr;
+inline constexpr OUString HID_SMA_DENOMINATOR_DIST = u"STARMATH_HID_SMA_DENOMINATOR_DIST"_ustr;
+inline constexpr OUString HID_SMA_FRACLINE_EXCWIDTH = u"STARMATH_HID_SMA_FRACLINE_EXCWIDTH"_ustr;
+inline constexpr OUString HID_SMA_FRACLINE_LINEWIDTH = u"STARMATH_HID_SMA_FRACLINE_LINEWIDTH"_ustr;
+inline constexpr OUString HID_SMA_UPPERLIMIT_DIST = u"STARMATH_HID_SMA_UPPERLIMIT_DIST"_ustr;
+inline constexpr OUString HID_SMA_LOWERLIMIT_DIST = u"STARMATH_HID_SMA_LOWERLIMIT_DIST"_ustr;
+inline constexpr OUString HID_SMA_BRACKET_EXCHEIGHT = u"STARMATH_HID_SMA_BRACKET_EXCHEIGHT"_ustr;
+inline constexpr OUString HID_SMA_BRACKET_DIST = u"STARMATH_HID_SMA_BRACKET_DIST"_ustr;
+inline constexpr OUString HID_SMA_MATRIXROW_DIST = u"STARMATH_HID_SMA_MATRIXROW_DIST"_ustr;
+inline constexpr OUString HID_SMA_MATRIXCOL_DIST = u"STARMATH_HID_SMA_MATRIXCOL_DIST"_ustr;
+inline constexpr OUString HID_SMA_ATTRIBUT_DIST = u"STARMATH_HID_SMA_ATTRIBUT_DIST"_ustr;
+inline constexpr OUString HID_SMA_INTERATTRIBUT_DIST = u"STARMATH_HID_SMA_INTERATTRIBUT_DIST"_ustr;
+inline constexpr OUString HID_SMA_OPERATOR_EXCHEIGHT = u"STARMATH_HID_SMA_OPERATOR_EXCHEIGHT"_ustr;
+inline constexpr OUString HID_SMA_OPERATOR_DIST = u"STARMATH_HID_SMA_OPERATOR_DIST"_ustr;
+inline constexpr OUString HID_SMA_LEFTBORDER_DIST = u"STARMATH_HID_SMA_LEFTBORDER_DIST"_ustr;
+inline constexpr OUString HID_SMA_RIGHTBORDER_DIST = u"STARMATH_HID_SMA_RIGHTBORDER_DIST"_ustr;
+inline constexpr OUString HID_SMA_UPPERBORDER_DIST = u"STARMATH_HID_SMA_UPPERBORDER_DIST"_ustr;
+inline constexpr OUString HID_SMA_LOWERBORDER_DIST = u"STARMATH_HID_SMA_LOWERBORDER_DIST"_ustr;
+inline constexpr OUString HID_SMA_BRACKET_EXCHEIGHT2 = u"STARMATH_HID_SMA_BRACKET_EXCHEIGHT2"_ustr;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/mathml/attribute.hxx b/starmath/inc/mathml/attribute.hxx
new file mode 100644
index 0000000000..946e9f463e
--- /dev/null
+++ b/starmath/inc/mathml/attribute.hxx
@@ -0,0 +1,203 @@
+/* -*- 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 "def.hxx"
+
+/* All possible data needed to do the job outside mathml limits */
+// Ml prefix means it is part of mathml standard
+// NMl means it is not part of mathml standard but needed info to work
+
+/* Union for storing the mathml attribute value */
+/*************************************************************************************************/
+
+union SmMlAttributeValue {
+ SmMlAttributeValue(){};
+
+ struct SmMlAccent m_aAccent;
+ struct SmMlDir m_aDir;
+ struct SmMlDisplaystyle m_aDisplaystyle;
+ struct SmMlFence m_aFence;
+ struct SmMlForm m_aForm;
+ struct SmMlHref m_aHref;
+ struct SmMlLspace m_aLspace;
+ struct SmMlMathbackground m_aMathbackground;
+ struct SmMlMathcolor m_aMathcolor;
+ struct SmMlMathsize m_aMathsize;
+ struct SmMlMathvariant m_aMathvariant;
+ struct SmMlMaxsize m_aMaxsize;
+ struct SmMlMinsize m_aMinsize;
+ struct SmMlMovablelimits m_aMovablelimits;
+ struct SmMlRspace m_aRspace;
+ struct SmMlSeparator m_aSeparator;
+ struct SmMlStretchy m_aStretchy;
+ struct SmMlSymmetric m_aSymmetric;
+};
+
+/* Class managing the attribute value */
+/*************************************************************************************************/
+
+class SmMlAttribute
+{
+private:
+ SmMlAttributeValueType m_aSmMlAttributeValueType;
+ SmMlAttributeValue m_aAttributeValue;
+ bool m_bSet;
+
+private:
+ void clearPreviousAttributeValue();
+ void setDefaultAttributeValue();
+ void setAttributeValue(const SmMlAttribute* aMlAttribute);
+
+public:
+ SmMlAttribute()
+ : m_aSmMlAttributeValueType(SmMlAttributeValueType::NMlEmpty)
+ , m_bSet(false){};
+
+ ~SmMlAttribute() { clearPreviousAttributeValue(); };
+
+ SmMlAttribute(SmMlAttributeValueType)
+ : m_aSmMlAttributeValueType(SmMlAttributeValueType::NMlEmpty)
+ , m_bSet(false)
+ {
+ setDefaultAttributeValue();
+ };
+
+ SmMlAttribute(const SmMlAttribute& aMlAttribute)
+ : m_aSmMlAttributeValueType(SmMlAttributeValueType::NMlEmpty)
+ , m_bSet(aMlAttribute.isSet())
+ {
+ setAttributeValue(&aMlAttribute);
+ }
+
+ SmMlAttribute(const SmMlAttribute* aMlAttribute)
+ : m_aSmMlAttributeValueType(SmMlAttributeValueType::NMlEmpty)
+ , m_bSet(aMlAttribute->isSet())
+ {
+ setAttributeValue(aMlAttribute);
+ }
+
+public:
+ /** Check if the attribute has been set
+ */
+ bool isSet() const { return m_bSet; }
+
+ /** Set if the attribute has been set
+ */
+ void setSet(bool bSet) { m_bSet = bSet; }
+
+public:
+ /**
+ * Returns the type of attribute we are dealing with.
+ * Attribute Value Type
+ */
+ SmMlAttributeValueType getMlAttributeValueType() const { return m_aSmMlAttributeValueType; };
+
+ /**
+ * Checks if the attribute contains information.
+ * Attribute Value Type
+ */
+ bool isNullAttribute() const
+ {
+ return m_aSmMlAttributeValueType == SmMlAttributeValueType::NMlEmpty;
+ };
+
+ /**
+ * Compares the type of attribute with a given one.
+ * Attribute Value Type
+ */
+ bool isMlAttributeValueType(SmMlAttributeValueType aAttributeValueType) const
+ {
+ return m_aSmMlAttributeValueType == aAttributeValueType;
+ };
+
+ /**
+ * Set the type of attribute we are dealing with.
+ * @param Attribute Value Type
+ */
+ void setMlAttributeValueType(SmMlAttributeValueType aAttributeValueType)
+ {
+ clearPreviousAttributeValue();
+ m_aSmMlAttributeValueType = aAttributeValueType;
+ setDefaultAttributeValue();
+ }
+
+ void setMlAttributeValue(const SmMlAttribute& aMlAttribute)
+ {
+ m_bSet = true;
+ setAttributeValue(&aMlAttribute);
+ }
+
+ void setMlAttributeValue(const SmMlAttribute* aMlAttribute)
+ {
+ m_bSet = true;
+ setAttributeValue(aMlAttribute);
+ }
+
+public:
+ // Get values
+ const struct SmMlAccent* getMlAccent() const;
+ const struct SmMlDir* getMlDir() const;
+ const struct SmMlDisplaystyle* getMlDisplaystyle() const;
+ const struct SmMlFence* getMlFence() const;
+ const struct SmMlForm* getMlForm() const;
+ const struct SmMlHref* getMlHref() const;
+ const struct SmMlLspace* getMlLspace() const;
+ const struct SmMlMathbackground* getMlMathbackground() const;
+ const struct SmMlMathcolor* getMlMathcolor() const;
+ const struct SmMlMathsize* getMlMathsize() const;
+ const struct SmMlMathvariant* getMlMathvariant() const;
+ const struct SmMlMaxsize* getMlMaxsize() const;
+ const struct SmMlMinsize* getMlMinsize() const;
+ const struct SmMlMovablelimits* getMlMovablelimits() const;
+ const struct SmMlRspace* getMlRspace() const;
+ const struct SmMlSeparator* getMlSeparator() const;
+ const struct SmMlStretchy* getMlStretchy() const;
+ const struct SmMlSymmetric* getMlSymmetric() const;
+
+ // Set values
+ // Note that content is copied.
+ void setMlAccent(const SmMlAccent* aAccent);
+ void setMlDir(const SmMlDir* aDir);
+ void setMlDisplaystyle(const SmMlDisplaystyle* aDisplaystyle);
+ void setMlFence(const SmMlFence* aFence);
+ void setMlForm(const SmMlForm* aForm);
+ void setMlHref(const SmMlHref* aHref);
+ void setMlLspace(const SmMlLspace* aLspace);
+ void setMlMathbackground(const SmMlMathbackground* aMathbackground);
+ void setMlMathcolor(const SmMlMathcolor* aMathcolor);
+ void setMlMathsize(const SmMlMathsize* aMathsize);
+ void setMlMathvariant(const SmMlMathvariant* aMathvariant);
+ void setMlMaxsize(const SmMlMaxsize* aMaxsize);
+ void setMlMinsize(const SmMlMinsize* aMinSize);
+ void setMlMovablelimits(const SmMlMovablelimits* aMovablelimits);
+ void setMlRspace(const SmMlRspace* aRspace);
+ void setMlSeparator(const SmMlSeparator* aSeparator);
+ void setMlStretchy(const SmMlStretchy* aStretchy);
+ void setMlSymmetric(const SmMlSymmetric* aSymmetric);
+};
+
+/* element's attributes */
+/*************************************************************************************************/
+
+namespace starmathdatabase
+{
+extern SmMlAttributePos MlAttributeListEmpty[1];
+extern SmMlAttributePos MlAttributeListMath[1];
+extern SmMlAttributePos MlAttributeListMi[7];
+extern SmMlAttributePos MlAttributeListMerror[4];
+extern SmMlAttributePos MlAttributeListMn[7];
+extern SmMlAttributePos MlAttributeListMo[18];
+extern SmMlAttributePos MlAttributeListMrow[4];
+extern SmMlAttributePos MlAttributeListMtext[7];
+extern SmMlAttributePos MlAttributeListMstyle[18];
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/mathml/def.hxx b/starmath/inc/mathml/def.hxx
new file mode 100644
index 0000000000..3807367118
--- /dev/null
+++ b/starmath/inc/mathml/def.hxx
@@ -0,0 +1,330 @@
+/* -*- 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 <tools/color.hxx>
+
+/* All possible data needed to do the job outside mathml limits */
+// Ml prefix means it is part of mathml standard
+// NMl means it is not part of mathml standard but needed info to work
+
+/* For now empty, don't know yet what's needed besides default font size. */
+struct SmGlobalData
+{
+};
+
+/* Mhtml length tools */
+/*************************************************************************************************/
+
+enum class SmLengthUnit : uint_fast8_t
+{
+ MlEm,
+ MlEx,
+ MlPx,
+ MlIn,
+ MlCm,
+ MlMm,
+ MlPt,
+ MlPc,
+ MlP, // Percent
+ MlM // Multiplier
+};
+
+struct SmLengthValue
+{
+ SmLengthUnit m_aLengthUnit;
+ double m_aLengthValue;
+ // Keeps original text value to avoid numerical error data loss
+ OUString* m_aOriginalText;
+};
+
+/* Possible mathml elements */
+/*************************************************************************************************/
+
+enum class SmMlElementType : uint_fast8_t
+{
+ // Used for base element. Means no information contained.
+ NMlEmpty,
+ // Used for structural dependencies. Means no information contained.
+ NMlStructural,
+ NMlSmNode,
+ // Mathml real elements
+ MlMath,
+ MlMi,
+ MlMerror,
+ MlMn,
+ MlMo,
+ MlMrow,
+ MlMtext,
+ MlMstyle
+};
+
+/* Possible mathml attributes */
+/*************************************************************************************************/
+
+enum class SmMlAttributeValueType : uint_fast8_t
+{
+ NMlEmpty,
+ MlAccent,
+ MlDir,
+ MlDisplaystyle,
+ MlFence,
+ MlForm,
+ MlHref,
+ MlLspace,
+ MlMathbackground,
+ MlMathcolor,
+ MlMathsize,
+ MlMathvariant,
+ MlMaxsize,
+ MlMinsize,
+ MlMovablelimits,
+ MlRspace,
+ MlSeparator,
+ MlStretchy,
+ MlSymmetric
+};
+
+/* Possible values of mathml attributes */
+/*************************************************************************************************/
+
+enum class SmMlAttributeValueEmpty : uint_fast8_t
+{
+ MlEmpty = 0x00
+};
+
+enum class SmMlAttributeValueAccent : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+enum class SmMlAttributeValueDir : uint_fast8_t
+{
+ MlLtr = 0x00,
+ MlRtl = 0x01
+};
+
+enum class SmMlAttributeValueDisplaystyle : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+enum class SmMlAttributeValueFence : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+enum class SmMlAttributeValueForm : uint_fast8_t
+{
+ MlPrefix = 0x01,
+ MlInfix = 0x02,
+ MlPosfix = 0x04
+};
+
+enum class SmMlAttributeValueHref : uint_fast8_t
+{
+ NMlEmpty = 0x00,
+ NMlValid = 0x01
+};
+
+enum class SmMlAttributeValueLspace : uint_fast8_t
+{
+ NMlEmpty = 0x00
+};
+
+enum class SmMlAttributeValueMathbackground : uint_fast32_t
+{
+ MlTransparent = 0x00,
+ MlRgb = 0x01
+};
+
+enum class SmMlAttributeValueMathcolor : uint_fast8_t
+{
+ MlDefault = 0x00,
+ MlRgb = 0x01
+};
+
+enum class SmMlAttributeValueMathsize : uint_fast8_t
+{
+ NMlEmpty = 0x00,
+};
+
+enum class SmMlAttributeValueMathvariant : uint_fast16_t
+{
+ normal = 0x000,
+ bold = 0x001,
+ italic = 0x002,
+ double_struck = 0x004,
+ script = 0x008,
+ fraktur = 0x010,
+ sans_serif = 0x020,
+ monospace = 0x040,
+ bold_italic = 0x001 | 0x002,
+ bold_fraktur = 0x001 | 0x010,
+ bold_script = 0x001 | 0x008,
+ bold_sans_serif = 0x001 | 0x020,
+ sans_serif_italic = 0x002 | 0x20,
+ sans_serif_bold_italic = 0x001 | 0x002 | 0x020,
+ // Non english
+ initial = 0x080,
+ tailed = 0x100,
+ looped = 0x200,
+ stretched = 0x400
+};
+
+enum class SmMlAttributeValueMaxsize : uint_fast8_t
+{
+ MlInfinity = 0x00,
+ MlFinite = 0x01
+};
+
+/*
+ * Specifies whether attached under- and overscripts move to sub- and superscript positions when displaystyle is false.
+ * Source: https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mo
+ */
+enum class SmMlAttributeValueMovablelimits : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+enum class SmMlAttributeValueRspace : uint_fast8_t
+{
+ NMlEmpty = 0x00
+};
+
+enum class SmMlAttributeValueSeparator : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+enum class SmMlAttributeValueStretchy : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+enum class SmMlAttributeValueSymmetric : uint_fast8_t
+{
+ MlFalse = 0x00,
+ MlTrue = 0x01
+};
+
+/* Structures for all possible attributes */
+/*************************************************************************************************/
+
+struct SmMlAccent
+{
+ SmMlAttributeValueAccent m_aAccent;
+};
+
+struct SmMlDir
+{
+ SmMlAttributeValueDir m_aDir;
+};
+
+struct SmMlDisplaystyle
+{
+ SmMlAttributeValueDisplaystyle m_aDisplaystyle;
+};
+
+struct SmMlFence
+{
+ SmMlAttributeValueFence m_aFence;
+};
+
+struct SmMlForm
+{
+ SmMlAttributeValueForm m_aForm;
+};
+
+struct SmMlHref
+{
+ SmMlAttributeValueHref m_aHref;
+ OUString* m_aLnk;
+};
+
+struct SmMlLspace
+{
+ SmLengthValue m_aLengthValue;
+};
+
+struct SmMlMathbackground
+{
+ SmMlAttributeValueMathbackground m_aMathbackground;
+ Color m_aCol;
+};
+
+struct SmMlMathcolor
+{
+ SmMlAttributeValueMathcolor m_aMathcolor;
+ Color m_aCol;
+};
+
+struct SmMlMathsize
+{
+ SmLengthValue m_aLengthValue;
+};
+
+struct SmMlMathvariant
+{
+ SmMlAttributeValueMathvariant m_aMathvariant;
+};
+
+struct SmMlMaxsize
+{
+ SmMlAttributeValueMaxsize m_aMaxsize;
+ SmLengthValue m_aLengthValue;
+};
+
+struct SmMlMinsize
+{
+ SmLengthValue m_aLengthValue;
+};
+
+struct SmMlMovablelimits
+{
+ SmMlAttributeValueMovablelimits m_aMovablelimits;
+};
+
+struct SmMlRspace
+{
+ SmLengthValue m_aLengthValue;
+};
+
+struct SmMlSeparator
+{
+ SmMlAttributeValueSeparator m_aSeparator;
+};
+
+struct SmMlStretchy
+{
+ SmMlAttributeValueStretchy m_aStretchy;
+};
+
+struct SmMlSymmetric
+{
+ SmMlAttributeValueSymmetric m_aSymmetric;
+};
+
+/* order attributes */
+/*************************************************************************************************/
+
+struct SmMlAttributePos
+{
+ SmMlAttributeValueType m_aAttributeValueType;
+ uint_fast8_t m_nPos;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/mathml/element.hxx b/starmath/inc/mathml/element.hxx
new file mode 100644
index 0000000000..3b39edbf12
--- /dev/null
+++ b/starmath/inc/mathml/element.hxx
@@ -0,0 +1,300 @@
+/* -*- 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 "attribute.hxx"
+#include <rect.hxx>
+
+#include <editeng/editdata.hxx>
+
+class SmMlElement final : public SmRect
+{
+ /* Technical stuff */
+
+public:
+ SmMlElement()
+ : m_aElementType(SmMlElementType::NMlEmpty)
+ , m_aText(u""_ustr)
+ , m_aESelection(0, 0, 0, 0)
+ , m_aAttributeList(0)
+ , m_aAttributePosList(0)
+ , m_aSubElements(0)
+ , m_aParentElement(nullptr)
+ , m_nSubElementId(0)
+ {
+ SmImplAttributeType();
+ };
+ /* Mathml stuff */
+
+public:
+ SmMlElement(SmMlElementType aElementType)
+ : m_aElementType(aElementType)
+ , m_aText(u"\u00B6"_ustr)
+ , 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;
+
+ // Element text
+ OUString m_aText;
+
+ // Location in source code
+ ESelection m_aESelection;
+
+ // Attribute list
+ std::vector<SmMlAttribute> m_aAttributeList;
+
+ // Attribute position list
+ std::vector<SmMlAttributePos> m_aAttributePosList;
+
+ // Sub elements
+ std::vector<SmMlElement*> m_aSubElements;
+
+ // Parent element
+ SmMlElement* m_aParentElement;
+
+ // Child id, so it is possible to iterate
+ size_t m_nSubElementId;
+
+private:
+ void SmImplAttributeType();
+
+public: // Element type
+ /**
+ * Returns the mathml element type
+ * @return mathml element type
+ */
+ SmMlElementType getMlElementType() const { return m_aElementType; };
+
+ /**
+ * Check if the mathml element is of a given type
+ * @param aElementType
+ * @return is mathml element type
+ */
+ bool isMlElementType(SmMlElementType aElementType) const
+ {
+ return m_aElementType == aElementType;
+ };
+
+public: // location in the source
+ /**
+ * Returns the location in the source code of the node type
+ * @return selection
+ */
+ const 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
+ */
+ void setESelection(ESelection aESelection) { m_aESelection = aESelection; };
+
+ /**
+ * Gets the line in the text where the node is located.
+ * It is used to do the visual <-> text correspondence.
+ * @return line
+ */
+ sal_Int32 GetSourceCodeRow() const { return m_aESelection.nStartPara; }
+
+ /**
+ * Gets the column of the line in the text where the node is located.
+ * It is used to do the visual <-> text correspondence.
+ * @return column
+ */
+ sal_Int32 GetSourceCodeColumn() const { return m_aESelection.nStartPos; }
+
+public: // attributes
+ /**
+ * Returns the amount of available attributes
+ * @return attribute count
+ */
+ size_t getAttributeCount() const { return m_aAttributeList.size(); };
+
+ /**
+ * Gets a given attribute.
+ * If no available returns empty attribute.
+ * @param nAttributePos
+ * @return given attribute.
+ */
+ SmMlAttribute getAttribute(size_t nAttributePos) const
+ {
+ return nAttributePos < m_aAttributeList.size() ? m_aAttributeList[nAttributePos]
+ : SmMlAttribute();
+ }
+
+ /**
+ * Gets a given attribute.
+ * If no available returns empty attribute.
+ * @param nAttributePos
+ * @return given attribute.
+ */
+ SmMlAttribute getAttribute(SmMlAttributeValueType aAttributeType) const;
+
+ /**
+ * Sets a given attribute.
+ * If no available does nothing.
+ * @param nAttributePos
+ * @return given attribute.
+ */
+ void setAttribute(const SmMlAttribute* aAttribute);
+
+ /**
+ * Set's a given attribute.
+ * If no available does nothing.
+ * @param nAttributePos
+ * @return given attribute.
+ */
+ void setAttribute(const SmMlAttribute& aAttribute) { setAttribute(&aAttribute); }
+
+ /** Checks if an attribute has been manually set
+ * @param aElementType
+ */
+ bool isAttributeSet(SmMlAttributeValueType aAttributeType) const;
+
+private: // attributes
+ /**
+ * Gets 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;
+ }
+
+ /**
+ * Sets 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
+ * @return sub elements count
+ */
+ size_t getSubElementsCount() const { return m_aSubElements.size(); };
+
+ /**
+ * Returns a given sub element
+ * @param nPos
+ * @return sub elements
+ */
+ SmMlElement* getSubElement(size_t nPos)
+ {
+ return nPos < m_aSubElements.size() ? m_aSubElements[nPos] : nullptr;
+ };
+
+ /**
+ * Returns a given sub element
+ * @param nPos
+ * @return sub elements
+ */
+ const SmMlElement* getSubElement(size_t nPos) const
+ {
+ return nPos < m_aSubElements.size() ? m_aSubElements[nPos] : nullptr;
+ };
+
+ /**
+ * Sets a given sub element
+ * @param nPos
+ * @param aElement
+ */
+ void setSubElement(size_t nPos, SmMlElement* aElement);
+
+ /**
+ * Gets subelement id
+ */
+ size_t getSubElementId() const { return m_nSubElementId; }
+
+ /**
+ * Sets subelement id
+ * @param nSubElementId
+ */
+ void setSubElementId(size_t nSubElementId) { m_nSubElementId = nSubElementId; }
+
+public: // parent elements
+ /**
+ * Returns the parent element
+ * @return parent element
+ */
+ SmMlElement* getParentElement() { return m_aParentElement; };
+
+ /**
+ * Returns the parent element
+ * @return parent element
+ */
+ const SmMlElement* getParentElement() const { return m_aParentElement; };
+
+ /**
+ * Sets the parent element
+ * No allocation / free is done.
+ * @param aParentElement
+ */
+ void setParentElement(SmMlElement* aParentElement) { m_aParentElement = aParentElement; };
+
+public: // text elements
+ /**
+ * Returns the element text
+ */
+ const OUString& getText() const { return m_aText; };
+
+ /**
+ * Returns the element text
+ */
+ void setText(const OUString& rText) { m_aText = rText; };
+};
+
+namespace starmathdatabase
+{
+/**
+ * Generates an attribute vector of default values from an attribute position list.
+ * @param aAttributePosList
+ * @return attribute vector
+ */
+std::vector<SmMlAttribute> makeMlAttributeList(std::vector<SmMlAttributePos> aAttributePosList);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/mathml/export.hxx b/starmath/inc/mathml/export.hxx
new file mode 100644
index 0000000000..08d3f92d06
--- /dev/null
+++ b/starmath/inc/mathml/export.hxx
@@ -0,0 +1,239 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+// Our mathml
+#include "element.hxx"
+
+// Xml tools
+#include <utility>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmltoken.hxx>
+
+// Extras
+#include <com/sun/star/io/XOutputStream.hpp>
+
+class SfxMedium;
+class SmDocShell;
+class SmModel;
+
+class SmMLExportWrapper
+{
+private:
+ // Model
+ rtl::Reference<SmModel> m_xModel;
+ // Save as a flat document ( mml, fodf ... )
+ bool m_bFlat;
+ // Use html / mathml entities
+ bool m_bUseHTMLMLEntities;
+ // Mathmml tree to parse
+ SmMlElement* m_pElementTree;
+ // Export xmlns tag
+ bool m_bUseExportTag;
+
+public:
+ /** Set's the writer to export to flat document
+ */
+ void setFlat(bool bFlat) { m_bFlat = bFlat; }
+
+ /** Checks if the writer is set to export to flat document
+ */
+ bool getFlat() const { return m_bFlat; }
+
+ /** Checks the use of HTML / MathML entities such as &infinity;
+ */
+ void setUseHTMLMLEntities(bool bUseHTMLMLEntities)
+ {
+ m_bUseHTMLMLEntities = bUseHTMLMLEntities;
+ }
+
+ /** Activates the use of HTML / MathML entities such as &infinity;
+ */
+ bool getUseHTMLMLEntities() const { return m_bUseHTMLMLEntities; }
+
+ /** Get's if xmlns field is added
+ */
+ bool getUseExportTag() const { return m_bUseExportTag; }
+
+ /** Set's if xmlns field is added
+ */
+ void setUseExportTag(bool bUseExportTag) { m_bUseExportTag = bUseExportTag; }
+
+public:
+ explicit SmMLExportWrapper(rtl::Reference<SmModel> xRef)
+ : m_xModel(std::move(xRef))
+ , m_bFlat(true)
+ , m_bUseHTMLMLEntities(false)
+ , m_pElementTree(nullptr)
+ , m_bUseExportTag(false)
+ {
+ }
+
+ /** Export to an archive
+ */
+ bool Export(SfxMedium& rMedium);
+
+ /** Just export a mathml tree
+ */
+ OUString Export(SmMlElement* pElementTree);
+
+ // Making this protected we can keep it from getting trash as input
+protected:
+ /** export through an XML exporter component (output stream version)
+ */
+ bool WriteThroughComponentOS(const css::uno::Reference<css::io::XOutputStream>& xOutputStream,
+ const css::uno::Reference<css::lang::XComponent>& xComponent,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char16_t* pComponentName, int_fast16_t nSyntaxVersion);
+
+ /** export through an XML exporter component (storage version)
+ */
+ bool WriteThroughComponentS(const css::uno::Reference<css::embed::XStorage>& xStor,
+ const css::uno::Reference<css::lang::XComponent>& xComponent,
+ const char16_t* pStreamName,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char16_t* pComponentName, int_fast16_t nSyntaxVersion);
+
+ /** export through an XML exporter component (memory stream version)
+ */
+ OUString
+ WriteThroughComponentMS(const css::uno::Reference<css::lang::XComponent>& xComponent,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet);
+};
+
+class SmMLExport final : public SvXMLExport
+{
+private:
+ SmMlElement* m_pElementTree;
+ bool m_bSuccess;
+ bool m_bUseExportTag;
+
+public:
+ /** Everything was allright
+ */
+ bool getSuccess() const { return m_bSuccess; }
+
+ /** Get's if xmlns field is added
+ */
+ bool getUseExportTag() const { return m_bUseExportTag; }
+
+ /** Set's if xmlns field is added
+ */
+ void setUseExportTag(bool bUseExportTag) { m_bUseExportTag = bUseExportTag; }
+
+ /** Set's the element tree to be exported.
+ * If it isn't nullptr the this will be exported instead of the document
+ */
+ void setElementTree(SmMlElement* pElementTree) { m_pElementTree = pElementTree; }
+
+private:
+ /** Adds an element
+ */
+ SvXMLElementExport* createElementExport(xmloff::token::XMLTokenEnum nElement)
+ {
+ // We can't afford to ignore white spaces. They are part of the code.
+ return new SvXMLElementExport(*this, XML_NAMESPACE_MATH, nElement, false, false);
+ }
+
+ /** Adds an attribute
+ */
+ void addAttribute(xmloff::token::XMLTokenEnum pAttribute,
+ xmloff::token::XMLTokenEnum pAttributeValue)
+ {
+ AddAttribute(XML_NAMESPACE_MATH, pAttribute, pAttributeValue);
+ }
+
+ /** Adds an attribute
+ */
+ void addAttribute(xmloff::token::XMLTokenEnum pAttribute, const OUString& pAttributeValue)
+ {
+ AddAttribute(XML_NAMESPACE_MATH, pAttribute, pAttributeValue);
+ }
+
+public:
+ /** Exports an attribute of type "length"
+ */
+ void exportMlAttributeLength(xmloff::token::XMLTokenEnum pAttribute,
+ const SmLengthValue& aLengthValue);
+
+ /** Exports attributes of an element
+ */
+ void exportMlAttributes(const SmMlElement* pMlElement);
+
+ /** Exports an element and all it's attributes
+ */
+ SvXMLElementExport* exportMlElement(const SmMlElement* pMlElement);
+
+ /** Exports an element tree
+ */
+ void exportMlElementTree();
+
+ /** Handles an error on the mathml structure
+ */
+ void declareMlError();
+
+public:
+ /** Constructor
+ */
+ SmMLExport(const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ OUString const& implementationName, SvXMLExportFlags nExportFlags);
+
+private:
+ /** Get's document shell
+ */
+ SmDocShell* getSmDocShell();
+
+public:
+ /** Exports auto styles
+ * However math doesn't have any
+ */
+ void ExportAutoStyles_() override {}
+
+ /** Exports master styles
+ * However math doesn't have any
+ */
+ void ExportMasterStyles_() override {}
+
+ /** Exports formula
+ * Handler used from exportDoc
+ */
+ void ExportContent_() override { exportMlElementTree(); };
+
+ /** Exports the document
+ * If m_pElementTree isn't null then exports m_pElementTree
+ */
+ ErrCode exportDoc(enum ::xmloff::token::XMLTokenEnum eClass
+ = ::xmloff::token::XML_TOKEN_INVALID) override;
+
+ /** Get's view settings and prepares them to export
+ */
+ virtual void GetViewSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
+
+ /** Get's configuration settings and prepares them to export
+ */
+ virtual void
+ GetConfigurationSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/mathml/import.hxx b/starmath/inc/mathml/import.hxx
new file mode 100644
index 0000000000..764d5451c6
--- /dev/null
+++ b/starmath/inc/mathml/import.hxx
@@ -0,0 +1,148 @@
+/* -*- 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
+
+// Our mathml
+#include "element.hxx"
+
+// XML tools
+#include <utility>
+#include <comphelper/errcode.hxx>
+#include <xmloff/xmlimp.hxx>
+
+// Extras
+
+class SfxMedium;
+class SmDocShell;
+class SmMLImport;
+class SmModel;
+
+class SmMLImportWrapper
+{
+ rtl::Reference<SmModel> m_xModel;
+ SmDocShell* m_pDocShell;
+ SmMLImport* m_pMlImport;
+
+private:
+ // Use customized entities
+
+public:
+ /** Get the element tree when parsed from text
+ */
+ SmMlElement* getElementTree();
+
+public:
+ /** Constructor
+ */
+ explicit SmMLImportWrapper(rtl::Reference<SmModel> xRef)
+ : m_xModel(std::move(xRef))
+ , m_pDocShell(nullptr)
+ , m_pMlImport(nullptr)
+ {
+ }
+
+ /** Imports the mathml
+ */
+ ErrCode Import(SfxMedium& rMedium);
+
+ /** Imports the mathml
+ */
+ ErrCode Import(std::u16string_view aSource);
+
+ /** read a component from input stream
+ */
+ ErrCode
+ ReadThroughComponentIS(const css::uno::Reference<css::io::XInputStream>& xInputStream,
+ const css::uno::Reference<css::lang::XComponent>& xModelComponent,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char16_t* pFilterName, bool bEncrypted,
+ int_fast16_t nSyntaxVersion);
+
+ /** read a component from storage
+ */
+ ErrCode ReadThroughComponentS(const css::uno::Reference<css::embed::XStorage>& xStorage,
+ const css::uno::Reference<css::lang::XComponent>& xModelComponent,
+ const char16_t* pStreamName,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char16_t* pFilterName, int_fast16_t nSyntaxVersion);
+
+ /** read a component from text
+ */
+ ErrCode
+ ReadThroughComponentMS(std::u16string_view aText,
+ const css::uno::Reference<css::lang::XComponent>& xModelComponent,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet);
+};
+
+class SmMLImport final : public SvXMLImport
+{
+private:
+ SmMlElement* m_pElementTree = new SmMlElement(SmMlElementType::NMlEmpty);
+ bool m_bSuccess;
+ size_t m_nSmSyntaxVersion;
+
+public:
+ /** Gets parsed element tree
+ */
+ SmMlElement* getElementTree() { return m_pElementTree; }
+
+ /** Checks out if parse was a success
+ */
+ bool getSuccess() const { return m_bSuccess; }
+
+public:
+ /** Handles an error on the mathml structure
+ */
+ void declareMlError();
+
+public:
+ /** Constructor
+ */
+ SmMLImport(const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ OUString const& implementationName, SvXMLImportFlags nImportFlags);
+
+ /** Destructor
+ */
+ virtual ~SmMLImport() noexcept override { cleanup(); };
+
+public:
+ /** End the document
+ */
+ void SAL_CALL endDocument() override;
+
+ /** Create a fast context
+ */
+ SvXMLImportContext* CreateFastContext(
+ sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList) override;
+
+ /** Imports view settings formula
+ */
+ virtual void
+ SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& aViewProps) override;
+
+ /** Imports configurations settings formula
+ */
+ virtual void SetConfigurationSettings(
+ const css::uno::Sequence<css::beans::PropertyValue>& aViewProps) override;
+
+ /** Set syntax version
+ */
+ void SetSmSyntaxVersion(sal_Int16 nSmSyntaxVersion) { m_nSmSyntaxVersion = nSmSyntaxVersion; }
+
+ /** Get syntax version
+ */
+ sal_Int16 GetSmSyntaxVersion() const { return m_nSmSyntaxVersion; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/mathml/iterator.hxx b/starmath/inc/mathml/iterator.hxx
new file mode 100644
index 0000000000..559829ce82
--- /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/inc/mathml/mathmlMo.hxx b/starmath/inc/mathml/mathmlMo.hxx
new file mode 100644
index 0000000000..e6457fd459
--- /dev/null
+++ b/starmath/inc/mathml/mathmlMo.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/*
+ Warning: The SvXMLElementExport helper class creates the beginning and
+ closing tags of xml elements in its constructor and destructor, so there's
+ hidden stuff going on, on occasion the ordering of these classes declarations
+ may be significant
+*/
+
+#pragma once
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <utility>
+#include <vector>
+
+// https://www.w3.org/TR/MathML3/appendixc.html
+
+enum class moOpDP : sal_uInt16
+{ // moOperatorDataProperty
+ nonedp = 0x0000,
+ accent = 0x0001,
+ fence = 0x0002,
+ stretchy = 0x0004,
+ symmetric = 0x0008,
+ separator = 0x0010,
+ linebreakstyleAfter = 0x0020,
+ largeop = 0x0080,
+ movablelimits = 0x0100,
+ starmathCustom = 0x0200,
+ starmathCustomMo = 0x0400,
+ stretchyfence = 0x0006,
+ movablelargeop = 0x0180
+};
+
+enum class moOpDF : sal_uInt16
+{ // moOperatorDataForm
+ nonedf = 0x0000,
+ prefix = 0x0001,
+ infix = 0x0002,
+ postfix = 0x0004,
+ prepostfix = 0x0005
+};
+
+struct moOperatorData
+{
+ OUString m_motxt;
+ moOpDF m_form;
+ sal_uInt16 m_priority;
+ sal_uInt16 m_lspace;
+ sal_uInt16 m_rspace;
+ moOpDP m_properties;
+
+ moOperatorData(OUString motxt, moOpDF form, sal_uInt16 priority, sal_uInt16 lspace,
+ sal_uInt16 rspace, moOpDP properties)
+ : m_motxt(std::move(motxt))
+ , m_form(form)
+ , m_priority(priority)
+ , m_lspace(lspace)
+ , m_rspace(rspace)
+ , m_properties(properties)
+ {
+ }
+};
+
+inline moOpDF operator|(moOpDF a, moOpDF b)
+{
+ return static_cast<moOpDF>(static_cast<sal_uInt16>(a) | static_cast<sal_uInt16>(b));
+}
+
+inline moOpDF operator&(moOpDF a, moOpDF b)
+{
+ return static_cast<moOpDF>(static_cast<sal_uInt16>(a) & static_cast<sal_uInt16>(b));
+}
+
+inline moOpDP operator|(moOpDP a, moOpDP b)
+{
+ return static_cast<moOpDP>(static_cast<sal_uInt16>(a) | static_cast<sal_uInt16>(b));
+}
+
+inline moOpDP operator&(moOpDP a, moOpDP b)
+{
+ return static_cast<moOpDP>(static_cast<sal_uInt16>(a) & static_cast<sal_uInt16>(b));
+}
+
+namespace starmathdatabase
+{
+constexpr size_t MATHML_MO_COUNT = 1100;
+
+extern std::vector<moOperatorData> moOperatorDataDictionary;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/mathml/mathmlattr.hxx b/starmath/inc/mathml/mathmlattr.hxx
new file mode 100644
index 0000000000..b7d1160bb8
--- /dev/null
+++ b/starmath/inc/mathml/mathmlattr.hxx
@@ -0,0 +1,79 @@
+/* -*- 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 <sal/config.h>
+
+#include <string_view>
+
+#include <rtl/ustring.hxx>
+#include <tools/fract.hxx>
+
+// MathML 3: 2.1.5.1 Syntax notation used in the MathML specification
+// <https://www.w3.org/TR/MathML/chapter2.html#id.2.1.5.1>
+// MathML 2: 2.4.4.2 Attributes with units
+// <https://www.w3.org/TR/MathML2/chapter2.html#fund.attval>
+// MathML 3: 2.1.5.2 Length Valued Attributes
+// <https://www.w3.org/TR/MathML/chapter2.html#fund.units>
+
+enum class MathMLLengthUnit
+{
+ None,
+ Em,
+ Ex,
+ Px,
+ In,
+ Cm,
+ Mm,
+ Pt,
+ Pc,
+ Percent
+};
+
+struct MathMLAttributeLengthValue
+{
+ Fraction aNumber;
+ MathMLLengthUnit eUnit;
+ MathMLAttributeLengthValue()
+ : eUnit(MathMLLengthUnit::None)
+ {
+ }
+};
+
+bool ParseMathMLAttributeLengthValue(std::u16string_view rStr, MathMLAttributeLengthValue& rV);
+
+// MathML 3: 3.2.2 Mathematics style attributes common to token elements
+// <https://www.w3.org/TR/MathML3/chapter3.html#presm.commatt>
+
+enum class MathMLMathvariantValue
+{
+ Normal,
+ Bold,
+ Italic,
+ BoldItalic,
+ DoubleStruck,
+ BoldFraktur,
+ Script,
+ BoldScript,
+ Fraktur,
+ SansSerif,
+ BoldSansSerif,
+ SansSerifItalic,
+ SansSerifBoldItalic,
+ Monospace,
+ Initial,
+ Tailed,
+ Looped,
+ Stretched
+};
+
+bool GetMathMLMathvariantValue(const OUString& rStr, MathMLMathvariantValue& rV);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/mathml/mathmlexport.hxx b/starmath/inc/mathml/mathmlexport.hxx
new file mode 100644
index 0000000000..74a6551740
--- /dev/null
+++ b/starmath/inc/mathml/mathmlexport.hxx
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <utility>
+#include <xmloff/xmlexp.hxx>
+#include <xmloff/xmltoken.hxx>
+
+class SfxMedium;
+class SmNode;
+class SmVerticalBraceNode;
+namespace com::sun::star
+{
+namespace io
+{
+class XOutputStream;
+}
+namespace beans
+{
+class XPropertySet;
+}
+}
+
+class SmXMLExportWrapper
+{
+ css::uno::Reference<css::frame::XModel> xModel;
+ bool bFlat; //set true for export to flat .mml, set false for
+ //export to a .sxm (or whatever) package
+
+private:
+ // Use customized entities
+ bool m_bUseHTMLMLEntities;
+
+public:
+ explicit SmXMLExportWrapper(css::uno::Reference<css::frame::XModel> xRef)
+ : xModel(std::move(xRef))
+ , bFlat(true)
+ , m_bUseHTMLMLEntities(false)
+ {
+ }
+
+ bool Export(SfxMedium& rMedium);
+ void SetFlat(bool bIn) { bFlat = bIn; }
+
+ bool IsUseHTMLMLEntities() const { return m_bUseHTMLMLEntities; }
+ void SetUseHTMLMLEntities(bool bUseHTMLMLEntities)
+ {
+ m_bUseHTMLMLEntities = bUseHTMLMLEntities;
+ }
+
+ bool WriteThroughComponent(const css::uno::Reference<css::io::XOutputStream>& xOutputStream,
+ const css::uno::Reference<css::lang::XComponent>& xComponent,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char* pComponentName);
+
+ bool WriteThroughComponent(const css::uno::Reference<css::embed::XStorage>& xStor,
+ const css::uno::Reference<css::lang::XComponent>& xComponent,
+ const char* pStreamName,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char* pComponentName);
+};
+
+class SmXMLExport final : public SvXMLExport
+{
+ const SmNode* pTree;
+ OUString aText;
+ bool bSuccess;
+
+ void ExportNodes(const SmNode* pNode, int nLevel);
+ void ExportTable(const SmNode* pNode, int nLevel);
+ void ExportLine(const SmNode* pNode, int nLevel);
+ void ExportExpression(const SmNode* pNode, int nLevel, bool bNoMrowContainer = false);
+ void ExportText(const SmNode* pNode);
+ void ExportMath(const SmNode* pNode);
+ void ExportBinaryHorizontal(const SmNode* pNode, int nLevel);
+ void ExportUnaryHorizontal(const SmNode* pNode, int nLevel);
+ void ExportBrace(const SmNode* pNode, int nLevel);
+ void ExportBinaryVertical(const SmNode* pNode, int nLevel);
+ void ExportBinaryDiagonal(const SmNode* pNode, int nLevel);
+ void ExportSubSupScript(const SmNode* pNode, int nLevel);
+ void ExportRoot(const SmNode* pNode, int nLevel);
+ void ExportOperator(const SmNode* pNode, int nLevel);
+ void ExportAttributes(const SmNode* pNode, int nLevel);
+ void ExportFont(const SmNode* pNode, int nLevel);
+ void ExportVerticalBrace(const SmVerticalBraceNode* pNode, int nLevel);
+ void ExportMatrix(const SmNode* pNode, int nLevel);
+ void ExportBlank(const SmNode* pNode);
+
+public:
+ SmXMLExport(const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ OUString const& implementationName, SvXMLExportFlags nExportFlags);
+
+ void ExportAutoStyles_() override {}
+ void ExportMasterStyles_() override {}
+ void ExportContent_() override;
+ ErrCode exportDoc(enum ::xmloff::token::XMLTokenEnum eClass
+ = ::xmloff::token::XML_TOKEN_INVALID) override;
+
+ virtual void GetViewSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
+ virtual void
+ GetConfigurationSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
+
+ bool GetSuccess() const { return bSuccess; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/mathml/mathmlimport.hxx b/starmath/inc/mathml/mathmlimport.hxx
new file mode 100644
index 0000000000..3e2b5d2a99
--- /dev/null
+++ b/starmath/inc/mathml/mathmlimport.hxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <utility>
+#include <xmloff/xmlimp.hxx>
+#include <comphelper/errcode.hxx>
+
+#include <deque>
+
+class SmNode;
+class SfxMedium;
+namespace com::sun::star
+{
+namespace beans
+{
+class XPropertySet;
+}
+}
+class SmModel;
+
+typedef std::deque<std::unique_ptr<SmNode>> SmNodeStack;
+
+class SmXMLImportWrapper
+{
+ rtl::Reference<SmModel> m_xModel;
+
+private:
+ // Use customized entities
+ bool m_bUseHTMLMLEntities;
+
+public:
+ explicit SmXMLImportWrapper(rtl::Reference<SmModel> xRef)
+ : m_xModel(std::move(xRef))
+ , m_bUseHTMLMLEntities(false)
+ {
+ }
+
+ ErrCode Import(SfxMedium& rMedium);
+ void useHTMLMLEntities(bool bUseHTMLMLEntities) { m_bUseHTMLMLEntities = bUseHTMLMLEntities; }
+
+ static ErrCode
+ ReadThroughComponent(const css::uno::Reference<css::io::XInputStream>& xInputStream,
+ const css::uno::Reference<css::lang::XComponent>& xModelComponent,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char* pFilterName, bool bEncrypted, bool bUseHTMLMLEntities);
+
+ static ErrCode
+ ReadThroughComponent(const css::uno::Reference<css::embed::XStorage>& xStorage,
+ const css::uno::Reference<css::lang::XComponent>& xModelComponent,
+ const char* pStreamName,
+ css::uno::Reference<css::uno::XComponentContext> const& rxContext,
+ css::uno::Reference<css::beans::XPropertySet> const& rPropSet,
+ const char* pFilterName, bool bUseHTMLMLEntities);
+};
+
+class SmXMLImport final : public SvXMLImport
+{
+ SmNodeStack aNodeStack;
+ bool bSuccess;
+ int nParseDepth;
+ OUString aText;
+ sal_Int16 mnSmSyntaxVersion;
+
+public:
+ SmXMLImport(const css::uno::Reference<css::uno::XComponentContext>& rContext,
+ OUString const& implementationName, SvXMLImportFlags nImportFlags);
+ virtual ~SmXMLImport() noexcept override;
+
+ void SAL_CALL endDocument() override;
+
+ SvXMLImportContext* CreateFastContext(
+ sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList) override;
+
+ SmNodeStack& GetNodeStack() { return aNodeStack; }
+
+ bool GetSuccess() const { return bSuccess; }
+ [[nodiscard]] const OUString& GetText() const { return aText; }
+ void SetText(const OUString& rStr) { aText = rStr; }
+
+ virtual void
+ SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& aViewProps) override;
+ virtual void SetConfigurationSettings(
+ const css::uno::Sequence<css::beans::PropertyValue>& aViewProps) override;
+
+ void IncParseDepth() { ++nParseDepth; }
+ bool TooDeep() const { return nParseDepth >= 2048; }
+ void DecParseDepth() { --nParseDepth; }
+ void SetSmSyntaxVersion(sal_Int16 nSmSyntaxVersion) { mnSmSyntaxVersion = nSmSyntaxVersion; }
+ sal_Int16 GetSmSyntaxVersion() const { return mnSmSyntaxVersion; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/mathml/starmathdatabase.hxx b/starmath/inc/mathml/starmathdatabase.hxx
new file mode 100644
index 0000000000..3af9b009b5
--- /dev/null
+++ b/starmath/inc/mathml/starmathdatabase.hxx
@@ -0,0 +1,326 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <token.hxx>
+
+// Starmath color types
+// In order to add them to starmath, edit the SmColorTokenTableEntry lists on
+// /core/starmath/source/starmathdatabase.css .
+
+// HTML
+// https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_Keywords
+/* CSS Level 1 */
+constexpr Color COL_SM_BLACK(0x000000);
+constexpr Color COL_SM_SILVER(0xC0C0C0);
+constexpr Color COL_SM_GRAY(0x808080);
+constexpr Color COL_SM_WHITE(0xFFFFFF);
+constexpr Color COL_SM_MAROON(0x800000);
+constexpr Color COL_SM_RED(0xFF0000);
+constexpr Color COL_SM_PURPLE(0x800080);
+constexpr Color COL_SM_FUCHSIA(0xFF00FF);
+constexpr Color COL_SM_GREEN(0x008000);
+constexpr Color COL_SM_LIME(0x00FF00);
+constexpr Color COL_SM_OLIVE(0x808000);
+constexpr Color COL_SM_YELLOW(0xFFFF00);
+constexpr Color COL_SM_NAVY(0x000080);
+constexpr Color COL_SM_BLUE(0x0000FF);
+constexpr Color COL_SM_TEAL(0x008080);
+constexpr Color COL_SM_AQUA(0x00FFFF);
+/* CSS Level 2 */
+constexpr Color COL_SM_ORANGE(0xFFA500);
+/* CSS Level 3 */
+constexpr Color COL_SM_ALICEBLUE(0xF0F8FF);
+constexpr Color COL_SM_ANTIQUEWHITE(0xFAEBD7);
+constexpr Color COL_SM_AQUAMARINE(0x7FFFD4);
+constexpr Color COL_SM_AZURE(0xF0FFFF);
+constexpr Color COL_SM_BEIGE(0xF5F5DC);
+constexpr Color COL_SM_BISQUE(0xFFE4C4);
+constexpr Color COL_SM_BLANCHEDALMOND(0xFFEBCD);
+constexpr Color COL_SM_BLUEVIOLET(0x8A2BE2);
+constexpr Color COL_SM_BROWN(0xA52A2A);
+constexpr Color COL_SM_BURLYWOOD(0xDEB887);
+constexpr Color COL_SM_CADETBLUE(0x5F9EA0);
+constexpr Color COL_SM_CHARTREUSE(0x7FFF00);
+constexpr Color COL_SM_CHOCOLATE(0xD2691E);
+constexpr Color COL_SM_CORAL(0xFF7F50);
+constexpr Color COL_SM_CORNFLOWERBLUE(0x6495ED);
+constexpr Color COL_SM_CORNSILK(0xFFF8DC);
+constexpr Color COL_SM_CRIMSON(0xDC143C);
+constexpr Color COL_SM_CYAN(0x00FFFF);
+constexpr Color COL_SM_DARKBLUE(0x00008B);
+constexpr Color COL_SM_DARKCYAN(0x008B8B);
+constexpr Color COL_SM_DARKGOLDENROD(0xB8860B);
+constexpr Color COL_SM_DARKGRAY(0xA9A9A9);
+constexpr Color COL_SM_DARKGREEN(0x006400);
+constexpr Color COL_SM_DARKGREY(0xA9A9A9);
+constexpr Color COL_SM_DARKKHAKI(0xBDB76B);
+constexpr Color COL_SM_DARKMAGENTA(0x8B008B);
+constexpr Color COL_SM_DARKOLIVEGREEN(0x556B2F);
+constexpr Color COL_SM_DARKORANGE(0xFF8C00);
+constexpr Color COL_SM_DARKORCHID(0x9932CC);
+constexpr Color COL_SM_DARKRED(0x8B0000);
+constexpr Color COL_SM_DARKSALMON(0xE9967A);
+constexpr Color COL_SM_DARKSEAGREEN(0x8FBC8F);
+constexpr Color COL_SM_DARKSLATEBLUE(0x483D8B);
+constexpr Color COL_SM_DARKSLATEGRAY(0x2F4F4F);
+constexpr Color COL_SM_DARKSLATEGREY(0x2F4F4F);
+constexpr Color COL_SM_DARKTURQUOISE(0x00CED1);
+constexpr Color COL_SM_DARKVIOLET(0x9400D3);
+constexpr Color COL_SM_DEEPPINK(0xFF1493);
+constexpr Color COL_SM_DEEPSKYBLUE(0x00BFFF);
+constexpr Color COL_SM_DIMGRAY(0x696969);
+constexpr Color COL_SM_DIMGREY(0x696969);
+constexpr Color COL_SM_DODGERBLUE(0x1E90FF);
+constexpr Color COL_SM_FIREBRICK(0xB22222);
+constexpr Color COL_SM_FLORALWHITE(0xFFFAF0);
+constexpr Color COL_SM_FORESTGREEN(0x228B22);
+constexpr Color COL_SM_GAINSBORO(0xDCDCDC);
+constexpr Color COL_SM_GHOSTWHITE(0xF8F8FF);
+constexpr Color COL_SM_GOLD(0xFFD700);
+constexpr Color COL_SM_GOLDENROD(0xDAA520);
+constexpr Color COL_SM_GREENYELLOW(0xADFF2F);
+constexpr Color COL_SM_GREY(0x808080);
+constexpr Color COL_SM_HONEYDEW(0xF0FFF0);
+constexpr Color COL_SM_HOTPINK(0xFF69B4);
+constexpr Color COL_SM_INDIANRED(0xCD5C5C);
+constexpr Color COL_SM_INDIGO(0x4B0082);
+constexpr Color COL_SM_IVORY(0xFFFFF0);
+constexpr Color COL_SM_KHAKI(0xF0E68C);
+constexpr Color COL_SM_LAVENDER(0xE6E6FA);
+constexpr Color COL_SM_LAVENDERBLUSH(0xFFF0F5);
+constexpr Color COL_SM_LAWNGREEN(0x7CFC00);
+constexpr Color COL_SM_LEMONCHIFFON(0xFFFACD);
+constexpr Color COL_SM_LIGHTBLUE(0xADD8E6);
+constexpr Color COL_SM_LIGHTCORAL(0xF08080);
+constexpr Color COL_SM_LIGHTCYAN(0xE0FFFF);
+constexpr Color COL_SM_LIGHTGOLDENRODYELLOW(0xFAFAD2);
+constexpr Color COL_SM_LIGHTGRAY(0xD3D3D3);
+constexpr Color COL_SM_LIGHTGREEN(0x90EE90);
+constexpr Color COL_SM_LIGHTGREY(0xD3D3D3);
+constexpr Color COL_SM_LIGHTPINK(0xFFB6C1);
+constexpr Color COL_SM_LIGHTSALMON(0xFFA07A);
+constexpr Color COL_SM_LIGHTSEAGREEN(0x20B2AA);
+constexpr Color COL_SM_LIGHTSKYBLUE(0x87CEFA);
+constexpr Color COL_SM_LIGHTSLATEGRAY(0x778899);
+constexpr Color COL_SM_LIGHTSLATEGREY(0x778899);
+constexpr Color COL_SM_LIGHTSTEELBLUE(0xB0C4DE);
+constexpr Color COL_SM_LIGHTYELLOW(0xFFFFE0);
+constexpr Color COL_SM_LIMEGREEN(0x32CD32);
+constexpr Color COL_SM_LINEN(0xFAF0E6);
+constexpr Color COL_SM_MAGENTA(0xFF00FF);
+constexpr Color COL_SM_MEDIUMAQUAMARINE(0x66CDAA);
+constexpr Color COL_SM_MEDIUMBLUE(0x0000CD);
+constexpr Color COL_SM_MEDIUMORCHID(0xBA55D3);
+constexpr Color COL_SM_MEDIUMPURPLE(0x9370DB);
+constexpr Color COL_SM_MEDIUMSEAGREEN(0x3CB371);
+constexpr Color COL_SM_MEDIUMSLATEBLUE(0x7B68EE);
+constexpr Color COL_SM_MEDIUMSPRINGGREEN(0x00FA9A);
+constexpr Color COL_SM_MEDIUMTURQUOISE(0x48D1CC);
+constexpr Color COL_SM_MEDIUMVIOLETRED(0xC71585);
+constexpr Color COL_SM_MIDNIGHTBLUE(0x191970);
+constexpr Color COL_SM_MINTCREAM(0xF5FFFA);
+constexpr Color COL_SM_MISTYROSE(0xFFE4E1);
+constexpr Color COL_SM_MOCCASIN(0xFFE4B5);
+constexpr Color COL_SM_NAVAJOWHITE(0xFFDEAD);
+constexpr Color COL_SM_OLDLACE(0xFDF5E6);
+constexpr Color COL_SM_OLIVEDRAB(0x6B8E23);
+constexpr Color COL_SM_ORANGERED(0xFF4500);
+constexpr Color COL_SM_ORCHID(0xDA70D6);
+constexpr Color COL_SM_PALEGOLDENROD(0xEEE8AA);
+constexpr Color COL_SM_PALEGREEN(0x98FB98);
+constexpr Color COL_SM_PALETURQUOISE(0xAFEEEE);
+constexpr Color COL_SM_PALEVIOLETRED(0xDB7093);
+constexpr Color COL_SM_PAPAYAWHIP(0xFFEFD5);
+constexpr Color COL_SM_PEACHPUFF(0xFFDAB9);
+constexpr Color COL_SM_PERU(0xCD853F);
+constexpr Color COL_SM_PINK(0xFFC0CB);
+constexpr Color COL_SM_PLUM(0xDDA0DD);
+constexpr Color COL_SM_POWDERBLUE(0xB0E0E6);
+constexpr Color COL_SM_ROSYBROWN(0xBC8F8F);
+constexpr Color COL_SM_ROYALBLUE(0x4169E1);
+constexpr Color COL_SM_SADDLEBROWN(0x8B4513);
+constexpr Color COL_SM_SALMON(0xFA8072);
+constexpr Color COL_SM_SANDYBROWN(0xF4A460);
+constexpr Color COL_SM_SEAGREEN(0x2E8B57);
+constexpr Color COL_SM_SEASHELL(0xFFF5EE);
+constexpr Color COL_SM_SIENNA(0xA0522D);
+constexpr Color COL_SM_SKYBLUE(0x87CEEB);
+constexpr Color COL_SM_SLATEBLUE(0x6A5ACD);
+constexpr Color COL_SM_SLATEGRAY(0x708090);
+constexpr Color COL_SM_SLATEGREY(0x708090);
+constexpr Color COL_SM_SNOW(0xFFFAFA);
+constexpr Color COL_SM_SPRINGGREEN(0x00FF7F);
+constexpr Color COL_SM_STEELBLUE(0x4682B4);
+constexpr Color COL_SM_TAN(0xD2B48C);
+constexpr Color COL_SM_THISTLE(0xD8BFD8);
+constexpr Color COL_SM_TOMATO(0xFF6347);
+constexpr Color COL_SM_TURQUOISE(0x40E0D0);
+constexpr Color COL_SM_VIOLET(0xEE82EE);
+constexpr Color COL_SM_WHEAT(0xF5DEB3);
+constexpr Color COL_SM_WHITESMOKE(0xF5F5F5);
+constexpr Color COL_SM_YELLOWGREEN(0x9ACD32);
+/* CSS Level 4 */
+constexpr Color COL_SM_REBECCAPURPLE(0x663399);
+/* dvipsnames */
+// For now only five colors.
+// In a future all of them.
+// https://www.overleaf.com/learn/latex/Using_colours_in_LaTeX
+constexpr Color COL_SM_DIV_APRICOT(0xFFB781);
+constexpr Color COL_SM_DIV_AQUAMARINE(0x1BBEC1);
+constexpr Color COL_SM_DIV_BITTERSWEET(0xCF4B16);
+constexpr Color COL_SM_DIV_BLACK(0xCF4B16);
+constexpr Color COL_SM_DIV_BLUE(0x102694);
+/* Iconic colors */
+// https://design.ubuntu.com/brand/colour-palette/
+constexpr Color COL_SM_UBUNTU_ORANGE(0xE95420);
+// https://www.debian.org/logos/ Picked from SVG logo
+constexpr Color COL_SM_DEBIAN_MAGENTA(0xA80030);
+// https://libreoffice.org/
+constexpr Color COL_SM_LO_GREEN(0x00A500);
+
+namespace starmathdatabase
+{
+// Variables containing color information.
+extern const SmColorTokenTableEntry aColorTokenTableParse[159];
+extern const SmColorTokenTableEntry aColorTokenTableHTML[148];
+extern const SmColorTokenTableEntry aColorTokenTableMATHML[16];
+extern const SmColorTokenTableEntry aColorTokenTableDVIPS[5];
+extern const SmColorTokenTableEntry aColorTokenTableERROR[1];
+
+/**
+ * Identifies operator chars tokens for importing mathml.
+ * Identifies from rText
+ *
+ * While loading MO or MI elements might find an unicode16 symbol.
+ * This code allows to generate appropriate token for them.
+ *
+ * @param rText
+ * @return closing fences' token
+ */
+SmToken Identify_SmXMLOperatorContext_Impl(std::u16string_view rText, bool bIsStretchy = true,
+ sal_Int32 nIndex = 0);
+
+/**
+ * Identifies opening / closing brace tokens for importing mathml.
+ * Identifies from rText
+ *
+ * While loading MO fenced elements might find braces symbols.
+ * This code allows to generate appropriate token for them.
+ *
+ * @param rText
+ * @return closing fences' token
+ */
+SmToken Identify_PrefixPostfix_SmXMLOperatorContext_Impl(std::u16string_view rText,
+ sal_Int32 nIndex = 0);
+
+/**
+ * Identifies opening brace tokens for importing mathml.
+ * Identifies from rText
+ *
+ * While loading MO elements ( with prefix value for form attribute ) might find braces symbols.
+ * This code allows to generate appropriate token for them.
+ *
+ * @param rText
+ * @return closing fences' token
+ */
+SmToken Identify_Prefix_SmXMLOperatorContext_Impl(std::u16string_view rText, sal_Int32 nIndex = 0);
+
+/**
+ * Identifies closing brace tokens for importing mathml.
+ * Identifies from rText
+ *
+ * While loading MO elements ( with postfix value for form attribute ) might find braces symbols.
+ * This code allows to generate appropriate token for them.
+ *
+ * @param rText
+ * @return closing fences' token
+ */
+SmToken Identify_Postfix_SmXMLOperatorContext_Impl(std::u16string_view rText, sal_Int32 nIndex = 0);
+
+/**
+ * Identifies color from color code cColor.
+ * It will be returned with the parser syntax.
+ *
+ * For a given color returns the way it would be in the parser.
+ * Used for nodes to text visitors.
+ *
+ * @param cColor
+ * @param parser color
+ */
+SmColorTokenTableEntry Identify_Color_Parser(sal_uInt32 cColor);
+
+/**
+ * Identifies color from color code cColor.
+ * It will be returned with the MATHML syntax.
+ *
+ * This is used to export mathml.
+ * Identifies the color and allows it to export it in proper mathml code.
+ *
+ * @param cColor
+ * @param parser color
+ */
+SmColorTokenTableEntry Identify_Color_MATHML(sal_uInt32 cColor);
+
+/**
+ * Identifies color from color code cColor.
+ * It will be returned with the dvipsnames syntax.
+ * @param cColor
+ * @param parser color
+ */
+SmColorTokenTableEntry Identify_Color_DVIPSNAMES(sal_uInt32 cColor);
+
+/**
+ * Identifies color from color name.
+ * It will be returned with the parser syntax.
+ *
+ * This finds color values for the color names loaded by the parser.
+ *
+ * @param cColor
+ * @param parser color
+ */
+const SmColorTokenTableEntry* Identify_ColorName_Parser(std::u16string_view colorname);
+
+/**
+ * Identifies color from color name.
+ * It will be returned with the HTML syntax.
+ *
+ * This finds color values for the color names loaded by mathmlimport.
+ * In theory mathml only supports HTML4 colors, but most browsers support all HTML5 colors.
+ * That's why there is an high risk of finding them inside mathml and have to give support.
+ *
+ * @param cColor
+ * @param parser color
+ */
+SmColorTokenTableEntry Identify_ColorName_HTML(std::u16string_view colorname);
+
+/**
+ * Identifies color from color name.
+ * It will be returned with the dvipsnames syntax.
+ *
+ * This code has been implemented to add a compatibility layer to import / export latex.
+ *
+ * @param cColor
+ * @param parser color
+ */
+const SmColorTokenTableEntry* Identify_ColorName_DVIPSNAMES(std::u16string_view colorname);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/mathml/xparsmlbase.hxx b/starmath/inc/mathml/xparsmlbase.hxx
new file mode 100644
index 0000000000..6c645a55e3
--- /dev/null
+++ b/starmath/inc/mathml/xparsmlbase.hxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/beans/Pair.hpp>
+namespace starmathdatabase
+{
+/**
+ * w3 documentation has been used for this.
+ * See: https://www.w3.org/2003/entities/2007/htmlmathml-f.ent
+ * Copyright 1998 - 2011 W3C.
+ * We allow the import of HTML5 entities because are compatible with mathml
+ * and ill formatted are expected.
+ * On export only mathml entities are allowed.
+ * Some documentation: https://www.w3.org/TR/MathML3/chapter7.html
+ */
+
+constexpr sal_Int32 STARMATH_MATHMLHTML_ENTITY_NUMBER = 2125;
+
+/**
+ * Entity names for mathml. Example: &infin -> \u221E;
+ * These ones are to be used on import.
+ */
+const extern ::css::uno::Sequence<::css::beans::Pair<::rtl::OUString, ::rtl::OUString>>
+ icustomMathmlHtmlEntities;
+
+/**
+ * Entity names for mathml. Example: "\u221E"; -> &infin;
+ * These ones are to be used on file export.
+ */
+const extern ::css::uno::Sequence<::css::beans::Pair<::rtl::OUString, ::rtl::OUString>>
+ icustomMathmlHtmlEntitiesExport;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx
new file mode 100644
index 0000000000..b637fea76d
--- /dev/null
+++ b/starmath/inc/node.hxx
@@ -0,0 +1,2096 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** The SmNode is the basic structure of formula data.
+ *
+ * Each token is stored in one node of specific kind.
+ * They can have SmNodeType. It allows to identify node type after abstraction.
+ * Here goes the subclasses tree:
+ *
+ * SmRect
+ * SmNode
+ * SmStructureNode Head of tree diagram
+ * SmTableNode binom
+ * SmLineNode A line
+ * SmExpressionNode { content }
+ * SmUnHorNode unary operators +-; -+; +x; -x; ...
+ * SmRootNode Root structure
+ * SmBinHorNode binary operators A + B
+ * SmBinVerNode over; frac; ...
+ * SmBinDiagonalNode wideslash
+ * SmSubSupNode csub, csup, lsub, from, to, ...
+ * SmBraceNode (); []; left lbrace right rbrace; ...
+ * SmBracebodyNode ( content ); [ content ]; ...
+ * SmVerticalBraceNode overbrace; underbrace;
+ * SmOperNode sum from to; int from to;
+ * SmAlignNode text alignment
+ * SmAttributeNode font attributes; bold;
+ * SmFontNode font serif; ...
+ * SmMatrixNode matrix
+ * SmVisibleNode drawable node
+ * SmGraphicNode graphics display
+ * SmRectangleNode
+ * SmPolyLineNode overline; underline; widehat; ...
+ * SmBlankNode blank space; ~; ...
+ * SmTextNode "text"; func functname; ...
+ * SmSpecialNode
+ * SmGlyphSpecialNode %symbolname
+ * SmMathSymbolNode math symbols
+ * SmMathIdentifierNode variable
+ * SmRootSymbolNode root symbol
+ * SmPlaceNode <?>
+ * SmErrorNode red ? for errors
+ *
+ */
+
+#pragma once
+
+#include "types.hxx"
+#include "token.hxx"
+#include "rect.hxx"
+#include "format.hxx"
+#include "nodetype.hxx"
+
+#include <editeng/editdata.hxx>
+#include <rtl/ustrbuf.hxx>
+
+enum class FontAttribute {
+ None = 0x0000,
+ Bold = 0x0001,
+ Italic = 0x0002
+};
+
+namespace o3tl
+{
+ template<> struct typed_flags<FontAttribute> : is_typed_flags<FontAttribute, 0x0003> {};
+}
+
+
+enum class FontSizeType {
+ ABSOLUT = 1,
+ PLUS = 2,
+ MINUS = 3,
+ MULTIPLY = 4,
+ DIVIDE = 5
+};
+
+// flags to interdict respective status changes
+enum class FontChangeMask {
+ None = 0x0000,
+ Face = 0x0001,
+ Size = 0x0002,
+ Bold = 0x0004,
+ Italic = 0x0008,
+ Color = 0x0010,
+ Phantom = 0x0020
+};
+
+namespace o3tl
+{
+ template<> struct typed_flags<FontChangeMask> : is_typed_flags<FontChangeMask, 0x003f> {};
+}
+
+
+class SmVisitor;
+class SmDocShell;
+class SmNode;
+class SmStructureNode;
+
+typedef std::vector< SmNode * > SmNodeArray;
+
+enum class SmScaleMode
+{
+ None,
+ Width,
+ Height
+};
+
+class SmNode : public SmRect
+{
+ // Rendering info for SmRect
+ SmFace maFace;
+ // Anclage to the code
+ SmToken maNodeToken;
+ ESelection m_aESelection;
+ // Node information
+ SmNodeType meType;
+ SmScaleMode meScaleMode;
+ RectHorAlign meRectHorAlign;
+ FontChangeMask mnFlags;
+ FontAttribute mnAttributes;
+ bool mbIsPhantom;
+ bool mbIsSelected;
+ // index in accessible text; -1 if not (yet) applicable
+ sal_Int32 mnAccIndex;
+
+protected:
+ SmNode(SmNodeType eNodeType, SmToken aNodeToken);
+
+public:
+ SmNode(const SmNode&) = delete;
+ SmNode& operator=(const SmNode&) = delete;
+
+ virtual ~SmNode();
+
+ /**
+ * Checks node visibility.
+ * Returns true if this is an instance of SmVisibleNode's subclass, false otherwise.
+ * @return node visibility
+ */
+ virtual bool IsVisible() const = 0;
+
+ /**
+ * Gets the number of subnodes.
+ * @return number of subnodes
+ */
+ virtual size_t GetNumSubNodes() const = 0;
+
+ /**
+ * Gets the subnode of index nIndex.
+ * @param nIndex
+ * @return subnode of index nIndex
+ */
+ virtual SmNode * GetSubNode(size_t nIndex) = 0;
+ const SmNode * GetSubNode(size_t nIndex) const
+ { return const_cast<SmNode *>(this)->GetSubNode(nIndex); }
+
+ virtual const SmNode * GetLeftMost() const;
+
+ /**
+ * Gets the FontChangeMask flags.
+ * @return FontChangeMask flags
+ */
+ FontChangeMask &Flags() { return mnFlags; }
+
+ /**
+ * Gets the font attributes.
+ * @return font attributes
+ */
+ FontAttribute &Attributes() { return mnAttributes; }
+
+ /**
+ * Checks if it is a visible node rendered invisible.
+ * @return rendered visibility
+ */
+ bool IsPhantom() const { return mbIsPhantom; }
+
+ /**
+ * Sets the render visibility of a visible node to bIsPhantom.
+ * @param bIsPhantom
+ * @return
+ */
+ void SetPhantom(bool bIsPhantom);
+
+ /**
+ * Sets the font color.
+ * @param rColor
+ * @return
+ */
+ void SetColor(const Color &rColor);
+
+ /**
+ * Sets the font attribute nAttrib.
+ * Check FontAttribute class.
+ * @param nAttrib
+ * @return
+ */
+ void SetAttribute(FontAttribute nAttrib);
+
+ /**
+ * Clears the font attribute nAttrib.
+ * Check FontAttribute class.
+ * @param nAttrib
+ * @return
+ */
+ void ClearAttribute(FontAttribute nAttrib);
+
+ /**
+ * Gets the font.
+ * @return font
+ */
+ const SmFace & GetFont() const { return maFace; };
+ SmFace & GetFont() { return maFace; };
+
+ /**
+ * Sets the font to rFace.
+ * @param rFace
+ * @return
+ */
+ void SetFont(const SmFace &rFace);
+
+ /**
+ * Sets the font size to rRelSize with type nType.
+ * Check FontSizeType for details.
+ * @param rRelSize
+ * @param nType
+ * @return
+ */
+ void SetFontSize(const Fraction &rRelSize, FontSizeType nType);
+
+ /**
+ * Sets the font size to rRelSize with type FontSizeType::ABSOLUT.
+ * @param rScale
+ * @return
+ */
+ void SetSize(const Fraction &rScale);
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell, int nDepth);
+
+ /**
+ * Prepare preliminary font attributes
+ * Called on Prepare(...).
+ * @return
+ */
+ void PrepareAttributes();
+
+ /**
+ * Sets the alignment of the text.
+ * Check RectHorAlign class for details.
+ * The subtrees will be affected if bApplyToSubTree.
+ * @param eHorAlign
+ * @param bApplyToSubTree
+ * @return
+ */
+ void SetRectHorAlign(RectHorAlign eHorAlign, bool bApplyToSubTree = true );
+
+ /**
+ * Gets the alignment of the text.
+ * @return alignment of the text
+ */
+ RectHorAlign GetRectHorAlign() const { return meRectHorAlign; }
+
+ /**
+ * Parses itself to SmRect.
+ * @return this
+ */
+ const SmRect & GetRect() const { return *this; }
+
+ /**
+ * Moves the rectangle by rVector.
+ * @param rVector
+ * @return
+ */
+ void Move(const Point &rVector);
+
+ /**
+ * Moves the rectangle to rPoint, being the top left corner the origin.
+ * @param rPoint
+ * @return
+ */
+ void MoveTo(const Point &rPoint) { Move(rPoint - GetTopLeft()); }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) = 0;
+
+ /**
+ * Appends to rText the node text.
+ * @param rText
+ * @return
+ */
+ virtual void GetAccessibleText( OUStringBuffer &rText ) const = 0;
+
+ /**
+ * Gets the node accessible index.
+ * Used for visual editing.
+ * @return node accessible index
+ */
+ sal_Int32 GetAccessibleIndex() const { return mnAccIndex; }
+
+ /**
+ * Sets the node accessible index to nAccIndex.
+ * Used for visual editing.
+ * @param nAccIndex
+ * @return
+ */
+ void SetAccessibleIndex(sal_Int32 nAccIndex) { mnAccIndex = nAccIndex; }
+
+ /**
+ * Finds the node with accessible index nAccIndex.
+ * Used for visual editing.
+ * @param nAccIndex
+ * @return node with accessible index nAccIndex
+ */
+ const SmNode * FindNodeWithAccessibleIndex(sal_Int32 nAccIndex) const;
+
+ /**
+ * Gets the line in the text where the node is located.
+ * It is used to do the visual <-> text correspondence.
+ * @return line
+ */
+ sal_uInt16 GetRow() const { return sal::static_int_cast<sal_uInt16>(m_aESelection.nStartPara); }
+
+ /**
+ * Gets the column of the line in the text where the node is located.
+ * It is used to do the visual <-> text correspondence.
+ * @return column
+ */
+ sal_uInt16 GetColumn() const { return sal::static_int_cast<sal_uInt16>(m_aESelection.nStartPos); }
+
+ /**
+ * Gets the scale mode.
+ * @return scale mode
+ */
+ SmScaleMode GetScaleMode() const { return meScaleMode; }
+
+ /**
+ * Sets the scale mode to eMode.
+ * @param eMode
+ * @return
+ */
+ void SetScaleMode(SmScaleMode eMode) { meScaleMode = eMode; }
+
+ //visual stuff TODO comment
+ virtual void AdaptToX(OutputDevice &rDev, sal_uLong nWidth);
+ virtual void AdaptToY(OutputDevice &rDev, sal_uLong nHeight);
+
+ /**
+ * Gets the node type.
+ * @return node type
+ */
+ SmNodeType GetType() const { return meType; }
+
+ /**
+ * Gets the token.
+ * The token contains the data extracted from the text mode.
+ * Ej: text, type (sub, sup, int,...), row and column,...
+ * @return node type
+ */
+ const SmToken & GetToken() const { return maNodeToken; }
+ SmToken & GetToken() { return maNodeToken; }
+
+ /**
+ * Gets node position in input text.
+ * @return node position in input text
+ */
+ const ESelection& GetSelection() const { return m_aESelection; }
+
+ /**
+ * Gets node position in input text.
+ * @param aESelection
+ */
+ void SetSelection(ESelection aESelection) { m_aESelection = aESelection; }
+
+ /**
+ * Finds the node from the position in the text.
+ * It is used to do the visual <-> text correspondence.
+ * @param nRow
+ * @param nCol
+ * @return the given node
+ */
+ const SmNode * FindTokenAt(sal_uInt16 nRow, sal_uInt16 nCol) const;
+
+ /**
+ * Finds the closest rectangle in the screen.
+ * @param rPoint
+ * @return the given node
+ */
+ const SmNode * FindRectClosestTo(const Point &rPoint) const;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ virtual void Accept(SmVisitor* pVisitor) = 0;
+
+ /**
+ * Checks if the node is selected.
+ * @return the node is selected
+ */
+ bool IsSelected() const {return mbIsSelected;}
+
+ /**
+ * Sets the node to Selected.
+ * @param Selected
+ * @return
+ */
+ void SetSelected(bool Selected) {mbIsSelected = Selected;}
+
+ /**
+ * Gets the parent node of this node.
+ * @return parent node
+ */
+ const SmStructureNode* GetParent() const { return mpParentNode; }
+ SmStructureNode* GetParent() { return mpParentNode; }
+
+ /**
+ * Sets the parent node.
+ * @param parent
+ * @return
+ */
+ void SetParent(SmStructureNode* parent){ mpParentNode = parent; }
+
+ /**
+ * Sets the token for this node.
+ * @param token
+ * @return
+ */
+ void SetToken(SmToken const & token){ maNodeToken = token; }
+
+private:
+ SmStructureNode* mpParentNode;
+};
+
+
+/** Abstract baseclass for all composite node
+ *
+ * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
+ * this class does not have subnodes.
+ */
+class SmStructureNode : public SmNode
+{
+ SmNodeArray maSubNodes;
+
+protected:
+ SmStructureNode(SmNodeType eNodeType, const SmToken &rNodeToken, size_t nSize = 0)
+ : SmNode(eNodeType, rNodeToken)
+ , maSubNodes(nSize) {}
+
+public:
+ virtual ~SmStructureNode() override;
+
+ /**
+ * Checks node visibility.
+ * Returns true if this is an instance of SmVisibleNode's subclass, false otherwise.
+ * @return node visibility
+ */
+ virtual bool IsVisible() const override;
+
+ /**
+ * Gets the number of subnodes.
+ * @return number of subnodes
+ */
+ virtual size_t GetNumSubNodes() const override;
+
+ /**
+ * Gets the subnode of index nIndex.
+ * @param nIndex
+ * @return subnode of index nIndex
+ */
+ using SmNode::GetSubNode;
+ virtual SmNode * GetSubNode(size_t nIndex) override;
+
+ /**
+ * Gets the subnode of index nIndex, used for operators.
+ * @param nIndex
+ * @return subnode of index nIndex
+ */
+ SmNode * GetSubNodeBinMo(size_t nIndex) const;
+
+ /**
+ * Does the cleaning of the subnodes.
+ * @return
+ */
+ void ClearSubNodes();
+
+ /**
+ * Sets subnodes, used for operators.
+ * @param pFirst
+ * @param pSecond
+ * @param pThird
+ * @return
+ */
+ void SetSubNodes(std::unique_ptr<SmNode> pFirst, std::unique_ptr<SmNode> pSecond,
+ std::unique_ptr<SmNode> pThird = nullptr);
+
+ /**
+ * Sets subnodes.
+ * @param pFirst
+ * @param pSecond
+ * @param pThird
+ * @return
+ */
+ void SetSubNodes(SmNode* pFirst, SmNode* pSecond, SmNode* pThird);
+
+ /**
+ * Sets subnodes, used for operators.
+ * The data is reordered so the items are correctly ordered.
+ * @param pFirst
+ * @param pSecond
+ * @param pThird
+ * @return
+ */
+ void SetSubNodesBinMo(std::unique_ptr<SmNode> pFirst, std::unique_ptr<SmNode> pSecond,
+ std::unique_ptr<SmNode> pThird = nullptr);
+
+ /**
+ * Sets subnodes.
+ * @param rNodeArray
+ * @return
+ */
+ void SetSubNodes(SmNodeArray&& rNodeArray);
+
+ /**
+ * Appends to rText the node text.
+ * @param rText
+ * @return
+ */
+ virtual void GetAccessibleText( OUStringBuffer &rText ) const override;
+
+ /**
+ * Gets the first subnode.
+ * @return first subnode
+ */
+ SmNodeArray::iterator begin() {return maSubNodes.begin();}
+
+ /**
+ * Gets the last subnode.
+ * @return last subnode
+ */
+ SmNodeArray::iterator end() {return maSubNodes.end();}
+
+ /**
+ * Gets the last subnode.
+ * @return last subnode
+ */
+ SmNodeArray::reverse_iterator rbegin() {return maSubNodes.rbegin();}
+
+ /**
+ * Gets the first subnode.
+ * @return first subnode
+ */
+ SmNodeArray::reverse_iterator rend() {return maSubNodes.rend();}
+
+ /**
+ * Get the index of the child node pSubNode.
+ * Returns -1, if pSubNode isn't a subnode of this.
+ * @param pSubNode
+ * @return index of the child node
+ */
+ int IndexOfSubNode(SmNode const * pSubNode);
+
+ /**
+ * Sets the subnode pNode at nIndex.
+ * If necessary increases the subnodes length.
+ * @param nIndex
+ * @param pNode
+ * @return
+ */
+ void SetSubNode(size_t nIndex, SmNode* pNode);
+
+private:
+ /** Sets parent on children of this node */
+ void ClaimPaternity();
+};
+
+
+/** Abstract base class for all visible node
+ *
+ * Nodes that doesn't derivate from this class doesn't draw anything, but their
+ * children.
+ */
+class SmVisibleNode : public SmNode
+{
+protected:
+ SmVisibleNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmNode(eNodeType, rNodeToken) {}
+
+public:
+
+ /**
+ * Checks node visibility.
+ * Returns true if this is an instance of SmVisibleNode's subclass, false otherwise.
+ * @return node visibility
+ */
+ virtual bool IsVisible() const override;
+
+ /**
+ * Gets the number of subnodes.
+ * @return number of subnodes
+ */
+ virtual size_t GetNumSubNodes() const override;
+
+ /**
+ * Gets the subnode of index nIndex.
+ * @param nIndex
+ * @return subnode of index nIndex
+ */
+ using SmNode::GetSubNode;
+ virtual SmNode * GetSubNode(size_t nIndex) override;
+};
+
+
+class SmGraphicNode : public SmVisibleNode
+{
+protected:
+ SmGraphicNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmVisibleNode(eNodeType, rNodeToken) {}
+
+public:
+
+ /**
+ * Appends to rText the node text.
+ * @param rText
+ * @return
+ */
+ virtual void GetAccessibleText( OUStringBuffer &rText ) const override;
+};
+
+
+/** Draws a rectangle
+ *
+ * Used for drawing the line in the OVER and OVERSTRIKE commands.
+ */
+class SmRectangleNode final : public SmGraphicNode
+{
+ Size maToSize;
+
+public:
+ explicit SmRectangleNode(const SmToken &rNodeToken)
+ : SmGraphicNode(SmNodeType::Rectangle, rNodeToken)
+ {}
+
+ //visual stuff TODO comment
+ virtual void AdaptToX(OutputDevice &rDev, sal_uLong nWidth) override;
+ virtual void AdaptToY(OutputDevice &rDev, sal_uLong nHeight) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Polygon line node
+ *
+ * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
+ */
+class SmPolyLineNode final : public SmGraphicNode
+{
+ tools::Polygon maPoly;
+ Size maToSize;
+ tools::Long mnWidth;
+
+public:
+ explicit SmPolyLineNode(const SmToken &rNodeToken);
+
+ /**
+ * Gets the width of the rect.
+ * @return width
+ */
+ tools::Long GetWidth() const { return mnWidth; }
+
+ /**
+ * Gets the polygon to draw the node.
+ * @return polygon
+ */
+ tools::Polygon &GetPolygon() { return maPoly; }
+
+ //visual stuff TODO comment
+ virtual void AdaptToX(OutputDevice &rDev, sal_uLong nWidth) override;
+ virtual void AdaptToY(OutputDevice &rDev, sal_uLong nHeight) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Text node
+ *
+ * @remarks This class also serves as baseclass for all nodes that contains text.
+ */
+class SmTextNode : public SmVisibleNode
+{
+ OUString maText;
+ sal_uInt16 mnFontDesc;
+ /** Index within text where the selection starts
+ * @remarks Only valid if SmNode::IsSelected() is true
+ */
+ sal_Int32 mnSelectionStart;
+ /** Index within text where the selection ends
+ * @remarks Only valid if SmNode::IsSelected() is true
+ */
+ sal_Int32 mnSelectionEnd;
+
+protected:
+ SmTextNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP );
+
+public:
+ SmTextNode(const SmToken &rNodeToken, sal_uInt16 nFontDescP );
+
+ /**
+ * Returns the font type being used (text, variable, symbol, ...).
+ * @return font type
+ */
+ sal_uInt16 GetFontDesc() const { return mnFontDesc; }
+
+ /**
+ * Sets the node text to rText.
+ * @param rText
+ * @return
+ */
+ void SetText(const OUString &rText) { maText = rText; }
+
+ /**
+ * Gets the node text.
+ * @return node text
+ */
+ const OUString & GetText() const { return maText; }
+ OUString & GetText() { return maText; }
+
+ /**
+ * Change the text of this node, including the underlying token to rText.
+ * @param rText
+ * @return
+ */
+ void ChangeText(const OUString &rText);
+
+ /**
+ * Try to guess the correct FontDesc, used during visual editing
+ * @return
+ */
+ void AdjustFontDesc();
+
+ /**
+ * Index within GetText() where the selection starts.
+ * @remarks Only valid of SmNode::IsSelected() is true.
+ * @return index.
+ */
+ sal_Int32 GetSelectionStart() const { return mnSelectionStart; }
+
+ /**
+ * Index within GetText() where the selection ends.
+ * @remarks Only valid of SmNode::IsSelected() is true.
+ * @return index.
+ */
+ sal_Int32 GetSelectionEnd() const {return mnSelectionEnd; }
+
+ /**
+ * Sets the index within GetText() where the selection starts to index.
+ * @param index
+ * @return
+ */
+ void SetSelectionStart(sal_Int32 index) {mnSelectionStart = index;}
+
+ /**
+ * Sets the index within GetText() where the selection ends to index.
+ * @param index
+ * @return
+ */
+ void SetSelectionEnd(sal_Int32 index) {mnSelectionEnd = index;}
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Appends to rText the node text.
+ * @param rText
+ * @return
+ */
+ virtual void GetAccessibleText( OUStringBuffer &rText ) const override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+
+ /**
+ * Converts the character from StarMath's private area symbols to a matching Unicode
+ * character, if necessary. To be used when converting GetText() to a normal text.
+ * @param nIn
+ * @return unicode char
+ */
+ static sal_Unicode ConvertSymbolToUnicode(sal_Unicode nIn);
+};
+
+
+/** Special node for user defined characters
+ *
+ * Node used for pre- and user-defined characters from:
+ * officecfg/registry/data/org/openoffice/Office/Math.xcu
+ *
+ * This is just single characters, I think.
+ */
+class SmSpecialNode : public SmTextNode
+{
+protected:
+ SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc);
+
+public:
+ explicit SmSpecialNode(const SmToken &rNodeToken);
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Glyph node for custom operators
+ *
+ * This node is used with commands: oper, uoper and boper.
+ * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
+ * "boper" simply interprets "op", the following token, as a binary operator.
+ * The command "uoper" interprets the following token as unary operator.
+ * For these commands an instance of SmGlyphSpecialNode is used for the
+ * operator token, following the command.
+ */
+class SmGlyphSpecialNode final : public SmSpecialNode
+{
+public:
+ explicit SmGlyphSpecialNode(const SmToken &rNodeToken)
+ : SmSpecialNode(SmNodeType::GlyphSpecial, rNodeToken, FNT_MATH)
+ {}
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Math symbol node
+ *
+ * Use for math symbols such as plus, minus and integral in the INT command.
+ */
+class SmMathSymbolNode : public SmSpecialNode
+{
+protected:
+ SmMathSymbolNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmSpecialNode(eNodeType, rNodeToken, FNT_MATH)
+ {
+ SetText(GetToken().cMathChar);
+ }
+
+public:
+ explicit SmMathSymbolNode(const SmToken &rNodeToken);
+
+ //visual stuff TODO comment
+ virtual void AdaptToX(OutputDevice &rDev, sal_uLong nWidth) override;
+ virtual void AdaptToY(OutputDevice &rDev, sal_uLong nHeight) override;
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Math Identifier
+ *
+ * This behaves essentially the same as SmMathSymbolNode and is only used to
+ * represent math symbols that should be exported as <mi> elements rather than
+ * <mo> elements.
+ */
+class SmMathIdentifierNode final : public SmMathSymbolNode
+{
+public:
+ explicit SmMathIdentifierNode(const SmToken &rNodeToken)
+ : SmMathSymbolNode(SmNodeType::MathIdent, rNodeToken) {}
+};
+
+
+/** Root symbol node
+ *
+ * Root symbol node used by SmRootNode to create the root symbol, in front of
+ * the line with the line above. I don't think this node should be used for
+ * anything else.
+ */
+class SmRootSymbolNode final : public SmMathSymbolNode
+{
+ sal_uLong mnBodyWidth; // width of body (argument) of root sign
+
+public:
+ explicit SmRootSymbolNode(const SmToken &rNodeToken)
+ : SmMathSymbolNode(SmNodeType::RootSymbol, rNodeToken)
+ , mnBodyWidth(0) { }
+
+ /**
+ * Gets the body width.
+ * Allows to know how long is the root and paint it.
+ * @return body width
+ */
+ sal_uLong GetBodyWidth() const {return mnBodyWidth;};
+
+ //visual stuff TODO comment
+ virtual void AdaptToX(OutputDevice &rDev, sal_uLong nHeight) override;
+ virtual void AdaptToY(OutputDevice &rDev, sal_uLong nHeight) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Place node
+ *
+ * Used to create the <?> command, that denotes place where something can be
+ * written.
+ * It is drawn as a square with a shadow.
+ */
+class SmPlaceNode final : public SmMathSymbolNode
+{
+public:
+ explicit SmPlaceNode(const SmToken &rNodeToken)
+ : SmMathSymbolNode(SmNodeType::Place, rNodeToken) { }
+ SmPlaceNode() : SmMathSymbolNode(SmNodeType::Place, SmToken(TPLACE, MS_PLACE, "<?>")) { };
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Error node, for parsing errors
+ *
+ * This node is used for parsing errors and draws a questionmark turned upside
+ * down (inverted question mark).
+ */
+class SmErrorNode final : public SmMathSymbolNode
+{
+public:
+ explicit SmErrorNode(const SmToken &rNodeToken)
+ : SmMathSymbolNode(SmNodeType::Error, rNodeToken) { SetText(OUString(MS_ERROR)); }
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Table node
+ *
+ * This is the root node for the formula tree. This node is also used for the
+ * STACK and BINOM commands. When used for root node, its
+ * children are instances of SmLineNode, and in some obscure cases the child
+ * can be an instance of SmExpressionNode, mainly when errors occur.
+ */
+class SmTableNode final : public SmStructureNode
+{
+ tools::Long mnFormulaBaseline;
+public:
+ explicit SmTableNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Table, rNodeToken)
+ , mnFormulaBaseline(0) { }
+
+ virtual const SmNode * GetLeftMost() const override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Gets the formula baseline.
+ * @return formula baseline
+ */
+ tools::Long GetFormulaBaseline() const;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** A line
+ *
+ * Used as child of SmTableNode when the SmTableNode is the root node of the
+ * formula tree.
+ */
+class SmLineNode : public SmStructureNode
+{
+ bool mbUseExtraSpaces;
+
+protected:
+ SmLineNode(SmNodeType eNodeType, const SmToken &rNodeToken)
+ : SmStructureNode(eNodeType, rNodeToken)
+ , mbUseExtraSpaces(true) { }
+
+public:
+ explicit SmLineNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Line, rNodeToken)
+ , mbUseExtraSpaces(true) { }
+
+ /**
+ * Sets if it going to use extra spaces.
+ * It is used to set if there has to be space between node while rendering.
+ * By default it is true.
+ * @param bVal
+ * @return
+ */
+ void SetUseExtraSpaces(bool bVal) { mbUseExtraSpaces = bVal; }
+
+ /**
+ * Checks if it is using extra spaces.
+ * It is used for calculating space between nodes when rendering.
+ * By default it is true.
+ * @return is using extra spaces
+ */
+ bool IsUseExtraSpaces() const { return mbUseExtraSpaces; };
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Expression node
+ *
+ * Used whenever you have an expression such as "A OVER {B + C}", here there is
+ * an expression node that allows "B + C" to be the denominator of the
+ * SmBinVerNode, that the OVER command creates.
+ */
+class SmExpressionNode final : public SmLineNode
+{
+public:
+ explicit SmExpressionNode(const SmToken &rNodeToken)
+ : SmLineNode(SmNodeType::Expression, rNodeToken) { }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Unary horizontal node
+ *
+ * The same as SmBinHorNode except this is for unary operators.
+ */
+class SmUnHorNode final : public SmStructureNode
+{
+public:
+ explicit SmUnHorNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::UnHor, rNodeToken, 2) { }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Root node
+ *
+ * Used for create square roots and other roots, example:
+ * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
+ *
+ * Children:<BR>
+ * 0: Argument (optional)<BR>
+ * 1: Symbol (instance of SmRootSymbolNode)<BR>
+ * 2: Body<BR>
+ * Where argument is optional and may be NULL.
+ */
+class SmRootNode final : public SmStructureNode
+{
+public:
+ explicit SmRootNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Root, rNodeToken, 3) { }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+
+ /**
+ * Returns the node containing the data of the order of the root.
+ * @return order data
+ */
+ const SmNode* Argument() const { return const_cast<SmRootNode *>(this)->Argument(); }
+ SmNode* Argument() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 0 ); }
+
+ /**
+ * Returns the node containing the data of the character used for the root.
+ * @return symbol data
+ */
+ const SmRootSymbolNode* Symbol() const { return const_cast<SmRootNode *>(this)->Symbol(); }
+ SmRootSymbolNode* Symbol() { assert( GetNumSubNodes() == 3 );
+ assert( GetSubNode( 1 )->GetType()
+ == SmNodeType::RootSymbol );
+ return static_cast< SmRootSymbolNode* >
+ ( GetSubNode( 1 )); }
+
+ /**
+ * Returns the node containing the data inside the root.
+ * @return body data
+ */
+ const SmNode* Body() const { return const_cast<SmRootNode *>(this)->Body(); }
+ SmNode* Body() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 2 ); }
+
+};
+
+
+/** Binary horizontal node
+ *
+ * This node is used for binary operators. In a formula such as "A + B".
+ *
+ * Children:<BR>
+ * 0: Left operand<BR>
+ * 1: Binary operator<BR>
+ * 2: Right operand<BR>
+ *
+ * None of the children may be NULL.
+ */
+class SmBinHorNode final : public SmStructureNode
+{
+public:
+ explicit SmBinHorNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::BinHor, rNodeToken, 3) { }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+
+ /**
+ * Returns the node containing the data of the binary operator.
+ * @return symbol data
+ */
+ const SmNode* Symbol() const { return const_cast<SmBinHorNode *>(this)->Symbol(); }
+ SmNode* Symbol() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 1 ); }
+
+ /**
+ * Returns the node containing the data of the left operand.
+ * @return left operand data
+ */
+ const SmNode* LeftOperand() const { return const_cast<SmBinHorNode *>(this)->LeftOperand(); }
+ SmNode* LeftOperand() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 0 ); }
+
+ /**
+ * Returns the node containing the data of the right operand.
+ * @return right operand data
+ */
+ const SmNode* RightOperand() const { return const_cast<SmBinHorNode *>(this)->RightOperand(); }
+ SmNode* RightOperand() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 2 ); }
+};
+
+
+/** Binary horizontal node
+ *
+ * This node is used for creating the OVER command, consider the formula:
+ * "numerator OVER denominator", which looks like
+ * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
+ *
+ * Children:<BR>
+ * 0: Numerator<BR>
+ * 1: Line (instance of SmRectangleNode)<BR>
+ * 2: Denominator<BR>
+ * None of the children may be NULL.
+ */
+class SmBinVerNode final : public SmStructureNode
+{
+public:
+ explicit SmBinVerNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::BinVer, rNodeToken, 3) { }
+
+ virtual const SmNode * GetLeftMost() const override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Binary diagonal node
+ *
+ * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
+ *
+ * Children:<BR>
+ * 0: Left operand<BR>
+ * 1: right operand<BR>
+ * 2: Line (instance of SmPolyLineNode).<BR>
+ * None of the children may be NULL.
+ */
+class SmBinDiagonalNode final : public SmStructureNode
+{
+ bool mbAscending;
+
+ /**
+ * Returns the position and size of the diagonal line by reference.
+ * @param rPos
+ * @param rSize
+ * @param rDiagPoint
+ * @param fAngleDeg
+ * @return position and size of the diagonal line
+ */
+ void GetOperPosSize(Point &rPos, Size &rSize, const Point &rDiagPoint, double fAngleDeg) const;
+
+public:
+ explicit SmBinDiagonalNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::BinDiagonal, rNodeToken, 3)
+ , mbAscending(false) { }
+
+ /**
+ * Checks if it is of ascending type.
+ * Ascending:
+ * / b
+ * /
+ * a /
+ * Descending:
+ * a \
+ * \
+ * \ b
+ * @return ascending.
+ */
+ bool IsAscending() const { return mbAscending; }
+
+ /**
+ * Sets if the wideslash is ascending to bVal.
+ * @param bVal
+ * @return
+ */
+ void SetAscending(bool bVal) { mbAscending = bVal; }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Enum used to index sub-/supscripts in the 'maSubNodes' array
+ * in 'SmSubSupNode'
+ *
+ * See graphic for positions at char:
+ *
+ * \code
+ * CSUP
+ *
+ * LSUP H H RSUP
+ * H H
+ * HHHH
+ * H H
+ * LSUB H H RSUB
+ *
+ * CSUB
+ * \endcode
+ */
+enum SmSubSup
+{ CSUB, CSUP, RSUB, RSUP, LSUB, LSUP
+};
+
+/** numbers of entries in the above enum (that is: the number of possible
+ * sub-/supscripts)
+ */
+#define SUBSUP_NUM_ENTRIES 6
+
+/** Super- and subscript node
+ *
+ * Used for creating super- and subscripts for commands such as:
+ * "^", "_", "lsup", "lsub", "csup" and "csub".
+ * Example: "A^2" which looks like: \f$ A^2 \f$
+ *
+ * This node is also used for creating limits on SmOperNode, when
+ * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
+ *
+ * Children of this node can be enumerated using the SmSubSup enum.
+ * Please note that children may be NULL, except for the body.
+ * It is recommended that you access children using GetBody() and
+ * GetSubSup().
+ */
+class SmSubSupNode final : public SmStructureNode
+{
+ bool mbUseLimits;
+
+public:
+ explicit SmSubSupNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::SubSup, rNodeToken, 1 + SUBSUP_NUM_ENTRIES)
+ , mbUseLimits(false) { }
+
+ /**
+ * Returns the node with the data of what has to be superindex or subindex.
+ * @return body data
+ */
+ const SmNode * GetBody() const { return const_cast<SmSubSupNode *>(this)->GetBody(); }
+ SmNode * GetBody() { return GetSubNode(0); }
+
+ /**
+ * Checks if it is going to be used for a limit.
+ * Example lim from { x toward 0 } { {sin x}over x } = 1
+ * @return is a limit
+ */
+ bool IsUseLimits() const { return mbUseLimits; };
+
+ /**
+ * Sets if it is going to be used for a limit to bVal.
+ * @param bVal
+ * @return
+ */
+ void SetUseLimits(bool bVal) { mbUseLimits = bVal; }
+
+ /**
+ * Gets the node with the data of what has to be superindex or subindex.
+ * The position to check is given by eSubSup.
+ * @remarks this method may return NULL.
+ * @param eSubSup
+ * @return body data
+ */
+ const SmNode * GetSubSup(SmSubSup eSubSup) const { return const_cast< SmSubSupNode* >
+ ( this )->GetSubSup( eSubSup ); }
+ SmNode * GetSubSup(SmSubSup eSubSup) { return GetSubNode(1 + eSubSup); };
+
+ /**
+ * Sets the node with the data of what has to be superindex or subindex.
+ * @param pScript
+ */
+ void SetBody(SmNode* pBody) { SetSubNode(0, pBody); }
+
+ /**
+ * Sets the node with the data of what has to be superindex or subindex.
+ * The position to check is given by eSubSup.
+ * @param eSubSup
+ * @param pScript
+ */
+ void SetSubSup(SmSubSup eSubSup, SmNode* pScript) { SetSubNode( 1 + eSubSup, pScript); }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+
+};
+
+
+/** Node for brace construction
+ *
+ * Used for "lbrace [body] rbrace" and similar constructions.
+ * Should look like \f$ \{\mbox{[body]}\} \f$
+ *
+ * Children:<BR>
+ * 0: Opening brace<BR>
+ * 1: Body (usually SmBracebodyNode)<BR>
+ * 2: Closing brace<BR>
+ * None of the children can be NULL.
+ *
+ * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
+ */
+class SmBraceNode final : public SmStructureNode
+{
+public:
+ explicit SmBraceNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Brace, rNodeToken, 3) { }
+
+ /**
+ * Returns the node containing the data of the opening brace.
+ * @return opening brace data
+ */
+ const SmMathSymbolNode* OpeningBrace() const { return const_cast<SmBraceNode *>
+ (this)->OpeningBrace(); }
+ SmMathSymbolNode* OpeningBrace() { assert( GetNumSubNodes() == 3 );
+ assert( GetSubNode( 0 )->GetType()
+ == SmNodeType::Math );
+ return static_cast< SmMathSymbolNode* >
+ ( GetSubNode( 0 )); }
+
+ /**
+ * Returns the node containing the data of what is between braces.
+ * @return body data
+ */
+ const SmNode* Body() const { return const_cast<SmBraceNode *>(this)->Body(); }
+ SmNode* Body() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 1 ); }
+
+ /**
+ * Returns the node containing the data of the closing brace.
+ * @return closing brace data
+ */
+ const SmMathSymbolNode* ClosingBrace() const { return const_cast<SmBraceNode *>
+ (this)->ClosingBrace(); }
+ SmMathSymbolNode* ClosingBrace() { assert( GetNumSubNodes() == 3 );
+ assert( GetSubNode( 2 )->GetType()
+ == SmNodeType::Math );
+ return static_cast< SmMathSymbolNode* >
+ ( GetSubNode( 2 )); }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Body of an SmBraceNode
+ *
+ * This usually only has one child an SmExpressionNode, however, it can also
+ * have other children.
+ * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
+ * \f$ \{\mbox{[body1] | [body2]}\} \f$.
+ * In this case SmBracebodyNode will have three children, "[body1]", "|" and
+ * [body2].
+ */
+class SmBracebodyNode final : public SmStructureNode
+{
+ tools::Long mnBodyHeight;
+
+public:
+ explicit SmBracebodyNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Bracebody, rNodeToken)
+ , mnBodyHeight(0) { }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+ tools::Long GetBodyHeight() const { return mnBodyHeight; }
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Node for vertical brace construction
+ *
+ * Used to implement commands "[body] underbrace [script]" and
+ * "[body] overbrace [script]".
+ * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
+ *
+ * Children:<BR>
+ * 0: body<BR>
+ * 1: brace<BR>
+ * 2: script<BR>
+ * (None of these children are optional, e.g. they must all be not NULL).
+ */
+class SmVerticalBraceNode final : public SmStructureNode
+{
+public:
+ explicit SmVerticalBraceNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::VerticalBrace, rNodeToken, 3) { }
+
+ /**
+ * Returns the node containing the data of what the brace is pointing for.
+ * body { script }
+ * @return body data
+ */
+ const SmNode* Body() const { return const_cast<SmVerticalBraceNode *>(this)->Body(); }
+ SmNode* Body() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 0 ); }
+
+ /**
+ * Returns the node containing the data of the brace.
+ * @return brace data
+ */
+ const SmMathSymbolNode* Brace() const { return const_cast<SmVerticalBraceNode *>
+ (this)->Brace(); }
+ SmMathSymbolNode* Brace() { assert( GetNumSubNodes() == 3 );
+ assert( GetSubNode( 1 )->GetType()
+ == SmNodeType::Math );
+ return static_cast< SmMathSymbolNode* >
+ ( GetSubNode( 1 )); }
+
+ /**
+ * Returns the node containing the data of what is in the brace.
+ * body { script }
+ * @return opening brace data
+ */
+ const SmNode* Script() const { return const_cast<SmVerticalBraceNode *>(this)->Script(); }
+ SmNode* Script() { assert( GetNumSubNodes() == 3 ); return GetSubNode( 2 ); }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+/** Operation Node
+ *
+ * Used for commands like SUM, INT and similar.
+ *
+ * Children:<BR>
+ * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
+ * 1: Body<BR>
+ * None of the children may be NULL.
+ *
+ */
+class SmOperNode final : public SmStructureNode
+{
+public:
+ explicit SmOperNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Oper, rNodeToken, 2) { }
+
+ /**
+ * Returns the node with the operator data
+ * @return operator data
+ */
+ const SmNode * GetSymbol() const { return const_cast<SmOperNode *>(this)->GetSymbol(); }
+ SmNode * GetSymbol();
+
+ /**
+ * Returns the height of the node in base to the symbol
+ * ( rSymbol contains the operator data )
+ * and the font format ( rFormat ).
+ * @param rSymbol
+ * @param rFormat
+ * @return node's height
+ */
+ tools::Long CalcSymbolHeight(const SmNode &rSymbol, const SmFormat &rFormat) const;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Node used for alignment
+ *
+ * This node has exactly one child at index 0.
+ */
+class SmAlignNode final : public SmStructureNode
+{
+public:
+ explicit SmAlignNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Align, rNodeToken) { }
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Attribute node
+ *
+ * Used to give an attribute to another node. Used for commands such as:
+ * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHARPOON, WIDEHAT and WIDETILDE.
+ *
+ * Children:<BR>
+ * 0: Attribute<BR>
+ * 1: Body<BR>
+ * None of these may be NULL.
+ */
+class SmAttributeNode final : public SmStructureNode
+{
+public:
+ explicit SmAttributeNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Attribute, rNodeToken, 2) {}
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+
+ /**
+ * Gets the attribute data.
+ * @return attribute data
+ */
+ const SmNode* Attribute() const { return const_cast<SmAttributeNode *>(this)->Attribute(); }
+ SmNode* Attribute() { assert( GetNumSubNodes() == 2 ); return GetSubNode( 0 ); }
+
+ /**
+ * Gets the body data ( the nodes affected by the attribute ).
+ * @return body data
+ */
+ const SmNode* Body() const { return const_cast<SmAttributeNode *>(this)->Body(); }
+ SmNode* Body() { assert( GetNumSubNodes() == 2 ); return GetSubNode( 1 ); }
+};
+
+
+/** Font node
+ *
+ * Used to change the font of its children.
+ */
+class SmFontNode final : public SmStructureNode
+{
+ FontSizeType meSizeType;
+ Fraction maFontSize;
+
+public:
+ explicit SmFontNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Font, rNodeToken)
+ , meSizeType(FontSizeType::MULTIPLY)
+ , maFontSize(1) { }
+
+ /**
+ * Sets font size to rValue in nType mode.
+ * Check FontSizeType for details.
+ * @param rValue
+ * @param nType
+ * @return
+ */
+ void SetSizeParameter(const Fraction &rValue, FontSizeType nType)
+ { meSizeType = nType; maFontSize = rValue; }
+
+ /**
+ * Returns the font size.
+ * @return font size.
+ */
+ const Fraction & GetSizeParameter() const {return maFontSize;}
+
+ /**
+ * Returns the font size type.
+ * Check FontSizeType for details.
+ * @return font size type.
+ */
+ FontSizeType GetSizeType() const {return meSizeType;}
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Matrix node
+ *
+ * Used to implement the MATRIX command, example:
+ * "matrix{ 1 # 2 ## 3 # 4}".
+ */
+class SmMatrixNode final : public SmStructureNode
+{
+ sal_uInt16 mnNumRows,
+ mnNumCols;
+
+public:
+ explicit SmMatrixNode(const SmToken &rNodeToken)
+ : SmStructureNode(SmNodeType::Matrix, rNodeToken)
+ , mnNumRows(0)
+ , mnNumCols(0) { }
+
+ /**
+ * Gets the number of rows of the matrix.
+ * @return rows number
+ */
+ sal_uInt16 GetNumRows() const {return mnNumRows;}
+
+ /**
+ * Gets the number of columns of the matrix.
+ * @return columns number
+ */
+ sal_uInt16 GetNumCols() const {return mnNumCols;}
+
+ /**
+ * Sets the dimensions of the matrix.
+ * @param nMatrixRows
+ * @param nMatrixCols
+ * @return
+ */
+ void SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols)
+ { mnNumRows = nMatrixRows; mnNumCols = nMatrixCols; }
+
+ virtual const SmNode * GetLeftMost() const override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+};
+
+
+/** Node for whitespace
+ *
+ * Used to implement the commands "~" and "`". This node is just a blank space.
+ */
+class SmBlankNode final : public SmGraphicNode
+{
+ sal_uInt16 mnNum;
+
+public:
+ explicit SmBlankNode(const SmToken &rNodeToken)
+ : SmGraphicNode(SmNodeType::Blank, rNodeToken)
+ , mnNum(0) { }
+
+ void IncreaseBy(const SmToken &rToken, sal_uInt32 nMultiplyBy = 1);
+ void Clear() { mnNum = 0; }
+ sal_uInt16 GetBlankNum() const { return mnNum; }
+ void SetBlankNum(sal_uInt16 nNumber) { mnNum = nNumber; }
+
+ /**
+ * Prepare preliminary settings about font and text
+ * (e.g. maFace, meRectHorAlign, mnFlags, mnAttributes, etc.)
+ * @param rFormat
+ * @param rDocShell
+ * @param nDepth
+ * @return
+ */
+ virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell,
+ int nDepth) override;
+
+ /**
+ * Prepares the SmRect to render.
+ * @param rDev
+ * @param rFormat
+ * @return
+ */
+ virtual void Arrange(OutputDevice &rDev, const SmFormat &rFormat) override;
+
+ /**
+ * Accept a visitor.
+ * Calls the method for this class on the visitor.
+ * @param pVisitor
+ * @return
+ */
+ void Accept(SmVisitor* pVisitor) override;
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/nodetype.hxx b/starmath/inc/nodetype.hxx
new file mode 100644
index 0000000000..f0bf28cece
--- /dev/null
+++ b/starmath/inc/nodetype.hxx
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/**
+ * This file provides definition for the nodetypes.
+ * Also provides analysis of the node functions
+ */
+
+enum class SmNodeType : int_fast16_t
+{
+ Table, // tree header
+ Brace, // () [] {}
+ Bracebody, // content of () [] {}
+ Oper, // largeop
+ Align, // alignment
+ Attribute, // attributes
+ Font, // fonts
+ UnHor, // unmo
+ BinHor, // binmo
+ BinVer, // over frac
+ BinDiagonal, // slash
+ SubSup, // lsub lsup rsub rsup csub csup
+ Matrix, // binom matrix
+ Place, // <?>
+ Text, // "text"
+ Special, // %glyph
+ GlyphSpecial, // %glyph
+ Math, // operator value
+ Blank, // ~
+ Error, // Syntax error
+ Line, // a line of math until newline
+ Expression, // { content in here }
+ PolyLine, // ^
+ Root, // root node
+ RootSymbol, // 3 of cubic root
+ Rectangle, //just structural
+ VerticalBrace, // vertical {}
+ MathIdent // identities and variables
+};
+
+namespace starmathdatabase
+{
+inline bool isStructuralNode(SmNodeType aNodeTypeName)
+{
+ return aNodeTypeName == SmNodeType::Table || aNodeTypeName == SmNodeType::Line
+ || aNodeTypeName == SmNodeType::UnHor || aNodeTypeName == SmNodeType::BinHor
+ || aNodeTypeName == SmNodeType::BinVer || aNodeTypeName == SmNodeType::BinDiagonal
+ || aNodeTypeName == SmNodeType::SubSup || aNodeTypeName == SmNodeType::Matrix
+ || aNodeTypeName == SmNodeType::Root || aNodeTypeName == SmNodeType::Expression
+ || aNodeTypeName == SmNodeType::Brace || aNodeTypeName == SmNodeType::Bracebody
+ || aNodeTypeName == SmNodeType::Oper || aNodeTypeName == SmNodeType::Align
+ || aNodeTypeName == SmNodeType::Attribute || aNodeTypeName == SmNodeType::Font;
+}
+
+inline bool isBinOperatorNode(SmNodeType aNodeTypeName)
+{
+ return aNodeTypeName == SmNodeType::BinHor || aNodeTypeName == SmNodeType::BinVer
+ || aNodeTypeName == SmNodeType::BinDiagonal || aNodeTypeName == SmNodeType::SubSup;
+}
+
+inline bool isUnOperatorNode(SmNodeType aNodeTypeName)
+{
+ return aNodeTypeName == SmNodeType::UnHor;
+}
+
+inline bool isOperatorNode(SmNodeType aNodeTypeName)
+{
+ return aNodeTypeName == SmNodeType::BinHor || aNodeTypeName == SmNodeType::BinVer
+ || aNodeTypeName == SmNodeType::BinDiagonal || aNodeTypeName == SmNodeType::SubSup
+ || aNodeTypeName == SmNodeType::UnHor || aNodeTypeName == SmNodeType::Oper;
+}
+
+inline bool isStandaloneNode(SmNodeType aNodeTypeName)
+{
+ return aNodeTypeName == SmNodeType::Text || aNodeTypeName == SmNodeType::Special
+ || aNodeTypeName == SmNodeType::GlyphSpecial || aNodeTypeName == SmNodeType::Math
+ || aNodeTypeName == SmNodeType::Blank || aNodeTypeName == SmNodeType::MathIdent;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/parse.hxx b/starmath/inc/parse.hxx
new file mode 100644
index 0000000000..a62d515b5f
--- /dev/null
+++ b/starmath/inc/parse.hxx
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** Parses the starmath code and creates the nodes.
+ *
+ */
+
+#pragma once
+
+#include "parsebase.hxx"
+
+namespace starmathdatabase
+{
+
+AbstractSmParser* GetDefaultSmParser();
+
+AbstractSmParser* GetVersionSmParser(sal_uInt16 nVersion);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/parse5.hxx b/starmath/inc/parse5.hxx
new file mode 100644
index 0000000000..92fc2a0291
--- /dev/null
+++ b/starmath/inc/parse5.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** Parses the starmath code and creates the nodes.
+ *
+ */
+
+#pragma once
+
+#include "parsebase.hxx"
+#include <unotools/charclass.hxx>
+
+class SmParser5 final : public AbstractSmParser
+{
+ OUString m_aBufferString;
+ SmToken m_aCurToken;
+ ESelection m_aCurESelection;
+ std::vector<SmErrorDesc> m_aErrDescList;
+ int m_nCurError;
+ sal_Int32 m_nBufferIndex, m_nTokenIndex;
+ sal_Int32 m_nRow, // 1-based
+ m_nColOff; // 0-based
+ bool m_bImportSymNames, m_bExportSymNames;
+ sal_Int32 m_nParseDepth;
+
+ // map of used symbols (used to reduce file size by exporting only actually used symbols)
+ std::set<OUString> m_aUsedSymbols;
+
+ // CharClass representing a locale for parsing numbers
+ CharClass m_aNumCC;
+ // pointer to System locale's CharClass, which is alive inside SM_MOD()
+ const CharClass* m_pSysCC;
+
+ SmParser5(const SmParser5&) = delete;
+ SmParser5& operator=(const SmParser5&) = delete;
+
+ // Moves between tokens inside starmath code.
+ void NextToken();
+ void NextTokenColor(SmTokenType dvipload);
+ void NextTokenFontSize();
+ sal_Int32 GetTokenIndex() const { return m_nTokenIndex; }
+ void Replace(sal_Int32 nPos, sal_Int32 nLen, std::u16string_view aText);
+
+ inline bool TokenInGroup(TG nGroup);
+
+ // grammar
+ std::unique_ptr<SmTableNode> DoTable();
+ std::unique_ptr<SmNode> DoLine();
+ std::unique_ptr<SmNode> DoExpression(bool bUseExtraSpaces = true);
+ std::unique_ptr<SmNode> DoRelation();
+ std::unique_ptr<SmNode> DoSum();
+ std::unique_ptr<SmNode> DoProduct();
+ std::unique_ptr<SmNode> DoSubSup(TG nActiveGroup, std::unique_ptr<SmNode> xGivenNode);
+ std::unique_ptr<SmNode> DoSubSupEvaluate(std::unique_ptr<SmNode> xGivenNode);
+ std::unique_ptr<SmNode> DoOpSubSup();
+ std::unique_ptr<SmNode> DoPower();
+ std::unique_ptr<SmBlankNode> DoBlank();
+ std::unique_ptr<SmNode> DoTerm(bool bGroupNumberIdent);
+ std::unique_ptr<SmNode> DoEscape();
+ std::unique_ptr<SmOperNode> DoOperator();
+ std::unique_ptr<SmNode> DoOper();
+ std::unique_ptr<SmStructureNode> DoUnOper();
+ std::unique_ptr<SmNode> DoAlign(bool bUseExtraSpaces = true);
+ std::unique_ptr<SmStructureNode> DoFontAttribute();
+ std::unique_ptr<SmStructureNode> DoAttribute();
+ std::unique_ptr<SmStructureNode> DoFont();
+ std::unique_ptr<SmStructureNode> DoFontSize();
+ std::unique_ptr<SmStructureNode> DoColor();
+ std::unique_ptr<SmStructureNode> DoBrace();
+ std::unique_ptr<SmBracebodyNode> DoBracebody(bool bIsLeftRight);
+ std::unique_ptr<SmNode> DoEvaluate();
+ std::unique_ptr<SmTextNode> DoFunction();
+ std::unique_ptr<SmTableNode> DoBinom();
+ std::unique_ptr<SmBinVerNode> DoFrac();
+ std::unique_ptr<SmStructureNode> DoStack();
+ std::unique_ptr<SmStructureNode> DoMatrix();
+ std::unique_ptr<SmSpecialNode> DoSpecial();
+ std::unique_ptr<SmGlyphSpecialNode> DoGlyphSpecial();
+ std::unique_ptr<SmExpressionNode> DoError(SmParseError Error);
+ // end of grammar
+
+public:
+ SmParser5();
+ virtual ~SmParser5();
+
+ /** Parse rBuffer to formula tree */
+ std::unique_ptr<SmTableNode> Parse(const OUString& rBuffer);
+ /** Parse rBuffer to formula subtree that constitutes an expression */
+ std::unique_ptr<SmNode> ParseExpression(const OUString& rBuffer);
+
+ const OUString& GetText() const { return m_aBufferString; };
+
+ bool IsImportSymbolNames() const { return m_bImportSymNames; }
+ void SetImportSymbolNames(bool bVal) { m_bImportSymNames = bVal; }
+ bool IsExportSymbolNames() const { return m_bExportSymNames; }
+ void SetExportSymbolNames(bool bVal) { m_bExportSymNames = bVal; }
+
+ const SmErrorDesc* NextError();
+ const SmErrorDesc* PrevError();
+ const SmErrorDesc* GetError() const;
+ const std::set<OUString>& GetUsedSymbols() const { return m_aUsedSymbols; }
+};
+
+inline bool SmParser5::TokenInGroup(TG nGroup) { return bool(m_aCurToken.nGroup & nGroup); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/parsebase.hxx b/starmath/inc/parsebase.hxx
new file mode 100644
index 0000000000..dd53ce631c
--- /dev/null
+++ b/starmath/inc/parsebase.hxx
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** Parses the starmath code and creates the nodes.
+ *
+ */
+
+#pragma once
+
+#include <unotools/resmgr.hxx>
+
+#include "node.hxx"
+
+#include <set>
+#include <utility>
+
+#define DEPTH_LIMIT 1024
+
+// Those are the errors that the parser may encounter.
+enum class SmParseError : uint_fast8_t
+{
+ None = 0,
+ UnexpectedChar = 1,
+ UnexpectedToken = 2,
+ PoundExpected = 3,
+ ColorExpected = 4,
+ LgroupExpected = 5,
+ RgroupExpected = 6,
+ LbraceExpected = 7,
+ RbraceExpected = 8,
+ ParentMismatch = 9,
+ RightExpected = 10,
+ FontExpected = 11,
+ SizeExpected = 12,
+ DoubleAlign = 13,
+ DoubleSubsupscript = 14,
+ NumberExpected = 15
+};
+
+struct SmErrorDesc
+{
+ SmParseError m_eType;
+ SmNode* m_pNode;
+ OUString m_aText;
+
+ SmErrorDesc(SmParseError eType, SmNode* pNode, OUString aText)
+ : m_eType(eType)
+ , m_pNode(pNode)
+ , m_aText(std::move(aText))
+ {
+ }
+};
+
+class DepthProtect
+{
+private:
+ sal_Int32& m_rParseDepth;
+
+public:
+ DepthProtect(sal_Int32& rParseDepth)
+ : m_rParseDepth(rParseDepth)
+ {
+ ++m_rParseDepth;
+ if (m_rParseDepth > DEPTH_LIMIT)
+ throw std::range_error("parser depth limit");
+ }
+ ~DepthProtect() { --m_rParseDepth; }
+};
+
+namespace starmathdatabase
+{
+// Must be in sync with SmParseError list
+extern const TranslateId SmParseErrorDesc[16];
+
+OUString getParseErrorDesc(SmParseError err);
+}
+
+class AbstractSmParser
+{
+public:
+ virtual ~AbstractSmParser() {}
+
+ /** Parse rBuffer to formula tree */
+ virtual std::unique_ptr<SmTableNode> Parse(const OUString& rBuffer) = 0;
+ /** Parse rBuffer to formula subtree that constitutes an expression */
+ virtual std::unique_ptr<SmNode> ParseExpression(const OUString& rBuffer) = 0;
+
+ virtual const OUString& GetText() const = 0;
+
+ virtual bool IsImportSymbolNames() const = 0;
+ virtual void SetImportSymbolNames(bool bVal) = 0;
+ virtual bool IsExportSymbolNames() const = 0;
+ virtual void SetExportSymbolNames(bool bVal) = 0;
+
+ virtual const SmErrorDesc* NextError() = 0;
+ virtual const SmErrorDesc* PrevError() = 0;
+ virtual const SmErrorDesc* GetError() const = 0;
+ virtual const std::set<OUString>& GetUsedSymbols() const = 0;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/pch/precompiled_sm.cxx b/starmath/inc/pch/precompiled_sm.cxx
new file mode 100644
index 0000000000..f5d78e96fb
--- /dev/null
+++ b/starmath/inc/pch/precompiled_sm.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 "precompiled_sm.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/pch/precompiled_sm.hxx b/starmath/inc/pch/precompiled_sm.hxx
new file mode 100644
index 0000000000..25a73ab315
--- /dev/null
+++ b/starmath/inc/pch/precompiled_sm.hxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2023-07-19 09:27:30 using:
+ ./bin/update_pch starmath sm --cutoff=5 --exclude:system --exclude:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./starmath/inc/pch/precompiled_sm.hxx "make starmath.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <algorithm>
+#include <assert.h>
+#include <cassert>
+#include <cmath>
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+#include <functional>
+#include <limits.h>
+#include <limits>
+#include <math.h>
+#include <memory>
+#include <new>
+#include <optional>
+#include <ostream>
+#include <span>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+#include <boost/property_tree/ptree_fwd.hpp>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <rtl/alloc.h>
+#include <rtl/character.hxx>
+#include <rtl/locale.h>
+#include <rtl/math.h>
+#include <rtl/math.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/stringconcat.hxx>
+#include <rtl/stringutils.hxx>
+#include <rtl/textenc.h>
+#include <rtl/ustrbuf.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+#include <sal/saldllapi.h>
+#include <sal/types.h>
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/cairo.hxx>
+#include <vcl/dllapi.h>
+#include <vcl/font.hxx>
+#include <vcl/gradient.hxx>
+#include <vcl/kernarray.hxx>
+#include <vcl/mapmod.hxx>
+#include <vcl/metaactiontypes.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/region.hxx>
+#include <vcl/rendercontext/AddFontSubstituteFlags.hxx>
+#include <vcl/rendercontext/AntialiasingFlags.hxx>
+#include <vcl/rendercontext/DrawGridFlags.hxx>
+#include <vcl/rendercontext/DrawImageFlags.hxx>
+#include <vcl/rendercontext/DrawModeFlags.hxx>
+#include <vcl/rendercontext/DrawTextFlags.hxx>
+#include <vcl/rendercontext/GetDefaultFontFlags.hxx>
+#include <vcl/rendercontext/ImplMapRes.hxx>
+#include <vcl/rendercontext/InvertFlags.hxx>
+#include <vcl/rendercontext/RasterOp.hxx>
+#include <vcl/rendercontext/SalLayoutFlags.hxx>
+#include <vcl/rendercontext/State.hxx>
+#include <vcl/rendercontext/SystemTextColorFlags.hxx>
+#include <vcl/salnativewidgets.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/vclenum.hxx>
+#include <vcl/vclptr.hxx>
+#include <vcl/vclreferencebase.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/wall.hxx>
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <basegfx/basegfxdllapi.h>
+#include <basegfx/numeric/ftools.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <basegfx/vector/b2enums.hxx>
+#include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
+#include <com/sun/star/awt/DeviceInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <comphelper/comphelperdllapi.h>
+#include <comphelper/diagnose_ex.hxx>
+#include <comphelper/errcode.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/propertysetinfo.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <cppu/unotype.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <editeng/editengdllapi.h>
+#include <i18nlangtag/lang.h>
+#include <o3tl/cow_wrapper.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <o3tl/strong_int.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <o3tl/unit_conversion.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/dllapi.h>
+#include <sfx2/docfile.hxx>
+#include <sfx2/shell.hxx>
+#include <sot/storage.hxx>
+#include <svl/hint.hxx>
+#include <svl/itemset.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/lstner.hxx>
+#include <svl/poolitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/svldllapi.h>
+#include <svl/typedwhich.hxx>
+#include <svx/svxdllapi.h>
+#include <tools/color.hxx>
+#include <tools/degree.hxx>
+#include <tools/fldunit.hxx>
+#include <tools/gen.hxx>
+#include <tools/lineend.hxx>
+#include <tools/link.hxx>
+#include <tools/long.hxx>
+#include <tools/mapunit.hxx>
+#include <tools/poly.hxx>
+#include <tools/ref.hxx>
+#include <tools/solar.h>
+#include <tools/toolsdllapi.h>
+#include <typelib/typedescription.h>
+#include <uno/data.h>
+#include <unotools/fontdefs.hxx>
+#include <unotools/resmgr.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/unotoolsdllapi.h>
+#include <xmloff/dllapi.h>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#include <cfgitem.hxx>
+#include <dialog.hxx>
+#include <document.hxx>
+#include <node.hxx>
+#include <smmod.hxx>
+#include <starmathdatabase.hxx>
+#include <symbol.hxx>
+#include <unomodel.hxx>
+#include <utility.hxx>
+#include <view.hxx>
+#include <visitors.hxx>
+#include <xparsmlbase.hxx>
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/rect.hxx b/starmath/inc/rect.hxx
new file mode 100644
index 0000000000..0b28581a00
--- /dev/null
+++ b/starmath/inc/rect.hxx
@@ -0,0 +1,216 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+#include <tools/gen.hxx>
+#include <vcl/outdev.hxx>
+
+class SmFormat;
+
+
+inline tools::Long SmFromTo(tools::Long nFrom, tools::Long nTo, double fRelDist)
+{
+ return nFrom + static_cast<tools::Long>(fRelDist * (nTo - nFrom));
+}
+
+
+// SmRect
+// ... (to be done)
+// This Implementation assumes that the x-axis points to the right and the
+// y-axis to the bottom.
+// Note: however, italic spaces can be negative!
+
+
+// possible positions and alignments for the 'AlignTo' function
+enum class RectPos
+{
+ Left, // align the current object to the left of the argument
+ Right,
+ Top,
+ Bottom,
+ Attribute
+};
+
+enum class RectHorAlign
+{
+ Left,
+ Center,
+ Right
+};
+
+enum class RectVerAlign
+{
+ Top,
+ Mid,
+ Bottom,
+ Baseline,
+ CenterY,
+ AttributeHi,
+ AttributeMid,
+ AttributeLo
+};
+
+// different methods of copying baselines and mid's in 'ExtendBy' function
+enum class RectCopyMBL
+{
+ This, // keep baseline of current object even if it has none
+ Arg, // as above but for the argument
+ None, // result will have no baseline
+ Xor // if current object has a baseline keep it else copy
+ // the arguments baseline (even if it has none)
+};
+
+
+class SmRect
+{
+ Point aTopLeft;
+ Size aSize;
+ tools::Long nBaseline,
+ nAlignT,
+ nAlignM,
+ nAlignB,
+ nGlyphTop,
+ nGlyphBottom,
+ nItalicLeftSpace,
+ nItalicRightSpace,
+ nLoAttrFence,
+ nHiAttrFence;
+ sal_uInt16 nBorderWidth;
+ bool bHasBaseline,
+ bHasAlignInfo;
+
+ inline void CopyMBL(const SmRect& rRect);
+ void CopyAlignInfo(const SmRect& rRect);
+
+ void Union(const SmRect &rRect);
+
+public:
+ SmRect();
+ SmRect(const OutputDevice &rDev, const SmFormat *pFormat,
+ const OUString &rText, sal_uInt16 nBorderWidth);
+ SmRect(tools::Long nWidth, tools::Long nHeight);
+
+
+ sal_uInt16 GetBorderWidth() const { return nBorderWidth; }
+
+ void SetItalicSpaces(tools::Long nLeftSpace, tools::Long nRightSpace);
+
+ void SetWidth(sal_uLong nWidth) { aSize.setWidth(nWidth); }
+
+ void SetLeft(tools::Long nLeft);
+ void SetRight(tools::Long nRight);
+ void SetBottom(tools::Long nBottom);
+ void SetTop(tools::Long nTop);
+
+ const Point & GetTopLeft() const { return aTopLeft; }
+
+ tools::Long GetTop() const { return GetTopLeft().Y(); }
+ tools::Long GetLeft() const { return GetTopLeft().X(); }
+ tools::Long GetBottom() const { return GetTop() + GetHeight() - 1; }
+ tools::Long GetRight() const { return GetLeft() + GetWidth() - 1; }
+ tools::Long GetCenterY() const { return (GetTop() + GetBottom()) / 2; }
+ tools::Long GetWidth() const { return GetSize().Width(); }
+ tools::Long GetHeight() const { return GetSize().Height(); }
+
+ tools::Long GetItalicLeftSpace() const { return nItalicLeftSpace; }
+ tools::Long GetItalicRightSpace() const { return nItalicRightSpace; }
+
+ tools::Long GetHiAttrFence() const { return nHiAttrFence; }
+ tools::Long GetLoAttrFence() const { return nLoAttrFence; }
+
+ tools::Long GetItalicLeft() const { return GetLeft() - GetItalicLeftSpace(); }
+ tools::Long GetItalicCenterX() const { return (GetItalicLeft() + GetItalicRight()) / 2; }
+ tools::Long GetItalicRight() const { return GetRight() + GetItalicRightSpace(); }
+ tools::Long GetItalicWidth() const { return GetWidth() + GetItalicLeftSpace() + GetItalicRightSpace(); }
+
+ bool HasBaseline() const { return bHasBaseline; }
+ inline tools::Long GetBaseline() const;
+ tools::Long GetBaselineOffset() const { return GetBaseline() - GetTop(); }
+
+ tools::Long GetAlignT() const { return nAlignT; }
+ tools::Long GetAlignM() const { return nAlignM; }
+ tools::Long GetAlignB() const { return nAlignB; }
+
+ const Size & GetSize() const { return aSize; }
+
+ Size GetItalicSize() const
+ { return Size(GetItalicWidth(), GetHeight()); }
+
+ void Move (const Point &rPosition);
+ void MoveTo(const Point &rPosition) { Move(rPosition - GetTopLeft()); }
+
+ bool IsEmpty() const
+ {
+ return GetWidth() == 0 || GetHeight() == 0;
+ }
+
+ bool HasAlignInfo() const { return bHasAlignInfo; }
+
+ Point AlignTo(const SmRect &rRect, RectPos ePos,
+ RectHorAlign eHor, RectVerAlign eVer) const;
+
+ SmRect & ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode);
+ void ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode,
+ tools::Long nNewAlignM);
+ SmRect & ExtendBy(const SmRect &rRect, RectCopyMBL eCopyMode,
+ bool bKeepVerAlignParams);
+
+ tools::Long OrientedDist(const Point &rPoint) const;
+ bool IsInsideRect(const Point &rPoint) const;
+ bool IsInsideItalicRect(const Point &rPoint) const;
+
+ inline tools::Rectangle AsRectangle() const;
+ SmRect AsGlyphRect() const;
+};
+
+
+inline void SmRect::SetItalicSpaces(tools::Long nLeftSpace, tools::Long nRightSpace)
+ // set extra spacing to the left and right for (italic)
+ // letters/text
+{
+ nItalicLeftSpace = nLeftSpace;
+ nItalicRightSpace = nRightSpace;
+}
+
+
+inline void SmRect::CopyMBL(const SmRect &rRect)
+ // copy AlignM baseline and value of 'rRect'
+{
+ nBaseline = rRect.nBaseline;
+ bHasBaseline = rRect.bHasBaseline;
+ nAlignM = rRect.nAlignM;
+}
+
+
+inline tools::Long SmRect::GetBaseline() const
+{
+ SAL_WARN_IF( !HasBaseline(), "starmath", "Baseline does not exist" );
+ return nBaseline;
+}
+
+
+inline tools::Rectangle SmRect::AsRectangle() const
+{
+ return tools::Rectangle(Point(GetItalicLeft(), GetTop()), GetItalicSize());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/smdll.hxx b/starmath/inc/smdll.hxx
new file mode 100644
index 0000000000..1a1e175c88
--- /dev/null
+++ b/starmath/inc/smdll.hxx
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include "smdllapi.hxx"
+
+namespace SmGlobals
+{
+SM_DLLPUBLIC void ensure();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/smdllapi.hxx b/starmath/inc/smdllapi.hxx
new file mode 100644
index 0000000000..6354936194
--- /dev/null
+++ b/starmath/inc/smdllapi.hxx
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 <sal/types.h>
+
+#if defined(SM_DLLIMPLEMENTATION)
+#define SM_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define SM_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/smediteng.hxx b/starmath/inc/smediteng.hxx
new file mode 100644
index 0000000000..6c95b58044
--- /dev/null
+++ b/starmath/inc/smediteng.hxx
@@ -0,0 +1,59 @@
+/* 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 <editeng/editeng.hxx>
+#include <unotools/lingucfg.hxx>
+
+class SmEditEngine final : public EditEngine
+{
+public:
+ SmEditEngine(SfxItemPool* pItemPool);
+ SmEditEngine(const SmEditEngine&) = delete;
+
+public:
+ /**
+ * Runs checkZoom and if true runs updateZoom
+ */
+ void executeZoom(EditView* pEditView = nullptr);
+
+ /**
+ * Sets up default font parameters for the item pool.
+ */
+ static void setSmItemPool(SfxItemPool* mpItemPool, const SvtLinguOptions& maLangOptions);
+
+ // Deal with text scaling
+private:
+ sal_Int32 m_nOldZoom;
+ sal_Int32 m_nNewZoom;
+ sal_Int32 m_nDefaultFontSize;
+
+ /**
+ * Checks if the zoom of smeditwindow has changed.
+ * m_nNewZoom is updated.
+ * @return zoom has changed
+ */
+ bool checkZoom();
+
+ /**
+ * Updates the zoom of smeditwindow.
+ * m_nOldZoom is set to m_nNewZoom.
+ */
+
+ void updateZoom();
+
+ // Gather information for more complex tasks
+private:
+ ESelection m_aAllSelection;
+
+ /**
+ * Finds the ESelection which contains all the text.
+ */
+ void updateAllESelection();
+};
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/smmod.hrc b/starmath/inc/smmod.hrc
new file mode 100644
index 0000000000..effdcdcba3
--- /dev/null
+++ b/starmath/inc/smmod.hrc
@@ -0,0 +1,92 @@
+/* -*- 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 <unotools/resmgr.hxx>
+
+#define NC_(Context, String) TranslateId(Context, u8##String)
+
+const TranslateId RID_UI_SYMBOLSET_NAMES[] =
+{
+ NC_("RID_UI_SYMBOLSET_NAMES", "Greek"),
+ NC_("RID_UI_SYMBOLSET_NAMES", "Special")
+};
+
+const TranslateId RID_UI_SYMBOL_NAMES[] =
+{
+ NC_("RID_UI_SYMBOL_NAMES", "alpha"),
+ NC_("RID_UI_SYMBOL_NAMES", "ALPHA"),
+ NC_("RID_UI_SYMBOL_NAMES", "beta"),
+ NC_("RID_UI_SYMBOL_NAMES", "BETA"),
+ NC_("RID_UI_SYMBOL_NAMES", "gamma"),
+ NC_("RID_UI_SYMBOL_NAMES", "GAMMA"),
+ NC_("RID_UI_SYMBOL_NAMES", "delta"),
+ NC_("RID_UI_SYMBOL_NAMES", "DELTA"),
+ NC_("RID_UI_SYMBOL_NAMES", "epsilon"),
+ NC_("RID_UI_SYMBOL_NAMES", "EPSILON"),
+ NC_("RID_UI_SYMBOL_NAMES", "zeta"),
+ NC_("RID_UI_SYMBOL_NAMES", "ZETA"),
+ NC_("RID_UI_SYMBOL_NAMES", "eta"),
+ NC_("RID_UI_SYMBOL_NAMES", "ETA"),
+ NC_("RID_UI_SYMBOL_NAMES", "theta"),
+ NC_("RID_UI_SYMBOL_NAMES", "THETA"),
+ NC_("RID_UI_SYMBOL_NAMES", "iota"),
+ NC_("RID_UI_SYMBOL_NAMES", "IOTA"),
+ NC_("RID_UI_SYMBOL_NAMES", "kappa"),
+ NC_("RID_UI_SYMBOL_NAMES", "KAPPA"),
+ NC_("RID_UI_SYMBOL_NAMES", "lambda"),
+ NC_("RID_UI_SYMBOL_NAMES", "LAMBDA"),
+ NC_("RID_UI_SYMBOL_NAMES", "mu"),
+ NC_("RID_UI_SYMBOL_NAMES", "MU"),
+ NC_("RID_UI_SYMBOL_NAMES", "nu"),
+ NC_("RID_UI_SYMBOL_NAMES", "NU"),
+ NC_("RID_UI_SYMBOL_NAMES", "xi"),
+ NC_("RID_UI_SYMBOL_NAMES", "XI"),
+ NC_("RID_UI_SYMBOL_NAMES", "omicron"),
+ NC_("RID_UI_SYMBOL_NAMES", "OMICRON"),
+ NC_("RID_UI_SYMBOL_NAMES", "pi"),
+ NC_("RID_UI_SYMBOL_NAMES", "PI"),
+ NC_("RID_UI_SYMBOL_NAMES", "rho"),
+ NC_("RID_UI_SYMBOL_NAMES", "RHO"),
+ NC_("RID_UI_SYMBOL_NAMES", "sigma"),
+ NC_("RID_UI_SYMBOL_NAMES", "SIGMA"),
+ NC_("RID_UI_SYMBOL_NAMES", "tau"),
+ NC_("RID_UI_SYMBOL_NAMES", "TAU"),
+ NC_("RID_UI_SYMBOL_NAMES", "upsilon"),
+ NC_("RID_UI_SYMBOL_NAMES", "UPSILON"),
+ NC_("RID_UI_SYMBOL_NAMES", "phi"),
+ NC_("RID_UI_SYMBOL_NAMES", "PHI"),
+ NC_("RID_UI_SYMBOL_NAMES", "chi"),
+ NC_("RID_UI_SYMBOL_NAMES", "CHI"),
+ NC_("RID_UI_SYMBOL_NAMES", "psi"),
+ NC_("RID_UI_SYMBOL_NAMES", "PSI"),
+ NC_("RID_UI_SYMBOL_NAMES", "omega"),
+ NC_("RID_UI_SYMBOL_NAMES", "OMEGA"),
+ NC_("RID_UI_SYMBOL_NAMES", "varepsilon"),
+ NC_("RID_UI_SYMBOL_NAMES", "vartheta"),
+ NC_("RID_UI_SYMBOL_NAMES", "varpi"),
+ NC_("RID_UI_SYMBOL_NAMES", "varrho"),
+ NC_("RID_UI_SYMBOL_NAMES", "varsigma"),
+ NC_("RID_UI_SYMBOL_NAMES", "varphi"),
+ NC_("RID_UI_SYMBOL_NAMES", "element"),
+ NC_("RID_UI_SYMBOL_NAMES", "noelement"),
+ NC_("RID_UI_SYMBOL_NAMES", "strictlylessthan"),
+ NC_("RID_UI_SYMBOL_NAMES", "strictlygreaterthan"),
+ NC_("RID_UI_SYMBOL_NAMES", "notequal"),
+ NC_("RID_UI_SYMBOL_NAMES", "identical"),
+ NC_("RID_UI_SYMBOL_NAMES", "tendto"),
+ NC_("RID_UI_SYMBOL_NAMES", "infinite"),
+ NC_("RID_UI_SYMBOL_NAMES", "angle"),
+ NC_("RID_UI_SYMBOL_NAMES", "perthousand"),
+ NC_("RID_UI_SYMBOL_NAMES", "and"),
+ NC_("RID_UI_SYMBOL_NAMES", "or")
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/smmod.hxx b/starmath/inc/smmod.hxx
new file mode 100644
index 0000000000..54f339b550
--- /dev/null
+++ b/starmath/inc/smmod.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/module.hxx>
+#include <sfx2/app.hxx>
+#include <vcl/vclptr.hxx>
+#include <unotools/options.hxx>
+#include <optional>
+
+namespace svtools { class ColorConfig; }
+
+class SfxObjectFactory;
+class SmSymbolManager;
+class SmMathConfig;
+
+/*************************************************************************
+|*
+|* This subclass of <SfxModule> (which is a subclass of <SfxShell>) is
+|* linked to the DLL. One instance of this class exists while the DLL is
+|* loaded.
+|*
+|* SdModule is like to be compared with the <SfxApplication>-subclass.
+|*
+|* Remember: Don`t export this class! It uses DLL-internal symbols.
+|*
+\************************************************************************/
+
+class SvtSysLocale;
+class VirtualDevice;
+
+
+OUString SmResId(TranslateId aId);
+
+namespace SmLocalizedSymbolData
+{
+ OUString GetUiSymbolName( std::u16string_view rExportName );
+ OUString GetExportSymbolName( std::u16string_view rUiName );
+
+ OUString GetUiSymbolSetName( std::u16string_view rExportName );
+ OUString GetExportSymbolSetName( std::u16string_view rUiName );
+};
+
+class SmModule final : public SfxModule, public utl::ConfigurationListener
+{
+ std::unique_ptr<svtools::ColorConfig> mpColorConfig;
+ std::unique_ptr<SmMathConfig> mpConfig;
+ std::optional<SvtSysLocale> moSysLocale;
+ VclPtr<VirtualDevice> mpVirtualDev;
+
+public:
+ SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START + SfxInterfaceId(0))
+
+private:
+ /// SfxInterface initializer.
+ static void InitInterface_Impl();
+
+public:
+ explicit SmModule(SfxObjectFactory* pObjFact);
+ virtual ~SmModule() override;
+
+ virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, ConfigurationHints ) override;
+
+ svtools::ColorConfig & GetColorConfig();
+
+ SmMathConfig * GetConfig();
+ SmSymbolManager & GetSymbolManager();
+
+ static void GetState(SfxItemSet&);
+
+ const SvtSysLocale& GetSysLocale();
+
+ VirtualDevice & GetDefaultVirtualDev();
+
+ //virtual methods for options dialog
+ virtual std::optional<SfxItemSet> CreateItemSet( sal_uInt16 nId ) override;
+ virtual void ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet ) override;
+ virtual std::unique_ptr<SfxTabPage> CreateTabPage( sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet ) override;
+};
+
+#define SM_MOD() ( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule::Math)) )
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/starmath.hrc b/starmath/inc/starmath.hrc
new file mode 100644
index 0000000000..1127e6660c
--- /dev/null
+++ b/starmath/inc/starmath.hrc
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <svl/solar.hrc>
+
+class SfxBoolItem;
+class SfxInt16Item;
+class SfxUInt16Item;
+
+#define SID_NEXTERR (SID_SMA_START + 1)
+#define SID_PREVERR (SID_SMA_START + 2)
+#define SID_NEXTMARK (SID_SMA_START + 3)
+#define SID_PREVMARK (SID_SMA_START + 4)
+#define SID_SYMBOLS_CATALOGUE (SID_SMA_START + 5)
+#define SID_ZOOMIN (SID_SMA_START + 10)
+#define SID_ZOOMOUT (SID_SMA_START + 11)
+#define SID_DRAW (SID_SMA_START + 12)
+#define SID_FORMULACURSOR (SID_SMA_START + 15)
+#define SID_FONT (SID_SMA_START + 50)
+#define SID_FONTSIZE (SID_SMA_START + 51)
+#define SID_DISTANCE (SID_SMA_START + 52)
+#define SID_ALIGN (SID_SMA_START + 53)
+
+#define SID_AUTO_REDRAW (SID_SMA_START + 55)
+#define SID_TEXTMODE (SID_SMA_START + 57)
+#define SID_IMPORT_FORMULA (SID_SMA_START + 58)
+#define SID_IMPORT_MATHML_CLIPBOARD (SID_SMA_START + 59)
+#define SID_TEXT TypedWhichId<SfxStringItem>(SID_SMA_START + 100)
+#define SID_GRAPHIC_SM TypedWhichId<SfxInt16Item>(SID_SMA_START + 101)
+/** Command for inserting a symbol specified by a string (Inserts an SmSpecialNode) */
+#define SID_INSERTSPECIAL TypedWhichId<SfxStringItem>(SID_SMA_START + 104)
+/** Command for inserting a math construction */
+#define SID_INSERTCOMMANDTEXT TypedWhichId<SfxStringItem>(SID_SMA_START + 106)
+
+#define SID_LOADSYMBOLS (SID_SMA_START + 107)
+#define SID_SAVESYMBOLS (SID_SMA_START + 108)
+#define SID_MODIFYSTATUS TypedWhichId<SfxStringItem>(SID_SMA_START + 110)
+#define SID_TEXTSTATUS TypedWhichId<SfxStringItem>(SID_SMA_START + 111)
+
+#define SID_PRINTTITLE TypedWhichId<SfxBoolItem>(SID_SMA_START + 112)
+#define SID_PRINTTEXT TypedWhichId<SfxBoolItem>(SID_SMA_START + 113)
+#define SID_PRINTFRAME TypedWhichId<SfxBoolItem>(SID_SMA_START + 114)
+#define SID_PRINTSIZE TypedWhichId<SfxUInt16Item>(SID_SMA_START + 115)
+#define SID_PRINTZOOM TypedWhichId<SfxUInt16Item>(SID_SMA_START + 116)
+
+#define SID_COPYOBJECT (SID_SMA_START + 117)
+#define SID_PASTEOBJECT (SID_SMA_START + 118)
+#define SID_AUTOREDRAW TypedWhichId<SfxBoolItem>(SID_SMA_START + 119)
+
+#define SID_GETEDITTEXT (SID_SMA_START + 121)
+#define SID_CMDBOXWINDOW (SID_SMA_START + 122)
+#define SID_NO_RIGHT_SPACES TypedWhichId<SfxBoolItem>(SID_SMA_START + 124)
+#define SID_SAVE_ONLY_USED_SYMBOLS TypedWhichId<SfxBoolItem>(SID_SMA_START + 125)
+#define SID_ELEMENTSDOCKINGWINDOW (SID_SMA_START + 126)
+#define SID_AUTO_CLOSE_BRACKETS TypedWhichId<SfxBoolItem>(SID_SMA_START + 127)
+#define SID_SMEDITWINDOWZOOM TypedWhichId<SfxUInt16Item>(SID_SMA_START + 129)
+#define SID_DEFAULT_SM_SYNTAX_VERSION TypedWhichId<SfxUInt16Item>(SID_SMA_START + 130)
+#define SID_INLINE_EDIT_ENABLE TypedWhichId<SfxBoolItem>(SID_SMA_START + 131)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/strings.hrc b/starmath/inc/strings.hrc
new file mode 100644
index 0000000000..4afb0d2598
--- /dev/null
+++ b/starmath/inc/strings.hrc
@@ -0,0 +1,411 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** Those are the starmath codes descriptions for ElementsDockingWindow.hxx.
+ *
+ * Those codes will be displayed as formulas on the ElementsDockingWindow.
+ * The user can then graphically insert them.
+ * When passing the mouse over them, those descriptions will be displayed.
+ */
+
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, u8##String)
+
+// clang-format off
+#define RID_PLUSX_HELP NC_("RID_PLUSX_HELP", "+ Sign" )
+#define RID_MINUSX_HELP NC_("RID_MINUSX_HELP", "- Sign" )
+#define RID_PLUSMINUSX_HELP NC_("RID_PLUSMINUSX_HELP", "+- Sign" )
+#define RID_MINUSPLUSX_HELP NC_("RID_MINUSPLUSX_HELP", "-+ Sign" )
+#define RID_NEGX_HELP NC_("RID_NEGX_HELP", "Boolean NOT" )
+#define RID_XPLUSY_HELP NC_("RID_XPLUSY_HELP", "Addition +" )
+#define RID_XMINUSY_HELP NC_("RID_XMINUSY_HELP", "Subtraction -" )
+#define RID_XCDOTY_HELP NC_("RID_XCDOTY_HELP", "Multiplication (Dot)" )
+#define RID_XTIMESY_HELP NC_("RID_XTIMESY_HELP", "Multiplication (x)" )
+#define RID_XSYMTIMESY_HELP NC_("RID_XSYMTIMESY_HELP", "Multiplication (*)" )
+#define RID_XSYMDIVIDEY_HELP NC_("RID_XSYMDIVIDEY_HELP", "Division (Slash)" )
+#define RID_XDIVY_HELP NC_("RID_XDIVY_HELP", "Division (÷)" )
+#define RID_XOVERY_HELP NC_("RID_XOVERY_HELP", "Division (Fraction)" )
+#define RID_FRACXY_HELP NC_("RID_FRACXY_HELP", "Fraction" )
+#define RID_XODIVIDEY_HELP NC_("RID_XODIVIDEY_HELP", "Circled Slash" )
+#define RID_XODOTY_HELP NC_("RID_XODOTY_HELP", "Circled Dot" )
+#define RID_XOMINUSY_HELP NC_("RID_XOMINUSY_HELP", "Circled Minus" )
+#define RID_XOPLUSY_HELP NC_("RID_XOPLUSY_HELP", "Circled Plus" )
+#define RID_XOTIMESY_HELP NC_("RID_XOTIMESY_HELP", "Tensor Product" )
+#define RID_XANDY_HELP NC_("RID_XANDY_HELP", "Boolean AND" )
+#define RID_XORY_HELP NC_("RID_XORY_HELP", "Boolean OR" )
+#define RID_XEQY_HELP NC_("RID_XEQY_HELP", "Is Equal" )
+#define RID_XNEQY_HELP NC_("RID_XNEQY_HELP", "Is Not Equal" )
+#define RID_XLTY_HELP NC_("RID_XLTY_HELP", "Is Less Than" )
+#define RID_XGTY_HELP NC_("RID_XGTY_HELP", "Is Greater Than" )
+#define RID_XLEY_HELP NC_("RID_XLEY_HELP", "Is Less Than Or Equal To" )
+#define RID_XGEY_HELP NC_("RID_XGEY_HELP", "Is Greater Than Or Equal To" )
+#define RID_XLESLANTY_HELP NC_("RID_XLESLANTY_HELP", "Is Less Than Or Equal To" )
+#define RID_XGESLANTY_HELP NC_("RID_XGESLANTY_HELP", "Is Greater Than Or Equal To" )
+#define RID_XLLY_HELP NC_("RID_XLLY_HELP", "Is Much Less Than" )
+#define RID_XGGY_HELP NC_("RID_XGGY_HELP", "Is Much Greater Than" )
+#define RID_XDEFY_HELP NC_("RID_XDEFY_HELP", "Is Defined As" )
+#define RID_XEQUIVY_HELP NC_("RID_XEQUIVY_HELP", "Is Congruent To" )
+#define RID_XAPPROXY_HELP NC_("RID_XAPPROXY_HELP", "Is Approximately Equal" )
+#define RID_XSIMY_HELP NC_("RID_XSIMY_HELP", "Is Similar To" )
+#define RID_XSIMEQY_HELP NC_("RID_XSIMEQY_HELP", "Is Similar Or Equal" )
+#define RID_XPROPY_HELP NC_("RID_XPROPY_HELP", "Is Proportional To" )
+#define RID_XORTHOY_HELP NC_("RID_XORTHOY_HELP", "Is Orthogonal To" )
+#define RID_XPARALLELY_HELP NC_("RID_XPARALLELY_HELP", "Is Parallel To" )
+#define RID_XTOWARDY_HELP NC_("RID_XTOWARDY_HELP", "Toward" )
+#define RID_XTRANSLY_HELP NC_("RID_XTRANSLY_HELP", "Corresponds To (Left)" )
+#define RID_XTRANSRY_HELP NC_("RID_XTRANSRY_HELP", "Corresponds To (Right)" )
+#define RID_XINY_HELP NC_("RID_XINY_HELP", "Is In" )
+#define RID_XNOTINY_HELP NC_("RID_XNOTINY_HELP", "Is Not In" )
+#define RID_XOWNSY_HELP NC_("RID_XOWNSY_HELP", "Owns" )
+#define RID_XUNIONY_HELP NC_("RID_XUNIONY_HELP", "Union" )
+#define RID_XINTERSECTIONY_HELP NC_("RID_XINTERSECTIONY_HELP", "Intersection" )
+#define RID_XSETMINUSY_HELP NC_("RID_XSETMINUSY_HELP", "Difference" )
+#define RID_XSETQUOTIENTY_HELP NC_("RID_XSETQUOTIENTY_HELP", "Quotient Set" )
+#define RID_XSUBSETY_HELP NC_("RID_XSUBSETY_HELP", "Subset" )
+#define RID_XSUBSETEQY_HELP NC_("RID_XSUBSETEQY_HELP", "Subset Or Equal To" )
+#define RID_XSUPSETY_HELP NC_("RID_XSUPSETY_HELP", "Superset" )
+#define RID_XSUPSETEQY_HELP NC_("RID_XSUPSETEQY_HELP", "Superset Or Equal To" )
+#define RID_XNSUBSETY_HELP NC_("RID_XNSUBSETY_HELP", "Not Subset" )
+#define RID_XNSUBSETEQY_HELP NC_("RID_XNSUBSETEQY_HELP", "Not Subset Or Equal" )
+#define RID_XNSUPSETY_HELP NC_("RID_XNSUPSETY_HELP", "Not Superset" )
+#define RID_XNSUPSETEQY_HELP NC_("RID_XNSUPSETEQY_HELP", "Not Superset Or Equal" )
+#define RID_FUNCX_HELP NC_("RID_FUNCX_HELP", "General function" )
+#define RID_ABSX_HELP NC_("RID_ABSX_HELP", "Absolute Value" )
+#define RID_FACTX_HELP NC_("RID_FACTX_HELP", "Factorial" )
+#define RID_SQRTX_HELP NC_("RID_SQRTX_HELP", "Square Root" )
+#define RID_NROOTXY_HELP NC_("RID_NROOTXY_HELP", "N-th Root" )
+#define RID_EX_HELP NC_("RID_EX_HELP", "Exponential Function" )
+#define RID_EXPX_HELP NC_("RID_EXPX_HELP", "Exponential Function" )
+#define RID_LNX_HELP NC_("RID_LNX_HELP", "Natural Logarithm" )
+#define RID_LOGX_HELP NC_("RID_LOGX_HELP", "Logarithm" )
+#define RID_SINX_HELP NC_("RID_SINX_HELP", "Sine" )
+#define RID_COSX_HELP NC_("RID_COSX_HELP", "Cosine" )
+#define RID_TANX_HELP NC_("RID_TANX_HELP", "Tangent" )
+#define RID_COTX_HELP NC_("RID_COTX_HELP", "Cotangent" )
+#define RID_ARCSINX_HELP NC_("RID_ARCSINX_HELP", "Arcsine" )
+#define RID_ARCCOSX_HELP NC_("RID_ARCCOSX_HELP", "Arccosine" )
+#define RID_ARCTANX_HELP NC_("RID_ARCTANX_HELP", "Arctangent" )
+#define RID_ARCCOTX_HELP NC_("RID_ARCCOTX_HELP", "Arccotangent" )
+#define RID_SINHX_HELP NC_("RID_SINHX_HELP", "Hyperbolic Sine" )
+#define RID_COSHX_HELP NC_("RID_COSHX_HELP", "Hyperbolic Cosine" )
+#define RID_TANHX_HELP NC_("RID_TANHX_HELP", "Hyperbolic Tangent" )
+#define RID_COTHX_HELP NC_("RID_COTHX_HELP", "Hyperbolic Cotangent" )
+#define RID_ARSINHX_HELP NC_("RID_ARSINHX_HELP", "Area Hyperbolic Sine" )
+#define RID_ARCOSHX_HELP NC_("RID_ARCOSHX_HELP", "Area Hyperbolic Cosine" )
+#define RID_ARTANHX_HELP NC_("RID_ARTANHX_HELP", "Area Hyperbolic Tangent" )
+#define RID_ARCOTHX_HELP NC_("RID_ARCOTHX_HELP", "Area Hyperbolic Cotangent" )
+#define RID_OPERX_HELP NC_("RID_OPERX_HELP", "General operator" )
+#define RID_OPER_FROMX_HELP NC_("RID_OPER_FROMX_HELP", "General operator Subscript Bottom" )
+#define RID_OPER_TOX_HELP NC_("RID_OPER_TOX_HELP", "General operator Superscript Top" )
+#define RID_OPER_FROMTOX_HELP NC_("RID_OPER_FROMTOX_HELP", "General operator Sup/Sub script" )
+#define RID_SUMX_HELP NC_("RID_SUMX_HELP", "Sum" )
+#define RID_SUM_FROMX_HELP NC_("RID_SUM_FROMX_HELP", "Sum Subscript Bottom" )
+#define RID_SUM_TOX_HELP NC_("RID_SUM_TOX_HELP", "Sum Superscript Top" )
+#define RID_SUM_FROMTOX_HELP NC_("RID_SUM_FROMTOX_HELP", "Sum Sup/Sub script" )
+#define RID_MAJX_HELP NC_("RID_MAJX_HELP", "Summation (Arabic)" )
+#define RID_MAJ_FROMX_HELP NC_("RID_MAJ_FROMX_HELP", "Summation Subscript Bottom (Arabic)" )
+#define RID_MAJ_TOX_HELP NC_("RID_MAJ_TOX_HELP", "Summation Superscript Top (Arabic)" )
+#define RID_MAJ_FROMTOX_HELP NC_("RID_MAJ_FROMTOX_HELP", "Summation Sup/Sub script (Arabic)" )
+#define RID_PRODX_HELP NC_("RID_PRODX_HELP", "Product" )
+#define RID_PROD_FROMX_HELP NC_("RID_PROD_FROMX_HELP", "Product Subscript Bottom" )
+#define RID_PROD_TOX_HELP NC_("RID_PROD_TOX_HELP", "Product Superscript Top" )
+#define RID_PROD_FROMTOX_HELP NC_("RID_PROD_FROMTOX_HELP", "Product Sup/Sub script" )
+#define RID_COPRODX_HELP NC_("RID_COPRODX_HELP", "Coproduct" )
+#define RID_COPROD_FROMX_HELP NC_("RID_COPROD_FROMX_HELP", "Coproduct Subscript Bottom" )
+#define RID_COPROD_TOX_HELP NC_("RID_COPROD_TOX_HELP", "Coproduct Superscript Top" )
+#define RID_COPROD_FROMTOX_HELP NC_("RID_COPROD_FROMTOX_HELP", "Coproduct Sup/Sub script" )
+#define RID_LIMX_HELP NC_("RID_LIMX_HELP", "Limes" )
+#define RID_LIM_FROMX_HELP NC_("RID_LIM_FROMX_HELP", "Limes Subscript Bottom" )
+#define RID_LIM_TOX_HELP NC_("RID_LIM_TOX_HELP", "Limes Superscript Top" )
+#define RID_LIM_FROMTOX_HELP NC_("RID_LIM_FROMTOX_HELP", "Limes Sup/Sub script" )
+#define RID_LIMINFX_HELP NC_("RID_LIMINFX_HELP", "Limit Inferior" )
+#define RID_LIMINF_FROMX_HELP NC_("RID_LIMINF_FROMX_HELP", "Limit Inferior Subscript Bottom" )
+#define RID_LIMINF_TOX_HELP NC_("RID_LIMINF_TOX_HELP", "Limit Inferior Superscript Top" )
+#define RID_LIMINF_FROMTOX_HELP NC_("RID_LIMINF_FROMTOX_HELP", "Limit Inferior Sup/Sub script" )
+#define RID_LIMSUPX_HELP NC_("RID_LIMSUPX_HELP", "Limit Superior" )
+#define RID_LIMSUP_FROMX_HELP NC_("RID_LIMSUP_FROMX_HELP", "Limit Superior Subscript Bottom" )
+#define RID_LIMSUP_TOX_HELP NC_("RID_LIMSUP_TOX_HELP", "Limit Superior Superscript Top" )
+#define RID_LIMSUP_FROMTOX_HELP NC_("RID_LIMSUP_FROMTOX_HELP", "Limit Superior Sup/Sub script" )
+#define RID_HADDX_HELP NC_("RID_HADDX_HELP", "Limits (Persian)" )
+#define RID_HADD_FROMX_HELP NC_("RID_HADD_FROMX_HELP", "Limits Subscript Bottom (Persian)" )
+#define RID_HADD_TOX_HELP NC_("RID_HADD_TOX_HELP", "Limits Superscript Top (Persian)" )
+#define RID_HADD_FROMTOX_HELP NC_("RID_HADD_FROMTOX_HELP", "Limits Sup/Sub script (Persian)" )
+#define RID_EXISTS_HELP NC_("RID_EXISTS_HELP", "There Exists" )
+#define RID_NOTEXISTS_HELP NC_("RID_NOTEXISTS_HELP", "There does not exist" )
+#define RID_FORALL_HELP NC_("RID_FORALL_HELP", "For all" )
+#define RID_INTX_HELP NC_("RID_INTX_HELP", "Integral" )
+#define RID_INT_FROMX_HELP NC_("RID_INT_FROMX_HELP", "Integral Subscript Bottom" )
+#define RID_INT_TOX_HELP NC_("RID_INT_TOX_HELP", "Integral Superscript Top" )
+#define RID_INT_FROMTOX_HELP NC_("RID_INT_FROMTOX_HELP", "Integral Sup/Sub script" )
+#define RID_IINTX_HELP NC_("RID_IINTX_HELP", "Double Integral" )
+#define RID_IINT_FROMX_HELP NC_("RID_IINT_FROMX_HELP", "Double Integral Subscript Bottom" )
+#define RID_IINT_TOX_HELP NC_("RID_IINT_TOX_HELP", "Double Integral Superscript Top" )
+#define RID_IINT_FROMTOX_HELP NC_("RID_IINT_FROMTOX_HELP", "Double Integral Sup/Sub script" )
+#define RID_IIINTX_HELP NC_("RID_IIINTX_HELP", "Triple Integral" )
+#define RID_IIINT_FROMX_HELP NC_("RID_IIINT_FROMX_HELP", "Triple Integral Subscript Bottom" )
+#define RID_IIINT_TOX_HELP NC_("RID_IIINT_TOX_HELP", "Triple Integral Superscript Top" )
+#define RID_IIINT_FROMTOX_HELP NC_("RID_IIINT_FROMTOX_HELP", "Triple Integral Sup/Sub script" )
+#define RID_LINTX_HELP NC_("RID_LINTX_HELP", "Curve Integral" )
+#define RID_LINT_FROMX_HELP NC_("RID_LINT_FROMX_HELP", "Curve Integral Subscript Bottom" )
+#define RID_LINT_TOX_HELP NC_("RID_LINT_TOX_HELP", "Curve Integral Superscript Top" )
+#define RID_LINT_FROMTOX_HELP NC_("RID_LINT_FROMTOX_HELP", "Curve Integral Sup/Sub script" )
+#define RID_LLINTX_HELP NC_("RID_LLINTX_HELP", "Double Curve Integral" )
+#define RID_LLINT_FROMX_HELP NC_("RID_LLINT_FROMX_HELP", "Double Curve Integral Subscript Bottom" )
+#define RID_LLINT_TOX_HELP NC_("RID_LLINT_TOX_HELP", "Double Curve Integral Superscript Top" )
+#define RID_LLINT_FROMTOX_HELP NC_("RID_LLINT_FROMTOX_HELP", "Double Curve Integral Sup/Sub script" )
+#define RID_LLLINTX_HELP NC_("RID_LLLINTX_HELP", "Triple Curve Integral" )
+#define RID_LLLINT_FROMX_HELP NC_("RID_LLLINT_FROMX_HELP", "Triple Curve Integral Subscript Bottom" )
+#define RID_LLLINT_TOX_HELP NC_("RID_LLLINT_TOX_HELP", "Triple Curve Integral Superscript Top" )
+#define RID_LLLINT_FROMTOX_HELP NC_("RID_LLLINT_FROMTOX_HELP", "Triple Curve Integral Sup/Sub script" )
+#define RID_ACUTEX_HELP NC_("RID_ACUTEX_HELP", "Acute Accent" )
+#define RID_BARX_HELP NC_("RID_BARX_HELP", "Line Above" )
+#define RID_BREVEX_HELP NC_("RID_BREVEX_HELP", "Breve" )
+#define RID_CHECKX_HELP NC_("RID_CHECKX_HELP", "Reverse Circumflex" )
+#define RID_CIRCLEX_HELP NC_("RID_CIRCLEX_HELP", "Circle" )
+#define RID_DOTX_HELP NC_("RID_DOTX_HELP", "Dot" )
+#define RID_DDOTX_HELP NC_("RID_DDOTX_HELP", "Double Dot" )
+#define RID_DDDOTX_HELP NC_("RID_DDDOTX_HELP", "Triple Dot" )
+#define RID_GRAVEX_HELP NC_("RID_GRAVEX_HELP", "Grave Accent" )
+#define RID_HATX_HELP NC_("RID_HATX_HELP", "Circumflex" )
+#define RID_TILDEX_HELP NC_("RID_TILDEX_HELP", "Tilde" )
+#define RID_VECX_HELP NC_("RID_VECX_HELP", "Vector Arrow" )
+#define RID_HARPOONX_HELP NC_("RID_HARPOONX_HELP", "Harpoon" )
+#define RID_UNDERLINEX_HELP NC_("RID_UNDERLINEX_HELP", "Line Below" )
+#define RID_OVERLINEX_HELP NC_("RID_OVERLINEX_HELP", "Line Over" )
+#define RID_OVERSTRIKEX_HELP NC_("RID_OVERSTRIKEX_HELP", "Line Through" )
+#define RID_PHANTOMX_HELP NC_("RID_PHANTOMX_HELP", "Transparent" )
+#define RID_BOLDX_HELP NC_("RID_BOLDX_HELP", "Bold Font" )
+#define RID_ITALX_HELP NC_("RID_ITALX_HELP", "Italic Font" )
+#define RID_SIZEXY_HELP NC_("RID_SIZEXY_HELP", "Resize" )
+#define RID_FONTXY_HELP NC_("RID_FONTXY_HELP", "Change Font" )
+#define RID_COLORX_BLACK_HELP NC_("RID_COLORX_BLACK_HELP", "Color Black" )
+#define RID_COLORX_BLUE_HELP NC_("RID_COLORX_BLUE_HELP", "Color Blue" )
+#define RID_COLORX_GREEN_HELP NC_("RID_COLORX_GREEN_HELP", "Color Green" )
+#define RID_COLORX_RED_HELP NC_("RID_COLORX_RED_HELP", "Color Red" )
+#define RID_COLORX_AQUA_HELP NC_("RID_COLORX_AQUA_HELP", "Color Aqua" )
+#define RID_COLORX_FUCHSIA_HELP NC_("RID_COLORX_FUCHSIA_HELP", "Color Fuchsia" )
+#define RID_COLORX_GRAY_HELP NC_("RID_COLORX_GRAY_HELP", "Color Gray" )
+#define RID_COLORX_LIME_HELP NC_("RID_COLORX_LIME_HELP", "Color Lime" )
+#define RID_COLORX_MAROON_HELP NC_("RID_COLORX_MAROON_HELP", "Color Maroon" )
+#define RID_COLORX_NAVY_HELP NC_("RID_COLORX_NAVY_HELP", "Color Navy" )
+#define RID_COLORX_OLIVE_HELP NC_("RID_COLORX_OLIVE_HELP", "Color Olive" )
+#define RID_COLORX_PURPLE_HELP NC_("RID_COLORX_PURPLE_HELP", "Color Purple" )
+#define RID_COLORX_SILVER_HELP NC_("RID_COLORX_SILVER_HELP", "Color Silver" )
+#define RID_COLORX_TEAL_HELP NC_("RID_COLORX_TEAL_HELP", "Color Teal" )
+#define RID_COLORX_YELLOW_HELP NC_("RID_COLORX_YELLOW_HELP", "Color Yellow" )
+#define RID_COLORX_RGB_HELP NC_("RID_COLORX_RGB_HELP", "Color RGB" )
+#define RID_COLORX_RGBA_HELP NC_("RID_COLORX_RGBA_HELP", "Color RGBA" )
+#define RID_COLORX_HEX_HELP NC_("RID_COLORX_HEX_HELP", "Color hexadecimal" )
+#define RID_COLORX_CORAL_HELP NC_("RID_COLORX_CORAL_HELP", "Color Coral" )
+#define RID_COLORX_CRIMSON_HELP NC_("RID_COLORX_CRIMSON_HELP", "Color Crimson" )
+#define RID_COLORX_MIDNIGHT_HELP NC_("RID_COLORX_MIDNIGHT_HELP", "Color Midnight blue" )
+#define RID_COLORX_VIOLET_HELP NC_("RID_COLORX_VIOLET_HELP", "Color Violet" )
+#define RID_COLORX_ORANGE_HELP NC_("RID_COLORX_ORANGE_HELP", "Color Orange" )
+#define RID_COLORX_ORANGERED_HELP NC_("RID_COLORX_ORANGERED_HELP", "Color Orangered" )
+#define RID_COLORX_SEAGREEN_HELP NC_("RID_COLORX_SEAGREEN_HELP", "Color Seagreen" )
+#define RID_COLORX_INDIGO_HELP NC_("RID_COLORX_INDIGO_HELP", "Color Indigo" )
+#define RID_COLORX_HOTPINK_HELP NC_("RID_COLORX_HOTPINK_HELP", "Color Hot pink" )
+#define RID_COLORX_LAVENDER_HELP NC_("RID_COLORX_LAVENDER_HELP", "Color Lavender" )
+#define RID_COLORX_SNOW_HELP NC_("RID_COLORX_SNOW_HELP", "Color Snow" )
+#define RID_LRGROUPX_HELP NC_("RID_LRGROUPX_HELP", "Group Brackets" )
+#define RID_LRPARENTX_HELP NC_("RID_LRPARENTX_HELP", "Round Brackets" )
+#define RID_LRBRACKETX_HELP NC_("RID_LRBRACKETX_HELP", "Square Brackets" )
+#define RID_LRDBRACKETX_HELP NC_("RID_LRDBRACKETX_HELP", "Double Square Brackets" )
+#define RID_LRBRACEX_HELP NC_("RID_LRBRACEX_HELP", "Braces" )
+#define RID_LRANGLEX_HELP NC_("RID_LRANGLEX_HELP", "Angle Brackets" )
+#define RID_LRCEILX_HELP NC_("RID_LRCEILX_HELP", "Upper Ceil" )
+#define RID_LRFLOORX_HELP NC_("RID_LRFLOORX_HELP", "Floor" )
+#define RID_LRLINEX_HELP NC_("RID_LRLINEX_HELP", "Single Lines" )
+#define RID_LRDLINEX_HELP NC_("RID_LRDLINEX_HELP", "Double Lines" )
+#define RID_LMRANGLEXY_HELP NC_("RID_LMRANGLEXY_HELP", "Operator Brackets" )
+#define RID_SLRPARENTX_HELP NC_("RID_SLRPARENTX_HELP", "Round Brackets (Scalable)" )
+#define RID_SLRBRACKETX_HELP NC_("RID_SLRBRACKETX_HELP", "Square Brackets (Scalable)" )
+#define RID_SLRDBRACKETX_HELP NC_("RID_SLRDBRACKETX_HELP", "Double Square Brackets (Scalable)" )
+#define RID_SLRBRACEX_HELP NC_("RID_SLRBRACEX_HELP", "Braces (Scalable)" )
+#define RID_SLRANGLEX_HELP NC_("RID_SLRANGLEX_HELP", "Angle Brackets (Scalable)" )
+#define RID_SLRCEILX_HELP NC_("RID_SLRCEILX_HELP", "Ceiling (Scalable)" )
+#define RID_SLRFLOORX_HELP NC_("RID_SLRFLOORX_HELP", "Floor (Scalable)" )
+#define RID_SLRLINEX_HELP NC_("RID_SLRLINEX_HELP", "Single Lines (Scalable)" )
+#define RID_SLRDLINEX_HELP NC_("RID_SLRDLINEX_HELP", "Double Lines (Scalable)" )
+#define RID_SLMRANGLEXY_HELP NC_("RID_SLMRANGLEXY_HELP", "Operator Brackets (Scalable)" )
+#define RID_XOVERBRACEY_HELP NC_("RID_XOVERBRACEY_HELP", "Braces Top (Scalable)" )
+#define RID_XUNDERBRACEY_HELP NC_("RID_XUNDERBRACEY_HELP", "Braces Bottom (Scalable)" )
+#define RID_EVALUATEX_HELP NC_("RID_EVALUATEX_HELP", "Evaluate" )
+#define RID_EVALUATE_FROMX_HELP NC_("RID_EVALUATE_FROMX_HELP", "Evaluate Subscript Bottom" )
+#define RID_EVALUATE_TOX_HELP NC_("RID_EVALUATE_TOX_HELP", "Evaluate Superscript Top" )
+#define RID_EVALUATE_FROMTOX_HELP NC_("RID_EVALUATE_FROMTOX_HELP", "Evaluate Sup/Sub script" )
+#define RID_RSUBX_HELP NC_("RID_RSUBX_HELP", "Subscript Right" )
+#define RID_RSUPX_HELP NC_("RID_RSUPX_HELP", "Power" )
+#define RID_LSUBX_HELP NC_("RID_LSUBX_HELP", "Subscript Left" )
+#define RID_LSUPX_HELP NC_("RID_LSUPX_HELP", "Superscript Left" )
+#define RID_CSUBX_HELP NC_("RID_CSUBX_HELP", "Subscript Bottom" )
+#define RID_CSUPX_HELP NC_("RID_CSUPX_HELP", "Superscript Top" )
+#define RID_SBLANK_HELP NC_("RID_SBLANK_HELP", "Small Gap" )
+#define RID_BLANK_HELP NC_("RID_BLANK_HELP", "Blank" )
+#define RID_NEWLINE_HELP NC_("RID_NEWLINE_HELP", "New Line" )
+#define RID_BINOMXY_HELP NC_("RID_BINOMXY_HELP", "Vertical Stack (2 Elements)")
+#define RID_STACK_HELP NC_("RID_STACK_HELP", "Vertical Stack" )
+#define RID_MATRIX_HELP NC_("RID_MATRIX_HELP", "Matrix Stack" )
+#define RID_ALIGNLX_HELP NC_("RID_ALIGNLX_HELP", "Align Left" )
+#define RID_ALIGNCX_HELP NC_("RID_ALIGNCX_HELP", "Align Center" )
+#define RID_ALIGNRX_HELP NC_("RID_ALIGNRX_HELP", "Align Right" )
+#define RID_ALEPH_HELP NC_("RID_ALEPH_HELP", "Aleph" )
+#define RID_EMPTYSET_HELP NC_("RID_EMPTYSET_HELP", "Empty Set" )
+#define RID_RE_HELP NC_("RID_RE_HELP", "Real Part" )
+#define RID_IM_HELP NC_("RID_IM_HELP", "Imaginary Part" )
+#define RID_INFINITY_HELP NC_("RID_INFINITY_HELP", "Infinity" )
+#define RID_PARTIAL_HELP NC_("RID_PARTIAL_HELP", "Partial" )
+#define RID_NABLA_HELP NC_("RID_NABLA_HELP", "Nabla" )
+#define RID_LAPLACE_HELP NC_("RID_LAPLACE_HELP", "Laplace transform" )
+#define RID_FOURIER_HELP NC_("RID_FOURIER_HELP", "Fourier transform" )
+#define RID_BACKEPSILON_HELP NC_("RID_BACKEPSILON_HELP", "Backwards epsilon" )
+#define RID_WP_HELP NC_("RID_WP_HELP", "Weierstrass p" )
+#define RID_DOTSAXIS_HELP NC_("RID_DOTSAXIS_HELP", "Dots In Middle" )
+#define RID_DOTSUP_HELP NC_("RID_DOTSUP_HELP", "Dots To Top" )
+#define RID_DOTSDOWN_HELP NC_("RID_DOTSDOWN_HELP", "Dots To Bottom" )
+#define RID_DOTSLOW_HELP NC_("RID_DOTSLOW_HELP", "Dots At Bottom" )
+#define RID_DOTSVERT_HELP NC_("RID_DOTSVERT_HELP", "Dots Vertically" )
+#define RID_XCIRCY_HELP NC_("RID_XCIRCY_HELP", "Concatenate" )
+#define RID_XWIDESLASHY_HELP NC_("RID_XWIDESLASHY_HELP", "Division (wideslash)" )
+#define RID_XWIDEBSLASHY_HELP NC_("RID_XWIDEBSLASHY_HELP", "Division (counter wideslash)" )
+#define RID_XDIVIDESY_HELP NC_("RID_XDIVIDESY_HELP", "Divides" )
+#define RID_XNDIVIDESY_HELP NC_("RID_XNDIVIDESY_HELP", "Does Not Divide" )
+#define RID_DLARROW_HELP NC_("RID_DLARROW_HELP", "Double Arrow Left" )
+#define RID_DLRARROW_HELP NC_("RID_DLRARROW_HELP", "Double Arrow Left And Right" )
+#define RID_DRARROW_HELP NC_("RID_DRARROW_HELP", "Double Arrow Right" )
+#define RID_SETN_HELP NC_("RID_SETN_HELP", "Natural Numbers Set" )
+#define RID_SETZ_HELP NC_("RID_SETZ_HELP", "Integers Set" )
+#define RID_SETQ_HELP NC_("RID_SETQ_HELP", "Set of Rational Numbers" )
+#define RID_SETR_HELP NC_("RID_SETR_HELP", "Real Numbers Set" )
+#define RID_SETC_HELP NC_("RID_SETC_HELP", "Complex Numbers Set" )
+#define RID_WIDEHATX_HELP NC_("RID_WIDEHATX_HELP", "Large Circumflex" )
+#define RID_WIDETILDEX_HELP NC_("RID_WIDETILDEX_HELP", "Large Tilde" )
+#define RID_WIDEVECX_HELP NC_("RID_WIDEVECX_HELP", "Large Vector Arrow" )
+#define RID_WIDEHARPOONX_HELP NC_("RID_WIDEHARPOONX_HELP", "Large Harpoon" )
+#define RID_HBAR_HELP NC_("RID_HBAR_HELP", "h Bar" )
+#define RID_LAMBDABAR_HELP NC_("RID_LAMBDABAR_HELP", "Lambda Bar" )
+#define RID_LEFTARROW_HELP NC_("RID_LEFTARROW_HELP", "Left Arrow" )
+#define RID_RIGHTARROW_HELP NC_("RID_RIGHTARROW_HELP", "Right Arrow" )
+#define RID_UPARROW_HELP NC_("RID_UPARROW_HELP", "Up Arrow" )
+#define RID_DOWNARROW_HELP NC_("RID_DOWNARROW_HELP", "Down Arrow" )
+#define RID_NOSPACE_HELP NC_("RID_NOSPACE_HELP", "No space" )
+#define RID_XPRECEDESY_HELP NC_("RID_XPRECEDESY_HELP", "Precedes" )
+#define RID_XPRECEDESEQUALY_HELP NC_("RID_XPRECEDESEQUALY_HELP", "Precedes or equal to" )
+#define RID_XPRECEDESEQUIVY_HELP NC_("RID_XPRECEDESEQUIVY_HELP", "Precedes or equivalent to" )
+#define RID_XSUCCEEDSY_HELP NC_("RID_XSUCCEEDSY_HELP", "Succeeds" )
+#define RID_XSUCCEEDSEQUALY_HELP NC_("RID_XSUCCEEDSEQUALY_HELP", "Succeeds or equal to" )
+#define RID_XSUCCEEDSEQUIVY_HELP NC_("RID_XSUCCEEDSEQUIVY_HELP", "Succeeds or equivalent to" )
+#define RID_XNOTPRECEDESY_HELP NC_("RID_XNOTPRECEDESY_HELP", "Does not precede" )
+#define RID_XNOTSUCCEEDSY_HELP NC_("RID_XNOTSUCCEEDSY_HELP", "Does not succeed" )
+#define RID_CATEGORY_UNARY_BINARY_OPERATORS NC_("RID_CATEGORY_UNARY_BINARY_OPERATORS", "Unary/Binary Operators" )
+#define RID_CATEGORY_RELATIONS NC_("RID_CATEGORY_RELATIONS", "Relations" )
+#define RID_CATEGORY_SET_OPERATIONS NC_("RID_CATEGORY_SET_OPERATIONS", "Set Operations" )
+#define RID_CATEGORY_FUNCTIONS NC_("RID_CATEGORY_FUNCTIONS", "Functions" )
+#define RID_CATEGORY_OPERATORS NC_("RID_CATEGORY_OPERATORS", "Operators" )
+#define RID_CATEGORY_ATTRIBUTES NC_("RID_CATEGORY_ATTRIBUTES", "Attributes" )
+#define RID_CATEGORY_BRACKETS NC_("RID_CATEGORY_BRACKETS", "Brackets" )
+#define RID_CATEGORY_FORMATS NC_("RID_CATEGORY_FORMATS", "Formats" )
+#define RID_CATEGORY_OTHERS NC_("RID_CATEGORY_OTHERS", "Others" )
+#define RID_CATEGORY_EXAMPLES NC_("RID_CATEGORY_EXAMPLES", "Examples" )
+
+#define RID_EXAMPLE_CIRCUMFERENCE_HELP NC_("RID_EXAMPLE_CIRCUMFERENCE_HELP", "Circumference" )
+#define RID_EXAMPLE_MASS_ENERGY_EQUIV_HELP NC_("RID_EXAMPLE_MASS_ENERGY_EQUIV_HELP", "Mass–energy equivalence" )
+#define RID_EXAMPLE_PYTHAGOREAN_THEO_HELP NC_("RID_EXAMPLE_PYTHAGOREAN_THEO_HELP", "Pythagorean theorem" )
+#define RID_EXAMPLE_A_TAYLOR_SERIES_HELP NC_("RID_EXAMPLE_A_TAYLOR_SERIES_HELP", "Taylor series" )
+#define RID_EXAMPLE_GAUSS_DISTRIBUTION_HELP NC_("RID_EXAMPLE_GAUSS_DISTRIBUTION_HELP", "Gauss distribution" )
+#define RID_EXAMPLE_EULER_LAGRANGE_HELP NC_("RID_EXAMPLE_EULER_LAGRANGE_HELP", "Euler-Lagrange equation" )
+#define RID_EXAMPLE_FTC_HELP NC_("RID_EXAMPLE_FTC_HELP", "Fundamental theorem of calculus" )
+#define RID_EXAMPLE_CHAOS_HELP NC_("RID_EXAMPLE_CHAOS_HELP", "Chaos equation" )
+#define RID_EXAMPLE_EULER_IDENTITY_HELP NC_("RID_EXAMPLE_EULER_IDENTITY_HELP", "Euler's identity" )
+#define RID_EXAMPLE_2NEWTON NC_("RID_EXAMPLE_2NEWTON", "Newton's second law" )
+#define RID_EXAMPLE_GENERAL_RELATIVITY_HELP NC_("RID_EXAMPLE_GENERAL_RELATIVITY_HELP", "General relativity")
+#define RID_EXAMPLE_SPECIAL_RELATIVITY_HELP NC_("RID_EXAMPLE_SPECIAL_RELATIVITY_HELP", "Special relativity")
+
+#define RID_FONTREGULAR NC_("RID_FONTREGULAR", "Standard" )
+#define RID_FONTITALIC NC_("RID_FONTITALIC", "Italic" )
+#define RID_FONTBOLD NC_("RID_FONTBOLD", "Bold" )
+#define STR_BLACK NC_("STR_BLACK", "black" )
+#define STR_BLUE NC_("STR_BLUE", "blue" )
+#define STR_GREEN NC_("STR_GREEN", "green" )
+#define STR_RED NC_("STR_RED", "red" )
+#define STR_AQUA NC_("STR_AQUA", "aqua" )
+#define STR_FUCHSIA NC_("STR_FUCHSIA", "fuchsia" )
+#define STR_GRAY NC_("STR_GRAY", "gray" )
+#define STR_LIME NC_("STR_LIME", "lime" )
+#define STR_MAROON NC_("STR_MAROON", "maroon" )
+#define STR_NAVY NC_("STR_NAVY", "navy" )
+#define STR_OLIVE NC_("STR_OLIVE", "olive" )
+#define STR_PURPLE NC_("STR_PURPLE", "purple" )
+#define STR_SILVER NC_("STR_SILVER", "silver" )
+#define STR_TEAL NC_("STR_TEAL", "teal" )
+#define STR_YELLOW NC_("STR_YELLOW", "yellow" )
+#define STR_CORAL NC_("STR_CORAL", "coral" )
+#define STR_CRIMSON NC_("STR_CRIMSON", "crimson" )
+#define STR_MIDNIGHT NC_("STR_MIDNIGHT", "midnight" )
+#define STR_VIOLET NC_("STR_VIOLET", "violet" )
+#define STR_ORANGE NC_("STR_ORANGE", "orange" )
+#define STR_ORANGERED NC_("STR_ORANGERED", "orangered" )
+#define STR_LAVENDER NC_("STR_LAVENDER", "lavender" )
+#define STR_SNOW NC_("STR_SNOW", "snow" )
+#define STR_SEAGREEN NC_("STR_SEAGREEN", "seagreen" )
+#define STR_INDIGO NC_("STR_INDIGO", "indigo" )
+#define STR_HOTPINK NC_("STR_HOTPINK", "hotpink" )
+#define STR_RGB NC_("STR_RGB", "rgb" )
+#define STR_RGBA NC_("STR_RGBA", "rgba" )
+#define STR_HEX NC_("STR_HEX", "hex" )
+#define STR_HIDE NC_("STR_HIDE", "hide" )
+#define STR_SIZE NC_("STR_SIZE", "size" )
+#define STR_FONT NC_("STR_FONT", "font" )
+#define STR_ALIGN_LEFT NC_("STR_ALIGN_LEFT", "left" )
+#define STR_ALIGN_CENTER NC_("STR_ALIGN_CENTER", "center" )
+#define STR_ALIGN_RIGHT NC_("STR_ALIGN_RIGHT", "right" )
+#define STR_CMDBOXWINDOW NC_("STR_CMDBOXWINDOW", "Commands" )
+#define RID_DOCUMENTSTR NC_("RID_DOCUMENTSTR", "Formula" )
+#define STR_STATSTR_WRITING NC_("STR_STATSTR_WRITING", "Saving document..." )
+#define STR_MATH_DOCUMENT_FULLTYPE_CURRENT NC_("STR_MATH_DOCUMENT_FULLTYPE_CURRENT", "%PRODUCTNAME %PRODUCTVERSION Formula")
+#define RID_ERR_IDENT NC_("RID_ERR_IDENT", "ERROR : " )
+#define RID_ERR_NONE NC_("RID_ERR_NONE", "no error" )
+#define RID_ERR_UNEXPECTEDCHARACTER NC_("RID_ERR_UNEXPECTEDCHARACTER", "Unexpected character" )
+#define RID_ERR_UNEXPECTEDTOKEN NC_("RID_ERR_UNEXPECTEDTOKEN", "Unexpected token" )
+#define RID_ERR_LGROUPEXPECTED NC_("RID_ERR_LGROUPEXPECTED", "'{' expected" )
+#define RID_ERR_RGROUPEXPECTED NC_("RID_ERR_RGROUPEXPECTED", "'}' expected" )
+#define RID_ERR_LBRACEEXPECTED NC_("RID_ERR_LBRACEEXPECTED", "'(' expected" )
+#define RID_ERR_RBRACEEXPECTED NC_("RID_ERR_RBRACEEXPECTED", "')' expected" )
+#define RID_ERR_PARENTMISMATCH NC_("RID_ERR_PARENTMISMATCH", "Left and right symbols mismatched" )
+#define RID_ERR_FONTEXPECTED NC_("RID_ERR_FONTEXPECTED", "'fixed', 'sans', or 'serif' expected" )
+#define RID_ERR_SIZEEXPECTED NC_("RID_ERR_SIZEEXPECTED", "'size' followed by an unexpected token" )
+#define RID_ERR_DOUBLEALIGN NC_("RID_ERR_DOUBLEALIGN", "Double aligning is not allowed" )
+#define RID_ERR_DOUBLESUBSUPSCRIPT NC_("RID_ERR_DOUBLESUBSUPSCRIPT", "Double sub/superscripts is not allowed" )
+#define RID_ERR_NUMBEREXPECTED NC_("RID_ERR_NUMBEREXPECTED", "Expected number" )
+#define RID_ERR_POUNDEXPECTED NC_("RID_ERR_POUNDEXPECTED", "'#' expected" )
+#define RID_ERR_COLOREXPECTED NC_("RID_ERR_COLOREXPECTED", "Color required" )
+#define RID_ERR_RIGHTEXPECTED NC_("RID_ERR_RIGHTEXPECTED", "'RIGHT' expected" )
+#define RID_PRINTUIOPT_PRODNAME NC_("RID_PRINTUIOPT_PRODNAME", "%PRODUCTNAME %s" )
+#define RID_PRINTUIOPT_CONTENTS NC_("RID_PRINTUIOPT_CONTENTS", "Contents" )
+#define RID_PRINTUIOPT_TITLE NC_("RID_PRINTUIOPT_TITLE", "~Title" )
+#define RID_PRINTUIOPT_FRMLTXT NC_("RID_PRINTUIOPT_FRMLTXT", "~Formula text" )
+#define RID_PRINTUIOPT_BORDERS NC_("RID_PRINTUIOPT_BORDERS", "B~orders" )
+#define RID_PRINTUIOPT_SIZE NC_("RID_PRINTUIOPT_SIZE", "Size" )
+#define RID_PRINTUIOPT_ORIGSIZE NC_("RID_PRINTUIOPT_ORIGSIZE", "O~riginal size" )
+#define RID_PRINTUIOPT_FITTOPAGE NC_("RID_PRINTUIOPT_FITTOPAGE", "Fit to ~page" )
+#define RID_PRINTUIOPT_SCALING NC_("RID_PRINTUIOPT_SCALING", "~Scaling" )
+// clang-format on
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/strings.hxx b/starmath/inc/strings.hxx
new file mode 100644
index 0000000000..469b54575c
--- /dev/null
+++ b/starmath/inc/strings.hxx
@@ -0,0 +1,338 @@
+/* -*- 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/.
+ */
+
+/** Those are the starmath codes for ElementsDockingWindow.hxx.
+ *
+ * Those codes will be displayed as formulas on the ElementsDockingWindow.
+ * The user can then graphically insert them.
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+inline constexpr OUString RID_UNDOFORMATNAME = u"Format"_ustr;
+
+// clang-format off
+#define RID_PLUSX u"+<?> "
+#define RID_MINUSX u"-<?> "
+#define RID_PLUSMINUSX u"+-<?> "
+#define RID_MINUSPLUSX u"-+<?> "
+#define RID_NEGX u"neg <?> "
+#define RID_XPLUSY u"<?> + <?> "
+#define RID_XMINUSY u"<?> - <?> "
+#define RID_XCDOTY u"<?> cdot <?> "
+#define RID_XTIMESY u"<?> times <?> "
+#define RID_XSYMTIMESY u"<?> * <?> "
+#define RID_XSYMDIVIDEY u"<?> / <?> "
+#define RID_XDIVY u"<?> div <?> "
+#define RID_XOVERY u"{<?>} over {<?>} "
+#define RID_FRACXY u"frac {<?>} {<?>} "
+#define RID_XODIVIDEY u"<?> odivide <?> "
+#define RID_XODOTY u"<?> odot <?> "
+#define RID_XOMINUSY u"<?> ominus <?> "
+#define RID_XOPLUSY u"<?> oplus <?> "
+#define RID_XOTIMESY u"<?> otimes <?> "
+#define RID_XANDY u"<?> and <?> "
+#define RID_XORY u"<?> or <?> "
+#define RID_XEQY u"<?> = <?> "
+#define RID_XNEQY u"<?> <> <?> "
+#define RID_XLTY u"<?> < <?> "
+#define RID_XGTY u"<?> > <?> "
+#define RID_XLEY u"<?> <= <?> "
+#define RID_XGEY u"<?> >= <?> "
+#define RID_XLESLANTY u"<?> leslant <?> "
+#define RID_XGESLANTY u"<?> geslant <?> "
+#define RID_XLLY u"<?> << <?> "
+#define RID_XGGY u"<?> >> <?> "
+#define RID_XDEFY u"<?> def <?> "
+#define RID_XEQUIVY u"<?> equiv <?> "
+#define RID_XAPPROXY u"<?> approx <?> "
+#define RID_XSIMY u"<?> sim <?> "
+#define RID_XSIMEQY u"<?> simeq <?> "
+#define RID_XPROPY u"<?> prop <?> "
+#define RID_XORTHOY u"<?> ortho <?> "
+#define RID_XPARALLELY u"<?> parallel <?> "
+#define RID_XTOWARDY u"<?> toward <?> "
+#define RID_XTRANSLY u"<?> transl <?> "
+#define RID_XTRANSRY u"<?> transr <?> "
+#define RID_XINY u"<?> in <?> "
+#define RID_XNOTINY u"<?> notin <?> "
+#define RID_XOWNSY u"<?> owns <?> "
+#define RID_XUNIONY u"<?> union <?> "
+#define RID_XINTERSECTIONY u"<?> intersection <?> "
+#define RID_XSETMINUSY u"<?> setminus <?> "
+#define RID_XSETQUOTIENTY u"<?> setquotient <?> "
+#define RID_XSUBSETY u"<?> subset <?> "
+#define RID_XSUBSETEQY u"<?> subseteq <?> "
+#define RID_XSUPSETY u"<?> supset <?> "
+#define RID_XSUPSETEQY u"<?> supseteq <?> "
+#define RID_XNSUBSETY u"<?> nsubset <?> "
+#define RID_XNSUBSETEQY u"<?> nsubseteq <?> "
+#define RID_XNSUPSETY u"<?> nsupset <?> "
+#define RID_XNSUPSETEQY u"<?> nsupseteq <?> "
+#define RID_FUNCX u"func <?>(<?>) "
+#define RID_ABSX u"abs{<?>} "
+#define RID_FACTX u"fact{<?>} "
+#define RID_SQRTX u"sqrt{<?>} "
+#define RID_NROOTXY u"nroot{<?>}{<?>} "
+#define RID_EX u"func e^{<?>} "
+#define RID_EXPX u"exp(<?>) "
+#define RID_LNX u"ln(<?>) "
+#define RID_LOGX u"log(<?>) "
+#define RID_SINX u"sin(<?>) "
+#define RID_COSX u"cos(<?>) "
+#define RID_TANX u"tan(<?>) "
+#define RID_COTX u"cot(<?>) "
+#define RID_ARCSINX u"arcsin(<?>) "
+#define RID_ARCCOSX u"arccos(<?>) "
+#define RID_ARCTANX u"arctan(<?>) "
+#define RID_ARCCOTX u"arccot(<?>) "
+#define RID_SINHX u"sinh(<?>) "
+#define RID_COSHX u"cosh(<?>) "
+#define RID_TANHX u"tanh(<?>) "
+#define RID_COTHX u"coth(<?>) "
+#define RID_ARSINHX u"arsinh(<?>) "
+#define RID_ARCOSHX u"arcosh(<?>) "
+#define RID_ARTANHX u"artanh(<?>) "
+#define RID_ARCOTHX u"arcoth(<?>) "
+#define RID_OPERX u"oper oper <?> "
+#define RID_OPER_FROMX u"oper oper from{<?>} <?> "
+#define RID_OPER_TOX u"oper oper to{<?>} <?> "
+#define RID_OPER_FROMTOX u"oper oper from{<?>} to{<?>} <?> "
+#define RID_SUMX u"sum <?> "
+#define RID_SUM_FROMX u"sum from{<?>} <?> "
+#define RID_SUM_TOX u"sum to{<?>} <?> "
+#define RID_SUM_FROMTOX u"sum from{<?>} to{<?>} <?> "
+#define RID_MAJX u"maj <?> "
+#define RID_MAJ_FROMX u"maj from{<?>} <?> "
+#define RID_MAJ_TOX u"maj to{<?>} <?> "
+#define RID_MAJ_FROMTOX u"maj from{<?>} to{<?>} <?> "
+#define RID_PRODX u"prod <?> "
+#define RID_PROD_FROMX u"prod from{<?>} <?> "
+#define RID_PROD_TOX u"prod to{<?>} <?> "
+#define RID_PROD_FROMTOX u"prod from{<?>} to{<?>} <?> "
+#define RID_COPRODX u"coprod <?> "
+#define RID_COPROD_FROMX u"coprod from{<?>} <?> "
+#define RID_COPROD_TOX u"coprod to{<?>} <?> "
+#define RID_COPROD_FROMTOX u"coprod from{<?>} to{<?>} <?> "
+#define RID_LIMX u"lim <?> "
+#define RID_LIM_FROMX u"lim from{<?>} <?> "
+#define RID_LIM_TOX u"lim to{<?>} <?> "
+#define RID_LIM_FROMTOX u"lim from{<?>} to{<?>} <?> "
+#define RID_LIMINFX u"liminf <?> "
+#define RID_LIMINF_FROMX u"liminf from{<?>} <?> "
+#define RID_LIMINF_TOX u"liminf to{<?>} <?> "
+#define RID_LIMINF_FROMTOX u"liminf from{<?>} to{<?>} <?> "
+#define RID_LIMSUPX u"limsup <?> "
+#define RID_LIMSUP_FROMX u"limsup from{<?>} <?> "
+#define RID_LIMSUP_TOX u"limsup to{<?>} <?> "
+#define RID_LIMSUP_FROMTOX u"limsup from{<?>} to{<?>} <?> "
+#define RID_HADDX u"hadd <?> "
+#define RID_HADD_FROMX u"hadd from{<?>} <?> "
+#define RID_HADD_TOX u"hadd to{<?>} <?> "
+#define RID_HADD_FROMTOX u"hadd from{<?>} to{<?>} <?> "
+#define RID_EXISTS u"exists "
+#define RID_NOTEXISTS u"notexists "
+#define RID_FORALL u"forall "
+#define RID_INTX u"int <?> "
+#define RID_INT_FROMX u"int from{<?>} <?> "
+#define RID_INT_TOX u"int to{<?>} <?> "
+#define RID_INT_FROMTOX u"int from{<?>} to{<?>} <?> "
+#define RID_IINTX u"iint <?> "
+#define RID_IINT_FROMX u"iint from{<?>} <?> "
+#define RID_IINT_TOX u"iint to{<?>} <?> "
+#define RID_IINT_FROMTOX u"iint from{<?>} to{<?>} <?> "
+#define RID_IIINTX u"iiint <?> "
+#define RID_IIINT_FROMX u"iiint from{<?>} <?> "
+#define RID_IIINT_TOX u"iiint to{<?>} <?> "
+#define RID_IIINT_FROMTOX u"iiint from{<?>} to{<?>} <?> "
+#define RID_LINTX u"lint <?> "
+#define RID_LINT_FROMX u"lint from{<?>} <?> "
+#define RID_LINT_TOX u"lint to{<?>} <?> "
+#define RID_LINT_FROMTOX u"lint from{<?>} to{<?>} <?> "
+#define RID_LLINTX u"llint <?> "
+#define RID_LLINT_FROMX u"llint from{<?>} <?> "
+#define RID_LLINT_TOX u"llint to{<?>} <?> "
+#define RID_LLINT_FROMTOX u"llint from{<?>} to{<?>} <?> "
+#define RID_LLLINTX u"lllint <?> "
+#define RID_LLLINT_FROMX u"lllint from{<?>} <?> "
+#define RID_LLLINT_TOX u"lllint to{<?>} <?> "
+#define RID_LLLINT_FROMTOX u"lllint from{<?>} to{<?>} <?> "
+#define RID_FROMX u"from{<?>} <?> "
+#define RID_TOX u"to{<?>} <?> "
+#define RID_FROMXTOY u"from{<?>} to{<?>} <?> "
+#define RID_ACUTEX u"acute <?> "
+#define RID_BARX u"bar <?> "
+#define RID_BREVEX u"breve <?> "
+#define RID_CHECKX u"check <?> "
+#define RID_CIRCLEX u"circle <?> "
+#define RID_DOTX u"dot <?> "
+#define RID_DDOTX u"ddot <?> "
+#define RID_DDDOTX u"dddot <?> "
+#define RID_GRAVEX u"grave <?> "
+#define RID_HATX u"hat <?> "
+#define RID_TILDEX u"tilde <?> "
+#define RID_VECX u"vec <?> "
+#define RID_HARPOONX u"harpoon <?> "
+#define RID_UNDERLINEX u"underline {<?>} "
+#define RID_OVERLINEX u"overline {<?>} "
+#define RID_OVERSTRIKEX u"overstrike {<?>} "
+#define RID_PHANTOMX u"phantom {<?>} "
+#define RID_BOLDX u"bold <?> "
+#define RID_ITALX u"ital <?> "
+#define RID_SIZEXY u"size <?> {<?>} "
+#define RID_FONTXY u"font <?> {<?>} "
+#define RID_COLORX_BLACK u"color black {<?>} "
+#define RID_COLORX_BLUE u"color blue {<?>} "
+#define RID_COLORX_GREEN u"color green {<?>} "
+#define RID_COLORX_RED u"color red {<?>} "
+#define RID_COLORX_AQUA u"color aqua {<?>} "
+#define RID_COLORX_FUCHSIA u"color fuchsia {<?>} "
+#define RID_COLORX_GRAY u"color gray {<?>} "
+#define RID_COLORX_LIME u"color lime {<?>} "
+#define RID_COLORX_MAROON u"color maroon {<?>} "
+#define RID_COLORX_NAVY u"color navy {<?>} "
+#define RID_COLORX_OLIVE u"color olive {<?>} "
+#define RID_COLORX_PURPLE u"color purple {<?>} "
+#define RID_COLORX_SILVER u"color silver {<?>} "
+#define RID_COLORX_TEAL u"color teal {<?>} "
+#define RID_COLORX_YELLOW u"color yellow {<?>} "
+#define RID_COLORX_RGB u"color rgb 0 0 0 {<?>} "
+#define RID_COLORX_RGBA u"color rgba 0 0 0 0 {<?>} "
+#define RID_COLORX_HEX u"color hex 000000 {<?>} "
+#define RID_COLORX_CORAL u"color coral {<?>} "
+#define RID_COLORX_CRIMSON u"color crimson {<?>} "
+#define RID_COLORX_MIDNIGHT u"color midnightblue {<?>} "
+#define RID_COLORX_VIOLET u"color violet {<?>} "
+#define RID_COLORX_ORANGE u"color orange {<?>} "
+#define RID_COLORX_ORANGERED u"color orangered {<?>} "
+#define RID_COLORX_SEAGREEN u"color seagreen {<?>} "
+#define RID_COLORX_INDIGO u"color indigo {<?>} "
+#define RID_COLORX_HOTPINK u"color hotpink {<?>} "
+#define RID_COLORX_LAVENDER u"color lavender {<?>} "
+#define RID_COLORX_SNOW u"color snow {<?>} "
+#define RID_LRGROUPX u"{<?>} "
+#define RID_LRPARENTX u"(<?>) "
+#define RID_LRBRACKETX u"[<?>] "
+#define RID_LRDBRACKETX u"ldbracket <?> rdbracket "
+#define RID_LRBRACEX u"lbrace <?> rbrace "
+#define RID_LRANGLEX u"langle <?> rangle "
+#define RID_LRCEILX u"lceil <?> rceil "
+#define RID_LRFLOORX u"lfloor <?> rfloor "
+#define RID_LRLINEX u"lline <?> rline "
+#define RID_LRDLINEX u"ldline <?> rdline "
+#define RID_LMRANGLEXY u"langle <?> mline <?> rangle "
+#define RID_SLRPARENTX u"left ( <?> right ) "
+#define RID_SLRBRACKETX u"left [ <?> right ] "
+#define RID_SLRDBRACKETX u"left ldbracket <?> right rdbracket "
+#define RID_SLRBRACEX u"left lbrace <?> right rbrace "
+#define RID_SLRANGLEX u"left langle <?> right rangle "
+#define RID_SLRCEILX u"left lceil <?> right rceil "
+#define RID_SLRFLOORX u"left lfloor <?> right rfloor "
+#define RID_SLRLINEX u"left lline <?> right rline "
+#define RID_SLRDLINEX u"left ldline <?> right rdline "
+#define RID_SLMRANGLEXY u"left langle <?> mline <?> right rangle "
+#define RID_XOVERBRACEY u"{<?>} overbrace {<?>} "
+#define RID_XUNDERBRACEY u"{<?>} underbrace {<?>} "
+#define RID_EVALX u"evaluate <?> "
+#define RID_EVAL_FROMX u"evaluate {<?>} from{<?>} "
+#define RID_EVAL_TOX u"evaluate {<?>} to{<?>} "
+#define RID_EVAL_FROMTOX u"evaluate {<?>} from{<?>} to{<?>} "
+#define RID_RSUBX u"<?>_{<?>} "
+#define RID_RSUPX u"<?>^{<?>} "
+#define RID_LSUBX u"<?> lsub{<?>} "
+#define RID_LSUPX u"<?> lsup{<?>} "
+#define RID_CSUBX u"<?> csub{<?>} "
+#define RID_CSUPX u"<?> csup{<?>} "
+#define RID_SBLANK u"` "
+#define RID_BLANK u"~ "
+#define RID_NEWLINE u"newline "
+#define RID_BINOMXY u"binom{<?>}{<?>} "
+#define RID_STACK u"stack{<?> # <?> # <?>} "
+#define RID_MATRIX u"matrix{<?> # <?> ## <?> # <?>} "
+#define RID_ALIGNLX u"alignl <?> "
+#define RID_ALIGNCX u"alignc <?> "
+#define RID_ALIGNRX u"alignr <?> "
+#define RID_ALEPH u"aleph "
+#define RID_EMPTYSET u"emptyset "
+#define RID_RE u"Re "
+#define RID_IM u"Im "
+#define RID_INFINITY u"infinity "
+#define RID_PARTIAL u"partial "
+#define RID_NABLA u"nabla "
+#define RID_WP u"wp "
+#define RID_LAPLACE u"laplace "
+#define RID_BACKEPSILON u"backepsilon "
+#define RID_FOURIER u"fourier "
+#define RID_DOTSAXIS u"dotsaxis "
+#define RID_DOTSUP u"dotsup "
+#define RID_DOTSDOWN u"dotsdown "
+#define RID_DOTSLOW u"dotslow "
+#define RID_DOTSVERT u"dotsvert "
+#define RID_XCIRCY u"<?> circ <?> "
+#define RID_XWIDESLASHY u"{<?>} wideslash {<?>} "
+#define RID_XWIDEBSLASHY u"{<?>} widebslash {<?>} "
+#define RID_XDIVIDESY u"<?> divides <?> "
+#define RID_XNDIVIDESY u"<?> ndivides <?> "
+#define RID_DLARROW u"<?> dlarrow <?> "
+#define RID_DLRARROW u"<?> dlrarrow <?> "
+#define RID_DRARROW u"<?> drarrow <?> "
+#define RID_SETN u"setN "
+#define RID_SETZ u"setZ "
+#define RID_SETQ u"setQ "
+#define RID_SETR u"setR "
+#define RID_SETC u"setC "
+#define RID_WIDEHATX u"widehat {<?>} "
+#define RID_WIDETILDEX u"widetilde {<?>} "
+#define RID_WIDEVECX u"widevec {<?>} "
+#define RID_WIDEHARPOONX u"wideharpoon {<?>} "
+#define RID_HBAR u"hbar "
+#define RID_LAMBDABAR u"lambdabar "
+#define RID_LEFTARROW u"leftarrow "
+#define RID_RIGHTARROW u"rightarrow "
+#define RID_UPARROW u"uparrow "
+#define RID_DOWNARROW u"downarrow "
+#define RID_NOSPACE u"nospace {<?>} "
+#define RID_XPRECEDESY u"<?> prec <?> "
+#define RID_XPRECEDESEQUALY u"<?> preccurlyeq <?> "
+#define RID_XPRECEDESEQUIVY u"<?> precsim <?> "
+#define RID_XSUCCEEDSY u"<?> succ <?> "
+#define RID_XSUCCEEDSEQUALY u"<?> succcurlyeq <?> "
+#define RID_XSUCCEEDSEQUIVY u"<?> succsim <?> "
+#define RID_XNOTPRECEDESY u"<?> nprec <?> "
+#define RID_XNOTSUCCEEDSY u"<?> nsucc <?> "
+#define RID_ARALOGX u"لو(<?>) "
+#define RID_ARASINX u"حا(<?>) "
+#define RID_ARACOSX u"حتا(<?>) "
+#define RID_ARATANX u"طا(<?>) "
+#define RID_ARACOTX u"طتا(<?>) "
+#define RID_ARASECX u"ٯا(<?>) "
+#define RID_ARACSCX u"ٯتا(<?>) "
+#define RID_ARASINHX u"حاز(<?>) "
+#define RID_ARACOSHX u"حتاز(<?>) "
+#define RID_ARATANHX u"طاز(<?>) "
+#define RID_ARACOTHX u"طتاز(<?>) "
+#define RID_ARASECHX u"ٯاز(<?>) "
+#define RID_ARACSCHX u"ٯتاز(<?>) "
+#define RID_ARASIN2X u"جا(<?>) "
+#define RID_ARACOS2X u"جتا(<?>) "
+#define RID_ARATAN2X u"ظا(<?>) "
+#define RID_ARACOT2X u"ظتا(<?>) "
+#define RID_ARASEC2X u"قا(<?>) "
+#define RID_ARACSC2X u"قتا(<?>) "
+#define RID_ARASINH2X u"جاز(<?>) "
+#define RID_ARACOSH2X u"جتاز(<?>) "
+#define RID_ARATANH2X u"ظاز(<?>) "
+#define RID_ARACOTH2X u"ظتاز(<?>) "
+#define RID_ARASECH2X u"قاز(<?>) "
+#define RID_ARACSCH2X u"قتاز(<?>) "
+// clang-format on
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/starmath/inc/symbol.hxx b/starmath/inc/symbol.hxx
new file mode 100644
index 0000000000..f337a0dfac
--- /dev/null
+++ b/starmath/inc/symbol.hxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** This stuff is used to work with %charname.
+ *
+ * Will remember the char name, char code and font.
+ */
+
+#pragma once
+
+#include <map>
+#include <vector>
+#include <set>
+
+#include "format.hxx"
+#include "utility.hxx"
+
+
+#define SYMBOL_NONE 0xFFFF
+
+class SmSym
+{
+private:
+ SmFace m_aFace;
+ OUString m_aUiName;
+ OUString m_aExportName;
+ OUString m_aSetName;
+ sal_UCS4 m_cChar;
+ bool m_bPredefined;
+
+public:
+ SmSym();
+ SmSym(const OUString& rName, const vcl::Font& rFont, sal_UCS4 cChar,
+ const OUString& rSet, bool bIsPredefined = false);
+ SmSym(const SmSym& rSymbol);
+
+ SmSym& operator = (const SmSym& rSymbol);
+
+ const vcl::Font& GetFace(const SmFormat* pFormat = nullptr) const;
+ sal_UCS4 GetCharacter() const { return m_cChar; }
+ const OUString& GetUiName() const { return m_aUiName; }
+
+ bool IsPredefined() const { return m_bPredefined; }
+ const OUString& GetSymbolSetName() const { return m_aSetName; }
+ const OUString& GetExportName() const { return m_aExportName; }
+ void SetExportName( const OUString &rName ) { m_aExportName = rName; }
+
+ // true if rSymbol has the same name, font and character
+ bool IsEqualInUI( const SmSym& rSymbol ) const;
+};
+
+// type of the actual container to hold the symbols
+typedef std::map< OUString, SmSym > SymbolMap_t;
+
+// vector of pointers to the actual symbols in the above container
+typedef std::vector< const SmSym * > SymbolPtrVec_t;
+
+
+class SmSymbolManager
+{
+private:
+ SymbolMap_t m_aSymbols;
+ bool m_bModified;
+
+public:
+ SmSymbolManager();
+ SmSymbolManager(const SmSymbolManager& rSymbolSetManager);
+ ~SmSymbolManager();
+
+ SmSymbolManager & operator = (const SmSymbolManager& rSymbolSetManager);
+
+ // symbol sets are for UI purpose only, thus we assemble them here
+ std::set< OUString > GetSymbolSetNames() const;
+ SymbolPtrVec_t GetSymbolSet( std::u16string_view rSymbolSetName );
+
+ SymbolPtrVec_t GetSymbols() const;
+ bool AddOrReplaceSymbol( const SmSym & rSymbol, bool bForceChange = false );
+ void RemoveSymbol( const OUString & rSymbolName );
+
+ SmSym* GetSymbolByName(std::u16string_view rSymbolName);
+ SmSym* GetSymbolByUiName(std::u16string_view rSymbolName);
+ SmSym* GetSymbolByExportName(std::u16string_view rSymbolName);
+
+ bool IsModified() const { return m_bModified; }
+ void SetModified(bool bModify) { m_bModified = bModify; }
+
+ void Load();
+ void Save();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/token.hxx b/starmath/inc/token.hxx
new file mode 100644
index 0000000000..e22b8cdc1d
--- /dev/null
+++ b/starmath/inc/token.hxx
@@ -0,0 +1,289 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+/** The tokens contain the information gathered by the parser.
+ *
+ * They contain:
+ * the data type (~ mathematical operation).
+ * The mathematical char.
+ * The corresponding code or information to recreate it.
+ * Location of the token in the starmath code.
+ */
+
+#pragma once
+
+#include <tools/color.hxx>
+#include <o3tl/string_view.hxx>
+#include <o3tl/typed_flags_set.hxx>
+
+// std imports
+#include <memory>
+#include <utility>
+
+// TokenGroups
+enum class TG
+{
+ NONE = 0x000000,
+ Oper = 0x000001,
+ Relation = 0x000002,
+ Sum = 0x000004,
+ Product = 0x000008,
+ UnOper = 0x000010,
+ Power = 0x000020,
+ Attribute = 0x000040,
+ Align = 0x000080,
+ Function = 0x000100,
+ Blank = 0x000200,
+ LBrace = 0x000400,
+ RBrace = 0x000800,
+ Color = 0x001000,
+ Font = 0x002000,
+ Standalone = 0x004000,
+ Limit = 0x010000,
+ FontAttr = 0x020000
+};
+
+namespace o3tl
+{
+template <> struct typed_flags<TG> : is_typed_flags<TG, 0x037fff>
+{
+};
+}
+
+// Tokens identifiers. Allow to know what kind of information the node contains.
+enum SmTokenType
+{
+ // clang-format off
+ // Uncategorized
+ TEND, TSPECIAL, TNONE, TESCAPE, TUNKNOWN,
+ TBLANK, TSBLANK, TPLACE, TNOSPACE, TDOTSDOWN,
+ TNEWLINE, TDOTSAXIS, TDOTSLOW, TDOTSVERT, TBACKEPSILON,
+ TDOTSDIAG, TDOTSUP, TERROR,
+ // Basic
+ TPLUS, TMINUS, TMULTIPLY, TDIVIDEBY, // +-*/
+ TGT, TLT, TGE, TLE, // > < >= <=
+ TASSIGN, TNEQ, TGG, TLL, // = != >>> <<<
+ TPARALLEL, TORTHO, TEQUIV, // Geometry
+ TOPER, TSUM, TPROD, TCOPROD, // Operators
+ TIM, TRE, THBAR, TLAMBDABAR, // Complex and constants
+ TPLUSMINUS, TMINUSPLUS, TSIM, TSIMEQ, // +- -+ ~ ~=
+ TLIM, TLIMSUP, TLIMINF, TTOWARD, // Limits
+ THADD, TNAHA,
+ TOVER, TTIMES, TCDOT, TDIV, // Product type
+ TSLASH, TBACKSLASH, TWIDESLASH, TWIDEBACKSLASH, //Slash
+ TFRAC, TIT, // mathml related
+ // Structure
+ TMATRIX, TPOUND, TDPOUND, TSTACK, TBINOM,
+ // Logic
+ TAND, TOR, TNEG, // && || !
+ TPRECEDES, TSUCCEEDS, TNOTPRECEDES, TNOTSUCCEEDS, // Order
+ TPRECEDESEQUAL, TSUCCEEDSEQUAL, TPRECEDESEQUIV, TSUCCEEDSEQUIV, // Order eq
+ TLEFTARROW, TRIGHTARROW, TUPARROW, TDOWNARROW, // Arrows
+ TDRARROW, TDLARROW, TDLRARROW, TDEF, // Double arrows, definition
+ TPROP, TNDIVIDES, TDIVIDES, TAPPROX, // Proportions, approximation
+ TLESLANT, TGESLANT, TTRANSL, TTRANSR, // <= >= corresponds
+ // Tensors
+ TOPLUS, TOMINUS, TOTIMES, TODIVIDE, TODOT,
+ TCIRC,
+ // Positions
+ TRSUB, TRSUP, TCSUB, TCSUP, TLSUB,
+ TLSUP, TFROM, TTO, TUOPER, TBOPER,
+ // Set theory
+ TSETN, TSETZ, TSETQ, TSETR, TSETC,
+ TIN, TNOTIN, TNI, TEMPTYSET, // Insideout
+ TSUBSET, TSUBSETEQ, TSUPSET, TSUPSETEQ, // Subsupset
+ TNSUBSET, TNSUPSET, TNSUBSETEQ, TNSUPSETEQ, // Not subsupset
+ TINTERSECT, TUNION, TSETMINUS, TSETQUOTIENT, // +-/
+ TALEPH, TWP, TINFINITY, // Abstract sets
+ TFORALL, TEXISTS, TNOTEXISTS, // Existential
+ // Font
+ TFONT, TSIZE, TCOLOR, TPHANTOM, // Basic
+ TITALIC, TNITALIC, TBOLD, TNBOLD, // Bold ital
+ TALIGNL, TALIGNC, TALIGNR, // Align
+ TUNDERLINE, TOVERLINE, TOVERSTRIKE, TBAR, // Lines
+ TFIXED, TSANS, TSERIF, // Types
+ TACUTE, TGRAVE, THAT, TBREVE, // Accents
+ TWIDEVEC, TWIDEHARPOON, TWIDETILDE, TWIDEHAT, // Wide math
+ TVEC, THARPOON, TTILDE, TCIRCLE, // math
+ TCHECK,
+ TTEXT, TNUMBER, TCHARACTER, TIDENT, // Content type
+ // Brackets
+ TLEFT, TRIGHT, TUNDERBRACE, TOVERBRACE, // Scalable, upsidedown
+ TLGROUP, TRGROUP, TLPARENT, TRPARENT, // Structural
+ TLBRACKET, TRBRACKET, TLDBRACKET, TRDBRACKET, // Bracket x1 & x2
+ TLCEIL, TRCEIL, TLFLOOR, TRFLOOR, // Reals -> Wholes
+ TLANGLE, TRANGLE, TLBRACE, TRBRACE, // <x> {x}
+ TLLINE, TRLINE, TLDLINE, TRDLINE, // Lines x1 x2
+ TMLINE, TEVALUATE, TLRLINE, TLRDLINE, // Custom
+ // Differential calculus
+ TNABLA, TPARTIAL, TFOURIER, TLAPLACE, // Derivative, Transformation
+ TINTD, TINT, TIINT, TIIINT, // Integral
+ TLINT, TLLINT, TLLLINT, // Circuit integral
+ TDOT, TDDOT, TDDDOT, // Derivative dots
+ // Function
+ TFUNC, TLN, TLOG, TEXP, // Exp - Log
+ TSIN, TCOS, TTAN, TCOT, // Trigo
+ TSEC, TCSC, TSECH, TCSCH,
+ TSINH, TCOSH, TTANH, TCOTH, // Trigo hyperbolic
+ TASIN, TACOS, TATAN, TACOT, // Arctrigo
+ TASINH, TACOSH, TATANH, TACOTH, // Arctrigo hyperbolic
+ TSQRT, TNROOT, TFACT, TABS, // roots, n! |z|
+ // Color
+ TRGB, TRGBA, THEX, THTMLCOL, TDVIPSNAMESCOL,
+ TICONICCOL, TMATHMLCOL
+ // clang-format on
+};
+
+struct SmTokenTableEntry
+{
+ OUString aIdent;
+ SmTokenType eType;
+ sal_uInt32 cMathChar;
+ TG nGroup;
+ sal_uInt16 nLevel;
+};
+
+struct SmColorTokenTableEntry
+{
+ OUString aIdent;
+ SmTokenType eType;
+ Color cColor;
+
+ SmColorTokenTableEntry()
+ : eType(TERROR)
+ , cColor()
+ {
+ }
+
+ SmColorTokenTableEntry(const SmColorTokenTableEntry* amColorTokenTableEntry)
+ : aIdent(amColorTokenTableEntry->aIdent)
+ , eType(amColorTokenTableEntry->eType)
+ , cColor(amColorTokenTableEntry->cColor)
+ {
+ }
+
+ SmColorTokenTableEntry(const std::unique_ptr<SmColorTokenTableEntry> amColorTokenTableEntry)
+ : aIdent(amColorTokenTableEntry->aIdent)
+ , eType(amColorTokenTableEntry->eType)
+ , cColor(amColorTokenTableEntry->cColor)
+ {
+ }
+
+ SmColorTokenTableEntry(OUString name, SmTokenType ctype, Color ncolor)
+ : aIdent(std::move(name))
+ , eType(ctype)
+ , cColor(ncolor)
+ {
+ }
+
+ SmColorTokenTableEntry(OUString name, SmTokenType ctype, sal_uInt32 ncolor)
+ : aIdent(std::move(name))
+ , eType(ctype)
+ , cColor(ColorTransparency, ncolor)
+ {
+ }
+
+ bool equals(std::u16string_view colorname) const
+ {
+ return o3tl::compareToIgnoreAsciiCase(colorname, aIdent) == 0;
+ }
+
+ bool equals(sal_uInt32 colorcode) const { return colorcode == static_cast<sal_uInt32>(cColor); }
+
+ bool equals(Color colorcode) const { return colorcode == cColor; }
+};
+
+struct SmToken
+{
+ OUString aText; // token text
+ SmTokenType eType; // token info
+ OUString cMathChar;
+
+ // parse-help info
+ TG nGroup;
+ sal_uInt16 nLevel;
+
+ SmToken()
+ : eType(TUNKNOWN)
+ , cMathChar('\0')
+ , nGroup(TG::NONE)
+ , nLevel(0)
+ {
+ }
+
+ SmToken(SmTokenType eTokenType, sal_uInt32 cMath, OUString rText, TG nTokenGroup = TG::NONE,
+ sal_uInt16 nTokenLevel = 0)
+ : aText(std::move(rText))
+ , eType(eTokenType)
+ , cMathChar(&cMath, 1)
+ , nGroup(nTokenGroup)
+ , nLevel(nTokenLevel)
+ {
+ }
+
+ void operator=(const SmTokenTableEntry& aTokenTableEntry)
+ {
+ aText = aTokenTableEntry.aIdent;
+ eType = aTokenTableEntry.eType;
+ cMathChar = OUString(&aTokenTableEntry.cMathChar, 1);
+ nGroup = aTokenTableEntry.nGroup;
+ nLevel = aTokenTableEntry.nLevel;
+ }
+
+ void operator=(const SmTokenTableEntry* aTokenTableEntry)
+ {
+ aText = aTokenTableEntry->aIdent;
+ eType = aTokenTableEntry->eType;
+ cMathChar = OUString(&aTokenTableEntry->cMathChar, 1);
+ nGroup = aTokenTableEntry->nGroup;
+ nLevel = aTokenTableEntry->nLevel;
+ }
+
+ void operator=(const SmColorTokenTableEntry& aTokenTableEntry)
+ {
+ aText = u""_ustr;
+ eType = aTokenTableEntry.eType;
+ cMathChar = OUString::number(static_cast<sal_uInt32>(aTokenTableEntry.cColor), 16);
+ nGroup = TG::Color;
+ nLevel = 0;
+ }
+
+ void operator=(const SmColorTokenTableEntry* aTokenTableEntry)
+ {
+ aText = u""_ustr;
+ eType = aTokenTableEntry->eType;
+ cMathChar = OUString::number(static_cast<sal_uInt32>(aTokenTableEntry->cColor), 16);
+ nGroup = TG::Color;
+ nLevel = 0;
+ }
+
+ void operator=(const std::unique_ptr<SmColorTokenTableEntry>& aTokenTableEntry)
+ {
+ aText = u""_ustr;
+ eType = aTokenTableEntry->eType;
+ cMathChar = OUString::number(static_cast<sal_uInt32>(aTokenTableEntry->cColor), 16);
+ nGroup = TG::Color;
+ nLevel = 0;
+ }
+
+ void setChar(sal_uInt32 cChar) { cMathChar = OUString(&cChar, 1); }
+ void setChar(const OUString& rText) { cMathChar = rText; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/types.hxx b/starmath/inc/types.hxx
new file mode 100644
index 0000000000..f9267e0d04
--- /dev/null
+++ b/starmath/inc/types.hxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+
+inline constexpr OUString FONTNAME_MATH = u"OpenSymbol"_ustr;
+
+enum SmPrintSize
+{
+ PRINT_SIZE_NORMAL,
+ PRINT_SIZE_SCALED,
+ PRINT_SIZE_ZOOMED
+};
+
+// definitions for characters from the 'StarSymbol' font
+// (some chars have more than one alias!)
+//! Note: not listed here does not(!) mean "not used"
+//! (see %alpha ... %gamma for example)
+
+sal_Unicode const MS_NONE = '\0';
+sal_Unicode const MS_NULLCHAR = '\0';
+sal_Unicode const MS_FACT = 0x0021;
+sal_Unicode const MS_INFINITY = 0x221E;
+sal_Unicode const MS_SLASH = 0x002F;
+
+sal_Unicode const MS_NDIVIDES = 0x2224;
+sal_Unicode const MS_DRARROW = 0x21D2;
+sal_Unicode const MS_DLARROW = 0x21D0;
+sal_Unicode const MS_DLRARROW = 0x21D4;
+sal_Unicode const MS_OVERBRACE = 0x23DE;
+sal_Unicode const MS_UNDERBRACE = 0x23DF;
+sal_Unicode const MS_CIRC = 0x2218;
+sal_Unicode const MS_ASSIGN = 0x003D;
+sal_Unicode const MS_ERROR = 0x00BF;
+
+sal_Unicode const MS_NEQ = 0x2260;
+sal_Unicode const MS_PLUS = 0x002B;
+sal_Unicode const MS_MINUS = 0x2212;
+sal_Unicode const MS_MULTIPLY = 0x2217;
+sal_Unicode const MS_TIMES = 0x00D7;
+sal_Unicode const MS_CDOT = 0x22C5;
+sal_Unicode const MS_DIV = 0x00F7;
+sal_Unicode const MS_PLUSMINUS = 0x00B1;
+sal_Unicode const MS_MINUSPLUS = 0x2213;
+sal_Unicode const MS_OPLUS = 0x2295;
+sal_Unicode const MS_OMINUS = 0x2296;
+sal_Unicode const MS_OTIMES = 0x2297;
+sal_Unicode const MS_ODIVIDE = 0x2298;
+sal_Unicode const MS_ODOT = 0x2299;
+sal_Unicode const MS_UNION = 0x222A;
+sal_Unicode const MS_INTERSECT = 0x2229;
+
+sal_Unicode const MS_LT = 0x003C;
+sal_Unicode const MS_GT = 0x003E;
+sal_Unicode const MS_LE = 0x2264;
+sal_Unicode const MS_GE = 0x2265;
+sal_Unicode const MS_LESLANT = 0x2A7D;
+sal_Unicode const MS_GESLANT = 0x2A7E;
+sal_Unicode const MS_LL = 0x226A;
+sal_Unicode const MS_GG = 0x226B;
+sal_Unicode const MS_SIM = 0x223C;
+sal_Unicode const MS_SIMEQ = 0x2243;
+sal_Unicode const MS_APPROX = 0x2248;
+sal_Unicode const MS_DEF = 0x225D;
+sal_Unicode const MS_EQUIV = 0x2261;
+sal_Unicode const MS_PROP = 0x221D;
+sal_Unicode const MS_PARTIAL = 0x2202;
+sal_Unicode const MS_LAPLACE = 0x2112;
+sal_Unicode const MS_FOURIER = 0x2131;
+
+sal_Unicode const MS_SUBSET = 0x2282;
+sal_Unicode const MS_SUPSET = 0x2283;
+sal_Unicode const MS_SUBSETEQ = 0x2286;
+sal_Unicode const MS_SUPSETEQ = 0x2287;
+sal_Unicode const MS_NSUBSET = 0x2284;
+sal_Unicode const MS_NSUPSET = 0x2285;
+sal_Unicode const MS_NSUBSETEQ = 0x2288;
+sal_Unicode const MS_NSUPSETEQ = 0x2289;
+sal_Unicode const MS_IN = 0x2208;
+sal_Unicode const MS_NOTIN = 0x2209;
+sal_Unicode const MS_EXISTS = 0x2203;
+sal_Unicode const MS_NOTEXISTS = 0x2204;
+sal_Unicode const MS_BACKEPSILON = 0x220D;
+sal_Unicode const MS_ALEPH = 0x2135;
+sal_Unicode const MS_IM = 0x2111;
+sal_Unicode const MS_RE = 0x211C;
+sal_Unicode const MS_WP = 0x2118;
+
+sal_Unicode const MS_LINE = 0x2223;
+sal_Unicode const MS_VERTLINE = 0x007C;
+sal_Unicode const MS_DLINE = 0x2225;
+sal_Unicode const MS_DVERTLINE = 0x2016;
+sal_Unicode const MS_ORTHO = 0x22A5;
+sal_Unicode const MS_DOTSLOW = 0x2026;
+sal_Unicode const MS_DOTSAXIS = 0x22EF;
+sal_Unicode const MS_DOTSVERT = 0x22EE;
+sal_Unicode const MS_DOTSUP = 0x22F0;
+sal_Unicode const MS_DOTSDOWN = 0x22F1;
+sal_Unicode const MS_TRANSR = 0x22B6;
+sal_Unicode const MS_TRANSL = 0x22B7;
+sal_Unicode const MS_BACKSLASH = 0x2216;
+sal_Unicode const MS_NEG = 0x00AC;
+
+sal_Unicode const MS_FORALL = 0x2200;
+sal_Unicode const MS_NABLA = 0x2207;
+sal_Unicode const MS_PROD = 0x220F;
+sal_Unicode const MS_COPROD = 0x2210;
+sal_Unicode const MS_SUM = 0x2211;
+sal_uInt32 const MS_MAJ = 0x1EEF0;
+sal_uInt32 const MS_HADD = 0x1EEF1;
+sal_Unicode const MS_SQRT = 0x221A;
+sal_Unicode const MS_INT = 0x222B;
+sal_Unicode const MS_IINT = 0x222C;
+sal_Unicode const MS_IIINT = 0x222D;
+sal_Unicode const MS_LINT = 0x222E;
+sal_Unicode const MS_LLINT = 0x222F;
+sal_Unicode const MS_LLLINT = 0x2230;
+
+sal_Unicode const MS_GRAVE = 0x0060;
+sal_Unicode const MS_COMBGRAVE = 0x0300;
+sal_Unicode const MS_ACUTE = 0x00B4;
+sal_Unicode const MS_COMBACUTE = 0x0301;
+sal_Unicode const MS_HAT = 0x005E;
+sal_Unicode const MS_COMBHAT = 0x0302;
+sal_Unicode const MS_TILDE = 0x007E;
+sal_Unicode const MS_COMBTILDE = 0x0303;
+sal_Unicode const MS_BAR = 0x00AF;
+sal_Unicode const MS_COMBBAR = 0x0304;
+sal_Unicode const MS_COMBOVERLINE = 0x0305;
+sal_Unicode const MS_BREVE = 0x02D8;
+sal_Unicode const MS_COMBBREVE = 0x0306;
+sal_Unicode const MS_CIRCLE = 0x02DA;
+sal_Unicode const MS_COMBCIRCLE = 0x030A;
+sal_Unicode const MS_CHECK = 0x02C7;
+sal_Unicode const MS_COMBCHECK = 0x030C;
+sal_Unicode const MS_HARPOON = 0x20D1;
+sal_Unicode const MS_VEC = 0x20D7;
+sal_Unicode const MS_DOT = 0x02D9;
+sal_Unicode const MS_DDOT = 0x00A8;
+sal_Unicode const MS_COMBDOT = 0x0307;
+sal_Unicode const MS_COMBDDOT = 0x0308;
+sal_Unicode const MS_DDDOT = 0x20DB;
+sal_Unicode const MS_AND = 0x2227;
+sal_Unicode const MS_OR = 0x2228;
+sal_Unicode const MS_NI = 0x220B;
+sal_Unicode const MS_EMPTYSET = 0x2205;
+
+sal_Unicode const MS_LPARENT = 0x0028;
+sal_Unicode const MS_RPARENT = 0x0029;
+sal_Unicode const MS_LBRACKET = 0x005B;
+sal_Unicode const MS_RBRACKET = 0x005D;
+sal_Unicode const MS_LBRACE = 0x007B;
+sal_Unicode const MS_RBRACE = 0x007D;
+sal_Unicode const MS_LCEIL = 0x2308;
+sal_Unicode const MS_RCEIL = 0x2309;
+sal_Unicode const MS_LFLOOR = 0x230A;
+sal_Unicode const MS_RFLOOR = 0x230B;
+sal_Unicode const MS_LANGLE = 0x2329;
+sal_Unicode const MS_RANGLE = 0x232A;
+sal_Unicode const MS_LDBRACKET = 0x27E6;
+sal_Unicode const MS_RDBRACKET = 0x27E7;
+sal_Unicode const MS_LMATHANGLE = 0x27E8;
+sal_Unicode const MS_RMATHANGLE = 0x27E9;
+
+sal_Unicode const MS_PLACE = 0x2751;
+
+sal_Unicode const MS_LAMBDABAR = 0x019B;
+sal_Unicode const MS_HBAR = 0x210F;
+sal_Unicode const MS_LEFTARROW = 0x2190;
+sal_Unicode const MS_UPARROW = 0x2191;
+sal_Unicode const MS_RIGHTARROW = 0x2192;
+sal_Unicode const MS_DOWNARROW = 0x2193;
+
+sal_Unicode const MS_SETN = 0x2115;
+sal_Unicode const MS_SETZ = 0x2124;
+sal_Unicode const MS_SETQ = 0x211A;
+sal_Unicode const MS_SETR = 0x211D;
+sal_Unicode const MS_SETC = 0x2102;
+
+sal_Unicode const MS_PERCENT = 0x0025;
+
+sal_Unicode const MS_PRECEDES = 0x227A;
+sal_Unicode const MS_PRECEDESEQUAL = 0x227C;
+sal_Unicode const MS_PRECEDESEQUIV = 0x227E;
+sal_Unicode const MS_SUCCEEDS = 0x227B;
+sal_Unicode const MS_SUCCEEDSEQUAL = 0x227D;
+sal_Unicode const MS_SUCCEEDSEQUIV = 0x227F;
+sal_Unicode const MS_NOTPRECEDES = 0x2280;
+sal_Unicode const MS_NOTSUCCEEDS = 0x2281;
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/unomodel.hxx b/starmath/inc/unomodel.hxx
new file mode 100644
index 0000000000..b16d69ee66
--- /dev/null
+++ b/starmath/inc/unomodel.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/view/XRenderable.hpp>
+
+#include <sfx2/sfxbasemodel.hxx>
+#include <comphelper/propertysethelper.hxx>
+#include <vcl/print.hxx>
+#include <oox/mathml/imexport.hxx>
+
+#include "format.hxx"
+
+inline constexpr OUString PRTUIOPT_TITLE_ROW = u"TitleRow"_ustr;
+inline constexpr OUString PRTUIOPT_FORMULA_TEXT = u"FormulaText"_ustr;
+inline constexpr OUString PRTUIOPT_BORDER = u"Border"_ustr;
+inline constexpr OUString PRTUIOPT_PRINT_FORMAT = u"PrintFormat"_ustr;
+inline constexpr OUString PRTUIOPT_PRINT_SCALE = u"PrintScale"_ustr;
+
+class SmPrintUIOptions : public vcl::PrinterOptionsHelper
+{
+public:
+ SmPrintUIOptions();
+};
+
+
+class SmModel final : public SfxBaseModel,
+ public comphelper::PropertySetHelper,
+ public css::lang::XServiceInfo,
+ public css::view::XRenderable,
+ public oox::FormulaImExportBase
+{
+ std::unique_ptr<SmPrintUIOptions> m_pPrintUIOptions;
+
+ SmFace maFonts[FNT_END + 1];
+
+ virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const css::uno::Any* pValues ) override;
+ virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, css::uno::Any* pValue ) override;
+public:
+ explicit SmModel( SfxObjectShell *pObjSh );
+ virtual ~SmModel() noexcept override;
+
+ //XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) override;
+ virtual void SAL_CALL acquire( ) noexcept override;
+ virtual void SAL_CALL release( ) noexcept override;
+
+ //XTypeProvider
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
+
+ static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId();
+
+ //XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& aIdentifier ) override;
+
+ //XRenderable
+ virtual sal_Int32 SAL_CALL getRendererCount( const css::uno::Any& rSelection, const css::uno::Sequence< css::beans::PropertyValue >& rxOptions ) override;
+ virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRenderer( sal_Int32 nRenderer, const css::uno::Any& rSelection, const css::uno::Sequence< css::beans::PropertyValue >& rxOptions ) override;
+ virtual void SAL_CALL render( sal_Int32 nRenderer, const css::uno::Any& rSelection, const css::uno::Sequence< css::beans::PropertyValue >& rxOptions ) override;
+
+ //XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() override;
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
+
+ virtual void SAL_CALL setParent( const css::uno::Reference< css::uno::XInterface >& xParent ) override;
+
+ // oox::FormulaImExportBase
+ virtual void writeFormulaOoxml(::sax_fastparser::FSHelperPtr pSerializer,
+ oox::core::OoxmlVersion version,
+ oox::drawingml::DocumentType documentType, sal_Int8 nAlign) override;
+ virtual void writeFormulaRtf(OStringBuffer& rBuffer, rtl_TextEncoding nEncoding) override;
+ virtual void readFormulaOoxml( oox::formulaimport::XmlStream& stream ) override;
+ virtual Size getFormulaSize() const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/utility.hxx b/starmath/inc/utility.hxx
new file mode 100644
index 0000000000..feaae1fedb
--- /dev/null
+++ b/starmath/inc/utility.hxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+#include "smdllapi.hxx"
+
+#include <o3tl/unit_conversion.hxx>
+#include <sal/log.hxx>
+#include <vcl/font.hxx>
+#include <vcl/weld.hxx>
+#include <tools/fract.hxx>
+#include <tools/mapunit.hxx>
+#include <deque>
+
+
+class SmViewShell;
+SmViewShell * SmGetActiveView();
+
+
+// SmFace
+
+
+bool IsItalic( const vcl::Font &rFont );
+bool IsBold( const vcl::Font &rFont );
+
+class SM_DLLPUBLIC SmFace final : public vcl::Font
+{
+ tools::Long nBorderWidth;
+
+ void Impl_Init();
+
+public:
+ SmFace() :
+ Font(), nBorderWidth(-1) { Impl_Init(); }
+ SmFace(const Font& rFont) :
+ Font(rFont), nBorderWidth(-1) { Impl_Init(); }
+ SmFace(const OUString& rName, const Size& rSize) :
+ Font(rName, rSize), nBorderWidth(-1) { Impl_Init(); }
+
+ SmFace(const SmFace &rFace) :
+ Font(rFace), nBorderWidth(-1) { Impl_Init(); }
+
+ // overloaded version in order to supply a min value
+ // for font size (height). (Also used in ctor's to do so.)
+ void SetSize(const Size& rSize);
+
+ void SetBorderWidth(tools::Long nWidth) { nBorderWidth = nWidth; }
+ tools::Long GetBorderWidth() const;
+ tools::Long GetDefaultBorderWidth() const { return GetFontSize().Height() / 20 ; }
+ void FreezeBorderWidth() { nBorderWidth = GetDefaultBorderWidth(); }
+
+ SmFace & operator = (const SmFace &rFace);
+};
+
+SmFace & operator *= (SmFace &rFace, const Fraction &rFrac);
+
+
+// SmFontPickList
+
+
+class SmFontDialog;
+
+class SmFontPickList
+{
+protected:
+ sal_uInt16 nMaxItems;
+ std::deque<vcl::Font> aFontVec;
+
+public:
+ explicit SmFontPickList(sal_uInt16 nMax = 5) : nMaxItems(nMax) {}
+ virtual ~SmFontPickList() { Clear(); }
+
+ virtual void Insert(const vcl::Font &rFont);
+
+ void Clear();
+ vcl::Font Get(sal_uInt16 nPos = 0) const;
+
+ SmFontPickList& operator = (const SmFontPickList& rList);
+
+ void ReadFrom(const SmFontDialog& rDialog);
+ void WriteTo(SmFontDialog& rDialog) const;
+};
+
+
+// SmFontPickListBox
+
+
+class SmFontPickListBox final : public SmFontPickList
+{
+private:
+ std::unique_ptr<weld::ComboBox> m_xWidget;
+
+ DECL_LINK(SelectHdl, weld::ComboBox&, void);
+
+public:
+ SmFontPickListBox(std::unique_ptr<weld::ComboBox> pWidget);
+ SmFontPickListBox& operator = (const SmFontPickList& rList);
+ virtual void Insert(const vcl::Font &rFont) override;
+};
+
+// Math used to use 100ths of MM by default, but now uses twips
+// which seems to improve (subpixel) positioning.
+inline MapUnit SmMapUnit()
+{
+ return MapUnit::MapTwip;
+}
+inline o3tl::Length SmO3tlLengthUnit()
+{
+ return o3tl::Length::twip;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/view.hxx b/starmath/inc/view.hxx
new file mode 100644
index 0000000000..03f67fdbed
--- /dev/null
+++ b/starmath/inc/view.hxx
@@ -0,0 +1,333 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+#include <rtl/ref.hxx>
+#include <sfx2/docinsert.hxx>
+#include <sfx2/dockwin.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/ctrlitem.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/InterimItemWindow.hxx>
+#include <vcl/timer.hxx>
+#include "document.hxx"
+#include "edit.hxx"
+
+class SmViewShell;
+class SmPrintUIOptions;
+class SmGraphicAccessible;
+class SmGraphicWidget;
+
+constexpr sal_uInt16 MINZOOM = 25;
+constexpr sal_uInt16 MAXZOOM = 800;
+
+class SmGraphicWindow final : public InterimItemWindow
+{
+private:
+ Point aPixOffset; // offset to virtual window (pixel)
+ Size aTotPixSz; // total size of virtual window (pixel)
+ tools::Long nLinePixH; // size of a line/column (pixel)
+ tools::Long nColumnPixW;
+ sal_uInt16 nZoom;
+
+ std::unique_ptr<weld::ScrolledWindow> mxScrolledWindow;
+ std::unique_ptr<SmGraphicWidget> mxGraphic;
+ std::unique_ptr<weld::CustomWeld> mxGraphicWin;
+
+ DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);
+
+public:
+ explicit SmGraphicWindow(SmViewShell& rShell);
+ virtual void dispose() override;
+ virtual ~SmGraphicWindow() override;
+
+ virtual bool IsStarMath() const override { return true; }
+
+ void SetTotalSize(const Size& rNewSize);
+ Size GetTotalSize() const;
+
+ void SetZoom(sal_uInt16 Factor);
+ sal_uInt16 GetZoom() const { return nZoom; }
+
+ void ZoomToFitInWindow();
+
+ virtual void Resize() override;
+ void ShowContextMenu(const CommandEvent& rCEvt);
+
+ void SetGraphicMapMode(const MapMode& rNewMapMode);
+ MapMode GetGraphicMapMode() const;
+
+ SmGraphicWidget& GetGraphicWidget()
+ {
+ return *mxGraphic;
+ }
+
+ const SmGraphicWidget& GetGraphicWidget() const
+ {
+ return *mxGraphic;
+ }
+};
+
+class SmGraphicWidget final : public weld::CustomWidgetController
+{
+public:
+ bool IsCursorVisible() const
+ {
+ return bIsCursorVisible;
+ }
+ void ShowCursor(bool bShow);
+ bool IsLineVisible() const
+ {
+ return bIsLineVisible;
+ }
+ void ShowLine(bool bShow);
+ const SmNode * SetCursorPos(sal_uInt16 nRow, sal_uInt16 nCol);
+
+ explicit SmGraphicWidget(SmViewShell& rShell, SmGraphicWindow& rGraphicWindow);
+ virtual ~SmGraphicWidget() override;
+
+ // CustomWidgetController
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ virtual bool MouseButtonDown(const MouseEvent &rMEvt) override;
+ virtual bool MouseMove(const MouseEvent &rMEvt) override;
+ virtual void GetFocus() override;
+ virtual void LoseFocus() override;
+ virtual bool KeyInput(const KeyEvent& rKEvt) override;
+
+ void SetTotalSize();
+
+ SmViewShell& GetView() { return mrViewShell; }
+ SmDocShell* GetDoc();
+ SmCursor& GetCursor();
+
+ const Point& GetFormulaDrawPos() const
+ {
+ return aFormulaDrawPos;
+ }
+
+ // for Accessibility
+ virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
+
+ SmGraphicAccessible* GetAccessible_Impl()
+ {
+ return mxAccessible.get();
+ }
+
+ OutputDevice& GetOutputDevice()
+ {
+ assert(GetDrawingArea());
+ return GetDrawingArea()->get_ref_device();
+ }
+
+private:
+ void SetIsCursorVisible(bool bVis);
+ void SetCursor(const SmNode *pNode);
+ void SetCursor(const tools::Rectangle &rRect);
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual bool Command(const CommandEvent& rCEvt) override;
+
+ void RepaintViewShellDoc();
+ DECL_LINK(CaretBlinkTimerHdl, Timer *, void);
+ void CaretBlinkInit();
+ void CaretBlinkStart();
+ void CaretBlinkStop();
+
+ SmGraphicWindow& mrGraphicWindow;
+
+ Point aFormulaDrawPos;
+ // old style editing pieces
+ tools::Rectangle aCursorRect;
+ bool bIsCursorVisible;
+ bool bIsLineVisible;
+ AutoTimer aCaretBlinkTimer;
+ rtl::Reference<SmGraphicAccessible> mxAccessible;
+ SmViewShell& mrViewShell;
+ double mfLastZoomScale = 0;
+ double mfAccumulatedZoom = 0;
+};
+
+class SmGraphicController final : public SfxControllerItem
+{
+ SmGraphicWidget &rGraphic;
+public:
+ SmGraphicController(SmGraphicWidget &, sal_uInt16, SfxBindings & );
+ virtual void StateChangedAtToolBoxControl(sal_uInt16 nSID,
+ SfxItemState eState,
+ const SfxPoolItem* pState) override;
+};
+
+class SmEditController final : public SfxControllerItem
+{
+ SmEditWindow &rEdit;
+
+public:
+ SmEditController(SmEditWindow &, sal_uInt16, SfxBindings & );
+
+ virtual void StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) override;
+};
+
+class SmCmdBoxWindow final : public SfxDockingWindow
+{
+ std::unique_ptr<SmEditWindow, o3tl::default_delete<SmEditWindow>> m_xEdit;
+ SmEditController aController;
+ bool bExiting;
+
+ Timer aInitialFocusTimer;
+
+ DECL_LINK(InitialFocusTimerHdl, Timer *, void);
+
+ virtual Size CalcDockingSize(SfxChildAlignment eAlign) override;
+ virtual SfxChildAlignment CheckAlignment(SfxChildAlignment eActual,
+ SfxChildAlignment eWish) override;
+
+ virtual void ToggleFloatingMode() override;
+
+public:
+ SmCmdBoxWindow(SfxBindings *pBindings,
+ SfxChildWindow *pChildWindow,
+ Window *pParent);
+
+ virtual ~SmCmdBoxWindow () override;
+ virtual void dispose() override;
+
+ // Window
+ virtual void GetFocus() override;
+ virtual void StateChanged( StateChangedType nStateChange ) override;
+ virtual void Command(const CommandEvent& rCEvt) override;
+
+ Point WidgetToWindowPos(const weld::Widget& rWidget, const Point& rPos);
+
+ void ShowContextMenu(const Point& rPos);
+
+ void AdjustPosition();
+
+ SmEditWindow& GetEditWindow()
+ {
+ return *m_xEdit;
+ }
+ SmViewShell* GetView();
+};
+
+class SmCmdBoxWrapper final : public SfxChildWindow
+{
+ SFX_DECL_CHILDWINDOW_WITHID(SmCmdBoxWrapper);
+
+ SmCmdBoxWrapper(vcl::Window* pParentWindow, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo);
+
+public:
+
+ SmEditWindow& GetEditWindow()
+ {
+ return static_cast<SmCmdBoxWindow *>(GetWindow())->GetEditWindow();
+ }
+};
+
+namespace sfx2 { class FileDialogHelper; }
+
+class SmViewShell final : public SfxViewShell
+{
+ std::unique_ptr<sfx2::DocumentInserter> mpDocInserter;
+ std::unique_ptr<SfxRequest> mpRequest;
+ VclPtr<SmGraphicWindow> mxGraphicWindow;
+ SmGraphicController maGraphicController;
+ OUString maStatusText;
+ bool mbPasteState;
+
+ DECL_LINK( DialogClosedHdl, sfx2::FileDialogHelper*, void );
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
+
+ virtual SfxPrinter *GetPrinter(bool bCreate = false) override;
+ virtual sal_uInt16 SetPrinter(SfxPrinter *pNewPrinter,
+ SfxPrinterChangeFlags nDiffFlags = SFX_PRINTER_ALL) override;
+
+ void Insert( SfxMedium& rMedium );
+ void InsertFrom(SfxMedium &rMedium);
+
+ virtual bool HasPrintOptionsPage() const override;
+ virtual std::unique_ptr<SfxTabPage> CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet &rOptions) override;
+ virtual void Deactivate(bool IsMDIActivate) override;
+ virtual void Activate(bool IsMDIActivate) override;
+ virtual void InnerResizePixel(const Point &rOfs, const Size &rSize, bool inplaceEditModeChange) override;
+ virtual void OuterResizePixel(const Point &rOfs, const Size &rSize) override;
+ virtual void QueryObjAreaPixel( tools::Rectangle& rRect ) const override;
+ virtual void SetZoomFactor( const Fraction &rX, const Fraction &rY ) override;
+ virtual std::optional<OString> getLOKPayload(int nType, int nViewId) const override;
+
+public:
+
+ SmViewShell(SfxViewFrame& rFrame, SfxViewShell *pOldSh);
+ virtual ~SmViewShell() override;
+
+ SmDocShell * GetDoc() const
+ {
+ return static_cast<SmDocShell *>( GetViewFrame().GetObjectShell() );
+ }
+
+ SmEditWindow * GetEditWindow();
+
+ SmGraphicWidget& GetGraphicWidget()
+ {
+ return mxGraphicWindow->GetGraphicWidget();
+ }
+ const SmGraphicWidget& GetGraphicWidget() const
+ {
+ return mxGraphicWindow->GetGraphicWidget();
+ }
+
+ SmGraphicWindow& GetGraphicWindow()
+ {
+ return *mxGraphicWindow;
+ }
+
+ void SetStatusText(const OUString& rText);
+
+ void ShowError( const SmErrorDesc *pErrorDesc );
+ void NextError();
+ void PrevError();
+
+ SFX_DECL_INTERFACE(SFX_INTERFACE_SMA_START+SfxInterfaceId(2))
+ SFX_DECL_VIEWFACTORY(SmViewShell);
+
+ void SendCaretToLOK() const;
+
+ void InvalidateSlots();
+
+private:
+ /// SfxInterface initializer.
+ static void InitInterface_Impl();
+
+public:
+ void Execute( SfxRequest& rReq );
+ void GetState(SfxItemSet &);
+
+ static bool IsInlineEditEnabled();
+
+ // Opens the main help page for the Math module
+ void StartMainHelp();
+
+private:
+ void ZoomByItemSet(const SfxItemSet *pSet);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx
new file mode 100644
index 0000000000..338e93432b
--- /dev/null
+++ b/starmath/inc/visitors.hxx
@@ -0,0 +1,538 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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/.
+ */
+
+/** Visitors are an easy way to automating operations with nodes.
+ *
+ * The available visitors are:
+ * SmVisitor base class
+ * SmDefaultingVisitor default visitor
+ * SmDrawingVisitor draws formula
+ * SmCaretPosGraphBuildingVisitor position of the node inside starmath code
+ * SmCloningVisitor duplicate nodes
+ * SmNodeToTextVisitor create code from nodes
+ *
+ */
+
+#pragma once
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include "node.hxx"
+#include "caret.hxx"
+
+/** Base class for visitors that visits a tree of SmNodes
+ * @remarks all methods have been left abstract to ensure that implementers
+ * don't forget to implement one.
+ */
+class SmVisitor
+{
+public:
+ virtual void Visit( SmTableNode* pNode ) = 0;
+ virtual void Visit( SmBraceNode* pNode ) = 0;
+ virtual void Visit( SmBracebodyNode* pNode ) = 0;
+ virtual void Visit( SmOperNode* pNode ) = 0;
+ virtual void Visit( SmAlignNode* pNode ) = 0;
+ virtual void Visit( SmAttributeNode* pNode ) = 0;
+ virtual void Visit( SmFontNode* pNode ) = 0;
+ virtual void Visit( SmUnHorNode* pNode ) = 0;
+ virtual void Visit( SmBinHorNode* pNode ) = 0;
+ virtual void Visit( SmBinVerNode* pNode ) = 0;
+ virtual void Visit( SmBinDiagonalNode* pNode ) = 0;
+ virtual void Visit( SmSubSupNode* pNode ) = 0;
+ virtual void Visit( SmMatrixNode* pNode ) = 0;
+ virtual void Visit( SmPlaceNode* pNode ) = 0;
+ virtual void Visit( SmTextNode* pNode ) = 0;
+ virtual void Visit( SmSpecialNode* pNode ) = 0;
+ virtual void Visit( SmGlyphSpecialNode* pNode ) = 0;
+ virtual void Visit( SmMathSymbolNode* pNode ) = 0;
+ virtual void Visit( SmBlankNode* pNode ) = 0;
+ virtual void Visit( SmErrorNode* pNode ) = 0;
+ virtual void Visit( SmLineNode* pNode ) = 0;
+ virtual void Visit( SmExpressionNode* pNode ) = 0;
+ virtual void Visit( SmPolyLineNode* pNode ) = 0;
+ virtual void Visit( SmRootNode* pNode ) = 0;
+ virtual void Visit( SmRootSymbolNode* pNode ) = 0;
+ virtual void Visit( SmRectangleNode* pNode ) = 0;
+ virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
+
+protected:
+ ~SmVisitor() {}
+};
+
+// SmDefaultingVisitor
+
+
+/** Visitor that uses DefaultVisit for handling visits by default
+ *
+ * This abstract baseclass is useful for visitors where many methods share the same
+ * implementation.
+ */
+class SmDefaultingVisitor : public SmVisitor
+{
+public:
+ void Visit( SmTableNode* pNode ) override;
+ void Visit( SmBraceNode* pNode ) override;
+ void Visit( SmBracebodyNode* pNode ) override;
+ void Visit( SmOperNode* pNode ) override;
+ void Visit( SmAlignNode* pNode ) override;
+ void Visit( SmAttributeNode* pNode ) override;
+ void Visit( SmFontNode* pNode ) override;
+ void Visit( SmUnHorNode* pNode ) override;
+ void Visit( SmBinHorNode* pNode ) override;
+ void Visit( SmBinVerNode* pNode ) override;
+ void Visit( SmBinDiagonalNode* pNode ) override;
+ void Visit( SmSubSupNode* pNode ) override;
+ void Visit( SmMatrixNode* pNode ) override;
+ void Visit( SmPlaceNode* pNode ) override;
+ void Visit( SmTextNode* pNode ) override;
+ void Visit( SmSpecialNode* pNode ) override;
+ void Visit( SmGlyphSpecialNode* pNode ) override;
+ void Visit( SmMathSymbolNode* pNode ) override;
+ void Visit( SmBlankNode* pNode ) override;
+ void Visit( SmErrorNode* pNode ) override;
+ void Visit( SmLineNode* pNode ) override;
+ void Visit( SmExpressionNode* pNode ) override;
+ void Visit( SmPolyLineNode* pNode ) override;
+ void Visit( SmRootNode* pNode ) override;
+ void Visit( SmRootSymbolNode* pNode ) override;
+ void Visit( SmRectangleNode* pNode ) override;
+ void Visit( SmVerticalBraceNode* pNode ) override;
+protected:
+ ~SmDefaultingVisitor() {}
+
+ /** Method invoked by Visit methods by default */
+ virtual void DefaultVisit( SmNode* pNode ) = 0;
+};
+
+// SmCaretLinesVisitor: ancestor of caret rectangle enumeration and drawing visitors
+
+class SmCaretLinesVisitor : public SmDefaultingVisitor
+{
+public:
+ SmCaretLinesVisitor(OutputDevice& rDevice, SmCaretPos position, Point offset);
+ virtual ~SmCaretLinesVisitor() = default;
+ void Visit(SmTextNode* pNode) override;
+ using SmDefaultingVisitor::Visit;
+
+protected:
+ void DoIt();
+
+ OutputDevice& getDev() { return mrDev; }
+ virtual void ProcessCaretLine(Point from, Point to) = 0;
+ virtual void ProcessUnderline(Point from, Point to) = 0;
+
+ /** Default method for drawing pNodes */
+ void DefaultVisit(SmNode* pNode) override;
+
+private:
+ OutputDevice& mrDev;
+ SmCaretPos maPos;
+ /** Offset to draw from */
+ Point maOffset;
+};
+
+// SmCaretRectanglesVisitor: obtains the set of rectangles to sent to lok
+
+class SmCaretRectanglesVisitor final : public SmCaretLinesVisitor
+{
+public:
+ SmCaretRectanglesVisitor(OutputDevice& rDevice, SmCaretPos position);
+ const tools::Rectangle& getCaret() const { return maCaret; }
+
+protected:
+ virtual void ProcessCaretLine(Point from, Point to) override;
+ virtual void ProcessUnderline(Point from, Point to) override;
+
+private:
+ tools::Rectangle maCaret;
+};
+
+// SmCaretDrawingVisitor
+
+/** Visitor for drawing a caret position */
+class SmCaretDrawingVisitor final : public SmCaretLinesVisitor
+{
+public:
+ /** Given position and device this constructor will draw the caret */
+ SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
+
+protected:
+ virtual void ProcessCaretLine(Point from, Point to) override;
+ virtual void ProcessUnderline(Point from, Point to) override;
+
+private:
+ bool mbCaretVisible;
+};
+
+// SmCaretPos2LineVisitor
+
+/** Visitor getting a line from a caret position */
+class SmCaretPos2LineVisitor final : public SmDefaultingVisitor
+{
+public:
+ /** Given position and device this constructor will compute a line for the caret */
+ SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position )
+ : mpDev( pDevice )
+ , maPos( position )
+ {
+ SAL_WARN_IF( !position.IsValid(), "starmath", "Cannot draw invalid position!" );
+
+ maPos.pSelectedNode->Accept( this );
+ }
+ virtual ~SmCaretPos2LineVisitor() {}
+ void Visit( SmTextNode* pNode ) override;
+ using SmDefaultingVisitor::Visit;
+ const SmCaretLine& GetResult( ) const {
+ return maLine;
+ }
+private:
+ SmCaretLine maLine;
+ VclPtr<OutputDevice> mpDev;
+ SmCaretPos maPos;
+
+ /** Default method for computing lines for pNodes */
+ void DefaultVisit( SmNode* pNode ) override;
+};
+
+// SmDrawingVisitor
+
+/** Visitor for drawing SmNodes to OutputDevice */
+class SmDrawingVisitor final : public SmVisitor
+{
+public:
+ /** Create an instance of SmDrawingVisitor, and use it to draw a formula
+ * @param rDevice Device to draw on
+ * @param position Offset on device to draw the formula
+ * @param pTree Formula tree to draw
+ * @param rFormat Formula formatting settings
+ * @remarks This constructor will do the drawing, no need to anything more.
+ */
+ SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree, const SmFormat& rFormat )
+ : mrDev( rDevice )
+ , maPosition( position )
+ , mrFormat( rFormat )
+ {
+ if (mrFormat.IsRightToLeft() && mrDev.GetOutDevType() != OUTDEV_WINDOW)
+ mrDev.ReMirror(maPosition);
+ pTree->Accept( this );
+ }
+ virtual ~SmDrawingVisitor() {}
+ void Visit( SmTableNode* pNode ) override;
+ void Visit( SmBraceNode* pNode ) override;
+ void Visit( SmBracebodyNode* pNode ) override;
+ void Visit( SmOperNode* pNode ) override;
+ void Visit( SmAlignNode* pNode ) override;
+ void Visit( SmAttributeNode* pNode ) override;
+ void Visit( SmFontNode* pNode ) override;
+ void Visit( SmUnHorNode* pNode ) override;
+ void Visit( SmBinHorNode* pNode ) override;
+ void Visit( SmBinVerNode* pNode ) override;
+ void Visit( SmBinDiagonalNode* pNode ) override;
+ void Visit( SmSubSupNode* pNode ) override;
+ void Visit( SmMatrixNode* pNode ) override;
+ void Visit( SmPlaceNode* pNode ) override;
+ void Visit( SmTextNode* pNode ) override;
+ void Visit( SmSpecialNode* pNode ) override;
+ void Visit( SmGlyphSpecialNode* pNode ) override;
+ void Visit( SmMathSymbolNode* pNode ) override;
+ void Visit( SmBlankNode* pNode ) override;
+ void Visit( SmErrorNode* pNode ) override;
+ void Visit( SmLineNode* pNode ) override;
+ void Visit( SmExpressionNode* pNode ) override;
+ void Visit( SmPolyLineNode* pNode ) override;
+ void Visit( SmRootNode* pNode ) override;
+ void Visit( SmRootSymbolNode* pNode ) override;
+ void Visit( SmRectangleNode* pNode ) override;
+ void Visit( SmVerticalBraceNode* pNode ) override;
+private:
+ /** Draw the children of a pNode
+ * This the default method, use by most pNodes
+ */
+ void DrawChildren( SmStructureNode* pNode );
+
+ /** Draw an SmTextNode or a subclass of this */
+ void DrawTextNode( SmTextNode* pNode );
+ /** Draw an SmSpecialNode or a subclass of this */
+ void DrawSpecialNode( SmSpecialNode* pNode );
+ /** OutputDevice to draw on */
+ OutputDevice& mrDev;
+ /** Position to draw on the mrDev
+ * @remarks This variable is used to pass parameters in DrawChildren( ), this means
+ that after a call to DrawChildren( ) the contents of this method is undefined
+ so if needed cache it locally on the stack.
+ */
+ Point maPosition;
+ const SmFormat& mrFormat;
+};
+
+// SmSetSelectionVisitor
+
+/** Set Selection Visitor
+ * Sets the IsSelected( ) property on all SmNodes of the tree
+ */
+class SmSetSelectionVisitor final : public SmDefaultingVisitor
+{
+public:
+ SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
+ virtual ~SmSetSelectionVisitor() {}
+ void Visit( SmBinHorNode* pNode ) override;
+ void Visit( SmUnHorNode* pNode ) override;
+ void Visit( SmFontNode* pNode ) override;
+ void Visit( SmTextNode* pNode ) override;
+ void Visit( SmExpressionNode* pNode ) override;
+ void Visit( SmLineNode* pNode ) override;
+ void Visit( SmAlignNode* pNode ) override;
+ using SmDefaultingVisitor::Visit;
+ /** Set IsSelected on all pNodes of pSubTree */
+ static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
+private:
+ /** Visit a selectable pNode
+ * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
+ * than 0 and 1 inside them. SmTextNode should be handle separately!
+ * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
+ * it.
+ */
+ void DefaultVisit( SmNode* pNode ) override;
+ void VisitCompositionNode( SmStructureNode* pNode );
+ /** Caret position where the selection starts */
+ SmCaretPos maStartPos;
+ /** Caret position where the selection ends */
+ SmCaretPos maEndPos;
+ /** The current state of this visitor
+ * This property changes when the visitor meets either maStartPos
+ * or maEndPos. This means that anything visited in between will be
+ * selected.
+ */
+ bool mbSelecting;
+};
+
+
+// SmCaretPosGraphBuildingVisitor
+
+
+/** A visitor for building a SmCaretPosGraph
+ *
+ * Visit invariant:
+ * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitutes an entry
+ * in a line. Consider the line entry "H", this entry creates one carat position, here
+ * denoted by | in "H|".
+ *
+ * Parameter variables:
+ * The following variables are used to transfer parameters into calls and results out
+ * of calls.
+ * pRightMost : SmCaretPosGraphEntry*
+ *
+ * Prior to a Visit call:
+ * pRightMost: A pointer to right most position in front of the current line entry.
+ *
+ * After a Visit call:
+ * pRightMost: A pointer to the right most position in the called line entry, if no there's
+ * no caret positions in called line entry don't change this variable.
+ */
+class SmCaretPosGraphBuildingVisitor final : public SmVisitor
+{
+public:
+ /** Builds a caret position graph for pRootNode */
+ explicit SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
+ virtual ~SmCaretPosGraphBuildingVisitor();
+ void Visit( SmTableNode* pNode ) override;
+ void Visit( SmBraceNode* pNode ) override;
+ void Visit( SmBracebodyNode* pNode ) override;
+ void Visit( SmOperNode* pNode ) override;
+ void Visit( SmAlignNode* pNode ) override;
+ void Visit( SmAttributeNode* pNode ) override;
+ void Visit( SmFontNode* pNode ) override;
+ void Visit( SmUnHorNode* pNode ) override;
+ void Visit( SmBinHorNode* pNode ) override;
+ void Visit( SmBinVerNode* pNode ) override;
+ void Visit( SmBinDiagonalNode* pNode ) override;
+ void Visit( SmSubSupNode* pNode ) override;
+ void Visit( SmMatrixNode* pNode ) override;
+ void Visit( SmPlaceNode* pNode ) override;
+ void Visit( SmTextNode* pNode ) override;
+ void Visit( SmSpecialNode* pNode ) override;
+ void Visit( SmGlyphSpecialNode* pNode ) override;
+ void Visit( SmMathSymbolNode* pNode ) override;
+ void Visit( SmBlankNode* pNode ) override;
+ void Visit( SmErrorNode* pNode ) override;
+ void Visit( SmLineNode* pNode ) override;
+ void Visit( SmExpressionNode* pNode ) override;
+ void Visit( SmPolyLineNode* pNode ) override;
+ void Visit( SmRootNode* pNode ) override;
+ void Visit( SmRootSymbolNode* pNode ) override;
+ void Visit( SmRectangleNode* pNode ) override;
+ void Visit( SmVerticalBraceNode* pNode ) override;
+ SmCaretPosGraph* takeGraph()
+ {
+ return mpGraph.release();
+ }
+private:
+ SmCaretPosGraphEntry* mpRightMost;
+ std::unique_ptr<SmCaretPosGraph> mpGraph;
+};
+
+// SmCloningVisitor
+
+/** Visitor for cloning a pNode
+ *
+ * This visitor creates deep clones.
+ */
+class SmCloningVisitor final : public SmVisitor
+{
+public:
+ SmCloningVisitor()
+ : mpResult(nullptr)
+ {}
+ virtual ~SmCloningVisitor() {}
+ void Visit( SmTableNode* pNode ) override;
+ void Visit( SmBraceNode* pNode ) override;
+ void Visit( SmBracebodyNode* pNode ) override;
+ void Visit( SmOperNode* pNode ) override;
+ void Visit( SmAlignNode* pNode ) override;
+ void Visit( SmAttributeNode* pNode ) override;
+ void Visit( SmFontNode* pNode ) override;
+ void Visit( SmUnHorNode* pNode ) override;
+ void Visit( SmBinHorNode* pNode ) override;
+ void Visit( SmBinVerNode* pNode ) override;
+ void Visit( SmBinDiagonalNode* pNode ) override;
+ void Visit( SmSubSupNode* pNode ) override;
+ void Visit( SmMatrixNode* pNode ) override;
+ void Visit( SmPlaceNode* pNode ) override;
+ void Visit( SmTextNode* pNode ) override;
+ void Visit( SmSpecialNode* pNode ) override;
+ void Visit( SmGlyphSpecialNode* pNode ) override;
+ void Visit( SmMathSymbolNode* pNode ) override;
+ void Visit( SmBlankNode* pNode ) override;
+ void Visit( SmErrorNode* pNode ) override;
+ void Visit( SmLineNode* pNode ) override;
+ void Visit( SmExpressionNode* pNode ) override;
+ void Visit( SmPolyLineNode* pNode ) override;
+ void Visit( SmRootNode* pNode ) override;
+ void Visit( SmRootSymbolNode* pNode ) override;
+ void Visit( SmRectangleNode* pNode ) override;
+ void Visit( SmVerticalBraceNode* pNode ) override;
+ /** Clone a pNode */
+ SmNode* Clone( SmNode* pNode );
+private:
+ SmNode* mpResult;
+ /** Clone children of pSource and give them to pTarget */
+ void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
+ /** Clone attributes on a pNode */
+ static void CloneNodeAttr( SmNode const * pSource, SmNode* pTarget );
+};
+
+
+// SmSelectionRectanglesVisitor: collect selection
+
+class SmSelectionRectanglesVisitor : public SmDefaultingVisitor
+{
+public:
+ SmSelectionRectanglesVisitor(OutputDevice& rDevice, SmNode* pTree);
+ virtual ~SmSelectionRectanglesVisitor() = default;
+ void Visit( SmTextNode* pNode ) override;
+ using SmDefaultingVisitor::Visit;
+
+ const tools::Rectangle& GetSelection() { return maSelectionArea; }
+
+private:
+ /** Reference to drawing device */
+ OutputDevice& mrDev;
+ /** The current area that is selected */
+ tools::Rectangle maSelectionArea;
+ /** Extend the area that must be selected */
+ void ExtendSelectionArea(const tools::Rectangle& rArea) { maSelectionArea.Union(rArea); }
+ /** Default visiting method */
+ void DefaultVisit( SmNode* pNode ) override;
+ /** Visit the children of a given pNode */
+ void VisitChildren( SmNode* pNode );
+};
+
+// SmSelectionDrawingVisitor
+
+class SmSelectionDrawingVisitor final : public SmSelectionRectanglesVisitor
+{
+public:
+ /** Draws a selection on rDevice for the selection on pTree */
+ SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, const Point& rOffset );
+};
+
+// SmNodeToTextVisitor
+
+/** Extract command text from pNodes */
+class SmNodeToTextVisitor final : public SmVisitor
+{
+public:
+ SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
+ virtual ~SmNodeToTextVisitor() {}
+
+ void Visit( SmTableNode* pNode ) override;
+ void Visit( SmBraceNode* pNode ) override;
+ void Visit( SmBracebodyNode* pNode ) override;
+ void Visit( SmOperNode* pNode ) override;
+ void Visit( SmAlignNode* pNode ) override;
+ void Visit( SmAttributeNode* pNode ) override;
+ void Visit( SmFontNode* pNode ) override;
+ void Visit( SmUnHorNode* pNode ) override;
+ void Visit( SmBinHorNode* pNode ) override;
+ void Visit( SmBinVerNode* pNode ) override;
+ void Visit( SmBinDiagonalNode* pNode ) override;
+ void Visit( SmSubSupNode* pNode ) override;
+ void Visit( SmMatrixNode* pNode ) override;
+ void Visit( SmPlaceNode* pNode ) override;
+ void Visit( SmTextNode* pNode ) override;
+ void Visit( SmSpecialNode* pNode ) override;
+ void Visit( SmGlyphSpecialNode* pNode ) override;
+ void Visit( SmMathSymbolNode* pNode ) override;
+ void Visit( SmBlankNode* pNode ) override;
+ void Visit( SmErrorNode* pNode ) override;
+ void Visit( SmLineNode* pNode ) override;
+ void Visit( SmExpressionNode* pNode ) override;
+ void Visit( SmPolyLineNode* pNode ) override;
+ void Visit( SmRootNode* pNode ) override;
+ void Visit( SmRootSymbolNode* pNode ) override;
+ void Visit( SmRectangleNode* pNode ) override;
+ void Visit( SmVerticalBraceNode* pNode ) override;
+private:
+
+ /**
+ * Extract text from a pNode that constitutes a line.
+ * @param pNode
+ * @return
+ */
+ void LineToText( SmNode* pNode ) {
+ Separate( );
+ if( pNode ) pNode->Accept( this );
+ Separate( );
+ }
+
+ /**
+ * Appends rText to the OUStringBuffer ( maCmdText ).
+ * @param rText
+ * @return
+ */
+ void Append( std::u16string_view rText ) {
+ maCmdText.append( rText );
+ }
+
+ /**
+ * Append a blank for separation, if needed.
+ * It is needed if last char is not ' '.
+ * @return
+ */
+ void Separate( ){
+ if( !maCmdText.isEmpty() && maCmdText[ maCmdText.getLength() - 1 ] != ' ' )
+ maCmdText.append(' ');
+ }
+
+ /** Output text generated from the pNodes */
+ OUStringBuffer maCmdText;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */