LCOV - code coverage report
Current view: top level - starmath/inc - node.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 285 314 90.8 %
Date: 2015-06-13 12:38:46 Functions: 166 188 88.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #ifndef INCLUDED_STARMATH_INC_NODE_HXX
      21             : #define INCLUDED_STARMATH_INC_NODE_HXX
      22             : 
      23             : #include <vector>
      24             : #include <ostream>
      25             : 
      26             : #include "types.hxx"
      27             : #include "token.hxx"
      28             : #include "error.hxx"
      29             : #include "rect.hxx"
      30             : #include "format.hxx"
      31             : #include <boost/ptr_container/ptr_deque.hpp>
      32             : #include <memory>
      33             : 
      34             : #define ATTR_BOLD       0x0001
      35             : #define ATTR_ITALIC     0x0002
      36             : 
      37             : 
      38             : enum class FontSizeType {
      39             :   ABSOLUT  = 1,
      40             :   PLUS     = 2,
      41             :   MINUS    = 3,
      42             :   MULTIPLY = 4,
      43             :   DIVIDE   = 5
      44             : };
      45             : 
      46             : // flags to interdict respective status changes
      47             : #define FLG_FONT        0x0001
      48             : #define FLG_SIZE        0x0002
      49             : #define FLG_BOLD        0x0004
      50             : #define FLG_ITALIC      0x0008
      51             : #define FLG_COLOR       0x0010
      52             : #define FLG_VISIBLE     0x0020
      53             : #define FLG_HORALIGN    0x0040
      54             : 
      55             : 
      56             : extern SmFormat *pActiveFormat;
      57             : 
      58             : class SmVisitor;
      59             : class SmDocShell;
      60             : class SmNode;
      61             : class SmStructureNode;
      62             : 
      63             : typedef std::shared_ptr<SmNode> SmNodePointer;
      64             : typedef boost::ptr_deque<SmNode> SmNodeStack;
      65             : typedef std::vector< SmNode * > SmNodeArray;
      66             : typedef std::vector< SmStructureNode * > SmStructureNodeArray;
      67             : 
      68             : template < typename T >
      69       18052 : T* popOrZero( boost::ptr_deque<T> & rStack )
      70             : {
      71       18052 :     if (rStack.empty())
      72           2 :         return 0;
      73       18050 :     auto pTmp = rStack.pop_front();
      74       18050 :     return pTmp.release();
      75             : }
      76             : 
      77             : enum SmScaleMode    { SCALE_NONE, SCALE_WIDTH, SCALE_HEIGHT };
      78             : 
      79             : enum SmNodeType
      80             : {
      81             : /* 0*/ NTABLE,         NBRACE,         NBRACEBODY,     NOPER,          NALIGN,
      82             : /* 5*/ NATTRIBUT,      NFONT,          NUNHOR,         NBINHOR,        NBINVER,
      83             : /*10*/ NBINDIAGONAL,   NSUBSUP,        NMATRIX,        NPLACE,         NTEXT,
      84             : /*15*/ NSPECIAL,       NGLYPH_SPECIAL, NMATH,          NBLANK,         NERROR,
      85             : /*20*/ NLINE,          NEXPRESSION,    NPOLYLINE,      NROOT,          NROOTSYMBOL,
      86             : /*25*/ NRECTANGLE,  NVERTICAL_BRACE, NMATHIDENT,  NDYNINT, NDYNINTSYMBOL
      87             : };
      88             : 
      89             : 
      90             : 
      91             : 
      92             : 
      93           0 : class SmNode : public SmRect
      94             : {
      95             :     SmFace      aFace;
      96             : 
      97             :     SmToken     aNodeToken;
      98             :     SmNodeType      eType;
      99             :     SmScaleMode     eScaleMode;
     100             :     RectHorAlign    eRectHorAlign;
     101             :     sal_uInt16          nFlags,
     102             :                     nAttributes;
     103             :     bool            bIsPhantom;
     104             :     bool            bIsSelected;
     105             : 
     106             : protected:
     107             :     SmNode(SmNodeType eNodeType, const SmToken &rNodeToken);
     108             : 
     109             :     // index in accessible text -1 if not (yet) applicable
     110             :     sal_Int32       nAccIndex;
     111             : 
     112             : public:
     113             :     virtual             ~SmNode();
     114             : 
     115             :     virtual bool        IsVisible() const;
     116             : 
     117             :     virtual sal_uInt16      GetNumSubNodes() const;
     118             :     virtual SmNode *    GetSubNode(sal_uInt16 nIndex);
     119       12923 :             const SmNode * GetSubNode(sal_uInt16 nIndex) const
     120             :             {
     121       12923 :                 return const_cast<SmNode *>(this)->GetSubNode(nIndex);
     122             :             }
     123             : 
     124             :     virtual SmNode *       GetLeftMost();
     125             :             const SmNode * GetLeftMost() const
     126             :             {
     127             :                 return const_cast<SmNode *>(this)->GetLeftMost();
     128             :             }
     129             : 
     130        7154 :             sal_uInt16 &    Flags() { return nFlags; }
     131       18295 :             sal_uInt16 &    Attributes() { return nAttributes; }
     132             : 
     133       70264 :             bool IsPhantom() const { return bIsPhantom; }
     134             :             void SetPhantom(bool bIsPhantom);
     135             :             void SetColor(const Color &rColor);
     136             : 
     137             :             void SetAttribut(sal_uInt16 nAttrib);
     138             :             void ClearAttribut(sal_uInt16 nAttrib);
     139             : 
     140        2151 :             const SmFace & GetFont() const { return aFace; };
     141      187622 :                   SmFace & GetFont()       { return aFace; };
     142             : 
     143             :             void SetFont(const SmFace &rFace);
     144             :             void SetFontSize(const Fraction &rRelSize, FontSizeType nType);
     145             :             void SetSize(const Fraction &rScale);
     146             : 
     147             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell);
     148             :     void PrepareAttributes();
     149             : 
     150             :     sal_uInt16 FindIndex() const;
     151             : 
     152             :     void         SetRectHorAlign(RectHorAlign eHorAlign, bool bApplyToSubTree = true );
     153        2721 :     RectHorAlign GetRectHorAlign() const { return eRectHorAlign; }
     154             : 
     155             :     const SmRect & GetRect() const { return *this; }
     156        5756 :           SmRect & GetRect()       { return *this; }
     157             : 
     158             :     void Move(const Point &rPosition);
     159        7730 :     void MoveTo(const Point &rPosition) { Move(rPosition - GetTopLeft()); }
     160             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat);
     161             :     virtual void CreateTextFromNode(OUString &rText);
     162             : 
     163             :     virtual void    GetAccessibleText( OUStringBuffer &rText ) const;
     164           0 :     sal_Int32       GetAccessibleIndex() const { return nAccIndex; }
     165             :     const SmNode *  FindNodeWithAccessibleIndex(sal_Int32 nAccIndex) const;
     166             : 
     167           0 :     sal_uInt16  GetRow() const    { return (sal_uInt16)aNodeToken.nRow; }
     168           0 :     sal_uInt16  GetColumn() const { return (sal_uInt16)aNodeToken.nCol; }
     169             : 
     170        2638 :     SmScaleMode     GetScaleMode() const { return eScaleMode; }
     171        1340 :     void            SetScaleMode(SmScaleMode eMode) { eScaleMode = eMode; }
     172             : 
     173             :     virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth);
     174             :     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight);
     175             : 
     176       17542 :     SmNodeType      GetType() const  { return eType; }
     177       34313 :     const SmToken & GetToken() const { return aNodeToken; }
     178             : 
     179             :     const SmNode *  FindTokenAt(sal_uInt16 nRow, sal_uInt16 nCol) const;
     180             :     const SmNode *  FindRectClosestTo(const Point &rPoint) const;
     181             : 
     182             :     virtual long    GetFormulaBaseline() const;
     183             : 
     184             :     /** Accept a visitor
     185             :      * Calls the method for this class on the visitor
     186             :      */
     187             :     virtual void Accept(SmVisitor* pVisitor);
     188             : 
     189             :     /** True if this node is selected */
     190          36 :     bool IsSelected() const {return bIsSelected;}
     191         230 :     void SetSelected(bool Selected = true) {bIsSelected = Selected;}
     192             : 
     193             : #ifdef DEBUG_ENABLE_DUMPASDOT
     194             :     /** The tree as dot graph for graphviz, usable for debugging
     195             :      * Convert the output to a image using $ dot graph.gv -Tpng > graph.png
     196             :      */
     197             :     inline void DumpAsDot(std::ostream &out, OUString* label = NULL) const{
     198             :         int id = 0;
     199             :         DumpAsDot(out, label, -1, id, -1);
     200             :     }
     201             : #endif /* DEBUG_ENABLE_DUMPASDOT */
     202             : 
     203             :     /** Get the parent node of this node */
     204         175 :     SmStructureNode* GetParent(){ return aParentNode; }
     205           0 :     const SmStructureNode* GetParent() const { return aParentNode; }
     206             :     /** Set the parent node */
     207       14292 :     void SetParent(SmStructureNode* parent){
     208       14292 :         aParentNode = parent;
     209       14292 :     }
     210             : 
     211             :     /** Get the index of a child node
     212             :      *
     213             :      * Returns -1, if pSubNode isn't a subnode of this.
     214             :      */
     215          32 :     int IndexOfSubNode(SmNode* pSubNode){
     216          32 :         sal_uInt16 nSize = GetNumSubNodes();
     217          64 :         for(sal_uInt16 i = 0; i < nSize; i++)
     218          64 :             if(pSubNode == GetSubNode(i))
     219          32 :                 return i;
     220           0 :         return -1;
     221             :     }
     222             :     /** Set the token for this node */
     223          17 :     void SetToken(SmToken& token){
     224          17 :         aNodeToken = token;
     225          17 :     }
     226             : protected:
     227             :     /** Sets parent on children of this node */
     228             :     inline void ClaimPaternity();
     229             : private:
     230             :     SmStructureNode* aParentNode;
     231             :     void DumpAsDot(std::ostream &out, OUString* label, int number, int& id, int parent) const;
     232             : };
     233             : 
     234             : 
     235             : 
     236             : /** A simple auxiliary iterator class for SmNode
     237             :  *
     238             :  * Example of iteration over children of pMyNode:
     239             :  * \code
     240             :  *  //Node to iterate over:
     241             :  *  SmNode* pMyNode = 0;// A pointer from somewhere
     242             :  *  //The iterator:
     243             :  *  SmNodeIterator it(pMyNode);
     244             :  *  //The iteration:
     245             :  *  while(it.Next()) {
     246             :  *      it->SetSelected(true);
     247             :  *  }
     248             :  * \endcode
     249             :  */
     250             : class SmNodeIterator{
     251             : public:
     252       33253 :     SmNodeIterator(SmNode* node, bool bReverse = false){
     253       33253 :         pNode = node;
     254       33253 :         nSize = pNode->GetNumSubNodes();
     255       33253 :         nIndex = 0;
     256       33253 :         pChildNode = NULL;
     257       33253 :         bIsReverse = bReverse;
     258       33253 :     }
     259             :     /** Get the subnode or NULL if none */
     260       99862 :     SmNode* Next(){
     261      218799 :         while(!bIsReverse && nIndex < nSize){
     262       85686 :             if(NULL != (pChildNode = pNode->GetSubNode(nIndex++)))
     263       66611 :                 return pChildNode;
     264             :         }
     265       66502 :         while(bIsReverse && nSize > 0){
     266           4 :             if(NULL != (pChildNode = pNode->GetSubNode((nSize--)-1)))
     267           4 :                 return pChildNode;
     268             :         }
     269       33247 :         pChildNode = NULL;
     270       33247 :         return NULL;
     271             :     }
     272             :     /** Get the current child node, NULL if none */
     273         100 :     SmNode* Current(){
     274         100 :         return pChildNode;
     275             :     }
     276             :     /** Get the current child node, NULL if none */
     277      131206 :     SmNode* operator->(){
     278      131206 :         return pChildNode;
     279             :     }
     280             : private:
     281             :     /** Current child */
     282             :     SmNode* pChildNode;
     283             :     /** Node whos children we're iterating over */
     284             :     SmNode* pNode;
     285             :     /** Size of the node */
     286             :     sal_uInt16 nSize;
     287             :     /** Current index in the node */
     288             :     sal_uInt16 nIndex;
     289             :     /** Move reverse */
     290             :     bool bIsReverse;
     291             : };
     292             : 
     293             : 
     294             : 
     295             : /** Abstract baseclass for all composite node
     296             :  *
     297             :  * Subclasses of this class can have subnodes. Nodes that doesn't derivate from
     298             :  * this class does not have subnodes.
     299             :  */
     300             : class SmStructureNode : public SmNode
     301             : {
     302             :     SmNodeArray  aSubNodes;
     303             : 
     304             : protected:
     305        6787 :     SmStructureNode(SmNodeType eNodeType, const SmToken &rNodeToken)
     306        6787 :     :   SmNode(eNodeType, rNodeToken)
     307        6787 :     {}
     308             : 
     309             : public:
     310             :             SmStructureNode( const SmStructureNode &rNode );
     311             :     virtual ~SmStructureNode();
     312             : 
     313             :     virtual bool        IsVisible() const SAL_OVERRIDE;
     314             : 
     315             :     virtual sal_uInt16      GetNumSubNodes() const SAL_OVERRIDE;
     316        3037 :             void        SetNumSubNodes(sal_uInt16 nSize) { aSubNodes.resize(nSize); }
     317             : 
     318             :     using   SmNode::GetSubNode;
     319             :     virtual SmNode *    GetSubNode(sal_uInt16 nIndex) SAL_OVERRIDE;
     320             :             void SetSubNodes(SmNode *pFirst, SmNode *pSecond, SmNode *pThird = NULL);
     321             :             void SetSubNodes(const SmNodeArray &rNodeArray);
     322             : 
     323             :     SmStructureNode & operator = ( const SmStructureNode &rNode );
     324             : 
     325             :     virtual void  GetAccessibleText( OUStringBuffer &rText ) const SAL_OVERRIDE;
     326             : 
     327          34 :     void SetSubNode(size_t nIndex, SmNode* pNode)
     328             :     {
     329          34 :         size_t size = aSubNodes.size();
     330          34 :         if (size <= nIndex)
     331             :         {
     332             :             //Resize subnodes array
     333           0 :             aSubNodes.resize(nIndex + 1);
     334             :             //Set new slots to NULL
     335           0 :             for (size_t i = size; i < nIndex+1; i++)
     336           0 :                 aSubNodes[i] = NULL;
     337             :         }
     338          34 :         aSubNodes[nIndex] = pNode;
     339          34 :         ClaimPaternity();
     340          34 :     }
     341             : };
     342             : 
     343        7099 : inline void SmNode::ClaimPaternity() {
     344             :     SmNode* pNode;
     345        7099 :     sal_uInt16  nSize = GetNumSubNodes();
     346       25334 :     for (sal_uInt16 i = 0;  i < nSize;  i++)
     347       18235 :         if (NULL != (pNode = GetSubNode(i)))
     348       14292 :             pNode->SetParent(static_cast<SmStructureNode*>(this)); //Cast is valid if we have children
     349        7099 : }
     350             : 
     351             : /** Abstract base class for all visible node
     352             :  *
     353             :  * Nodes that doesn't derivate from this class doesn't draw anything, but their
     354             :  * children.
     355             :  */
     356        8969 : class SmVisibleNode : public SmNode
     357             : {
     358             : protected:
     359        8969 :     SmVisibleNode(SmNodeType eNodeType, const SmToken &rNodeToken)
     360        8969 :     :   SmNode(eNodeType, rNodeToken)
     361        8969 :     {}
     362             : 
     363             : public:
     364             : 
     365             :     virtual bool        IsVisible() const SAL_OVERRIDE;
     366             :     virtual sal_uInt16      GetNumSubNodes() const SAL_OVERRIDE;
     367             :     using   SmNode::GetSubNode;
     368             :     virtual SmNode *    GetSubNode(sal_uInt16 nIndex) SAL_OVERRIDE;
     369             : };
     370             : 
     371             : 
     372             : 
     373             : 
     374             : 
     375         337 : class SmGraphicNode : public SmVisibleNode
     376             : {
     377             : protected:
     378         337 :     SmGraphicNode(SmNodeType eNodeType, const SmToken &rNodeToken)
     379         337 :     :   SmVisibleNode(eNodeType, rNodeToken)
     380         337 :     {}
     381             : 
     382             : public:
     383             : 
     384             :     virtual void  GetAccessibleText( OUStringBuffer &rText ) const SAL_OVERRIDE;
     385             : };
     386             : 
     387             : 
     388             : 
     389             : 
     390             : /** Draws a rectangle
     391             :  *
     392             :  * Used for drawing the line in the OVER and OVERSTRIKE commands.
     393             :  */
     394         598 : class SmRectangleNode : public SmGraphicNode
     395             : {
     396             :     Size  aToSize;
     397             : 
     398             : public:
     399         299 :     SmRectangleNode(const SmToken &rNodeToken)
     400         299 :     :   SmGraphicNode(NRECTANGLE, rNodeToken)
     401         299 :     {}
     402             : 
     403             :     virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth) SAL_OVERRIDE;
     404             :     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
     405             : 
     406             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     407             : 
     408             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     409             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     410             : };
     411             : 
     412             : 
     413             : 
     414             : 
     415             : /** Polygon line node
     416             :  *
     417             :  * Used to draw the slash of the WIDESLASH command by SmBinDiagonalNode.
     418             :  */
     419          68 : class SmPolyLineNode : public SmGraphicNode
     420             : {
     421             :     Polygon     aPoly;
     422             :     Size        aToSize;
     423             :     long        nWidth;
     424             : 
     425             : public:
     426             :     SmPolyLineNode(const SmToken &rNodeToken);
     427             : 
     428          98 :     long         GetWidth() const { return nWidth; }
     429             :     Size         GetToSize() const { return aToSize; }
     430         192 :     Polygon     &GetPolygon() { return aPoly; }
     431             : 
     432             :     virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth) SAL_OVERRIDE;
     433             :     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
     434             : 
     435             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     436             : 
     437             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     438             : };
     439             : 
     440             : 
     441             : 
     442             : 
     443             : /** Text node
     444             :  *
     445             :  * @remarks This class also serves as baseclass for all nodes that contains text.
     446             :  */
     447       13572 : class SmTextNode : public SmVisibleNode
     448             : {
     449             :     OUString   aText;
     450             :     sal_uInt16      nFontDesc;
     451             :     /** Index within text where the selection starts
     452             :      * @remarks Only valid if SmNode::IsSelected() is true
     453             :      */
     454             :     sal_Int32  nSelectionStart;
     455             :     /** Index within text where the selection ends
     456             :      * @remarks Only valid if SmNode::IsSelected() is true
     457             :      */
     458             :     sal_Int32  nSelectionEnd;
     459             : 
     460             : protected:
     461             :     SmTextNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 nFontDescP );
     462             : 
     463             : public:
     464             :     SmTextNode(const SmToken &rNodeToken, sal_uInt16 nFontDescP );
     465             : 
     466       12067 :     sal_uInt16              GetFontDesc() const { return nFontDesc; }
     467        3667 :     void                SetText(const OUString &rText) { aText = rText; }
     468      129762 :     const OUString &    GetText() const { return aText; }
     469             :     /** Change the text of this node, including the underlying token */
     470           4 :     void                ChangeText(const OUString &rText) {
     471           4 :         aText = rText;
     472           4 :         SmToken token = GetToken();
     473           4 :         token.aText = rText;
     474           4 :         SetToken(token); //TODO: Merge this with AdjustFontDesc for better performance
     475           4 :         AdjustFontDesc();
     476           4 :     }
     477             :     /** Try to guess the correct FontDesc, used during visual editing */
     478             :     void                AdjustFontDesc();
     479             :     /** Index within GetText() where the selection starts
     480             :      * @remarks Only valid of SmNode::IsSelected() is true
     481             :      */
     482           2 :     sal_Int32           GetSelectionStart() const {return nSelectionStart;}
     483             :     /** Index within GetText() where the selection end
     484             :      * @remarks Only valid of SmNode::IsSelected() is true
     485             :      */
     486           2 :     sal_Int32           GetSelectionEnd() const {return nSelectionEnd;}
     487             :     /** Set the index within GetText() where the selection starts */
     488          42 :     void                SetSelectionStart(sal_Int32 index) {nSelectionStart = index;}
     489             :     /** Set the index within GetText() where the selection end */
     490          42 :     void                SetSelectionEnd(sal_Int32 index) {nSelectionEnd = index;}
     491             : 
     492             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
     493             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     494             :     virtual void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     495             : 
     496             :     virtual void  GetAccessibleText( OUStringBuffer &rText ) const SAL_OVERRIDE;
     497             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     498             :     /**
     499             :       Converts the character from StarMath's private area symbols to a matching Unicode
     500             :       character, if necessary. To be used when converting GetText() to a normal text.
     501             :     */
     502             :     static sal_Unicode ConvertSymbolToUnicode(sal_Unicode nIn);
     503             : };
     504             : 
     505             : 
     506             : 
     507             : 
     508             : /** Special node for user defined characters
     509             :  *
     510             :  * Node used for pre- and user-defined characters from:
     511             :  * officecfg/registry/data/org/openoffice/Office/Math.xcu
     512             :  *
     513             :  * This is just single characters, I think.
     514             :  */
     515        3823 : class SmSpecialNode : public SmTextNode
     516             : {
     517             :     bool    bIsFromGreekSymbolSet;
     518             : 
     519             : protected:
     520             :     SmSpecialNode(SmNodeType eNodeType, const SmToken &rNodeToken, sal_uInt16 _nFontDesc);
     521             : 
     522             : public:
     523             :     SmSpecialNode(const SmToken &rNodeToken);
     524             : 
     525             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
     526             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     527             : 
     528             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     529             : };
     530             : 
     531             : 
     532             : 
     533             : 
     534             : /** Glyph node for custom operators
     535             :  *
     536             :  * This node is used with commands: oper, uoper and boper.
     537             :  * E.g. in "A boper op B", "op" will be an instance of SmGlyphSpecialNode.
     538             :  * "boper" simply inteprets "op", the following token, as an binary operator.
     539             :  * The command "uoper" interprets the following token as unary operator.
     540             :  * For these commands an instance of SmGlyphSpecialNode is used for the
     541             :  * operator token, following the command.
     542             :  */
     543           0 : class SmGlyphSpecialNode : public SmSpecialNode
     544             : {
     545             : public:
     546           0 :     SmGlyphSpecialNode(const SmToken &rNodeToken)
     547           0 :     :   SmSpecialNode(NGLYPH_SPECIAL, rNodeToken, FNT_MATH)
     548           0 :     {}
     549             : 
     550             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     551             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     552             : };
     553             : 
     554             : 
     555             : 
     556             : 
     557             : /** Math symbol node
     558             :  *
     559             :  * Use for math symbols such as plus, minus and integrale in the INT command.
     560             :  */
     561        6327 : class SmMathSymbolNode : public SmSpecialNode
     562             : {
     563             : protected:
     564         795 :     SmMathSymbolNode(SmNodeType eNodeType, const SmToken &rNodeToken)
     565         795 :     :   SmSpecialNode(eNodeType, rNodeToken, FNT_MATH)
     566             :     {
     567         795 :         sal_Unicode cChar = GetToken().cMathChar;
     568         795 :         if ((sal_Unicode) '\0' != cChar)
     569         765 :             SetText(OUString(cChar));
     570         795 :     }
     571             : 
     572             : public:
     573             :     SmMathSymbolNode(const SmToken &rNodeToken);
     574             : 
     575             :     virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nWidth) SAL_OVERRIDE;
     576             :     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
     577             : 
     578             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
     579             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     580             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     581             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     582             : };
     583             : 
     584             : 
     585             : 
     586             : /** Math Identifier
     587             :  *
     588             :  * This behaves essentially the same as SmMathSymbolNode and is only used to
     589             :  * represent math symbols that should be exported as <mi> elements rather than
     590             :  * <mo> elements.
     591             :  */
     592          52 : class SmMathIdentifierNode : public SmMathSymbolNode
     593             : {
     594             : public:
     595          26 :     SmMathIdentifierNode(const SmToken &rNodeToken)
     596          26 :     :   SmMathSymbolNode(NMATHIDENT, rNodeToken) {}
     597             : };
     598             : 
     599             : 
     600             : 
     601             : /** Root symbol node
     602             :  *
     603             :  * Root symbol node used by SmRootNode to create the root symbol, in front of
     604             :  * the line with the line above. I don't think this node should be used for
     605             :  * anything else.
     606             :  */
     607         164 : class SmRootSymbolNode : public SmMathSymbolNode
     608             : {
     609             :     sal_uLong  nBodyWidth;  // width of body (argument) of root sign
     610             : 
     611             : public:
     612          82 :     SmRootSymbolNode(const SmToken &rNodeToken)
     613             :         : SmMathSymbolNode(NROOTSYMBOL, rNodeToken)
     614          82 :         , nBodyWidth(0)
     615             :     {
     616          82 :     }
     617             : 
     618         442 :     sal_uLong GetBodyWidth() const {return nBodyWidth;};
     619             :     virtual void AdaptToX(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
     620             :     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
     621             : 
     622             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     623             : };
     624             : 
     625             : 
     626             : /** Dynamic Integral symbol node
     627             :  *
     628             :  * Node for drawing dynamically sized integral symbols.
     629             :  *
     630             :  * TODO: It might be created a parent class SmDynamicSizedNode
     631             :         (for both dynamic integrals, roots and other dynamic symbols)
     632             : 
     633             :  */
     634           0 : class SmDynIntegralSymbolNode : public SmMathSymbolNode
     635             : {
     636             : 
     637             : 
     638             : public:
     639           0 :     SmDynIntegralSymbolNode(const SmToken &rNodeToken)
     640           0 :     :   SmMathSymbolNode(NDYNINTSYMBOL, rNodeToken)
     641           0 :     {}
     642             : 
     643             :     virtual void AdaptToY(const OutputDevice &rDev, sal_uLong nHeight) SAL_OVERRIDE;
     644             : 
     645             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     646             : };
     647             : 
     648             : 
     649             : 
     650             : 
     651             : /** Place node
     652             :  *
     653             :  * Used to create the <?> command, that denotes place where something can be
     654             :  * written.
     655             :  * It is drawn as a square with a shadow.
     656             :  */
     657        1312 : class SmPlaceNode : public SmMathSymbolNode
     658             : {
     659             : public:
     660         654 :     SmPlaceNode(const SmToken &rNodeToken)
     661         654 :     :   SmMathSymbolNode(NPLACE, rNodeToken)
     662             :     {
     663         654 :     }
     664           2 :     SmPlaceNode() : SmMathSymbolNode(NPLACE, SmToken(TPLACE, MS_PLACE, "<?>")) {};
     665             : 
     666             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
     667             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     668             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     669             : };
     670             : 
     671             : 
     672             : 
     673             : 
     674             : /** Error node, for parsing errors
     675             :  *
     676             :  * This node is used for parsing errors and draws an questionmark turned upside
     677             :  * down (inverted question mark).
     678             :  */
     679          62 : class SmErrorNode : public SmMathSymbolNode
     680             : {
     681             : public:
     682          31 :     SmErrorNode(SmParseError /*eError*/, const SmToken &rNodeToken)
     683          31 :     :   SmMathSymbolNode(NERROR, rNodeToken)
     684             :     {
     685          31 :         SetText(OUString(MS_ERROR));
     686          31 :     }
     687             : 
     688             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
     689             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     690             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     691             : };
     692             : 
     693             : 
     694             : 
     695             : 
     696             : /** Table node
     697             :  *
     698             :  * This is the root node for the formula tree. This node is also used for the
     699             :  * STACK and BINOM commands. When used for root node, its
     700             :  * children are instances of SmLineNode, and in some obscure cases the a child
     701             :  * can be an instance of SmExpressionNode, mainly when errors occur.
     702             :  */
     703        2036 : class SmTableNode : public SmStructureNode
     704             : {
     705             :     long nFormulaBaseline;
     706             : public:
     707        1024 :     SmTableNode(const SmToken &rNodeToken)
     708             :         :   SmStructureNode(NTABLE, rNodeToken)
     709        1024 :         , nFormulaBaseline(0)
     710             :     {
     711        1024 :     }
     712             : 
     713             :     using   SmNode::GetLeftMost;
     714             :     virtual SmNode * GetLeftMost() SAL_OVERRIDE;
     715             : 
     716             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     717             :     virtual long GetFormulaBaseline() const SAL_OVERRIDE;
     718             : 
     719             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     720             : };
     721             : 
     722             : 
     723             : 
     724             : 
     725             : /** A line
     726             :  *
     727             :  * Used as child of SmTableNode when the SmTableNode is the root node of the
     728             :  * formula tree.
     729             :  */
     730        2648 : class SmLineNode : public SmStructureNode
     731             : {
     732             :     bool  bUseExtraSpaces;
     733             : 
     734             : protected:
     735         839 :     SmLineNode(SmNodeType eNodeType, const SmToken &rNodeToken)
     736         839 :     :   SmStructureNode(eNodeType, rNodeToken)
     737             :     {
     738         839 :         bUseExtraSpaces = true;
     739         839 :     }
     740             : 
     741             : public:
     742         915 :     SmLineNode(const SmToken &rNodeToken)
     743         915 :     :   SmStructureNode(NLINE, rNodeToken)
     744             :     {
     745         915 :         bUseExtraSpaces = true;
     746         915 :     }
     747             : 
     748         713 :     void  SetUseExtraSpaces(bool bVal) { bUseExtraSpaces = bVal; }
     749        1754 :     bool  IsUseExtraSpaces() const { return bUseExtraSpaces; };
     750             : 
     751             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
     752             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     753             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     754             : };
     755             : 
     756             : 
     757             : 
     758             : 
     759             : /** Expression node
     760             :  *
     761             :  * Used whenever you have an expression such as "A OVER {B + C}", here there is
     762             :  * an expression node that allows "B + C" to be the denominator of the
     763             :  * SmBinVerNode, that the OVER command creates.
     764             :  */
     765        1660 : class SmExpressionNode : public SmLineNode
     766             : {
     767             : public:
     768         839 :     SmExpressionNode(const SmToken &rNodeToken)
     769         839 :     :   SmLineNode(NEXPRESSION, rNodeToken)
     770         839 :     {}
     771             : 
     772             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     773             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     774             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     775             : };
     776             : 
     777             : 
     778             : 
     779             : 
     780             : /** Unary horizontal node
     781             :  *
     782             :  * The same as SmBinHorNode except this is for unary operators.
     783             :  */
     784         348 : class SmUnHorNode : public SmStructureNode
     785             : {
     786             : public:
     787         174 :     SmUnHorNode(const SmToken &rNodeToken)
     788         174 :     :   SmStructureNode(NUNHOR, rNodeToken)
     789             :     {
     790         174 :         SetNumSubNodes(2);
     791         174 :     }
     792             : 
     793             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     794             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     795             : };
     796             : 
     797             : 
     798             : 
     799             : 
     800             : /** Root node
     801             :  *
     802             :  * Used for create square roots and other roots, example:
     803             :  * \f$ \sqrt[\mbox{[Argument]}]{\mbox{[Body]}} \f$.
     804             :  *
     805             :  * Children:<BR>
     806             :  * 0: Argument (optional)<BR>
     807             :  * 1: Symbol (instance of SmRootSymbolNode)<BR>
     808             :  * 2: Body<BR>
     809             :  * Where argument is optional and may be NULL.
     810             :  */
     811         164 : class SmRootNode : public SmStructureNode
     812             : {
     813             : protected:
     814             :     static void  GetHeightVerOffset(const SmRect &rRect,
     815             :                               long &rHeight, long &rVerOffset);
     816             :     static Point GetExtraPos(const SmRect &rRootSymbol, const SmRect &rExtra);
     817             : 
     818             : public:
     819          82 :     SmRootNode(const SmToken &rNodeToken)
     820          82 :     :   SmStructureNode(NROOT, rNodeToken)
     821             :     {
     822          82 :         SetNumSubNodes(3);
     823          82 :     }
     824             : 
     825             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     826             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     827             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     828             : 
     829             :     SmNode* Argument();
     830             :     const SmNode* Argument() const;
     831             :     SmRootSymbolNode* Symbol();
     832             :     const SmRootSymbolNode* Symbol() const;
     833             :     SmNode* Body();
     834             :     const SmNode* Body() const;
     835             : };
     836             : 
     837             : 
     838             : /** Dynamic Integral node
     839             :  *
     840             :  * Used to create Dynamically sized integrals
     841             :  *
     842             :  * Children:<BR>
     843             :  * 0: Symbol (instance of DynIntegralSymbolNode)<BR>
     844             :  * 1: Body<BR>
     845             :  */
     846           0 : class SmDynIntegralNode : public SmStructureNode
     847             : {
     848             : protected:
     849             :     void   GetHeightVerOffset(const SmRect &rRect,
     850             :                               long &rHeight, long &rVerOffset) const;
     851             : 
     852             : public:
     853           0 :     SmDynIntegralNode(const SmToken &rNodeToken)
     854           0 :     :   SmStructureNode(NDYNINT, rNodeToken)
     855             :     {
     856           0 :         SetNumSubNodes(2);
     857           0 :     }
     858             : 
     859             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     860             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     861             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     862             : 
     863             :     SmDynIntegralSymbolNode* Symbol();
     864             :     const SmDynIntegralSymbolNode* Symbol() const;
     865             :     SmNode* Body();
     866             :     const SmNode* Body() const;
     867             : };
     868             : 
     869             : 
     870             : 
     871             : 
     872             : /** Binary horizontal node
     873             :  *
     874             :  * This node is used for binary operators. In a formula such as "A + B".
     875             :  *
     876             :  * Children:<BR>
     877             :  * 0: Left operand<BR>
     878             :  * 1: Binary operator<BR>
     879             :  * 2: Right operand<BR>
     880             :  *
     881             :  * None of the children may be NULL.
     882             :  */
     883        1878 : class SmBinHorNode : public SmStructureNode
     884             : {
     885             : public:
     886         939 :     SmBinHorNode(const SmToken &rNodeToken)
     887         939 :     :   SmStructureNode(NBINHOR, rNodeToken)
     888             :     {
     889         939 :         SetNumSubNodes(3);
     890         939 :     }
     891             : 
     892             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     893             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     894             : 
     895             :     SmMathSymbolNode* Symbol();
     896             :     const SmMathSymbolNode* Symbol() const;
     897             :     SmNode* LeftOperand();
     898             :     const SmNode* LeftOperand() const;
     899             :     SmNode* RightOperand();
     900             :     const SmNode* RightOperand() const;
     901             : };
     902             : 
     903             : 
     904             : 
     905             : 
     906             : /** Binary horizontal node
     907             :  *
     908             :  * This node is used for creating the OVER command, consider the formula:
     909             :  * "numerator OVER denominator", which looks like
     910             :  * \f$ \frac{\mbox{numerator}}{\mbox{denominator}} \f$
     911             :  *
     912             :  * Children:<BR>
     913             :  * 0: Numerator<BR>
     914             :  * 1: Line (instance of SmRectangleNode)<BR>
     915             :  * 2: Denominator<BR>
     916             :  * None of the children may be NULL.
     917             :  */
     918         514 : class SmBinVerNode : public SmStructureNode
     919             : {
     920             : public:
     921         257 :     SmBinVerNode(const SmToken &rNodeToken)
     922         257 :     :   SmStructureNode(NBINVER, rNodeToken)
     923             :     {
     924         257 :         SetNumSubNodes(3);
     925         257 :     }
     926             : 
     927             :     using   SmNode::GetLeftMost;
     928             :     virtual SmNode * GetLeftMost() SAL_OVERRIDE;
     929             : 
     930             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     931             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
     932             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     933             : };
     934             : 
     935             : 
     936             : 
     937             : 
     938             : /** Binary diagonal node
     939             :  *
     940             :  * Used for implementing the WIDESLASH command, example: "A WIDESLASH B".
     941             :  *
     942             :  * Children:<BR>
     943             :  * 0: Left operand<BR>
     944             :  * 1: right operand<BR>
     945             :  * 2: Line (instance of SmPolyLineNode).<BR>
     946             :  * None of the children may be NULL.
     947             :  */
     948          68 : class SmBinDiagonalNode : public SmStructureNode
     949             : {
     950             :     bool    bAscending;
     951             : 
     952             :     void    GetOperPosSize(Point &rPos, Size &rSize,
     953             :                            const Point &rDiagPoint, double fAngleDeg) const;
     954             : 
     955             : public:
     956             :     SmBinDiagonalNode(const SmToken &rNodeToken);
     957             : 
     958         136 :     bool    IsAscending() const { return bAscending; }
     959          34 :     void    SetAscending(bool bVal)  { bAscending = bVal; }
     960             : 
     961             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
     962             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
     963             : };
     964             : 
     965             : 
     966             : 
     967             : 
     968             : 
     969             : /** Enum used to index sub-/supscripts in the 'aSubNodes' array
     970             :  * in 'SmSubSupNode'
     971             :  *
     972             :  * See graphic for positions at char:
     973             :  *
     974             :  * \code
     975             :  *      CSUP
     976             :  *
     977             :  * LSUP H  H RSUP
     978             :  *      H  H
     979             :  *      HHHH
     980             :  *      H  H
     981             :  * LSUB H  H RSUB
     982             :  *
     983             :  *      CSUB
     984             :  * \endcode
     985             :  */
     986             : enum SmSubSup
     987             : {   CSUB, CSUP, RSUB, RSUP, LSUB, LSUP
     988             : };
     989             : 
     990             : /** numbers of entries in the above enum (that is: the number of possible
     991             :  * sub-/supscripts)
     992             :  */
     993             : #define SUBSUP_NUM_ENTRIES 6
     994             : 
     995             : /** Super- and subscript node
     996             :  *
     997             :  * Used for creating super- and subscripts for commands such as:
     998             :  * "^", "_", "lsup", "lsub", "csup" and "csub".
     999             :  * Example: "A^2" which looks like: \f$ A^2 \f$
    1000             :  *
    1001             :  * This node is also used for creating limits on SmOperNode, when
    1002             :  * "FROM" and "TO" commands are used with "INT", "SUM" or similar.
    1003             :  *
    1004             :  * Children of this node can be enumerated using the SmSubSup enum.
    1005             :  * Please note that children may be NULL, except for the body.
    1006             :  * It is recommended that you access children using GetBody() and
    1007             :  * GetSubSup().
    1008             :  */
    1009        1588 : class SmSubSupNode : public SmStructureNode
    1010             : {
    1011             :     bool  bUseLimits;
    1012             : 
    1013             : public:
    1014         794 :     SmSubSupNode(const SmToken &rNodeToken)
    1015         794 :     :   SmStructureNode(NSUBSUP, rNodeToken)
    1016             :     {
    1017         794 :         SetNumSubNodes(1 + SUBSUP_NUM_ENTRIES);
    1018         794 :         bUseLimits = false;
    1019         794 :     }
    1020             : 
    1021             :     /** Get body (Not NULL) */
    1022        1044 :     SmNode *       GetBody()    { return GetSubNode(0); }
    1023             :     /** Get body (Not NULL) */
    1024          93 :     const SmNode * GetBody() const
    1025             :     {
    1026          93 :         return const_cast<SmSubSupNode *>(this)->GetBody();
    1027             :     }
    1028             : 
    1029         787 :     void  SetUseLimits(bool bVal) { bUseLimits = bVal; }
    1030          16 :     bool  IsUseLimits() const { return bUseLimits; };
    1031             : 
    1032             :     /** Get super- or subscript
    1033             :      * @remarks this method may return NULL.
    1034             :      */
    1035        5398 :     SmNode * GetSubSup(SmSubSup eSubSup) { return GetSubNode( sal::static_int_cast< sal_uInt16 >(1 + eSubSup) ); };
    1036         651 :     const SmNode * GetSubSup(SmSubSup eSubSup) const { return const_cast< SmSubSupNode* >( this )->GetSubSup( eSubSup ); }
    1037             : 
    1038             :     /** Set the body */
    1039           1 :     void SetBody(SmNode* pBody) { SetSubNode(0, pBody); }
    1040           1 :     void SetSubSup(SmSubSup eSubSup, SmNode* pScript) { SetSubNode( 1 + eSubSup, pScript); }
    1041             : 
    1042             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1043             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
    1044             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1045             : 
    1046             : };
    1047             : 
    1048             : 
    1049             : 
    1050             : 
    1051             : /** Node for brace construction
    1052             :  *
    1053             :  * Used for "lbrace [body] rbrace" and similar constructions.
    1054             :  * Should look like \f$ \{\mbox{[body]}\} \f$
    1055             :  *
    1056             :  * Children:<BR>
    1057             :  * 0: Opening brace<BR>
    1058             :  * 1: Body (usually SmBracebodyNode)<BR>
    1059             :  * 2: Closing brace<BR>
    1060             :  * None of the children can be NULL.
    1061             :  *
    1062             :  * Note that child 1 (Body) is usually SmBracebodyNode, but it can also be e.g. SmExpressionNode.
    1063             :  */
    1064        1056 : class SmBraceNode : public SmStructureNode
    1065             : {
    1066             : public:
    1067         528 :     SmBraceNode(const SmToken &rNodeToken)
    1068         528 :     :   SmStructureNode(NBRACE, rNodeToken)
    1069             :     {
    1070         528 :         SetNumSubNodes(3);
    1071         528 :     }
    1072             : 
    1073             :     SmMathSymbolNode* OpeningBrace();
    1074             :     const SmMathSymbolNode* OpeningBrace() const;
    1075             :     SmNode* Body();
    1076             :     const SmNode* Body() const;
    1077             :     SmMathSymbolNode* ClosingBrace();
    1078             :     const SmMathSymbolNode* ClosingBrace() const;
    1079             : 
    1080             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1081             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
    1082             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1083             : };
    1084             : 
    1085             : 
    1086             : 
    1087             : 
    1088             : /** Body of an SmBraceNode
    1089             :  *
    1090             :  * This usually only has one child an SmExpressionNode, however, it can also
    1091             :  * have other children.
    1092             :  * Consider the formula "lbrace [body1] mline [body2] rbrace", looks like:
    1093             :  * \f$ \{\mbox{[body1] | [body2]}\} \f$.
    1094             :  * In this case SmBracebodyNode will have three children, "[body1]", "|" and
    1095             :  * [body2].
    1096             :  */
    1097        1044 : class SmBracebodyNode : public SmStructureNode
    1098             : {
    1099             :     long  nBodyHeight;
    1100             : 
    1101             : public:
    1102             :     inline SmBracebodyNode(const SmToken &rNodeToken);
    1103             : 
    1104             :     virtual void    Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1105         409 :     long            GetBodyHeight() const { return nBodyHeight; }
    1106             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1107             : };
    1108             : 
    1109             : 
    1110         522 : inline SmBracebodyNode::SmBracebodyNode(const SmToken &rNodeToken) :
    1111         522 :     SmStructureNode(NBRACEBODY, rNodeToken)
    1112             : {
    1113         522 :     nBodyHeight = 0;
    1114         522 : }
    1115             : 
    1116             : 
    1117             : 
    1118             : 
    1119             : /** Node for vertical brace construction
    1120             :  *
    1121             :  * Used to implement commands "[body] underbrace [script]" and
    1122             :  * "[body] overbrace [script]".
    1123             :  * Underbrace should look like this \f$ \underbrace{\mbox{body}}_{\mbox{script}}\f$.
    1124             :  *
    1125             :  * Children:<BR>
    1126             :  * 0: body<BR>
    1127             :  * 1: brace<BR>
    1128             :  * 2: script<BR>
    1129             :  * (None of these children are optional, e.g. they must all be not NULL).
    1130             :  */
    1131          80 : class SmVerticalBraceNode : public SmStructureNode
    1132             : {
    1133             : public:
    1134             :     inline SmVerticalBraceNode(const SmToken &rNodeToken);
    1135             : 
    1136             :     SmNode* Body();
    1137             :     const SmNode* Body() const;
    1138             :     SmMathSymbolNode* Brace();
    1139             :     const SmMathSymbolNode* Brace() const;
    1140             :     SmNode* Script();
    1141             :     const SmNode* Script() const;
    1142             : 
    1143             :     virtual void    Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1144             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1145             : };
    1146             : 
    1147             : 
    1148          40 : inline SmVerticalBraceNode::SmVerticalBraceNode(const SmToken &rNodeToken) :
    1149          40 :     SmStructureNode(NVERTICAL_BRACE, rNodeToken)
    1150             : {
    1151          40 :     SetNumSubNodes(3);
    1152          40 : }
    1153             : 
    1154             : 
    1155             : 
    1156             : 
    1157             : 
    1158             : /** Operation Node
    1159             :  *
    1160             :  * Used for commands like SUM, INT and similar.
    1161             :  *
    1162             :  * Children:<BR>
    1163             :  * 0: Operation (instance of SmMathSymbolNode or SmSubSupNode)<BR>
    1164             :  * 1: Body<BR>
    1165             :  * None of the children may be NULL.
    1166             :  *
    1167             :  */
    1168         378 : class SmOperNode : public SmStructureNode
    1169             : {
    1170             : public:
    1171         189 :     SmOperNode(const SmToken &rNodeToken)
    1172         189 :     :   SmStructureNode(NOPER, rNodeToken)
    1173             :     {
    1174         189 :         SetNumSubNodes(2);
    1175         189 :     }
    1176             : 
    1177             :     SmNode *       GetSymbol();
    1178           2 :     const SmNode * GetSymbol() const
    1179             :     {
    1180           2 :         return const_cast<SmOperNode *>(this)->GetSymbol();
    1181             :     }
    1182             : 
    1183             :     long CalcSymbolHeight(const SmNode &rSymbol, const SmFormat &rFormat) const;
    1184             : 
    1185             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1186             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1187             : };
    1188             : 
    1189             : 
    1190             : 
    1191             : 
    1192             : /** Node used for alignment
    1193             :  */
    1194          28 : class SmAlignNode : public SmStructureNode
    1195             : {
    1196             : public:
    1197          14 :     SmAlignNode(const SmToken &rNodeToken)
    1198          14 :     :   SmStructureNode(NALIGN, rNodeToken)
    1199          14 :     {}
    1200             : 
    1201             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1202             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1203             : };
    1204             : 
    1205             : 
    1206             : 
    1207             : 
    1208             : /** Attribute node
    1209             :  *
    1210             :  * Used to give an attribute to another node. Used for commands such as:
    1211             :  * UNDERLINE, OVERLINE, OVERSTRIKE, WIDEVEC, WIDEHAT and WIDETILDE.
    1212             :  *
    1213             :  * Children:<BR>
    1214             :  * 0: Attribute<BR>
    1215             :  * 1: Body<BR>
    1216             :  * None of these may be NULL.
    1217             :  */
    1218         580 : class SmAttributNode : public SmStructureNode
    1219             : {
    1220             : public:
    1221         290 :     SmAttributNode(const SmToken &rNodeToken)
    1222         290 :     :   SmStructureNode(NATTRIBUT, rNodeToken)
    1223         290 :     {}
    1224             : 
    1225             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1226             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
    1227             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1228             : 
    1229             :     SmNode* Attribute();
    1230             :     const SmNode* Attribute() const;
    1231             :     SmNode* Body();
    1232             :     const SmNode* Body() const;
    1233             : };
    1234             : 
    1235             : 
    1236             : 
    1237             : 
    1238             : /** Font node
    1239             :  *
    1240             :  * Used to change the font of its children.
    1241             :  */
    1242         242 : class SmFontNode : public SmStructureNode
    1243             : {
    1244             :     FontSizeType nSizeType;
    1245             :     Fraction    aFontSize;
    1246             : 
    1247             : public:
    1248         121 :     SmFontNode(const SmToken &rNodeToken)
    1249         121 :     :   SmStructureNode(NFONT, rNodeToken)
    1250             :     {
    1251         121 :         nSizeType = FontSizeType::MULTIPLY;
    1252         121 :         aFontSize = Fraction(1L);
    1253         121 :     }
    1254             : 
    1255             :     void SetSizeParameter(const Fraction &rValue, FontSizeType nType);
    1256          42 :     const Fraction & GetSizeParameter() const {return aFontSize;}
    1257          42 :     const FontSizeType& GetSizeType() const {return nSizeType;}
    1258             : 
    1259             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
    1260             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1261             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
    1262             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1263             : };
    1264             : 
    1265             : 
    1266             : 
    1267             : 
    1268             : /** Matrix node
    1269             :  *
    1270             :  * Used to implement the MATRIX command, example:
    1271             :  * "matrix{ 1 # 2 ## 3 # 4}".
    1272             :  */
    1273          50 : class SmMatrixNode : public SmStructureNode
    1274             : {
    1275             :     sal_uInt16  nNumRows,
    1276             :             nNumCols;
    1277             : 
    1278             : public:
    1279          25 :     SmMatrixNode(const SmToken &rNodeToken)
    1280          25 :     :   SmStructureNode(NMATRIX, rNodeToken)
    1281             :     {
    1282          25 :         nNumRows = nNumCols = 0;
    1283          25 :     }
    1284             : 
    1285          62 :     sal_uInt16 GetNumRows() const {return nNumRows;}
    1286         160 :     sal_uInt16 GetNumCols() const {return nNumCols;}
    1287             :     void SetRowCol(sal_uInt16 nMatrixRows, sal_uInt16 nMatrixCols);
    1288             : 
    1289             :     using   SmNode::GetLeftMost;
    1290             :     virtual SmNode * GetLeftMost() SAL_OVERRIDE;
    1291             : 
    1292             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1293             :     void CreateTextFromNode(OUString &rText) SAL_OVERRIDE;
    1294             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1295             : };
    1296             : 
    1297             : 
    1298             : 
    1299             : 
    1300             : /** Node for whitespace
    1301             :  *
    1302             :  * Used to implement the "~" command. This node is just a blank space.
    1303             :  */
    1304           8 : class SmBlankNode : public SmGraphicNode
    1305             : {
    1306             :     sal_uInt16  nNum;
    1307             : 
    1308             : public:
    1309           4 :     SmBlankNode(const SmToken &rNodeToken)
    1310           4 :     :   SmGraphicNode(NBLANK, rNodeToken)
    1311             :     {
    1312           4 :         nNum = 0;
    1313           4 :     }
    1314             : 
    1315             :     void         IncreaseBy(const SmToken &rToken);
    1316           0 :     void         Clear() { nNum = 0; }
    1317           0 :     sal_uInt16       GetBlankNum() const { return nNum; }
    1318           0 :     void         SetBlankNum(sal_uInt16 nNumber) { nNum = nNumber; }
    1319             : 
    1320             :     virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) SAL_OVERRIDE;
    1321             :     virtual void Arrange(const OutputDevice &rDev, const SmFormat &rFormat) SAL_OVERRIDE;
    1322             :     void Accept(SmVisitor* pVisitor) SAL_OVERRIDE;
    1323             : };
    1324             : 
    1325             : 
    1326             : 
    1327             : 
    1328             : 
    1329          10 : inline SmNode* SmRootNode::Argument()
    1330             : {
    1331             :     OSL_ASSERT( GetNumSubNodes() > 0 );
    1332          10 :     return GetSubNode( 0 );
    1333             : }
    1334          10 : inline const SmNode* SmRootNode::Argument() const
    1335             : {
    1336          10 :     return const_cast< SmRootNode* >( this )->Argument();
    1337             : }
    1338             : inline SmRootSymbolNode* SmRootNode::Symbol()
    1339             : {
    1340             :     OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NROOTSYMBOL );
    1341             :     return static_cast< SmRootSymbolNode* >( GetSubNode( 1 ));
    1342             : }
    1343             : inline const SmRootSymbolNode* SmRootNode::Symbol() const
    1344             : {
    1345             :     return const_cast< SmRootNode* >( this )->Symbol();
    1346             : }
    1347          10 : inline SmNode* SmRootNode::Body()
    1348             : {
    1349             :     OSL_ASSERT( GetNumSubNodes() > 2 );
    1350          10 :     return GetSubNode( 2 );
    1351             : }
    1352          10 : inline const SmNode* SmRootNode::Body() const
    1353             : {
    1354          10 :     return const_cast< SmRootNode* >( this )->Body();
    1355             : }
    1356             : 
    1357             : 
    1358             : 
    1359           0 : inline SmDynIntegralSymbolNode* SmDynIntegralNode::Symbol()
    1360             : {
    1361             :     OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NDYNINTSYMBOL );
    1362           0 :     return static_cast< SmDynIntegralSymbolNode* >( GetSubNode( 0 ));
    1363             : }
    1364             : inline const SmDynIntegralSymbolNode* SmDynIntegralNode::Symbol() const
    1365             : {
    1366             :     return const_cast< SmDynIntegralNode* >( this )->Symbol();
    1367             : }
    1368           0 : inline SmNode* SmDynIntegralNode::Body()
    1369             : {
    1370             :     OSL_ASSERT( GetNumSubNodes() > 1 );
    1371           0 :     return GetSubNode( 1 );
    1372             : }
    1373             : inline const SmNode* SmDynIntegralNode::Body() const
    1374             : {
    1375             :     return const_cast< SmDynIntegralNode* >( this )->Body();
    1376             : }
    1377             : 
    1378             : 
    1379         530 : inline SmMathSymbolNode* SmBinHorNode::Symbol()
    1380             : {
    1381             :     OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
    1382         530 :     return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
    1383             : }
    1384         530 : inline const SmMathSymbolNode* SmBinHorNode::Symbol() const
    1385             : {
    1386         530 :     return const_cast< SmBinHorNode* >( this )->Symbol();
    1387             : }
    1388         432 : inline SmNode* SmBinHorNode::LeftOperand()
    1389             : {
    1390             :     OSL_ASSERT( GetNumSubNodes() > 0 );
    1391         432 :     return GetSubNode( 0 );
    1392             : }
    1393         432 : inline const SmNode* SmBinHorNode::LeftOperand() const
    1394             : {
    1395         432 :     return const_cast< SmBinHorNode* >( this )->LeftOperand();
    1396             : }
    1397         432 : inline SmNode* SmBinHorNode::RightOperand()
    1398             : {
    1399             :     OSL_ASSERT( GetNumSubNodes() > 2 );
    1400         432 :     return GetSubNode( 2 );
    1401             : }
    1402         432 : inline const SmNode* SmBinHorNode::RightOperand() const
    1403             : {
    1404         432 :     return const_cast< SmBinHorNode* >( this )->RightOperand();
    1405             : }
    1406             : 
    1407          54 : inline SmNode* SmAttributNode::Attribute()
    1408             : {
    1409             :     OSL_ASSERT( GetNumSubNodes() > 0 );
    1410          54 :     return GetSubNode( 0 );
    1411             : }
    1412          54 : inline const SmNode* SmAttributNode::Attribute() const
    1413             : {
    1414          54 :     return const_cast< SmAttributNode* >( this )->Attribute();
    1415             : }
    1416          28 : inline SmNode* SmAttributNode::Body()
    1417             : {
    1418             :     OSL_ASSERT( GetNumSubNodes() > 1 );
    1419          28 :     return GetSubNode( 1 );
    1420             : }
    1421          28 : inline const SmNode* SmAttributNode::Body() const
    1422             : {
    1423          28 :     return const_cast< SmAttributNode* >( this )->Body();
    1424             : }
    1425             : 
    1426          56 : inline SmMathSymbolNode* SmBraceNode::OpeningBrace()
    1427             : {
    1428             :     OSL_ASSERT( GetNumSubNodes() > 0 && GetSubNode( 0 )->GetType() == NMATH );
    1429          56 :     return static_cast< SmMathSymbolNode* >( GetSubNode( 0 ));
    1430             : }
    1431          56 : inline const SmMathSymbolNode* SmBraceNode::OpeningBrace() const
    1432             : {
    1433          56 :     return const_cast< SmBraceNode* >( this )->OpeningBrace();
    1434             : }
    1435         114 : inline SmNode* SmBraceNode::Body()
    1436             : {
    1437             :     OSL_ASSERT( GetNumSubNodes() > 1 );
    1438         114 :     return GetSubNode( 1 );
    1439             : }
    1440         114 : inline const SmNode* SmBraceNode::Body() const
    1441             : {
    1442         114 :     return const_cast< SmBraceNode* >( this )->Body();
    1443             : }
    1444          56 : inline SmMathSymbolNode* SmBraceNode::ClosingBrace()
    1445             : {
    1446             :     OSL_ASSERT( GetNumSubNodes() > 2 && GetSubNode( 2 )->GetType() == NMATH );
    1447          56 :     return static_cast< SmMathSymbolNode* >( GetSubNode( 2 ));
    1448             : }
    1449          56 : inline const SmMathSymbolNode* SmBraceNode::ClosingBrace() const
    1450             : {
    1451          56 :     return const_cast< SmBraceNode* >( this )->ClosingBrace();
    1452             : }
    1453             : 
    1454           4 : inline SmNode* SmVerticalBraceNode::Body()
    1455             : {
    1456             :     OSL_ASSERT( GetNumSubNodes() > 0 );
    1457           4 :     return GetSubNode( 0 );
    1458             : }
    1459           4 : inline const SmNode* SmVerticalBraceNode::Body() const
    1460             : {
    1461           4 :     return const_cast< SmVerticalBraceNode* >( this )->Body();
    1462             : }
    1463           4 : inline SmMathSymbolNode* SmVerticalBraceNode::Brace()
    1464             : {
    1465             :     OSL_ASSERT( GetNumSubNodes() > 1 && GetSubNode( 1 )->GetType() == NMATH );
    1466           4 :     return static_cast< SmMathSymbolNode* >( GetSubNode( 1 ));
    1467             : }
    1468           4 : inline const SmMathSymbolNode* SmVerticalBraceNode::Brace() const
    1469             : {
    1470           4 :     return const_cast< SmVerticalBraceNode* >( this )->Brace();
    1471             : }
    1472           4 : inline SmNode* SmVerticalBraceNode::Script()
    1473             : {
    1474             :     OSL_ASSERT( GetNumSubNodes() > 2 );
    1475           4 :     return GetSubNode( 2 );
    1476             : }
    1477           4 : inline const SmNode* SmVerticalBraceNode::Script() const
    1478             : {
    1479           4 :     return const_cast< SmVerticalBraceNode* >( this )->Script();
    1480             : }
    1481             : 
    1482             : #endif
    1483             : 
    1484             : 
    1485             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11