diff options
Diffstat (limited to 'starmath/inc')
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: · (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: · (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"; -> ∞ + * 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: */ |