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

Generated by: LCOV version 1.10